## sendevent-to-wire.pkg
#
# Encode X SendEvent values in wire
# (network bytestring) format.
#
# Currently we implement:
#
# fun encode_send_selectionnotify_xevent # Respond to a selection request.
# fun encode_send_unmapnotify_xevent # Tell window manager to unmap a toplevel window.
#
# These get used in (respectively):
#
#
src/lib/x-kit/xclient/src/window/selection-imp-old.pkg#
src/lib/x-kit/xclient/src/window/window-old.pkg#
# See also:
#
src/lib/x-kit/xclient/src/wire/value-to-wire.pkg# Compiled by:
#
src/lib/x-kit/xclient/xclient-internals.sublibstipulate
# package g2d = geometry2d; # geometry2d is from
src/lib/std/2d/geometry2d.pkg package xt = xtypes; # xtypes is from
src/lib/x-kit/xclient/src/wire/xtypes.pkg package ts = xserver_timestamp; # xserver_timestamp is from
src/lib/x-kit/xclient/src/wire/xserver-timestamp.pkg #
package w8a = rw_vector_of_one_byte_unts; # rw_vector_of_one_byte_unts is from
src/lib/std/src/rw-vector-of-one-byte-unts.pkg package w8v = vector_of_one_byte_unts; # vector_of_one_byte_unts is from
src/lib/std/src/vector-of-one-byte-unts.pkg package v2w = value_to_wire; # value_to_wire is from
src/lib/x-kit/xclient/src/wire/value-to-wire.pkg package xtr = xlogger; # xlogger is from
src/lib/x-kit/xclient/src/stuff/xlogger.pkg #
sendevent_tracing = logger::make_logtree_leaf { parent => xlogger::lib_logging, name => "sendevent_tracing", default => FALSE };
trace = xtr::log_if sendevent_tracing 0; # Conditionally write strings to tracing.log or whatever.
herein
package sendevent_to_wire
: Sendevent_To_Wire # Sendevent_To_Wire is from
src/lib/x-kit/xclient/src/wire/sendevent-to-wire.api {
stipulate
# We need to treat requests as modifiable
# for initialization purposes, but we don't
# want them to be modifiable afterwords:
#
ro2rw = unsafe::cast: vector_of_one_byte_unts::Vector -> rw_vector_of_one_byte_unts::Rw_Vector;
encode_push_event
=
v2w::encode_push_event;
event_offset = 12;
fun put8 (buf, i, w) = w8a::set (ro2rw buf, i+event_offset, w);
fun put_signed8 (buf, i, x) = put8 (buf, i, one_byte_unt::from_int x);
fun put16 (buf, i, x)
=
pack_big_endian_unt16::set (ro2rw buf, i / 2 + event_offset / 2, x);
fun put_signed16 (buf, i, x)
=
put16 (buf, i, large_unt::from_int x);
fun put32 (buf, i, x)
=
pack_big_endian_unt1::set (ro2rw buf, i / 4 + event_offset / 4, x);
fun put_word32 (buf, i, x) = put32 (buf, i, unt::to_large_unt x);
fun put_signed32 (buf, i, x) = put32 (buf, i, large_unt::from_int x);
fun put_bool (buf, i, FALSE) => put8 (buf, i, 0u0);
put_bool (buf, i, TRUE ) => put8 (buf, i, 0u1);
end;
fun put_buttons (buf, i, xt::MOUSEBUTTON_STATE unt)
=
put16 (buf, i, one_word_unt::from_int (unt::to_int unt)); # There must be a better way to do this conversion...
fun put_keycode (buf, i, xt::KEYCODE keycode)
=
put_signed8 (buf, i, keycode);
fun put_button (buf, i, xt::MOUSEBUTTON button)
=
put_signed8 (buf, i, button);
fun put_xid (buf, i, xid)
=
put_word32 (buf, i, xt::xid_to_unt xid);
fun put_null_or_xid (buf, i, NULL) => put_word32 (buf, i, 0u0);
put_null_or_xid (buf, i, THE xid) => put_word32 (buf, i, xt::xid_to_unt xid);
end;
fun put_atom (buf, i, xt::XATOM n)
=
put_word32 (buf, i, n);
fun put_null_or_atom (buf, i, NULL) => put_word32 (buf, i, 0u0);
put_null_or_atom (buf, i, THE (xt::XATOM n)) => put_word32 (buf, i, n);
end;
fun put_timestamp (buf, i, xt::CURRENT_TIME) => put32 (buf, i, 0u0);
put_timestamp (buf, i, xt::TIMESTAMP (ts::XSERVER_TIMESTAMP t)) => put32 (buf, i, t);
end;
# Event codes:
#
package event {
key_press = 0u2: one_byte_unt::Unt;
key_release = 0u3: one_byte_unt::Unt;
button_press = 0u4: one_byte_unt::Unt;
button_release = 0u5: one_byte_unt::Unt;
motion_notify = 0u6: one_byte_unt::Unt;
enter_notify = 0u7: one_byte_unt::Unt;
leave_notify = 0u8: one_byte_unt::Unt;
focus_in = 0u9: one_byte_unt::Unt;
focus_out = 0u10: one_byte_unt::Unt;
keymap_notify = 0u11: one_byte_unt::Unt;
expose = 0u12: one_byte_unt::Unt;
graphics_expose = 0u13: one_byte_unt::Unt;
no_expose = 0u14: one_byte_unt::Unt;
visibility_notify = 0u15: one_byte_unt::Unt;
create_notify = 0u16: one_byte_unt::Unt;
destroy_notify = 0u17: one_byte_unt::Unt;
unmap_notify = 0u18: one_byte_unt::Unt;
map_notify = 0u19: one_byte_unt::Unt;
map_request = 0u20: one_byte_unt::Unt;
reparent_notify = 0u21: one_byte_unt::Unt;
configure_notify = 0u22: one_byte_unt::Unt;
configure_request = 0u23: one_byte_unt::Unt;
gravity_notify = 0u24: one_byte_unt::Unt;
resize_request = 0u25: one_byte_unt::Unt;
circulate_notify = 0u26: one_byte_unt::Unt;
circulate_request = 0u27: one_byte_unt::Unt;
property_notify = 0u28: one_byte_unt::Unt;
selection_clear = 0u29: one_byte_unt::Unt;
selection_request = 0u30: one_byte_unt::Unt;
selection_notify = 0u31: one_byte_unt::Unt;
colormap_notify = 0u32: one_byte_unt::Unt;
client_message = 0u33: one_byte_unt::Unt;
mapping_notify = 0u34: one_byte_unt::Unt;
};
fun put_event_code (msg, code)
=
put8 (msg, 0, code);
fun put_detail_code (msg, code)
=
put8 (msg, 1, code);
herein
# For SendEvent proper, see:
# p27 http://mythryl.org/pub/exene/X-protocol-R6.pdf
# p126 http://mythryl.org/pub/exene/X-protocol-R7.pdf
# Event wire encodings are documented in
# p 150-157 http://mythryl.org/pub/exene/X-protocol-R7.pdf
# See p88 http://mythryl.org/pub/exene/X-protocol-R7.pdf
#
fun encode_send_selectionnotify_xevent
{ send_event_to, propagate, event_mask,
requesting_window_id, selection, target, property, timestamp
}
=
{ msg = encode_push_event { send_event_to, propagate, event_mask };
put_event_code (msg, event::selection_notify );
put_timestamp (msg, 4, timestamp );
put_xid (msg, 8, requesting_window_id );
put_atom (msg, 12, selection );
put_atom (msg, 16, target );
put_null_or_atom (msg, 20, property );
msg;
};
# See p84 http://mythryl.org/pub/exene/X-protocol-R7.pdf
#
fun encode_send_unmapnotify_xevent
{ send_event_to, propagate, event_mask,
event_window_id, unmapped_window_id, from_configure
}
=
{ msg = encode_push_event { send_event_to, propagate, event_mask };
put_event_code (msg, event::unmap_notify );
put_xid (msg, 4, event_window_id );
put_xid (msg, 8, unmapped_window_id );
put_bool (msg, 12, from_configure );
msg;
};
# Simulate press of a keyboard key.
#
# For semantics see p77 (81) http://mythryl.org/pub/exene/X-protocol-R6.pdf
# For binary encoding see p151 (155) http://mythryl.org/pub/exene/X-protocol-R6.pdf
#
# Note that 'buttons' is the logical state BEFORE the event.
#
fun encode_send_keypress_xevent
{ send_event_to, propagate, event_mask,
#
timestamp,
root_window_id,
event_window_id, # Window handling the keyboard-key press event.
child_window_id, # Child of event window containing the press point. NULL if none such exists.
root_x, # Mouse position on root window at time of keyboard keypress.
root_y,
event_x, # Mouse position on recipient window at time of keypress.
event_y,
keycode, # Keyboard key just "pressed".
buttons # Mouse button state before keypress.
# We should support modifier keys as well as mouse keys here. XXX BUGGO FIXME.
}
=
{ msg = encode_push_event { send_event_to, propagate, event_mask };
same_screen = TRUE; # I'm pretending multiple-screen X servers do not exist.
put_event_code (msg, event::key_press );
put_keycode (msg, 1, keycode ); # Keyboard key being "pressed".
put_timestamp (msg, 4, timestamp );
put_xid (msg, 8, root_window_id );
put_xid (msg, 12, event_window_id );
put_null_or_xid (msg, 16, child_window_id );
put_signed16 (msg, 20, root_x );
put_signed16 (msg, 22, root_y );
put_signed16 (msg, 24, event_x );
put_signed16 (msg, 26, event_y );
put_buttons (msg, 28, buttons ); # Supposed keys-and-buttons state before the keypress.
put_bool (msg, 30, same_screen );
msg;
};
# Simulate release of a keyboard key.
#
# For semantics see p77 (81) http://mythryl.org/pub/exene/X-protocol-R6.pdf
# For binary encoding see p151 (155) http://mythryl.org/pub/exene/X-protocol-R6.pdf
#
# Note that 'buttons' is the logical state BEFORE the event.
#
fun encode_send_keyrelease_xevent
{ send_event_to, propagate, event_mask,
#
timestamp,
root_window_id,
event_window_id, # Window handling the keyboard-key release event.
child_window_id, # Child of event window containing the release point. NULL if none such exists.
root_x, # Mouse position on root window at time of keyboard key release.
root_y,
event_x, # Mouse position on recipient window at time of key release.
event_y,
keycode, # Keyboard key just "released".
buttons # Mouse button state before key release.
# We should support modifier keys as well as mouse keys here. XXX BUGGO FIXME.
}
=
{ msg = encode_push_event { send_event_to, propagate, event_mask };
same_screen = TRUE; # I'm pretending multiple-screen X servers do not exist.
put_event_code (msg, event::key_release );
put_keycode (msg, 1, keycode ); # Keyboard key being "released".
put_timestamp (msg, 4, timestamp );
put_xid (msg, 8, root_window_id );
put_xid (msg, 12, event_window_id );
put_null_or_xid (msg, 16, child_window_id );
put_signed16 (msg, 20, root_x );
put_signed16 (msg, 22, root_y );
put_signed16 (msg, 24, event_x );
put_signed16 (msg, 26, event_y );
put_buttons (msg, 28, buttons ); # Supposed keys-and-buttons state before the key release.
put_bool (msg, 30, same_screen );
msg;
};
# Simulate down-click of a mousebutton.
#
# For semantics see p77 (81) http://mythryl.org/pub/exene/X-protocol-R6.pdf
# For binary encoding see p151 (155) http://mythryl.org/pub/exene/X-protocol-R6.pdf
#
# Note that 'buttons' is the logical state BEFORE the event.
#
fun encode_send_buttonpress_xevent
{ send_event_to, propagate, event_mask,
#
timestamp,
root_window_id,
event_window_id, # Window handling the mouse-button click event.
child_window_id, # Child of event window containing the click point. NULL if none such exists.
root_x, # Mouse position on root window at time of button click.
root_y,
event_x, # Mouse position on recipient window at time of button click.
event_y,
button, # Mouse button just clicked down.
buttons # Mouse button state before buttonclick.
# We should support modifier keys as well as mouse keys here. XXX BUGGO FIXME.
}
=
{ msg = encode_push_event { send_event_to, propagate, event_mask };
same_screen = TRUE; # I'm pretending multiple-screen X servers do not exist.
put_event_code (msg, event::button_press );
put_button (msg, 1, button ); # Mouse button being clicked.
put_timestamp (msg, 4, timestamp );
put_xid (msg, 8, root_window_id );
put_xid (msg, 12, event_window_id );
put_null_or_xid (msg, 16, child_window_id );
put_signed16 (msg, 20, root_x );
put_signed16 (msg, 22, root_y );
put_signed16 (msg, 24, event_x );
put_signed16 (msg, 26, event_y );
put_buttons (msg, 28, buttons ); # Supposed keys-and-buttons state before the click.
put_bool (msg, 30, same_screen );
msg;
};
# Simulate up-click of a mousebutton.
#
# For semantics see p77 (81) http://mythryl.org/pub/exene/X-protocol-R6.pdf
# For binary encoding see p151 (155) http://mythryl.org/pub/exene/X-protocol-R6.pdf
#
# NOTE that the last three lines of the binary encoding are on page 152!
# I missed this the first time around and wound up spending a day or two
# tracking the problem down. :-(
#
# Note that 'buttons' is the logical state BEFORE the event.
#
fun encode_send_buttonrelease_xevent
{ send_event_to, propagate, event_mask,
#
timestamp,
root_window_id,
event_window_id, # Window handling the mouse-button release event.
child_window_id, # Child of event window containing the release point. NULL if none such exists.
root_x, # Mouse position on root window at time of button release.
root_y,
event_x, # Mouse position on recipient window at time of button release.
event_y,
button, # Mouse button just released.
buttons # Mouse button state before buttonrelease
# We should support modifier keys as well as mouse keys here. XXX BUGGO FIXME.
}
=
{ msg = encode_push_event { send_event_to, propagate, event_mask };
same_screen = TRUE; # I'm pretending multiple-screen X servers do not exist.
# Layout is identical to the button-press case:
#
put_event_code (msg, event::button_release );
put_button (msg, 1, button ); # Mouse button being released.
put_timestamp (msg, 4, timestamp );
put_xid (msg, 8, root_window_id );
put_xid (msg, 12, event_window_id );
put_null_or_xid (msg, 16, child_window_id );
put_signed16 (msg, 20, root_x );
put_signed16 (msg, 22, root_y );
put_signed16 (msg, 24, event_x );
put_signed16 (msg, 26, event_y );
put_buttons (msg, 28, buttons ); # Supposed keys-and-buttons state before the click.
put_bool (msg, 30, same_screen );
msg;
};
# For semantics see p77 (81) http://mythryl.org/pub/exene/X-protocol-R6.pdf
# For binary encoding see p152 (156) http://mythryl.org/pub/exene/X-protocol-R6.pdf
#
fun encode_send_motionnotify_xevent
{ send_event_to, propagate, event_mask,
#
timestamp,
root_window_id,
event_window_id, # Window handling the mouse-button release event.
child_window_id, # Child of event window containing the release point. NULL if none such exists.
root_x, # Mouse position on root window at time of button release.
root_y,
event_x, # Mouse position on recipient window at time of button release.
event_y,
buttons # Mouse button state before buttonrelease
# We should support modifier keys as well as mouse keys here. XXX BUGGO FIXME.
}
=
{ msg = encode_push_event { send_event_to, propagate, event_mask };
same_screen = TRUE; # I'm pretending multiple-screen X servers do not exist.
# Layout is identical to the button-press case:
#
put_event_code (msg, event::motion_notify );
put8 (msg, 1, 0u0 ); # 0=Normal 1=Hint
put_timestamp (msg, 4, timestamp );
put_xid (msg, 8, root_window_id );
put_xid (msg, 12, event_window_id );
put_null_or_xid (msg, 16, child_window_id );
put_signed16 (msg, 20, root_x );
put_signed16 (msg, 22, root_y );
put_signed16 (msg, 24, event_x );
put_signed16 (msg, 26, event_y );
put_buttons (msg, 28, buttons ); # Supposed keys-and-buttons state.
put_bool (msg, 30, same_screen );
msg;
};
# For semantics see p78 (82) http://mythryl.org/pub/exene/X-protocol-R6.pdf
# For binary encoding see p152 (156) http://mythryl.org/pub/exene/X-protocol-R6.pdf
#
fun encode_send_enternotify_xevent
{ send_event_to, propagate, event_mask,
#
timestamp,
root_window_id,
event_window_id, # Window handling the EnterNotify event.
child_window_id, # Child of event window containing the release point. NULL if none such exists.
root_x, # Mouse position on root window at end of EnterNotify event.
root_y,
event_x, # Mouse position on recipient window at end of EnterNotify event.
event_y,
buttons # Mouse button state before buttonclick.
# We should support modifier keys as well as mouse keys here. XXX BUGGO FIXME.
}
=
{ msg = encode_push_event { send_event_to, propagate, event_mask };
# Layout is identical to the button-press case
# except that it is missing the final two fields,
# 'buttons' and 'same_screen':
#
put_event_code (msg, event::enter_notify );
put8 (msg, 1, 0u0 ); # entered from: 0=Ancestor 1=Virtual 2=Inferior 3=Nonlinear 4=NonlinearVirtual
put_timestamp (msg, 4, timestamp );
put_xid (msg, 8, root_window_id );
put_xid (msg, 12, event_window_id );
put_null_or_xid (msg, 16, child_window_id );
put_signed16 (msg, 20, root_x );
put_signed16 (msg, 22, root_y );
put_signed16 (msg, 24, event_x );
put_signed16 (msg, 26, event_y );
put_buttons (msg, 28, buttons ); # Supposed keys-and-buttons state on entry.
put8 (msg, 30, 0u0 ); # Mode: 0=Normal 1=Grab 2=Ungrab
put8 (msg, 31, 0u2 ); # 0x1=Focus 0x2=sameScreen
msg;
};
fun encode_send_leavenotify_xevent
{ send_event_to, propagate, event_mask,
#
timestamp,
root_window_id,
event_window_id, # Window handling the EnterNotify event.
child_window_id, # Child of event window containing the release point. NULL if none such exists.
root_x, # Mouse position on root window at end of EnterNotify event.
root_y,
event_x, # Mouse position on recipient window at end of EnterNotify event.
event_y,
buttons # Mouse button state before buttonclick.
# We should support modifier keys as well as mouse keys here. XXX BUGGO FIXME.
}
=
{ msg = encode_push_event { send_event_to, propagate, event_mask };
# Layout is identical to the button-press case
# except that it is missing the final two fields,
# 'buttons' and 'same_screen':
#
put_event_code (msg, event::leave_notify );
put8 (msg, 1, 0u2 ); # exited to: 0=Ancestor 1=Virtual 2=Inferior 3=Nonlinear 4=NonlinearVirtual
put_timestamp (msg, 4, timestamp );
put_xid (msg, 8, root_window_id );
put_xid (msg, 12, event_window_id );
put_null_or_xid (msg, 16, child_window_id );
put_signed16 (msg, 20, root_x );
put_signed16 (msg, 22, root_y );
put_signed16 (msg, 24, event_x );
put_signed16 (msg, 26, event_y );
put_buttons (msg, 28, buttons ); # Supposed keys-and-buttons state on entry.
put8 (msg, 30, 0u0 ); # Mode: 0=Normal 1=Grab 2=Ungrab
put8 (msg, 31, 0u2 ); # 0x1=Focus 0x2=sameScreen
msg;
};
end; # stipulate
}; # package sendevent_to_wire
end; # stipulate