Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compose: add support to all interactive tools #399

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tools/interactive-evdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ process_event(struct keyboard *kbd, uint16_t type, uint16_t code, int32_t value)

if (value != KEY_STATE_RELEASE) {
tools_print_keycode_state(
kbd->state, kbd->compose_state, keycode,
NULL, kbd->state, kbd->compose_state, keycode,
consumed_mode, print_fields
);
}
Expand Down
106 changes: 92 additions & 14 deletions tools/interactive-wayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <locale.h>
#include <stdbool.h>
#include <stdint.h>
Expand All @@ -36,7 +37,9 @@
#include <unistd.h>

#include "xkbcommon/xkbcommon.h"
#include "xkbcommon/xkbcommon-compose.h"
#include "tools-common.h"
#include "src/utils.h"

#include <wayland-client.h>
#include "xdg-shell-client-protocol.h"
Expand All @@ -56,6 +59,7 @@ struct interactive_dpy {
uint32_t shm_format;

struct xkb_context *ctx;
struct xkb_compose_table *compose_table;

struct wl_surface *wl_surf;
struct xdg_surface *xdg_surf;
Expand All @@ -76,6 +80,7 @@ struct interactive_seat {

struct xkb_keymap *keymap;
struct xkb_state *state;
struct xkb_compose_state *compose_state;

struct wl_list link;
};
Expand Down Expand Up @@ -394,17 +399,30 @@ kbd_key(void *data, struct wl_keyboard *wl_kbd, uint32_t serial, uint32_t time,
uint32_t key, uint32_t state)
{
struct interactive_seat *seat = data;
xkb_keycode_t keycode = key + EVDEV_OFFSET;

if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
return;
if (seat->compose_state && state != WL_KEYBOARD_KEY_STATE_RELEASED) {
xkb_keysym_t keysym = xkb_state_key_get_one_sym(seat->state, keycode);
xkb_compose_state_feed(seat->compose_state, keysym);
}

printf("%s: ", seat->name_str);
tools_print_keycode_state(seat->state, NULL, key + EVDEV_OFFSET,
XKB_CONSUMED_MODE_XKB,
PRINT_ALL_FIELDS);
if (state != WL_KEYBOARD_KEY_STATE_RELEASED) {
char *prefix = asprintf_safe("%s: ", seat->name_str);
tools_print_keycode_state(prefix, seat->state, seat->compose_state, keycode,
XKB_CONSUMED_MODE_XKB,
PRINT_ALL_FIELDS);
free(prefix);
}

if (seat->compose_state) {
enum xkb_compose_status status = xkb_compose_state_get_status(seat->compose_state);
if (status == XKB_COMPOSE_CANCELLED || status == XKB_COMPOSE_COMPOSED)
xkb_compose_state_reset(seat->compose_state);
}

/* Exit on ESC. */
if (xkb_state_key_get_one_sym(seat->state, key + EVDEV_OFFSET) == XKB_KEY_Escape)
if (xkb_state_key_get_one_sym(seat->state, keycode) == XKB_KEY_Escape &&
state != WL_KEYBOARD_KEY_STATE_PRESSED)
terminate = true;
}

Expand Down Expand Up @@ -518,8 +536,10 @@ seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t caps)

xkb_state_unref(seat->state);
xkb_keymap_unref(seat->keymap);
xkb_compose_state_unref(seat->compose_state);

seat->state = NULL;
seat->compose_state = NULL;
seat->keymap = NULL;
seat->wl_kbd = NULL;
}
Expand Down Expand Up @@ -564,6 +584,10 @@ seat_create(struct interactive_dpy *inter, struct wl_registry *registry,
seat->wl_seat = wl_registry_bind(registry, name, &wl_seat_interface,
MIN(version, 5));
wl_seat_add_listener(seat->wl_seat, &seat_listener, seat);
if (seat->inter->compose_table) {
seat->compose_state = xkb_compose_state_new(seat->inter->compose_table,
XKB_COMPOSE_STATE_NO_FLAGS);
}
ret = asprintf(&seat->name_str, "seat:%d",
wl_proxy_get_id((struct wl_proxy *) seat->wl_seat));
assert(ret >= 0);
Expand All @@ -580,6 +604,7 @@ seat_destroy(struct interactive_seat *seat)
wl_keyboard_destroy(seat->wl_kbd);

xkb_state_unref(seat->state);
xkb_compose_state_unref(seat->compose_state);
xkb_keymap_unref(seat->keymap);
}

Expand Down Expand Up @@ -673,19 +698,56 @@ dpy_disconnect(struct interactive_dpy *inter)
wl_display_disconnect(inter->dpy);
}

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[])
{
int ret;
struct interactive_dpy inter;
struct wl_registry *registry;

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;
const char *locale;
struct xkb_compose_table *compose_table = NULL;

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 All @@ -707,6 +769,20 @@ main(int argc, char *argv[])
goto err_out;
}

if (with_compose) {
locale = setlocale(LC_CTYPE, NULL);
compose_table =
xkb_compose_table_new_from_locale(inter.ctx, locale,
XKB_COMPOSE_COMPILE_NO_FLAGS);
if (!compose_table) {
fprintf(stderr, "Couldn't create compose from locale\n");
goto err_compose;
}
inter.compose_table = compose_table;
} else {
inter.compose_table = NULL;
}

registry = wl_display_get_registry(inter.dpy);
wl_registry_add_listener(registry, &registry_listener, &inter);

Expand Down Expand Up @@ -738,6 +814,8 @@ main(int argc, char *argv[])
wl_registry_destroy(registry);
err_conn:
dpy_disconnect(&inter);
err_compose:
xkb_compose_table_unref(compose_table);
err_out:
exit(ret >= 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
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(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
Loading