mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-05-01 23:18:56 +02:00
libeis: switch the keymap to be a separate object
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
937f9fd8c5
commit
7318512a89
8 changed files with 205 additions and 108 deletions
|
|
@ -179,12 +179,8 @@ _public_
|
|||
OBJECT_IMPLEMENT_GETTER(ei_keymap, fd, int);
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(ei_keymap, size, size_t);
|
||||
|
||||
_public_ struct ei_device *
|
||||
ei_keymap_get_device(struct ei_keymap *keymap)
|
||||
{
|
||||
return keymap->device;
|
||||
}
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(ei_keymap, device, struct ei_device *);
|
||||
|
||||
static void
|
||||
ei_keymap_destroy(struct ei_keymap *keymap)
|
||||
|
|
@ -276,6 +272,9 @@ ei_device_set_keymap(struct ei_device *device,
|
|||
{
|
||||
device->keymap = ei_keymap_unref(device->keymap);
|
||||
|
||||
if (!type)
|
||||
return;
|
||||
|
||||
_cleanup_ei_keymap_ struct ei_keymap *keymap = ei_keymap_new(type, keymap_fd, size);
|
||||
if (!keymap) {
|
||||
log_bug(ei_device_get_context(device),
|
||||
|
|
|
|||
|
|
@ -31,11 +31,84 @@
|
|||
|
||||
#include "libeis-private.h"
|
||||
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_REF(eis_keymap);
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_UNREF(eis_keymap);
|
||||
#define _cleanup_eis_keymap_ _cleanup_(eis_keymap_cleanup)
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(eis_keymap, type, enum eis_keymap_type);
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(eis_keymap, fd, int);
|
||||
_public_
|
||||
OBJECT_IMPLEMENT_GETTER(eis_keymap, size, size_t);
|
||||
|
||||
static void
|
||||
eis_keymap_destroy(struct eis_keymap *keymap)
|
||||
{
|
||||
xclose(keymap->fd);
|
||||
}
|
||||
|
||||
static
|
||||
OBJECT_IMPLEMENT_CREATE(eis_keymap);
|
||||
|
||||
_public_ struct eis_keymap *
|
||||
eis_keymap_new(enum eis_keymap_type type, int fd, size_t size)
|
||||
{
|
||||
_cleanup_eis_keymap_ struct eis_keymap *keymap = eis_keymap_create(NULL);
|
||||
|
||||
switch (type) {
|
||||
case EIS_KEYMAP_TYPE_XKB:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fd < 0 || size == 0)
|
||||
return NULL;
|
||||
|
||||
int newfd = dup(fd);
|
||||
if (newfd < 0)
|
||||
return NULL;
|
||||
|
||||
keymap->fd = newfd;
|
||||
keymap->type = type;
|
||||
keymap->size = size;
|
||||
|
||||
return eis_keymap_ref(keymap);
|
||||
}
|
||||
|
||||
_public_ void
|
||||
eis_device_keyboard_set_keymap(struct eis_device *device,
|
||||
struct eis_keymap *keymap)
|
||||
{
|
||||
if (device->state != EIS_DEVICE_STATE_NEW)
|
||||
return;
|
||||
|
||||
if (device->keymap && !device->keymap->is_client_keymap)
|
||||
return;
|
||||
|
||||
if (keymap && keymap->assigned)
|
||||
return;
|
||||
|
||||
device->keymap = eis_keymap_unref(device->keymap);
|
||||
if (keymap) {
|
||||
keymap->assigned = true;
|
||||
device->keymap = eis_keymap_ref(keymap);
|
||||
}
|
||||
}
|
||||
|
||||
_public_ struct eis_keymap *
|
||||
eis_device_keyboard_get_keymap(struct eis_device *device)
|
||||
{
|
||||
return device->keymap;
|
||||
}
|
||||
|
||||
static void
|
||||
eis_device_destroy(struct eis_device *device)
|
||||
{
|
||||
eis_keymap_unref(device->keymap);
|
||||
free(device->name);
|
||||
xclose(device->keymap.fd);
|
||||
}
|
||||
|
||||
_public_
|
||||
|
|
@ -83,11 +156,6 @@ eis_device_new(struct eis_client *client,
|
|||
device->id = id;
|
||||
device->state = EIS_DEVICE_STATE_NEW;
|
||||
|
||||
device->keymap.server_overrides = false;
|
||||
device->keymap.fd = -1;
|
||||
device->keymap.type = EIS_KEYMAP_TYPE_NONE;
|
||||
device->keymap.size = 0;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
|
@ -115,24 +183,14 @@ eis_device_set_client_keymap(struct eis_device *device,
|
|||
if (device->state != EIS_DEVICE_STATE_NEW)
|
||||
return;
|
||||
|
||||
device->keymap.fd = dup(keymap_fd);
|
||||
device->keymap.type = type;
|
||||
device->keymap.size = size;
|
||||
}
|
||||
|
||||
_public_ void
|
||||
eis_device_keyboard_set_keymap(struct eis_device *device,
|
||||
enum eis_keymap_type type,
|
||||
int keymap_fd, size_t size)
|
||||
{
|
||||
if (device->state != EIS_DEVICE_STATE_NEW)
|
||||
_cleanup_eis_keymap_ struct eis_keymap *keymap =
|
||||
eis_keymap_new(type, keymap_fd, size);
|
||||
if (!keymap)
|
||||
return;
|
||||
|
||||
device->keymap.type = type;
|
||||
xclose(device->keymap.fd);
|
||||
device->keymap.fd = dup(keymap_fd);
|
||||
device->keymap.server_overrides = true;
|
||||
device->keymap.size = size;
|
||||
eis_device_keyboard_set_keymap(device, keymap);
|
||||
keymap->is_client_keymap = true;
|
||||
keymap->assigned = true;
|
||||
}
|
||||
|
||||
_public_ bool
|
||||
|
|
@ -187,24 +245,6 @@ eis_device_touch_get_height(struct eis_device *device)
|
|||
return device->touch.dim.height;
|
||||
}
|
||||
|
||||
_public_ enum eis_keymap_type
|
||||
eis_device_keyboard_get_keymap_type(struct eis_device *device)
|
||||
{
|
||||
return device->keymap.type;
|
||||
}
|
||||
|
||||
_public_ size_t
|
||||
eis_device_keyboard_get_keymap_size(struct eis_device *device)
|
||||
{
|
||||
return device->keymap.size;
|
||||
}
|
||||
|
||||
_public_ int
|
||||
eis_device_keyboard_get_keymap(struct eis_device *device)
|
||||
{
|
||||
return device->keymap.fd;
|
||||
}
|
||||
|
||||
int
|
||||
eis_device_pointer_rel(struct eis_device *device,
|
||||
double x, double y)
|
||||
|
|
|
|||
|
|
@ -103,12 +103,7 @@ struct eis_device {
|
|||
struct dimensions dim;
|
||||
} touch;
|
||||
|
||||
struct {
|
||||
bool server_overrides;
|
||||
enum eis_keymap_type type;
|
||||
int fd;
|
||||
size_t size;
|
||||
} keymap;
|
||||
struct eis_keymap *keymap;
|
||||
};
|
||||
|
||||
struct eis_event {
|
||||
|
|
@ -136,6 +131,16 @@ struct eis_event {
|
|||
};
|
||||
};
|
||||
|
||||
struct eis_keymap {
|
||||
struct object object;
|
||||
struct eis_device *device;
|
||||
enum eis_keymap_type type;
|
||||
int fd;
|
||||
size_t size;
|
||||
bool assigned;
|
||||
bool is_client_keymap;
|
||||
};
|
||||
|
||||
void
|
||||
eis_init_object(struct eis *eis, struct object *parent);
|
||||
|
||||
|
|
@ -183,11 +188,6 @@ eis_device_set_client_keymap(struct eis_device *device,
|
|||
enum eis_keymap_type type,
|
||||
int keymap_fd, size_t size);
|
||||
|
||||
void
|
||||
eis_device_keyboard_set_keymap(struct eis_device *device,
|
||||
enum eis_keymap_type type,
|
||||
int keymap_fd, size_t size);
|
||||
|
||||
int
|
||||
eis_device_pointer_rel(struct eis_device *device,
|
||||
double x, double y);
|
||||
|
|
|
|||
|
|
@ -142,21 +142,26 @@ eis_proto_send_device_added(struct eis_client *client, struct eis_device *device
|
|||
{
|
||||
ServerMessage msg = SERVER_MESSAGE__INIT;
|
||||
DeviceAdded added = DEVICE_ADDED__INIT;
|
||||
int fds[2] = {-1, -1};
|
||||
|
||||
added.deviceid = device->id;
|
||||
added.name = device->name;
|
||||
added.capabilities = device->capabilities;
|
||||
added.keymap_type = device->keymap.type;
|
||||
added.keymap_size = device->keymap.size;
|
||||
added.keymap_from_server = device->keymap.server_overrides;
|
||||
if (device->keymap) {
|
||||
struct eis_keymap *keymap = device->keymap;
|
||||
added.keymap_type = keymap->type;
|
||||
added.keymap_size = keymap->size;
|
||||
added.keymap_from_server = !keymap->is_client_keymap;
|
||||
if (!keymap->is_client_keymap)
|
||||
fds[0] = keymap->fd;
|
||||
} else {
|
||||
/* it's NULL anyway */
|
||||
added.keymap_from_server = true;
|
||||
}
|
||||
|
||||
msg.device_added = &added;
|
||||
msg.msg_case = SERVER_MESSAGE__MSG_DEVICE_ADDED;
|
||||
|
||||
int fds[2] = {-1, -1};
|
||||
if (device->keymap.server_overrides)
|
||||
fds[0] = device->keymap.fd;
|
||||
|
||||
return eis_proto_send_msg_with_fds(client, &msg, fds);
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +252,7 @@ eis_proto_parse_message(struct brei_message *bmsg, size_t *consumed)
|
|||
.add_device.keymap_size = a->keymap_size,
|
||||
};
|
||||
|
||||
if (a->keymap_type != EIS_KEYMAP_TYPE_NONE)
|
||||
if (a->keymap_type)
|
||||
msg->add_device.keymap_fd = brei_message_take_fd(bmsg);
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
98
src/libeis.h
98
src/libeis.h
|
|
@ -45,6 +45,7 @@ struct eis;
|
|||
struct eis_client;
|
||||
struct eis_device;
|
||||
struct eis_event;
|
||||
struct eis_keymap;
|
||||
|
||||
enum eis_device_capability {
|
||||
EIS_DEVICE_CAP_POINTER = 1,
|
||||
|
|
@ -54,8 +55,7 @@ enum eis_device_capability {
|
|||
};
|
||||
|
||||
enum eis_keymap_type {
|
||||
EIS_KEYMAP_TYPE_NONE = 0,
|
||||
EIS_KEYMAP_TYPE_XKB,
|
||||
EIS_KEYMAP_TYPE_XKB = 1,
|
||||
};
|
||||
|
||||
enum eis_event_type {
|
||||
|
|
@ -433,50 +433,92 @@ eis_device_touch_get_width(struct eis_device *device);
|
|||
uint32_t
|
||||
eis_device_touch_get_height(struct eis_device *device);
|
||||
|
||||
/**
|
||||
* Create a new keymap of the given @p type. This keymap does not immediately
|
||||
* apply to the device, use eis_device_keyboard_set_keymap() to apply
|
||||
* this keymap. A keymap may only be applied once and to a single device.
|
||||
*
|
||||
* The returned keymap has a refcount of at least 1, use eis_keymap_unref()
|
||||
* to release resources associated with this keymap.
|
||||
*
|
||||
* @param type The type of the keymap.
|
||||
* @param fd A memmap-able file descriptor of size @p size pointing to the
|
||||
* keymap used by this device. @p fd can be closed by the caller after this
|
||||
* function completes.
|
||||
* @param size The size of the data at @p fd in bytes
|
||||
*
|
||||
* @return A keymap object or `NULL` on failure.
|
||||
*/
|
||||
struct eis_keymap *
|
||||
eis_keymap_new(enum eis_keymap_type type, int fd, size_t size);
|
||||
|
||||
/**
|
||||
* @return the size of the keymap in bytes
|
||||
*/
|
||||
size_t
|
||||
eis_keymap_get_size(struct eis_keymap *keymap);
|
||||
|
||||
/**
|
||||
* Returns the type for this keymap. The type specifies how to interpret the
|
||||
* data at the file descriptor returned by eis_keymap_get_fd().
|
||||
*/
|
||||
enum eis_keymap_type
|
||||
eis_keymap_get_type(struct eis_keymap *keymap);
|
||||
|
||||
/**
|
||||
* Return a memmap-able file descriptor pointing to the keymap used by the
|
||||
* device. The keymap is constant for the lifetime of the device and
|
||||
* assigned to this device individually.
|
||||
*
|
||||
* If this function returns -1, this device does not have
|
||||
* an individual keymap assigned.
|
||||
*/
|
||||
int
|
||||
eis_device_keyboard_get_keymap(struct eis_device *device);
|
||||
eis_keymap_get_fd(struct eis_keymap *keymap);
|
||||
|
||||
size_t
|
||||
eis_device_keyboard_get_keymap_size(struct eis_device *device);
|
||||
struct eis_keymap *
|
||||
eis_keymap_ref(struct eis_keymap *keymap);
|
||||
|
||||
enum eis_keymap_type
|
||||
eis_device_keyboard_get_keymap_type(struct eis_device *device);
|
||||
struct eis_keymap *
|
||||
eis_keymap_unref(struct eis_keymap *keymap);
|
||||
|
||||
/**
|
||||
* Set the keymap on the device. This overwrites the client's choice of
|
||||
* keyboard. Note that **not** calling this function when
|
||||
* eis_device_keyboard_get_keymap() returns a value other than -1 is equivalent to
|
||||
* Return the device this keymap belongs to, or `NULL` if it has not yet
|
||||
* been assigned to a device.
|
||||
*
|
||||
* If the keymap is a client-assigned keymap and the server has changed or
|
||||
* unset the keymap with eis_device_keyboard_set_keymap(), this function
|
||||
* returns `NULL`.
|
||||
*
|
||||
*/
|
||||
struct eis_device *
|
||||
eis_keymap_get_device(struct eis_keymap *keymap);
|
||||
|
||||
/**
|
||||
* Return the keymap assigned to this device. The return value of this
|
||||
* function is the client-assigned keymap (if any) before the call to
|
||||
* eis_device_keyboard_set_keymap(), or the server-assigned one after.
|
||||
*/
|
||||
struct eis_keymap *
|
||||
eis_device_keyboard_get_keymap(struct eis_device *device);
|
||||
|
||||
/**
|
||||
* Set the keymap on the device. This overwrites the client's keymap
|
||||
* choice. Note that **not** calling this function when
|
||||
* eis_device_keyboard_get_keymap() returns non-`NULL` is equivalent to
|
||||
* accepting the client's choice of keymap.
|
||||
*
|
||||
* If the fd is not -1, it is a memmap-able file descriptor pointing to the
|
||||
* keymap used by the device. This keymap is constant for the lifetime of
|
||||
* the device and assigned to this device individually. Where the keymap has
|
||||
* to change, remove the device and wait for the client to create a new one.
|
||||
* If the keymap is not `NULL`, the keymap is the one used by this device.
|
||||
* This keymap is constant for the lifetime of the device and assigned to
|
||||
* this device individually. Where the keymap has to change, remove the
|
||||
* device and wait for the client to create a new one.
|
||||
*
|
||||
* If the fd is -1, the device does not have an individual keymap assigned.
|
||||
* and keymap type argument is ignored. A server that does not handle
|
||||
* individual client keymaps must call this function with an fd of
|
||||
* -1.
|
||||
* If the keymap is `NULL`, the device does not have an individual keymap
|
||||
* assigned. A server that does not handle individual client keymaps must
|
||||
* call this function with an @p keymap of `NULL`.
|
||||
*
|
||||
* This function has no effect if called after eis_device_connect()
|
||||
*
|
||||
* @param device the EIS device
|
||||
* @param type the type of the keymap
|
||||
* @param fd a memmap-able file descriptor to the keymap
|
||||
* @param size the size of the keymap in bytes
|
||||
*/
|
||||
void
|
||||
eis_device_keyboard_set_keymap(struct eis_device *device,
|
||||
enum eis_keymap_type type,
|
||||
int fd, size_t size);
|
||||
struct eis_keymap *keymap);
|
||||
|
||||
/**
|
||||
* Return the device from this event.
|
||||
|
|
|
|||
|
|
@ -233,6 +233,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct eis_event *, eis_event_unref);
|
|||
#define _cleanup_eis_event_ _cleanup_(eis_event_unrefp)
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct eis_device *, eis_device_unref);
|
||||
#define _cleanup_eis_device_ _cleanup_(eis_device_unrefp)
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct eis_keymap *, eis_keymap_unref);
|
||||
#define _cleanup_eis_keymap_ _cleanup_(eis_keymap_unrefp)
|
||||
|
||||
/* Macros intended just for readability to make it more obvious which part
|
||||
of a test handles server vs client */
|
||||
|
|
|
|||
|
|
@ -1004,11 +1004,12 @@ MUNIT_TEST(test_ei_keymap_set)
|
|||
_cleanup_eis_event_ struct eis_event *event =
|
||||
peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED);
|
||||
struct eis_device *eis_device = eis_event_get_device(event);
|
||||
struct eis_keymap *eis_keymap = eis_device_keyboard_get_keymap(eis_device);
|
||||
|
||||
int fd = eis_device_keyboard_get_keymap(eis_device);
|
||||
int fd = eis_keymap_get_fd(eis_keymap);
|
||||
munit_assert_int(fd, !=, -1);
|
||||
munit_assert_uint(eis_device_keyboard_get_keymap_size(eis_device), ==, memfile_get_size(fd1));
|
||||
munit_assert_uint(eis_device_keyboard_get_keymap_type(eis_device), ==, EIS_KEYMAP_TYPE_XKB);
|
||||
munit_assert_uint(eis_keymap_get_size(eis_keymap), ==, memfile_get_size(fd1));
|
||||
munit_assert_uint(eis_keymap_get_type(eis_keymap), ==, EIS_KEYMAP_TYPE_XKB);
|
||||
eis_device_disconnect(eis_device);
|
||||
}
|
||||
|
||||
|
|
@ -1058,7 +1059,7 @@ MUNIT_TEST(test_ei_keymap_null)
|
|||
_cleanup_eis_event_ struct eis_event *event =
|
||||
peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED);
|
||||
struct eis_device *device = eis_event_get_device(event);
|
||||
eis_device_keyboard_set_keymap(device, EIS_KEYMAP_TYPE_NONE, -1, 0);
|
||||
eis_device_keyboard_set_keymap(device, NULL);
|
||||
eis_device_allow_capability(device, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_device_connect(device);
|
||||
}
|
||||
|
|
@ -1109,9 +1110,10 @@ MUNIT_TEST(test_ei_keymap_changed)
|
|||
_cleanup_eis_event_ struct eis_event *event =
|
||||
peck_eis_next_event(eis, EIS_EVENT_DEVICE_ADDED);
|
||||
struct eis_device *device = eis_event_get_device(event);
|
||||
eis_device_keyboard_set_keymap(device, EIS_KEYMAP_TYPE_XKB,
|
||||
memfile_get_fd(fd1),
|
||||
memfile_get_size(fd1));
|
||||
_cleanup_eis_keymap_ struct eis_keymap *keymap =
|
||||
eis_keymap_new(EIS_KEYMAP_TYPE_XKB, memfile_get_fd(fd1),
|
||||
memfile_get_size(fd1));
|
||||
eis_device_keyboard_set_keymap(device, keymap);
|
||||
eis_device_allow_capability(device, EIS_DEVICE_CAP_KEYBOARD);
|
||||
eis_device_connect(device);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct eis *, eis_unref);
|
|||
#define _cleanup_eis_ _cleanup_(eis_unrefp)
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct eis_event *, eis_event_unref);
|
||||
#define _cleanup_eis_event_ _cleanup_(eis_event_unrefp)
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct eis_keymap *, eis_keymap_unref);
|
||||
#define _cleanup_eis_keymap_ _cleanup_(eis_keymap_unrefp)
|
||||
|
||||
static void unlink_free(char **path) {
|
||||
if (*path) {
|
||||
|
|
@ -116,17 +118,22 @@ setup_keymap(struct eis_demo_server *server, struct eis_device *device)
|
|||
if (!f)
|
||||
return;
|
||||
|
||||
eis_device_keyboard_set_keymap(device, EIS_KEYMAP_TYPE_XKB,
|
||||
memfile_get_fd(f), memfile_get_size(f));
|
||||
_cleanup_eis_keymap_ struct eis_keymap *k =
|
||||
eis_keymap_new(EIS_KEYMAP_TYPE_XKB, memfile_get_fd(f),
|
||||
memfile_get_size(f));
|
||||
eis_device_keyboard_set_keymap(device, k);
|
||||
memfile_unref(f);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (eis_device_keyboard_get_keymap_type(device) == EIS_KEYMAP_TYPE_NONE)
|
||||
struct eis_keymap *keymap = eis_device_keyboard_get_keymap(device);
|
||||
if (!keymap)
|
||||
return;
|
||||
|
||||
colorprint("Using client keymap\n");
|
||||
int fd = eis_device_keyboard_get_keymap(device);
|
||||
size_t size = eis_device_keyboard_get_keymap_size(device);
|
||||
int fd = eis_keymap_get_fd(keymap);
|
||||
size_t size = eis_keymap_get_size(keymap);
|
||||
char *str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (str == MAP_FAILED)
|
||||
return;
|
||||
|
|
@ -136,18 +143,18 @@ setup_keymap(struct eis_demo_server *server, struct eis_device *device)
|
|||
if (!ctx)
|
||||
return;
|
||||
|
||||
_cleanup_xkb_keymap_ struct xkb_keymap *keymap =
|
||||
_cleanup_xkb_keymap_ struct xkb_keymap *xkb_keymap =
|
||||
xkb_keymap_new_from_string(ctx, str,
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1, 0);
|
||||
if (!keymap)
|
||||
return;
|
||||
|
||||
_cleanup_xkb_state_ struct xkb_state *state = xkb_state_new(keymap);
|
||||
_cleanup_xkb_state_ struct xkb_state *state = xkb_state_new(xkb_keymap);
|
||||
if (!state)
|
||||
return;
|
||||
|
||||
server->ctx = steal(&ctx);
|
||||
server->keymap = steal(&keymap);
|
||||
server->keymap = steal(&xkb_keymap);
|
||||
server->state = steal(&state);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue