summaryrefslogtreecommitdiff
path: root/src/lib/efl_wl
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2018-01-23 16:49:52 -0500
committerMike Blumenkrantz <zmike@osg.samsung.com>2018-01-24 16:18:51 -0500
commit10fc36614f1613f60d861815ce43a383d0f3826e (patch)
tree572f15daad565dbb0ca57d0c6e304b9e5a6bbae8 /src/lib/efl_wl
parent2f4a89cb0ec10537c0dd12f25af0c878b2e0b390 (diff)
efl-wl: add functionality for directly passing through xkb objects
when used in enlightenment, it's necessary to be able to directly use the compositor's keyboard state to ensure consistency when keypress events are not propagated @feature
Diffstat (limited to 'src/lib/efl_wl')
-rw-r--r--src/lib/efl_wl/Efl_Wl.h27
-rw-r--r--src/lib/efl_wl/efl_wl.c345
2 files changed, 272 insertions, 100 deletions
diff --git a/src/lib/efl_wl/Efl_Wl.h b/src/lib/efl_wl/Efl_Wl.h
index eb9e57938e..d27dedde28 100644
--- a/src/lib/efl_wl/Efl_Wl.h
+++ b/src/lib/efl_wl/Efl_Wl.h
@@ -160,6 +160,33 @@ EAPI Evas_Object *efl_wl_extracted_surface_object_find(void *surface_resource);
160 * @since 1.21 160 * @since 1.21
161 */ 161 */
162EAPI Evas_Object *efl_wl_extracted_surface_extracted_parent_get(Evas_Object *surface); 162EAPI Evas_Object *efl_wl_extracted_surface_extracted_parent_get(Evas_Object *surface);
163
164/**
165 * Set external xkbcommon resources to be used read-only by the compositor object
166 *
167 * Use this function if you have available the necessary xkbcommon objects which are used
168 * to handle keyboard states in a compositor. The passed objects will not be modified or copied,
169 * so this function must be called again in the case that the compositor widget outlives the
170 * lifetime of any of the passed pointers.
171 *
172 * @param obj The compositor widget
173 * @param seat The seat to set the keymap for, NULL to set the keymap for all seats
174 * @param keymap The xkb_keymap object to use
175 * @param state The xkb_state object to use
176 * @param fd The fd created from a mmapped xkb_keymap
177 * @param size The size of the xkb_keymap memory
178 * @param wl_key_array A pointer to the wl_array in which keys are stored
179 * @since 1.21
180 */
181EAPI void efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, int fd, size_t size, void *wl_key_array);
182
183/**
184 * Set the key repeat rate for a seat in the compositor
185 *
186 * @param obj The compositor widget
187 * @since 1.21
188 */
189EAPI void efl_wl_seat_key_repeat_set(Evas_Object *obj, Eo *seat, int repeat_rate, int repeat_delay);
163#endif 190#endif
164 191
165#endif 192#endif
diff --git a/src/lib/efl_wl/efl_wl.c b/src/lib/efl_wl/efl_wl.c
index 12b2fa81f6..6967efc635 100644
--- a/src/lib/efl_wl/efl_wl.c
+++ b/src/lib/efl_wl/efl_wl.c
@@ -193,6 +193,7 @@ typedef struct Comp_Seat
193 struct 193 struct
194 { 194 {
195 struct wl_array keys; 195 struct wl_array keys;
196 struct wl_array *keys_external;
196 struct 197 struct
197 { 198 {
198 xkb_mod_mask_t depressed; 199 xkb_mod_mask_t depressed;
@@ -211,6 +212,7 @@ typedef struct Comp_Seat
211 int repeat_delay; 212 int repeat_delay;
212 Eina_Hash *resources; 213 Eina_Hash *resources;
213 Comp_Surface *enter; 214 Comp_Surface *enter;
215 Eina_Bool external : 1;
214 } kbd; 216 } kbd;
215 217
216 struct 218 struct
@@ -3651,12 +3653,63 @@ seat_update_caps(Comp_Seat *s, struct wl_resource *res)
3651} 3653}
3652 3654
3653static void 3655static void
3656seat_keymap_send(Comp_Seat *s)
3657{
3658 Eina_List *l;
3659 Eina_Iterator *it;
3660 it = eina_hash_iterator_data_new(s->kbd.resources);
3661 EINA_ITERATOR_FOREACH(it, l)
3662 {
3663 Eina_List *ll;
3664 struct wl_resource *res;
3665 EINA_LIST_FOREACH(l, ll, res)
3666 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, s->kbd.keymap_fd, s->kbd.keymap_mem_size);
3667 }
3668 eina_iterator_free(it);
3669}
3670
3671static Eina_Bool
3672seat_kbd_mods_update(Comp_Seat *s)
3673{
3674 xkb_mod_mask_t mod;
3675 xkb_layout_index_t grp;
3676
3677 mod = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_DEPRESSED);
3678 s->kbd.mods.changed |= mod != s->kbd.mods.depressed;
3679 s->kbd.mods.depressed = mod;
3680 mod = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_MODS_LATCHED);
3681 s->kbd.mods.changed |= mod != s->kbd.mods.latched;
3682 s->kbd.mods.latched = mod;
3683 mod = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_MODS_LOCKED);
3684 s->kbd.mods.changed |= mod != s->kbd.mods.locked;
3685 s->kbd.mods.locked = mod;
3686 grp = xkb_state_serialize_layout(s->kbd.state, XKB_STATE_LAYOUT_EFFECTIVE);
3687 s->kbd.mods.changed |= grp != s->kbd.mods.group;
3688 s->kbd.mods.group = grp;
3689 return s->kbd.mods.changed;
3690}
3691
3692static void
3693seat_kbd_external_init(Comp_Seat *s)
3694{
3695 Eina_List *l, *ll;
3696 uint32_t serial;
3697 struct wl_resource *res;
3698
3699 seat_keymap_send(s);
3700 if (!seat_kbd_mods_update(s)) return;
3701 l = seat_kbd_active_resources_get(s);
3702 if (!l) return;
3703 serial = wl_display_next_serial(s->c->display);
3704 EINA_LIST_FOREACH(l, ll, res)
3705 comp_seat_send_modifiers(s, res, serial);
3706}
3707
3708static void
3654seat_keymap_update(Comp_Seat *s) 3709seat_keymap_update(Comp_Seat *s)
3655{ 3710{
3656 char *str; 3711 char *str;
3657 Eina_Tmpstr *file; 3712 Eina_Tmpstr *file;
3658 Eina_List *l;
3659 Eina_Iterator *it;
3660 xkb_mod_mask_t latched = 0, locked = 0; 3713 xkb_mod_mask_t latched = 0, locked = 0;
3661 3714
3662 if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size); 3715 if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size);
@@ -3710,15 +3763,7 @@ seat_keymap_update(Comp_Seat *s)
3710 s->kbd.keymap_mem[s->kbd.keymap_mem_size] = 0; 3763 s->kbd.keymap_mem[s->kbd.keymap_mem_size] = 0;
3711 free(str); 3764 free(str);
3712 3765
3713 it = eina_hash_iterator_data_new(s->kbd.resources); 3766 seat_keymap_send(s);
3714 EINA_ITERATOR_FOREACH(it, l)
3715 {
3716 Eina_List *ll;
3717 struct wl_resource *res;
3718 EINA_LIST_FOREACH(l, ll, res)
3719 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, s->kbd.keymap_fd, s->kbd.keymap_mem_size);
3720 }
3721 eina_iterator_free(it);
3722} 3767}
3723 3768
3724static inline void 3769static inline void
@@ -3756,27 +3801,6 @@ seat_keymap_create(Comp_Seat *s)
3756 s->kbd.keymap = xkb_map_new_from_names(s->kbd.context, &names, 0); 3801 s->kbd.keymap = xkb_map_new_from_names(s->kbd.context, &names, 0);
3757} 3802}
3758 3803
3759static Eina_Bool
3760seat_mods_update(Comp_Seat *s)
3761{
3762 xkb_mod_mask_t mod;
3763 xkb_layout_index_t grp;
3764
3765 mod = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_DEPRESSED);
3766 s->kbd.mods.changed |= mod != s->kbd.mods.depressed;
3767 s->kbd.mods.depressed = mod;
3768 mod = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_MODS_LATCHED);
3769 s->kbd.mods.changed |= mod != s->kbd.mods.latched;
3770 s->kbd.mods.latched = mod;
3771 mod = xkb_state_serialize_mods(s->kbd.state, XKB_STATE_MODS_LOCKED);
3772 s->kbd.mods.changed |= mod != s->kbd.mods.locked;
3773 s->kbd.mods.locked = mod;
3774 grp = xkb_state_serialize_layout(s->kbd.state, XKB_STATE_LAYOUT_EFFECTIVE);
3775 s->kbd.mods.changed |= grp != s->kbd.mods.group;
3776 s->kbd.mods.group = grp;
3777 return s->kbd.mods.changed;
3778}
3779
3780static const struct wl_keyboard_interface seat_kbd_interface = 3804static const struct wl_keyboard_interface seat_kbd_interface =
3781{ 3805{
3782 resource_destroy 3806 resource_destroy
@@ -4018,6 +4042,18 @@ seat_resource_hash_free(Eina_Hash *h)
4018} 4042}
4019 4043
4020static void 4044static void
4045seat_kbd_destroy(Comp_Seat *s)
4046{
4047 if (s->kbd.external) return;
4048 if (s->kbd.state) xkb_state_unref(s->kbd.state);
4049 if (s->kbd.keymap) xkb_keymap_unref(s->kbd.keymap);
4050 if (s->kbd.context) xkb_context_unref(s->kbd.context);
4051 if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size);
4052 if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd);
4053 wl_array_release(&s->kbd.keys);
4054}
4055
4056static void
4021seat_destroy(Comp_Seat *s) 4057seat_destroy(Comp_Seat *s)
4022{ 4058{
4023 Eina_Stringshare *type; 4059 Eina_Stringshare *type;
@@ -4027,12 +4063,7 @@ seat_destroy(Comp_Seat *s)
4027 while (s->resources) 4063 while (s->resources)
4028 wl_resource_destroy(eina_list_data_get(s->resources)); 4064 wl_resource_destroy(eina_list_data_get(s->resources));
4029 eina_stringshare_del(s->name); 4065 eina_stringshare_del(s->name);
4030 if (s->kbd.state) xkb_state_unref(s->kbd.state); 4066 seat_kbd_destroy(s);
4031 if (s->kbd.keymap) xkb_keymap_unref(s->kbd.keymap);
4032 if (s->kbd.context) xkb_context_unref(s->kbd.context);
4033 if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size);
4034 if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd);
4035 wl_array_release(&s->kbd.keys);
4036 efl_unref(s->dev); 4067 efl_unref(s->dev);
4037 s->c->seats = eina_inlist_remove(s->c->seats, EINA_INLIST_GET(s)); 4068 s->c->seats = eina_inlist_remove(s->c->seats, EINA_INLIST_GET(s));
4038 eina_hash_free(s->data_devices); 4069 eina_hash_free(s->data_devices);
@@ -4345,18 +4376,23 @@ comp_device_caps_update(Comp_Seat *s)
4345 } 4376 }
4346 if (s->keyboard != kbd) 4377 if (s->keyboard != kbd)
4347 { 4378 {
4348 if (s->keyboard) 4379 if (s->kbd.external)
4349 { 4380 seat_kbd_external_init(s);
4350 seat_keymap_create(s);
4351 seat_kbd_repeat_rate_update(s);
4352 }
4353 else 4381 else
4354 { 4382 {
4355 xkb_keymap_unref(s->kbd.keymap); 4383 if (s->keyboard)
4356 s->kbd.keymap = NULL; 4384 {
4385 seat_keymap_create(s);
4386 seat_kbd_repeat_rate_update(s);
4387 }
4388 else
4389 {
4390 xkb_keymap_unref(s->kbd.keymap);
4391 s->kbd.keymap = NULL;
4392 }
4393 seat_keymap_update(s);
4394 s->keyboard = !!s->kbd.state;
4357 } 4395 }
4358 seat_keymap_update(s);
4359 s->keyboard = !!s->kbd.state;
4360 } 4396 }
4361 seat_update_caps(s, NULL); 4397 seat_update_caps(s, NULL);
4362} 4398}
@@ -4403,22 +4439,28 @@ comp_seats_proxy(Comp *c)
4403 s->touch = !!(caps & ECORE_WL2_SEAT_CAPABILITIES_TOUCH); 4439 s->touch = !!(caps & ECORE_WL2_SEAT_CAPABILITIES_TOUCH);
4404 if (s->keyboard) 4440 if (s->keyboard)
4405 { 4441 {
4406 if (s->seat) 4442 if (s->kbd.external)
4443 seat_kbd_external_init(s);
4444 else
4407 { 4445 {
4408 s->kbd.keymap = ecore_wl2_input_keymap_get(s->seat); 4446 if (s->seat)
4409 if (s->kbd.keymap) xkb_keymap_ref(s->kbd.keymap); 4447 {
4448 s->kbd.keymap = ecore_wl2_input_keymap_get(s->seat);
4449 if (s->kbd.keymap) xkb_keymap_ref(s->kbd.keymap);
4450 }
4451 else
4452 seat_keymap_create(s);
4453 seat_kbd_repeat_rate_update(s);
4454 seat_keymap_update(s);
4455 s->keyboard = !!s->kbd.state;
4410 } 4456 }
4411 else
4412 seat_keymap_create(s);
4413 seat_kbd_repeat_rate_update(s);
4414 seat_keymap_update(s);
4415 s->keyboard = !!s->kbd.state;
4416 } 4457 }
4417 4458
4418 } 4459 }
4419 else if (!c->parent_disp) 4460 else if (!c->parent_disp)
4420 comp_device_caps_update(s); 4461 comp_device_caps_update(s);
4421 s->global = wl_global_create(c->display, &wl_seat_interface, 4, s, seat_bind); 4462 s->global = wl_global_create(c->display, &wl_seat_interface, 4, s, seat_bind);
4463 evas_object_smart_callback_call(s->c->obj, "seat_added", dev);
4422 if (ecore_wl2_display_sync_is_done(c->client_disp)) 4464 if (ecore_wl2_display_sync_is_done(c->client_disp))
4423 seat_proxy_update(s); 4465 seat_proxy_update(s);
4424 } 4466 }
@@ -4508,18 +4550,23 @@ comp_seat_caps_handler(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Wl2_Event_S
4508 s->pointer = ev->pointer_enabled; 4550 s->pointer = ev->pointer_enabled;
4509 if (s->keyboard != ev->keyboard_enabled) 4551 if (s->keyboard != ev->keyboard_enabled)
4510 { 4552 {
4511 if (ev->keyboard_enabled) 4553 if (s->kbd.external)
4512 { 4554 seat_kbd_external_init(s);
4513 s->kbd.keymap = ecore_wl2_input_keymap_get(s->seat);
4514 if (s->kbd.keymap) xkb_keymap_ref(s->kbd.keymap);
4515 seat_kbd_repeat_rate_update(s);
4516 }
4517 else 4555 else
4518 { 4556 {
4519 xkb_keymap_unref(s->kbd.keymap); 4557 if (ev->keyboard_enabled)
4520 s->kbd.keymap = NULL; 4558 {
4559 s->kbd.keymap = ecore_wl2_input_keymap_get(s->seat);
4560 if (s->kbd.keymap) xkb_keymap_ref(s->kbd.keymap);
4561 seat_kbd_repeat_rate_update(s);
4562 }
4563 else
4564 {
4565 xkb_keymap_unref(s->kbd.keymap);
4566 s->kbd.keymap = NULL;
4567 }
4568 seat_keymap_update(s);
4521 } 4569 }
4522 seat_keymap_update(s);
4523 } 4570 }
4524 s->keyboard = !!ev->keyboard_enabled && !!s->kbd.state; 4571 s->keyboard = !!ev->keyboard_enabled && !!s->kbd.state;
4525 s->touch = ev->touch_enabled; 4572 s->touch = ev->touch_enabled;
@@ -4569,6 +4616,7 @@ comp_seat_keymap_changed(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Wl2_Event
4569 { 4616 {
4570 struct xkb_keymap *keymap; 4617 struct xkb_keymap *keymap;
4571 4618
4619 if (s->kbd.external) continue;
4572 if (ecore_wl2_input_seat_id_get(s->seat) != ev->id) continue; 4620 if (ecore_wl2_input_seat_id_get(s->seat) != ev->id) continue;
4573 4621
4574 if (s->kbd.keymap) xkb_map_unref(s->kbd.keymap); 4622 if (s->kbd.keymap) xkb_map_unref(s->kbd.keymap);
@@ -4585,6 +4633,21 @@ comp_seat_keymap_changed(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Wl2_Event
4585 return ECORE_CALLBACK_RENEW; 4633 return ECORE_CALLBACK_RENEW;
4586} 4634}
4587 4635
4636static void
4637seat_kbd_repeat_rate_send(Comp_Seat *s)
4638{
4639 Eina_List *ll, *lll;
4640 struct wl_resource *res;
4641 Eina_Iterator *it;
4642
4643 it = eina_hash_iterator_data_new(s->kbd.resources);
4644 EINA_ITERATOR_FOREACH(it, ll)
4645 EINA_LIST_FOREACH(ll, lll, res)
4646 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
4647 wl_keyboard_send_repeat_info(res, s->kbd.repeat_rate, s->kbd.repeat_delay);
4648 eina_iterator_free(it);
4649}
4650
4588static Eina_Bool 4651static Eina_Bool
4589comp_seat_keyboard_repeat_changed(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Wl2_Event_Seat_Keyboard_Repeat_Changed *ev) 4652comp_seat_keyboard_repeat_changed(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Wl2_Event_Seat_Keyboard_Repeat_Changed *ev)
4590{ 4653{
@@ -4596,36 +4659,23 @@ comp_seat_keyboard_repeat_changed(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_
4596 if (c->parent_disp == ev->display) 4659 if (c->parent_disp == ev->display)
4597 EINA_INLIST_FOREACH(c->seats, s) 4660 EINA_INLIST_FOREACH(c->seats, s)
4598 { 4661 {
4599 Eina_List *ll, *lll;
4600 struct wl_resource *res;
4601 Eina_Iterator *it;
4602
4603 if (ecore_wl2_input_seat_id_get(s->seat) != ev->id) continue; 4662 if (ecore_wl2_input_seat_id_get(s->seat) != ev->id) continue;
4663 if (s->kbd.external) continue;
4604 4664
4605 seat_kbd_repeat_rate_update(s); 4665 seat_kbd_repeat_rate_update(s);
4606 it = eina_hash_iterator_data_new(s->kbd.resources); 4666 seat_kbd_repeat_rate_send(s);
4607 EINA_ITERATOR_FOREACH(it, ll)
4608 EINA_LIST_FOREACH(ll, lll, res)
4609 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
4610 wl_keyboard_send_repeat_info(res, s->kbd.repeat_rate, s->kbd.repeat_delay);
4611 eina_iterator_free(it);
4612 } 4667 }
4613 return ECORE_CALLBACK_RENEW; 4668 return ECORE_CALLBACK_RENEW;
4614} 4669}
4615 4670
4616static void 4671static void
4617comp_seat_key_update(Comp_Seat *s, xkb_keycode_t key, int dir, unsigned int timestamp) 4672comp_seat_key_send(Comp_Seat *s, xkb_keycode_t key, int dir, unsigned int timestamp, Eina_Bool mods)
4618{ 4673{
4619 Eina_List *l, *ll; 4674 Eina_List *l, *ll;
4620 struct wl_resource *res; 4675 struct wl_resource *res;
4621 uint32_t serial = wl_display_next_serial(s->c->display); 4676 uint32_t serial = wl_display_next_serial(s->c->display);
4622 uint32_t xkb[] = { XKB_KEY_DOWN, XKB_KEY_UP };
4623 uint32_t wl[] = { WL_KEYBOARD_KEY_STATE_PRESSED, WL_KEYBOARD_KEY_STATE_RELEASED }; 4677 uint32_t wl[] = { WL_KEYBOARD_KEY_STATE_PRESSED, WL_KEYBOARD_KEY_STATE_RELEASED };
4624 Eina_Bool mods = EINA_FALSE;
4625 4678
4626 if (xkb_state_update_key(s->kbd.state, key + 8, xkb[dir]))
4627 mods = seat_mods_update(s);
4628 if (!s->focused) return;
4629 l = seat_kbd_active_resources_get(s); 4679 l = seat_kbd_active_resources_get(s);
4630 4680
4631 EINA_LIST_FOREACH(l, ll, res) 4681 EINA_LIST_FOREACH(l, ll, res)
@@ -4635,6 +4685,18 @@ comp_seat_key_update(Comp_Seat *s, xkb_keycode_t key, int dir, unsigned int time
4635 } 4685 }
4636} 4686}
4637 4687
4688static void
4689comp_seat_key_update(Comp_Seat *s, xkb_keycode_t key, int dir, unsigned int timestamp)
4690{
4691 uint32_t xkb[] = { XKB_KEY_DOWN, XKB_KEY_UP };
4692 Eina_Bool mods = EINA_FALSE;
4693
4694 if (s->kbd.external || xkb_state_update_key(s->kbd.state, key + 8, xkb[dir]))
4695 mods = seat_kbd_mods_update(s);
4696 if (s->focused)
4697 comp_seat_key_send(s, key, dir, timestamp, mods);
4698}
4699
4638static Eina_Bool 4700static Eina_Bool
4639comp_key_down(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Key *ev) 4701comp_key_down(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Key *ev)
4640{ 4702{
@@ -4648,17 +4710,25 @@ comp_key_down(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Key *ev)
4648 EINA_LIST_FOREACH(comps, l, c) 4710 EINA_LIST_FOREACH(comps, l, c)
4649 EINA_INLIST_FOREACH(c->seats, s) 4711 EINA_INLIST_FOREACH(c->seats, s)
4650 { 4712 {
4651 uint32_t *end, *k;
4652
4653 if (c->parent_disp && (dev != s->dev)) continue; 4713 if (c->parent_disp && (dev != s->dev)) continue;
4654 end = (uint32_t*)s->kbd.keys.data + (s->kbd.keys.size / sizeof(uint32_t));
4655 4714
4656 for (k = s->kbd.keys.data; k < end; k++) 4715 if (s->kbd.external)
4657 if (*k == keycode) return ECORE_CALLBACK_RENEW; 4716 {
4717 /* only doing passthrough in external mode */
4718 if (!s->focused) return ECORE_CALLBACK_RENEW;
4719 }
4720 else
4721 {
4722 uint32_t *end, *k;
4658 4723
4659 s->kbd.keys.size = (char*)end - (char*)s->kbd.keys.data; 4724 end = (uint32_t*)s->kbd.keys.data + (s->kbd.keys.size / sizeof(uint32_t));
4660 k = wl_array_add(&s->kbd.keys, sizeof(uint32_t)); 4725 for (k = s->kbd.keys.data; k < end; k++)
4661 *k = keycode; 4726 if (*k == keycode) return ECORE_CALLBACK_RENEW;
4727
4728 s->kbd.keys.size = (char*)end - (char*)s->kbd.keys.data;
4729 k = wl_array_add(&s->kbd.keys, sizeof(uint32_t));
4730 *k = keycode;
4731 }
4662 comp_seat_key_update(s, keycode, 0, ev->timestamp); 4732 comp_seat_key_update(s, keycode, 0, ev->timestamp);
4663 } 4733 }
4664 return ECORE_CALLBACK_RENEW; 4734 return ECORE_CALLBACK_RENEW;
@@ -4677,19 +4747,27 @@ comp_key_up(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Key *ev)
4677 EINA_LIST_FOREACH(comps, l, c) 4747 EINA_LIST_FOREACH(comps, l, c)
4678 EINA_INLIST_FOREACH(c->seats, s) 4748 EINA_INLIST_FOREACH(c->seats, s)
4679 { 4749 {
4680 uint32_t *end, *k;
4681
4682 if (c->parent_disp && (dev != s->dev)) continue; 4750 if (c->parent_disp && (dev != s->dev)) continue;
4683 end = (uint32_t*)s->kbd.keys.data + (s->kbd.keys.size / sizeof(uint32_t));
4684 4751
4685 for (k = s->kbd.keys.data; k < end; k++) 4752 if (s->kbd.external)
4686 if (*k == keycode) 4753 {
4687 { 4754 /* only doing passthrough in external mode */
4688 *k = end[-1]; 4755 if (!s->focused) return ECORE_CALLBACK_RENEW;
4689 s->kbd.keys.size = (char*)end - (char*)s->kbd.keys.data - 1; 4756 }
4690 break; 4757 else
4691 } 4758 {
4759 uint32_t *end, *k;
4760
4761 end = (uint32_t*)s->kbd.keys.data + (s->kbd.keys.size / sizeof(uint32_t));
4692 4762
4763 for (k = s->kbd.keys.data; k < end; k++)
4764 if (*k == keycode)
4765 {
4766 *k = end[-1];
4767 s->kbd.keys.size = (char*)end - (char*)s->kbd.keys.data - 1;
4768 break;
4769 }
4770 }
4693 comp_seat_key_update(s, keycode, 1, ev->timestamp); 4771 comp_seat_key_update(s, keycode, 1, ev->timestamp);
4694 } 4772 }
4695 return ECORE_CALLBACK_RENEW; 4773 return ECORE_CALLBACK_RENEW;
@@ -4939,8 +5017,27 @@ comp_focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, voi
4939 s->focused = 1; 5017 s->focused = 1;
4940 if (s->selection_changed) 5018 if (s->selection_changed)
4941 comp_seat_selection_update(s); 5019 comp_seat_selection_update(s);
4942 if (!s->kbd.keymap) continue; 5020 if ((!s->kbd.keymap) && (!s->kbd.state)) continue;
4943 if (!seat_mods_update(s)) continue; 5021 if (s->kbd.external)
5022 {
5023 Eina_Bool mods = seat_kbd_mods_update(s);
5024 if (!s->focused) return;
5025 l = seat_kbd_active_resources_get(s);
5026
5027 EINA_LIST_FOREACH(l, ll, res)
5028 {
5029 uint32_t *end, *k;
5030 serial = wl_display_next_serial(s->c->display);
5031
5032 end = (uint32_t*)s->kbd.keys_external->data + (s->kbd.keys_external->size / sizeof(uint32_t));
5033 if (mods) comp_seat_send_modifiers(s, res, serial);
5034
5035 for (k = s->kbd.keys_external->data; k < end; k++)
5036 comp_seat_key_send(s, *k, 0, 0, mods);
5037 }
5038 return;
5039 }
5040 if (!seat_kbd_mods_update(s)) continue;
4944 l = seat_kbd_active_resources_get(s); 5041 l = seat_kbd_active_resources_get(s);
4945 if (!l) continue; 5042 if (!l) continue;
4946 serial = wl_display_next_serial(s->c->display); 5043 serial = wl_display_next_serial(s->c->display);
@@ -5738,3 +5835,51 @@ efl_wl_extracted_surface_extracted_parent_get(Evas_Object *surface)
5738 } 5835 }
5739 return NULL; 5836 return NULL;
5740} 5837}
5838
5839void
5840efl_wl_seat_keymap_set(Evas_Object *obj, Eo *seat, void *state, int fd, size_t size, void *key_array)
5841{
5842 Comp *c;
5843 Comp_Seat *s;
5844
5845 if (!eina_streq(evas_object_type_get(obj), "comp")) abort();
5846 c = evas_object_smart_data_get(obj);
5847 EINA_INLIST_FOREACH(c->seats, s)
5848 {
5849 if (!seat) efl_wl_seat_keymap_set(obj, s->dev, state, fd, size, key_array);
5850 else if (s->dev == seat) break;
5851 }
5852 if (!seat) return;
5853 EINA_SAFETY_ON_NULL_RETURN(s);
5854 seat_kbd_destroy(s);
5855 s->kbd.external = 1;
5856 s->kbd.keys_external = key_array;
5857 s->kbd.state = state;
5858 s->kbd.keymap_fd = fd;
5859 s->kbd.keymap_mem_size = size;
5860 s->kbd.context = NULL;
5861 s->kbd.keymap = NULL;
5862 s->kbd.keymap_mem = NULL;
5863 if (s->keyboard)
5864 seat_kbd_external_init(s);
5865}
5866
5867void
5868efl_wl_seat_key_repeat_set(Evas_Object *obj, Eo *seat, int repeat_rate, int repeat_delay)
5869{
5870 Comp *c;
5871 Comp_Seat *s;
5872
5873 if (!eina_streq(evas_object_type_get(obj), "comp")) abort();
5874 c = evas_object_smart_data_get(obj);
5875 EINA_INLIST_FOREACH(c->seats, s)
5876 {
5877 if (!seat) efl_wl_seat_key_repeat_set(obj, s->dev, repeat_rate, repeat_delay);
5878 else if (s->dev == seat) break;
5879 }
5880 if (!seat) return;
5881 EINA_SAFETY_ON_NULL_RETURN(s);
5882 s->kbd.repeat_rate = repeat_rate;
5883 s->kbd.repeat_delay = repeat_delay;
5884 seat_kbd_repeat_rate_send(s);
5885}