summaryrefslogtreecommitdiff
path: root/src/lib/efl_wl
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
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 'src/lib/efl_wl')
-rw-r--r--src/lib/efl_wl/copiedfromweston.x50
-rw-r--r--src/lib/efl_wl/efl_wl.c57
-rw-r--r--src/lib/efl_wl/x11.x118
3 files changed, 200 insertions, 25 deletions
diff --git a/src/lib/efl_wl/copiedfromweston.x b/src/lib/efl_wl/copiedfromweston.x
index 0b1388b064..17a31cbe55 100644
--- a/src/lib/efl_wl/copiedfromweston.x
+++ b/src/lib/efl_wl/copiedfromweston.x
@@ -356,3 +356,53 @@ drag_grab_button(Comp_Seat *s,
356#endif 356#endif
357 } 357 }
358} 358}
359
360#ifdef HAVE_ECORE_X
361static xkb_mod_index_t x11_kbd_shift_mod;
362static xkb_mod_index_t x11_kbd_caps_mod;
363static xkb_mod_index_t x11_kbd_ctrl_mod;
364static xkb_mod_index_t x11_kbd_alt_mod;
365static xkb_mod_index_t x11_kbd_mod2_mod;
366static xkb_mod_index_t x11_kbd_mod3_mod;
367static xkb_mod_index_t x11_kbd_super_mod;
368static xkb_mod_index_t x11_kbd_mod5_mod;
369
370static void
371keymap_mods_init(struct xkb_keymap *keymap)
372{
373 x11_kbd_shift_mod = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
374 x11_kbd_caps_mod = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
375 x11_kbd_ctrl_mod = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
376 x11_kbd_alt_mod = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_ALT);
377 x11_kbd_mod2_mod = xkb_keymap_mod_get_index(keymap, "Mod2");
378 x11_kbd_mod3_mod = xkb_keymap_mod_get_index(keymap, "Mod3");
379 x11_kbd_super_mod = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
380 x11_kbd_mod5_mod = xkb_keymap_mod_get_index(keymap, "Mod5");
381}
382
383static uint32_t
384get_xkb_mod_mask(uint32_t in)
385{
386 uint32_t ret = 0;
387
388 if ((in & ECORE_X_MODIFIER_SHIFT) && x11_kbd_shift_mod != XKB_MOD_INVALID)
389 ret |= (1 << x11_kbd_shift_mod);
390 if ((in & ECORE_X_LOCK_CAPS) && x11_kbd_caps_mod != XKB_MOD_INVALID)
391 ret |= (1 << x11_kbd_caps_mod);
392 if ((in & ECORE_X_MODIFIER_CTRL) && x11_kbd_ctrl_mod != XKB_MOD_INVALID)
393 ret |= (1 << x11_kbd_ctrl_mod);
394 if ((in & ECORE_X_MODIFIER_ALT) && x11_kbd_alt_mod != XKB_MOD_INVALID)
395 ret |= (1 << x11_kbd_alt_mod);
396 if ((in & ECORE_X_LOCK_NUM) && x11_kbd_mod2_mod != XKB_MOD_INVALID)
397 ret |= (1 << x11_kbd_mod2_mod);
398 if ((in & ECORE_X_LOCK_SCROLL) && x11_kbd_mod3_mod != XKB_MOD_INVALID)
399 ret |= (1 << x11_kbd_mod3_mod);
400 if ((in & ECORE_X_MODIFIER_WIN) && x11_kbd_super_mod != XKB_MOD_INVALID)
401 ret |= (1 << x11_kbd_super_mod);
402 if ((in & ECORE_X_MODIFIER_ALTGR) && x11_kbd_mod5_mod != XKB_MOD_INVALID)
403 ret |= (1 << x11_kbd_mod5_mod);
404
405 return ret;
406}
407
408#endif
diff --git a/src/lib/efl_wl/efl_wl.c b/src/lib/efl_wl/efl_wl.c
index d6622ef8dd..fd02aed44a 100644
--- a/src/lib/efl_wl/efl_wl.c
+++ b/src/lib/efl_wl/efl_wl.c
@@ -3710,26 +3710,32 @@ seat_keymap_update(Comp_Seat *s)
3710 Eina_Tmpstr *file; 3710 Eina_Tmpstr *file;
3711 xkb_mod_mask_t latched = 0, locked = 0; 3711 xkb_mod_mask_t latched = 0, locked = 0;
3712 3712
3713 if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size); 3713#ifdef HAVE_ECORE_X
3714 if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd); 3714 if (!x11_kbd_keymap)
3715
3716 if (s->kbd.state)
3717 {
3718 latched = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_MODS_LATCHED);
3719 locked = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_MODS_LOCKED);
3720 xkb_state_unref(s->kbd.state);
3721 }
3722 if (!s->kbd.keymap)
3723 { 3715 {
3724 s->kbd.state = NULL; 3716#endif
3725 s->kbd.keymap_fd = -1; 3717 if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size);
3726 s->kbd.keymap_mem = NULL; 3718 if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd);
3727 return;
3728 }
3729 3719
3730 s->kbd.state = xkb_state_new(s->kbd.keymap); 3720 if (s->kbd.state)
3731 xkb_state_update_mask(s->kbd.state, 0, latched, locked, 0, 0, 0); 3721 {
3722 latched = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_MODS_LATCHED);
3723 locked = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_MODS_LOCKED);
3724 xkb_state_unref(s->kbd.state);
3725 }
3726 if (!s->kbd.keymap)
3727 {
3728 s->kbd.state = NULL;
3729 s->kbd.keymap_fd = -1;
3730 s->kbd.keymap_mem = NULL;
3731 return;
3732 }
3732 3733
3734 s->kbd.state = xkb_state_new(s->kbd.keymap);
3735 xkb_state_update_mask(s->kbd.state, 0, latched, locked, 0, 0, 0);
3736#ifdef HAVE_ECORE_X
3737 }
3738#endif
3733 str = xkb_map_get_as_string(s->kbd.keymap); 3739 str = xkb_map_get_as_string(s->kbd.keymap);
3734 s->kbd.keymap_mem_size = strlen(str) + 1; 3740 s->kbd.keymap_mem_size = strlen(str) + 1;
3735 s->kbd.keymap_fd = eina_file_mkstemp("comp-keymapXXXXXX", &file); 3741 s->kbd.keymap_fd = eina_file_mkstemp("comp-keymapXXXXXX", &file);
@@ -4395,6 +4401,11 @@ comp_device_caps_update(Comp_Seat *s)
4395 { 4401 {
4396 if (s->keyboard) 4402 if (s->keyboard)
4397 { 4403 {
4404#ifdef HAVE_ECORE_X
4405 if ((!s->c->parent_disp) && ecore_x_display_get())
4406 x11_kbd_apply(s);
4407 else
4408#endif
4398 seat_keymap_create(s); 4409 seat_keymap_create(s);
4399 seat_kbd_repeat_rate_update(s); 4410 seat_kbd_repeat_rate_update(s);
4400 } 4411 }
@@ -4462,9 +4473,16 @@ comp_seats_proxy(Comp *c)
4462 if (s->kbd.keymap) xkb_keymap_ref(s->kbd.keymap); 4473 if (s->kbd.keymap) xkb_keymap_ref(s->kbd.keymap);
4463 } 4474 }
4464 else 4475 else
4465 seat_keymap_create(s); 4476 {
4466 seat_kbd_repeat_rate_update(s); 4477#ifdef HAVE_ECORE_X
4478 if ((!s->c->parent_disp) && ecore_x_display_get())
4479 x11_kbd_apply(s);
4480 else
4481#endif
4482 seat_keymap_create(s);
4483 }
4467 seat_keymap_update(s); 4484 seat_keymap_update(s);
4485 seat_kbd_repeat_rate_update(s);
4468 s->keyboard = !!s->kbd.state; 4486 s->keyboard = !!s->kbd.state;
4469 } 4487 }
4470 } 4488 }
@@ -5339,6 +5357,7 @@ comp_smart_add(Evas_Object *obj)
5339#ifdef HAVE_ECORE_X 5357#ifdef HAVE_ECORE_X
5340 if (ecore_x_display_get()) 5358 if (ecore_x_display_get())
5341 { 5359 {
5360 ecore_x_xkb_track_state();
5342 // if proxiedallowed 5361 // if proxiedallowed
5343 ecore_x_dnd_aware_set(ecore_evas_window_get(ecore_evas_ecore_evas_get(c->evas)), EINA_TRUE); 5362 ecore_x_dnd_aware_set(ecore_evas_window_get(ecore_evas_ecore_evas_get(c->evas)), EINA_TRUE);
5344 if (!comps) x11_init(); 5363 if (!comps) x11_init();
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}