mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-05-05 06:38:02 +02:00
tools: add keymap handling to the socket demos
Client sets layout fr, server accepts it and prints azerty for the keys pressed. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
2a619fd4b4
commit
4af29d930a
6 changed files with 154 additions and 11 deletions
|
|
@ -32,14 +32,14 @@ variables:
|
|||
# See the documentation here: #
|
||||
# https://wayland.freedesktop.org/libinput/doc/latest/building_libinput.html #
|
||||
###############################################################################
|
||||
FEDORA_PACKAGES: 'git diffutils gcc gcc-c++ pkgconf-pkg-config meson systemd-devel protobuf-c-devel'
|
||||
FEDORA_PACKAGES: 'git diffutils gcc gcc-c++ pkgconf-pkg-config meson systemd-devel protobuf-c-devel libxkbcommon-devel'
|
||||
############################ end of package lists #############################
|
||||
|
||||
# these tags should be updated each time the list of packages is updated
|
||||
# changing these will force rebuilding the associated image
|
||||
# Note: these tags have no meaning and are not tied to a particular
|
||||
# libinput version
|
||||
FEDORA_TAG: '2020-08-20.1'
|
||||
FEDORA_TAG: '2020-08-21.1'
|
||||
|
||||
FDO_UPSTREAM_REPO: whot/libei
|
||||
|
||||
|
|
@ -226,6 +226,12 @@ default-build-release@fedora:32:
|
|||
MESON_ARGS: "-Dbuildtype=release"
|
||||
CFLAGS: "-Werror"
|
||||
|
||||
build-no-libxkcommon-nodeps@fedora:32:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
before_script:
|
||||
- dnf remove -y libxkcommon-devel
|
||||
|
||||
valgrind@fedora:32:
|
||||
extends:
|
||||
- .fedora-build@template
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ variables:
|
|||
# See the documentation here: #
|
||||
# https://wayland.freedesktop.org/libinput/doc/latest/building_libinput.html #
|
||||
###############################################################################
|
||||
FEDORA_PACKAGES: 'git diffutils gcc gcc-c++ pkgconf-pkg-config meson systemd-devel protobuf-c-devel'
|
||||
FEDORA_PACKAGES: 'git diffutils gcc gcc-c++ pkgconf-pkg-config meson systemd-devel protobuf-c-devel libxkbcommon-devel'
|
||||
############################ end of package lists #############################
|
||||
|
||||
# these tags should be updated each time the list of packages is updated
|
||||
|
|
@ -247,6 +247,12 @@ default-build-release@{{distro.name}}:{{version}}:
|
|||
MESON_ARGS: "-Dbuildtype=release"
|
||||
CFLAGS: "-Werror"
|
||||
|
||||
build-no-libxkcommon-nodeps@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
before_script:
|
||||
- dnf remove -y libxkcommon-devel
|
||||
|
||||
valgrind@{{distro.name}}:{{version}}:
|
||||
extends:
|
||||
- .{{distro.name}}-build@template
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
# We're happy to rebuild all containers when one changes.
|
||||
.default_tag: &default_tag '2020-08-20.1'
|
||||
.default_tag: &default_tag '2020-08-21.1'
|
||||
|
||||
distributions:
|
||||
- name: fedora
|
||||
|
|
|
|||
|
|
@ -123,13 +123,15 @@ pkgconfig.generate(lib_libreis,
|
|||
libraries: lib_libreis,
|
||||
)
|
||||
|
||||
dep_libxkbcommon = dependency('xkbcommon', required: false)
|
||||
config_h.set10('HAVE_LIBXKBCOMMON', dep_libxkbcommon.found())
|
||||
executable('eis-socket-server',
|
||||
'tools/eis-socket-server.c',
|
||||
dependencies: [dep_libeis])
|
||||
dependencies: [dep_libutil, dep_libeis, dep_libxkbcommon])
|
||||
|
||||
executable('ei-socket-client',
|
||||
'tools/ei-socket-client.c',
|
||||
dependencies: [dep_libei])
|
||||
dependencies: [dep_libutil, dep_libei, dep_libxkbcommon])
|
||||
|
||||
# tests
|
||||
subproject('munit')
|
||||
|
|
|
|||
|
|
@ -31,10 +31,15 @@
|
|||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if HAVE_LIBXKBCOMMON
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#endif
|
||||
|
||||
#include "libei.h"
|
||||
|
||||
#include "src/util-macros.h"
|
||||
#include "src/util-mem.h"
|
||||
#include "src/util-memfile.h"
|
||||
#include "src/util-color.h"
|
||||
#include "src/util-strings.h"
|
||||
|
||||
|
|
@ -60,6 +65,48 @@ colorprint(const char *format, ...)
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
#if HAVE_LIBXKBCOMMON
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct xkb_context*, xkb_context_unref);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct xkb_keymap*, xkb_keymap_unref);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct xkb_state*, xkb_state_unref);
|
||||
#define _cleanup_xkb_context_ _cleanup_(xkb_context_unrefp)
|
||||
#define _cleanup_xkb_keymap_ _cleanup_(xkb_keymap_unrefp)
|
||||
#define _cleanup_xkb_state_ _cleanup_(xkb_state_unrefp)
|
||||
#endif
|
||||
|
||||
static void
|
||||
setup_keymap(struct ei_device *kbd)
|
||||
{
|
||||
#if HAVE_LIBXKBCOMMON
|
||||
_cleanup_xkb_context_ struct xkb_context *ctx =
|
||||
xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
struct xkb_rule_names names = {
|
||||
.rules = "evdev",
|
||||
.model = "pc105",
|
||||
.layout = "fr",
|
||||
};
|
||||
|
||||
_cleanup_xkb_keymap_ struct xkb_keymap *keymap =
|
||||
xkb_keymap_new_from_names(ctx, &names, 0);
|
||||
if (!keymap)
|
||||
return;
|
||||
|
||||
const char *str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
|
||||
size_t len = strlen(str) - 1;
|
||||
|
||||
struct memfile *f = memfile_new(str, len);
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
ei_device_configure_keymap(kbd, EI_KEYMAP_TYPE_XKB,
|
||||
memfile_get_fd(f), memfile_get_size(f));
|
||||
memfile_unref(f);
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char SOCKETNAME[] = "eis-0";
|
||||
|
|
@ -90,6 +137,7 @@ int main(int argc, char **argv)
|
|||
|
||||
_cleanup_(ei_device_unrefp) struct ei_device *kbd = ei_device_new(ei);
|
||||
ei_device_configure_capability(kbd, EI_DEVICE_CAP_KEYBOARD);
|
||||
setup_keymap(kbd);
|
||||
|
||||
bool stop = false;
|
||||
bool have_ptr = false;
|
||||
|
|
@ -156,9 +204,11 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (have_kbd) {
|
||||
static int key = 0;
|
||||
colorprint("sending key event\n");
|
||||
ei_device_keyboard_key(kbd, 57, true); /* KEY_SPACE */
|
||||
ei_device_keyboard_key(kbd, 57, false); /* KEY_SPACE */
|
||||
ei_device_keyboard_key(kbd, 16 + key, true); /* KEY_Q */
|
||||
ei_device_keyboard_key(kbd, 16 + key, false); /* KEY_Q */
|
||||
key = (key + 1) % 6;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,13 +29,28 @@
|
|||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#if HAVE_LIBXKBCOMMON
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#endif
|
||||
|
||||
#include "libeis.h"
|
||||
|
||||
#include "src/util-color.h"
|
||||
#include "src/util-mem.h"
|
||||
#include "src/util-memfile.h"
|
||||
#include "src/util-strings.h"
|
||||
|
||||
struct eis_server {
|
||||
uint32_t pad; /* avoid warning with missing libxkbcommon */
|
||||
#if HAVE_LIBXKBCOMMON
|
||||
struct xkb_context *ctx;
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_state *state;
|
||||
#endif
|
||||
};
|
||||
|
||||
static bool stop = false;
|
||||
|
||||
static void sighandler(int signal) {
|
||||
|
|
@ -71,8 +86,71 @@ colorprint(const char *format, ...)
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
#if HAVE_LIBXKBCOMMON
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct xkb_context*, xkb_context_unref);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct xkb_keymap*, xkb_keymap_unref);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct xkb_state*, xkb_state_unref);
|
||||
#define _cleanup_xkb_context_ _cleanup_(xkb_context_unrefp)
|
||||
#define _cleanup_xkb_keymap_ _cleanup_(xkb_keymap_unrefp)
|
||||
#define _cleanup_xkb_state_ _cleanup_(xkb_state_unrefp)
|
||||
#endif
|
||||
|
||||
static void
|
||||
setup_keymap(struct eis_server *server, struct eis_device *device)
|
||||
{
|
||||
#if HAVE_LIBXKBCOMMON
|
||||
if (eis_device_get_keymap_type(device) == EIS_KEYMAP_TYPE_NONE)
|
||||
return;
|
||||
|
||||
colorprint("Using client keymap\n");
|
||||
int fd = eis_device_get_keymap(device);
|
||||
size_t size = eis_device_get_keymap_size(device);
|
||||
char *str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (str == MAP_FAILED)
|
||||
return;
|
||||
|
||||
_cleanup_xkb_context_ struct xkb_context *ctx =
|
||||
xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
_cleanup_xkb_keymap_ struct xkb_keymap *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);
|
||||
if (!state)
|
||||
return;
|
||||
|
||||
server->ctx = steal(&ctx);
|
||||
server->keymap = steal(&keymap);
|
||||
server->state = steal(&state);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
handle_key(struct eis_server *server, uint32_t keycode, bool is_press)
|
||||
{
|
||||
char keysym_name[64] = {0};
|
||||
|
||||
#if HAVE_LIBXKBCOMMON
|
||||
if (server->state) {
|
||||
uint32_t xkbkc = keycode + 8;
|
||||
xkb_state_update_key(server->state, xkbkc, is_press ? XKB_KEY_DOWN : XKB_KEY_UP);
|
||||
xkb_state_key_get_utf8(server->state, xkbkc, keysym_name, sizeof(keysym_name));
|
||||
}
|
||||
#endif
|
||||
colorprint("key %d (%s) [%s]\n",
|
||||
keycode, is_press ? "press" : "release",
|
||||
keysym_name);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct eis_server server = {0};
|
||||
|
||||
_cleanup_(eis_unrefp) struct eis *eis = eis_new(NULL);
|
||||
assert(eis);
|
||||
|
||||
|
|
@ -137,6 +215,7 @@ int main(int argc, char **argv)
|
|||
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" : "");
|
||||
setup_keymap(&server, device);
|
||||
/* insert sophisticated device checks here */
|
||||
eis_device_connect(device);
|
||||
eis_device_resume(device);
|
||||
|
|
@ -163,9 +242,9 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
case EIS_EVENT_KEYBOARD_KEY:
|
||||
{
|
||||
colorprint("key %d (%s)\n",
|
||||
eis_event_keyboard_get_key(e),
|
||||
eis_event_keyboard_get_key_is_press(e) ? "press" : "release");
|
||||
handle_key(&server,
|
||||
eis_event_keyboard_get_key(e),
|
||||
eis_event_keyboard_get_key_is_press(e));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue