interactive-x11: Add support for Compose

master
Pierre Le Marre 2023-11-01 18:12:15 +01:00 committed by Wismill
parent c7f4e308f2
commit 0f9c95df06
2 changed files with 87 additions and 9 deletions

View File

@ -23,6 +23,7 @@
#include "config.h" #include "config.h"
#include <getopt.h>
#include <locale.h> #include <locale.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
@ -31,6 +32,7 @@
#include <xcb/xkb.h> #include <xcb/xkb.h>
#include "xkbcommon/xkbcommon-x11.h" #include "xkbcommon/xkbcommon-x11.h"
#include "xkbcommon/xkbcommon-compose.h"
#include "tools-common.h" #include "tools-common.h"
/* /*
@ -58,6 +60,7 @@ struct keyboard {
struct xkb_keymap *keymap; struct xkb_keymap *keymap;
struct xkb_state *state; struct xkb_state *state;
struct xkb_compose_state *compose_state;
int32_t device_id; int32_t device_id;
}; };
@ -153,7 +156,8 @@ err_out:
static int static int
init_kbd(struct keyboard *kbd, xcb_connection_t *conn, uint8_t first_xkb_event, init_kbd(struct keyboard *kbd, xcb_connection_t *conn, uint8_t first_xkb_event,
int32_t device_id, struct xkb_context *ctx) int32_t device_id, struct xkb_context *ctx,
struct xkb_compose_table *compose_table)
{ {
int ret; int ret;
@ -162,11 +166,15 @@ init_kbd(struct keyboard *kbd, xcb_connection_t *conn, uint8_t first_xkb_event,
kbd->ctx = ctx; kbd->ctx = ctx;
kbd->keymap = NULL; kbd->keymap = NULL;
kbd->state = NULL; kbd->state = NULL;
kbd->compose_state = NULL;
kbd->device_id = device_id; kbd->device_id = device_id;
ret = update_keymap(kbd); ret = update_keymap(kbd);
if (ret) if (ret)
goto err_out; goto err_out;
if (compose_table)
kbd->compose_state = xkb_compose_state_new(compose_table,
XKB_COMPOSE_STATE_NO_FLAGS);
ret = select_xkb_events_for_device(conn, device_id); ret = select_xkb_events_for_device(conn, device_id);
if (ret) if (ret)
@ -176,6 +184,7 @@ init_kbd(struct keyboard *kbd, xcb_connection_t *conn, uint8_t first_xkb_event,
err_state: err_state:
xkb_state_unref(kbd->state); xkb_state_unref(kbd->state);
xkb_compose_state_unref(kbd->compose_state);
xkb_keymap_unref(kbd->keymap); xkb_keymap_unref(kbd->keymap);
err_out: err_out:
return -1; return -1;
@ -185,6 +194,7 @@ static void
deinit_kbd(struct keyboard *kbd) deinit_kbd(struct keyboard *kbd)
{ {
xkb_state_unref(kbd->state); xkb_state_unref(kbd->state);
xkb_compose_state_unref(kbd->compose_state);
xkb_keymap_unref(kbd->keymap); xkb_keymap_unref(kbd->keymap);
} }
@ -242,10 +252,22 @@ process_event(xcb_generic_event_t *gevent, struct keyboard *kbd)
xcb_key_press_event_t *event = (xcb_key_press_event_t *) gevent; xcb_key_press_event_t *event = (xcb_key_press_event_t *) gevent;
xkb_keycode_t keycode = event->detail; xkb_keycode_t keycode = event->detail;
tools_print_keycode_state(NULL, kbd->state, NULL, keycode, if (kbd->compose_state) {
xkb_keysym_t keysym = xkb_state_key_get_one_sym(kbd->state, keycode);
xkb_compose_state_feed(kbd->compose_state, keysym);
}
tools_print_keycode_state(NULL, kbd->state, kbd->compose_state, keycode,
XKB_CONSUMED_MODE_XKB, XKB_CONSUMED_MODE_XKB,
PRINT_ALL_FIELDS); PRINT_ALL_FIELDS);
if (kbd->compose_state) {
enum xkb_compose_status status = xkb_compose_state_get_status(kbd->compose_state);
if (status == XKB_COMPOSE_CANCELLED ||
status == XKB_COMPOSE_COMPOSED)
xkb_compose_state_reset(kbd->compose_state);
}
/* Exit on ESC. */ /* Exit on ESC. */
if (xkb_state_key_get_one_sym(kbd->state, keycode) == XKB_KEY_Escape) if (xkb_state_key_get_one_sym(kbd->state, keycode) == XKB_KEY_Escape)
terminate = true; terminate = true;
@ -328,6 +350,18 @@ create_capture_window(xcb_connection_t *conn)
return 0; return 0;
} }
static void
usage(FILE *fp, char *progname)
{
fprintf(fp,
"Usage: %s [--help] [--enable-compose]\n",
progname);
fprintf(fp,
" --enable-compose enable Compose\n"
" --help display this help and exit\n"
);
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
@ -337,13 +371,38 @@ main(int argc, char *argv[])
int32_t core_kbd_device_id; int32_t core_kbd_device_id;
struct xkb_context *ctx; struct xkb_context *ctx;
struct keyboard core_kbd; struct keyboard core_kbd;
const char *locale;
struct xkb_compose_table *compose_table = NULL;
if (argc != 1) { bool with_compose = false;
ret = strcmp(argv[1], "--help"); enum options {
fprintf(ret ? stderr : stdout, "Usage: %s [--help]\n", argv[0]); OPT_COMPOSE,
if (ret) };
fprintf(stderr, "unrecognized option: %s\n", argv[1]); static struct option opts[] = {
return ret ? EXIT_INVALID_USAGE : EXIT_SUCCESS; {"help", no_argument, 0, 'h'},
{"enable-compose", no_argument, 0, OPT_COMPOSE},
{0, 0, 0, 0},
};
while (1) {
int opt;
int option_index = 0;
opt = getopt_long(argc, argv, "h", opts, &option_index);
if (opt == -1)
break;
switch (opt) {
case OPT_COMPOSE:
with_compose = true;
break;
case 'h':
usage(stdout, argv[0]);
return EXIT_SUCCESS;
case '?':
usage(stderr, argv[0]);
return EXIT_INVALID_USAGE;
}
} }
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
@ -373,6 +432,19 @@ main(int argc, char *argv[])
goto err_conn; goto err_conn;
} }
if (with_compose) {
locale = setlocale(LC_CTYPE, NULL);
compose_table =
xkb_compose_table_new_from_locale(ctx, locale,
XKB_COMPOSE_COMPILE_NO_FLAGS);
if (!compose_table) {
fprintf(stderr, "Couldn't create compose from locale\n");
goto err_compose;
}
} else {
compose_table = NULL;
}
core_kbd_device_id = xkb_x11_get_core_keyboard_device_id(conn); core_kbd_device_id = xkb_x11_get_core_keyboard_device_id(conn);
if (core_kbd_device_id == -1) { if (core_kbd_device_id == -1) {
ret = -1; ret = -1;
@ -380,7 +452,8 @@ main(int argc, char *argv[])
goto err_ctx; goto err_ctx;
} }
ret = init_kbd(&core_kbd, conn, first_xkb_event, core_kbd_device_id, ctx); ret = init_kbd(&core_kbd, conn, first_xkb_event, core_kbd_device_id,
ctx, compose_table);
if (ret) { if (ret) {
fprintf(stderr, "Couldn't initialize core keyboard device\n"); fprintf(stderr, "Couldn't initialize core keyboard device\n");
goto err_ctx; goto err_ctx;
@ -396,6 +469,8 @@ main(int argc, char *argv[])
ret = loop(conn, &core_kbd); ret = loop(conn, &core_kbd);
tools_enable_stdin_echo(); tools_enable_stdin_echo();
err_compose:
xkb_compose_table_unref(compose_table);
err_core_kbd: err_core_kbd:
deinit_kbd(&core_kbd); deinit_kbd(&core_kbd);
err_ctx: err_ctx:

View File

@ -28,6 +28,9 @@ This is a debugging tool, its behavior or output is not guaranteed to be stable.
.Bl -tag -width Ds .Bl -tag -width Ds
.It Fl \-help .It Fl \-help
Print help and exit Print help and exit
.
.It Fl \-enable\-compose
Enable Compose functionality
.El .El
. .
.Sh SEE ALSO .Sh SEE ALSO