Skip to content

Commit

Permalink
interactive-x11: Add support for Compose
Browse files Browse the repository at this point in the history
  • Loading branch information
wismill committed Nov 1, 2023
1 parent d027ebe commit 546228a
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 9 deletions.
93 changes: 84 additions & 9 deletions tools/interactive-x11.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "config.h"

#include <getopt.h>
#include <locale.h>
#include <stdbool.h>
#include <stdlib.h>
Expand All @@ -31,6 +32,7 @@
#include <xcb/xkb.h>

#include "xkbcommon/xkbcommon-x11.h"
#include "xkbcommon/xkbcommon-compose.h"
#include "tools-common.h"

/*
Expand Down Expand Up @@ -58,6 +60,7 @@ struct keyboard {

struct xkb_keymap *keymap;
struct xkb_state *state;
struct xkb_compose_state *compose_state;
int32_t device_id;
};

Expand Down Expand Up @@ -153,7 +156,8 @@ update_keymap(struct keyboard *kbd)

static int
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;

Expand All @@ -162,11 +166,15 @@ init_kbd(struct keyboard *kbd, xcb_connection_t *conn, uint8_t first_xkb_event,
kbd->ctx = ctx;
kbd->keymap = NULL;
kbd->state = NULL;
kbd->compose_state = NULL;
kbd->device_id = device_id;

ret = update_keymap(kbd);
if (ret)
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);
if (ret)
Expand All @@ -176,6 +184,7 @@ init_kbd(struct keyboard *kbd, xcb_connection_t *conn, uint8_t first_xkb_event,

err_state:
xkb_state_unref(kbd->state);
xkb_compose_state_unref(kbd->compose_state);
xkb_keymap_unref(kbd->keymap);
err_out:
return -1;
Expand All @@ -185,6 +194,7 @@ static void
deinit_kbd(struct keyboard *kbd)
{
xkb_state_unref(kbd->state);
xkb_compose_state_unref(kbd->compose_state);
xkb_keymap_unref(kbd->keymap);
}

Expand Down Expand Up @@ -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;
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,
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. */
if (xkb_state_key_get_one_sym(kbd->state, keycode) == XKB_KEY_Escape)
terminate = true;
Expand Down Expand Up @@ -328,6 +350,18 @@ create_capture_window(xcb_connection_t *conn)
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
main(int argc, char *argv[])
{
Expand All @@ -337,13 +371,38 @@ main(int argc, char *argv[])
int32_t core_kbd_device_id;
struct xkb_context *ctx;
struct keyboard core_kbd;
const char *locale;
struct xkb_compose_table *compose_table = NULL;

if (argc != 1) {
ret = strcmp(argv[1], "--help");
fprintf(ret ? stderr : stdout, "Usage: %s [--help]\n", argv[0]);
if (ret)
fprintf(stderr, "unrecognized option: %s\n", argv[1]);
return ret ? EXIT_INVALID_USAGE : EXIT_SUCCESS;
bool with_compose = false;
enum options {
OPT_COMPOSE,
};
static struct option opts[] = {
{"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, "");
Expand Down Expand Up @@ -373,14 +432,28 @@ main(int argc, char *argv[])
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);
if (core_kbd_device_id == -1) {
ret = -1;
fprintf(stderr, "Couldn't find core keyboard device\n");
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) {
fprintf(stderr, "Couldn't initialize core keyboard device\n");
goto err_ctx;
Expand All @@ -396,6 +469,8 @@ main(int argc, char *argv[])
ret = loop(conn, &core_kbd);
tools_enable_stdin_echo();

err_compose:
xkb_compose_table_unref(compose_table);
err_core_kbd:
deinit_kbd(&core_kbd);
err_ctx:
Expand Down
3 changes: 3 additions & 0 deletions tools/xkbcli-interactive-x11.1
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ This is a debugging tool, its behavior or output is not guaranteed to be stable.
.Bl -tag -width Ds
.It Fl \-help
Print help and exit
.
.It Fl \-enable\-compose
Enable Compose functionality
.El
.
.Sh SEE ALSO
Expand Down

0 comments on commit 546228a

Please sign in to comment.