summaryrefslogtreecommitdiff
path: root/src/lib/efl_wl/x11.x
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2018-01-24 16:16:17 -0500
committerMike Blumenkrantz <zmike@osg.samsung.com>2018-01-24 16:18:51 -0500
commita32735e9a7bc537430d155a4af853d498dda2009 (patch)
treea3076403e7c261d3e229e51991005f6d3bc3fcbf /src/lib/efl_wl/x11.x
parent6e4c3b04458052ab94b7b358074a6df9cdd1479d (diff)
efl-wl: create and maintain xserver-based keymap and keyboard states under x11
when run in a non-wayland environment, it's necessary to do some extra work in order to guarantee that the keymap remains the same in the compositor as in the xserver and to also guarantee that modifier states are accurately applied even when the compositor is not actively focused fix T6631
Diffstat (limited to '')
-rw-r--r--src/lib/efl_wl/x11.x118
1 files changed, 112 insertions, 6 deletions
diff --git a/src/lib/efl_wl/x11.x b/src/lib/efl_wl/x11.x
index bebd017519..2d7a88352f 100644
--- a/src/lib/efl_wl/x11.x
+++ b/src/lib/efl_wl/x11.x
@@ -1,3 +1,5 @@
1#include "xkbcommon/xkbcommon-x11.h"
2
1#define WL_TEXT_STR "text/plain;charset=utf-8" 3#define WL_TEXT_STR "text/plain;charset=utf-8"
2#define INCR_CHUNK_SIZE 1 << 17 4#define INCR_CHUNK_SIZE 1 << 17
3 5
@@ -562,6 +564,99 @@ x11_dnd_move(void *data, Ecore_X_Xdnd_Position *pos)
562 evas_object_move(data, pos->position.x, pos->position.y); 564 evas_object_move(data, pos->position.x, pos->position.y);
563} 565}
564 566
567static int32_t x11_core_device = -1;
568static struct xkb_context *x11_kbd_context;
569static struct xkb_keymap *x11_kbd_keymap;
570static struct xkb_state *x11_kbd_state;
571
572static Eina_Bool seat_kbd_mods_update(Comp_Seat *s);
573static void comp_seat_send_modifiers(Comp_Seat *s, struct wl_resource *res, uint32_t serial);
574
575static Eina_Bool
576x11_xkb_state(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Xkb *ev)
577{
578 Comp *c;
579 Eina_List *l;
580 Comp_Seat *s;
581
582 if (!xkb_state_update_mask(x11_kbd_state,
583 get_xkb_mod_mask(ev->base_mods),
584 get_xkb_mod_mask(ev->latched_mods),
585 get_xkb_mod_mask(ev->locked_mods),
586 0,
587 0,
588 ev->group)) return ECORE_CALLBACK_RENEW;
589 EINA_LIST_FOREACH(comps, l, c)
590 EINA_INLIST_FOREACH(c->seats, s)
591 {
592 Eina_List *ll, *lll;
593 uint32_t serial;
594 struct wl_resource *res;
595
596 seat_kbd_mods_update(s);
597 ll = seat_kbd_active_resources_get(s);
598 if (!ll) continue;
599 serial = wl_display_next_serial(s->c->display);
600 EINA_LIST_FOREACH(ll, lll, res)
601 comp_seat_send_modifiers(s, res, serial);
602 }
603 return ECORE_CALLBACK_RENEW;
604}
605
606static void
607x11_kbd_destroy(void)
608{
609 if (x11_kbd_state) xkb_state_unref(x11_kbd_state);
610 x11_kbd_state = NULL;
611 if (x11_kbd_keymap) xkb_keymap_unref(x11_kbd_keymap);
612 x11_kbd_keymap = NULL;
613 if (x11_kbd_context) xkb_context_unref(x11_kbd_context);
614 x11_kbd_context = NULL;
615}
616
617static void
618x11_kbd_create(void)
619{
620 Ecore_X_Connection *conn = ecore_x_connection_get();
621
622 x11_kbd_destroy();
623
624 x11_kbd_context = xkb_context_new(0);
625 x11_core_device = xkb_x11_get_core_keyboard_device_id(conn);
626 x11_kbd_keymap = xkb_x11_keymap_new_from_device(x11_kbd_context, conn, x11_core_device, 0);
627 x11_kbd_state = xkb_x11_state_new_from_device(x11_kbd_keymap, conn, x11_core_device);
628 keymap_mods_init(x11_kbd_keymap);
629}
630
631static void
632x11_kbd_apply(Comp_Seat *s)
633{
634 if (!x11_kbd_state) x11_kbd_create();
635 s->kbd.context = x11_kbd_context;
636 s->kbd.keymap = x11_kbd_keymap;
637 s->kbd.state = x11_kbd_state;
638}
639
640static void seat_keymap_update(Comp_Seat *s);
641
642static Eina_Bool
643x11_xkb_refresh()
644{
645 Eina_List *l;
646 Comp *c;
647 Comp_Seat *s;
648
649 x11_kbd_create();
650 EINA_LIST_FOREACH(comps, l, c)
651 EINA_INLIST_FOREACH(c->seats, s)
652 {
653 if (!s->keyboard) continue;
654 x11_kbd_apply(s);
655 seat_keymap_update(s);
656 }
657 return ECORE_CALLBACK_RENEW;
658}
659
565static void 660static void
566x11_init(void) 661x11_init(void)
567{ 662{
@@ -589,18 +684,29 @@ x11_init(void)
589 handlers = eina_list_append(handlers, h); 684 handlers = eina_list_append(handlers, h);
590 h = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, (Ecore_Event_Handler_Cb)x11_dnd_mouse_up, NULL); 685 h = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, (Ecore_Event_Handler_Cb)x11_dnd_mouse_up, NULL);
591 handlers = eina_list_append(handlers, h); 686 handlers = eina_list_append(handlers, h);
592 xconvertselection = dlsym(NULL, "XConvertSelection"); 687 h = ecore_event_handler_add(ECORE_X_EVENT_XKB_STATE_NOTIFY, (Ecore_Event_Handler_Cb)x11_xkb_state, NULL);
593 string_atom = ecore_x_atom_get("UTF8_STRING"); 688 handlers = eina_list_append(handlers, h);
594 timestamp_atom = ecore_x_atom_get("TIMESTAMP"); 689 h = ecore_event_handler_add(ECORE_X_EVENT_XKB_NEWKBD_NOTIFY, (Ecore_Event_Handler_Cb)x11_xkb_refresh, NULL);
595 int_atom = ecore_x_atom_get("INTEGER"); 690 handlers = eina_list_append(handlers, h);
596 incr_atom = ecore_x_atom_get("TIMESTAMP"); 691 if (!xconvertselection)
597 comp_dnd_atom = ecore_x_atom_get("SIRCMPWIDG_ATOM"); 692 {
693 xconvertselection = dlsym(NULL, "XConvertSelection");
694 string_atom = ecore_x_atom_get("UTF8_STRING");
695 timestamp_atom = ecore_x_atom_get("TIMESTAMP");
696 int_atom = ecore_x_atom_get("INTEGER");
697 incr_atom = ecore_x_atom_get("TIMESTAMP");
698 comp_dnd_atom = ecore_x_atom_get("SIRCMPWIDG_ATOM");
699 ecore_x_xkb_track_state();
700 }
701
598 pipes = eina_hash_int32_new((Eina_Free_Cb)_pipe_free); 702 pipes = eina_hash_int32_new((Eina_Free_Cb)_pipe_free);
599} 703}
600 704
601static void 705static void
602x11_shutdown(void) 706x11_shutdown(void)
603{ 707{
708 x11_core_device = -1;
709 x11_kbd_destroy();
604 eina_hash_free(pipes); 710 eina_hash_free(pipes);
605 pipes = NULL; 711 pipes = NULL;
606} 712}