libei/examples/libeis-server.pseudo
Peter Hutterer fa7b624f93 Rename suspend to pause to indicate it's a "lighter" form of suspending
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>
2021-08-23 08:34:44 +10:00

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)