summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2017-05-26 16:34:10 -0400
committerMike Blumenkrantz <zmike@osg.samsung.com>2017-05-26 16:27:42 -0400
commite8fe0bcc47ff44a5afaf8442407248887f716b89 (patch)
tree4fd7e06b862670ab7f87b2aa313f763e77b99cfc
parent6ddcd48fdeb57fc5b237825df709a2e3746e845e (diff)
elput/drm: redo xkb context/keymap setting
context and keymap need to be set at the same time in order to effectively update keyboard state, and active group should be accessible through api as well preserve old function ABI to ensure old binaries don't crash
-rw-r--r--src/lib/ecore_drm2/Ecore_Drm2.h16
-rw-r--r--src/lib/ecore_drm2/ecore_drm2_device.c12
-rw-r--r--src/lib/elput/Elput.h16
-rw-r--r--src/lib/elput/elput_evdev.c120
-rw-r--r--src/lib/elput/elput_input.c26
-rw-r--r--src/lib/elput/elput_logind.c2
-rw-r--r--src/lib/elput/elput_private.h8
7 files changed, 140 insertions, 60 deletions
diff --git a/src/lib/ecore_drm2/Ecore_Drm2.h b/src/lib/ecore_drm2/Ecore_Drm2.h
index 7d52d3aa00..d62f4e8f4c 100644
--- a/src/lib/ecore_drm2/Ecore_Drm2.h
+++ b/src/lib/ecore_drm2/Ecore_Drm2.h
@@ -285,26 +285,28 @@ EAPI void ecore_drm2_device_window_set(Ecore_Drm2_Device *device, unsigned int w
285EAPI void ecore_drm2_device_pointer_max_set(Ecore_Drm2_Device *device, int w, int h); 285EAPI void ecore_drm2_device_pointer_max_set(Ecore_Drm2_Device *device, int w, int h);
286 286
287/** 287/**
288 * Set a cached context to be used on keyboards 288 * Set info to be used on keyboards
289 * 289 *
290 * @param device 290 * @param device
291 * @param context 291 * @param context
292 * @param keymap
293 * @param group
292 * 294 *
293 * @ingroup Ecore_Drm2_Device_Group 295 * @ingroup Ecore_Drm2_Device_Group
294 * @since 1.18 296 * @since 1.20
295 */ 297 */
296EAPI void ecore_drm2_device_keyboard_cached_context_set(Ecore_Drm2_Device *device, void *context); 298EAPI void ecore_drm2_device_keyboard_info_set(Ecore_Drm2_Device *device, void *context, void *keymap, int group);
297 299
298/** 300/**
299 * Set a cached keymap to be used on keyboards 301 * Set a group layout to be used on keyboards
300 * 302 *
301 * @param device 303 * @param device
302 * @param keymap 304 * @param group
303 * 305 *
304 * @ingroup Ecore_Drm2_Device_Group 306 * @ingroup Ecore_Drm2_Device_Group
305 * @since 1.18 307 * @since 1.20
306 */ 308 */
307EAPI void ecore_drm2_device_keyboard_cached_keymap_set(Ecore_Drm2_Device *device, void *keymap); 309EAPI void ecore_drm2_device_keyboard_group_set(Ecore_Drm2_Device *device, int group);
308 310
309/** 311/**
310 * Get the crtcs of a given device 312 * Get the crtcs of a given device
diff --git a/src/lib/ecore_drm2/ecore_drm2_device.c b/src/lib/ecore_drm2/ecore_drm2_device.c
index dbd95fe465..f225ad8129 100644
--- a/src/lib/ecore_drm2/ecore_drm2_device.c
+++ b/src/lib/ecore_drm2/ecore_drm2_device.c
@@ -777,19 +777,19 @@ ecore_drm2_device_pointer_max_set(Ecore_Drm2_Device *device, int w, int h)
777} 777}
778 778
779EAPI void 779EAPI void
780ecore_drm2_device_keyboard_cached_context_set(Ecore_Drm2_Device *device, void *context) 780ecore_drm2_device_keyboard_info_set(Ecore_Drm2_Device *device, void *context, void *keymap, int group)
781{ 781{
782 EINA_SAFETY_ON_NULL_RETURN(device); 782 EINA_SAFETY_ON_NULL_RETURN(device);
783 783
784 elput_input_keyboard_cached_context_set(device->em, context); 784 elput_input_keyboard_info_set(device->em, context, keymap, group);
785} 785}
786 786
787EAPI void 787EAPI void
788ecore_drm2_device_keyboard_cached_keymap_set(Ecore_Drm2_Device *device, void *keymap) 788ecore_drm2_device_keyboard_group_set(Ecore_Drm2_Device *device, int group)
789{ 789{
790 EINA_SAFETY_ON_NULL_RETURN(device); 790 EINA_SAFETY_ON_NULL_RETURN(device);
791 791
792 elput_input_keyboard_cached_keymap_set(device->em, keymap); 792 elput_input_keyboard_group_set(device->em, group);
793} 793}
794 794
795EAPI unsigned int * 795EAPI unsigned int *
@@ -848,3 +848,7 @@ ecore_drm2_device_prefer_shadow(Ecore_Drm2_Device *device)
848 else 848 else
849 return EINA_FALSE; 849 return EINA_FALSE;
850} 850}
851
852/* prevent crashing with old apps compiled against these functions */
853EAPI void ecore_drm2_device_keyboard_cached_context_set(){};
854EAPI void ecore_drm2_device_keyboard_cached_keymap_set(){};
diff --git a/src/lib/elput/Elput.h b/src/lib/elput/Elput.h
index 378912eb90..f9e950c821 100644
--- a/src/lib/elput/Elput.h
+++ b/src/lib/elput/Elput.h
@@ -395,26 +395,28 @@ EAPI Eina_Bool elput_input_key_remap_enable(Elput_Manager *manager, Eina_Bool en
395EAPI Eina_Bool elput_input_key_remap_set(Elput_Manager *manager, int *from_keys, int *to_keys, int num); 395EAPI Eina_Bool elput_input_key_remap_set(Elput_Manager *manager, int *from_keys, int *to_keys, int num);
396 396
397/** 397/**
398 * Set a cached context to be used for keyboards 398 * Set info to be used for keyboards
399 * 399 *
400 * @param manager 400 * @param manager
401 * @param context 401 * @param context
402 * @param keymap
403 * @param group
402 * 404 *
403 * @ingroup Elput_Input_Group 405 * @ingroup Elput_Input_Group
404 * @since 1.18 406 * @since 1.20
405 */ 407 */
406EAPI void elput_input_keyboard_cached_context_set(Elput_Manager *manager, void *context); 408EAPI void elput_input_keyboard_info_set(Elput_Manager *manager, void *context, void *keymap, int group);
407 409
408/** 410/**
409 * Set a cached keymap to be used for keyboards 411 * Set group layout to be used for keyboards
410 * 412 *
411 * @param manager 413 * @param manager
412 * @param keymap 414 * @param group
413 * 415 *
414 * @ingroup Elput_Input_Group 416 * @ingroup Elput_Input_Group
415 * @since 1.18 417 * @since 1.20
416 */ 418 */
417EAPI void elput_input_keyboard_cached_keymap_set(Elput_Manager *manager, void *keymap); 419EAPI void elput_input_keyboard_group_set(Elput_Manager *manager, int group);
418 420
419/** 421/**
420 * Return the output name associated with a given device 422 * Return the output name associated with a given device
diff --git a/src/lib/elput/elput_evdev.c b/src/lib/elput/elput_evdev.c
index 3c6243bc1a..46f8068f79 100644
--- a/src/lib/elput/elput_evdev.c
+++ b/src/lib/elput/elput_evdev.c
@@ -89,7 +89,7 @@ _keyboard_fd_get(off_t size)
89} 89}
90 90
91static Elput_Keyboard_Info * 91static Elput_Keyboard_Info *
92_keyboard_info_create(struct xkb_keymap *keymap, Eina_Bool external) 92_keyboard_info_create(struct xkb_keymap *keymap)
93{ 93{
94 Elput_Keyboard_Info *info; 94 Elput_Keyboard_Info *info;
95 char *str; 95 char *str;
@@ -113,9 +113,6 @@ _keyboard_info_create(struct xkb_keymap *keymap, Eina_Bool external)
113 info->mods.altgr = 113 info->mods.altgr =
114 1 << xkb_keymap_mod_get_index(info->keymap.map, "ISO_Level3_Shift"); 114 1 << xkb_keymap_mod_get_index(info->keymap.map, "ISO_Level3_Shift");
115 115
116 /* if we are using an external keymap then we do not need go further */
117 if (external) return info;
118
119 str = xkb_keymap_get_as_string(info->keymap.map, XKB_KEYMAP_FORMAT_TEXT_V1); 116 str = xkb_keymap_get_as_string(info->keymap.map, XKB_KEYMAP_FORMAT_TEXT_V1);
120 if (!str) goto err; 117 if (!str) goto err;
121 118
@@ -145,17 +142,14 @@ err:
145} 142}
146 143
147static void 144static void
148_keyboard_info_destroy(Elput_Keyboard_Info *info, Eina_Bool external) 145_keyboard_info_destroy(Elput_Keyboard_Info *info)
149{ 146{
150 if (--info->refs > 0) return; 147 if (--info->refs > 0) return;
151 148
152 xkb_keymap_unref(info->keymap.map); 149 xkb_keymap_unref(info->keymap.map);
153 150
154 if (!external) 151 if (info->keymap.area) munmap(info->keymap.area, info->keymap.size);
155 { 152 if (info->keymap.fd >= 0) close(info->keymap.fd);
156 if (info->keymap.area) munmap(info->keymap.area, info->keymap.size);
157 if (info->keymap.fd >= 0) close(info->keymap.fd);
158 }
159 153
160 free(info); 154 free(info);
161} 155}
@@ -175,7 +169,7 @@ _keyboard_global_build(Elput_Keyboard *kbd)
175 keymap = xkb_keymap_new_from_names(kbd->context, &kbd->names, 0); 169 keymap = xkb_keymap_new_from_names(kbd->context, &kbd->names, 0);
176 if (!keymap) return EINA_FALSE; 170 if (!keymap) return EINA_FALSE;
177 171
178 kbd->info = _keyboard_info_create(keymap, EINA_FALSE); 172 kbd->info = _keyboard_info_create(keymap);
179 xkb_keymap_unref(keymap); 173 xkb_keymap_unref(keymap);
180 174
181 if (!kbd->info) return EINA_FALSE; 175 if (!kbd->info) return EINA_FALSE;
@@ -231,7 +225,9 @@ _keyboard_init(Elput_Seat *seat, struct xkb_keymap *keymap)
231 225
232 if (keymap) 226 if (keymap)
233 { 227 {
234 kbd->info = _keyboard_info_create(keymap, EINA_TRUE); 228 if (seat->manager->cached.keymap == keymap)
229 kbd->context = xkb_context_ref(seat->manager->cached.context);
230 kbd->info = _keyboard_info_create(keymap);
235 if (!kbd->info) goto err; 231 if (!kbd->info) goto err;
236 } 232 }
237 else 233 else
@@ -254,7 +250,7 @@ _keyboard_init(Elput_Seat *seat, struct xkb_keymap *keymap)
254 return EINA_TRUE; 250 return EINA_TRUE;
255 251
256err: 252err:
257 if (kbd->info) _keyboard_info_destroy(kbd->info, kbd->external_map); 253 if (kbd->info) _keyboard_info_destroy(kbd->info);
258 free(kbd); 254 free(kbd);
259 return EINA_FALSE; 255 return EINA_FALSE;
260} 256}
@@ -346,39 +342,91 @@ _keyboard_modifiers_send(Elput_Keyboard *kbd)
346 ecore_event_add(ELPUT_EVENT_MODIFIERS_SEND, ev, NULL, NULL); 342 ecore_event_add(ELPUT_EVENT_MODIFIERS_SEND, ev, NULL, NULL);
347} 343}
348 344
349static void 345static Eina_Bool
346_keyboard_state_update(Elput_Keyboard *kbd, struct xkb_keymap *map, xkb_mod_mask_t *latched, xkb_mod_mask_t *locked)
347{
348 struct xkb_state *state, *maskless_state;
349
350 state = xkb_state_new(map);
351 if (!state) return EINA_FALSE;
352 maskless_state = xkb_state_new(map);
353 if (!maskless_state)
354 {
355 xkb_state_unref(state);
356 return EINA_FALSE;
357 }
358
359 *latched = xkb_state_serialize_mods(kbd->state, XKB_STATE_MODS_LATCHED);
360 *locked = xkb_state_serialize_mods(kbd->state, XKB_STATE_MODS_LOCKED);
361 xkb_state_update_mask(state, 0, *latched, *locked, kbd->seat->manager->cached.group, 0, 0);
362
363 xkb_state_unref(kbd->state);
364 kbd->state = state;
365 xkb_state_unref(kbd->maskless_state);
366 kbd->maskless_state = maskless_state;
367 return EINA_TRUE;
368}
369
370void
350_keyboard_keymap_update(Elput_Seat *seat) 371_keyboard_keymap_update(Elput_Seat *seat)
351{ 372{
352 Elput_Keyboard *kbd; 373 Elput_Keyboard *kbd;
353 Elput_Keyboard_Info *info; 374 Elput_Keyboard_Info *info = NULL;
354 struct xkb_state *state;
355 xkb_mod_mask_t latched, locked; 375 xkb_mod_mask_t latched, locked;
376 Eina_Bool state = EINA_TRUE;
356 377
357 kbd = _evdev_keyboard_get(seat); 378 kbd = _evdev_keyboard_get(seat);
358 if (!kbd) return; 379 if (!kbd) return;
380 kbd->pending_keymap = 1;
381 if (kbd->key_count) return;
359 382
360 info = _keyboard_info_create(kbd->pending_map, kbd->external_map); 383 if (kbd->seat->manager->cached.keymap)
361 xkb_keymap_unref(kbd->pending_map); 384 {
362 kbd->pending_map = NULL; 385 if (kbd->context) xkb_context_unref(kbd->context);
363 386 kbd->context = xkb_context_ref(kbd->seat->manager->cached.context);
364 if (!info) return; 387 info = _keyboard_info_create(kbd->seat->manager->cached.keymap);
365 388 if (!info) return;
366 state = xkb_state_new(info->keymap.map); 389 state = _keyboard_state_update(kbd, info->keymap.map, &latched, &locked);
390 }
391 else if (!_keyboard_global_build(kbd)) return;
392 else
393 state = _keyboard_state_update(kbd, kbd->info->keymap.map, &latched, &locked);
394 kbd->pending_keymap = 0;
367 if (!state) 395 if (!state)
368 { 396 {
369 _keyboard_info_destroy(info, kbd->external_map); 397 if (info) _keyboard_info_destroy(info);
370 return; 398 return;
371 } 399 }
372 400
373 latched = xkb_state_serialize_mods(kbd->state, XKB_STATE_MODS_LATCHED); 401 if (info)
374 locked = xkb_state_serialize_mods(kbd->state, XKB_STATE_MODS_LOCKED); 402 {
375 xkb_state_update_mask(state, 0, latched, locked, 0, 0, 0); 403 _keyboard_info_destroy(kbd->info);
404 kbd->info = info;
405 }
376 406
377 _keyboard_info_destroy(kbd->info, kbd->external_map); 407 _keyboard_compose_init(kbd);
378 kbd->info = info;
379 408
380 xkb_state_unref(kbd->state); 409 _keyboard_modifiers_update(kbd, seat);
381 kbd->state = state; 410 _keyboard_keymap_send(kbd->info);
411
412 if ((!latched) && (!locked)) return;
413
414 _keyboard_modifiers_send(kbd);
415}
416
417void
418_keyboard_group_update(Elput_Seat *seat)
419{
420 Elput_Keyboard *kbd;
421 xkb_mod_mask_t latched, locked;
422 Eina_Bool state;
423
424 kbd = _evdev_keyboard_get(seat);
425 if (!kbd) return;
426
427 state = _keyboard_state_update(kbd, kbd->info->keymap.map, &latched, &locked);
428 if (!state) return;
429 _keyboard_compose_init(kbd);
382 430
383 _keyboard_modifiers_update(kbd, seat); 431 _keyboard_modifiers_update(kbd, seat);
384 _keyboard_keymap_send(kbd->info); 432 _keyboard_keymap_send(kbd->info);
@@ -568,7 +616,7 @@ _keyboard_key(struct libinput_device *idevice, struct libinput_event_keyboard *e
568 if (!kbd) return; 616 if (!kbd) return;
569 617
570 state = libinput_event_keyboard_get_key_state(event); 618 state = libinput_event_keyboard_get_key_state(event);
571 count = libinput_event_keyboard_get_seat_key_count(event); 619 kbd->key_count = count = libinput_event_keyboard_get_seat_key_count(event);
572 620
573 /* Ignore key events that are not seat wide state changes. */ 621 /* Ignore key events that are not seat wide state changes. */
574 if (((state == LIBINPUT_KEY_STATE_PRESSED) && (count != 1)) || 622 if (((state == LIBINPUT_KEY_STATE_PRESSED) && (count != 1)) ||
@@ -610,7 +658,7 @@ _keyboard_key(struct libinput_device *idevice, struct libinput_event_keyboard *e
610 _keyboard_keysym_translate(sym, dev->seat->modifiers, compose, sizeof(compose)); 658 _keyboard_keysym_translate(sym, dev->seat->modifiers, compose, sizeof(compose));
611 _keyboard_key_send(dev, state, keyname, key, compose, code, timestamp); 659 _keyboard_key_send(dev, state, keyname, key, compose, code, timestamp);
612 660
613 if ((kbd->pending_map) && (count == 0)) 661 if ((kbd->pending_keymap) && (count == 0))
614 _keyboard_keymap_update(dev->seat); 662 _keyboard_keymap_update(dev->seat);
615 663
616 if (state == LIBINPUT_KEY_STATE_PRESSED) 664 if (state == LIBINPUT_KEY_STATE_PRESSED)
@@ -1588,12 +1636,14 @@ _evdev_keyboard_destroy(Elput_Keyboard *kbd)
1588 free((char *)kbd->names.variant); 1636 free((char *)kbd->names.variant);
1589 free((char *)kbd->names.options); 1637 free((char *)kbd->names.options);
1590 1638
1639 if (kbd->compose_table) xkb_compose_table_unref(kbd->compose_table);
1640 if (kbd->compose_state) xkb_compose_state_unref(kbd->compose_state);
1641
1591 if (kbd->state) xkb_state_unref(kbd->state); 1642 if (kbd->state) xkb_state_unref(kbd->state);
1592 if (kbd->info) _keyboard_info_destroy(kbd->info, kbd->external_map);
1593 if (kbd->maskless_state) xkb_state_unref(kbd->maskless_state); 1643 if (kbd->maskless_state) xkb_state_unref(kbd->maskless_state);
1644 if (kbd->info) _keyboard_info_destroy(kbd->info);
1594 1645
1595 xkb_context_unref(kbd->context); 1646 xkb_context_unref(kbd->context);
1596 xkb_keymap_unref(kbd->pending_map);
1597 1647
1598 free(kbd); 1648 free(kbd);
1599} 1649}
diff --git a/src/lib/elput/elput_input.c b/src/lib/elput/elput_input.c
index f46f26d246..a5afe74fd9 100644
--- a/src/lib/elput/elput_input.c
+++ b/src/lib/elput/elput_input.c
@@ -654,21 +654,37 @@ elput_input_key_remap_set(Elput_Manager *manager, int *from_keys, int *to_keys,
654} 654}
655 655
656EAPI void 656EAPI void
657elput_input_keyboard_cached_context_set(Elput_Manager *manager, void *context) 657elput_input_keyboard_info_set(Elput_Manager *manager, void *context, void *keymap, int group)
658{ 658{
659 Eina_List *l;
660 Elput_Seat *seat;
661
659 EINA_SAFETY_ON_NULL_RETURN(manager); 662 EINA_SAFETY_ON_NULL_RETURN(manager);
663 EINA_SAFETY_ON_FALSE_RETURN((!!context) == (!!keymap));
660 664
661 if ((context) && (manager->cached.context == context)) return; 665 if ((manager->cached.context == context) && (manager->cached.keymap == keymap)) return;
666 if (context) xkb_context_ref(context);
667 if (keymap) xkb_keymap_ref(keymap);
668 if (manager->cached.context) xkb_context_unref(manager->cached.context);
669 if (manager->cached.keymap) xkb_keymap_unref(manager->cached.keymap);
662 manager->cached.context = context; 670 manager->cached.context = context;
671 manager->cached.keymap = keymap;
672 manager->cached.group = group;
673 EINA_LIST_FOREACH(manager->input.seats, l, seat)
674 _keyboard_keymap_update(seat);
663} 675}
664 676
665EAPI void 677EAPI void
666elput_input_keyboard_cached_keymap_set(Elput_Manager *manager, void *keymap) 678elput_input_keyboard_group_set(Elput_Manager *manager, int group)
667{ 679{
680 Eina_List *l;
681 Elput_Seat *seat;
668 EINA_SAFETY_ON_NULL_RETURN(manager); 682 EINA_SAFETY_ON_NULL_RETURN(manager);
669 683
670 if ((keymap) && (manager->cached.keymap == keymap)) return; 684 if (manager->cached.group == group) return;
671 manager->cached.keymap = keymap; 685 manager->cached.group = group;
686 EINA_LIST_FOREACH(manager->input.seats, l, seat)
687 _keyboard_group_update(seat);
672} 688}
673 689
674EAPI Eina_Stringshare * 690EAPI Eina_Stringshare *
diff --git a/src/lib/elput/elput_logind.c b/src/lib/elput/elput_logind.c
index 25034480d2..cfce90e3aa 100644
--- a/src/lib/elput/elput_logind.c
+++ b/src/lib/elput/elput_logind.c
@@ -527,6 +527,8 @@ _logind_disconnect(Elput_Manager *em)
527 _logind_dbus_close(em->dbus.conn); 527 _logind_dbus_close(em->dbus.conn);
528 eina_stringshare_del(em->seat); 528 eina_stringshare_del(em->seat);
529 free(em->sid); 529 free(em->sid);
530 if (em->cached.context) xkb_context_unref(em->cached.context);
531 if (em->cached.keymap) xkb_keymap_unref(em->cached.keymap);
530 free(em); 532 free(em);
531} 533}
532 534
diff --git a/src/lib/elput/elput_private.h b/src/lib/elput/elput_private.h
index c6e3c81d83..4c7881e0ef 100644
--- a/src/lib/elput/elput_private.h
+++ b/src/lib/elput/elput_private.h
@@ -135,9 +135,9 @@ struct _Elput_Keyboard
135 } grab; 135 } grab;
136 136
137 Elput_Keyboard_Info *info; 137 Elput_Keyboard_Info *info;
138 unsigned int key_count;
138 139
139 struct xkb_state *state; 140 struct xkb_state *state;
140 struct xkb_keymap *pending_map;
141 struct xkb_state *maskless_state; 141 struct xkb_state *maskless_state;
142 struct xkb_context *context; 142 struct xkb_context *context;
143 struct xkb_rule_names names; 143 struct xkb_rule_names names;
@@ -146,7 +146,7 @@ struct _Elput_Keyboard
146 146
147 Elput_Seat *seat; 147 Elput_Seat *seat;
148 148
149 Eina_Bool external_map : 1; 149 Eina_Bool pending_keymap : 1;
150}; 150};
151 151
152struct _Elput_Pointer 152struct _Elput_Pointer
@@ -261,6 +261,7 @@ struct _Elput_Manager
261 { 261 {
262 struct xkb_keymap *keymap; 262 struct xkb_keymap *keymap;
263 struct xkb_context *context; 263 struct xkb_context *context;
264 int group;
264 } cached; 265 } cached;
265 266
266 Elput_Input input; 267 Elput_Input input;
@@ -292,4 +293,7 @@ Elput_Touch *_evdev_touch_get(Elput_Seat *seat);
292 293
293extern Elput_Interface _logind_interface; 294extern Elput_Interface _logind_interface;
294 295
296void _keyboard_keymap_update(Elput_Seat *seat);
297void _keyboard_group_update(Elput_Seat *seat);
298
295#endif 299#endif