libei/examples/libeis-server.pseudo
Peter Hutterer 8fc654bfb0 Purge the portal code
The original idea here was that we would have an EmulatedInput portal
that allows the application to connect directly to the EIS
implementation to exchange input events - instead of ping-ponging DBus
events through the xdg-desktop-portal as the RemoteDesktop portal
requires.

This is no longer accurate, there are suggested PRs open to add
RemoteDesktop.ConnectToEIS to achieve the same through the existing
RemoteDesktop interface [1] and to add a new InputCapture portal
to allow for events to be sent to a libei receiver context [2].

The example EmulatedInput portal is thus superfluous and can be removed
from here.

We could switch the ei_setup_backend_portal() code to use RemoteDesktop
or InputCapture, depending on the context type, the utility of this is
questionable. Interaction with portals is complex, one needs to
implement the Session/Request interfaces correctly and in the case of
InputCapture also handle the complex zones/pointer barrier setup.
libportal does some of this (or it will, anyway) so it's more useful for
an application to use libportal and then just pass the received fd to
libei.

If there is a future need for this to be handled as part of libei, we
can (re)implement this, but for now it's best to just purge all of this.

[1] https://github.com/flatpak/xdg-desktop-portal/pull/762
[2] https://github.com/flatpak/xdg-desktop-portal/pull/714
2022-12-08 10:45:47 +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_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)