summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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