mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-25 18:40:06 +01:00
There's nothing in the protocol to modify the client device state from the server, so a pause/resume cycle must leave the client with the same(-ish) state. Pause is really just that, a short "no event now please". Anything that would require e.g. modifying the device state by releasing keys or buttons should result in the device being removed and re-added. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
134 lines
4.2 KiB
Text
134 lines
4.2 KiB
Text
# This is pseudocode, illustrating a libeis server implementation
|
|
#
|
|
# This pseudocode assumes to be part of a compositor that can handle
|
|
# input events. It assumes policy decisions as to whether a client may
|
|
# connect are made in the portal or the compositor.
|
|
#
|
|
|
|
function main():
|
|
ctx = eis_new()
|
|
eis_portal_init(ctx)
|
|
|
|
while True:
|
|
poll(eis_get_fd()):
|
|
event = eis_get_event();
|
|
handler = functions[eis_event_get_type(event)]
|
|
handler(event)
|
|
|
|
for client in myclients:
|
|
eis_client_disconnect(client)
|
|
|
|
eis_unref(ctx)
|
|
|
|
|
|
function event_client_connect(event):
|
|
client = eis_event_get_client(event)
|
|
|
|
if do_not_allow_emulated_input:
|
|
eis_client_disconnect(client)
|
|
return
|
|
|
|
# for the portal backend we're assuming that the client has been
|
|
# authenticated by the user, otherwise some authentication needs to
|
|
# be done here
|
|
eis_client_connect(client)
|
|
myclients[client] = eis_client_ref(client)
|
|
|
|
# Send a seats out to the client. Could be the list of seats the
|
|
# server uses anyway, or custom ones.
|
|
seat = eis_client_new_seat(client, "default")
|
|
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_POINTER)
|
|
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_KEYBOARD)
|
|
eis_seat_add(seat)
|
|
|
|
|
|
function event_client_disconnect(event):
|
|
client = eis_event_get_client(event)
|
|
eis_client_unref(client)
|
|
|
|
|
|
function event_device_added(event):
|
|
client = eis_event_get_client(event)
|
|
device = eis_event_get_device(event)
|
|
|
|
if client has too many devices:
|
|
eis_device_disconnect(device)
|
|
return
|
|
|
|
if disallow_touch_input:
|
|
eis_device_disable_capability(EIS_DEVICE_CAP_TOUCH)
|
|
|
|
if eis_device_has_capability(EIS_DEVICE_CAP_POINTER_ABSOLUTE):
|
|
# this is the fixed range give the client. Let's check if there's a
|
|
# monitor with those dimensions and map the device to that monitor
|
|
# That's a server private implementation detail, just used as
|
|
# example here
|
|
w = eis_device_pointer_get_width()
|
|
h = eis_device_pointer_get_height()
|
|
if (w, h) matches an output:
|
|
eis_device_set_user_data(output)
|
|
|
|
if eis_device_has_capability(EIS_DEVICE_CAP_KEYBOARD):
|
|
keymap = eis_device_keyboard_get_keymap()
|
|
# We do not implement per-device keymap in this pseudoserver, notify
|
|
# the client. If we did, here'd be the place to assign the map.
|
|
if keymap != -1:
|
|
eis_device_keyboard_set_keymap(device, -1)
|
|
|
|
eis_device_connect(device)
|
|
# Allow the client to send events
|
|
eis_device_resume(capabilities)
|
|
|
|
|
|
function event_pointer_motion(event):
|
|
x = eis_event_pointer_get_x(event)
|
|
y = eis_event_pointer_get_y(event)
|
|
compositor_handle_pointer_motion(x, y)
|
|
|
|
|
|
function event_pointer_motion_absolute(event):
|
|
x = eis_event_pointer_get_absolute_x(event)
|
|
y = eis_event_pointer_get_absolute_y(event)
|
|
|
|
# the output we map to, see event_device_added
|
|
output = eis_device_get_userdata()
|
|
sx = x/1000
|
|
sy = y/1000
|
|
|
|
compositor_handle_pointer_motion_absolute(output, sx, sy)
|
|
|
|
|
|
function event_pointer_keyboard_key(event):
|
|
device = eis_event_get_device(event)
|
|
|
|
key = eis_event_keyboard_get_key(event)
|
|
press = eis_event_keyboard_get_key_is_press(event)
|
|
|
|
# double escape pauses the device, as an example
|
|
if press and key == KEY_ESC and last_key == KEY_ESC:
|
|
eis_device_pause()
|
|
discard_events = true
|
|
|
|
# We may have paused the client but events can be in mid flight, so
|
|
# we need to process all incoming events regardless. libeis will filter
|
|
# only once the client has received the pause notification.
|
|
update_client_key_state(key, press)
|
|
if not discard_events:
|
|
compositor_handle_key(key, press)
|
|
|
|
|
|
function compositor_vt_switch_callback():
|
|
for client in myclients:
|
|
for device in devices[client]:
|
|
if vt_in:
|
|
eis_device_resume(device)
|
|
else
|
|
eis_device_pause(device)
|
|
|
|
|
|
# Compositor callback if no more emulated input should be handled
|
|
# from a specific client
|
|
function compositor_callback_terminate_EI(condition):
|
|
for client in myclients:
|
|
if client matches condition:
|
|
eis_client_disconnect(client)
|