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 "gdk-private.h" |
40 | #include "gdkkeysprivate.h" |
41 | |
42 | #include <xkbcommon/xkbcommon.h> |
43 | |
44 | typedef struct _GdkWaylandKeymap GdkWaylandKeymap; |
45 | typedef struct _GdkWaylandKeymapClass GdkWaylandKeymapClass; |
46 | |
47 | struct _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 | |
58 | struct _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 | |
67 | GType _gdk_wayland_keymap_get_type (void); |
68 | |
69 | G_DEFINE_TYPE (GdkWaylandKeymap, _gdk_wayland_keymap, GDK_TYPE_KEYMAP) |
70 | |
71 | static void |
72 | gdk_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 | |
83 | static PangoDirection |
84 | gdk_wayland_keymap_get_direction (GdkKeymap *keymap) |
85 | { |
86 | GdkWaylandKeymap *keymap_wayland = GDK_WAYLAND_KEYMAP (keymap); |
87 | int 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 | |
98 | static gboolean |
99 | gdk_wayland_keymap_have_bidi_layouts (GdkKeymap *keymap) |
100 | { |
101 | GdkWaylandKeymap *keymap_wayland = GDK_WAYLAND_KEYMAP (keymap); |
102 | |
103 | return keymap_wayland->bidi; |
104 | } |
105 | |
106 | static gboolean |
107 | gdk_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 | |
113 | static gboolean |
114 | gdk_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 | |
120 | static gboolean |
121 | gdk_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 | |
127 | static gboolean |
128 | gdk_wayland_keymap_get_entries_for_keyval (GdkKeymap *keymap, |
129 | guint keyval, |
130 | GArray *retval) |
131 | { |
132 | struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap; |
133 | guint keycode; |
134 | xkb_keycode_t min_keycode, max_keycode; |
135 | guint len = retval->len; |
136 | |
137 | min_keycode = xkb_keymap_min_keycode (xkb_keymap); |
138 | max_keycode = xkb_keymap_max_keycode (xkb_keymap); |
139 | for (keycode = min_keycode; keycode < max_keycode; keycode++) |
140 | { |
141 | int num_layouts, layout; |
142 | num_layouts = xkb_keymap_num_layouts_for_key (xkb_keymap, keycode); |
143 | for (layout = 0; layout < num_layouts; layout++) |
144 | { |
145 | int num_levels, level; |
146 | num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, keycode, layout); |
147 | for (level = 0; level < num_levels; level++) |
148 | { |
149 | const xkb_keysym_t *syms; |
150 | int num_syms, sym; |
151 | num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, keycode, layout, level, &syms); |
152 | for (sym = 0; sym < num_syms; sym++) |
153 | { |
154 | if (syms[sym] == keyval) |
155 | { |
156 | GdkKeymapKey key; |
157 | |
158 | key.keycode = keycode; |
159 | key.group = layout; |
160 | key.level = level; |
161 | |
162 | g_array_append_val (retval, key); |
163 | } |
164 | } |
165 | } |
166 | } |
167 | } |
168 | |
169 | return retval->len > len; |
170 | } |
171 | |
172 | static gboolean |
173 | gdk_wayland_keymap_get_entries_for_keycode (GdkKeymap *keymap, |
174 | guint hardware_keycode, |
175 | GdkKeymapKey **keys, |
176 | guint **keyvals, |
177 | int *n_entries) |
178 | { |
179 | struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap; |
180 | int num_layouts, layout; |
181 | int num_entries; |
182 | int i; |
183 | |
184 | num_layouts = xkb_keymap_num_layouts_for_key (xkb_keymap, hardware_keycode); |
185 | |
186 | num_entries = 0; |
187 | for (layout = 0; layout < num_layouts; layout++) |
188 | num_entries += xkb_keymap_num_levels_for_key (xkb_keymap, hardware_keycode, layout); |
189 | |
190 | if (n_entries) |
191 | *n_entries = num_entries; |
192 | if (keys) |
193 | *keys = g_new0 (GdkKeymapKey, num_entries); |
194 | if (keyvals) |
195 | *keyvals = g_new0 (guint, num_entries); |
196 | |
197 | i = 0; |
198 | for (layout = 0; layout < num_layouts; layout++) |
199 | { |
200 | int num_levels, level; |
201 | num_levels = xkb_keymap_num_levels_for_key (xkb_keymap, hardware_keycode, layout); |
202 | for (level = 0; level < num_levels; level++) |
203 | { |
204 | const xkb_keysym_t *syms; |
205 | int num_syms; |
206 | num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, hardware_keycode, layout, 0, &syms); |
207 | if (keys) |
208 | { |
209 | (*keys)[i].keycode = hardware_keycode; |
210 | (*keys)[i].group = layout; |
211 | (*keys)[i].level = level; |
212 | } |
213 | if (keyvals && num_syms > 0) |
214 | (*keyvals)[i] = syms[0]; |
215 | |
216 | i++; |
217 | } |
218 | } |
219 | |
220 | return num_entries > 0; |
221 | } |
222 | |
223 | static guint |
224 | gdk_wayland_keymap_lookup_key (GdkKeymap *keymap, |
225 | const GdkKeymapKey *key) |
226 | { |
227 | struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap; |
228 | const xkb_keysym_t *syms; |
229 | int num_syms; |
230 | |
231 | num_syms = xkb_keymap_key_get_syms_by_level (xkb_keymap, |
232 | key->keycode, |
233 | key->group, |
234 | key->level, |
235 | &syms); |
236 | if (num_syms > 0) |
237 | return syms[0]; |
238 | else |
239 | return XKB_KEY_NoSymbol; |
240 | } |
241 | |
242 | static guint32 |
243 | get_xkb_modifiers (struct xkb_keymap *xkb_keymap, |
244 | GdkModifierType state) |
245 | { |
246 | guint32 mods = 0; |
247 | |
248 | if (state & GDK_SHIFT_MASK) |
249 | mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_SHIFT); |
250 | if (state & GDK_LOCK_MASK) |
251 | mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CAPS); |
252 | if (state & GDK_CONTROL_MASK) |
253 | mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CTRL); |
254 | if (state & GDK_ALT_MASK) |
255 | mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_ALT); |
256 | if (state & GDK_SUPER_MASK) |
257 | mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Super" ); |
258 | if (state & GDK_HYPER_MASK) |
259 | mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Hyper" ); |
260 | if (state & GDK_META_MASK) |
261 | mods |= 1 << xkb_keymap_mod_get_index (xkb_keymap, "Meta" ); |
262 | |
263 | return mods; |
264 | } |
265 | |
266 | static GdkModifierType |
267 | get_gdk_modifiers (struct xkb_keymap *xkb_keymap, |
268 | guint32 mods) |
269 | { |
270 | GdkModifierType state = 0; |
271 | |
272 | if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_SHIFT))) |
273 | state |= GDK_SHIFT_MASK; |
274 | if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CAPS))) |
275 | state |= GDK_LOCK_MASK; |
276 | if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_CTRL))) |
277 | state |= GDK_CONTROL_MASK; |
278 | if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, XKB_MOD_NAME_ALT))) |
279 | state |= GDK_ALT_MASK; |
280 | if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Super" ))) |
281 | state |= GDK_SUPER_MASK; |
282 | if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Hyper" ))) |
283 | state |= GDK_HYPER_MASK; |
284 | /* GTK treats MOD1 as a synonym for Alt, and does not expect it to |
285 | * be mapped around, so we should avoid adding GDK_META_MASK if MOD1 |
286 | * is already included to avoid confusing GTK and applications that |
287 | * rely on that behavior. |
288 | */ |
289 | if (mods & (1 << xkb_keymap_mod_get_index (xkb_keymap, "Meta" )) && |
290 | (state & GDK_ALT_MASK) == 0) |
291 | state |= GDK_META_MASK; |
292 | |
293 | return state; |
294 | } |
295 | |
296 | GdkModifierType |
297 | gdk_wayland_keymap_get_gdk_modifiers (GdkKeymap *keymap, |
298 | guint32 mods) |
299 | { |
300 | struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap; |
301 | |
302 | return get_gdk_modifiers (xkb_keymap, mods); |
303 | } |
304 | |
305 | static gboolean |
306 | gdk_wayland_keymap_translate_keyboard_state (GdkKeymap *keymap, |
307 | guint hardware_keycode, |
308 | GdkModifierType state, |
309 | int group, |
310 | guint *keyval, |
311 | int *effective_group, |
312 | int *effective_level, |
313 | GdkModifierType *consumed_modifiers) |
314 | { |
315 | struct xkb_keymap *xkb_keymap; |
316 | struct xkb_state *xkb_state; |
317 | guint32 modifiers; |
318 | guint32 consumed; |
319 | xkb_layout_index_t layout; |
320 | xkb_level_index_t level; |
321 | xkb_keysym_t sym; |
322 | |
323 | g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); |
324 | g_return_val_if_fail (group < 4, FALSE); |
325 | |
326 | xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap; |
327 | |
328 | modifiers = get_xkb_modifiers (xkb_keymap, state); |
329 | |
330 | xkb_state = xkb_state_new (xkb_keymap); |
331 | |
332 | xkb_state_update_mask (xkb_state, modifiers, 0, 0, group, 0, 0); |
333 | |
334 | layout = xkb_state_key_get_layout (xkb_state, hardware_keycode); |
335 | level = xkb_state_key_get_level (xkb_state, hardware_keycode, layout); |
336 | sym = xkb_state_key_get_one_sym (xkb_state, hardware_keycode); |
337 | consumed = modifiers & ~xkb_state_mod_mask_remove_consumed (xkb_state, hardware_keycode, modifiers); |
338 | |
339 | xkb_state_unref (xkb_state); |
340 | |
341 | if (keyval) |
342 | *keyval = sym; |
343 | if (effective_group) |
344 | *effective_group = layout; |
345 | if (effective_level) |
346 | *effective_level = level; |
347 | if (consumed_modifiers) |
348 | *consumed_modifiers = get_gdk_modifiers (xkb_keymap, consumed); |
349 | |
350 | return (sym != XKB_KEY_NoSymbol); |
351 | } |
352 | |
353 | static guint |
354 | gdk_wayland_keymap_get_modifier_state (GdkKeymap *keymap) |
355 | { |
356 | struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap; |
357 | struct xkb_state *xkb_state = GDK_WAYLAND_KEYMAP (keymap)->xkb_state; |
358 | xkb_mod_mask_t mods; |
359 | |
360 | mods = xkb_state_serialize_mods (xkb_state, XKB_STATE_MODS_EFFECTIVE); |
361 | |
362 | return get_gdk_modifiers (xkb_keymap, mods); |
363 | } |
364 | |
365 | static void |
366 | _gdk_wayland_keymap_class_init (GdkWaylandKeymapClass *klass) |
367 | { |
368 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
369 | GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass); |
370 | |
371 | object_class->finalize = gdk_wayland_keymap_finalize; |
372 | |
373 | keymap_class->get_direction = gdk_wayland_keymap_get_direction; |
374 | keymap_class->have_bidi_layouts = gdk_wayland_keymap_have_bidi_layouts; |
375 | keymap_class->get_caps_lock_state = gdk_wayland_keymap_get_caps_lock_state; |
376 | keymap_class->get_num_lock_state = gdk_wayland_keymap_get_num_lock_state; |
377 | keymap_class->get_scroll_lock_state = gdk_wayland_keymap_get_scroll_lock_state; |
378 | keymap_class->get_entries_for_keyval = gdk_wayland_keymap_get_entries_for_keyval; |
379 | keymap_class->get_entries_for_keycode = gdk_wayland_keymap_get_entries_for_keycode; |
380 | keymap_class->lookup_key = gdk_wayland_keymap_lookup_key; |
381 | keymap_class->translate_keyboard_state = gdk_wayland_keymap_translate_keyboard_state; |
382 | keymap_class->get_modifier_state = gdk_wayland_keymap_get_modifier_state; |
383 | } |
384 | |
385 | static void |
386 | _gdk_wayland_keymap_init (GdkWaylandKeymap *keymap) |
387 | { |
388 | } |
389 | |
390 | static void |
391 | update_direction (GdkWaylandKeymap *keymap) |
392 | { |
393 | int num_layouts; |
394 | int i; |
395 | int *rtl; |
396 | xkb_keycode_t min_keycode, max_keycode; |
397 | guint key; |
398 | gboolean have_rtl, have_ltr; |
399 | |
400 | num_layouts = xkb_keymap_num_layouts (keymap->xkb_keymap); |
401 | |
402 | keymap->direction = g_renew (PangoDirection, keymap->direction, num_layouts); |
403 | rtl = g_newa (int, num_layouts); |
404 | for (i = 0; i < num_layouts; i++) |
405 | rtl[i] = 0; |
406 | |
407 | min_keycode = xkb_keymap_min_keycode (keymap->xkb_keymap); |
408 | max_keycode = xkb_keymap_max_keycode (keymap->xkb_keymap); |
409 | for (key = min_keycode; key < max_keycode; key++) |
410 | { |
411 | int layouts, layout; |
412 | |
413 | layouts = xkb_keymap_num_layouts_for_key (keymap->xkb_keymap, key); |
414 | g_assert (layouts <= num_layouts); |
415 | for (layout = 0; layout < layouts; layout++) |
416 | { |
417 | const xkb_keysym_t *syms; |
418 | int num_syms; |
419 | int sym; |
420 | |
421 | num_syms = xkb_keymap_key_get_syms_by_level (keymap->xkb_keymap, key, layout, 0, &syms); |
422 | for (sym = 0; sym < num_syms; sym++) |
423 | { |
424 | PangoDirection dir; |
425 | |
426 | dir = gdk_unichar_direction (xkb_keysym_to_utf32 (syms[sym])); |
427 | switch (dir) |
428 | { |
429 | case PANGO_DIRECTION_RTL: |
430 | rtl[layout]++; |
431 | break; |
432 | case PANGO_DIRECTION_LTR: |
433 | rtl[layout]--; |
434 | break; |
435 | case PANGO_DIRECTION_TTB_LTR: |
436 | case PANGO_DIRECTION_TTB_RTL: |
437 | case PANGO_DIRECTION_WEAK_LTR: |
438 | case PANGO_DIRECTION_WEAK_RTL: |
439 | case PANGO_DIRECTION_NEUTRAL: |
440 | default: |
441 | break; |
442 | } |
443 | } |
444 | } |
445 | } |
446 | |
447 | have_rtl = have_ltr = FALSE; |
448 | for (i = 0; i < num_layouts; i++) |
449 | { |
450 | if (rtl[i] > 0) |
451 | { |
452 | keymap->direction[i] = PANGO_DIRECTION_RTL; |
453 | have_rtl = TRUE; |
454 | } |
455 | else |
456 | { |
457 | keymap->direction[i] = PANGO_DIRECTION_LTR; |
458 | have_ltr = TRUE; |
459 | } |
460 | } |
461 | |
462 | if (have_rtl && have_ltr) |
463 | keymap->bidi = TRUE; |
464 | } |
465 | |
466 | GdkKeymap * |
467 | _gdk_wayland_keymap_new (GdkDisplay *display) |
468 | { |
469 | GdkWaylandKeymap *keymap; |
470 | struct xkb_context *context; |
471 | struct xkb_rule_names names; |
472 | |
473 | keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL); |
474 | GDK_KEYMAP (keymap)->display = display; |
475 | |
476 | context = xkb_context_new (0); |
477 | |
478 | names.rules = "evdev" ; |
479 | names.model = "pc105" ; |
480 | names.layout = "us" ; |
481 | names.variant = "" ; |
482 | names.options = "" ; |
483 | keymap->xkb_keymap = xkb_keymap_new_from_names (context, &names, 0); |
484 | keymap->xkb_state = xkb_state_new (keymap->xkb_keymap); |
485 | xkb_context_unref (context); |
486 | |
487 | update_direction (keymap); |
488 | |
489 | return GDK_KEYMAP (keymap); |
490 | } |
491 | |
492 | #ifdef G_ENABLE_DEBUG |
493 | static void |
494 | print_modifiers (struct xkb_keymap *keymap) |
495 | { |
496 | int i, j; |
497 | uint32_t real; |
498 | struct xkb_state *state; |
499 | |
500 | g_print ("modifiers:\n" ); |
501 | for (i = 0; i < xkb_keymap_num_mods (keymap); i++) |
502 | g_print ("%s " , xkb_keymap_mod_get_name (keymap, i)); |
503 | g_print ("\n\n" ); |
504 | |
505 | g_print ("modifier mapping\n" ); |
506 | state = xkb_state_new (keymap); |
507 | for (i = 0; i < 8; i++) |
508 | { |
509 | gboolean need_arrow = TRUE; |
510 | g_print ("%s " , xkb_keymap_mod_get_name (keymap, i)); |
511 | for (j = 8; j < xkb_keymap_num_mods (keymap); j++) |
512 | { |
513 | xkb_state_update_mask (state, 1 << j, 0, 0, 0, 0, 0); |
514 | real = xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE); |
515 | if (real & (1 << i)) |
516 | { |
517 | if (need_arrow) |
518 | { |
519 | g_print ("-> " ); |
520 | need_arrow = FALSE; |
521 | } |
522 | g_print ("%s " , xkb_keymap_mod_get_name (keymap, j)); |
523 | } |
524 | } |
525 | g_print ("\n" ); |
526 | } |
527 | |
528 | xkb_state_unref (state); |
529 | } |
530 | #endif |
531 | |
532 | void |
533 | _gdk_wayland_keymap_update_from_fd (GdkKeymap *keymap, |
534 | uint32_t format, |
535 | uint32_t fd, |
536 | uint32_t size) |
537 | { |
538 | GdkWaylandKeymap *keymap_wayland = GDK_WAYLAND_KEYMAP (keymap); |
539 | struct xkb_context *context; |
540 | struct xkb_keymap *xkb_keymap; |
541 | char *map_str; |
542 | |
543 | context = xkb_context_new (0); |
544 | |
545 | map_str = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); |
546 | if (map_str == MAP_FAILED) |
547 | { |
548 | close(fd); |
549 | return; |
550 | } |
551 | |
552 | GDK_DISPLAY_NOTE (keymap->display, INPUT, g_message ("keymap:\n%s" , map_str)); |
553 | |
554 | xkb_keymap = xkb_keymap_new_from_string (context, map_str, format, 0); |
555 | munmap (map_str, size); |
556 | close (fd); |
557 | |
558 | if (!xkb_keymap) |
559 | { |
560 | g_warning ("Got invalid keymap from compositor, keeping previous/default one" ); |
561 | xkb_context_unref (context); |
562 | return; |
563 | } |
564 | |
565 | GDK_DISPLAY_NOTE (keymap->display, INPUT, print_modifiers (xkb_keymap)); |
566 | |
567 | xkb_keymap_unref (keymap_wayland->xkb_keymap); |
568 | keymap_wayland->xkb_keymap = xkb_keymap; |
569 | |
570 | xkb_state_unref (keymap_wayland->xkb_state); |
571 | keymap_wayland->xkb_state = xkb_state_new (keymap_wayland->xkb_keymap); |
572 | |
573 | xkb_context_unref (context); |
574 | |
575 | update_direction (keymap_wayland); |
576 | } |
577 | |
578 | struct xkb_keymap * |
579 | _gdk_wayland_keymap_get_xkb_keymap (GdkKeymap *keymap) |
580 | { |
581 | return GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap; |
582 | } |
583 | |
584 | struct xkb_state * |
585 | _gdk_wayland_keymap_get_xkb_state (GdkKeymap *keymap) |
586 | { |
587 | return GDK_WAYLAND_KEYMAP (keymap)->xkb_state; |
588 | } |
589 | |
590 | gboolean |
591 | _gdk_wayland_keymap_key_is_modifier (GdkKeymap *keymap, |
592 | guint keycode) |
593 | { |
594 | struct xkb_keymap *xkb_keymap = GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap; |
595 | struct xkb_state *xkb_state; |
596 | gboolean is_modifier; |
597 | |
598 | is_modifier = FALSE; |
599 | |
600 | xkb_state = xkb_state_new (xkb_keymap); |
601 | |
602 | if (xkb_state_update_key (xkb_state, keycode, XKB_KEY_DOWN) & XKB_STATE_MODS_EFFECTIVE) |
603 | is_modifier = TRUE; |
604 | |
605 | xkb_state_unref (xkb_state); |
606 | |
607 | return is_modifier; |
608 | } |
609 | |