summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2018-01-25 14:00:50 -0500
committerMike Blumenkrantz <zmike@osg.samsung.com>2018-01-25 14:00:50 -0500
commit564e693c032afcfa9a5f7c624dc97d9fec24bb43 (patch)
tree1366314c7c89022a1f6144554c779b61583c0bab
parentbd41e4626fdcab15e5f0bb9ecd13b9249537fa67 (diff)
-rw-r--r--src/lib/efl_wl/efl_wl.c170
-rw-r--r--src/lib/efl_wl/x11.x28
2 files changed, 114 insertions, 84 deletions
diff --git a/src/lib/efl_wl/efl_wl.c b/src/lib/efl_wl/efl_wl.c
index 4c16eb6c33..6513ba7304 100644
--- a/src/lib/efl_wl/efl_wl.c
+++ b/src/lib/efl_wl/efl_wl.c
@@ -95,6 +95,18 @@ typedef struct Input_Sequence
95 Eina_Bool pass : 1; 95 Eina_Bool pass : 1;
96} Input_Sequence; 96} Input_Sequence;
97 97
98typedef struct Keyboard_Info
99{
100 unsigned int refs;
101 struct xkb_context *context;
102 struct xkb_keymap *keymap;
103 char *keymap_mem;
104 int keymap_mem_size;
105 int keymap_fd;
106 int repeat_rate;
107 int repeat_delay;
108} Keyboard_Info;
109
98typedef struct Comp_Subsurface Comp_Subsurface; 110typedef struct Comp_Subsurface Comp_Subsurface;
99typedef struct Comp_Surface Comp_Surface; 111typedef struct Comp_Surface Comp_Surface;
100 112
@@ -202,14 +214,8 @@ typedef struct Comp_Seat
202 xkb_layout_index_t group; 214 xkb_layout_index_t group;
203 Eina_Bool changed : 1; 215 Eina_Bool changed : 1;
204 } mods; 216 } mods;
205 struct xkb_context *context; 217 Keyboard_Info *info;
206 struct xkb_keymap *keymap;
207 struct xkb_state *state; 218 struct xkb_state *state;
208 char *keymap_mem;
209 int keymap_mem_size;
210 int keymap_fd;
211 int repeat_rate;
212 int repeat_delay;
213 Eina_Hash *resources; 219 Eina_Hash *resources;
214 Comp_Surface *enter; 220 Comp_Surface *enter;
215 Eina_Bool external : 1; 221 Eina_Bool external : 1;
@@ -400,6 +406,7 @@ typedef struct Comp_Data_Device_Transfer
400 406
401static Eina_List *comps; 407static Eina_List *comps;
402static Eina_List *handlers; 408static Eina_List *handlers;
409static Eina_Hash *kbd_infos;
403 410
404static inline Eina_Tiler * 411static inline Eina_Tiler *
405tiler_new(void) 412tiler_new(void)
@@ -446,6 +453,61 @@ array_clear(Eina_Array **arr)
446 *arr = NULL; 453 *arr = NULL;
447} 454}
448 455
456static void
457keyboard_info_free(Keyboard_Info *info)
458{
459 if (info->refs) return;
460 if (info->state) xkb_state_unref(info->state);
461 if (info->keymap) xkb_keymap_unref(info->keymap);
462 if (info->context) xkb_context_unref(info->context);
463 if (info->keymap_mem) munmap(info->keymap_mem, info->keymap_mem_size);
464 if (info->keymap_fd > -1) close(info->keymap_fd);
465 free(info);
466}
467
468static Keyboard_Info *
469keyboard_info_create(struct xkb_keymap *keymap)
470{
471 Eina_Tmpstr *file;
472 char *str;
473 Keyboard_Info *info;
474
475 info = eina_hash_find(kbd_infos, &keymap);
476 if (info)
477 {
478 info->refs++;
479 return info;
480 }
481 info = calloc(1, sizeof(Keyboard_Info));
482 info->refs = 1;
483 str = xkb_map_get_as_string(keymap);
484 info->keymap_mem_size = strlen(str) + 1;
485 info->keymap_fd = eina_file_mkstemp("comp-keymapXXXXXX", &file);
486 if (info->keymap_fd < 0)
487 {
488 EINA_LOG_ERR("mkstemp failed!\n");
489 free(info);
490 return NULL;
491 }
492 if (!eina_file_close_on_exec(info->keymap_fd, 1))
493 {
494 EINA_LOG_ERR("Failed to set CLOEXEC on fd %d\n", info->keymap_fd);
495 close(info->keymap_fd);
496 free(info);
497 return NULL;
498 }
499 ftruncate(info->keymap_fd, info->keymap_mem_size);
500 eina_file_unlink(file);
501 eina_tmpstr_del(file);
502 info->keymap_mem = mmap(NULL, info->keymap_mem_size + 1,
503 PROT_READ | PROT_WRITE, MAP_SHARED, info->keymap_fd, 0);
504
505 memcpy(info->keymap_mem, str, info->keymap_mem_size);
506 info->keymap_mem[info->keymap_mem_size] = 0;
507 free(str);
508 return info;
509}
510
449static inline Eina_Bool 511static inline Eina_Bool
450client_allowed_check(Comp *c, struct wl_client *client) 512client_allowed_check(Comp *c, struct wl_client *client)
451{ 513{
@@ -3704,68 +3766,44 @@ seat_kbd_external_init(Comp_Seat *s)
3704} 3766}
3705 3767
3706static void 3768static void
3707seat_keymap_update(Comp_Seat *s) 3769seat_keymap_update(Comp_Seat *s, struct xkb_keymap *keymap)
3708{ 3770{
3709 char *str;
3710 Eina_Tmpstr *file;
3711 xkb_mod_mask_t latched = 0, locked = 0;
3712
3713 if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size);
3714 if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd);
3715
3716#ifdef HAVE_ECORE_X 3771#ifdef HAVE_ECORE_X
3717 if (!x11_kbd_keymap) 3772 if (!x11_kbd_state)
3718 { 3773 {
3719#endif 3774#endif
3775 xkb_mod_mask_t latched = 0, locked = 0;
3776 if (s->kbd.info)
3777 {
3778 s->kbd.info->refs--;
3779 if (!s->kbd.info->refs)
3780 eina_hash_del_by_key(kbd_infos, &s->kbd.info->keymap);
3781 s->kbd.info = NULL;
3782 }
3720 if (s->kbd.state) 3783 if (s->kbd.state)
3721 { 3784 {
3722 latched = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_MODS_LATCHED); 3785 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); 3786 locked = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_MODS_LOCKED);
3724 xkb_state_unref(s->kbd.state); 3787 xkb_state_unref(s->kbd.state);
3725 } 3788 }
3726 if (!s->kbd.keymap) 3789 if (!s->kbd.info) return;
3727 { 3790 s->kbd.state = xkb_state_new(keymap);
3728 s->kbd.state = NULL;
3729 s->kbd.keymap_fd = -1;
3730 s->kbd.keymap_mem = NULL;
3731 return;
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); 3791 xkb_state_update_mask(s->kbd.state, 0, latched, locked, 0, 0, 0);
3736#ifdef HAVE_ECORE_X 3792#ifdef HAVE_ECORE_X
3737 } 3793 }
3738#endif 3794#endif
3739 str = xkb_map_get_as_string(s->kbd.keymap); 3795 s->kbd.info = keyboard_info_create(keymap);
3740 s->kbd.keymap_mem_size = strlen(str) + 1; 3796 if (!s->kbd.info)
3741 s->kbd.keymap_fd = eina_file_mkstemp("comp-keymapXXXXXX", &file);
3742 if (s->kbd.keymap_fd < 0)
3743 {
3744 EINA_LOG_ERR("mkstemp failed!\n");
3745 s->kbd.keymap_fd = -1;
3746 xkb_state_unref(s->kbd.state);
3747 s->kbd.state = NULL;
3748 return;
3749 }
3750 if (!eina_file_close_on_exec(s->kbd.keymap_fd, 1))
3751 { 3797 {
3752 EINA_LOG_ERR("Failed to set CLOEXEC on fd %d\n", s->kbd.keymap_fd); 3798#ifdef HAVE_ECORE_X
3753 close(s->kbd.keymap_fd); 3799 if (!x11_kbd_state)
3754 s->kbd.keymap_fd = -1; 3800 {
3755 xkb_state_unref(s->kbd.state); 3801 xkb_state_unref(s->kbd.state);
3756 s->kbd.state = NULL; 3802 s->kbd.state = NULL;
3757 return; 3803 return;
3804 }
3805#endif
3758 } 3806 }
3759 ftruncate(s->kbd.keymap_fd, s->kbd.keymap_mem_size);
3760 eina_file_unlink(file);
3761 eina_tmpstr_del(file);
3762 s->kbd.keymap_mem =
3763 mmap(NULL, s->kbd.keymap_mem_size + 1,
3764 PROT_READ | PROT_WRITE, MAP_SHARED, s->kbd.keymap_fd, 0);
3765
3766 memcpy(s->kbd.keymap_mem, str, s->kbd.keymap_mem_size);
3767 s->kbd.keymap_mem[s->kbd.keymap_mem_size] = 0;
3768 free(str);
3769 3807
3770 seat_keymap_send(s); 3808 seat_keymap_send(s);
3771} 3809}
@@ -4048,20 +4086,12 @@ seat_resource_hash_free(Eina_Hash *h)
4048static void 4086static void
4049seat_kbd_destroy(Comp_Seat *s) 4087seat_kbd_destroy(Comp_Seat *s)
4050{ 4088{
4051 if (s->kbd.external) return; 4089 s->kbd.info->refs--;
4052#ifdef HAVE_ECORE_X 4090 if (!s->kbd.info->refs)
4053 if (!x11_kbd_keymap) 4091 eina_hash_del_by_key(kbd_infos, &s->kbd.info->keymap);
4054 { 4092 s->kbd.info = NULL;
4055#endif 4093 if (!s->kbd.external)
4056 if (s->kbd.state) xkb_state_unref(s->kbd.state); 4094 wl_array_release(&s->kbd.keys);
4057 if (s->kbd.keymap) xkb_keymap_unref(s->kbd.keymap);
4058 if (s->kbd.context) xkb_context_unref(s->kbd.context);
4059#ifdef HAVE_ECORE_X
4060 }
4061#endif
4062 if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size);
4063 if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd);
4064 wl_array_release(&s->kbd.keys);
4065} 4095}
4066 4096
4067static void 4097static void
@@ -5381,7 +5411,11 @@ comp_smart_add(Evas_Object *obj)
5381 evas_object_event_callback_add(c->obj, EVAS_CALLBACK_FOCUS_IN, comp_focus_in, c); 5411 evas_object_event_callback_add(c->obj, EVAS_CALLBACK_FOCUS_IN, comp_focus_in, c);
5382 evas_object_event_callback_add(c->obj, EVAS_CALLBACK_FOCUS_OUT, comp_focus_out, c); 5412 evas_object_event_callback_add(c->obj, EVAS_CALLBACK_FOCUS_OUT, comp_focus_out, c);
5383 5413
5384 if (!comps) comp_handlers_init(); 5414 if (!comps)
5415 {
5416 comp_handlers_init();
5417 kbd_infos = eina_hash_pointer_new((Eina_Free_Cb)keyboard_info_free);
5418 }
5385 comps = eina_list_append(comps, c); 5419 comps = eina_list_append(comps, c);
5386 free(env); 5420 free(env);
5387} 5421}
diff --git a/src/lib/efl_wl/x11.x b/src/lib/efl_wl/x11.x
index 2d7a88352f..f558d1a0fe 100644
--- a/src/lib/efl_wl/x11.x
+++ b/src/lib/efl_wl/x11.x
@@ -565,8 +565,7 @@ x11_dnd_move(void *data, Ecore_X_Xdnd_Position *pos)
565} 565}
566 566
567static int32_t x11_core_device = -1; 567static int32_t x11_core_device = -1;
568static struct xkb_context *x11_kbd_context; 568static Keyboard_Info *x11_kbd_info;
569static struct xkb_keymap *x11_kbd_keymap;
570static struct xkb_state *x11_kbd_state; 569static struct xkb_state *x11_kbd_state;
571 570
572static Eina_Bool seat_kbd_mods_update(Comp_Seat *s); 571static Eina_Bool seat_kbd_mods_update(Comp_Seat *s);
@@ -606,12 +605,8 @@ x11_xkb_state(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Xkb *ev)
606static void 605static void
607x11_kbd_destroy(void) 606x11_kbd_destroy(void)
608{ 607{
609 if (x11_kbd_state) xkb_state_unref(x11_kbd_state); 608 x11_kbd_info->refs = 0;
610 x11_kbd_state = NULL; 609 eina_hash_del_by_key(kbd_infos, &x11_kbd_info->keymap);
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} 610}
616 611
617static void 612static void
@@ -621,23 +616,24 @@ x11_kbd_create(void)
621 616
622 x11_kbd_destroy(); 617 x11_kbd_destroy();
623 618
624 x11_kbd_context = xkb_context_new(0);
625 x11_core_device = xkb_x11_get_core_keyboard_device_id(conn); 619 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); 620 x11_kbd_info.context = xkb_context_new(0);
627 x11_kbd_state = xkb_x11_state_new_from_device(x11_kbd_keymap, conn, x11_core_device); 621 x11_kbd_info.keymap = xkb_x11_keymap_new_from_device(x11_kbd_info.context, conn, x11_core_device, 0);
628 keymap_mods_init(x11_kbd_keymap); 622 x11_kbd_state = xkb_x11_state_new_from_device(x11_kbd_info.keymap, conn, x11_core_device);
623 keymap_mods_init(x11_kbd_info.keymap);
624 eina_hash_add(kbd_infos, &x11_kbd_info.keymap, &x11_kbd_info);
629} 625}
630 626
631static void 627static void
632x11_kbd_apply(Comp_Seat *s) 628x11_kbd_apply(Comp_Seat *s)
633{ 629{
634 if (!x11_kbd_state) x11_kbd_create(); 630 if (!x11_kbd_state) x11_kbd_create();
635 s->kbd.context = x11_kbd_context; 631 x11_kbd_info.refs++;
636 s->kbd.keymap = x11_kbd_keymap; 632 s->kbd.info = &x11_kbd_info;
637 s->kbd.state = x11_kbd_state; 633 s->kbd.state = x11_kbd_state);
638} 634}
639 635
640static void seat_keymap_update(Comp_Seat *s); 636static void seat_keymap_update(Comp_Seat *s, struct xkb_keymap *keymap);
641 637
642static Eina_Bool 638static Eina_Bool
643x11_xkb_refresh() 639x11_xkb_refresh()