diff options
author | Mike Blumenkrantz <zmike@osg.samsung.com> | 2017-05-26 16:34:10 -0400 |
---|---|---|
committer | Mike Blumenkrantz <zmike@osg.samsung.com> | 2017-05-26 16:27:42 -0400 |
commit | 6ddcd48fdeb57fc5b237825df709a2e3746e845e (patch) | |
tree | d6d0226d65305f54a0843cb26f56565c53637bcf /src/lib/elput | |
parent | f7ae2a7de8cfc9a2c6731eb4ee3a87460eb4685e (diff) |
elput: implement compose sequences
@feature
fix T5006
Diffstat (limited to 'src/lib/elput')
-rw-r--r-- | src/lib/elput/elput_evdev.c | 70 | ||||
-rw-r--r-- | src/lib/elput/elput_private.h | 3 |
2 files changed, 53 insertions, 20 deletions
diff --git a/src/lib/elput/elput_evdev.c b/src/lib/elput/elput_evdev.c index 0ce57d9f23..3c6243bc1a 100644 --- a/src/lib/elput/elput_evdev.c +++ b/src/lib/elput/elput_evdev.c | |||
@@ -195,6 +195,24 @@ _keyboard_create(Elput_Seat *seat) | |||
195 | return kbd; | 195 | return kbd; |
196 | } | 196 | } |
197 | 197 | ||
198 | static void | ||
199 | _keyboard_compose_init(Elput_Keyboard *kbd) | ||
200 | { | ||
201 | const char *locale; | ||
202 | if (!(locale = getenv("LC_ALL"))) | ||
203 | if (!(locale = getenv("LC_CTYPE"))) | ||
204 | if (!(locale = getenv("LANG"))) | ||
205 | locale = "C"; | ||
206 | if (kbd->compose_table) xkb_compose_table_unref(kbd->compose_table); | ||
207 | kbd->compose_table = xkb_compose_table_new_from_locale(kbd->context, locale, | ||
208 | XKB_COMPOSE_COMPILE_NO_FLAGS); | ||
209 | if (kbd->compose_table) | ||
210 | { | ||
211 | if (kbd->compose_state) xkb_compose_state_unref(kbd->compose_state); | ||
212 | kbd->compose_state = xkb_compose_state_new(kbd->compose_table, XKB_COMPOSE_STATE_NO_FLAGS); | ||
213 | } | ||
214 | } | ||
215 | |||
198 | static Eina_Bool | 216 | static Eina_Bool |
199 | _keyboard_init(Elput_Seat *seat, struct xkb_keymap *keymap) | 217 | _keyboard_init(Elput_Seat *seat, struct xkb_keymap *keymap) |
200 | { | 218 | { |
@@ -226,6 +244,8 @@ _keyboard_init(Elput_Seat *seat, struct xkb_keymap *keymap) | |||
226 | if (!kbd->state) goto err; | 244 | if (!kbd->state) goto err; |
227 | kbd->maskless_state = xkb_state_new(kbd->info->keymap.map); | 245 | kbd->maskless_state = xkb_state_new(kbd->info->keymap.map); |
228 | 246 | ||
247 | _keyboard_compose_init(kbd); | ||
248 | |||
229 | seat->kbd = kbd; | 249 | seat->kbd = kbd; |
230 | seat->count.kbd = 1; | 250 | seat->count.kbd = 1; |
231 | 251 | ||
@@ -482,6 +502,32 @@ in this Software without prior written authorization from The Open Group. | |||
482 | return 1; | 502 | return 1; |
483 | } | 503 | } |
484 | 504 | ||
505 | /* from weston/clients/window.c */ | ||
506 | /* Translate symbols appropriately if a compose sequence is being entered */ | ||
507 | static xkb_keysym_t | ||
508 | process_key_press(xkb_keysym_t sym, Elput_Keyboard *kbd) | ||
509 | { | ||
510 | if (!kbd->compose_state) | ||
511 | return sym; | ||
512 | if (sym == XKB_KEY_NoSymbol) | ||
513 | return sym; | ||
514 | if (xkb_compose_state_feed(kbd->compose_state, sym) != XKB_COMPOSE_FEED_ACCEPTED) | ||
515 | return sym; | ||
516 | |||
517 | switch (xkb_compose_state_get_status(kbd->compose_state)) | ||
518 | { | ||
519 | case XKB_COMPOSE_COMPOSING: | ||
520 | return XKB_KEY_NoSymbol; | ||
521 | case XKB_COMPOSE_COMPOSED: | ||
522 | return xkb_compose_state_get_one_sym(kbd->compose_state); | ||
523 | case XKB_COMPOSE_CANCELLED: | ||
524 | return XKB_KEY_NoSymbol; | ||
525 | case XKB_COMPOSE_NOTHING: | ||
526 | default: break; | ||
527 | } | ||
528 | return sym; | ||
529 | } | ||
530 | |||
485 | static void | 531 | static void |
486 | _elput_symbol_rep_find(xkb_keysym_t keysym, char *buffer, int size, unsigned int code) | 532 | _elput_symbol_rep_find(xkb_keysym_t keysym, char *buffer, int size, unsigned int code) |
487 | { | 533 | { |
@@ -512,8 +558,7 @@ _keyboard_key(struct libinput_device *idevice, struct libinput_event_keyboard *e | |||
512 | unsigned int code = 0; | 558 | unsigned int code = 0; |
513 | unsigned int nsyms; | 559 | unsigned int nsyms; |
514 | unsigned int timestamp; | 560 | unsigned int timestamp; |
515 | char key[256], keyname[256], buffer[256]; | 561 | char key[256] = {0}, keyname[256] = {0}, compose[256] = {0}; |
516 | char *tmp = NULL, *compose = NULL; | ||
517 | int count; | 562 | int count; |
518 | 563 | ||
519 | dev = libinput_device_get_user_data(idevice); | 564 | dev = libinput_device_get_user_data(idevice); |
@@ -544,6 +589,8 @@ _keyboard_key(struct libinput_device *idevice, struct libinput_event_keyboard *e | |||
544 | if (nsyms == 1) sym = syms[0]; | 589 | if (nsyms == 1) sym = syms[0]; |
545 | sym_name = xkb_state_key_get_one_sym(kbd->maskless_state, code); | 590 | sym_name = xkb_state_key_get_one_sym(kbd->maskless_state, code); |
546 | 591 | ||
592 | if (state == LIBINPUT_KEY_STATE_PRESSED) | ||
593 | sym = process_key_press(sym, kbd); | ||
547 | 594 | ||
548 | _elput_symbol_rep_find(sym, key, sizeof(key), code); | 595 | _elput_symbol_rep_find(sym, key, sizeof(key), code); |
549 | _elput_symbol_rep_find(sym_name, keyname, sizeof(keyname), code); | 596 | _elput_symbol_rep_find(sym_name, keyname, sizeof(keyname), code); |
@@ -560,26 +607,9 @@ _keyboard_key(struct libinput_device *idevice, struct libinput_event_keyboard *e | |||
560 | 607 | ||
561 | _keyboard_modifiers_update(kbd, dev->seat); | 608 | _keyboard_modifiers_update(kbd, dev->seat); |
562 | 609 | ||
563 | memset(buffer, 0, sizeof(buffer)); | 610 | _keyboard_keysym_translate(sym, dev->seat->modifiers, compose, sizeof(compose)); |
564 | if (_keyboard_keysym_translate(sym, dev->seat->modifiers, | ||
565 | buffer, sizeof(buffer))) | ||
566 | { | ||
567 | compose = eina_str_convert("ISO8859-1", "UTF-8", buffer); | ||
568 | if (!compose) | ||
569 | { | ||
570 | ERR("Elput cannot convert input key string '%s' to UTF-8. " | ||
571 | "Is Eina built with iconv support?", buffer); | ||
572 | } | ||
573 | else | ||
574 | tmp = compose; | ||
575 | } | ||
576 | |||
577 | if (!compose) compose = buffer; | ||
578 | |||
579 | _keyboard_key_send(dev, state, keyname, key, compose, code, timestamp); | 611 | _keyboard_key_send(dev, state, keyname, key, compose, code, timestamp); |
580 | 612 | ||
581 | if (tmp) free(tmp); | ||
582 | |||
583 | if ((kbd->pending_map) && (count == 0)) | 613 | if ((kbd->pending_map) && (count == 0)) |
584 | _keyboard_keymap_update(dev->seat); | 614 | _keyboard_keymap_update(dev->seat); |
585 | 615 | ||
diff --git a/src/lib/elput/elput_private.h b/src/lib/elput/elput_private.h index a2d46acbf5..c6e3c81d83 100644 --- a/src/lib/elput/elput_private.h +++ b/src/lib/elput/elput_private.h | |||
@@ -22,6 +22,7 @@ | |||
22 | # include <linux/input.h> | 22 | # include <linux/input.h> |
23 | # include <libinput.h> | 23 | # include <libinput.h> |
24 | # include <xkbcommon/xkbcommon.h> | 24 | # include <xkbcommon/xkbcommon.h> |
25 | # include <xkbcommon/xkbcommon-compose.h> | ||
25 | 26 | ||
26 | # ifdef HAVE_SYSTEMD | 27 | # ifdef HAVE_SYSTEMD |
27 | # include <systemd/sd-login.h> | 28 | # include <systemd/sd-login.h> |
@@ -140,6 +141,8 @@ struct _Elput_Keyboard | |||
140 | struct xkb_state *maskless_state; | 141 | struct xkb_state *maskless_state; |
141 | struct xkb_context *context; | 142 | struct xkb_context *context; |
142 | struct xkb_rule_names names; | 143 | struct xkb_rule_names names; |
144 | struct xkb_compose_table *compose_table; | ||
145 | struct xkb_compose_state *compose_state; | ||
143 | 146 | ||
144 | Elput_Seat *seat; | 147 | Elput_Seat *seat; |
145 | 148 | ||