Hi, On Tue, 2016-10-11 at 16:33 -0700, Bryce Harrington wrote: > Except for weston-info, client source files are not prefixed "weston- > ". > > Signed-off-by: Bryce Harrington <[email protected]> > --- > Makefile.am | 2 +- > clients/simple-im.c | 524 > +++++++++++++++++++++++++++++++++++++++++++++ > clients/weston-simple-im.c | 524 --------------------------------- > ------------ > 3 files changed, 525 insertions(+), 525 deletions(-) > create mode 100644 clients/simple-im.c > delete mode 100644 clients/weston-simple-im.c > > diff --git a/Makefile.am b/Makefile.am > index c94c211..b08ce71 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -779,7 +779,7 @@ nodist_weston_keyboard_SOURCES = > \ > weston_keyboard_LDADD = libtoytoolkit.la > weston_keyboard_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) > > -weston_simple_im_SOURCES = clients/weston-simple-im.c > +weston_simple_im_SOURCES = clients/simple-im.c > nodist_weston_simple_im_SOURCES = \ > protocol/input-method-unstable-v1-protocol.c > \ > protocol/input-method-unstable-v1-client-protocol.h > diff --git a/clients/simple-im.c b/clients/simple-im.c > new file mode 100644 > index 0000000..280589b > --- /dev/null > +++ b/clients/simple-im.c > @@ -0,0 +1,524 @@ > +/* > + * Copyright © 2012 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person > obtaining a > + * copy of this software and associated documentation files (the > "Software"), > + * to deal in the Software without restriction, including without > limitation > + * the rights to use, copy, modify, merge, publish, distribute, > sublicense, > + * and/or sell copies of the Software, and to permit persons to whom > the > + * Software is furnished to do so, subject to the following > conditions: > + * > + * The above copyright notice and this permission notice (including > the next > + * paragraph) shall be included in all copies or substantial > portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO > EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES > OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > OTHER > + * DEALINGS IN THE SOFTWARE. > + */ > + > +#include "config.h" > + > +#include <stdint.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <unistd.h> > +#include <sys/mman.h> > + > +#include <linux/input.h> > + > +#include "window.h" > +#include "input-method-unstable-v1-client-protocol.h" > +#include "shared/helpers.h" > + > +enum compose_state { > + state_normal, > + state_compose > +}; > + > +struct compose_seq { > + uint32_t keys[4]; > + > + const char *text; > +}; > + > +struct simple_im; > + > +typedef void (*keyboard_input_key_handler_t)(struct simple_im > *keyboard, > + uint32_t serial, > + uint32_t time, uint32_t > key, uint32_t unicode, > + enum > wl_keyboard_key_state state); > + > +struct simple_im { > + struct zwp_input_method_v1 *input_method; > + struct zwp_input_method_context_v1 *context; > + struct wl_display *display; > + struct wl_registry *registry; > + struct wl_keyboard *keyboard; > + enum compose_state compose_state; > + struct compose_seq compose_seq; > + > + struct xkb_context *xkb_context; > + > + uint32_t modifiers; > + > + struct xkb_keymap *keymap; > + struct xkb_state *state; > + xkb_mod_mask_t control_mask; > + xkb_mod_mask_t alt_mask; > + xkb_mod_mask_t shift_mask; > + > + keyboard_input_key_handler_t key_handler; > + > + uint32_t serial; > +}; > + > +static const struct compose_seq compose_seqs[] = { > + { { XKB_KEY_quotedbl, XKB_KEY_A, 0 }, "Ä" }, > + { { XKB_KEY_quotedbl, XKB_KEY_O, 0 }, "Ö" }, > + { { XKB_KEY_quotedbl, XKB_KEY_U, 0 }, "Ü" }, > + { { XKB_KEY_quotedbl, XKB_KEY_a, 0 }, "ä" }, > + { { XKB_KEY_quotedbl, XKB_KEY_o, 0 }, "ö" }, > + { { XKB_KEY_quotedbl, XKB_KEY_u, 0 }, "ü" }, > + { { XKB_KEY_apostrophe, XKB_KEY_A, 0 }, "Á" }, > + { { XKB_KEY_apostrophe, XKB_KEY_a, 0 }, "á" }, > + { { XKB_KEY_slash, XKB_KEY_O, 0 }, "Ø" }, > + { { XKB_KEY_slash, XKB_KEY_o, 0 }, "ø" }, > + { { XKB_KEY_less, XKB_KEY_3, 0 }, "♥" }, > + { { XKB_KEY_A, XKB_KEY_A, 0 }, "Å" }, > + { { XKB_KEY_A, XKB_KEY_E, 0 }, "Æ" }, > + { { XKB_KEY_O, XKB_KEY_C, 0 }, "©" }, > + { { XKB_KEY_O, XKB_KEY_R, 0 }, "®" }, > + { { XKB_KEY_s, XKB_KEY_s, 0 }, "ß" }, > + { { XKB_KEY_a, XKB_KEY_e, 0 }, "æ" }, > + { { XKB_KEY_a, XKB_KEY_a, 0 }, "å" }, > +}; > + > +static const uint32_t ignore_keys_on_compose[] = { > + XKB_KEY_Shift_L, > + XKB_KEY_Shift_R > +}; > + > +static void > +handle_surrounding_text(void *data, > + struct zwp_input_method_context_v1 *context, > + const char *text, > + uint32_t cursor, > + uint32_t anchor) > +{ > + fprintf(stderr, "Surrounding text updated: %s\n", text); > +} > + > +static void > +handle_reset(void *data, > + struct zwp_input_method_context_v1 *context) > +{ > + struct simple_im *keyboard = data; > + > + fprintf(stderr, "Reset pre-edit buffer\n"); > + > + keyboard->compose_state = state_normal; > +} > + > +static void > +handle_content_type(void *data, > + struct zwp_input_method_context_v1 *context, > + uint32_t hint, > + uint32_t purpose) > +{ > +} > + > +static void > +handle_invoke_action(void *data, > + struct zwp_input_method_context_v1 *context, > + uint32_t button, > + uint32_t index) > +{ > +} > + > +static void > +handle_commit_state(void *data, > + struct zwp_input_method_context_v1 *context, > + uint32_t serial) > +{ > + struct simple_im *keyboard = data; > + > + keyboard->serial = serial; > +} > + > +static void > +handle_preferred_language(void *data, > + struct zwp_input_method_context_v1 > *context, > + const char *language) > +{ > +} > + > +static const struct zwp_input_method_context_v1_listener > input_method_context_listener = { > + handle_surrounding_text, > + handle_reset, > + handle_content_type, > + handle_invoke_action, > + handle_commit_state, > + handle_preferred_language > +}; > + > +static void > +input_method_keyboard_keymap(void *data, > + struct wl_keyboard *wl_keyboard, > + uint32_t format, > + int32_t fd, > + uint32_t size) > +{ > + struct simple_im *keyboard = data; > + char *map_str; > + > + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { > + close(fd); > + return; > + } > + > + map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); > + if (map_str == MAP_FAILED) { > + close(fd); > + return; > + } > + > + keyboard->keymap = > + xkb_keymap_new_from_string(keyboard->xkb_context, > + map_str, > + XKB_KEYMAP_FORMAT_TEXT_V1 > , > + XKB_KEYMAP_COMPILE_NO_FLA > GS); > + > + munmap(map_str, size); > + close(fd); > + > + if (!keyboard->keymap) { > + fprintf(stderr, "Failed to compile keymap\n"); > + return; > + } > + > + keyboard->state = xkb_state_new(keyboard->keymap); > + if (!keyboard->state) { > + fprintf(stderr, "Failed to create XKB state\n"); > + xkb_keymap_unref(keyboard->keymap); > + return; > + } > + > + keyboard->control_mask = > + 1 << xkb_keymap_mod_get_index(keyboard->keymap, > "Control"); > + keyboard->alt_mask = > + 1 << xkb_keymap_mod_get_index(keyboard->keymap, > "Mod1"); > + keyboard->shift_mask = > + 1 << xkb_keymap_mod_get_index(keyboard->keymap, > "Shift"); > +} > + > +static void > +input_method_keyboard_key(void *data, > + struct wl_keyboard *wl_keyboard, > + uint32_t serial, > + uint32_t time, > + uint32_t key, > + uint32_t state_w) > +{ > + struct simple_im *keyboard = data; > + uint32_t code; > + uint32_t num_syms; > + const xkb_keysym_t *syms; > + xkb_keysym_t sym; > + enum wl_keyboard_key_state state = state_w; > + > + if (!keyboard->state) > + return; > + > + code = key + 8; > + num_syms = xkb_state_key_get_syms(keyboard->state, code, > &syms); > + > + sym = XKB_KEY_NoSymbol; > + if (num_syms == 1) > + sym = syms[0]; > + > + if (keyboard->key_handler) > + (*keyboard->key_handler)(keyboard, serial, time, > key, sym, > + state); > +} > + > +static void > +input_method_keyboard_modifiers(void *data, > + struct wl_keyboard *wl_keyboard, > + uint32_t serial, > + uint32_t mods_depressed, > + uint32_t mods_latched, > + uint32_t mods_locked, > + uint32_t group) > +{ > + struct simple_im *keyboard = data; > + struct zwp_input_method_context_v1 *context = keyboard- > >context; > + xkb_mod_mask_t mask; > + > + xkb_state_update_mask(keyboard->state, mods_depressed, > + mods_latched, mods_locked, 0, 0, > group); > + mask = xkb_state_serialize_mods(keyboard->state, > + XKB_STATE_MODS_DEPRESSED | > + XKB_STATE_MODS_LATCHED); > + > + keyboard->modifiers = 0; > + if (mask & keyboard->control_mask) > + keyboard->modifiers |= MOD_CONTROL_MASK; > + if (mask & keyboard->alt_mask) > + keyboard->modifiers |= MOD_ALT_MASK; > + if (mask & keyboard->shift_mask) > + keyboard->modifiers |= MOD_SHIFT_MASK; > + > + zwp_input_method_context_v1_modifiers(context, serial, > + mods_depressed, > mods_depressed, > + mods_latched, group); > +} > + > +static const struct wl_keyboard_listener > input_method_keyboard_listener = { > + input_method_keyboard_keymap, > + NULL, /* enter */ > + NULL, /* leave */ > + input_method_keyboard_key, > + input_method_keyboard_modifiers > +}; > + > +static void > +input_method_activate(void *data, > + struct zwp_input_method_v1 *input_method, > + struct zwp_input_method_context_v1 *context) > +{ > + struct simple_im *keyboard = data; > + > + if (keyboard->context) > + zwp_input_method_context_v1_destroy(keyboard- > >context); > + > + keyboard->compose_state = state_normal; > + > + keyboard->serial = 0; > + > + keyboard->context = context; > + zwp_input_method_context_v1_add_listener(context, > + &input_method_conte > xt_listener, > + keyboard); > + keyboard->keyboard = > zwp_input_method_context_v1_grab_keyboard(context); > + wl_keyboard_add_listener(keyboard->keyboard, > + &input_method_keyboard_listener, > + keyboard); > +} > + > +static void > +input_method_deactivate(void *data, > + struct zwp_input_method_v1 *input_method, > + struct zwp_input_method_context_v1 *context) > +{ > + struct simple_im *keyboard = data; > + > + if (!keyboard->context) > + return; > + > + zwp_input_method_context_v1_destroy(keyboard->context); > + keyboard->context = NULL; > +} > + > +static const struct zwp_input_method_v1_listener > input_method_listener = { > + input_method_activate, > + input_method_deactivate > +}; > + > +static void > +registry_handle_global(void *data, struct wl_registry *registry, > + uint32_t name, const char *interface, > uint32_t version) > +{ > + struct simple_im *keyboard = data; > + > + if (!strcmp(interface, "zwp_input_method_v1")) { > + keyboard->input_method = > + wl_registry_bind(registry, name, > + &zwp_input_method_v1_interf > ace, 1); > + zwp_input_method_v1_add_listener(keyboard- > >input_method, > + &input_method_liste > ner, keyboard); > + } > +} > + > +static void > +registry_handle_global_remove(void *data, struct wl_registry > *registry, > + uint32_t name) > +{ > +} > + > +static const struct wl_registry_listener registry_listener = { > + registry_handle_global, > + registry_handle_global_remove > +}; > + > +static int > +compare_compose_keys(const void *c1, const void *c2) > +{ > + const struct compose_seq *cs1 = c1; > + const struct compose_seq *cs2 = c2; > + int i; > + > + for (i = 0; cs1->keys[i] != 0 && cs2->keys[i] != 0; i++) { > + if (cs1->keys[i] != cs2->keys[i]) > + return cs1->keys[i] - cs2->keys[i]; > + } > + > + if (cs1->keys[i] == cs2->keys[i] > + || cs1->keys[i] == 0) > + return 0; > + > + return cs1->keys[i] - cs2->keys[i]; > +} > + > +static void > +simple_im_key_handler(struct simple_im *keyboard, > + uint32_t serial, uint32_t time, uint32_t key, > uint32_t sym, > + enum wl_keyboard_key_state state) > +{ > + struct zwp_input_method_context_v1 *context = keyboard- > >context; > + char text[64]; > + > + if (sym == XKB_KEY_Multi_key && > + state == WL_KEYBOARD_KEY_STATE_RELEASED && > + keyboard->compose_state == state_normal) { > + keyboard->compose_state = state_compose; > + memset(&keyboard->compose_seq, 0, sizeof(struct > compose_seq)); > + return; > + } > + > + if (keyboard->compose_state == state_compose) { > + uint32_t i = 0; > + struct compose_seq *cs; > + > + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) > + return; > + > + for (i = 0; i < > ARRAY_LENGTH(ignore_keys_on_compose); i++) { > + if (sym == ignore_keys_on_compose[i]) { > + zwp_input_method_context_v1_key(cont > ext, > + keyb > oard->serial, > + time > , > + key, > + stat > e); > + return; > + } > + } > + > + for (i = 0; keyboard->compose_seq.keys[i] != 0; > i++); > + > + keyboard->compose_seq.keys[i] = sym; > + > + cs = bsearch (&keyboard->compose_seq, compose_seqs, > + ARRAY_LENGTH(compose_seqs), > + sizeof(compose_seqs[0]), > compare_compose_keys); > + > + if (cs) { > + if (cs->keys[i + 1] == 0) { > + zwp_input_method_context_v1_preedit_ > cursor(keyboard->context, > + > 0); > + zwp_input_method_context_v1_preedit_ > string(keyboard->context, > + > keyboard->serial, > + > "", ""); > + zwp_input_method_context_v1_cursor_p > osition(keyboard->context, > + > 0, 0); > + zwp_input_method_context_v1_commit_s > tring(keyboard->context, > + > keyboard->serial, > + > cs->text); > + keyboard->compose_state = > state_normal; > + } else { > + uint32_t j = 0, idx = 0; > + > + for (; j <= i; j++) { > + idx += > xkb_keysym_to_utf8(cs->keys[j], text + idx, sizeof(text) - idx); > + } > + > + zwp_input_method_context_v1_preedit_ > cursor(keyboard->context, > + > strlen(text)); > + zwp_input_method_context_v1_preedit_ > string(keyboard->context, > + > keyboard->serial, > + > text, > + > text); > + } > + } else { > + uint32_t j = 0, idx = 0; > + > + for (; j <= i; j++) { > + idx += xkb_keysym_to_utf8(keyboard- > >compose_seq.keys[j], text + idx, sizeof(text) - idx); > + } > + zwp_input_method_context_v1_preedit_cursor(k > eyboard->context, > + 0 > ); > + zwp_input_method_context_v1_preedit_string(k > eyboard->context, > + k > eyboard->serial, > + " > ", ""); > + zwp_input_method_context_v1_cursor_position( > keyboard->context, > + > 0, 0); > + zwp_input_method_context_v1_commit_string(ke > yboard->context, > + ke > yboard->serial, > + te > xt); > + keyboard->compose_state = state_normal; > + } > + return; > + } > + > + if (xkb_keysym_to_utf8(sym, text, sizeof(text)) <= 0) { > + zwp_input_method_context_v1_key(context, serial, > time, key, state); > + return; > + } > + > + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) > + return; > + > + zwp_input_method_context_v1_cursor_position(keyboard- > >context, > + 0, 0); > + zwp_input_method_context_v1_commit_string(keyboard->context, > + keyboard->serial, > + text); > +} > + > +int > +main(int argc, char *argv[]) > +{ > + struct simple_im simple_im; > + int ret = 0; > + > + memset(&simple_im, 0, sizeof(simple_im)); > + > + simple_im.display = wl_display_connect(NULL); > + if (simple_im.display == NULL) { > + fprintf(stderr, "Failed to connect to server: > %m\n"); > + return -1; > + } > + > + simple_im.registry = > wl_display_get_registry(simple_im.display); > + wl_registry_add_listener(simple_im.registry, > + ®istry_listener, &simple_im); > + wl_display_roundtrip(simple_im.display); > + if (simple_im.input_method == NULL) { > + fprintf(stderr, "No input_method global\n"); > + return -1; > + } > + > + simple_im.xkb_context = > xkb_context_new(XKB_CONTEXT_NO_FLAGS); > + if (simple_im.xkb_context == NULL) { > + fprintf(stderr, "Failed to create XKB context\n"); > + return -1; > + } > + > + simple_im.context = NULL; > + simple_im.key_handler = simple_im_key_handler; > + > + while (ret != -1) > + ret = wl_display_dispatch(simple_im.display); > + > + if (ret == -1) { > + fprintf(stderr, "Dispatch error: %m\n"); > + return -1; > + } > + > + return 0; > +} > diff --git a/clients/weston-simple-im.c b/clients/weston-simple-im.c > deleted file mode 100644 > index 280589b..0000000 > --- a/clients/weston-simple-im.c > +++ /dev/null > @@ -1,524 +0,0 @@ > -/* > - * Copyright © 2012 Intel Corporation > - * > - * Permission is hereby granted, free of charge, to any person > obtaining a > - * copy of this software and associated documentation files (the > "Software"), > - * to deal in the Software without restriction, including without > limitation > - * the rights to use, copy, modify, merge, publish, distribute, > sublicense, > - * and/or sell copies of the Software, and to permit persons to whom > the > - * Software is furnished to do so, subject to the following > conditions: > - * > - * The above copyright notice and this permission notice (including > the next > - * paragraph) shall be included in all copies or substantial > portions of the > - * Software. > - * > - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS OR > - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO > EVENT SHALL > - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES > OR OTHER > - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > ARISING > - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > OTHER > - * DEALINGS IN THE SOFTWARE. > - */ > - > -#include "config.h" > - > -#include <stdint.h> > -#include <stdio.h> > -#include <stdlib.h> > -#include <string.h> > -#include <unistd.h> > -#include <sys/mman.h> > - > -#include <linux/input.h> > - > -#include "window.h" > -#include "input-method-unstable-v1-client-protocol.h" > -#include "shared/helpers.h" > - > -enum compose_state { > - state_normal, > - state_compose > -}; > - > -struct compose_seq { > - uint32_t keys[4]; > - > - const char *text; > -}; > - > -struct simple_im; > - > -typedef void (*keyboard_input_key_handler_t)(struct simple_im > *keyboard, > - uint32_t serial, > - uint32_t time, uint32_t > key, uint32_t unicode, > - enum > wl_keyboard_key_state state); > - > -struct simple_im { > - struct zwp_input_method_v1 *input_method; > - struct zwp_input_method_context_v1 *context; > - struct wl_display *display; > - struct wl_registry *registry; > - struct wl_keyboard *keyboard; > - enum compose_state compose_state; > - struct compose_seq compose_seq; > - > - struct xkb_context *xkb_context; > - > - uint32_t modifiers; > - > - struct xkb_keymap *keymap; > - struct xkb_state *state; > - xkb_mod_mask_t control_mask; > - xkb_mod_mask_t alt_mask; > - xkb_mod_mask_t shift_mask; > - > - keyboard_input_key_handler_t key_handler; > - > - uint32_t serial; > -}; > - > -static const struct compose_seq compose_seqs[] = { > - { { XKB_KEY_quotedbl, XKB_KEY_A, 0 }, "Ä" }, > - { { XKB_KEY_quotedbl, XKB_KEY_O, 0 }, "Ö" }, > - { { XKB_KEY_quotedbl, XKB_KEY_U, 0 }, "Ü" }, > - { { XKB_KEY_quotedbl, XKB_KEY_a, 0 }, "ä" }, > - { { XKB_KEY_quotedbl, XKB_KEY_o, 0 }, "ö" }, > - { { XKB_KEY_quotedbl, XKB_KEY_u, 0 }, "ü" }, > - { { XKB_KEY_apostrophe, XKB_KEY_A, 0 }, "Á" }, > - { { XKB_KEY_apostrophe, XKB_KEY_a, 0 }, "á" }, > - { { XKB_KEY_slash, XKB_KEY_O, 0 }, "Ø" }, > - { { XKB_KEY_slash, XKB_KEY_o, 0 }, "ø" }, > - { { XKB_KEY_less, XKB_KEY_3, 0 }, "♥" }, > - { { XKB_KEY_A, XKB_KEY_A, 0 }, "Å" }, > - { { XKB_KEY_A, XKB_KEY_E, 0 }, "Æ" }, > - { { XKB_KEY_O, XKB_KEY_C, 0 }, "©" }, > - { { XKB_KEY_O, XKB_KEY_R, 0 }, "®" }, > - { { XKB_KEY_s, XKB_KEY_s, 0 }, "ß" }, > - { { XKB_KEY_a, XKB_KEY_e, 0 }, "æ" }, > - { { XKB_KEY_a, XKB_KEY_a, 0 }, "å" }, > -}; > - > -static const uint32_t ignore_keys_on_compose[] = { > - XKB_KEY_Shift_L, > - XKB_KEY_Shift_R > -}; > - > -static void > -handle_surrounding_text(void *data, > - struct zwp_input_method_context_v1 *context, > - const char *text, > - uint32_t cursor, > - uint32_t anchor) > -{ > - fprintf(stderr, "Surrounding text updated: %s\n", text); > -} > - > -static void > -handle_reset(void *data, > - struct zwp_input_method_context_v1 *context) > -{ > - struct simple_im *keyboard = data; > - > - fprintf(stderr, "Reset pre-edit buffer\n"); > - > - keyboard->compose_state = state_normal; > -} > - > -static void > -handle_content_type(void *data, > - struct zwp_input_method_context_v1 *context, > - uint32_t hint, > - uint32_t purpose) > -{ > -} > - > -static void > -handle_invoke_action(void *data, > - struct zwp_input_method_context_v1 *context, > - uint32_t button, > - uint32_t index) > -{ > -} > - > -static void > -handle_commit_state(void *data, > - struct zwp_input_method_context_v1 *context, > - uint32_t serial) > -{ > - struct simple_im *keyboard = data; > - > - keyboard->serial = serial; > -} > - > -static void > -handle_preferred_language(void *data, > - struct zwp_input_method_context_v1 > *context, > - const char *language) > -{ > -} > - > -static const struct zwp_input_method_context_v1_listener > input_method_context_listener = { > - handle_surrounding_text, > - handle_reset, > - handle_content_type, > - handle_invoke_action, > - handle_commit_state, > - handle_preferred_language > -}; > - > -static void > -input_method_keyboard_keymap(void *data, > - struct wl_keyboard *wl_keyboard, > - uint32_t format, > - int32_t fd, > - uint32_t size) > -{ > - struct simple_im *keyboard = data; > - char *map_str; > - > - if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { > - close(fd); > - return; > - } > - > - map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); > - if (map_str == MAP_FAILED) { > - close(fd); > - return; > - } > - > - keyboard->keymap = > - xkb_keymap_new_from_string(keyboard->xkb_context, > - map_str, > - XKB_KEYMAP_FORMAT_TEXT_V1 > , > - XKB_KEYMAP_COMPILE_NO_FLA > GS); > - > - munmap(map_str, size); > - close(fd); > - > - if (!keyboard->keymap) { > - fprintf(stderr, "Failed to compile keymap\n"); > - return; > - } > - > - keyboard->state = xkb_state_new(keyboard->keymap); > - if (!keyboard->state) { > - fprintf(stderr, "Failed to create XKB state\n"); > - xkb_keymap_unref(keyboard->keymap); > - return; > - } > - > - keyboard->control_mask = > - 1 << xkb_keymap_mod_get_index(keyboard->keymap, > "Control"); > - keyboard->alt_mask = > - 1 << xkb_keymap_mod_get_index(keyboard->keymap, > "Mod1"); > - keyboard->shift_mask = > - 1 << xkb_keymap_mod_get_index(keyboard->keymap, > "Shift"); > -} > - > -static void > -input_method_keyboard_key(void *data, > - struct wl_keyboard *wl_keyboard, > - uint32_t serial, > - uint32_t time, > - uint32_t key, > - uint32_t state_w) > -{ > - struct simple_im *keyboard = data; > - uint32_t code; > - uint32_t num_syms; > - const xkb_keysym_t *syms; > - xkb_keysym_t sym; > - enum wl_keyboard_key_state state = state_w; > - > - if (!keyboard->state) > - return; > - > - code = key + 8; > - num_syms = xkb_state_key_get_syms(keyboard->state, code, > &syms); > - > - sym = XKB_KEY_NoSymbol; > - if (num_syms == 1) > - sym = syms[0]; > - > - if (keyboard->key_handler) > - (*keyboard->key_handler)(keyboard, serial, time, > key, sym, > - state); > -} > - > -static void > -input_method_keyboard_modifiers(void *data, > - struct wl_keyboard *wl_keyboard, > - uint32_t serial, > - uint32_t mods_depressed, > - uint32_t mods_latched, > - uint32_t mods_locked, > - uint32_t group) > -{ > - struct simple_im *keyboard = data; > - struct zwp_input_method_context_v1 *context = keyboard- > >context; > - xkb_mod_mask_t mask; > - > - xkb_state_update_mask(keyboard->state, mods_depressed, > - mods_latched, mods_locked, 0, 0, > group); > - mask = xkb_state_serialize_mods(keyboard->state, > - XKB_STATE_MODS_DEPRESSED | > - XKB_STATE_MODS_LATCHED); > - > - keyboard->modifiers = 0; > - if (mask & keyboard->control_mask) > - keyboard->modifiers |= MOD_CONTROL_MASK; > - if (mask & keyboard->alt_mask) > - keyboard->modifiers |= MOD_ALT_MASK; > - if (mask & keyboard->shift_mask) > - keyboard->modifiers |= MOD_SHIFT_MASK; > - > - zwp_input_method_context_v1_modifiers(context, serial, > - mods_depressed, > mods_depressed, > - mods_latched, group); > -} > - > -static const struct wl_keyboard_listener > input_method_keyboard_listener = { > - input_method_keyboard_keymap, > - NULL, /* enter */ > - NULL, /* leave */ > - input_method_keyboard_key, > - input_method_keyboard_modifiers > -}; > - > -static void > -input_method_activate(void *data, > - struct zwp_input_method_v1 *input_method, > - struct zwp_input_method_context_v1 *context) > -{ > - struct simple_im *keyboard = data; > - > - if (keyboard->context) > - zwp_input_method_context_v1_destroy(keyboard- > >context); > - > - keyboard->compose_state = state_normal; > - > - keyboard->serial = 0; > - > - keyboard->context = context; > - zwp_input_method_context_v1_add_listener(context, > - &input_method_conte > xt_listener, > - keyboard); > - keyboard->keyboard = > zwp_input_method_context_v1_grab_keyboard(context); > - wl_keyboard_add_listener(keyboard->keyboard, > - &input_method_keyboard_listener, > - keyboard); > -} > - > -static void > -input_method_deactivate(void *data, > - struct zwp_input_method_v1 *input_method, > - struct zwp_input_method_context_v1 *context) > -{ > - struct simple_im *keyboard = data; > - > - if (!keyboard->context) > - return; > - > - zwp_input_method_context_v1_destroy(keyboard->context); > - keyboard->context = NULL; > -} > - > -static const struct zwp_input_method_v1_listener > input_method_listener = { > - input_method_activate, > - input_method_deactivate > -}; > - > -static void > -registry_handle_global(void *data, struct wl_registry *registry, > - uint32_t name, const char *interface, > uint32_t version) > -{ > - struct simple_im *keyboard = data; > - > - if (!strcmp(interface, "zwp_input_method_v1")) { > - keyboard->input_method = > - wl_registry_bind(registry, name, > - &zwp_input_method_v1_interf > ace, 1); > - zwp_input_method_v1_add_listener(keyboard- > >input_method, > - &input_method_liste > ner, keyboard); > - } > -} > - > -static void > -registry_handle_global_remove(void *data, struct wl_registry > *registry, > - uint32_t name) > -{ > -} > - > -static const struct wl_registry_listener registry_listener = { > - registry_handle_global, > - registry_handle_global_remove > -}; > - > -static int > -compare_compose_keys(const void *c1, const void *c2) > -{ > - const struct compose_seq *cs1 = c1; > - const struct compose_seq *cs2 = c2; > - int i; > - > - for (i = 0; cs1->keys[i] != 0 && cs2->keys[i] != 0; i++) { > - if (cs1->keys[i] != cs2->keys[i]) > - return cs1->keys[i] - cs2->keys[i]; > - } > - > - if (cs1->keys[i] == cs2->keys[i] > - || cs1->keys[i] == 0) > - return 0; > - > - return cs1->keys[i] - cs2->keys[i]; > -} > - > -static void > -simple_im_key_handler(struct simple_im *keyboard, > - uint32_t serial, uint32_t time, uint32_t key, > uint32_t sym, > - enum wl_keyboard_key_state state) > -{ > - struct zwp_input_method_context_v1 *context = keyboard- > >context; > - char text[64]; > - > - if (sym == XKB_KEY_Multi_key && > - state == WL_KEYBOARD_KEY_STATE_RELEASED && > - keyboard->compose_state == state_normal) { > - keyboard->compose_state = state_compose; > - memset(&keyboard->compose_seq, 0, sizeof(struct > compose_seq)); > - return; > - } > - > - if (keyboard->compose_state == state_compose) { > - uint32_t i = 0; > - struct compose_seq *cs; > - > - if (state == WL_KEYBOARD_KEY_STATE_PRESSED) > - return; > - > - for (i = 0; i < > ARRAY_LENGTH(ignore_keys_on_compose); i++) { > - if (sym == ignore_keys_on_compose[i]) { > - zwp_input_method_context_v1_key(cont > ext, > - keyb > oard->serial, > - time > , > - key, > - stat > e); > - return; > - } > - } > - > - for (i = 0; keyboard->compose_seq.keys[i] != 0; > i++); > - > - keyboard->compose_seq.keys[i] = sym; > - > - cs = bsearch (&keyboard->compose_seq, compose_seqs, > - ARRAY_LENGTH(compose_seqs), > - sizeof(compose_seqs[0]), > compare_compose_keys); > - > - if (cs) { > - if (cs->keys[i + 1] == 0) { > - zwp_input_method_context_v1_preedit_ > cursor(keyboard->context, > - > 0); > - zwp_input_method_context_v1_preedit_ > string(keyboard->context, > - > keyboard->serial, > - > "", ""); > - zwp_input_method_context_v1_cursor_p > osition(keyboard->context, > - > 0, 0); > - zwp_input_method_context_v1_commit_s > tring(keyboard->context, > - > keyboard->serial, > - > cs->text); > - keyboard->compose_state = > state_normal; > - } else { > - uint32_t j = 0, idx = 0; > - > - for (; j <= i; j++) { > - idx += > xkb_keysym_to_utf8(cs->keys[j], text + idx, sizeof(text) - idx); > - } > - > - zwp_input_method_context_v1_preedit_ > cursor(keyboard->context, > - > strlen(text)); > - zwp_input_method_context_v1_preedit_ > string(keyboard->context, > - > keyboard->serial, > - > text, > - > text); > - } > - } else { > - uint32_t j = 0, idx = 0; > - > - for (; j <= i; j++) { > - idx += xkb_keysym_to_utf8(keyboard- > >compose_seq.keys[j], text + idx, sizeof(text) - idx); > - } > - zwp_input_method_context_v1_preedit_cursor(k > eyboard->context, > - 0 > ); > - zwp_input_method_context_v1_preedit_string(k > eyboard->context, > - k > eyboard->serial, > - " > ", ""); > - zwp_input_method_context_v1_cursor_position( > keyboard->context, > - > 0, 0); > - zwp_input_method_context_v1_commit_string(ke > yboard->context, > - ke > yboard->serial, > - te > xt); > - keyboard->compose_state = state_normal; > - } > - return; > - } > - > - if (xkb_keysym_to_utf8(sym, text, sizeof(text)) <= 0) { > - zwp_input_method_context_v1_key(context, serial, > time, key, state); > - return; > - } > - > - if (state == WL_KEYBOARD_KEY_STATE_PRESSED) > - return; > - > - zwp_input_method_context_v1_cursor_position(keyboard- > >context, > - 0, 0); > - zwp_input_method_context_v1_commit_string(keyboard->context, > - keyboard->serial, > - text); > -} > - > -int > -main(int argc, char *argv[]) > -{ > - struct simple_im simple_im; > - int ret = 0; > - > - memset(&simple_im, 0, sizeof(simple_im)); > - > - simple_im.display = wl_display_connect(NULL); > - if (simple_im.display == NULL) { > - fprintf(stderr, "Failed to connect to server: > %m\n"); > - return -1; > - } > - > - simple_im.registry = > wl_display_get_registry(simple_im.display); > - wl_registry_add_listener(simple_im.registry, > - ®istry_listener, &simple_im); > - wl_display_roundtrip(simple_im.display); > - if (simple_im.input_method == NULL) { > - fprintf(stderr, "No input_method global\n"); > - return -1; > - } > - > - simple_im.xkb_context = > xkb_context_new(XKB_CONTEXT_NO_FLAGS); > - if (simple_im.xkb_context == NULL) { > - fprintf(stderr, "Failed to create XKB context\n"); > - return -1; > - } > - > - simple_im.context = NULL; > - simple_im.key_handler = simple_im_key_handler; > - > - while (ret != -1) > - ret = wl_display_dispatch(simple_im.display); > - > - if (ret == -1) { > - fprintf(stderr, "Dispatch error: %m\n"); > - return -1; > - } > - > - return 0; > -}
This series looks good: Reviewed-by: Jan Arne Petersen <[email protected]> _______________________________________________ wayland-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/wayland-devel
