mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-24 13:30:05 +01:00
Initial commit
This is the outline of the API intended with a minimal compiler just to verify there are no immediate parsing issues.
This commit is contained in:
commit
5e649f682a
10 changed files with 1272 additions and 0 deletions
30
.editorconfig
Normal file
30
.editorconfig
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[meson.build]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
tab_width = 4
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
indent_style = space
|
||||||
|
tab_width = 4
|
||||||
|
|
||||||
|
[*.{c,h}]
|
||||||
|
indent_style = tab
|
||||||
|
tab_width = 8
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
[*.{yaml,tmpl}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
charset = utf-8
|
||||||
20
COPYING
Normal file
20
COPYING
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
Copyright © 2020 Red Hat, Inc.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
138
README.md
Normal file
138
README.md
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
libei
|
||||||
|
=====
|
||||||
|
|
||||||
|
**libei** is a library for Emulated Input, primarily aimed at the Wayland
|
||||||
|
stack. It provides two parts:
|
||||||
|
- 🥚 EI for the client side (`libei`)
|
||||||
|
- 🍦 EIS for the server side (`libeis`)
|
||||||
|
|
||||||
|
The communication between the two is an implementation detail, neither
|
||||||
|
client nor server need to care about the details. Let's call it the BRidge
|
||||||
|
for EI, or 🥣 brei.
|
||||||
|
|
||||||
|
For the purpose of this document, **libei** refers to the project,
|
||||||
|
`libei`/`libeis` to the two libraries provided.
|
||||||
|
|
||||||
|
In the Wayland stack, the EIS server component is part of the
|
||||||
|
compositor, the EI client component is part of the Wayland client.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
+--------------------+ +------------------+
|
||||||
|
| Wayland compositor |---wayland---| Wayland client B |
|
||||||
|
+--------------------+\ +------------------+
|
||||||
|
| libinput | libeis | \_wayland______
|
||||||
|
+----------+---------+ \
|
||||||
|
| | +-------+------------------+
|
||||||
|
/dev/input/ +---brei----| libei | Wayland client A |
|
||||||
|
+-------+------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
The use-cases **libei** attempts to solve are:
|
||||||
|
- on-demand input device emulation, e.g. `xdotool` or more generically the
|
||||||
|
XTEST extension
|
||||||
|
- input forwarding, e.g. `synergy`
|
||||||
|
|
||||||
|
**libei** provides three benefits:
|
||||||
|
- separation
|
||||||
|
- distinction
|
||||||
|
- control
|
||||||
|
|
||||||
|
**libei** provides **separation** of emulated input from normal input.
|
||||||
|
Emulated input is a distinct channel for the compositor and can thus be
|
||||||
|
handled accordingly. For example, the server may show warning sign in the
|
||||||
|
task bar while emulated input is active.
|
||||||
|
|
||||||
|
The second benefit is **distinction**. Each **libei** client has its own
|
||||||
|
input device set, the server is always aware of which client is requesting
|
||||||
|
input at any time. It is possible for the server to treat input from
|
||||||
|
different emulated input devices differently.
|
||||||
|
|
||||||
|
The server is in **control** of emulated input - it can filter input or
|
||||||
|
discard at will. For example, if the current focus window is a password
|
||||||
|
prompt, the server can simply discard any emulated input. If the screen is
|
||||||
|
locked, the server can cancel all emulated input devices.
|
||||||
|
|
||||||
|
For the use-case of fowarding input (e.g. `synergy`) **libei** provides
|
||||||
|
capability monitoring. As with input emulation same benefits apply -
|
||||||
|
input can only be forwarded if the compositor explicitly does so.
|
||||||
|
|
||||||
|
High-level summary
|
||||||
|
------------------
|
||||||
|
|
||||||
|
A pseudo-code implementation for server and client are available in
|
||||||
|
the [`examples/`](https://gitlab.freedesktop.org/whot/libei/-/tree/master/examples)
|
||||||
|
directory.
|
||||||
|
|
||||||
|
The server starts a `libeis` context (which can be integrated with flatpak
|
||||||
|
portals) and uses the `libeis` file descriptor to monitor for
|
||||||
|
client requests.
|
||||||
|
|
||||||
|
A client starts a `libei` context and connects to the server - either
|
||||||
|
directly, via DBus or via a portal. The server (or the portal) approves or
|
||||||
|
denies the client. After successful authentications the client can request
|
||||||
|
the creation of a device with capabilities `pointer`, `keyboard` or `touch`.
|
||||||
|
|
||||||
|
The client triggers input events on this device, the server receives those
|
||||||
|
as events through `libeis` and can forwards them as if they were libinput
|
||||||
|
events. The server has control of the client stream. If the stream is
|
||||||
|
paused, events from the client are discarded. If the stream is resumed, the
|
||||||
|
server will receive the events (but may discard them anyway depending on
|
||||||
|
local state).
|
||||||
|
|
||||||
|
The above caters for the `xdotool` use-case.
|
||||||
|
|
||||||
|
The client may request to monitor a capability. When the server deems the
|
||||||
|
client to be in-focus, it forwards events from real devices to the client.
|
||||||
|
The decision of what constitutes logical focus and what events to forward
|
||||||
|
are up to the server.
|
||||||
|
|
||||||
|
For a `synergy` use-case, the setup requires:
|
||||||
|
- `synergy-client` on host A monitoring the mouse and keyboard capabilities
|
||||||
|
- `synergy-server` on host B requesting a mouse/keyboard capability device
|
||||||
|
- when `synergy-client` receives events via `libei` from compositor A it
|
||||||
|
forwards those to the remote `synergy-server` which sends them via `libei`
|
||||||
|
to the compositor B.
|
||||||
|
|
||||||
|
The compositor may choose to implement a hotkey to start/stop the events or
|
||||||
|
it may implement the screen edges to be the hot key.
|
||||||
|
|
||||||
|
|
||||||
|
Open questions
|
||||||
|
--------------
|
||||||
|
|
||||||
|
### Flatpak integration
|
||||||
|
|
||||||
|
Where flatpak portals are in use, `libei` will communicate with
|
||||||
|
the portal and `libeis` with the portal implementation (e.g.
|
||||||
|
`xdg-desktop-portal-gdk`). The portal is reponsible for
|
||||||
|
allowing the client to connect and restrictions on the devices a client may
|
||||||
|
create. `libeis` will run in a private namespace of the compositor.
|
||||||
|
|
||||||
|
The portal **may** control suspending/resuming devices (in addition to the
|
||||||
|
server). The UI for this is not yet sorted.
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
|
Sandboxing is addressed via flatpak portals but a further level is likely
|
||||||
|
desirable, esp. outside flatpak. The simplest solution is the client
|
||||||
|
announcing the name so the UI can be adjusted accordingly. API wise-maybe an
|
||||||
|
opaque key/value system so the exact auth can be left to the implementation.
|
||||||
|
|
||||||
|
### Triggers
|
||||||
|
|
||||||
|
For `synergy` we need capability monitoring started by triggers, e.g. the
|
||||||
|
client requests a pointer capability monitoring when the real pointer hits
|
||||||
|
the screen edge. Or in response to a keyboard shortcut.
|
||||||
|
|
||||||
|
### Keyboard layouts
|
||||||
|
|
||||||
|
The emulated input may require a specific keyboard layout, we need some
|
||||||
|
keymap notification. Keymaps are effectively one-directional (keycode →
|
||||||
|
keysym is easy, keysym → keycode can be ambiguous), if the server decides on
|
||||||
|
a different layout than the client provides it's hard for the client to
|
||||||
|
figure out what keycodes it needs to send.
|
||||||
|
|
||||||
|
Possible solution here: protocol guarantees that keymap events are only sent
|
||||||
|
while the keyboard is suspended, this way the client knows that if *no*
|
||||||
|
keymap event has been sent before resume, the client keymap was accepted.
|
||||||
75
examples/libei-client.pseudo
Normal file
75
examples/libei-client.pseudo
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
# This is pseudocode, illustrating a libei client implementation
|
||||||
|
|
||||||
|
function main():
|
||||||
|
ctx = ei_new()
|
||||||
|
ei_portal_connect(ctx)
|
||||||
|
|
||||||
|
# let's say this is a blocking wait
|
||||||
|
event = ei_get_event();
|
||||||
|
if ei_event_get_type(event) == EI_EVENT_TYPE_DISCONNECT:
|
||||||
|
print("Sorry, server denied us")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Could also create one device here with both caps
|
||||||
|
ptr = ei_create_device(ctx, CAP_POINTER, "pseudopointer");
|
||||||
|
kbd = ei_create_device(ctx, CAP_KEYBOARD, "pseudokeyboard");
|
||||||
|
keymap_fd = compile_keymap("us", "dvorak")
|
||||||
|
ei_device_keyboard_set_keymap(kbd, FORMAT_XKB, keymap_fd);
|
||||||
|
|
||||||
|
event = ei_get_event()
|
||||||
|
device = ei_event_get_device()
|
||||||
|
if ei_event_get_type(event) == EI_EVENT_TYPE_DEVICE_ADDED:
|
||||||
|
if device == ptr:
|
||||||
|
# The server may not use the name we suggested but it does
|
||||||
|
# tell us the chosen name
|
||||||
|
print("Pointer was created: %s", ei_device_get_name(device))
|
||||||
|
else:
|
||||||
|
print("Keyboard was created: %s", ei_device_get_name(device))
|
||||||
|
else if ei_event_get_type(event) == EI_EVENT_TYPE_DEVICE_REMOVED:
|
||||||
|
if device == ptr:
|
||||||
|
print("We're not allowed a pointer device")
|
||||||
|
elif device == kbd:
|
||||||
|
print("We're not allowed a keyboard device")
|
||||||
|
|
||||||
|
|
||||||
|
# Our devices start in suspended mode
|
||||||
|
suspended = True
|
||||||
|
|
||||||
|
while True:
|
||||||
|
poll(ei_get_fd()):
|
||||||
|
if suspended:
|
||||||
|
wait_for_event(EI_EVENT_POINTER_RESUME or
|
||||||
|
EI_EVENT_KEYBOARD_RESUME)
|
||||||
|
suspended = False
|
||||||
|
continue
|
||||||
|
|
||||||
|
event = ei_get_event();
|
||||||
|
handler = functions[ei_event_get_type(event)]
|
||||||
|
handler(event)
|
||||||
|
|
||||||
|
ei_disconnect(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
function event_disconnect(event):
|
||||||
|
print("Ooops, the server kicked us off")
|
||||||
|
ei_unref(ctx);
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
function event_keyboard_keymap(event):
|
||||||
|
# see README comments
|
||||||
|
keymap_fd = ei_event_keyboard_get_keymap(event))
|
||||||
|
recompile_macros(keymap_fd)
|
||||||
|
|
||||||
|
|
||||||
|
# Called by our actual application to emulate input
|
||||||
|
function move_pointer(x, y):
|
||||||
|
ei_device_pointer_motion(ptr, x, y)
|
||||||
|
|
||||||
|
|
||||||
|
function macro(macro):
|
||||||
|
for key in macro:
|
||||||
|
ei_device_keyboard_key(kbd, key, true)
|
||||||
|
msleep(12); # fake an interval
|
||||||
|
ei_device_keyboard_key(kbd, key, false)
|
||||||
|
msleep(12); # fake an interval
|
||||||
117
examples/libeis-server.pseudo
Normal file
117
examples/libeis-server.pseudo
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
capabilities = eis_device_get_capabilties()
|
||||||
|
if disallow_touch_input:
|
||||||
|
capabilities &= ~EIS_CAP_TOUCH
|
||||||
|
|
||||||
|
if capabilities & EIS_CAP_POINTER_ABSOLUTE:
|
||||||
|
# this is the fixed range we give the client, actual screen
|
||||||
|
# mapping is performed by us later
|
||||||
|
eis_device_pointer_set_width(1024)
|
||||||
|
eis_device_pointer_set_height(768)
|
||||||
|
|
||||||
|
eis_device_connect(device)
|
||||||
|
# Allow the client to send events for all capabilities
|
||||||
|
eis_device_resume_capability(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)
|
||||||
|
|
||||||
|
screen = compositor_get_screen()
|
||||||
|
sx = x/1024 * screen->width
|
||||||
|
sy = y/768 * screen->height
|
||||||
|
|
||||||
|
compositor_handle_pointer_motion_absolute(sx, sy)
|
||||||
|
|
||||||
|
|
||||||
|
function event_pointer_keyboard_key(event):
|
||||||
|
device = eis_event_get_device(event)
|
||||||
|
keymap = eis_device_keyboard_get_keymap(device)
|
||||||
|
# do some libxkbcommon stuff if need be, or send the keymap down the
|
||||||
|
# wire
|
||||||
|
|
||||||
|
key = eis_event_keyboard_get_key(event)
|
||||||
|
press = eis_event_keyboard_get_key_is_press(event)
|
||||||
|
|
||||||
|
# double escape toggles pointer input, as an example
|
||||||
|
if press and key == KEY_ESC and last_key == KEY_ESC:
|
||||||
|
if pointer_is_suspended:
|
||||||
|
eis_device_resume_capability(EIS_CAP_POINTER_ABSOLUTE|EIS_CAP_POINTER)
|
||||||
|
else
|
||||||
|
eis_device_suspend_capability(EIS_CAP_POINTER_ABSOLUTE|EIS_CAP_POINTER)
|
||||||
|
return
|
||||||
|
|
||||||
|
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_capability(all_caps)
|
||||||
|
else
|
||||||
|
eis_device_suspend_capability(all_caps)
|
||||||
|
|
||||||
|
|
||||||
|
# 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)
|
||||||
39
meson.build
Normal file
39
meson.build
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
project('libei', 'c',
|
||||||
|
version: '0.1',
|
||||||
|
license: 'MIT/Expat',
|
||||||
|
default_options: [ 'c_std=gnu99', 'warning_level=2' ],
|
||||||
|
meson_version: '>= 0.50.0')
|
||||||
|
|
||||||
|
pkgconfig = import('pkgconfig')
|
||||||
|
|
||||||
|
cc = meson.get_compiler('c')
|
||||||
|
cppflags = ['-Wno-unused-parameter', '-fvisibility=hidden']
|
||||||
|
cflags = cppflags + ['-Wmissing-prototypes', '-Wstrict-prototypes']
|
||||||
|
add_project_arguments(cflags, language : 'c')
|
||||||
|
add_project_arguments(cppflags, language : 'cpp')
|
||||||
|
|
||||||
|
lib_libei = shared_library('ei',
|
||||||
|
'src/libei.h',
|
||||||
|
'src/libei.c',
|
||||||
|
install: true
|
||||||
|
)
|
||||||
|
|
||||||
|
pkgconfig.generate(lib_libei,
|
||||||
|
filebase: 'libei',
|
||||||
|
name : 'libEI',
|
||||||
|
description : 'Emulated Input client library',
|
||||||
|
version : meson.project_version(),
|
||||||
|
)
|
||||||
|
|
||||||
|
lib_libeis = shared_library('eis',
|
||||||
|
'src/libeis.h',
|
||||||
|
'src/libeis.c',
|
||||||
|
install: true
|
||||||
|
)
|
||||||
|
pkgconfig.generate(lib_libeis,
|
||||||
|
filebase: 'libeis',
|
||||||
|
name : 'libEIS',
|
||||||
|
description : 'Emulated Input server library',
|
||||||
|
version : meson.project_version(),
|
||||||
|
libraries : lib_libei
|
||||||
|
)
|
||||||
24
src/libei.c
Normal file
24
src/libei.c
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2020 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libei.h"
|
||||||
413
src/libei.h
Normal file
413
src/libei.h
Normal file
|
|
@ -0,0 +1,413 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2020 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct ei_ctx;
|
||||||
|
struct ei_device;
|
||||||
|
struct ei_event;
|
||||||
|
struct ei_event_client;
|
||||||
|
struct ei_event_pointer;
|
||||||
|
struct ei_event_keyboard;
|
||||||
|
struct ei_event_touch;
|
||||||
|
|
||||||
|
enum ei_device_capability {
|
||||||
|
EI_DEVICE_CAP_POINTER,
|
||||||
|
EI_DEVICE_CAP_POINTER_ABSOLUTE,
|
||||||
|
EI_DEVICE_CAP_KEYBOARD,
|
||||||
|
EI_DEVICE_CAP_TOUCH,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ei_keymap_type {
|
||||||
|
EI_KEYMAP_TYPE_XKB = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ei_event_type {
|
||||||
|
/**
|
||||||
|
* No event ever has this type, this type exists only as potential
|
||||||
|
* return value for ei_next_event_type().
|
||||||
|
*/
|
||||||
|
EI_EVENT_NONE = 0,
|
||||||
|
/**
|
||||||
|
* The server has approved the connection to this client.
|
||||||
|
*/
|
||||||
|
EI_EVENT_CONNECT,
|
||||||
|
/**
|
||||||
|
* The server has disconnected this client - all resources left to
|
||||||
|
* reference this server are now obsolete. Once this event has been
|
||||||
|
* received, the @ref struct ei_ctx and all its associated resources
|
||||||
|
* should be released.
|
||||||
|
*/
|
||||||
|
EI_EVENT_DISCONNECT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server has added a device for this client. The capabilities
|
||||||
|
* of the device may not match the requested capabilities - it is up
|
||||||
|
* to the client to verify the minimum required capabilities are
|
||||||
|
* indeed set.
|
||||||
|
*/
|
||||||
|
EI_EVENT_DEVICE_ADDED,
|
||||||
|
/**
|
||||||
|
* The server has removed a device belonging to this client.
|
||||||
|
*/
|
||||||
|
EI_EVENT_DEVICE_REMOVED,
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client may send events.
|
||||||
|
*/
|
||||||
|
EI_EVENT_POINTER_RESUME = 300,
|
||||||
|
/**
|
||||||
|
* Any events sent will be discarded until the next resume.
|
||||||
|
*/
|
||||||
|
EI_EVENT_POINTER_SUSPEND,
|
||||||
|
/**
|
||||||
|
* Update pointer ranges. This provides the client with the allowed
|
||||||
|
* axis ranges for absolute pointer motion. The axis ranges may not
|
||||||
|
* match the available screen ranges and the axis range may only map
|
||||||
|
* to a portion of the available screen size.
|
||||||
|
*/
|
||||||
|
EI_EVENT_POINTER_RANGES_CHANGED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client may send events.
|
||||||
|
*/
|
||||||
|
EI_EVENT_KEYBOARD_RESUME = 400,
|
||||||
|
/**
|
||||||
|
* Any events sent will be discarded until the next resume.
|
||||||
|
*/
|
||||||
|
EI_EVENT_KEYBOARD_SUSPEND,
|
||||||
|
/**
|
||||||
|
* Notification of the keymap to be used by the client.
|
||||||
|
*/
|
||||||
|
EI_EVENT_KEYBOARD_KEYMAP,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client may send events.
|
||||||
|
*/
|
||||||
|
EI_EVENT_TOUCH_RESUME = 500,
|
||||||
|
/**
|
||||||
|
* Any events sent will be discarded until the next resume.
|
||||||
|
*/
|
||||||
|
EI_EVENT_TOUCH_SUSPEND,
|
||||||
|
/**
|
||||||
|
* Update touch ranges. This provides the client with the allowed
|
||||||
|
* axis ranges for absolute pointer motion. The axis ranges may not
|
||||||
|
* match the available screen ranges and the axis range may only map
|
||||||
|
* to a portion of the available screen size.
|
||||||
|
*/
|
||||||
|
EI_EVENT_TOUCH_RANGES_CHANGED,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ei_ctx *
|
||||||
|
ei_new(void);
|
||||||
|
|
||||||
|
struct ei_ctx *
|
||||||
|
ei_ref(struct ei_ctx *ctx);
|
||||||
|
|
||||||
|
struct ei_ctx *
|
||||||
|
ei_unref(struct ei_ctx *ei);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to the libeis server via the org.freedesktop.portal
|
||||||
|
*
|
||||||
|
* @return 0 on success or a negative errno on failure
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ei_portal_connect(struct ei_ctx *ei);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to the libeis server on the org.freedesktop.Ei bus name.
|
||||||
|
*
|
||||||
|
* @return 0 on success or a negative errno on failure
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ei_dbus_connect(struct ei_ctx *ei);
|
||||||
|
|
||||||
|
int
|
||||||
|
ei_get_fd(struct ei_ctx *ei);
|
||||||
|
|
||||||
|
void
|
||||||
|
ei_dispatch(struct ei_ctx *ei);
|
||||||
|
|
||||||
|
struct ei_event *
|
||||||
|
ei_get_event(struct ei_ctx *ei);
|
||||||
|
|
||||||
|
enum ei_event_type
|
||||||
|
ei_next_event_type(struct ei_ctx *ei);
|
||||||
|
|
||||||
|
struct ei_event *
|
||||||
|
ei_event_unref(struct ei_event *event);
|
||||||
|
|
||||||
|
struct ei_device *
|
||||||
|
ei_device_ref(struct ei_device *device);
|
||||||
|
|
||||||
|
struct ei_device *
|
||||||
|
ei_device_unref(struct ei_device *device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the creation of a device with suggested capabilities and a
|
||||||
|
* suggested name. Note that the server may ignore the name and may ignore
|
||||||
|
* all capabilities.
|
||||||
|
*
|
||||||
|
* The device returned is a stub device maintained by the library and should
|
||||||
|
* only used for initial device configuration. It does not represent the
|
||||||
|
* server-created device until the @ref EI_EVENT_DEVICE_ADDED for this
|
||||||
|
* device has been received.
|
||||||
|
*
|
||||||
|
* This does not increase the refcount of the device. Use ei_device_ref() to
|
||||||
|
* keep a reference beyond the immediate scope.
|
||||||
|
*
|
||||||
|
* @param ei The context
|
||||||
|
* @param capabilities A bitmask of @ref ei_device_capability
|
||||||
|
* @param name A name suggestion for the device
|
||||||
|
*/
|
||||||
|
struct ei_device *
|
||||||
|
ei_create_device(struct ei_ctx *ei, uint32_t capabilities, const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request that the device be added to the server.
|
||||||
|
* The server will respond with an @ref EI_EVENT_DEVICE_ADDED or @ref
|
||||||
|
* EI_EVENT_DEVICE_REMOVED event.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_device_add(struct ei_device *device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the server that the device is no longer required. The server will
|
||||||
|
* reply with a @ref EI_EVENT_DEVICE_REMOVED event once the device has been
|
||||||
|
* removed.
|
||||||
|
*
|
||||||
|
* This does not release any resources associated with this device, use
|
||||||
|
* ei_device_unref() for any references held by the client.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_device_remove(struct ei_device *device);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name of the device (if any) or NULL
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
ei_device_get_name(struct ei_device *device);
|
||||||
|
|
||||||
|
bool
|
||||||
|
ei_device_has_capability(struct ei_device *device,
|
||||||
|
enum ei_device_capability cap);
|
||||||
|
|
||||||
|
struct ei_ctx *
|
||||||
|
ei_device_get_context(struct ei_device *device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a relative motion event on a device with
|
||||||
|
* the @ref EI_DEVICE_CAP_POINTER capability.
|
||||||
|
*
|
||||||
|
* @param x The x movement in 1/1000th of a logical pixel
|
||||||
|
* @param y The y movement in 1/1000th of a logical pixel
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_device_pointer_motion(struct ei_device *device, int32_t x, int32_t y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an absolute motion event on a device with
|
||||||
|
* the @ref EI_DEVICE_CAP_POINTER_ABSOLUTE capability.
|
||||||
|
*
|
||||||
|
* The required conditions are:
|
||||||
|
* - 0 <= x < width
|
||||||
|
* - 0 <= y < height
|
||||||
|
*
|
||||||
|
* @param x The x position in 1/1000th of a logical pixel
|
||||||
|
* @param y The y position in 1/1000th of a logical pixel
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_device_pointer_motion_absolute(struct ei_device *device,
|
||||||
|
uint32_t x, uint32_t y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a button event on a device with
|
||||||
|
* the @ref EI_DEVICE_CAP_POINTER_ABSOLUTE or
|
||||||
|
* @ref EI_DEVICE_CAP_POINTER capability.
|
||||||
|
*
|
||||||
|
* Buttons are merely sequentially numbered. It is up to the server to map
|
||||||
|
* button numbers into semantic button codes (if any). A server may silently
|
||||||
|
* ignore button events outside meaningful ranges.
|
||||||
|
*
|
||||||
|
* @param button A sequentially numbered button, starting at index 1
|
||||||
|
* @param is_press true for button press, false for button release
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_device_pointer_button(struct ei_device *device,
|
||||||
|
uint32_t button, bool is_press);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a scroll event on a device with
|
||||||
|
* the @ref EI_DEVICE_CAP_POINTER_ABSOLUTE or
|
||||||
|
* @ref EI_DEVICE_CAP_POINTER capability.
|
||||||
|
*
|
||||||
|
* The server emulates discrete scrolling based on the pixel value,
|
||||||
|
* do not call ei_device_pointer_scroll_discrete() for the
|
||||||
|
* same input event.
|
||||||
|
*
|
||||||
|
* @param x The x scroll distance in 1/1000th of a logical pixel
|
||||||
|
* @param y The y scroll distance in 1/1000th of a logical pixel
|
||||||
|
*
|
||||||
|
* @see ei_device_pointer_scroll_discrete
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_device_pointer_scroll(struct ei_device *device, int32_t x, int32_t y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a discrete scroll event on a device with
|
||||||
|
* the @ref EI_DEVICE_CAP_POINTER_ABSOLUTE or
|
||||||
|
* @ref EI_DEVICE_CAP_POINTER capability.
|
||||||
|
*
|
||||||
|
* A discrete scroll event is based logical scroll units (equivalent to one
|
||||||
|
* mouse wheel click). The value for one scroll unit is 120, a fraction or
|
||||||
|
* multiple thereof represents a fraction or multiple of a wheel click.
|
||||||
|
*
|
||||||
|
* The server emulates pixel-based scrolling based on the discrete value,
|
||||||
|
* do not call ei_device_pointer_scroll() for the
|
||||||
|
* same input event.
|
||||||
|
*
|
||||||
|
* @param x The x scroll distance in fractions or multiples of 120
|
||||||
|
* @param y The y scroll distance in fractions or multiples of 120
|
||||||
|
*
|
||||||
|
* @see ei_device_pointer_scroll
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_device_pointer_scroll_discrete(struct ei_device *device, int32_t x, int32_t y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a key event on a device with
|
||||||
|
* the @ref EI_DEVICE_CAP_KEYBOARD capability.
|
||||||
|
*
|
||||||
|
* Keys use the evdev scan codes as defined in
|
||||||
|
* linux/input-event-codes.h
|
||||||
|
*
|
||||||
|
* @param keycode The key code
|
||||||
|
* @param is_press true for key down, false for key up
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_device_keyboard_key(struct ei_device *device, uint32_t keycode, bool is_press);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the keymap on the device. This function has no effect if called
|
||||||
|
* after ei_device_add(). The keymap for this device is a suggestion to
|
||||||
|
* the server, the actual keymap used by this device is provided with
|
||||||
|
* the @ref EI_EVENT_KEYBOARD_KEYMAP event.
|
||||||
|
*
|
||||||
|
* @param type the type of the keymap
|
||||||
|
* @param fd a memmap-able file descriptor to the keymap
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ei_device_keyboard_set_keymap(struct ei_device *device,
|
||||||
|
enum ei_keymap_type type,
|
||||||
|
int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the device from this event.
|
||||||
|
*
|
||||||
|
* This does not increase the refcount of the device. Use eis_device_ref()
|
||||||
|
* to keep a reference beyond the immediate scope.
|
||||||
|
*/
|
||||||
|
struct ei_device *
|
||||||
|
ei_event_get_device(struct ei_event *event);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the event time in microseconds
|
||||||
|
*/
|
||||||
|
uint64_t
|
||||||
|
ei_event_pointer_get_time(struct ei_event_pointer *event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EI_EVENT_POINTER_RANGES_CHANGED, this function
|
||||||
|
* defines the allowable range for x - 0 (inclusive) to width (exclusive).
|
||||||
|
*
|
||||||
|
* The value is in 1/1000th of logical pixels, i.e. the value 1000 000
|
||||||
|
* refers to 1000 pixels.
|
||||||
|
*
|
||||||
|
* It is a client bug to send pointer values outside this range.
|
||||||
|
*
|
||||||
|
* If the touch range changes at runtime, an event of @ref
|
||||||
|
* EI_EVENT_POINTER_RANGES_CHANGED is generated.
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
ei_event_pointer_get_width(struct ei_event_pointer *event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ei_event_pointer_get_width
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
ei_event_pointer_get_height(struct ei_event_pointer *event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the event time in microseconds
|
||||||
|
*/
|
||||||
|
uint64_t
|
||||||
|
ei_event_keyboard_get_time(struct ei_event_keyboard *event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EI_EVENT_TOUCH_RANGES_CHANGED, this function
|
||||||
|
* defines the allowable range for x - 0 (inclusive) to width (exclusive).
|
||||||
|
*
|
||||||
|
* The value is in 1/1000th of logical pixels, i.e. the value 1000 000
|
||||||
|
* refers to 1000 pixels.
|
||||||
|
*
|
||||||
|
* It is a client bug to send touch values outside this range.
|
||||||
|
*
|
||||||
|
* If the touch range changes at runtime, an event of @ref
|
||||||
|
* EI_EVENT_TOUCH_RANGES_CHANGED is generated.
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
ei_event_touch_get_width(struct ei_event_touch *event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ei_event_touch_get_width
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
ei_event_touch_get_height(struct ei_event_touch *event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the event time in microseconds
|
||||||
|
*/
|
||||||
|
uint64_t
|
||||||
|
ei_event_touch_get_time(struct ei_event_touch *event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EI_EVENT_KEYBOARD_KEYMAP return the
|
||||||
|
* type of the keyamp.
|
||||||
|
*/
|
||||||
|
enum ei_keymap_type
|
||||||
|
ei_event_keyboard_get_keymap_type(struct ei_event_keyboard *kbdev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EI_EVENT_KEYBOARD_KEYMAP return the
|
||||||
|
* memmap-able file descriptor to the keymap.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ei_event_keyboard_get_keymap(struct ei_event_keyboard *kbdev);
|
||||||
24
src/libeis.c
Normal file
24
src/libeis.c
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2020 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libeis.h"
|
||||||
392
src/libeis.h
Normal file
392
src/libeis.h
Normal file
|
|
@ -0,0 +1,392 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2020 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct eis_ctx;
|
||||||
|
struct eis_client;
|
||||||
|
struct eis_device;
|
||||||
|
struct eis_event;
|
||||||
|
struct eis_event_client;
|
||||||
|
struct eis_event_pointer;
|
||||||
|
struct eis_event_keyboard;
|
||||||
|
struct eis_event_touch;
|
||||||
|
|
||||||
|
enum eis_device_capability {
|
||||||
|
EIS_DEVICE_CAP_POINTER = (1 << 0),
|
||||||
|
EIS_DEVICE_CAP_POINTER_ABSOLUTE = (1 << 1),
|
||||||
|
EIS_DEVICE_CAP_KEYBOARD = (1 << 2),
|
||||||
|
EIS_DEVICE_CAP_TOUCH = (1 << 3),
|
||||||
|
};
|
||||||
|
|
||||||
|
enum eis_keymap_type {
|
||||||
|
EIS_KEYMAP_TYPE_XKB = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum eis_event_type {
|
||||||
|
/**
|
||||||
|
* No event ever has this type, this type exists only as potential
|
||||||
|
* return value for eis_next_event_type().
|
||||||
|
*/
|
||||||
|
EIS_EVENT_NONE = 0,
|
||||||
|
/**
|
||||||
|
* A client has connected. This is the first event from any new
|
||||||
|
* client.
|
||||||
|
* The server is expected to either call eis_event_client_allow() or
|
||||||
|
* eis_event_client_deny().
|
||||||
|
*/
|
||||||
|
EIS_EVENT_CLIENT_CONNECT,
|
||||||
|
/**
|
||||||
|
* The client has disconnected, any pending requests for this client
|
||||||
|
* should be discarded.
|
||||||
|
*/
|
||||||
|
EIS_EVENT_CLIENT_DISCONNECT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client requests creation of a device with a given set of
|
||||||
|
* capabilities. A client may create more than one device and more
|
||||||
|
* than one device with the same capabilities. The server may filter
|
||||||
|
* the capabilities or deny them altogether.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EIS_EVENT_DEVICE_ADDED,
|
||||||
|
/**
|
||||||
|
* The device created by the client was removed.
|
||||||
|
*
|
||||||
|
* libeis guarantees this event is generated before
|
||||||
|
* @ref EIS_EVENT_CLIENT_DISCONNECT.
|
||||||
|
*/
|
||||||
|
EIS_EVENT_DEVICE_REMOVED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client requests monitoring of a capability.
|
||||||
|
*/
|
||||||
|
EIS_EVENT_REQUEST_CAPABILITY,
|
||||||
|
/**
|
||||||
|
* The client cancelled the request to monitor that capability.
|
||||||
|
*/
|
||||||
|
EIS_EVENT_CANCEL_CAPABILITY,
|
||||||
|
|
||||||
|
EIS_EVENT_POINTER_MOTION = 300,
|
||||||
|
EIS_EVENT_POINTER_MOTION_ABSOLUTE,
|
||||||
|
EIS_EVENT_POINTER_BUTTON,
|
||||||
|
EIS_EVENT_POINTER_SCROLL,
|
||||||
|
EIS_EVENT_POINTER_SCROLL_DISCRETE,
|
||||||
|
|
||||||
|
EIS_EVENT_KEYBOARD_KEY = 400,
|
||||||
|
EIS_EVENT_KEYBOARD_KEYMAP,
|
||||||
|
|
||||||
|
EIS_EVENT_TOUCH_DOWN = 500,
|
||||||
|
EIS_EVENT_TOUCH_UP,
|
||||||
|
EIS_EVENT_TOUCH_MOTION,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new libeis context with a refcount of 1.
|
||||||
|
*/
|
||||||
|
struct eis_ctx *
|
||||||
|
eis_new(void);
|
||||||
|
|
||||||
|
struct eis_ctx *
|
||||||
|
eis_ref(struct eis_ctx *eis);
|
||||||
|
|
||||||
|
struct eis_ctx *
|
||||||
|
eis_unref(struct eis_ctx *eis);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the context with org.freedesktop.portal integration.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eis_portal_init(struct eis_ctx *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the context with a DBus backend on the org.freedesktop.Ei bus
|
||||||
|
* name.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eis_dbus_init(struct eis_ctx *ctx);
|
||||||
|
|
||||||
|
int
|
||||||
|
eis_get_fd(struct eis_ctx *eis);
|
||||||
|
|
||||||
|
void
|
||||||
|
eis_dispatch(struct eis_ctx *eis);
|
||||||
|
|
||||||
|
struct eis_event *
|
||||||
|
eis_get_event(struct eis_ctx *eis);
|
||||||
|
|
||||||
|
enum eis_event_type
|
||||||
|
eis_next_event_type(struct eis_ctx *eis);
|
||||||
|
|
||||||
|
struct eis_client *
|
||||||
|
eis_client_ref(struct eis_client *client);
|
||||||
|
|
||||||
|
struct eis_client *
|
||||||
|
eis_client_unref(struct eis_client *client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow connection from the client. This can only be done once, further
|
||||||
|
* calls to this functions are ignored.
|
||||||
|
*
|
||||||
|
* When receiving an event of type @ref EIS_EVENT_CLIENT_CONNECT, the server
|
||||||
|
* should connect client as soon as possible to allow communication with the
|
||||||
|
* server. If the client is not authorized to talk to the server, call
|
||||||
|
* eis_client_disconnect().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eis_client_connect(struct eis_client *client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnect this client. Once disconnected the client may no longer talk
|
||||||
|
* to this context, all resources associated with this client should be
|
||||||
|
* released.
|
||||||
|
*
|
||||||
|
* It is not necessary to call this function when an @ref
|
||||||
|
* EIS_EVENT_CLIENT_DISCONNECT event is received.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eis_client_disconnect(struct eis_client *client);
|
||||||
|
|
||||||
|
struct eis_client *
|
||||||
|
eis_event_get_client(struct eis_event *event);
|
||||||
|
|
||||||
|
|
||||||
|
struct eis_device *
|
||||||
|
eis_device_ref(struct eis_device *device);
|
||||||
|
|
||||||
|
struct eis_device *
|
||||||
|
eis_device_unref(struct eis_device *device);
|
||||||
|
|
||||||
|
const char *
|
||||||
|
eis_device_get_name(struct eis_device *device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the name of the device. This function has no effect if called after
|
||||||
|
* eis_device_connect()
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
eis_device_set_name(struct eis_device *device, const char *name);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
eis_device_get_capabilities(struct eis_device *device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the capabilities of the device. This function has no effect if called after
|
||||||
|
* eis_device_connect()
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eis_device_set_capabilities(struct eis_device *device, uint32_t caps);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects the device.
|
||||||
|
*
|
||||||
|
* This function should be called in response to an @ref
|
||||||
|
* EIS_EVENT_DEVICE_ADDED if the server accepts the device creation.
|
||||||
|
* Any changes to the device, e.g. eis_device_set_name() and
|
||||||
|
* eis_device_disable_capability() must be performed before connecting the
|
||||||
|
* device.
|
||||||
|
*
|
||||||
|
* Calling eis_device_connect() on a device with all capabilities set to
|
||||||
|
* zero is a bug.
|
||||||
|
*
|
||||||
|
* If the device is rejected, call eis_device_disconnect() instead.
|
||||||
|
*
|
||||||
|
* The device's capabilities are suspended, use
|
||||||
|
* eis_device_resume_capability() to enable events from the client.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eis_device_connect(struct eis_device *device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnect the device.
|
||||||
|
* This does not release any resources associated with this device, use
|
||||||
|
* eils_device_unref() for any references held by the caller.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eis_device_disconnect(struct eis_device *device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the client that the capabilities are suspended and that no events
|
||||||
|
* from the client for this capability will be processed.
|
||||||
|
*
|
||||||
|
* @param device A connected device
|
||||||
|
* @param cap A bitmask of the capabilities to suspend.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eis_device_suspend_capability(struct eis_device *device, uint32_t cap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the client that the capabilities are resumed and that events
|
||||||
|
* from the client for this capability will be processed.
|
||||||
|
*
|
||||||
|
* @param device A connected device
|
||||||
|
* @param cap A bitmask of the capabilities to resume.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eis_device_resume_capability(struct eis_device *device, uint32_t cap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the client of a new range for absolute pointer events.
|
||||||
|
* The range is 0 (inclusive) to width (exclusive).
|
||||||
|
*
|
||||||
|
* The value is in 1/1000th of logical pixels, i.e. the value 1000 000
|
||||||
|
* refers to 1000 pixels.
|
||||||
|
*
|
||||||
|
* Due to inherent race conditions with changing the width of a device in an
|
||||||
|
* asynchronous communication channel, a server should alway suspend the
|
||||||
|
* pointer capability before changing the width.
|
||||||
|
*
|
||||||
|
* @param width The new width in 1/1000th of logical pixels
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eis_device_pointer_set_width(struct eis_device *device, uint32_t width);
|
||||||
|
/**
|
||||||
|
* @see eis_device_pointer_set_width
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eis_device_pointer_set_height(struct eis_device *device, uint32_t height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the keymap on the device.
|
||||||
|
* Due to inherent race conditions with changing the keymap on a device in
|
||||||
|
* an asynchronous communication channel, a server should alway suspend the
|
||||||
|
* keyboard capability before changing the keymap.
|
||||||
|
*
|
||||||
|
* @param type the type of the keymap
|
||||||
|
* @param fd a memmap-able file descriptor to the keymap
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
eis_device_keyboard_set_keymap(struct eis_device *device,
|
||||||
|
enum eis_keymap_type type,
|
||||||
|
int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the device from this event.
|
||||||
|
*
|
||||||
|
* This does not increase the refcount of the device. Use eis_device_ref()
|
||||||
|
* to keep a reference beyond the immediate scope.
|
||||||
|
*/
|
||||||
|
struct eis_device *
|
||||||
|
eis_event_get_device(struct eis_event *event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_POINTER_MOTION return the x movement
|
||||||
|
* in 1/1000th of a logical pixel.
|
||||||
|
*/
|
||||||
|
int32_t
|
||||||
|
eis_event_pointer_get_x(struct eis_event_pointer *ptrev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_POINTER_MOTION return the y movement
|
||||||
|
* in 1/1000th of a logical pixel.
|
||||||
|
*/
|
||||||
|
int32_t
|
||||||
|
eis_event_pointer_get_y(struct eis_event_pointer *ptrev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_POINTER_MOTION_ABSOLUTE return the x
|
||||||
|
* position in 1/1000th of a logical pixel.
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
eis_event_pointer_get_absolute_x(struct eis_event_pointer *ptrev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_POINTER_MOTION_ABSOLUTE return the y
|
||||||
|
* position in 1/1000th of a logical pixel.
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
eis_event_pointer_get_absolute_y(struct eis_event_pointer *ptrev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_POINTER_BUTTON return the button
|
||||||
|
* index (starting at 1).
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
eis_event_pointer_get_button(struct eis_event_pointer *ptrev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_POINTER_BUTTON return true if the
|
||||||
|
* event is a button press, false for a release.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
eis_event_pointer_get_button_is_press(struct eis_event_pointer *ptrev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_POINTER_SCROLL return the x scroll
|
||||||
|
* distance in 1/1000th of a logical pixel.
|
||||||
|
*/
|
||||||
|
int32_t
|
||||||
|
eis_event_pointer_get_scroll_x(struct eis_event_pointer *ptrev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_POINTER_SCROLL return the y scroll
|
||||||
|
* distance in 1/1000th of a logical pixel.
|
||||||
|
*/
|
||||||
|
int32_t
|
||||||
|
eis_event_pointer_get_scroll_y(struct eis_event_pointer *ptrev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_POINTER_SCROLL_DISCRETE return the x
|
||||||
|
* scroll distance in fractions or multiples of 120.
|
||||||
|
*/
|
||||||
|
int32_t
|
||||||
|
eis_event_pointer_get_scroll_discrete_x(struct eis_event_pointer *ptrev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_POINTER_SCROLL_DISCRETE return the y
|
||||||
|
* scroll distance in fractions or multiples of 120.
|
||||||
|
*/
|
||||||
|
int32_t
|
||||||
|
eis_event_pointer_get_scroll_discrete_y(struct eis_event_pointer *ptrev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_KEYBOARD_KEY return the key code (as
|
||||||
|
* defined in include/linux/input-event-codes.h).
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
eis_event_keyboard_get_key(struct eis_event_keyboard *kbdev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_KEYBOARD_KEY return true if the
|
||||||
|
* event is a key down, false for a release.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
eis_event_keyboard_get_key_is_press(struct eis_event_keyboard *kbdev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_KEYBOARD_KEYMAP return the
|
||||||
|
* type of the keyamp.
|
||||||
|
*/
|
||||||
|
enum eis_keymap_type
|
||||||
|
eis_event_keyboard_get_keymap_type(struct eis_event_keyboard *kbdev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For an event of type @ref EIS_EVENT_KEYBOARD_KEYMAP return the
|
||||||
|
* memmap-able file descriptor to the keymap.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eis_event_keyboard_get_keymap(struct eis_event_keyboard *kbdev);
|
||||||
Loading…
Add table
Reference in a new issue