1/* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2000 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the GTK+ Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
23 */
24
25#include "config.h"
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <unistd.h>
31#include <limits.h>
32#include <errno.h>
33#include <sys/mman.h>
34
35#include "gdk.h"
36#include "gdkwayland.h"
37
38#include "gdkprivate-wayland.h"
39#include "gdkinternals.h"
40#include "gdkkeysprivate.h"
41
42#include <xkbcommon/xkbcommon.h>
43
44typedef struct _GdkWaylandKeymap GdkWaylandKeymap;
45typedef struct _GdkWaylandKeymapClass GdkWaylandKeymapClass;
46
47struct _GdkWaylandKeymap
48{
49 GdkKeymap parent_instance;
50
51 struct xkb_keymap *xkb_keymap;
52 struct xkb_state *xkb_state;
53
54 PangoDirection *direction;
55 gboolean bidi;
56};
57
58struct _GdkWaylandKeymapClass
59{
60 GdkKeymapClass parent_class;
61};
62
63#define GDK_TYPE_WAYLAND_KEYMAP (_gdk_wayland_keymap_get_type ())
64#define GDK_WAYLAND_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_KEYMAP, GdkWaylandKeymap))
65#define GDK_IS_WAYLAND_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_KEYMAP))
66
67GType _gdk_wayland_keymap_get_type (void);
68
69G_DEFINE_TYPE (GdkWaylandKeymap, _gdk_wayland_keymap, GDK_TYPE_KEYMAP)
70
71static void
72gdk_wayland_keymap_finalize (GObject *object)
73{
74 GdkWaylandKeymap *keymap = GDK_WAYLAND_KEYMAP (object);
75
76 xkb_keymap_unref (keymap->xkb_keymap);
77 xkb_state_unref (keymap->xkb_state);
78 g_free (keymap->direction);
79
80 G_OBJECT_CLASS (_gdk_wayland_keymap_parent_class)->finalize (object);
81}
82
83static PangoDirection
84gdk_wayland_keymap_get_direction (GdkKeymap *keymap)
85{
86 GdkWaylandKeymap *keymap_wayland = GDK_WAYLAND_KEYMAP (keymap);
87 gint i;
88
89 for (i = 0; i < xkb_keymap_num_layouts (keymap_wayland->xkb_keymap); i++)
90 {
91 if (xkb_state_layout_index_is_active (keymap_wayland->xkb_state, i, XKB_STATE_LAYOUT_EFFECTIVE))
92 return keymap_wayland->direction[i];
93 }
94
95 return PANGO_DIRECTION_NEUTRAL;
96}
97
98static gboolean
99gdk_wayland_keymap_have_bidi_layouts (GdkKeymap *keymap)
100{
101 GdkWaylandKeymap *keymap_wayland = GDK_WAYLAND_KEYMAP (keymap);
102
103 return keymap_wayland->bidi;
104}
105
106static gboolean
107gdk_wayland_keymap_get_caps_lock_state (GdkKeymap *keymap)
108{
109 return xkb_state_led_name_is_active (GDK_WAYLAND_KEYMAP (keymap)->xkb_state,
110 XKB_LED_NAME_CAPS);
111}
112
113static gboolean
114gdk_wayland_keymap_get_num_lock_state (GdkKeymap *keymap)
115{
116 return xkb_state_led_name_is_active (GDK_WAYLAND_KEYMAP (keymap)->xkb_state,
117 XKB_LED_NAME_NUM);
118}
119
120static gboolean
121gdk_wayland_keymap_get_scroll_lock_state (GdkKeymap *keymap)
122{
123 return xkb_state_led_name_is_active (GDK_WAYLAND_KEYMAP (keymap)->xkb_state,
124 XKB_LED_NAME_SCROLL);
125}
126
127static gboolean
128gdk_wayland_keymap_get_entries_for_keyval (GdkKeymap *keymap,
129 guint keyval,
130 GdkKeymapKey **keys,
131 gint *n_keys)
132{
133 struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
134 GArray *retval;
135 guint keycode;
136 xkb_keycode_t min_keycode, max_keycode;
137
138 retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
139
140 min_keycode = xkb_keymap_min_keycode (xkb_keymap);
141 max_keycode = xkb_keymap_max_keycode (xkb_keymap);
142 for (keycode = min_keycode; keycode < max_keycode; keycode++)
143 {
144 gint num_layouts, layout;
145 num_layouts = xkb_keymap_num_layouts_for_key (xkb_keymap, keycode);
146 for (layout = 0; layout < num_layouts; layout++)
147 {
148 gint num_levels, level;
149 num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, keycode, layout);
150 for (level = 0; level < num_levels; level++)
151 {
152 const xkb_keysym_t *syms;
153 gint num_syms, sym;
154 num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, keycode, layout, level, &syms);
155 for (sym = 0; sym < num_syms; sym++)
156 {
157 if (syms[sym] == keyval)
158 {
159 GdkKeymapKey key;
160
161 key.keycode = keycode;
162 key.group = layout;
163 key.level = level;
164
165 g_array_append_val (retval, key);
166 }
167 }
168 }
169 }
170 }
171
172 *n_keys = retval->len;
173 *keys = (GdkKeymapKey*) g_array_free (retval, FALSE);
174
175 return TRUE;
176}
177
178static gboolean
179gdk_wayland_keymap_get_entries_for_keycode (GdkKeymap *keymap,
180 guint hardware_keycode,
181 GdkKeymapKey **keys,
182 guint **keyvals,
183 gint *n_entries)
184{
185 struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
186 gint num_layouts, layout;
187 gint num_entries;
188 gint i;
189
190 num_layouts = xkb_keymap_num_layouts_for_key (xkb_keymap, hardware_keycode);
191
192 num_entries = 0;
193 for (layout = 0; layout < num_layouts; layout++)
194 num_entries += xkb_keymap_num_levels_for_key (xkb_keymap, hardware_keycode, layout);
195
196 if (n_entries)
197 *n_entries = num_entries;
198 if (keys)
199 *keys = g_new0 (GdkKeymapKey, num_entries);
200 if (keyvals)
201 *keyvals = g_new0 (guint, num_entries);
202
203 i = 0;
204 for (layout = 0; layout < num_layouts; layout++)
205 {
206 gint num_levels, level;
207 num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, hardware_keycode, layout);
208 for (level = 0; level < num_levels; level++)
209 {
210 const xkb_keysym_t *syms;
211 int num_syms;
212 num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, hardware_keycode, layout, 0, &syms);
213 if (keys)
214 {
215 (*keys)[i].keycode = hardware_keycode;
216 (*keys)[i].group = layout;
217 (*keys)[i].level = level;
218 }
219 if (keyvals && num_syms > 0)
220 (*keyvals)[i] = syms[0];
221
222 i++;
223 }
224 }
225
226 return num_entries > 0;
227}
228
229static guint
230gdk_wayland_keymap_lookup_key (GdkKeymap *keymap,
231 const GdkKeymapKey *key)
232{
233 struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
234 const xkb_keysym_t *syms;
235 int num_syms;
236
237 num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap,
238 key->keycode,
239 key->group,
240 key->level,
241 &syms);
242 if (num_syms > 0)
243 return syms[0];
244 else
245 return XKB_KEY_NoSymbol;
246}
247
248static guint32
249get_xkb_modifiers (struct xkb_keymap *xkb_keymap,
250 GdkModifierType state)
251{
252 guint32 mods = 0;
253
254 if (state & GDK_SHIFT_MASK)
255 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_SHIFT);
256 if (state & GDK_LOCK_MASK)
257 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CAPS);
258 if (state & GDK_CONTROL_MASK)
259 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CTRL);
260 if (state & GDK_MOD1_MASK)
261 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_ALT);
262 if (state & GDK_MOD2_MASK)
263 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_NUM);
264 if (state & GDK_MOD3_MASK)
265 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod3");
266 if (state & GDK_MOD4_MASK)
267 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_LOGO);
268 if (state & GDK_MOD5_MASK)
269 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod5");
270 if (state & GDK_SUPER_MASK)
271 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Super");
272 if (state & GDK_HYPER_MASK)
273 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Hyper");
274 if (state & GDK_META_MASK)
275 mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Meta");
276
277 return mods;
278}
279
280static GdkModifierType
281get_gdk_modifiers (struct xkb_keymap *xkb_keymap,
282 guint32 mods)
283{
284 GdkModifierType state = 0;
285
286 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_SHIFT)))
287 state |= GDK_SHIFT_MASK;
288 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CAPS)))
289 state |= GDK_LOCK_MASK;
290 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CTRL)))
291 state |= GDK_CONTROL_MASK;
292 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_ALT)))
293 state |= GDK_MOD1_MASK;
294 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_NUM)))
295 state |= GDK_MOD2_MASK;
296 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod3")))
297 state |= GDK_MOD3_MASK;
298 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_LOGO)))
299 state |= GDK_MOD4_MASK;
300 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Mod5")))
301 state |= GDK_MOD5_MASK;
302 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Super")))
303 state |= GDK_SUPER_MASK;
304 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Hyper")))
305 state |= GDK_HYPER_MASK;
306 if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Meta")))
307 state |= GDK_META_MASK;
308
309 return state;
310}
311
312static gboolean
313gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap,
314 guint hardware_keycode,
315 GdkModifierType state,
316 gint group,
317 guint *keyval,
318 gint *effective_group,
319 gint *effective_level,
320 GdkModifierType *consumed_modifiers)
321{
322 struct xkb_keymap *xkb_keymap;
323 struct xkb_state *xkb_state;
324 guint32 modifiers;
325 guint32 consumed;
326 xkb_layout_index_t layout;
327 xkb_level_index_t level;
328 xkb_keysym_t sym;
329
330 g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
331 g_return_val_if_fail (group < 4, FALSE);
332
333 xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
334
335 modifiers = get_xkb_modifiers (xkb_keymap, state);
336
337 xkb_state = xkb_state_new (xkb_keymap);
338
339 xkb_state_update_mask (xkb_state, modifiers, 0, 0, group, 0, 0);
340
341 layout = xkb_state_key_get_layout (xkb_state, hardware_keycode);
342 level = xkb_state_key_get_level (xkb_state, hardware_keycode, layout);
343 sym = xkb_state_key_get_one_sym (xkb_state, hardware_keycode);
344 consumed = modifiers & ~xkb_state_mod_mask_remove_consumed (xkb_state, hardware_keycode, modifiers);
345
346 xkb_state_unref (xkb_state);
347
348 if (keyval)
349 *keyval = sym;
350 if (effective_group)
351 *effective_group = layout;
352 if (effective_level)
353 *effective_level = level;
354 if (consumed_modifiers)
355 *consumed_modifiers = get_gdk_modifiers (xkb_keymap, consumed);
356
357 return (sym != XKB_KEY_NoSymbol);
358}
359
360static guint
361gdk_wayland_keymap_get_modifier_state (GdkKeymap *keymap)
362{
363 struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
364 struct xkb_state *xkb_state = GDK_WAYLAND_KEYMAP (keymap)->xkb_state;
365 xkb_mod_mask_t mods;
366
367 mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE);
368
369 return get_gdk_modifiers (xkb_keymap, mods);
370}
371
372static void
373gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap *keymap,
374 GdkModifierType *state)
375{
376 struct xkb_keymap *xkb_keymap;
377 struct xkb_state *xkb_state;
378 xkb_mod_index_t idx;
379 uint32_t mods, real;
380 struct { const char *name; GdkModifierType mask; } vmods[] = {
381 { "Super", GDK_SUPER_MASK },
382 { "Hyper", GDK_HYPER_MASK },
383 { "Meta", GDK_META_MASK },
384 { NULL, 0 }
385 };
386 int i;
387
388 xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
389 mods = get_xkb_modifiers (xkb_keymap, *state);
390
391 xkb_state = xkb_state_new (xkb_keymap);
392
393 for (i = 0; vmods[i].name; i++)
394 {
395 idx = xkb_keymap_mod_get_index (xkb_keymap, vmods[i].name);
396 if (idx == XKB_MOD_INVALID)
397 continue;
398
399 xkb_state_update_mask (xkb_state, 1 << idx, 0, 0, 0, 0, 0);
400 real = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE);
401 real &= 0xf0; /* ignore mapping to Lock, Shift, Control, Mod1 */
402 if (mods & real)
403 *state |= vmods[i].mask;
404 xkb_state_update_mask (xkb_state, 0, 0, 0, 0, 0, 0);
405 }
406
407 xkb_state_unref (xkb_state);
408}
409
410static gboolean
411gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap *keymap,
412 GdkModifierType *state)
413{
414 struct xkb_keymap *xkb_keymap;
415 struct xkb_state *xkb_state;
416 uint32_t mods, mapped;
417 gboolean ret = TRUE;
418
419 xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
420 mods = get_xkb_modifiers (xkb_keymap, *state);
421
422 xkb_state = xkb_state_new (xkb_keymap);
423 xkb_state_update_mask (xkb_state, mods & ~0xff, 0, 0, 0, 0, 0);
424 mapped = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE);
425 if ((mapped & mods & 0xff) != 0)
426 ret = FALSE;
427 *state |= get_gdk_modifiers (xkb_keymap, mapped);
428
429 xkb_state_unref (xkb_state);
430
431 return ret;
432}
433
434static void
435_gdk_wayland_keymap_class_init (GdkWaylandKeymapClass *klass)
436{
437 GObjectClass *object_class = G_OBJECT_CLASS (klass);
438 GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass);
439
440 object_class->finalize = gdk_wayland_keymap_finalize;
441
442 keymap_class->get_direction = gdk_wayland_keymap_get_direction;
443 keymap_class->have_bidi_layouts = gdk_wayland_keymap_have_bidi_layouts;
444 keymap_class->get_caps_lock_state = gdk_wayland_keymap_get_caps_lock_state;
445 keymap_class->get_num_lock_state = gdk_wayland_keymap_get_num_lock_state;
446 keymap_class->get_scroll_lock_state = gdk_wayland_keymap_get_scroll_lock_state;
447 keymap_class->get_entries_for_keyval = gdk_wayland_keymap_get_entries_for_keyval;
448 keymap_class->get_entries_for_keycode = gdk_wayland_keymap_get_entries_for_keycode;
449 keymap_class->lookup_key = gdk_wayland_keymap_lookup_key;
450 keymap_class->translate_keyboard_state = gdk_wayland_keymap_translate_keyboard_state;
451 keymap_class->get_modifier_state = gdk_wayland_keymap_get_modifier_state;
452 keymap_class->add_virtual_modifiers = gdk_wayland_keymap_add_virtual_modifiers;
453 keymap_class->map_virtual_modifiers = gdk_wayland_keymap_map_virtual_modifiers;
454}
455
456static void
457_gdk_wayland_keymap_init (GdkWaylandKeymap *keymap)
458{
459}
460
461static void
462update_direction (GdkWaylandKeymap *keymap)
463{
464 gint num_layouts;
465 gint i;
466 gint *rtl;
467 xkb_keycode_t min_keycode, max_keycode;
468 guint key;
469 gboolean have_rtl, have_ltr;
470
471 num_layouts = xkb_keymap_num_layouts (keymap->xkb_keymap);
472
473 keymap->direction = g_renew (PangoDirection, keymap->direction, num_layouts);
474 rtl = g_newa (gint, num_layouts);
475 for (i = 0; i < num_layouts; i++)
476 rtl[i] = 0;
477
478 min_keycode = xkb_keymap_min_keycode (keymap->xkb_keymap);
479 max_keycode = xkb_keymap_max_keycode (keymap->xkb_keymap);
480 for (key = min_keycode; key < max_keycode; key++)
481 {
482 gint layouts, layout;
483
484 layouts = xkb_keymap_num_layouts_for_key (keymap->xkb_keymap, key);
485 for (layout = 0; layout < layouts; layout++)
486 {
487 const xkb_keysym_t *syms;
488 gint num_syms;
489 gint sym;
490
491 num_syms = xkb_keymap_key_get_syms_by_level (keymap->xkb_keymap, key, layout, 0, &syms);
492 for (sym = 0; sym < num_syms; sym++)
493 {
494 PangoDirection dir;
495
496 dir = pango_unichar_direction (xkb_keysym_to_utf32 (syms[sym]));
497 switch (dir)
498 {
499 case PANGO_DIRECTION_RTL:
500 rtl[layout]++;
501 break;
502 case PANGO_DIRECTION_LTR:
503 rtl[layout]--;
504 break;
505 default:
506 break;
507 }
508 }
509 }
510 }
511
512 have_rtl = have_ltr = FALSE;
513 for (i = 0; i < num_layouts; i++)
514 {
515 if (rtl[i] > 0)
516 {
517 keymap->direction[i] = PANGO_DIRECTION_RTL;
518 have_rtl = TRUE;
519 }
520 else
521 {
522 keymap->direction[i] = PANGO_DIRECTION_LTR;
523 have_ltr = TRUE;
524 }
525 }
526
527 if (have_rtl && have_ltr)
528 keymap->bidi = TRUE;
529}
530
531GdkKeymap *
532_gdk_wayland_keymap_new (void)
533{
534 GdkWaylandKeymap *keymap;
535 struct xkb_context *context;
536 struct xkb_rule_names names;
537
538 keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL);
539
540 context = xkb_context_new (0);
541
542 names.rules = "evdev";
543 names.model = "pc105";
544 names.layout = "us";
545 names.variant = "";
546 names.options = "";
547 keymap->xkb_keymap = xkb_keymap_new_from_names (context, &names, 0);
548 keymap->xkb_state = xkb_state_new (keymap->xkb_keymap);
549 xkb_context_unref (context);
550
551 update_direction (keymap);
552
553 return GDK_KEYMAP (keymap);
554}
555
556#ifdef G_ENABLE_DEBUG
557static void
558print_modifiers (struct xkb_keymap *keymap)
559{
560 int i, j;
561 uint32_t real;
562 struct xkb_state *state;
563
564 g_print ("modifiers:\n");
565 for (i = 0; i < xkb_keymap_num_mods (keymap); i++)
566 g_print ("%s ", xkb_keymap_mod_get_name (keymap, i));
567 g_print ("\n\n");
568
569 g_print ("modifier mapping\n");
570 state = xkb_state_new (keymap);
571 for (i = 0; i < 8; i++)
572 {
573 gboolean need_arrow = TRUE;
574 g_print ("%s ", xkb_keymap_mod_get_name (keymap, i));
575 for (j = 8; j < xkb_keymap_num_mods (keymap); j++)
576 {
577 xkb_state_update_mask (state, 1 << j, 0, 0, 0, 0, 0);
578 real = xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE);
579 if (real & (1 << i))
580 {
581 if (need_arrow)
582 {
583 g_print ("-> ");
584 need_arrow = FALSE;
585 }
586 g_print ("%s ", xkb_keymap_mod_get_name (keymap, j));
587 }
588 }
589 g_print ("\n");
590 }
591
592 xkb_state_unref (state);
593}
594#endif
595
596void
597_gdk_wayland_keymap_update_from_fd (GdkKeymap *keymap,
598 uint32_t format,
599 uint32_t fd,
600 uint32_t size)
601{
602 GdkWaylandKeymap *keymap_wayland = GDK_WAYLAND_KEYMAP (keymap);
603 struct xkb_context *context;
604 struct xkb_keymap *xkb_keymap;
605 char *map_str;
606
607 context = xkb_context_new (0);
608
609 map_str = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
610 if (map_str == MAP_FAILED)
611 {
612 close(fd);
613 return;
614 }
615
616 GDK_NOTE(INPUT, g_print ("keymap:\n%s\n", map_str));
617
618 xkb_keymap = xkb_keymap_new_from_string (context, map_str, format, 0);
619 munmap (map_str, size);
620 close (fd);
621
622 if (!xkb_keymap)
623 {
624 g_warning ("Got invalid keymap from compositor, keeping previous/default one");
625 xkb_context_unref (context);
626 return;
627 }
628
629 GDK_NOTE(INPUT, print_modifiers (xkb_keymap));
630
631 xkb_keymap_unref (keymap_wayland->xkb_keymap);
632 keymap_wayland->xkb_keymap = xkb_keymap;
633
634 xkb_state_unref (keymap_wayland->xkb_state);
635 keymap_wayland->xkb_state = xkb_state_new (keymap_wayland->xkb_keymap);
636
637 xkb_context_unref (context);
638
639 update_direction (keymap_wayland);
640}
641
642struct xkb_keymap *
643_gdk_wayland_keymap_get_xkb_keymap (GdkKeymap *keymap)
644{
645 return GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
646}
647
648struct xkb_state *
649_gdk_wayland_keymap_get_xkb_state (GdkKeymap *keymap)
650{
651 return GDK_WAYLAND_KEYMAP (keymap)->xkb_state;
652}
653
654gboolean
655_gdk_wayland_keymap_key_is_modifier (GdkKeymap *keymap,
656 guint keycode)
657{
658 struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
659 struct xkb_state *xkb_state;
660 gboolean is_modifier;
661
662 is_modifier = FALSE;
663
664 xkb_state = xkb_state_new (xkb_keymap);
665
666 if (xkb_state_update_key (xkb_state, keycode, XKB_KEY_DOWN) & XKB_STATE_MODS_EFFECTIVE)
667 is_modifier = TRUE;
668
669 xkb_state_unref (xkb_state);
670
671 return is_modifier;
672}
673