summaryrefslogtreecommitdiff
path: root/src/lib/elput/elput_evdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/elput/elput_evdev.c')
-rw-r--r--src/lib/elput/elput_evdev.c120
1 files changed, 85 insertions, 35 deletions
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}