# 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) 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_CAP_TOUCH) if eis_device_has_capability(EIS_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_get_pointer_width() h = eis_device_get_pointer_height() if (w, h) matches an output: eis_device_set_user_data(output) if eis_device_has_capability(EIS_CAP_KEYBOARD): keymap = eis_device_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_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 suspends the device, as an example if press and key == KEY_ESC and last_key == KEY_ESC: eis_device_suspend() discard_events = true # We may have suspended 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 suspend 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_suspend(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)