mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-25 21:00:07 +01:00
Change to use server-created devices
This changes the protocol so that it is the EIS implementation that creates devices within a seat. A client now "binds" to a seat and the EIS implementation creates devices matching the requested capabilities. A client can close a device if it no longer wants those but otherwise everything (including pointer ranges) is handled by the server. This is one giant patch because changes at the protocol level cannot easily be broken out into smaller patches. Some FIXMEs are left which will be handled in follow-up patches, e.g. the keymap handling is basically broken right now. Fixes #7 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
a5049c4b93
commit
2bb846696f
27 changed files with 1351 additions and 1773 deletions
169
meson.build
169
meson.build
|
|
@ -184,107 +184,104 @@ if get_option('portal')
|
|||
endif
|
||||
|
||||
# tests
|
||||
subproject('munit')
|
||||
if get_option('tests')
|
||||
subproject('munit')
|
||||
|
||||
munit = dependency('munit', fallback: ['munit', 'munit_dep'])
|
||||
munit = dependency('munit', fallback: ['munit', 'munit_dep'])
|
||||
|
||||
lib_unittest = static_library('unittest',
|
||||
'src/util-munit.h',
|
||||
'src/util-munit.c',
|
||||
dependencies: munit,
|
||||
)
|
||||
lib_unittest = static_library('unittest',
|
||||
'src/util-munit.h',
|
||||
'src/util-munit.c',
|
||||
dependencies: munit,
|
||||
)
|
||||
|
||||
dep_unittest = declare_dependency(
|
||||
link_with: lib_unittest,
|
||||
dependencies: munit
|
||||
)
|
||||
dep_unittest = declare_dependency(
|
||||
link_with: lib_unittest,
|
||||
dependencies: munit
|
||||
)
|
||||
|
||||
test('unit-tests-utils',
|
||||
executable('unit-tests-utils',
|
||||
'test/unit-tests.c',
|
||||
src_libutil,
|
||||
include_directories: 'src',
|
||||
c_args: ['-D_enable_tests_'],
|
||||
dependencies: [dep_unittest]))
|
||||
test('unit-tests-utils',
|
||||
executable('unit-tests-utils',
|
||||
'test/unit-tests.c',
|
||||
src_libutil,
|
||||
include_directories: 'src',
|
||||
c_args: ['-D_enable_tests_'],
|
||||
dependencies: [dep_unittest]))
|
||||
|
||||
test('unit-tests-ei',
|
||||
executable('unit-tests-ei',
|
||||
'test/unit-tests.c',
|
||||
src_libei,
|
||||
include_directories: 'src',
|
||||
c_args: ['-D_enable_tests_'],
|
||||
dependencies: deps_libei + [dep_unittest]))
|
||||
test('unit-tests-ei',
|
||||
executable('unit-tests-ei',
|
||||
'test/unit-tests.c',
|
||||
src_libei,
|
||||
include_directories: 'src',
|
||||
c_args: ['-D_enable_tests_'],
|
||||
dependencies: deps_libei + [dep_unittest]))
|
||||
|
||||
test('unit-tests-eis',
|
||||
executable('unit-tests-eis',
|
||||
'test/unit-tests.c',
|
||||
src_libeis,
|
||||
include_directories: 'src',
|
||||
c_args: ['-D_enable_tests_'],
|
||||
dependencies: [dep_unittest, dep_libutil, dep_protobuf]))
|
||||
test('unit-tests-eis',
|
||||
executable('unit-tests-eis',
|
||||
'test/unit-tests.c',
|
||||
src_libeis,
|
||||
include_directories: 'src',
|
||||
c_args: ['-D_enable_tests_'],
|
||||
dependencies: [dep_unittest, dep_libutil, dep_protobuf]))
|
||||
|
||||
lib_eierpecken = static_library('eierpecken',
|
||||
'test/eierpecken.h',
|
||||
'test/eierpecken.c',
|
||||
include_directories: 'src',
|
||||
dependencies: [munit, dep_libutil, dep_libei, dep_libeis],
|
||||
)
|
||||
lib_eierpecken = static_library('eierpecken',
|
||||
'test/eierpecken.h',
|
||||
'test/eierpecken.c',
|
||||
include_directories: 'src',
|
||||
dependencies: [munit, dep_libutil, dep_libei, dep_libeis],
|
||||
)
|
||||
|
||||
test('libei-integration-test',
|
||||
executable('eitest',
|
||||
'test/test-ei.c',
|
||||
link_with: lib_eierpecken,
|
||||
dependencies: [dep_unittest, dep_libei, dep_libeis]))
|
||||
test('libei-integration-test',
|
||||
executable('eitest',
|
||||
'test/test-main.c',
|
||||
'test/test-ei.c',
|
||||
'test/test-eis.c',
|
||||
link_with: lib_eierpecken,
|
||||
dependencies: [dep_unittest, dep_libei, dep_libeis]))
|
||||
|
||||
test('libeis-integration-test',
|
||||
executable('eistest',
|
||||
'test/test-eis.c',
|
||||
link_with: lib_eierpecken,
|
||||
dependencies: [dep_unittest, dep_libei, dep_libeis]))
|
||||
|
||||
|
||||
valgrind = find_program('valgrind', required : false)
|
||||
if valgrind.found()
|
||||
add_test_setup('valgrind',
|
||||
exe_wrapper : [ valgrind,
|
||||
'--leak-check=full',
|
||||
'--gen-suppressions=all',
|
||||
'--error-exitcode=3' ],
|
||||
timeout_multiplier : 100)
|
||||
else
|
||||
message('valgrind not found, disabling valgrind test suite')
|
||||
endif
|
||||
valgrind = find_program('valgrind', required : false)
|
||||
if valgrind.found()
|
||||
add_test_setup('valgrind',
|
||||
exe_wrapper : [ valgrind,
|
||||
'--leak-check=full',
|
||||
'--gen-suppressions=all',
|
||||
'--error-exitcode=3' ],
|
||||
timeout_multiplier : 100)
|
||||
else
|
||||
message('valgrind not found, disabling valgrind test suite')
|
||||
endif
|
||||
|
||||
|
||||
# build-test only
|
||||
executable('test-build-libei',
|
||||
'test/buildtest.c',
|
||||
dependencies : [dep_libei],
|
||||
include_directories : 'src',
|
||||
c_args : ['-Werror', '-DINCLUDE_LIBEI=1'],
|
||||
install : false)
|
||||
executable('test-build-libei',
|
||||
'test/buildtest.c',
|
||||
dependencies : [dep_libei],
|
||||
include_directories : 'src',
|
||||
c_args : ['-Werror', '-DINCLUDE_LIBEI=1'],
|
||||
install : false)
|
||||
|
||||
executable('test-build-libeis',
|
||||
'test/buildtest.c',
|
||||
dependencies : [dep_libeis],
|
||||
include_directories : 'src',
|
||||
c_args : ['-Werror', '-DINCLUDE_LIBEIS=1'],
|
||||
install : false)
|
||||
executable('test-build-libeis',
|
||||
'test/buildtest.c',
|
||||
dependencies : [dep_libeis],
|
||||
include_directories : 'src',
|
||||
c_args : ['-Werror', '-DINCLUDE_LIBEIS=1'],
|
||||
install : false)
|
||||
|
||||
executable('test-build-libreis',
|
||||
'test/buildtest.c',
|
||||
dependencies : [dep_libreis],
|
||||
include_directories : 'src',
|
||||
c_args : ['-Werror', '-DINCLUDE_LIBREIS=1'],
|
||||
install : false)
|
||||
executable('test-build-libreis',
|
||||
'test/buildtest.c',
|
||||
dependencies : [dep_libreis],
|
||||
include_directories : 'src',
|
||||
c_args : ['-Werror', '-DINCLUDE_LIBREIS=1'],
|
||||
install : false)
|
||||
|
||||
if add_languages('cpp', required: false)
|
||||
executable('test-build-cxx',
|
||||
'test/buildtest.cc',
|
||||
dependencies: [dep_libei, dep_libeis],
|
||||
include_directories: 'src',
|
||||
install: false)
|
||||
endif
|
||||
if add_languages('cpp', required: false)
|
||||
executable('test-build-cxx',
|
||||
'test/buildtest.cc',
|
||||
dependencies: [dep_libei, dep_libeis],
|
||||
include_directories: 'src',
|
||||
install: false)
|
||||
endif
|
||||
endif # tests
|
||||
|
||||
configure_file(output: 'config.h', configuration: config_h)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
option('portal', type: 'boolean', value: 'true', description: 'Enable/disable org.freedesktop.portal support')
|
||||
option('documentation', type: 'boolean', value: 'true', description: 'Enable/disable building the API documentation')
|
||||
option('tests', type: 'boolean', value: 'true', description: 'Enable/disable tests')
|
||||
|
|
|
|||
|
|
@ -16,24 +16,16 @@ syntax = "proto3";
|
|||
* 2.a - server replies with "Connected" or
|
||||
* 2.b - server replies with "Disconnected" and closes its end of the socket
|
||||
* 3. - server sends "AddSeat" (once or multiple times)
|
||||
* 4. - client sends "AddDevice" for a specific seat
|
||||
* 4.a - server replies with "DeviceAdded" or
|
||||
* 4.b - server replies with "DeviceRemoved"
|
||||
* 4. - client sends "BindSeat" for each seat
|
||||
* 5. - server sends "DeviceAdded" for any device on this seat
|
||||
* 5. - server sends "DeviceResumed"
|
||||
* 6. - client sends "PointerRelative" or any other event
|
||||
* 7. - client sends "RemoveDevice"
|
||||
* 7. - client sends "CloseDevice"
|
||||
* 8. - client sends "Disconnect" and closes its end of the socket
|
||||
*
|
||||
* The server may send Disconnect at any time.
|
||||
* The server may send Removed for a device at any time after that device's
|
||||
* Accepted.
|
||||
*
|
||||
* Where a server does not accept a client's device it is up to the client
|
||||
* to decide whether to Disconnect.
|
||||
* Where a server does not accept a client's device the server may send Removed
|
||||
* for all current client devices and send Disconnected before closing the
|
||||
* connection. IOW a client trying to create a device may result in the
|
||||
* client being disconnected. This decision is up to server policy.
|
||||
* The server may send SeatRemoved for a device at any time.
|
||||
* The server may send DeviceRemoved for a device at any time.
|
||||
*
|
||||
* Where a connection error occurs, the library (libei or libeis) will
|
||||
* unroll the state as seen from the API. i.e.
|
||||
|
|
@ -81,21 +73,16 @@ message Connect {
|
|||
message Disconnect {
|
||||
}
|
||||
|
||||
message AddDevice {
|
||||
uint32 deviceid = 1;
|
||||
message BindSeat {
|
||||
uint32 seatid = 1;
|
||||
uint32 capabilities = 2;
|
||||
uint32 pointer_width = 3;
|
||||
uint32 pointer_height = 4;
|
||||
uint32 touch_width = 5;
|
||||
uint32 touch_height = 6;
|
||||
/* keymap is passed as fd if type is not none */
|
||||
uint32 keymap_type = 8;
|
||||
uint32 keymap_size = 9;
|
||||
string name = 10;
|
||||
uint32 seat = 11;
|
||||
}
|
||||
|
||||
message RemoveDevice {
|
||||
message UnbindSeat {
|
||||
uint32 seatid = 1;
|
||||
}
|
||||
|
||||
message CloseDevice {
|
||||
uint32 deviceid = 1;
|
||||
}
|
||||
|
||||
|
|
@ -148,17 +135,18 @@ message ClientMessage {
|
|||
oneof msg {
|
||||
Connect connect = 1;
|
||||
Disconnect disconnect = 2;
|
||||
AddDevice add_device = 3;
|
||||
RemoveDevice remove_device = 4;
|
||||
PointerRelative rel = 5;
|
||||
PointerAbsolute abs = 6;
|
||||
Scroll scroll = 7;
|
||||
ScrollDiscrete disc = 8;
|
||||
PointerButton button = 9;
|
||||
KeyboardKey key = 10;
|
||||
Touch touch = 11;
|
||||
ConfigureName configure_name = 12;
|
||||
ConfigureCapabilities configure_caps = 13;
|
||||
BindSeat bind_seat = 3;
|
||||
UnbindSeat unbind_seat = 4;
|
||||
CloseDevice close_device = 5;
|
||||
PointerRelative rel = 6;
|
||||
PointerAbsolute abs = 7;
|
||||
Scroll scroll = 8;
|
||||
ScrollDiscrete disc = 9;
|
||||
PointerButton button = 10;
|
||||
KeyboardKey key = 11;
|
||||
Touch touch = 12;
|
||||
ConfigureName configure_name = 13;
|
||||
ConfigureCapabilities configure_caps = 14;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -187,6 +175,10 @@ message DeviceAdded {
|
|||
uint32 keymap_size = 5;
|
||||
string name = 6;
|
||||
uint32 seatid = 7;
|
||||
uint32 pointer_width = 8;
|
||||
uint32 pointer_height = 9;
|
||||
uint32 touch_width = 10;
|
||||
uint32 touch_height = 11;
|
||||
}
|
||||
|
||||
message DeviceRemoved {
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ static const char *
|
|||
ei_device_state_to_string(enum ei_device_state state)
|
||||
{
|
||||
switch (state) {
|
||||
CASE_RETURN_STRING(EI_DEVICE_STATE_NEW);
|
||||
CASE_RETURN_STRING(EI_DEVICE_STATE_CONNECTING);
|
||||
CASE_RETURN_STRING(EI_DEVICE_STATE_SUSPENDED);
|
||||
CASE_RETURN_STRING(EI_DEVICE_STATE_RESUMED);
|
||||
CASE_RETURN_STRING(EI_DEVICE_STATE_REMOVED_FROM_CLIENT);
|
||||
|
|
@ -100,93 +98,29 @@ ei_device_get_context(struct ei_device *device)
|
|||
return ei_seat_get_context(ei_device_get_seat(device));
|
||||
}
|
||||
|
||||
_public_ struct ei_device *
|
||||
ei_device_new(struct ei_seat *seat)
|
||||
struct ei_device *
|
||||
ei_device_new(struct ei_seat *seat, uint32_t deviceid)
|
||||
{
|
||||
/* device IDs are managed by the client, the server merely accepts
|
||||
* them and fails where they're being reused. */
|
||||
static uint32_t deviceid = 0;
|
||||
struct ei_device *device = ei_device_create(&seat->object);
|
||||
|
||||
device->capabilities = 0;
|
||||
device->id = seat->id | ++deviceid;
|
||||
device->state = EI_DEVICE_STATE_NEW;
|
||||
device->id = deviceid;
|
||||
device->state = EI_DEVICE_STATE_SUSPENDED;
|
||||
device->name = xaprintf("unnamed device %d", device->id);
|
||||
|
||||
/* We have a ref to the seat to make sure our seat doesn't get
|
||||
* destroyed while a ref to the device is still alive.
|
||||
* And the seat has a ref to the device, dropped when the device
|
||||
* state changes to DEAD (ei_device_remove()).
|
||||
* And the seat has a ref to the device in the seat->devices list.
|
||||
* dropped when the device state changes to DEAD (ei_device_remove()).
|
||||
*/
|
||||
ei_seat_ref(seat);
|
||||
ei_device_ref(device);
|
||||
|
||||
/* this list "owns" the ref for this device */
|
||||
list_append(&seat->devices, &device->link);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_device_configure_name(struct ei_device *device, const char *name)
|
||||
{
|
||||
if (device->state != EI_DEVICE_STATE_NEW)
|
||||
return;
|
||||
|
||||
free(device->name);
|
||||
device->name = xstrdup(name);
|
||||
}
|
||||
|
||||
_public_ bool
|
||||
ei_device_configure_capability(struct ei_device *device,
|
||||
enum ei_device_capability cap)
|
||||
{
|
||||
if (device->state != EI_DEVICE_STATE_NEW)
|
||||
return false;
|
||||
|
||||
switch (cap) {
|
||||
case EI_DEVICE_CAP_POINTER:
|
||||
case EI_DEVICE_CAP_POINTER_ABSOLUTE:
|
||||
case EI_DEVICE_CAP_KEYBOARD:
|
||||
case EI_DEVICE_CAP_TOUCH:
|
||||
device->capabilities |= bit(cap);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_device_pointer_configure_range(struct ei_device *device,
|
||||
uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
if (device->state != EI_DEVICE_STATE_NEW ||
|
||||
!flag_is_set(device->capabilities, EI_DEVICE_CAP_POINTER_ABSOLUTE))
|
||||
return;
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
device->abs.dim.width = width;
|
||||
device->abs.dim.height = height;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_device_touch_configure_range(struct ei_device *device,
|
||||
uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
if (device->state != EI_DEVICE_STATE_NEW ||
|
||||
!flag_is_set(device->capabilities, EI_DEVICE_CAP_TOUCH))
|
||||
return;
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
device->touch.dim.width = width;
|
||||
device->touch.dim.height = height;
|
||||
}
|
||||
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_REF(ei_keymap);
|
||||
_public_
|
||||
|
|
@ -227,12 +161,6 @@ ei_device_keyboard_configure_keymap(struct ei_device *device,
|
|||
return;
|
||||
}
|
||||
|
||||
if (device->state != EI_DEVICE_STATE_NEW) {
|
||||
log_bug_client(ei_device_get_context(device),
|
||||
"%s: Device has already been added\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Can only call this once */
|
||||
if (device->keymap) {
|
||||
log_bug_client(ei_device_get_context(device),
|
||||
|
|
@ -307,69 +235,19 @@ ei_device_set_keymap(struct ei_device *device,
|
|||
device->keymap = ei_keymap_ref(keymap);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_device_add(struct ei_device *device)
|
||||
{
|
||||
struct ei_seat *seat = ei_device_get_seat(device);
|
||||
|
||||
switch (device->state) {
|
||||
case EI_DEVICE_STATE_NEW:
|
||||
/* If the caller tries to add a device to a seat that has
|
||||
* been removed, immediately drop that device. But since our
|
||||
* SEAT_REMOVED event may still be in the queue, prepend the
|
||||
* device to the rest of the queue.
|
||||
*/
|
||||
if (seat->state == EI_SEAT_STATE_REMOVED) {
|
||||
ei_insert_device_removed_event(device);
|
||||
ei_device_set_state(device, EI_DEVICE_STATE_DEAD);
|
||||
ei_device_unref(device);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case EI_DEVICE_STATE_REMOVED_FROM_CLIENT:
|
||||
case EI_DEVICE_STATE_REMOVED_FROM_SERVER:
|
||||
case EI_DEVICE_STATE_CONNECTING:
|
||||
case EI_DEVICE_STATE_SUSPENDED:
|
||||
case EI_DEVICE_STATE_RESUMED:
|
||||
case EI_DEVICE_STATE_DEAD:
|
||||
log_bug_client(ei_device_get_context(device),
|
||||
"%s: device %s added twice by client\n",
|
||||
__func__, device->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ei_device_has_capability(device, EI_DEVICE_CAP_POINTER_ABSOLUTE) &&
|
||||
(device->abs.dim.width == 0 || device->abs.dim.height == 0))
|
||||
log_bug_client(ei_device_get_context(device),
|
||||
"%s: device %s is missing an abs pointer range\n",
|
||||
__func__, device->name);
|
||||
|
||||
if (ei_send_add_device(device) == 0)
|
||||
ei_device_set_state(device, EI_DEVICE_STATE_CONNECTING);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_device_remove(struct ei_device *device)
|
||||
ei_device_close(struct ei_device *device)
|
||||
{
|
||||
switch (device->state) {
|
||||
case EI_DEVICE_STATE_NEW:
|
||||
ei_device_set_state(device, EI_DEVICE_STATE_DEAD);
|
||||
ei_device_unref(device);
|
||||
break;
|
||||
case EI_DEVICE_STATE_DEAD:
|
||||
case EI_DEVICE_STATE_REMOVED_FROM_CLIENT:
|
||||
break;
|
||||
case EI_DEVICE_STATE_REMOVED_FROM_SERVER:
|
||||
/* device is properly dead now */
|
||||
ei_device_set_state(device, EI_DEVICE_STATE_DEAD);
|
||||
ei_send_remove_device(device);
|
||||
ei_device_unref(device);
|
||||
break;
|
||||
case EI_DEVICE_STATE_CONNECTING:
|
||||
case EI_DEVICE_STATE_SUSPENDED:
|
||||
case EI_DEVICE_STATE_RESUMED:
|
||||
ei_device_set_state(device, EI_DEVICE_STATE_REMOVED_FROM_CLIENT);
|
||||
ei_send_remove_device(device);
|
||||
ei_send_close_device(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -378,27 +256,20 @@ void
|
|||
ei_device_removed_by_server(struct ei_device *device)
|
||||
{
|
||||
switch (device->state) {
|
||||
case EI_DEVICE_STATE_NEW:
|
||||
case EI_DEVICE_STATE_DEAD:
|
||||
case EI_DEVICE_STATE_REMOVED_FROM_SERVER:
|
||||
break;
|
||||
case EI_DEVICE_STATE_REMOVED_FROM_CLIENT:
|
||||
/* device is properly dead now */
|
||||
ei_queue_device_removed_event(device);
|
||||
ei_device_set_state(device, EI_DEVICE_STATE_DEAD);
|
||||
ei_device_unref(device);
|
||||
break;
|
||||
case EI_DEVICE_STATE_CONNECTING:
|
||||
/* Device never seen by server, but our client still thinks
|
||||
* it's there */
|
||||
ei_queue_device_removed_event(device);
|
||||
ei_device_set_state(device, EI_DEVICE_STATE_DEAD);
|
||||
ei_device_unref(device);
|
||||
break;
|
||||
case EI_DEVICE_STATE_SUSPENDED:
|
||||
case EI_DEVICE_STATE_RESUMED:
|
||||
ei_queue_device_removed_event(device);
|
||||
ei_device_set_state(device, EI_DEVICE_STATE_REMOVED_FROM_SERVER);
|
||||
ei_device_set_state(device, EI_DEVICE_STATE_DEAD);
|
||||
/* This should be the last ref to the device that libei has
|
||||
* (not counting any queued events). Device is still in the
|
||||
* seat->device list, will be removed from that when all
|
||||
* remaining refs are at 0.
|
||||
*/
|
||||
ei_device_unref(device); /* the ref in the seat list */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -435,6 +306,20 @@ ei_device_set_capabilities(struct ei_device *device,
|
|||
device->capabilities = capabilities;
|
||||
}
|
||||
|
||||
void
|
||||
ei_device_set_pointer_range(struct ei_device *device, uint32_t w, uint32_t h)
|
||||
{
|
||||
device->abs.dim.width = w;
|
||||
device->abs.dim.height = h;
|
||||
}
|
||||
|
||||
void
|
||||
ei_device_set_touch_range(struct ei_device *device, uint32_t w, uint32_t h)
|
||||
{
|
||||
device->touch.dim.width = w;
|
||||
device->touch.dim.height = h;
|
||||
}
|
||||
|
||||
_public_ bool
|
||||
ei_device_has_capability(struct ei_device *device,
|
||||
enum ei_device_capability cap)
|
||||
|
|
@ -664,196 +549,3 @@ ei_touch_up(struct ei_touch *touch)
|
|||
touch->state = TOUCH_IS_UP;
|
||||
ei_send_touch_up(touch->device, touch->tracking_id);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _enable_tests_
|
||||
#include "src/util-munit.h"
|
||||
#include "src/util-memfile.h"
|
||||
|
||||
#define FAKE_SEAT(_seat) \
|
||||
struct ei ei_##__LINE__ = { 0 }; \
|
||||
struct ei_seat seat_##__LINE__ = { \
|
||||
.object = { \
|
||||
.parent = &ei_##__LINE__.object, \
|
||||
.refcount = 1, \
|
||||
}, \
|
||||
.id = __LINE__ << 16, \
|
||||
.capabilities = ~0, \
|
||||
.name = "default", \
|
||||
}; \
|
||||
list_init(&seat_##__LINE__.link); \
|
||||
list_init(&seat_##__LINE__.devices); \
|
||||
list_init(&seat_##__LINE__.devices_pending); \
|
||||
struct ei_seat *_seat = &seat_ ## __LINE__;
|
||||
|
||||
MUNIT_TEST(test_device_new)
|
||||
{
|
||||
FAKE_SEAT(seat);
|
||||
struct ei_device *d = ei_device_new(seat);
|
||||
|
||||
munit_assert_int(d->id, >, 0);
|
||||
munit_assert_int(d->capabilities, ==, 0);
|
||||
munit_assert_int(d->state, ==, EI_DEVICE_STATE_NEW);
|
||||
|
||||
struct ei_device *unrefd = ei_device_unref(d);
|
||||
munit_assert_ptr_null(unrefd);
|
||||
|
||||
ei_device_remove(d);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_device_ids)
|
||||
{
|
||||
FAKE_SEAT(seat);
|
||||
_unref_(ei_device) *d1 = ei_device_new(seat);
|
||||
_unref_(ei_device) *d2 = ei_device_new(seat);
|
||||
_unref_(ei_device) *d3 = ei_device_new(seat);
|
||||
|
||||
munit_assert_int(d1->id, <, d2->id);
|
||||
munit_assert_int(d1->id, <, d3->id);
|
||||
munit_assert_int(d2->id, <, d3->id);
|
||||
|
||||
ei_device_remove(d1);
|
||||
ei_device_remove(d2);
|
||||
ei_device_remove(d3);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_device_ref_unref)
|
||||
{
|
||||
FAKE_SEAT(seat);
|
||||
struct ei_device *d = ei_device_new(seat);
|
||||
|
||||
munit_assert_int(d->object.refcount, ==, 2);
|
||||
|
||||
struct ei_device *refd = ei_device_ref(d);
|
||||
munit_assert_ptr_equal(d, refd);
|
||||
munit_assert_int(d->object.refcount, ==, 3);
|
||||
|
||||
struct ei_device *unrefd = ei_device_unref(d);
|
||||
munit_assert_ptr_null(unrefd);
|
||||
munit_assert_int(d->object.refcount, ==, 2);
|
||||
|
||||
ei_device_remove(d);
|
||||
munit_assert_int(d->object.refcount, ==, 1);
|
||||
|
||||
unrefd = ei_device_unref(d);
|
||||
munit_assert_ptr_null(unrefd);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_device_cap)
|
||||
{
|
||||
FAKE_SEAT(seat);
|
||||
_unref_(ei_device) *d = ei_device_new(seat);
|
||||
|
||||
munit_assert(ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER));
|
||||
/* twice is fine */
|
||||
munit_assert(ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER));
|
||||
munit_assert(ei_device_has_capability(d, EI_DEVICE_CAP_POINTER));
|
||||
|
||||
munit_assert(ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert(ei_device_has_capability(d, EI_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
|
||||
munit_assert(ei_device_configure_capability(d, EI_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert(ei_device_has_capability(d, EI_DEVICE_CAP_KEYBOARD));
|
||||
|
||||
munit_assert(ei_device_configure_capability(d, EI_DEVICE_CAP_TOUCH));
|
||||
munit_assert(ei_device_has_capability(d, EI_DEVICE_CAP_TOUCH));
|
||||
|
||||
/* Invalid caps */
|
||||
munit_assert(!ei_device_configure_capability(d, 0));
|
||||
munit_assert(!ei_device_has_capability(d, 0));
|
||||
munit_assert(!ei_device_configure_capability(d, EI_DEVICE_CAP_TOUCH + 1));
|
||||
munit_assert(!ei_device_has_capability(d, EI_DEVICE_CAP_TOUCH + 1));
|
||||
|
||||
ei_device_remove(d);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_device_get_seat)
|
||||
{
|
||||
FAKE_SEAT(seat);
|
||||
_unref_(ei_device) *d = ei_device_new(seat);
|
||||
|
||||
munit_assert_ptr_equal(d->object.parent, seat);
|
||||
munit_assert_ptr_equal(ei_device_get_seat(d), seat);
|
||||
|
||||
ei_device_remove(d);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_device_pointer_ranges)
|
||||
{
|
||||
FAKE_SEAT(seat);
|
||||
_unref_(ei_device) *d = ei_device_new(seat);
|
||||
|
||||
/* Missing the cap */
|
||||
ei_device_pointer_configure_range(d, 1920, 1200);
|
||||
munit_assert_int(ei_device_pointer_get_width(d), ==, 0);
|
||||
munit_assert_int(ei_device_pointer_get_height(d), ==, 0);
|
||||
|
||||
munit_assert(ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
|
||||
ei_device_pointer_configure_range(d, 1024, 768);
|
||||
munit_assert_int(ei_device_pointer_get_width(d), ==, 1024);
|
||||
munit_assert_int(ei_device_pointer_get_height(d), ==, 768);
|
||||
|
||||
/* Twice is fine before adding the device */
|
||||
ei_device_pointer_configure_range(d, 640, 480);
|
||||
munit_assert_int(ei_device_pointer_get_width(d), ==, 640);
|
||||
munit_assert_int(ei_device_pointer_get_height(d), ==, 480);
|
||||
|
||||
/* But zero is silently rejected */
|
||||
ei_device_pointer_configure_range(d, 0, 480);
|
||||
munit_assert_int(ei_device_pointer_get_width(d), ==, 640);
|
||||
munit_assert_int(ei_device_pointer_get_height(d), ==, 480);
|
||||
ei_device_pointer_configure_range(d, 640, 0);
|
||||
munit_assert_int(ei_device_pointer_get_width(d), ==, 640);
|
||||
munit_assert_int(ei_device_pointer_get_height(d), ==, 480);
|
||||
|
||||
ei_device_remove(d);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_device_touch_ranges)
|
||||
{
|
||||
FAKE_SEAT(seat);
|
||||
_unref_(ei_device) *d = ei_device_new(seat);
|
||||
|
||||
/* Missing the cap */
|
||||
ei_device_touch_configure_range(d, 1920, 1200);
|
||||
munit_assert_int(ei_device_touch_get_width(d), ==, 0);
|
||||
munit_assert_int(ei_device_touch_get_height(d), ==, 0);
|
||||
|
||||
munit_assert(ei_device_configure_capability(d, EI_DEVICE_CAP_TOUCH));
|
||||
|
||||
ei_device_touch_configure_range(d, 1024, 768);
|
||||
munit_assert_int(ei_device_touch_get_width(d), ==, 1024);
|
||||
munit_assert_int(ei_device_touch_get_height(d), ==, 768);
|
||||
|
||||
/* Twice is fine before adding the device */
|
||||
ei_device_touch_configure_range(d, 640, 480);
|
||||
munit_assert_int(ei_device_touch_get_width(d), ==, 640);
|
||||
munit_assert_int(ei_device_touch_get_height(d), ==, 480);
|
||||
|
||||
/* But zero is silently rejected */
|
||||
ei_device_touch_configure_range(d, 0, 480);
|
||||
munit_assert_int(ei_device_touch_get_width(d), ==, 640);
|
||||
munit_assert_int(ei_device_touch_get_height(d), ==, 480);
|
||||
ei_device_touch_configure_range(d, 640, 0);
|
||||
munit_assert_int(ei_device_touch_get_width(d), ==, 640);
|
||||
munit_assert_int(ei_device_touch_get_height(d), ==, 480);
|
||||
|
||||
ei_device_remove(d);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -65,7 +65,9 @@ struct ei {
|
|||
};
|
||||
|
||||
enum ei_seat_state {
|
||||
EI_SEAT_STATE_PRESENT,
|
||||
EI_SEAT_STATE_NEW,
|
||||
EI_SEAT_STATE_BOUND,
|
||||
EI_SEAT_STATE_UNBOUND,
|
||||
EI_SEAT_STATE_REMOVED,
|
||||
};
|
||||
|
||||
|
|
@ -74,17 +76,14 @@ struct ei_seat {
|
|||
void *user_data;
|
||||
struct list link;
|
||||
enum ei_seat_state state;
|
||||
/* devices created by client but not yet added */
|
||||
struct list devices_pending;
|
||||
struct list devices;
|
||||
uint32_t id;
|
||||
uint32_t capabilities;
|
||||
uint32_t capabilities_mask;
|
||||
char *name;
|
||||
};
|
||||
|
||||
enum ei_device_state {
|
||||
EI_DEVICE_STATE_NEW,
|
||||
EI_DEVICE_STATE_CONNECTING,
|
||||
EI_DEVICE_STATE_SUSPENDED,
|
||||
EI_DEVICE_STATE_RESUMED,
|
||||
/**
|
||||
|
|
@ -175,10 +174,13 @@ void
|
|||
ei_seat_drop(struct ei_seat *seat);
|
||||
|
||||
int
|
||||
ei_send_add_device(struct ei_device *device);
|
||||
ei_send_seat_bind(struct ei_seat *seat, uint32_t capabilities);
|
||||
|
||||
int
|
||||
ei_send_remove_device(struct ei_device *device);
|
||||
ei_send_seat_unbind(struct ei_seat *seat);
|
||||
|
||||
int
|
||||
ei_send_close_device(struct ei_device *device);
|
||||
|
||||
void
|
||||
ei_queue_device_removed_event(struct ei_device *device);
|
||||
|
|
@ -189,6 +191,9 @@ ei_insert_device_removed_event(struct ei_device *device);
|
|||
void
|
||||
ei_queue_seat_removed_event(struct ei_seat *seat);
|
||||
|
||||
struct ei_device *
|
||||
ei_device_new(struct ei_seat *seat, uint32_t deviceid);
|
||||
|
||||
void
|
||||
ei_device_removed_by_server(struct ei_device *device);
|
||||
|
||||
|
|
@ -243,6 +248,10 @@ ei_device_set_seat(struct ei_device *device, const char *seat);
|
|||
void
|
||||
ei_device_set_capabilities(struct ei_device *device,
|
||||
uint32_t capabilities);
|
||||
void
|
||||
ei_device_set_pointer_range(struct ei_device *device, uint32_t w, uint32_t h);
|
||||
void
|
||||
ei_device_set_touch_range(struct ei_device *device, uint32_t w, uint32_t h);
|
||||
|
||||
void
|
||||
ei_device_set_keymap(struct ei_device *device,
|
||||
|
|
|
|||
|
|
@ -113,6 +113,10 @@ ei_proto_parse_message(struct brei_message *bmsg, size_t *consumed)
|
|||
.device_added.keymap_from_server = a->keymap_from_server,
|
||||
.device_added.keymap_size = a->keymap_size,
|
||||
.device_added.seatid = a->seatid,
|
||||
.device_added.pointer_width = a->pointer_width,
|
||||
.device_added.pointer_height = a->pointer_height,
|
||||
.device_added.touch_width = a->touch_width,
|
||||
.device_added.touch_height = a->touch_height,
|
||||
};
|
||||
if (a->keymap_type && a->keymap_from_server)
|
||||
msg->device_added.keymap_fd = brei_message_take_fd(bmsg);
|
||||
|
|
@ -166,8 +170,9 @@ log_wire_message(struct ei *ei, const ClientMessage *msg, int error)
|
|||
abort();
|
||||
MSG_STRING_CASE(CONNECT);
|
||||
MSG_STRING_CASE(DISCONNECT);
|
||||
MSG_STRING_CASE(ADD_DEVICE);
|
||||
MSG_STRING_CASE(REMOVE_DEVICE);
|
||||
MSG_STRING_CASE(BIND_SEAT);
|
||||
MSG_STRING_CASE(UNBIND_SEAT);
|
||||
MSG_STRING_CASE(CLOSE_DEVICE);
|
||||
MSG_STRING_CASE(REL);
|
||||
MSG_STRING_CASE(ABS);
|
||||
MSG_STRING_CASE(BUTTON);
|
||||
|
|
@ -206,7 +211,7 @@ ei_proto_send_msg(struct ei *ei, const ClientMessage *msg)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
_unused_ static int
|
||||
ei_proto_send_msg_with_fds(struct ei *ei, const ClientMessage *msg, int *fds)
|
||||
{
|
||||
size_t msglen = client_message__get_packed_size(msg);
|
||||
|
|
@ -250,47 +255,44 @@ ei_proto_send_disconnect(struct ei *ei)
|
|||
}
|
||||
|
||||
int
|
||||
ei_proto_send_add(struct ei *ei, struct ei_device *device)
|
||||
ei_proto_send_bind_seat(struct ei *ei, struct ei_seat *seat, uint32_t capabilities)
|
||||
{
|
||||
ClientMessage msg = CLIENT_MESSAGE__INIT;
|
||||
AddDevice add = ADD_DEVICE__INIT;
|
||||
struct ei_seat *seat = ei_device_get_seat(device);
|
||||
BindSeat bind = BIND_SEAT__INIT;
|
||||
|
||||
add.deviceid = device->id;
|
||||
add.name = device->name;
|
||||
add.capabilities = device->capabilities;
|
||||
add.pointer_width = device->abs.dim.width;
|
||||
add.pointer_height = device->abs.dim.height;
|
||||
add.touch_width = device->touch.dim.width;
|
||||
add.touch_height = device->touch.dim.height;
|
||||
add.keymap_type = 0;
|
||||
bind.seatid = seat->id;
|
||||
bind.capabilities = capabilities;
|
||||
|
||||
int fd[2] = {-1, -1};
|
||||
msg.bind_seat = &bind;
|
||||
msg.msg_case = CLIENT_MESSAGE__MSG_BIND_SEAT;
|
||||
|
||||
struct ei_keymap *keymap = device->keymap;
|
||||
if (keymap) {
|
||||
add.keymap_type = ei_keymap_get_type(keymap);
|
||||
add.keymap_size = ei_keymap_get_size(keymap);
|
||||
fd[0] = ei_keymap_get_fd(keymap);
|
||||
}
|
||||
add.seat = seat->id;
|
||||
|
||||
msg.add_device = &add;
|
||||
msg.msg_case = CLIENT_MESSAGE__MSG_ADD_DEVICE;
|
||||
|
||||
return ei_proto_send_msg_with_fds(ei, &msg, fd);
|
||||
return ei_proto_send_msg(ei, &msg);
|
||||
}
|
||||
|
||||
int
|
||||
ei_proto_send_remove(struct ei *ei, struct ei_device *device)
|
||||
ei_proto_send_unbind_seat(struct ei *ei, struct ei_seat *seat)
|
||||
{
|
||||
ClientMessage msg = CLIENT_MESSAGE__INIT;
|
||||
RemoveDevice remove = REMOVE_DEVICE__INIT;
|
||||
UnbindSeat unbind = UNBIND_SEAT__INIT;
|
||||
|
||||
remove.deviceid = device->id;
|
||||
unbind.seatid = seat->id;
|
||||
|
||||
msg.remove_device = &remove;
|
||||
msg.msg_case = CLIENT_MESSAGE__MSG_REMOVE_DEVICE;
|
||||
msg.unbind_seat = &unbind;
|
||||
msg.msg_case = CLIENT_MESSAGE__MSG_UNBIND_SEAT;
|
||||
|
||||
return ei_proto_send_msg(ei, &msg);
|
||||
}
|
||||
|
||||
int
|
||||
ei_proto_send_close_device(struct ei *ei, struct ei_device *device)
|
||||
{
|
||||
ClientMessage msg = CLIENT_MESSAGE__INIT;
|
||||
CloseDevice close = CLOSE_DEVICE__INIT;
|
||||
|
||||
close.deviceid = device->id;
|
||||
|
||||
msg.close_device = &close;
|
||||
msg.msg_case = CLIENT_MESSAGE__MSG_CLOSE_DEVICE;
|
||||
|
||||
return ei_proto_send_msg(ei, &msg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,10 @@ struct message {
|
|||
int keymap_fd;
|
||||
size_t keymap_size;
|
||||
uint32_t seatid;
|
||||
uint32_t pointer_width;
|
||||
uint32_t pointer_height;
|
||||
uint32_t touch_width;
|
||||
uint32_t touch_height;
|
||||
} device_added;
|
||||
struct message_device_removed {
|
||||
uint32_t deviceid;
|
||||
|
|
@ -116,7 +120,13 @@ int
|
|||
ei_proto_send_add(struct ei *ei, struct ei_device *device);
|
||||
|
||||
int
|
||||
ei_proto_send_remove(struct ei *ei, struct ei_device *device);
|
||||
ei_proto_send_bind_seat(struct ei *ei, struct ei_seat *seat, uint32_t capabilities);
|
||||
|
||||
int
|
||||
ei_proto_send_unbind_seat(struct ei *ei, struct ei_seat *seat);
|
||||
|
||||
int
|
||||
ei_proto_send_close_device(struct ei *ei, struct ei_device *device);
|
||||
|
||||
int
|
||||
ei_proto_send_rel(struct ei *ei, struct ei_device *device,
|
||||
|
|
|
|||
|
|
@ -65,10 +65,11 @@ ei_seat_new(struct ei *ei, uint32_t id, const char *name, uint32_t capabilities)
|
|||
{
|
||||
struct ei_seat *seat = ei_seat_create(&ei->object);
|
||||
|
||||
seat->state = EI_SEAT_STATE_PRESENT;
|
||||
seat->state = EI_SEAT_STATE_NEW;
|
||||
seat->name = xstrdup(name);
|
||||
seat->id = id;
|
||||
seat->capabilities = capabilities;
|
||||
seat->capabilities_mask = ~0; /* Masked out by client */
|
||||
|
||||
list_init(&seat->devices);
|
||||
list_init(&seat->link);
|
||||
|
|
@ -92,7 +93,7 @@ ei_seat_remove(struct ei_seat *seat)
|
|||
* need to clean this up in the library */
|
||||
list_for_each_safe(d, tmp, &seat->devices, link) {
|
||||
/* remove the device */
|
||||
ei_device_remove(d);
|
||||
ei_device_close(d);
|
||||
/* And pretend to process the removed message from
|
||||
* the server */
|
||||
ei_device_removed_by_server(d);
|
||||
|
|
@ -121,3 +122,41 @@ ei_seat_find_device(struct ei_seat *seat, uint32_t deviceid)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_seat_drop_capability(struct ei_seat *seat,
|
||||
enum ei_device_capability cap)
|
||||
{
|
||||
if (seat->state == EI_SEAT_STATE_NEW)
|
||||
flag_clear(seat->capabilities_mask, cap);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_seat_bind(struct ei_seat *seat)
|
||||
{
|
||||
if (seat->state != EI_SEAT_STATE_NEW)
|
||||
return;
|
||||
|
||||
ei_send_seat_bind(seat, seat->capabilities & seat->capabilities_mask);
|
||||
seat->state = EI_SEAT_STATE_BOUND;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
ei_seat_unbind(struct ei_seat *seat)
|
||||
{
|
||||
switch (seat->state) {
|
||||
case EI_SEAT_STATE_NEW:
|
||||
case EI_SEAT_STATE_BOUND:
|
||||
break;
|
||||
case EI_SEAT_STATE_UNBOUND:
|
||||
case EI_SEAT_STATE_REMOVED:
|
||||
return;
|
||||
}
|
||||
|
||||
struct ei_device *device;
|
||||
list_for_each(device, &seat->devices, link) {
|
||||
ei_device_close(device);
|
||||
}
|
||||
ei_send_seat_unbind(seat);
|
||||
seat->state = EI_SEAT_STATE_UNBOUND;
|
||||
}
|
||||
|
|
|
|||
101
src/libei.c
101
src/libei.c
|
|
@ -90,7 +90,7 @@ OBJECT_IMPLEMENT_GETTER(ei_event, device, struct ei_device*);
|
|||
_public_ struct ei_seat *
|
||||
ei_event_get_seat(struct ei_event *event)
|
||||
{
|
||||
return event->device ? ei_device_get_seat(event->device) : event->seat;
|
||||
return event->seat;
|
||||
}
|
||||
|
||||
static struct ei_seat *
|
||||
|
|
@ -254,6 +254,7 @@ queue_device_added_event(struct ei_device *device)
|
|||
|
||||
struct ei_event *e = ei_event_create(&ei->object);
|
||||
e->type = EI_EVENT_DEVICE_ADDED;
|
||||
e->seat = ei_seat_ref(ei_device_get_seat(device));
|
||||
e->device = ei_device_ref(device);
|
||||
|
||||
queue_event(ei, e);
|
||||
|
|
@ -266,6 +267,7 @@ queue_device_removed_event(struct ei_device *device)
|
|||
|
||||
struct ei_event *e = ei_event_create(&ei->object);
|
||||
e->type = EI_EVENT_DEVICE_REMOVED;
|
||||
e->seat = ei_seat_ref(ei_device_get_seat(device));
|
||||
e->device = ei_device_ref(device);
|
||||
|
||||
queue_event(ei, e);
|
||||
|
|
@ -278,6 +280,7 @@ insert_device_removed_event(struct ei_device *device)
|
|||
|
||||
struct ei_event *e = ei_event_create(&ei->object);
|
||||
e->type = EI_EVENT_DEVICE_REMOVED;
|
||||
e->seat = ei_seat_ref(ei_device_get_seat(device));
|
||||
e->device = ei_device_ref(device);
|
||||
|
||||
insert_event(ei, e);
|
||||
|
|
@ -290,6 +293,7 @@ queue_suspended_event(struct ei_device *device)
|
|||
|
||||
struct ei_event *e = ei_event_create(&ei->object);
|
||||
e->type = EI_EVENT_DEVICE_SUSPENDED;
|
||||
e->seat = ei_seat_ref(ei_device_get_seat(device));
|
||||
e->device = ei_device_ref(device);
|
||||
|
||||
queue_event(ei, e);
|
||||
|
|
@ -302,6 +306,7 @@ queue_resumed_event(struct ei_device *device)
|
|||
|
||||
struct ei_event *e = ei_event_create(&ei->object);
|
||||
e->type = EI_EVENT_DEVICE_RESUMED;
|
||||
e->seat = ei_seat_ref(ei_device_get_seat(device));
|
||||
e->device = ei_device_ref(device);
|
||||
|
||||
queue_event(ei, e);
|
||||
|
|
@ -328,23 +333,33 @@ connection_send_disconnect(struct ei *ei)
|
|||
}
|
||||
|
||||
static int
|
||||
connection_send_add(struct ei *ei, struct ei_device *device)
|
||||
connection_send_bind_seat(struct ei *ei, struct ei_seat *seat, uint32_t capabilities)
|
||||
{
|
||||
if (ei->state == EI_STATE_NEW ||
|
||||
ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
return ei_proto_send_add(ei, device);
|
||||
return ei_proto_send_bind_seat(ei, seat, capabilities);
|
||||
}
|
||||
|
||||
static int
|
||||
connection_send_remove(struct ei *ei, struct ei_device *device)
|
||||
connection_send_unbind_seat(struct ei *ei, struct ei_seat *seat)
|
||||
{
|
||||
if (ei->state == EI_STATE_NEW ||
|
||||
ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
return ei_proto_send_remove(ei, device);
|
||||
return ei_proto_send_unbind_seat(ei, seat);
|
||||
}
|
||||
|
||||
static int
|
||||
connection_send_close_device(struct ei *ei, struct ei_device *device)
|
||||
{
|
||||
if (ei->state == EI_STATE_NEW ||
|
||||
ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
return ei_proto_send_close_device(ei, device);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -473,28 +488,6 @@ ei_disconnect(struct ei *ei)
|
|||
ei->source = source_unref(ei->source);
|
||||
}
|
||||
|
||||
int
|
||||
ei_send_add_device(struct ei_device *device)
|
||||
{
|
||||
struct ei *ei = ei_device_get_context(device);
|
||||
int rc = connection_send_add(ei, device);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ei_send_remove_device(struct ei_device *device)
|
||||
{
|
||||
struct ei *ei = ei_device_get_context(device);
|
||||
int rc = connection_send_remove(ei, device);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_msg_seat_added(struct ei *ei, uint32_t seatid,
|
||||
const char *name, uint32_t capabilities)
|
||||
|
|
@ -504,6 +497,7 @@ handle_msg_seat_added(struct ei *ei, uint32_t seatid,
|
|||
|
||||
struct ei_seat *seat = ei_seat_new(ei, seatid, name, capabilities);
|
||||
|
||||
/* seats list owns the ref */
|
||||
list_append(&ei->seats, &seat->link);
|
||||
|
||||
queue_seat_added_event(seat);
|
||||
|
|
@ -529,7 +523,9 @@ handle_msg_device_added(struct ei *ei, uint32_t deviceid,
|
|||
const char *name, uint32_t capabilities,
|
||||
bool keymap_from_server, enum ei_keymap_type keymap_type,
|
||||
int keymap_fd, size_t keymap_sz,
|
||||
uint32_t seatid)
|
||||
uint32_t seatid,
|
||||
uint32_t pointer_width, uint32_t pointer_height,
|
||||
uint32_t touch_width, uint32_t touch_height)
|
||||
{
|
||||
struct ei_seat *seat = ei_find_seat(ei, seatid);
|
||||
|
||||
|
|
@ -540,15 +536,20 @@ handle_msg_device_added(struct ei *ei, uint32_t deviceid,
|
|||
}
|
||||
|
||||
struct ei_device *device = ei_seat_find_device(seat, deviceid);
|
||||
|
||||
/* Wrong device id or a device already removed by the client but we
|
||||
* won't know which unless we keep some device ID table. Not worth
|
||||
* it, so just silently ignore */
|
||||
if (!device)
|
||||
return 0;
|
||||
if (device) {
|
||||
log_error(ei, "Device sent duplicate device id %d\n", deviceid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
device = ei_device_new(seat, deviceid);
|
||||
|
||||
ei_device_set_name(device, name);
|
||||
ei_device_set_capabilities(device, capabilities);
|
||||
ei_device_set_pointer_range(device, pointer_width, pointer_height);
|
||||
ei_device_set_touch_range(device, touch_width, touch_height);
|
||||
if (keymap_from_server)
|
||||
ei_device_set_keymap(device, keymap_type,
|
||||
keymap_fd, keymap_sz);
|
||||
|
|
@ -621,6 +622,37 @@ handle_msg_suspended(struct ei *ei, uint32_t deviceid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ei_send_close_device(struct ei_device *device)
|
||||
{
|
||||
struct ei *ei = ei_device_get_context(device);
|
||||
int rc = connection_send_close_device(ei, device);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ei_send_seat_bind(struct ei_seat *seat, uint32_t capabilities)
|
||||
{
|
||||
struct ei *ei = ei_seat_get_context(seat);
|
||||
int rc = connection_send_bind_seat(ei, seat, capabilities);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ei_send_seat_unbind(struct ei_seat *seat)
|
||||
{
|
||||
struct ei *ei = ei_seat_get_context(seat);
|
||||
int rc = connection_send_unbind_seat(ei, seat);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ei_send_pointer_rel(struct ei_device *device, double x, double y)
|
||||
{
|
||||
|
|
@ -810,7 +842,12 @@ connection_connected_handle_msg(struct ei *ei, struct message *msg)
|
|||
msg->device_added.keymap_type,
|
||||
msg->device_added.keymap_fd,
|
||||
msg->device_added.keymap_size,
|
||||
msg->device_added.seatid);
|
||||
msg->device_added.seatid,
|
||||
msg->device_added.pointer_width,
|
||||
msg->device_added.pointer_height,
|
||||
msg->device_added.touch_width,
|
||||
msg->device_added.touch_height
|
||||
);
|
||||
break;
|
||||
case MESSAGE_DEVICE_REMOVED:
|
||||
rc = handle_msg_device_removed(ei, msg->device_removed.deviceid);
|
||||
|
|
|
|||
170
src/libei.h
170
src/libei.h
|
|
@ -191,8 +191,8 @@ enum ei_event_type {
|
|||
/**
|
||||
* The server has removed a seat previously available to this
|
||||
* client. The caller should release the struct @ref ei_seat and
|
||||
* all its associated resources. No devices can be created through
|
||||
* this seat anymore.
|
||||
* all its associated resources. No devices will be added to this seat
|
||||
* anymore.
|
||||
*
|
||||
* libei guarantees that any device in this seat generates a @ref
|
||||
* EI_EVENT_DEVICE_REMOVED event before the @ref
|
||||
|
|
@ -202,14 +202,10 @@ enum ei_event_type {
|
|||
|
||||
/**
|
||||
* The server has added a device for this client. The capabilities
|
||||
* of the device may not match the requested capabilities - it is up
|
||||
* of the device may be a subset of the seat capabilities - it is up
|
||||
* to the client to verify the minimum required capabilities are
|
||||
* indeed set.
|
||||
*
|
||||
* Where the server refuses to add a specific device or the
|
||||
* intersection of requested capabilities and allowed capabilities
|
||||
* is zero, the server sends @ref EI_EVENT_DEVICE_REMOVED instead.
|
||||
*
|
||||
* libei guarantees that any device added has a corresponding @ref
|
||||
* EI_EVENT_DEVICE_REMOVED event before @ref EI_EVENT_DISCONNECT.
|
||||
*/
|
||||
|
|
@ -469,6 +465,42 @@ bool
|
|||
ei_seat_has_capability(struct ei_seat *seat,
|
||||
enum ei_device_capability cap);
|
||||
|
||||
/**
|
||||
* Remove a capability from this seat before calling ei_seat_bind().
|
||||
* Devices with only the dropped capability will never be added to this
|
||||
* client, devices with multiple capabilities will not show the dropped
|
||||
* capabilities.
|
||||
*
|
||||
* This function has no effect if called after ei_seat_bind().
|
||||
*/
|
||||
void
|
||||
ei_seat_drop_capability(struct ei_seat *seat,
|
||||
enum ei_device_capability cap);
|
||||
|
||||
/**
|
||||
* Bind this client to the given seat for the seat's capabilities.
|
||||
* This function can only be called once per seat. Once bound, the server will
|
||||
* create devices for the seat's capabillities and send the respective @ref
|
||||
* EI_EVENT_DEVICE_ADDED events.
|
||||
*
|
||||
* Devices may be added and removed at any time.
|
||||
*/
|
||||
void
|
||||
ei_seat_bind(struct ei_seat *seat);
|
||||
|
||||
/**
|
||||
* Unbind a seat and remove it from the server.
|
||||
*
|
||||
* If called on a seat immediately after @ref EI_EVENT_SEAT_ADDED, this
|
||||
* function indicates that the client is not interested in this seat.
|
||||
* If called on a seat after ei_seat_bind(), this function implicitly calls
|
||||
* ei_device_close() on all devices for this seat.
|
||||
*
|
||||
* The server responds with an @ref EI_EVENT_SEAT_REMOVED event.
|
||||
*/
|
||||
void
|
||||
ei_seat_unbind(struct ei_seat *seat);
|
||||
|
||||
struct ei_seat *
|
||||
ei_seat_ref(struct ei_seat *seat);
|
||||
|
||||
|
|
@ -524,25 +556,6 @@ ei_device_ref(struct ei_device *device);
|
|||
struct ei_device *
|
||||
ei_device_unref(struct ei_device *device);
|
||||
|
||||
/**
|
||||
* Create a new device in the given seat. This device is a proxy
|
||||
* representing the server's device and should be 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.
|
||||
*
|
||||
* Use the configure API (e.g. ei_device_configure_capability()) to set up
|
||||
* the device, then call ei_device_add() to request creation of the device
|
||||
* by the server.
|
||||
*
|
||||
* @note A caller that does not want to add a created device to a seat
|
||||
* **must** call ei_device_remove() for this device to ensure the
|
||||
* resources are released.
|
||||
*
|
||||
* The returned object must be released by the caller with ei_event_unref()
|
||||
*/
|
||||
struct ei_device *
|
||||
ei_device_new(struct ei_seat *ei_seat);
|
||||
|
||||
struct ei_seat *
|
||||
ei_device_get_seat(struct ei_device *device);
|
||||
|
||||
|
|
@ -576,84 +589,6 @@ ei_device_set_user_data(struct ei_device *device, void *user_data);
|
|||
void *
|
||||
ei_device_get_user_data(struct ei_device *device);
|
||||
|
||||
/**
|
||||
* Set the name for this device. This is a suggestion only, the server may
|
||||
* ignore the name and assign a different one (or none). Use
|
||||
* ei_device_get_name() upon receiving @ref EI_EVENT_DEVICE_ADDED to get the
|
||||
* server-assigned
|
||||
* name.
|
||||
*
|
||||
* This function has no effect if called after ei_device_add()
|
||||
*
|
||||
* libei may quietly ignore names of unreasonable length. This is not
|
||||
* something a normal caller ever needs to worry about.
|
||||
*
|
||||
* @param device The EI device
|
||||
* @param name A name suggestion for the device
|
||||
*/
|
||||
void
|
||||
ei_device_configure_name(struct ei_device *device, const char *name);
|
||||
|
||||
/**
|
||||
* Enable the given capability on this device. This is a suggestion only,
|
||||
* the server may ignore this capability.
|
||||
* Use ei_device_has_capability() upon receiving @ref EI_EVENT_DEVICE_ADDED
|
||||
* to check for the actual capabilities of the device.
|
||||
*
|
||||
* This function has no effect if called after ei_device_add()
|
||||
*
|
||||
* @param device The EI device
|
||||
* @param cap The capability to enable
|
||||
*/
|
||||
bool
|
||||
ei_device_configure_capability(struct ei_device *device,
|
||||
enum ei_device_capability cap);
|
||||
|
||||
/**
|
||||
* Set the range of the absolute pointer device in logical
|
||||
* pixels. The allowable range for absolute pointer motion is
|
||||
* [0, max) for each axis, i.e. zero inclusive, max exclusive. Coordinates
|
||||
* outside this range may be discarded or clipped silently by the library.
|
||||
*
|
||||
* The pointer range is constant. Where the pointer range is no longer
|
||||
* applicable, the client needs to remove the device and create and add a
|
||||
* new device with the updated pointer range.
|
||||
*
|
||||
* The server may use this in mapping heuristics. For example, a pointer
|
||||
* device with a pixel range of 1920x1200 **may** be automatically mapped by
|
||||
* the server to the monitor with this range, or a pointer device with a
|
||||
* ratio of R **may** be mapped to the monitor with the same ratio. This is
|
||||
* not a guarantee, the mapping policy is a private implementation detail
|
||||
* in the server. It is assumed that the client has other communication
|
||||
* channels (e.g. Wayland) to obtain the pointer range it needs to emulate
|
||||
* input on a device and channels to notify the server of desired mappings
|
||||
* (e.g. gsettings).
|
||||
*
|
||||
* It is a client bug to send pointer values outside this range.
|
||||
* It is a client bug to call this function on a device without the @ref
|
||||
* EI_DEVICE_CAP_POINTER_ABSOLUTE capability.
|
||||
*
|
||||
* This function has no effect if called after ei_device_add()
|
||||
*
|
||||
* @param device The EI device
|
||||
* @param width The maximum (exclusive) x value in logical pixels
|
||||
* @param height The maximum (exclusive) y value in logical pixels
|
||||
*/
|
||||
void
|
||||
ei_device_pointer_configure_range(struct ei_device *device,
|
||||
uint32_t width,
|
||||
uint32_t height);
|
||||
|
||||
/**
|
||||
* Set the range of the touch device in logical pixels. This
|
||||
* function is identical to ei_device_pointer_configure_range() but
|
||||
* configures the touch range instead.
|
||||
*/
|
||||
void
|
||||
ei_device_touch_configure_range(struct ei_device *device,
|
||||
uint32_t width,
|
||||
uint32_t height);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new keymap of the given @p type. This keymap does not immediately
|
||||
|
|
@ -779,27 +714,8 @@ ei_device_keyboard_configure_keymap(struct ei_device *device,
|
|||
struct ei_keymap *keymap);
|
||||
|
||||
/**
|
||||
* 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 once the request has been processed.
|
||||
*
|
||||
* A client can assume that an @ref EI_EVENT_DEVICE_REMOVED event is sent
|
||||
* for any device for which ei_device_add() was called before the @ref
|
||||
* EI_EVENT_DISCONNECT. Where a client gets
|
||||
* disconnected libei will emulate that event.
|
||||
*
|
||||
* A client may not send events through this device until it has been added
|
||||
* by the server.
|
||||
*
|
||||
* Devices should only be added once all events from ei_get_event() have
|
||||
* been processed. It is considered a client bug to add a device to a seat
|
||||
* after the SEAT_REMOVED has been received by libei.
|
||||
*/
|
||||
void
|
||||
ei_device_add(struct ei_device *device);
|
||||
|
||||
/**
|
||||
* Notify the server that the device should be removed.
|
||||
* Notify the server that the client is no longer listening to events
|
||||
* from this device.
|
||||
*
|
||||
* Due to the asynchronous nature of the client-server interaction,
|
||||
* events for this device may still be in transit. The server will send an
|
||||
|
|
@ -807,7 +723,7 @@ ei_device_add(struct ei_device *device);
|
|||
* device is considered removed by the server.
|
||||
*
|
||||
* A client can assume that an @ref EI_EVENT_DEVICE_REMOVED event is sent
|
||||
* for any device for which ei_device_remove() was called before the @ref
|
||||
* for any device for which ei_device_close() was called before the @ref
|
||||
* EI_EVENT_DISCONNECT. Where a client gets
|
||||
* disconnected libei will emulate that event.
|
||||
*
|
||||
|
|
@ -815,7 +731,7 @@ ei_device_add(struct ei_device *device);
|
|||
* ei_device_unref() for any references held by the client.
|
||||
*/
|
||||
void
|
||||
ei_device_remove(struct ei_device *device);
|
||||
ei_device_close(struct ei_device *device);
|
||||
|
||||
/**
|
||||
* Return the name of this device.
|
||||
|
|
|
|||
|
|
@ -171,69 +171,7 @@ eis_client_disconnect(struct eis_client *client)
|
|||
}
|
||||
|
||||
static int
|
||||
client_new_device(struct eis_client *client,
|
||||
uint32_t id, const char *name, uint32_t capabilities,
|
||||
const struct dimensions *dim_pointer,
|
||||
const struct dimensions *dim_touch,
|
||||
enum eis_keymap_type keymap_type,
|
||||
int keymap_fd, size_t keymap_sz,
|
||||
uint32_t seatid)
|
||||
{
|
||||
struct eis_seat *s, *seat = NULL;
|
||||
|
||||
list_for_each(s, &client->seats, link) {
|
||||
if (s->id == seatid) {
|
||||
seat = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (seat == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check for duplicate IDs */
|
||||
struct eis_device *d;
|
||||
list_for_each(d, &seat->devices, link) {
|
||||
if (d->id == id)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (capabilities == 0 ||
|
||||
capabilities & ~(bit(EIS_DEVICE_CAP_POINTER) |
|
||||
bit(EIS_DEVICE_CAP_POINTER_ABSOLUTE) |
|
||||
bit(EIS_DEVICE_CAP_KEYBOARD) |
|
||||
bit(EIS_DEVICE_CAP_TOUCH)))
|
||||
return -EINVAL;
|
||||
|
||||
struct eis_device *device = eis_device_new(seat, id, name, capabilities);
|
||||
list_append(&seat->devices, &device->link);
|
||||
|
||||
if (flag_is_set(capabilities, EIS_DEVICE_CAP_POINTER_ABSOLUTE))
|
||||
eis_device_set_pointer_range(device, dim_pointer->width,
|
||||
dim_pointer->height);
|
||||
|
||||
if (flag_is_set(capabilities, EIS_DEVICE_CAP_TOUCH))
|
||||
eis_device_set_touch_range(device, dim_touch->width,
|
||||
dim_touch->height);
|
||||
|
||||
eis_device_set_client_keymap(device, keymap_type, keymap_fd, keymap_sz);
|
||||
|
||||
log_debug(eis_client_parent(client),
|
||||
"New device %#x '%s' caps: %s%s%s%s seat: %s\n",
|
||||
id, name,
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER) ? "p" : "",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE) ? "a" : "",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_KEYBOARD) ? "k" : "",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH) ? "t" : "",
|
||||
eis_seat_get_name(seat));
|
||||
|
||||
eis_queue_added_event(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
client_remove_device(struct eis_client *client, uint32_t deviceid)
|
||||
client_close_device(struct eis_client *client, uint32_t deviceid)
|
||||
{
|
||||
struct eis_seat *seat;
|
||||
|
||||
|
|
@ -242,7 +180,7 @@ client_remove_device(struct eis_client *client, uint32_t deviceid)
|
|||
|
||||
list_for_each(device, &seat->devices, link) {
|
||||
if (device->id == deviceid) {
|
||||
eis_device_removed_by_client(device);
|
||||
eis_device_closed_by_client(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -250,6 +188,36 @@ client_remove_device(struct eis_client *client, uint32_t deviceid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
client_seat_bind(struct eis_client *client, uint32_t seatid, uint32_t caps)
|
||||
{
|
||||
struct eis_seat *seat;
|
||||
|
||||
list_for_each(seat, &client->seats, link) {
|
||||
if (seat->id == seatid) {
|
||||
eis_queue_seat_bind_event(seat, caps);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
client_seat_unbind(struct eis_client *client, uint32_t seatid)
|
||||
{
|
||||
struct eis_seat *seat;
|
||||
|
||||
list_for_each(seat, &client->seats, link) {
|
||||
if (seat->id == seatid) {
|
||||
/* FIXME */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
client_pointer_rel(struct eis_client *client, uint32_t deviceid,
|
||||
double x, double y)
|
||||
|
|
@ -431,8 +399,9 @@ client_new_handle_msg(struct eis_client *client, struct message *msg)
|
|||
case MESSAGE_DISCONNECT:
|
||||
rc = -ECANCELED;
|
||||
break;
|
||||
case MESSAGE_ADD_DEVICE:
|
||||
case MESSAGE_REMOVE_DEVICE:
|
||||
case MESSAGE_BIND_SEAT:
|
||||
case MESSAGE_UNBIND_SEAT:
|
||||
case MESSAGE_CLOSE_DEVICE:
|
||||
case MESSAGE_POINTER_REL:
|
||||
case MESSAGE_POINTER_ABS:
|
||||
case MESSAGE_POINTER_BUTTON:
|
||||
|
|
@ -467,8 +436,9 @@ client_connecting_handle_msg(struct eis_client *client, const struct message *ms
|
|||
case MESSAGE_DISCONNECT:
|
||||
rc = -ECANCELED;
|
||||
break;
|
||||
case MESSAGE_ADD_DEVICE:
|
||||
case MESSAGE_REMOVE_DEVICE:
|
||||
case MESSAGE_BIND_SEAT:
|
||||
case MESSAGE_UNBIND_SEAT:
|
||||
case MESSAGE_CLOSE_DEVICE:
|
||||
case MESSAGE_POINTER_REL:
|
||||
case MESSAGE_POINTER_ABS:
|
||||
case MESSAGE_POINTER_BUTTON:
|
||||
|
|
@ -504,19 +474,14 @@ client_connected_handle_msg(struct eis_client *client,
|
|||
case MESSAGE_DISCONNECT:
|
||||
rc = -ECANCELED;
|
||||
break;
|
||||
case MESSAGE_ADD_DEVICE:
|
||||
rc = client_new_device(client, msg->add_device.deviceid,
|
||||
msg->add_device.name,
|
||||
msg->add_device.capabilities,
|
||||
&msg->add_device.dim_pointer,
|
||||
&msg->add_device.dim_touch,
|
||||
msg->add_device.keymap_type,
|
||||
msg->add_device.keymap_fd,
|
||||
msg->add_device.keymap_size,
|
||||
msg->add_device.seat);
|
||||
case MESSAGE_BIND_SEAT:
|
||||
client_seat_bind(client, msg->bind_seat.seatid, msg->bind_seat.capabilities);
|
||||
break;
|
||||
case MESSAGE_REMOVE_DEVICE:
|
||||
rc = client_remove_device(client, msg->remove_device.deviceid);
|
||||
case MESSAGE_UNBIND_SEAT:
|
||||
client_seat_unbind(client, msg->unbind_seat.seatid);
|
||||
break;
|
||||
case MESSAGE_CLOSE_DEVICE:
|
||||
rc = client_close_device(client, msg->close_device.deviceid);
|
||||
break;
|
||||
case MESSAGE_POINTER_REL:
|
||||
rc = client_pointer_rel(client, msg->pointer_rel.deviceid,
|
||||
|
|
@ -678,13 +643,13 @@ eis_client_remove_seat(struct eis_client *client, struct eis_seat *seat)
|
|||
}
|
||||
|
||||
void
|
||||
eis_client_connect_device(struct eis_client *client, struct eis_device *device)
|
||||
eis_client_add_device(struct eis_client *client, struct eis_device *device)
|
||||
{
|
||||
client_send_device_added(client, device);
|
||||
}
|
||||
|
||||
void
|
||||
eis_client_disconnect_device(struct eis_client *client, struct eis_device *device)
|
||||
eis_client_remove_device(struct eis_client *client, struct eis_device *device)
|
||||
{
|
||||
client_send_device_removed(client, device);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,39 +165,85 @@ eis_device_get_client(struct eis_device *device)
|
|||
return eis_seat_get_client(eis_device_get_seat(device));
|
||||
}
|
||||
|
||||
struct eis_device *
|
||||
eis_device_new(struct eis_seat *seat,
|
||||
uint32_t id,
|
||||
const char *name,
|
||||
uint32_t capabilities)
|
||||
_public_ struct eis_device *
|
||||
eis_device_new(struct eis_seat *seat)
|
||||
{
|
||||
static uint32_t deviceid;
|
||||
struct eis_device *device = eis_device_create(&seat->object);
|
||||
|
||||
device->name = xstrdup(name);
|
||||
device->capabilities_mask = 0;
|
||||
device->capabilities = capabilities;
|
||||
device->id = id;
|
||||
device->id = seat->id | deviceid++;
|
||||
device->name = xstrdup("unnamed device");
|
||||
device->capabilities = 0;
|
||||
device->state = EIS_DEVICE_STATE_NEW;
|
||||
|
||||
return device;
|
||||
list_append(&seat->devices, &device->link);
|
||||
|
||||
return eis_device_ref(device);
|
||||
}
|
||||
|
||||
void
|
||||
eis_device_set_pointer_range(struct eis_device *device,
|
||||
uint32_t w, uint32_t h)
|
||||
_public_ void
|
||||
eis_device_configure_name(struct eis_device *device, const char *name)
|
||||
{
|
||||
if (device->state != EIS_DEVICE_STATE_NEW)
|
||||
return;
|
||||
|
||||
free(device->name);
|
||||
device->name = xstrdup(name);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
eis_device_configure_capability(struct eis_device *device, enum eis_device_capability cap)
|
||||
{
|
||||
if (device->state != EIS_DEVICE_STATE_NEW)
|
||||
return;
|
||||
|
||||
if (!eis_seat_has_capability(eis_device_get_seat(device), cap))
|
||||
return;
|
||||
|
||||
flag_set(device->capabilities, cap);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
eis_device_configure_pointer_range(struct eis_device *device,
|
||||
uint32_t w, uint32_t h)
|
||||
{
|
||||
if (device->state != EIS_DEVICE_STATE_NEW)
|
||||
return;
|
||||
|
||||
device->abs.dim.width = w;
|
||||
device->abs.dim.height = h;
|
||||
}
|
||||
|
||||
void
|
||||
eis_device_set_touch_range(struct eis_device *device,
|
||||
uint32_t w, uint32_t h)
|
||||
_public_ void
|
||||
eis_device_configure_touch_range(struct eis_device *device,
|
||||
uint32_t w, uint32_t h)
|
||||
{
|
||||
if (device->state != EIS_DEVICE_STATE_NEW)
|
||||
return;
|
||||
|
||||
device->touch.dim.width = w;
|
||||
device->touch.dim.height = h;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
eis_device_add(struct eis_device *device)
|
||||
{
|
||||
if (device->state != EIS_DEVICE_STATE_NEW)
|
||||
return;
|
||||
|
||||
device->state = EIS_DEVICE_STATE_SUSPENDED;
|
||||
eis_client_add_device(eis_device_get_client(device), device);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
eis_device_remove(struct eis_device *device)
|
||||
{
|
||||
device->state = EIS_DEVICE_STATE_REMOVED_BY_SERVER ;
|
||||
eis_client_remove_device(eis_device_get_client(device), device);
|
||||
list_remove(&device->link);
|
||||
eis_device_unref(device);
|
||||
}
|
||||
|
||||
void
|
||||
eis_device_set_client_keymap(struct eis_device *device,
|
||||
enum eis_keymap_type type,
|
||||
|
|
@ -239,19 +285,6 @@ eis_device_has_capability(struct eis_device *device,
|
|||
return false;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
eis_device_allow_capability(struct eis_device *device,
|
||||
enum eis_device_capability cap)
|
||||
{
|
||||
switch(cap) {
|
||||
case EIS_DEVICE_CAP_POINTER:
|
||||
case EIS_DEVICE_CAP_POINTER_ABSOLUTE:
|
||||
case EIS_DEVICE_CAP_KEYBOARD:
|
||||
case EIS_DEVICE_CAP_TOUCH:
|
||||
flag_set(device->capabilities_mask, cap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_public_ uint32_t
|
||||
eis_device_pointer_get_width(struct eis_device *device)
|
||||
|
|
@ -415,24 +448,7 @@ eis_device_touch(struct eis_device *device, uint32_t touchid,
|
|||
return 0;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
eis_device_connect(struct eis_device *device)
|
||||
{
|
||||
if (device->state != EIS_DEVICE_STATE_NEW)
|
||||
return;
|
||||
|
||||
if (device->capabilities_mask == 0) {
|
||||
log_bug(eis_device_get_context(device),
|
||||
"Connecting a device without capabilities\n");
|
||||
eis_device_disconnect(device);
|
||||
return;
|
||||
}
|
||||
|
||||
device->capabilities &= device->capabilities_mask;
|
||||
device->state = EIS_DEVICE_STATE_SUSPENDED;
|
||||
eis_client_connect_device(eis_device_get_client(device), device);
|
||||
}
|
||||
|
||||
#if 0 /* FIXME: needs to move to eis_device_remove */
|
||||
_public_ void
|
||||
eis_device_disconnect(struct eis_device *device)
|
||||
{
|
||||
|
|
@ -450,36 +466,32 @@ eis_device_disconnect(struct eis_device *device)
|
|||
break;
|
||||
/* device was already removed by the client, so it's properly gone
|
||||
* now */
|
||||
case EIS_DEVICE_STATE_REMOVED_BY_CLIENT:
|
||||
case EIS_DEVICE_STATE_CLOSED_BY_CLIENT:
|
||||
device->state = EIS_DEVICE_STATE_DEAD;
|
||||
list_remove(&device->link);
|
||||
eis_device_unref(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
eis_device_removed_by_client(struct eis_device *device)
|
||||
eis_device_closed_by_client(struct eis_device *device)
|
||||
{
|
||||
switch (device->state) {
|
||||
case EIS_DEVICE_STATE_DEAD:
|
||||
case EIS_DEVICE_STATE_REMOVED_BY_CLIENT:
|
||||
case EIS_DEVICE_STATE_CLOSED_BY_CLIENT:
|
||||
/* libei bug, ignore */
|
||||
break;
|
||||
/* Confirmation from the client. Queue our local event but otherwise
|
||||
* this device is done */
|
||||
case EIS_DEVICE_STATE_REMOVED_BY_SERVER:
|
||||
eis_queue_removed_event(device);
|
||||
device->state = EIS_DEVICE_STATE_DEAD;
|
||||
list_remove(&device->link);
|
||||
eis_device_unref(device);
|
||||
/* FIXME: Late arrival after eis_device_removed? */
|
||||
break;
|
||||
case EIS_DEVICE_STATE_NEW:
|
||||
case EIS_DEVICE_STATE_SUSPENDED:
|
||||
case EIS_DEVICE_STATE_RESUMED:
|
||||
eis_queue_removed_event(device);
|
||||
device->state = EIS_DEVICE_STATE_REMOVED_BY_CLIENT;
|
||||
eis_client_disconnect_device(eis_device_get_client(device), device);
|
||||
eis_queue_device_closed_event(device);
|
||||
device->state = EIS_DEVICE_STATE_CLOSED_BY_CLIENT;
|
||||
eis_client_remove_device(eis_device_get_client(device), device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "util-bits.h"
|
||||
#include "util-object.h"
|
||||
#include "util-macros.h"
|
||||
|
||||
|
|
@ -36,7 +37,9 @@ eis_event_destroy(struct eis_event *event)
|
|||
switch (event->type) {
|
||||
case EIS_EVENT_CLIENT_CONNECT:
|
||||
case EIS_EVENT_CLIENT_DISCONNECT:
|
||||
case EIS_EVENT_DEVICE_ADDED:
|
||||
case EIS_EVENT_SEAT_BIND:
|
||||
case EIS_EVENT_SEAT_UNBIND:
|
||||
case EIS_EVENT_DEVICE_CLOSED:
|
||||
case EIS_EVENT_POINTER_BUTTON:
|
||||
case EIS_EVENT_POINTER_MOTION:
|
||||
case EIS_EVENT_POINTER_MOTION_ABSOLUTE:
|
||||
|
|
@ -47,13 +50,11 @@ eis_event_destroy(struct eis_event *event)
|
|||
case EIS_EVENT_TOUCH_MOTION:
|
||||
case EIS_EVENT_TOUCH_UP:
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_REMOVED:
|
||||
eis_device_disconnect(event->device);
|
||||
break;
|
||||
default:
|
||||
abort(); /* not yet implemented */
|
||||
}
|
||||
event->device = eis_device_unref(event->device);
|
||||
event->seat = eis_seat_unref(event->seat);
|
||||
event->client = eis_client_unref(event->client);
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +72,19 @@ eis_event_new_for_client(struct eis_client *client)
|
|||
return e;
|
||||
}
|
||||
|
||||
struct eis_event *
|
||||
eis_event_new_for_seat(struct eis_seat *seat)
|
||||
{
|
||||
struct eis_client *client = eis_seat_get_client(seat);
|
||||
struct eis *eis = eis_client_get_context(client);
|
||||
|
||||
struct eis_event *e = eis_event_create(&eis->object);
|
||||
e->client = eis_client_ref(client);
|
||||
e->seat = eis_seat_ref(seat);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
struct eis_event *
|
||||
eis_event_new_for_device(struct eis_device *device)
|
||||
{
|
||||
|
|
@ -79,6 +93,7 @@ eis_event_new_for_device(struct eis_device *device)
|
|||
|
||||
struct eis_event *e = eis_event_create(&eis->object);
|
||||
e->client = eis_client_ref(client);
|
||||
e->seat = eis_seat_ref(eis_device_get_seat(device));
|
||||
e->device = eis_device_ref(device);
|
||||
|
||||
return e;
|
||||
|
|
@ -94,6 +109,8 @@ OBJECT_IMPLEMENT_GETTER(eis_event, type, enum eis_event_type);
|
|||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(eis_event, client, struct eis_client*);
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(eis_event, seat, struct eis_seat*);
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(eis_event, device, struct eis_device*);
|
||||
|
||||
static
|
||||
|
|
@ -140,6 +157,14 @@ check_event_type(struct eis_event *event,
|
|||
if (!check_event_type(event_, __func__, __VA_ARGS__, -1)) \
|
||||
return retval_; \
|
||||
|
||||
_public_ bool
|
||||
eis_event_seat_has_capability(struct eis_event *event, enum eis_device_capability cap)
|
||||
{
|
||||
require_event_type(event, false, EIS_EVENT_SEAT_BIND);
|
||||
|
||||
return flag_is_set(event->bind.capabilities, cap);
|
||||
}
|
||||
|
||||
_public_ double
|
||||
eis_event_pointer_get_dx(struct eis_event *event)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ enum eis_device_state {
|
|||
EIS_DEVICE_STATE_NEW,
|
||||
EIS_DEVICE_STATE_SUSPENDED,
|
||||
EIS_DEVICE_STATE_RESUMED,
|
||||
EIS_DEVICE_STATE_REMOVED_BY_CLIENT,
|
||||
EIS_DEVICE_STATE_CLOSED_BY_CLIENT,
|
||||
EIS_DEVICE_STATE_REMOVED_BY_SERVER,
|
||||
EIS_DEVICE_STATE_DEAD,
|
||||
};
|
||||
|
|
@ -118,7 +118,6 @@ struct eis_device {
|
|||
char *name;
|
||||
enum eis_device_state state;
|
||||
uint32_t capabilities;
|
||||
uint32_t capabilities_mask;
|
||||
void *user_data;
|
||||
|
||||
struct {
|
||||
|
|
@ -136,9 +135,13 @@ struct eis_event {
|
|||
enum eis_event_type type;
|
||||
struct list link;
|
||||
struct eis_client *client;
|
||||
struct eis_seat *seat;
|
||||
struct eis_device *device;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint32_t capabilities;
|
||||
} bind;
|
||||
struct {
|
||||
double dx, dy; /* relative motion */
|
||||
double absx, absy; /* absolute motion */
|
||||
|
|
@ -189,11 +192,9 @@ void
|
|||
eis_client_remove_seat(struct eis_client *client, struct eis_seat *seat);
|
||||
|
||||
void
|
||||
eis_client_connect_device(struct eis_client *client,
|
||||
struct eis_device *device);
|
||||
eis_client_add_device(struct eis_client *client, struct eis_device *device);
|
||||
void
|
||||
eis_client_disconnect_device(struct eis_client *client,
|
||||
struct eis_device *device);
|
||||
eis_client_remove_device(struct eis_client *client, struct eis_device *device);
|
||||
|
||||
void
|
||||
eis_client_resume_device(struct eis_client *client,
|
||||
|
|
@ -203,13 +204,10 @@ eis_client_suspend_device(struct eis_client *client,
|
|||
struct eis_device *device);
|
||||
|
||||
void
|
||||
eis_seat_disconnect(struct eis_seat *seat);
|
||||
eis_seat_bind(struct eis_seat *seat, uint32_t cap);
|
||||
|
||||
struct eis_device *
|
||||
eis_device_new(struct eis_seat *seat,
|
||||
uint32_t id,
|
||||
const char *name,
|
||||
uint32_t capabilities);
|
||||
void
|
||||
eis_seat_disconnect(struct eis_seat *seat);
|
||||
|
||||
void
|
||||
eis_device_set_pointer_range(struct eis_device *device,
|
||||
|
|
@ -251,11 +249,14 @@ eis_device_touch(struct eis_device *device, uint32_t touchid,
|
|||
bool is_down, bool is_up, double x, double y);
|
||||
|
||||
void
|
||||
eis_device_removed_by_client(struct eis_device *device);
|
||||
eis_device_closed_by_client(struct eis_device *device);
|
||||
|
||||
struct eis_event *
|
||||
eis_event_new_for_client(struct eis_client *client);
|
||||
|
||||
struct eis_event *
|
||||
eis_event_new_for_seat(struct eis_seat *seat);
|
||||
|
||||
struct eis_event *
|
||||
eis_event_new_for_device(struct eis_device *device);
|
||||
|
||||
|
|
@ -272,10 +273,13 @@ void
|
|||
eis_queue_disconnect_event(struct eis_client *client);
|
||||
|
||||
void
|
||||
eis_queue_added_event(struct eis_device *device);
|
||||
eis_queue_seat_bind_event(struct eis_seat *seat, uint32_t capabilities);
|
||||
|
||||
void
|
||||
eis_queue_removed_event(struct eis_device *device);
|
||||
eis_queue_seat_unbind_event(struct eis_seat *seat);
|
||||
|
||||
void
|
||||
eis_queue_device_closed_event(struct eis_device *device);
|
||||
|
||||
void
|
||||
eis_queue_pointer_rel_event(struct eis_device *device, double x, double y);
|
||||
|
|
|
|||
|
|
@ -38,9 +38,6 @@ void
|
|||
message_free(struct message *msg)
|
||||
{
|
||||
switch (msg->type) {
|
||||
case MESSAGE_ADD_DEVICE:
|
||||
free(msg->add_device.name);
|
||||
break;
|
||||
case MESSAGE_CONNECT:
|
||||
free(msg->connect.name);
|
||||
break;
|
||||
|
|
@ -196,6 +193,11 @@ eis_proto_send_device_added(struct eis_client *client, struct eis_device *device
|
|||
}
|
||||
added.seatid = seat->id;
|
||||
|
||||
added.pointer_width = device->abs.dim.width;
|
||||
added.pointer_height = device->abs.dim.height;
|
||||
added.touch_width = device->touch.dim.width;
|
||||
added.touch_height = device->touch.dim.height;
|
||||
|
||||
msg.device_added = &added;
|
||||
msg.msg_case = SERVER_MESSAGE__MSG_DEVICE_ADDED;
|
||||
|
||||
|
|
@ -272,34 +274,31 @@ eis_proto_parse_message(struct brei_message *bmsg, size_t *consumed)
|
|||
.type = MESSAGE_DISCONNECT,
|
||||
};
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_ADD_DEVICE:
|
||||
case CLIENT_MESSAGE__MSG_BIND_SEAT:
|
||||
{
|
||||
AddDevice *a = proto->add_device;
|
||||
BindSeat *b = proto->bind_seat;
|
||||
*msg = (struct message) {
|
||||
.type = MESSAGE_ADD_DEVICE,
|
||||
.add_device.deviceid = a->deviceid,
|
||||
.add_device.name = a->name[0] ? xstrdup(a->name) : NULL,
|
||||
.add_device.capabilities = a->capabilities,
|
||||
.add_device.dim_pointer.width = a->pointer_width,
|
||||
.add_device.dim_pointer.height = a->pointer_height,
|
||||
.add_device.dim_touch.width = a->touch_width,
|
||||
.add_device.dim_touch.height = a->touch_height,
|
||||
.add_device.keymap_fd = -1,
|
||||
.add_device.keymap_type = a->keymap_type,
|
||||
.add_device.keymap_size = a->keymap_size,
|
||||
.add_device.seat = a->seat,
|
||||
.type = MESSAGE_BIND_SEAT,
|
||||
.bind_seat.seatid = b->seatid,
|
||||
.bind_seat.capabilities = b->capabilities,
|
||||
};
|
||||
|
||||
if (a->keymap_type)
|
||||
msg->add_device.keymap_fd = brei_message_take_fd(bmsg);
|
||||
}
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_REMOVE_DEVICE:
|
||||
case CLIENT_MESSAGE__MSG_UNBIND_SEAT:
|
||||
{
|
||||
RemoveDevice *r = proto->remove_device;
|
||||
UnbindSeat *u = proto->unbind_seat;
|
||||
*msg = (struct message) {
|
||||
.type = MESSAGE_REMOVE_DEVICE,
|
||||
.remove_device.deviceid = r->deviceid,
|
||||
.type = MESSAGE_UNBIND_SEAT,
|
||||
.unbind_seat.seatid = u->seatid,
|
||||
};
|
||||
}
|
||||
break;
|
||||
case CLIENT_MESSAGE__MSG_CLOSE_DEVICE:
|
||||
{
|
||||
CloseDevice *r = proto->close_device;
|
||||
*msg = (struct message) {
|
||||
.type = MESSAGE_CLOSE_DEVICE,
|
||||
.close_device.deviceid = r->deviceid,
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -37,8 +37,9 @@
|
|||
enum message_type {
|
||||
MESSAGE_CONNECT,
|
||||
MESSAGE_DISCONNECT,
|
||||
MESSAGE_ADD_DEVICE,
|
||||
MESSAGE_REMOVE_DEVICE,
|
||||
MESSAGE_BIND_SEAT,
|
||||
MESSAGE_UNBIND_SEAT,
|
||||
MESSAGE_CLOSE_DEVICE,
|
||||
MESSAGE_POINTER_REL,
|
||||
MESSAGE_POINTER_ABS,
|
||||
MESSAGE_POINTER_BUTTON,
|
||||
|
|
@ -57,8 +58,9 @@ message_type_to_string(enum message_type type)
|
|||
switch(type) {
|
||||
CASE_RETURN_STRING(MESSAGE_CONNECT);
|
||||
CASE_RETURN_STRING(MESSAGE_DISCONNECT);
|
||||
CASE_RETURN_STRING(MESSAGE_ADD_DEVICE);
|
||||
CASE_RETURN_STRING(MESSAGE_REMOVE_DEVICE);
|
||||
CASE_RETURN_STRING(MESSAGE_BIND_SEAT);
|
||||
CASE_RETURN_STRING(MESSAGE_UNBIND_SEAT);
|
||||
CASE_RETURN_STRING(MESSAGE_CLOSE_DEVICE);
|
||||
CASE_RETURN_STRING(MESSAGE_POINTER_REL);
|
||||
CASE_RETURN_STRING(MESSAGE_POINTER_ABS);
|
||||
CASE_RETURN_STRING(MESSAGE_POINTER_BUTTON);
|
||||
|
|
@ -81,6 +83,17 @@ struct message {
|
|||
struct message_disconnect {
|
||||
uint8_t pad; /* no data */
|
||||
} disconnect;
|
||||
struct message_bind_seat {
|
||||
uint32_t seatid;
|
||||
uint32_t capabilities;
|
||||
} bind_seat;
|
||||
struct message_unbind_seat {
|
||||
uint32_t seatid;
|
||||
} unbind_seat;
|
||||
struct message_close_device {
|
||||
uint32_t deviceid;
|
||||
} close_device;
|
||||
#if 0
|
||||
struct message_add_device {
|
||||
uint32_t deviceid;
|
||||
char *name;
|
||||
|
|
@ -96,6 +109,7 @@ struct message {
|
|||
struct message_remove_device {
|
||||
uint32_t deviceid;
|
||||
} remove_device;
|
||||
#endif
|
||||
struct message_pointer_rel {
|
||||
uint32_t deviceid;
|
||||
double x;
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ eis_seat_remove(struct eis_seat *seat)
|
|||
*/
|
||||
struct eis_device *d, *tmp;
|
||||
list_for_each_safe(d, tmp, &seat->devices, link) {
|
||||
eis_device_disconnect(d);
|
||||
eis_device_remove(d);
|
||||
}
|
||||
|
||||
eis_client_remove_seat(eis_seat_get_client(seat), seat);
|
||||
|
|
@ -141,7 +141,7 @@ eis_seat_disconnect(struct eis_seat *seat)
|
|||
* device removed event. */
|
||||
struct eis_device *d, *tmp;
|
||||
list_for_each_safe(d, tmp, &seat->devices, link) {
|
||||
eis_device_removed_by_client(d);
|
||||
eis_device_closed_by_client(d);
|
||||
}
|
||||
|
||||
seat->state = EIS_SEAT_STATE_DEAD;
|
||||
|
|
@ -150,15 +150,22 @@ eis_seat_disconnect(struct eis_seat *seat)
|
|||
}
|
||||
|
||||
_public_ void
|
||||
eis_seat_allow_capability(struct eis_seat *seat,
|
||||
enum eis_device_capability cap)
|
||||
eis_seat_configure_capability(struct eis_seat *seat,
|
||||
enum eis_device_capability cap)
|
||||
{
|
||||
switch (cap) {
|
||||
case EIS_DEVICE_CAP_POINTER:
|
||||
case EIS_DEVICE_CAP_POINTER_ABSOLUTE:
|
||||
case EIS_DEVICE_CAP_KEYBOARD:
|
||||
case EIS_DEVICE_CAP_TOUCH:
|
||||
seat->capabilities_mask |= bit(cap);
|
||||
flag_set(seat->capabilities_mask, cap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_public_ bool
|
||||
eis_seat_has_capability(struct eis_seat *seat,
|
||||
enum eis_device_capability cap)
|
||||
{
|
||||
return flag_is_set(seat->capabilities_mask, cap);
|
||||
}
|
||||
|
|
|
|||
24
src/libeis.c
24
src/libeis.c
|
|
@ -102,8 +102,9 @@ eis_event_type_to_string(enum eis_event_type type)
|
|||
switch(type) {
|
||||
CASE_RETURN_STRING(EIS_EVENT_CLIENT_CONNECT);
|
||||
CASE_RETURN_STRING(EIS_EVENT_CLIENT_DISCONNECT);
|
||||
CASE_RETURN_STRING(EIS_EVENT_DEVICE_ADDED);
|
||||
CASE_RETURN_STRING(EIS_EVENT_DEVICE_REMOVED);
|
||||
CASE_RETURN_STRING(EIS_EVENT_SEAT_BIND);
|
||||
CASE_RETURN_STRING(EIS_EVENT_SEAT_UNBIND);
|
||||
CASE_RETURN_STRING(EIS_EVENT_DEVICE_CLOSED);
|
||||
CASE_RETURN_STRING(EIS_EVENT_POINTER_MOTION);
|
||||
CASE_RETURN_STRING(EIS_EVENT_POINTER_MOTION_ABSOLUTE);
|
||||
CASE_RETURN_STRING(EIS_EVENT_POINTER_BUTTON);
|
||||
|
|
@ -146,18 +147,27 @@ eis_queue_disconnect_event(struct eis_client *client)
|
|||
}
|
||||
|
||||
void
|
||||
eis_queue_added_event(struct eis_device *device)
|
||||
eis_queue_seat_bind_event(struct eis_seat *seat, uint32_t capabilities)
|
||||
{
|
||||
struct eis_event *e = eis_event_new_for_device(device);
|
||||
e->type = EIS_EVENT_DEVICE_ADDED;
|
||||
struct eis_event *e = eis_event_new_for_seat(seat);
|
||||
e->type = EIS_EVENT_SEAT_BIND;
|
||||
e->bind.capabilities = capabilities;
|
||||
eis_queue_event(e);
|
||||
}
|
||||
|
||||
void
|
||||
eis_queue_removed_event(struct eis_device *device)
|
||||
eis_queue_seat_unbind_event(struct eis_seat *seat)
|
||||
{
|
||||
struct eis_event *e = eis_event_new_for_seat(seat);
|
||||
e->type = EIS_EVENT_SEAT_UNBIND;
|
||||
eis_queue_event(e);
|
||||
}
|
||||
|
||||
void
|
||||
eis_queue_device_closed_event(struct eis_device *device)
|
||||
{
|
||||
struct eis_event *e = eis_event_new_for_device(device);
|
||||
e->type = EIS_EVENT_DEVICE_REMOVED;
|
||||
e->type = EIS_EVENT_DEVICE_CLOSED;
|
||||
eis_queue_event(e);
|
||||
}
|
||||
|
||||
|
|
|
|||
97
src/libeis.h
97
src/libeis.h
|
|
@ -74,21 +74,21 @@ enum eis_event_type {
|
|||
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.
|
||||
*
|
||||
* The client wants to bind to a seat. Devices associated with this
|
||||
* seat should be sent to the client.
|
||||
*/
|
||||
EIS_EVENT_DEVICE_ADDED,
|
||||
EIS_EVENT_SEAT_BIND,
|
||||
|
||||
/**
|
||||
* The device created by the client was removed. The server must
|
||||
* call eis_device_disconnect() in response to this device.
|
||||
*
|
||||
* libeis guarantees this event is generated before
|
||||
* @ref EIS_EVENT_CLIENT_DISCONNECT.
|
||||
* The client wants to unbind from this seat.
|
||||
*/
|
||||
EIS_EVENT_DEVICE_REMOVED,
|
||||
EIS_EVENT_SEAT_UNBIND,
|
||||
|
||||
/**
|
||||
* The client no longer listens to events from this device. The caller
|
||||
* should released resources associated with this device.
|
||||
*/
|
||||
EIS_EVENT_DEVICE_CLOSED,
|
||||
|
||||
EIS_EVENT_POINTER_MOTION = 300,
|
||||
EIS_EVENT_POINTER_MOTION_ABSOLUTE,
|
||||
|
|
@ -287,9 +287,10 @@ void
|
|||
eis_client_disconnect(struct eis_client *client);
|
||||
|
||||
/**
|
||||
* Create a new logical seat with a given name. Devices created by the
|
||||
* client must bind to a seat, or in other words: a client cannot create
|
||||
* devices until at least one seat is bound.
|
||||
* Create a new logical seat with a given name. Devices available to a
|
||||
* client belong to a bound seat, or in other words: a client cannot receive
|
||||
* events from a device until it binds to a seat and receives all devices from
|
||||
* that seat.
|
||||
*
|
||||
* This seat is not immediately active, use eis_seat_add() to bind this
|
||||
* seat on the client and notify the client of it's availability.
|
||||
|
|
@ -315,6 +316,10 @@ eis_seat_get_name(struct eis_seat *eis_seat);
|
|||
void *
|
||||
eis_seat_get_user_data(struct eis_seat *eis_seat);
|
||||
|
||||
bool
|
||||
eis_seat_has_capability(struct eis_seat *seat,
|
||||
enum eis_device_capability cap);
|
||||
|
||||
void
|
||||
eis_seat_set_user_data(struct eis_seat *eis_seat, void *user_data);
|
||||
|
||||
|
|
@ -329,7 +334,7 @@ eis_seat_set_user_data(struct eis_seat *eis_seat, void *user_data);
|
|||
* This function has no effect if called after eis_seat_add()
|
||||
*/
|
||||
void
|
||||
eis_seat_allow_capability(struct eis_seat *seat,
|
||||
eis_seat_configure_capability(struct eis_seat *seat,
|
||||
enum eis_device_capability cap);
|
||||
|
||||
/**
|
||||
|
|
@ -351,6 +356,9 @@ eis_event_get_type(struct eis_event *event);
|
|||
struct eis_client *
|
||||
eis_event_get_client(struct eis_event *event);
|
||||
|
||||
struct eis_seat *
|
||||
eis_event_get_seat(struct eis_event *event);
|
||||
|
||||
struct eis_client *
|
||||
eis_device_get_client(struct eis_device *device);
|
||||
|
||||
|
|
@ -389,47 +397,47 @@ eis_device_has_capability(struct eis_device *device,
|
|||
enum eis_device_capability cap);
|
||||
|
||||
/**
|
||||
* Allow a capability on the device. This function must be called in
|
||||
* response to an @ref EIS_EVENT_DEVICE_ADDED and before
|
||||
* eis_device_connect().
|
||||
* Create a new device with the given name and capabilities on the seat.
|
||||
*
|
||||
* This function has no effect if called for a capability the device does
|
||||
* not support. This function has no effect if called for a capability not
|
||||
* allowed on the seat this device belongs to.
|
||||
* This device is not immediately active, use eis_device_add() to
|
||||
* notify the client of it's availability.
|
||||
*
|
||||
* This function has no effect if called after eis_device_connect()
|
||||
* The returned device is refcounted, use eis_device_unref() to drop the
|
||||
* reference.
|
||||
*/
|
||||
struct eis_device *
|
||||
eis_device_new(struct eis_seat *seat);
|
||||
|
||||
void
|
||||
eis_device_allow_capability(struct eis_device *device,
|
||||
enum eis_device_capability cap);
|
||||
eis_device_configure_name(struct eis_device *device, const char *name);
|
||||
|
||||
void
|
||||
eis_device_configure_capability(struct eis_device *device, enum eis_device_capability cap);
|
||||
|
||||
void
|
||||
eis_device_configure_pointer_range(struct eis_device *device,
|
||||
uint32_t w, uint32_t h);
|
||||
void
|
||||
eis_device_configure_touch_range(struct eis_device *device,
|
||||
uint32_t w, uint32_t h);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Add this device to its seat and notify the client of the device's
|
||||
* availability.
|
||||
*
|
||||
* The device is suspended, use eis_device_resume() to enable events from
|
||||
* the client.
|
||||
*/
|
||||
void
|
||||
eis_device_connect(struct eis_device *device);
|
||||
eis_device_add(struct eis_device *device);
|
||||
|
||||
/**
|
||||
* Disconnect the device.
|
||||
* Remove the device.
|
||||
* This does not release any resources associated with this device, use
|
||||
* eis_device_unref() for any references held by the caller.
|
||||
*/
|
||||
void
|
||||
eis_device_disconnect(struct eis_device *device);
|
||||
eis_device_remove(struct eis_device *device);
|
||||
|
||||
/**
|
||||
* Notify the client that the device is suspended and that no events
|
||||
|
|
@ -592,6 +600,13 @@ void
|
|||
eis_device_keyboard_set_keymap(struct eis_device *device,
|
||||
struct eis_keymap *keymap);
|
||||
|
||||
/**
|
||||
* For an event of type @ref EIS_EVENT_SEAT_BIND, return the capabilities
|
||||
* requested by the client.
|
||||
*/
|
||||
bool
|
||||
eis_event_seat_has_capability(struct eis_event *event, enum eis_device_capability cap);
|
||||
|
||||
/**
|
||||
* Return the device from this event.
|
||||
*
|
||||
|
|
@ -610,7 +625,7 @@ eis_event_pointer_get_dx(struct eis_event *event);
|
|||
|
||||
/**
|
||||
* For an event of type @ref EIS_EVENT_POINTER_MOTION return the relative y
|
||||
* movement in logical pixels.
|
||||
uint32_* movement in logical pixels.
|
||||
*/
|
||||
double
|
||||
eis_event_pointer_get_dy(struct eis_event *event);
|
||||
|
|
|
|||
|
|
@ -49,8 +49,18 @@ struct peck {
|
|||
uint32_t ei_behavior;
|
||||
struct logger *logger;
|
||||
|
||||
/* The default seat/devices */
|
||||
struct eis_seat *eis_seat;
|
||||
struct eis_device *eis_pointer;
|
||||
struct eis_device *eis_keyboard;
|
||||
struct eis_device *eis_abs;
|
||||
struct eis_device *eis_touch;
|
||||
|
||||
struct ei_seat *ei_seat;
|
||||
struct ei_device *ei_pointer;
|
||||
struct ei_device *ei_keyboard;
|
||||
struct ei_device *ei_abs;
|
||||
struct ei_device *ei_touch;
|
||||
|
||||
struct eis_client *eis_client;
|
||||
|
||||
|
|
@ -88,9 +98,19 @@ peck_destroy(struct peck *peck)
|
|||
|
||||
eis_client_unref(peck->eis_client);
|
||||
|
||||
ei_seat_unref(peck->ei_seat);
|
||||
|
||||
eis_device_unref(peck->eis_pointer);
|
||||
eis_device_unref(peck->eis_abs);
|
||||
eis_device_unref(peck->eis_keyboard);
|
||||
eis_device_unref(peck->eis_touch);
|
||||
eis_seat_unref(peck->eis_seat);
|
||||
|
||||
ei_device_unref(peck->ei_pointer);
|
||||
ei_device_unref(peck->ei_abs);
|
||||
ei_device_unref(peck->ei_keyboard);
|
||||
ei_device_unref(peck->ei_touch);
|
||||
ei_seat_unref(peck->ei_seat);
|
||||
|
||||
ei_unref(peck->ei);
|
||||
eis_unref(peck->eis);
|
||||
logger_unref(peck->logger);
|
||||
|
|
@ -105,6 +125,10 @@ OBJECT_IMPLEMENT_GETTER(peck, eis, struct eis*);
|
|||
void
|
||||
peck_drop_ei(struct peck *peck)
|
||||
{
|
||||
peck->ei_pointer = ei_device_unref(peck->ei_pointer);
|
||||
peck->ei_keyboard = ei_device_unref(peck->ei_keyboard);
|
||||
peck->ei_abs = ei_device_unref(peck->ei_abs);
|
||||
peck->ei_touch = ei_device_unref(peck->ei_touch);
|
||||
peck->ei_seat = ei_seat_unref(peck->ei_seat);
|
||||
peck->ei = NULL;
|
||||
}
|
||||
|
|
@ -123,6 +147,34 @@ peck_eis_get_default_seat(struct peck *peck)
|
|||
return peck->eis_seat;
|
||||
};
|
||||
|
||||
struct eis_device *
|
||||
peck_eis_get_default_pointer(struct peck *peck)
|
||||
{
|
||||
munit_assert_ptr_not_null(peck->eis_pointer);
|
||||
return peck->eis_pointer;
|
||||
};
|
||||
|
||||
struct eis_device *
|
||||
peck_eis_get_default_pointer_absolute(struct peck *peck)
|
||||
{
|
||||
munit_assert_ptr_not_null(peck->eis_abs);
|
||||
return peck->eis_abs;
|
||||
};
|
||||
|
||||
struct eis_device *
|
||||
peck_eis_get_default_keyboard(struct peck *peck)
|
||||
{
|
||||
munit_assert_ptr_not_null(peck->eis_keyboard);
|
||||
return peck->eis_keyboard;
|
||||
};
|
||||
|
||||
struct eis_device *
|
||||
peck_eis_get_default_touch(struct peck *peck)
|
||||
{
|
||||
munit_assert_ptr_not_null(peck->eis_touch);
|
||||
return peck->eis_touch;
|
||||
};
|
||||
|
||||
struct ei_seat *
|
||||
peck_ei_get_default_seat(struct peck *peck)
|
||||
{
|
||||
|
|
@ -130,6 +182,34 @@ peck_ei_get_default_seat(struct peck *peck)
|
|||
return peck->ei_seat;
|
||||
}
|
||||
|
||||
struct ei_device *
|
||||
peck_ei_get_default_pointer(struct peck *peck)
|
||||
{
|
||||
munit_assert_ptr_not_null(peck->ei_pointer);
|
||||
return peck->ei_pointer;
|
||||
};
|
||||
|
||||
struct ei_device *
|
||||
peck_ei_get_default_pointer_absolute(struct peck *peck)
|
||||
{
|
||||
munit_assert_ptr_not_null(peck->ei_abs);
|
||||
return peck->ei_abs;
|
||||
};
|
||||
|
||||
struct ei_device *
|
||||
peck_ei_get_default_keyboard(struct peck *peck)
|
||||
{
|
||||
munit_assert_ptr_not_null(peck->ei_keyboard);
|
||||
return peck->ei_keyboard;
|
||||
};
|
||||
|
||||
struct ei_device *
|
||||
peck_ei_get_default_touch(struct peck *peck)
|
||||
{
|
||||
munit_assert_ptr_not_null(peck->ei_touch);
|
||||
return peck->ei_touch;
|
||||
};
|
||||
|
||||
static void
|
||||
peck_ei_log_handler(struct ei *ei,
|
||||
enum ei_log_priority priority,
|
||||
|
|
@ -220,7 +300,7 @@ peck_new(void)
|
|||
rc = ei_setup_backend_fd(ei, sv[0]);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
peck->ei = ei;
|
||||
flag_set(peck->ei_behavior, PECK_EI_BEHAVIOR_AUTOCONNNECT);
|
||||
flag_set(peck->ei_behavior, PECK_EI_BEHAVIOR_AUTOCONNECT);
|
||||
flag_set(peck->ei_behavior, PECK_EI_BEHAVIOR_AUTOSEAT);
|
||||
|
||||
struct eis *eis = eis_new(peck);
|
||||
|
|
@ -254,46 +334,37 @@ peck_enable_eis_behavior(struct peck *peck, enum peck_eis_behavior behavior)
|
|||
case PECK_EIS_BEHAVIOR_ACCEPT_ALL:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_DEVICE);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_BIND_SEAT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_REJECT_ALL:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_REJECT_CLIENT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_REJECT_DEVICE);
|
||||
case PECK_EIS_BEHAVIOR_ADD_DEVICES:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER_ABSOLUTE);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_TOUCH);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_DEVICE:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_POINTER);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_POINTER_ABSOLUTE);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_KEYBOARD);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_TOUCH);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_REJECT_DEVICE:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DROP_POINTER);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DROP_POINTER_ABSOLUTE);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DROP_KEYBOARD);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DROP_TOUCH);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_DROP_POINTER:
|
||||
case PECK_EIS_BEHAVIOR_DROP_POINTER_ABSOLUTE:
|
||||
case PECK_EIS_BEHAVIOR_DROP_KEYBOARD:
|
||||
case PECK_EIS_BEHAVIOR_DROP_TOUCH:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_DEVICE);
|
||||
_fallthrough_;
|
||||
case PECK_EIS_BEHAVIOR_REJECT_CLIENT:
|
||||
flag_clear(peck->eis_behavior, behavior - 1);
|
||||
flag_set(peck->eis_behavior, behavior);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_POINTER:
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_POINTER_ABSOLUTE:
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_KEYBOARD:
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_TOUCH:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_DEVICE);
|
||||
_fallthrough_;
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_CLIENT:
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_UNBIND_SEAT:
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_BIND_SEAT:
|
||||
flag_clear(peck->eis_behavior, behavior + 1);
|
||||
flag_set(peck->eis_behavior, behavior);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_HANDLE_DEVICE:
|
||||
case PECK_EIS_BEHAVIOR_REJECT_UNBIND_SEAT:
|
||||
case PECK_EIS_BEHAVIOR_REJECT_BIND_SEAT:
|
||||
flag_clear(peck->eis_behavior, behavior - 1);
|
||||
flag_set(peck->eis_behavior, behavior);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_ADD_POINTER:
|
||||
case PECK_EIS_BEHAVIOR_ADD_POINTER_ABSOLUTE:
|
||||
case PECK_EIS_BEHAVIOR_ADD_KEYBOARD:
|
||||
case PECK_EIS_BEHAVIOR_ADD_TOUCH:
|
||||
flag_set(peck->eis_behavior, behavior);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_CLIENT:
|
||||
flag_clear(peck->eis_behavior, behavior + 1);
|
||||
flag_set(peck->eis_behavior, behavior);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_RESUME_DEVICE:
|
||||
|
|
@ -314,12 +385,12 @@ peck_enable_ei_behavior(struct peck *peck, enum peck_ei_behavior behavior)
|
|||
case PECK_EI_BEHAVIOR_NONE:
|
||||
peck->ei_behavior = 0;
|
||||
break;
|
||||
case PECK_EI_BEHAVIOR_AUTOCONNNECT:
|
||||
case PECK_EI_BEHAVIOR_AUTOCONNECT:
|
||||
case PECK_EI_BEHAVIOR_AUTOSEAT:
|
||||
flag_set(peck->ei_behavior, behavior);
|
||||
break;
|
||||
case PECK_EI_BEHAVIOR_AUTODEVICES:
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOCONNNECT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOCONNECT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSEAT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_RESUMED);
|
||||
|
|
@ -346,12 +417,12 @@ peck_enable_ei_behavior(struct peck *peck, enum peck_ei_behavior behavior)
|
|||
static inline void
|
||||
peck_create_eis_seat(struct peck *peck, struct eis_client *client)
|
||||
{
|
||||
_unref_(eis_seat) *seat = eis_client_new_seat(client, "default");
|
||||
_unref_(eis_seat) *seat = eis_client_new_seat(client, "peck default seat");
|
||||
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_POINTER);
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_TOUCH);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_POINTER);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_TOUCH);
|
||||
|
||||
log_debug(peck, "EIS adding seat: '%s'\n", eis_seat_get_name(seat));
|
||||
eis_seat_add(seat);
|
||||
|
|
@ -376,46 +447,119 @@ peck_handle_eis_connect(struct peck *peck, struct eis_event *e)
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
peck_handle_eis_added(struct peck *peck, struct eis_event *e)
|
||||
static inline struct eis_device *
|
||||
peck_eis_create_pointer(struct peck *peck, struct eis_seat *seat, const char *name)
|
||||
{
|
||||
struct eis_device *device = eis_event_get_device(e);
|
||||
uint32_t mask = 0;
|
||||
struct map {
|
||||
enum eis_device_capability cap;
|
||||
enum peck_eis_behavior behavior;
|
||||
} map[] = {
|
||||
{ EIS_DEVICE_CAP_POINTER, PECK_EIS_BEHAVIOR_ACCEPT_POINTER },
|
||||
{ EIS_DEVICE_CAP_POINTER_ABSOLUTE, PECK_EIS_BEHAVIOR_ACCEPT_POINTER_ABSOLUTE },
|
||||
{ EIS_DEVICE_CAP_KEYBOARD, PECK_EIS_BEHAVIOR_ACCEPT_KEYBOARD },
|
||||
{ EIS_DEVICE_CAP_TOUCH, PECK_EIS_BEHAVIOR_ACCEPT_TOUCH },
|
||||
};
|
||||
struct map *m;
|
||||
struct eis_device *device = eis_device_new(seat);
|
||||
|
||||
ARRAY_FOR_EACH(map, m) {
|
||||
if (eis_device_has_capability(device, m->cap)) {
|
||||
if (flag_is_set(peck->eis_behavior, m->behavior)) {
|
||||
mask |= bit(m->cap);
|
||||
eis_device_allow_capability(device, m->cap);
|
||||
} else {
|
||||
log_debug(peck, "Dropping cap %d\n", m->cap);
|
||||
}
|
||||
}
|
||||
eis_device_configure_name(device, name);
|
||||
eis_device_configure_capability(device, EIS_DEVICE_CAP_POINTER);
|
||||
eis_device_add(device);
|
||||
|
||||
if (!peck->eis_pointer)
|
||||
peck->eis_pointer = eis_device_ref(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static inline struct eis_device *
|
||||
peck_eis_create_pointer_absolute(struct peck *peck, struct eis_seat *seat, const char *name)
|
||||
{
|
||||
struct eis_device *device = eis_device_new(seat);
|
||||
|
||||
eis_device_configure_name(device, name);
|
||||
eis_device_configure_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
eis_device_configure_pointer_range(device, 1920, 1080); /* FIXME */
|
||||
eis_device_add(device);
|
||||
|
||||
if (!peck->eis_abs)
|
||||
peck->eis_abs = eis_device_ref(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static inline struct eis_device *
|
||||
peck_eis_create_keyboard(struct peck *peck, struct eis_seat *seat, const char *name)
|
||||
{
|
||||
struct eis_device *device = eis_device_new(seat);
|
||||
|
||||
eis_device_configure_name(device, name);
|
||||
eis_device_configure_capability(device, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_device_add(device);
|
||||
|
||||
if (!peck->eis_keyboard)
|
||||
peck->eis_keyboard = eis_device_ref(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static inline struct eis_device *
|
||||
peck_eis_create_touch(struct peck *peck, struct eis_seat *seat, const char *name)
|
||||
{
|
||||
struct eis_device *device = eis_device_new(seat);
|
||||
|
||||
eis_device_configure_name(device, name);
|
||||
eis_device_configure_capability(device, EIS_DEVICE_CAP_TOUCH);
|
||||
eis_device_configure_touch_range(device, 1920, 1080); /* FIXME */
|
||||
eis_device_add(device);
|
||||
|
||||
if (!peck->eis_touch)
|
||||
peck->eis_touch = eis_device_ref(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static inline void
|
||||
peck_handle_eis_seat_bind(struct peck *peck, struct eis_event *e)
|
||||
{
|
||||
struct eis_seat *seat = eis_event_get_seat(e);
|
||||
|
||||
log_debug(peck, "EIS binding seat: '%s'\n", eis_seat_get_name(seat));
|
||||
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER) &&
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_POINTER)) {
|
||||
log_debug(peck, "EIS creating default pointer\n");
|
||||
_unref_(eis_device) *ptr = peck_eis_create_pointer(peck, seat, "default pointer");
|
||||
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(ptr);
|
||||
}
|
||||
|
||||
if (!mask) {
|
||||
log_debug(peck, "EIS refusing device: '%s'\n",
|
||||
eis_device_get_name(device));
|
||||
eis_device_disconnect(device);
|
||||
return false;
|
||||
} else {
|
||||
log_debug(peck, "EIS adding device: '%s'\n",
|
||||
eis_device_get_name(device));
|
||||
eis_device_connect(device);
|
||||
return true;
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER_ABSOLUTE) &&
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_POINTER_ABSOLUTE)) {
|
||||
log_debug(peck, "EIS creating default abs pointer\n");
|
||||
_unref_(eis_device) *abs = peck_eis_create_pointer_absolute(peck, seat, "default abs");
|
||||
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(abs);
|
||||
}
|
||||
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_KEYBOARD) &&
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_KEYBOARD)) {
|
||||
log_debug(peck, "EIS creating default keyboard\n");
|
||||
_unref_(eis_device) *kbd = peck_eis_create_keyboard(peck, seat, "default keyboard");
|
||||
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(kbd);
|
||||
}
|
||||
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_TOUCH) &&
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ADD_TOUCH)) {
|
||||
log_debug(peck, "EIS creating default touch\n");
|
||||
_unref_(eis_device) *touch = peck_eis_create_touch(peck, seat, "default touch");
|
||||
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(touch);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
peck_handle_eis_seat_unbind(struct peck *peck, struct eis_seat *seat)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
_peck_dispatch_eis(struct peck *peck, int lineno)
|
||||
{
|
||||
|
|
@ -440,9 +584,16 @@ _peck_dispatch_eis(struct peck *peck, int lineno)
|
|||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_REJECT_CLIENT))
|
||||
process_event = tristate_yes;
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_ADDED:
|
||||
case EIS_EVENT_DEVICE_REMOVED:
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_HANDLE_DEVICE))
|
||||
case EIS_EVENT_SEAT_BIND:
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ACCEPT_BIND_SEAT) ||
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_REJECT_BIND_SEAT))
|
||||
process_event = tristate_yes;
|
||||
else
|
||||
process_event = tristate_no;
|
||||
break;
|
||||
case EIS_EVENT_SEAT_UNBIND:
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ACCEPT_UNBIND_SEAT) ||
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_REJECT_UNBIND_SEAT))
|
||||
process_event = tristate_yes;
|
||||
else
|
||||
process_event = tristate_no;
|
||||
|
|
@ -474,14 +625,11 @@ _peck_dispatch_eis(struct peck *peck, int lineno)
|
|||
eis_client_get_name(eis_event_get_client(e)));
|
||||
eis_client_disconnect(eis_event_get_client(e));
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_ADDED:
|
||||
if (peck_handle_eis_added(peck, e) &&
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_RESUME_DEVICE))
|
||||
eis_device_resume(eis_event_get_device(e));
|
||||
case EIS_EVENT_SEAT_BIND:
|
||||
peck_handle_eis_seat_bind(peck, e);
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_REMOVED:
|
||||
log_debug(peck, "EIS removing device\n");
|
||||
eis_device_disconnect(eis_event_get_device(e));
|
||||
case EIS_EVENT_SEAT_UNBIND:
|
||||
peck_handle_eis_seat_unbind(peck, eis_event_get_seat(e));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -537,7 +685,7 @@ _peck_dispatch_ei(struct peck *peck, int lineno)
|
|||
switch (ei_event_get_type(e)) {
|
||||
case EI_EVENT_CONNECT:
|
||||
if (flag_is_set(peck->ei_behavior,
|
||||
PECK_EI_BEHAVIOR_AUTOCONNNECT))
|
||||
PECK_EI_BEHAVIOR_AUTOCONNECT))
|
||||
process_event = tristate_yes;
|
||||
break;
|
||||
case EI_EVENT_SEAT_ADDED:
|
||||
|
|
@ -585,10 +733,23 @@ _peck_dispatch_ei(struct peck *peck, int lineno)
|
|||
struct ei_seat *seat = ei_event_get_seat(e);
|
||||
munit_assert_ptr_null(peck->ei_seat);
|
||||
peck->ei_seat = ei_seat_ref(seat);
|
||||
log_debug(peck, "default seat: %s\n");
|
||||
log_debug(peck, "default seat: %s\n", ei_seat_get_name(peck->ei_seat));
|
||||
ei_seat_bind(seat);
|
||||
break;
|
||||
}
|
||||
case EI_EVENT_DEVICE_ADDED:
|
||||
{
|
||||
struct ei_device *device = ei_event_get_device(e);
|
||||
if (ei_device_has_capability(device, EI_DEVICE_CAP_POINTER))
|
||||
peck->ei_pointer = ei_device_ref(device);
|
||||
if (ei_device_has_capability(device, EI_DEVICE_CAP_POINTER_ABSOLUTE))
|
||||
peck->ei_abs = ei_device_ref(device);
|
||||
if (ei_device_has_capability(device, EI_DEVICE_CAP_KEYBOARD))
|
||||
peck->ei_keyboard = ei_device_ref(device);
|
||||
if (ei_device_has_capability(device, EI_DEVICE_CAP_TOUCH))
|
||||
peck->ei_touch = ei_device_ref(device);
|
||||
break;
|
||||
}
|
||||
case EI_EVENT_DEVICE_RESUMED:
|
||||
case EI_EVENT_DEVICE_SUSPENDED:
|
||||
/* Nothing to do here */
|
||||
|
|
@ -765,8 +926,9 @@ peck_eis_event_type_name(enum eis_event_type type)
|
|||
switch (type) {
|
||||
CASE_STRING(CLIENT_CONNECT);
|
||||
CASE_STRING(CLIENT_DISCONNECT);
|
||||
CASE_STRING(DEVICE_ADDED);
|
||||
CASE_STRING(DEVICE_REMOVED);
|
||||
CASE_STRING(SEAT_BIND);
|
||||
CASE_STRING(SEAT_UNBIND);
|
||||
CASE_STRING(DEVICE_CLOSED);
|
||||
CASE_STRING(POINTER_MOTION);
|
||||
CASE_STRING(POINTER_MOTION_ABSOLUTE);
|
||||
CASE_STRING(POINTER_BUTTON);
|
||||
|
|
|
|||
|
|
@ -43,24 +43,10 @@ enum peck_eis_behavior {
|
|||
*/
|
||||
PECK_EIS_BEHAVIOR_NONE,
|
||||
/**
|
||||
* Create a "default" seat. This behavior is enabled as part of
|
||||
* PECK_EIS_BEHAVIOR_ACCEPT_ALL.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_DEFAULT_SEAT,
|
||||
/**
|
||||
* Do not create a "default" seat.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_NO_DEFAULT_SEAT,
|
||||
/**
|
||||
* Accept all client connection requests and device additions
|
||||
* Accept all client connection requests, create default seats
|
||||
* **and** resume any device immediately after add.
|
||||
* This also enables @ref PECK_EIS_BEHAVIOR_DEFAULT_SEAT.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_ALL,
|
||||
/**
|
||||
* Reject any client connection requests or device additions.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_REJECT_ALL,
|
||||
|
||||
/**
|
||||
* Process connect/disconnect requests from the client.
|
||||
|
|
@ -69,23 +55,31 @@ enum peck_eis_behavior {
|
|||
PECK_EIS_BEHAVIOR_REJECT_CLIENT,
|
||||
|
||||
/**
|
||||
* Process add/remove requests from the client.
|
||||
* Create a "default" seat. This behavior is enabled as part of
|
||||
* PECK_EIS_BEHAVIOR_ACCEPT_ALL.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_HANDLE_DEVICE, /* Implied by the various ones below */
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_DEVICE,
|
||||
PECK_EIS_BEHAVIOR_REJECT_DEVICE,
|
||||
PECK_EIS_BEHAVIOR_DEFAULT_SEAT,
|
||||
/**
|
||||
* Do not create a "default" seat.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_NO_DEFAULT_SEAT,
|
||||
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_POINTER,
|
||||
PECK_EIS_BEHAVIOR_DROP_POINTER,
|
||||
/**
|
||||
* Accept or reject bind/unbind seat requests
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_BIND_SEAT,
|
||||
PECK_EIS_BEHAVIOR_REJECT_BIND_SEAT,
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_UNBIND_SEAT,
|
||||
PECK_EIS_BEHAVIOR_REJECT_UNBIND_SEAT,
|
||||
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_POINTER_ABSOLUTE,
|
||||
PECK_EIS_BEHAVIOR_DROP_POINTER_ABSOLUTE,
|
||||
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_KEYBOARD,
|
||||
PECK_EIS_BEHAVIOR_DROP_KEYBOARD,
|
||||
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_TOUCH,
|
||||
PECK_EIS_BEHAVIOR_DROP_TOUCH,
|
||||
/**
|
||||
* Create default devices
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_ADD_DEVICES, /**< add all of the below */
|
||||
PECK_EIS_BEHAVIOR_ADD_POINTER,
|
||||
PECK_EIS_BEHAVIOR_ADD_POINTER_ABSOLUTE,
|
||||
PECK_EIS_BEHAVIOR_ADD_KEYBOARD,
|
||||
PECK_EIS_BEHAVIOR_ADD_TOUCH,
|
||||
|
||||
PECK_EIS_BEHAVIOR_RESUME_DEVICE,
|
||||
PECK_EIS_BEHAVIOR_SUSPEND_DEVICE,
|
||||
|
|
@ -94,9 +88,9 @@ enum peck_eis_behavior {
|
|||
enum peck_ei_behavior {
|
||||
PECK_EI_BEHAVIOR_NONE,
|
||||
/* enabled by default - handle the Connect event */
|
||||
PECK_EI_BEHAVIOR_AUTOCONNNECT,
|
||||
PECK_EI_BEHAVIOR_AUTOCONNECT,
|
||||
/* enabled by default - handle the first seat added event, setting
|
||||
* the default seat to the first seat */
|
||||
* the default seat to the first seat and bind to it */
|
||||
PECK_EI_BEHAVIOR_AUTOSEAT,
|
||||
/* handle Connect/Seat/Added/Resumed events, i.e. anything until the
|
||||
* first real device event */
|
||||
|
|
@ -137,9 +131,33 @@ peck_eis_get_default_client(struct peck *peck);
|
|||
struct eis_seat *
|
||||
peck_eis_get_default_seat(struct peck *peck);
|
||||
|
||||
struct eis_device *
|
||||
peck_eis_get_default_pointer(struct peck *peck);
|
||||
|
||||
struct eis_device *
|
||||
peck_eis_get_default_keyboard(struct peck *peck);
|
||||
|
||||
struct eis_device *
|
||||
peck_eis_get_default_pointer_absolute(struct peck *peck);
|
||||
|
||||
struct eis_device *
|
||||
peck_eis_get_default_touch(struct peck *peck);
|
||||
|
||||
struct ei_seat *
|
||||
peck_ei_get_default_seat(struct peck *peck);
|
||||
|
||||
struct ei_device *
|
||||
peck_ei_get_default_pointer(struct peck *peck);
|
||||
|
||||
struct ei_device *
|
||||
peck_ei_get_default_keyboard(struct peck *peck);
|
||||
|
||||
struct ei_device *
|
||||
peck_ei_get_default_pointer_absolute(struct peck *peck);
|
||||
|
||||
struct ei_device *
|
||||
peck_ei_get_default_touch(struct peck *peck);
|
||||
|
||||
/**
|
||||
* Dispatch all events according to the currently defined behavior.
|
||||
* When this function returns false, the connection is in a "stable" state
|
||||
|
|
@ -241,6 +259,7 @@ DEFINE_UNREF_CLEANUP_FUNC(ei_event);
|
|||
DEFINE_UNREF_CLEANUP_FUNC(ei_device);
|
||||
DEFINE_UNREF_CLEANUP_FUNC(ei_touch);
|
||||
DEFINE_UNREF_CLEANUP_FUNC(ei_keymap);
|
||||
DEFINE_UNREF_CLEANUP_FUNC(ei_seat);
|
||||
|
||||
DEFINE_UNREF_CLEANUP_FUNC(eis);
|
||||
DEFINE_UNREF_CLEANUP_FUNC(eis_client);
|
||||
|
|
|
|||
769
test/test-ei.c
769
test/test-ei.c
File diff suppressed because it is too large
Load diff
196
test/test-eis.c
196
test/test-eis.c
|
|
@ -76,6 +76,73 @@ MUNIT_TEST(eistest_name)
|
|||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(eistest_cliend_bind_all_caps)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
struct ei_seat *seat = peck_ei_get_default_seat(peck);
|
||||
ei_seat_bind(seat);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *event =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
|
||||
/* Our default seat has all caps */
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_TOUCH));
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(eistest_cliend_bind_some_caps)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOCONNECT);
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
_unref_(ei_event) *event =
|
||||
peck_ei_next_event(ei, EI_EVENT_SEAT_ADDED);
|
||||
struct ei_seat *seat = ei_event_get_seat(event);
|
||||
ei_seat_drop_capability(seat, EI_DEVICE_CAP_KEYBOARD);
|
||||
ei_seat_drop_capability(seat, EI_DEVICE_CAP_TOUCH);
|
||||
ei_seat_bind(seat);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *event =
|
||||
peck_eis_next_event(eis, EIS_EVENT_SEAT_BIND);
|
||||
|
||||
/* Our default seat has all caps */
|
||||
munit_assert_false(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_KEYBOARD));
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_POINTER));
|
||||
munit_assert_true(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_POINTER_ABSOLUTE));
|
||||
munit_assert_false(eis_event_seat_has_capability(event, EIS_DEVICE_CAP_TOUCH));
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
MUNIT_TEST(eistest_ranges)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
|
|
@ -112,33 +179,22 @@ MUNIT_TEST(eistest_ranges)
|
|||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
MUNIT_TEST(eistest_device_resume_suspend_twice)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
_unref_(eis_device) *device = NULL;
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
struct ei_seat *seat = peck_ei_get_default_seat(peck);
|
||||
_unref_(ei_device) *d = ei_device_new(seat);
|
||||
ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER);
|
||||
ei_device_add(d);
|
||||
}
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_BIND_SEAT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *added =
|
||||
peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED);
|
||||
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
||||
|
||||
device = eis_device_ref(eis_event_get_device(added));
|
||||
|
||||
eis_device_allow_capability(device, EIS_DEVICE_CAP_POINTER);
|
||||
eis_device_connect(device);
|
||||
/* Resuming multiple times should only trigger one event */
|
||||
eis_device_resume(device);
|
||||
eis_device_resume(device); /* noop */
|
||||
|
|
@ -148,14 +204,6 @@ MUNIT_TEST(eistest_device_resume_suspend_twice)
|
|||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
_unref_(ei_event) *added =
|
||||
peck_ei_next_event(ei, EI_EVENT_DEVICE_ADDED);
|
||||
|
||||
/* _until_stable() may stop after DEVICE_ADDED since it's
|
||||
* punting to the caller, so we need another dispatch to
|
||||
* make sure the RESUMED is really waiting for us here */
|
||||
ei_dispatch(ei);
|
||||
|
||||
_unref_(ei_event) *resumed =
|
||||
peck_ei_next_event(ei, EI_EVENT_DEVICE_RESUMED);
|
||||
|
||||
|
|
@ -164,6 +212,8 @@ MUNIT_TEST(eistest_device_resume_suspend_twice)
|
|||
|
||||
/* Suspending multiple times should only trigger one event */
|
||||
with_server(peck) {
|
||||
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
||||
|
||||
eis_device_suspend(device);
|
||||
eis_device_suspend(device); /* noop */
|
||||
eis_device_suspend(device); /* noop */
|
||||
|
|
@ -181,34 +231,14 @@ MUNIT_TEST(eistest_device_resume_suspend_twice)
|
|||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(eistest_device_ignore_suspended)
|
||||
MUNIT_TEST(eistest_device_ignore_suspended_device)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
_unref_(eis_device) *device = NULL;
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
struct ei_seat *seat = peck_ei_get_default_seat(peck);
|
||||
_unref_(ei_device) *d = ei_device_new(seat);
|
||||
ei_device_configure_capability(d, EI_DEVICE_CAP_POINTER);
|
||||
ei_device_add(d);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *added =
|
||||
peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED);
|
||||
|
||||
device = eis_device_ref(eis_event_get_device(added));
|
||||
|
||||
eis_device_allow_capability(device, EIS_DEVICE_CAP_POINTER);
|
||||
eis_device_connect(device);
|
||||
}
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_BIND_SEAT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
|
|
@ -220,7 +250,10 @@ MUNIT_TEST(eistest_device_ignore_suspended)
|
|||
ei_device_pointer_motion(device, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
struct eis_device *device = peck_eis_get_default_pointer(peck);
|
||||
|
||||
/* Device is suspended */
|
||||
with_server(peck) {
|
||||
peck_assert_no_eis_events(eis);
|
||||
|
|
@ -264,72 +297,3 @@ MUNIT_TEST(eistest_device_ignore_suspended)
|
|||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(eistest_device_late_connect)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
_unref_(eis_device) *eis_device = NULL;
|
||||
_unref_(ei_device) *ei_device = NULL;
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
struct ei_seat *seat = peck_ei_get_default_seat(peck);
|
||||
ei_device = ei_device_new(seat);
|
||||
ei_device_configure_capability(ei_device, EI_DEVICE_CAP_POINTER);
|
||||
ei_device_add(ei_device);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *added =
|
||||
peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED);
|
||||
eis_device = eis_device_ref(eis_event_get_device(added));
|
||||
/* Do not connect here */
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
/* remove before server accepted */
|
||||
ei_device_remove(ei_device);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
/* libeis will confirm removal automatically, so this is a
|
||||
* noop - the device is already removed */
|
||||
eis_device_allow_capability(eis_device, EIS_DEVICE_CAP_POINTER);
|
||||
eis_device_connect(eis_device);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *removed =
|
||||
peck_eis_next_event(eis, EIS_EVENT_DEVICE_REMOVED);
|
||||
peck_assert_no_eis_events(eis);
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
/* We never get an added event, the removed event is already
|
||||
* handled before we get to it */
|
||||
_unref_(ei_event) *removed =
|
||||
peck_ei_next_event(ei, EI_EVENT_DEVICE_REMOVED);
|
||||
peck_assert_no_ei_events(ei);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
return munit_tests_run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
8
test/test-main.c
Normal file
8
test/test-main.c
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "util-munit.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
return munit_tests_run(argc, argv);
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +71,7 @@ DEFINE_UNREF_CLEANUP_FUNC(xkb_keymap);
|
|||
DEFINE_UNREF_CLEANUP_FUNC(xkb_state);
|
||||
#endif
|
||||
|
||||
#if 0 /* FIXME: needs keymap revamp */
|
||||
static void
|
||||
setup_keymap(struct ei_device *kbd, const char *layout)
|
||||
{
|
||||
|
|
@ -104,6 +105,7 @@ setup_keymap(struct ei_device *kbd, const char *layout)
|
|||
memfile_unref(f);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
handle_keymap(struct ei_event *event)
|
||||
|
|
@ -158,7 +160,7 @@ int main(int argc, char **argv)
|
|||
PORTAL,
|
||||
} backend = SOCKET;
|
||||
bool verbose = false;
|
||||
const char *layout = NULL;
|
||||
_unused_ const char *layout = NULL;
|
||||
|
||||
_cleanup_free_ char *busname = xstrdup("org.freedesktop.portal.Desktop");
|
||||
|
||||
|
|
@ -276,39 +278,50 @@ int main(int argc, char **argv)
|
|||
}
|
||||
default_seat = ei_seat_ref(ei_event_get_seat(e));
|
||||
colorprint("seat added: %s\n", ei_seat_get_name(default_seat));
|
||||
ptr = ei_device_new(default_seat);
|
||||
ei_device_configure_capability(ptr, EI_DEVICE_CAP_POINTER);
|
||||
|
||||
kbd = ei_device_new(default_seat);
|
||||
ei_device_configure_capability(kbd, EI_DEVICE_CAP_KEYBOARD);
|
||||
if (layout)
|
||||
setup_keymap(kbd, layout);
|
||||
|
||||
ei_device_add(ptr);
|
||||
ei_device_add(kbd);
|
||||
ei_seat_bind(default_seat);
|
||||
break;
|
||||
}
|
||||
case EI_EVENT_SEAT_REMOVED:
|
||||
/* Don't need to close the devices, libei will
|
||||
* give us the right events */
|
||||
if (ei_event_get_seat(e) == default_seat)
|
||||
default_seat = ei_seat_unref(default_seat);
|
||||
break;
|
||||
case EI_EVENT_DEVICE_ADDED:
|
||||
colorprint("our device was accepted, waiting for resume\n");
|
||||
handle_keymap(e);
|
||||
{
|
||||
struct ei_device *device = ei_event_get_device(e);
|
||||
|
||||
if (ei_device_has_capability(device, EI_DEVICE_CAP_POINTER)) {
|
||||
colorprint("New pointer device: %s\n", ei_device_get_name(device));
|
||||
ptr = device;
|
||||
}
|
||||
if (ei_device_has_capability(device, EI_DEVICE_CAP_KEYBOARD)) {
|
||||
colorprint("New keyboard device: %s\n", ei_device_get_name(device));
|
||||
kbd = device;
|
||||
/* FIXME */
|
||||
handle_keymap(e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EI_EVENT_DEVICE_RESUMED:
|
||||
colorprint("our device was resumed\n");
|
||||
if (ei_event_get_device(e) == ptr)
|
||||
if (ei_event_get_device(e) == ptr) {
|
||||
colorprint("Pointer device was resumed\n");
|
||||
have_ptr = true;
|
||||
if (ei_event_get_device(e) == kbd)
|
||||
}
|
||||
if (ei_event_get_device(e) == kbd) {
|
||||
colorprint("Keybaord device was resumed\n");
|
||||
have_kbd = true;
|
||||
}
|
||||
break;
|
||||
case EI_EVENT_DEVICE_SUSPENDED:
|
||||
colorprint("our device was suspended\n");
|
||||
if (ei_event_get_device(e) == ptr)
|
||||
if (ei_event_get_device(e) == ptr) {
|
||||
colorprint("Pointer device was resumed\n");
|
||||
have_ptr = false;
|
||||
if (ei_event_get_device(e) == kbd)
|
||||
}
|
||||
if (ei_event_get_device(e) == kbd) {
|
||||
colorprint("Keyboard device was resumed\n");
|
||||
have_kbd = false;
|
||||
}
|
||||
break;
|
||||
case EI_EVENT_DEVICE_REMOVED:
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct libevdev_uinput *, libevdev_uinput_destroy);
|
|||
#define _cleanup_libevdev_ _cleanup_(libevdev_freep)
|
||||
#define _cleanup_libevdev_uinput_ _cleanup_(libevdev_uinput_destroyp)
|
||||
DEFINE_UNREF_CLEANUP_FUNC(eis_seat);
|
||||
DEFINE_UNREF_CLEANUP_FUNC(eis_device);
|
||||
|
||||
static inline void
|
||||
_printf_(1, 2)
|
||||
|
|
@ -61,10 +62,15 @@ struct uinput_context {
|
|||
};
|
||||
|
||||
static int
|
||||
create_mouse(struct eis_demo_server *server, struct eis_device *device)
|
||||
create_mouse(struct eis_demo_server *server, struct eis_seat *seat,
|
||||
struct eis_device **device_return)
|
||||
{
|
||||
struct eis_client *client = eis_device_get_client(device);
|
||||
struct eis_client *client = eis_seat_get_client(seat);
|
||||
_cleanup_free_ char *devicename = xaprintf("%s pointer", eis_client_get_name(client));
|
||||
_unref_(eis_device) *device = eis_device_new(seat);
|
||||
|
||||
eis_device_configure_name(device, devicename);
|
||||
eis_device_configure_capability(device, EIS_DEVICE_CAP_POINTER);
|
||||
|
||||
_cleanup_libevdev_ struct libevdev *dev = libevdev_new();
|
||||
libevdev_set_name(dev, devicename);
|
||||
|
|
@ -83,15 +89,21 @@ create_mouse(struct eis_demo_server *server, struct eis_device *device)
|
|||
if (err == 0) {
|
||||
colorprint("Pointer device is %s\n", libevdev_uinput_get_devnode(uinput));
|
||||
eis_device_set_user_data(device, steal(&uinput));
|
||||
*device_return = steal(&device);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
create_keyboard(struct eis_demo_server *server, struct eis_device *device)
|
||||
create_keyboard(struct eis_demo_server *server, struct eis_seat *seat,
|
||||
struct eis_device **device_return)
|
||||
{
|
||||
struct eis_client *client = eis_device_get_client(device);
|
||||
struct eis_client *client = eis_seat_get_client(seat);
|
||||
_cleanup_free_ char *devicename = xaprintf("%s keyboard", eis_client_get_name(client));
|
||||
_unref_(eis_device) *device = eis_device_new(seat);
|
||||
|
||||
eis_device_configure_name(device, devicename);
|
||||
eis_device_configure_capability(device, EIS_DEVICE_CAP_KEYBOARD);
|
||||
|
||||
_cleanup_libevdev_ struct libevdev *dev = libevdev_new();
|
||||
libevdev_set_name(dev, devicename);
|
||||
|
|
@ -103,11 +115,11 @@ create_keyboard(struct eis_demo_server *server, struct eis_device *device)
|
|||
if (err == 0) {
|
||||
colorprint("Keyboard device is %s\n", libevdev_uinput_get_devnode(uinput));
|
||||
eis_device_set_user_data(device, steal(&uinput));
|
||||
*device_return = steal(&device);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
eis_demo_server_uinput_handle_event(struct eis_demo_server *server,
|
||||
struct eis_event *e)
|
||||
|
|
@ -120,10 +132,10 @@ eis_demo_server_uinput_handle_event(struct eis_demo_server *server,
|
|||
colorprint("new client: %s, accepting. creating new seat 'default'\n", eis_client_get_name(client));
|
||||
|
||||
_unref_(eis_seat) *seat = eis_client_new_seat(client, "default");
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_POINTER);
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_TOUCH);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_POINTER);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_TOUCH);
|
||||
eis_seat_add(seat);
|
||||
break;
|
||||
}
|
||||
|
|
@ -134,46 +146,46 @@ eis_demo_server_uinput_handle_event(struct eis_demo_server *server,
|
|||
eis_client_disconnect(client);
|
||||
break;
|
||||
}
|
||||
case EIS_EVENT_DEVICE_ADDED:
|
||||
case EIS_EVENT_SEAT_BIND:
|
||||
{
|
||||
struct eis_device *device = eis_event_get_device(e);
|
||||
colorprint("new device, caps:%s%s%s%s\n",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER) ? " ptr" : "",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_KEYBOARD) ? " kbd" : "",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE) ? " abs" : "",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH) ? " touch" : "");
|
||||
struct eis_seat *seat = eis_event_get_seat(e);
|
||||
|
||||
if (eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER)) {
|
||||
eis_device_allow_capability(device, EIS_DEVICE_CAP_POINTER);
|
||||
int rc = create_mouse(server, device);
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_POINTER)) {
|
||||
struct eis_device *device = NULL;
|
||||
int rc = create_mouse(server, seat, &device);
|
||||
if (rc != 0) {
|
||||
colorprint("Failed to create device: %s\n", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
eis_device_connect(device);
|
||||
eis_device_add(device);
|
||||
eis_device_resume(device);
|
||||
} else if (eis_device_has_capability(device, EIS_DEVICE_CAP_KEYBOARD)) {
|
||||
eis_device_allow_capability(device, EIS_DEVICE_CAP_KEYBOARD);
|
||||
int rc = create_keyboard(server, device);
|
||||
}
|
||||
if (eis_event_seat_has_capability(e, EIS_DEVICE_CAP_KEYBOARD)) {
|
||||
struct eis_device *device = NULL;
|
||||
int rc = create_keyboard(server, seat, &device);
|
||||
if (rc != 0) {
|
||||
colorprint("Failed to create device: %s\n", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
eis_device_connect(device);
|
||||
eis_device_add(device);
|
||||
eis_device_resume(device);
|
||||
} else {
|
||||
colorprint("No supported capabilities found\n");
|
||||
eis_device_disconnect(device);
|
||||
}
|
||||
/* Note: our device has a dangling ref here. It's a
|
||||
* demo-server so we can just ignore that */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EIS_EVENT_DEVICE_REMOVED:
|
||||
case EIS_EVENT_SEAT_UNBIND:
|
||||
/* FIXME */
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_CLOSED:
|
||||
{
|
||||
struct eis_device *device = eis_event_get_device(e);
|
||||
colorprint("device removed\n");
|
||||
colorprint("device closed\n");
|
||||
struct libevdev_uinput *uinput = eis_device_get_user_data(device);
|
||||
if (uinput)
|
||||
libevdev_uinput_destroy(uinput);
|
||||
eis_device_remove(device);
|
||||
eis_device_unref(device); /* because we know we have a dangling ref */
|
||||
break;
|
||||
}
|
||||
case EIS_EVENT_POINTER_MOTION:
|
||||
|
|
|
|||
|
|
@ -203,10 +203,10 @@ eis_demo_server_printf_handle_event(struct eis_demo_server *server,
|
|||
eis_client_connect(client);
|
||||
colorprint("accepting client, creating new seat 'default'\n");
|
||||
_unref_(eis_seat) *seat = eis_client_new_seat(client, "default");
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_POINTER);
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_seat_allow_capability(seat, EIS_DEVICE_CAP_TOUCH);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_POINTER);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_TOUCH);
|
||||
eis_seat_add(seat);
|
||||
break;
|
||||
}
|
||||
|
|
@ -217,31 +217,48 @@ eis_demo_server_printf_handle_event(struct eis_demo_server *server,
|
|||
eis_client_disconnect(client);
|
||||
break;
|
||||
}
|
||||
case EIS_EVENT_DEVICE_ADDED:
|
||||
case EIS_EVENT_SEAT_BIND:
|
||||
{
|
||||
struct eis_device *device = eis_event_get_device(e);
|
||||
colorprint("new device, caps:%s%s%s%s\n",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER) ? " ptr" : "",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_KEYBOARD) ? " kbd" : "",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE) ? " abs" : "",
|
||||
eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH) ? " touch" : "");
|
||||
struct eis_client *client = eis_event_get_client(e);
|
||||
struct eis_seat *seat = eis_event_get_seat(e);
|
||||
struct eis_device *ptr = eis_device_new(seat);
|
||||
|
||||
eis_device_allow_capability(device, EIS_DEVICE_CAP_POINTER);
|
||||
eis_device_allow_capability(device, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
eis_device_allow_capability(device, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_device_allow_capability(device, EIS_DEVICE_CAP_TOUCH);
|
||||
eis_device_configure_name(ptr, "test pointer");
|
||||
eis_device_configure_capability(ptr, EIS_DEVICE_CAP_POINTER);
|
||||
colorprint("Creating pointer device %s for %s\n", eis_device_get_name(ptr),
|
||||
eis_client_get_name(client));
|
||||
eis_device_add(ptr);
|
||||
eis_device_resume(ptr);
|
||||
/* ptr ref is dangling */
|
||||
|
||||
setup_keymap(server, device);
|
||||
/* insert sophisticated device checks here */
|
||||
eis_device_connect(device);
|
||||
eis_device_resume(device);
|
||||
break;
|
||||
|
||||
struct eis_device *kbd = eis_device_new(seat);
|
||||
eis_device_configure_name(kbd, "test keyboard");
|
||||
/* FIXME: review keymaps */
|
||||
setup_keymap(server, kbd);
|
||||
eis_device_configure_capability(ptr, EIS_DEVICE_CAP_KEYBOARD);
|
||||
colorprint("Creating keyboard device %s for %s\n", eis_device_get_name(kbd),
|
||||
eis_client_get_name(client));
|
||||
eis_device_add(kbd);
|
||||
eis_device_resume(kbd);
|
||||
/* kbd ref is dangling */
|
||||
}
|
||||
case EIS_EVENT_DEVICE_REMOVED:
|
||||
break;
|
||||
case EIS_EVENT_SEAT_UNBIND:
|
||||
{
|
||||
colorprint("device removed\n");
|
||||
break;
|
||||
struct eis_seat *seat = eis_event_get_seat(e);
|
||||
/* FIXME: remove all devices? we need a devices_foreach
|
||||
* function on the eis seat */
|
||||
eis_seat_remove(seat);
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_CLOSED:
|
||||
{
|
||||
struct eis_device *device = eis_event_get_device(e);
|
||||
eis_device_remove(device);
|
||||
eis_device_unref(device); /* because our devices have a dangling */
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_POINTER_MOTION:
|
||||
{
|
||||
colorprint("motion by %.2f/%.2f\n",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue