]> Pileus Git - ~andy/gtk/blob - gdk/wayland/gdkkeys-wayland.c
wayland: Protocol update: wl_shell_surface_resize and _move take serials
[~andy/gtk] / gdk / wayland / gdkkeys-wayland.c
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
34 #include "gdk.h"
35 #include "gdkwayland.h"
36
37 #include "gdkprivate-wayland.h"
38 #include "gdkinternals.h"
39 #include "gdkdisplay-wayland.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   GdkModifierType modmap[8];
51   struct xkb_desc *xkb;
52 };
53
54 struct _GdkWaylandKeymapClass
55 {
56   GdkKeymapClass parent_class;
57 };
58
59 #define GDK_TYPE_WAYLAND_KEYMAP          (_gdk_wayland_keymap_get_type ())
60 #define GDK_WAYLAND_KEYMAP(object)       (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_KEYMAP, GdkWaylandKeymap))
61 #define GDK_IS_WAYLAND_KEYMAP(object)    (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_KEYMAP))
62
63 G_DEFINE_TYPE (GdkWaylandKeymap, _gdk_wayland_keymap, GDK_TYPE_KEYMAP)
64
65 static void
66 gdk_wayland_keymap_finalize (GObject *object)
67 {
68   G_OBJECT_CLASS (_gdk_wayland_keymap_parent_class)->finalize (object);
69 }
70
71 static PangoDirection
72 gdk_wayland_keymap_get_direction (GdkKeymap *keymap)
73 {
74     return PANGO_DIRECTION_NEUTRAL;
75 }
76
77 static gboolean
78 gdk_wayland_keymap_have_bidi_layouts (GdkKeymap *keymap)
79 {
80     return FALSE;
81 }
82
83 static gboolean
84 gdk_wayland_keymap_get_caps_lock_state (GdkKeymap *keymap)
85 {
86   return FALSE;
87 }
88
89 static gboolean
90 gdk_wayland_keymap_get_num_lock_state (GdkKeymap *keymap)
91 {
92   return FALSE;
93 }
94
95 static gboolean
96 gdk_wayland_keymap_get_entries_for_keyval (GdkKeymap     *keymap,
97                                            guint          keyval,
98                                            GdkKeymapKey **keys,
99                                            gint          *n_keys)
100 {
101 #if 0
102   GArray *retval;
103   uint32_t keycode;
104   struct xkb_desc *xkb;
105
106   xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb;
107   keycode = xkb->min_key_code;
108
109   retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
110
111   for (keycode = xkb->min_key_code; keycode <= xkb->max_key_code; keycode++)
112     {
113       gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode);
114
115       gint group = 0;
116       gint level = 0;
117       gint total_syms = XkbKeyNumSyms (xkb, keycode);
118       gint i = 0;
119       uint32_t *entry;
120
121       /* entry is an array with all syms for group 0, all
122        * syms for group 1, etc. and for each group the
123        * shift level syms are in order
124        */
125       entry = XkbKeySymsPtr (xkb, keycode);
126
127       for (i = 0; i < total_syms; i++)
128         {
129           /* check out our cool loop invariant */
130           g_assert (i == (group * max_shift_levels + level));
131
132           if (entry[i] == keyval)
133             {
134               /* Found a match */
135               GdkKeymapKey key;
136
137               key.keycode = keycode;
138               key.group = group;
139               key.level = level;
140
141               g_array_append_val (retval, key);
142
143               g_assert (XkbKeySymEntry (xkb, keycode, level, group) ==
144                         keyval);
145             }
146
147           level++;
148
149           if (level == max_shift_levels)
150             {
151               level = 0;
152               group++;
153             }
154         }
155     }
156
157   *n_keys = retval->len;
158   *keys = (GdkKeymapKey *) g_array_free (retval, FALSE);
159
160   return *n_keys > 0;
161 #endif
162   return FALSE;
163 }
164
165 static gboolean
166 gdk_wayland_keymap_get_entries_for_keycode (GdkKeymap     *keymap,
167                                             guint          hardware_keycode,
168                                             GdkKeymapKey **keys,
169                                             guint        **keyvals,
170                                             gint          *n_entries)
171 {
172 #if 0
173   GArray *key_array;
174   GArray *keyval_array;
175   struct xkb_desc *xkb;
176   gint max_shift_levels;
177   gint group = 0;
178   gint level = 0;
179   gint total_syms;
180   gint i;
181   uint32_t *entry;
182
183   g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
184   g_return_val_if_fail (n_entries != NULL, FALSE);
185
186   xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb;
187
188   if (hardware_keycode < xkb->min_key_code ||
189       hardware_keycode > xkb->max_key_code)
190     {
191       if (keys)
192         *keys = NULL;
193       if (keyvals)
194         *keyvals = NULL;
195
196       *n_entries = 0;
197       return FALSE;
198     }
199
200   if (keys)
201     key_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
202   else
203     key_array = NULL;
204
205   if (keyvals)
206     keyval_array = g_array_new (FALSE, FALSE, sizeof (guint));
207   else
208     keyval_array = NULL;
209
210   /* See sec 15.3.4 in XKB docs */
211   max_shift_levels = XkbKeyGroupsWidth (xkb, hardware_keycode);
212   total_syms = XkbKeyNumSyms (xkb, hardware_keycode);
213
214   /* entry is an array with all syms for group 0, all
215    * syms for group 1, etc. and for each group the
216    * shift level syms are in order
217    */
218   entry = XkbKeySymsPtr (xkb, hardware_keycode);
219
220   for (i = 0; i < total_syms; i++)
221     {
222       /* check out our cool loop invariant */
223       g_assert (i == (group * max_shift_levels + level));
224
225       if (key_array)
226         {
227           GdkKeymapKey key;
228
229           key.keycode = hardware_keycode;
230           key.group = group;
231           key.level = level;
232
233           g_array_append_val (key_array, key);
234         }
235
236       if (keyval_array)
237         g_array_append_val (keyval_array, entry[i]);
238
239       ++level;
240
241       if (level == max_shift_levels)
242         {
243           level = 0;
244           ++group;
245         }
246     }
247
248   *n_entries = 0;
249
250   if (keys)
251     {
252       *n_entries = key_array->len;
253       *keys = (GdkKeymapKey*) g_array_free (key_array, FALSE);
254     }
255
256   if (keyvals)
257     {
258       *n_entries = keyval_array->len;
259       *keyvals = (guint*) g_array_free (keyval_array, FALSE);
260     }
261
262   return *n_entries > 0;
263 #endif
264   return FALSE;
265 }
266
267 static guint
268 gdk_wayland_keymap_lookup_key (GdkKeymap          *keymap,
269                                const GdkKeymapKey *key)
270 {
271 #if 0
272   struct xkb_desc *xkb;
273
274   xkb = GDK_WAYLAND_KEYMAP (keymap)->xkb;
275
276   return XkbKeySymEntry (xkb, key->keycode, key->level, key->group);
277 #endif
278   return 0;
279 }
280
281 #if 0
282 /* This is copied straight from XFree86 Xlib, to:
283  *  - add the group and level return.
284  *  - change the interpretation of mods_rtrn as described
285  *    in the docs for gdk_keymap_translate_keyboard_state()
286  * It's unchanged for ease of diff against the Xlib sources; don't
287  * reformat it.
288  */
289 static int
290 MyEnhancedXkbTranslateKeyCode(struct xkb_desc *       xkb,
291                               KeyCode                 key,
292                               unsigned int            mods,
293                               unsigned int *          mods_rtrn,
294                               uint32_t *              keysym_rtrn,
295                               int *                   group_rtrn,
296                               int *                   level_rtrn)
297 {
298     struct xkb_key_type *type;
299     int col,nKeyGroups;
300     unsigned preserve,effectiveGroup;
301     uint32_t *syms;
302
303     if (mods_rtrn!=NULL)
304         *mods_rtrn = 0;
305
306     nKeyGroups= XkbKeyNumGroups(xkb,key);
307     if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) {
308         if (keysym_rtrn!=NULL)
309             *keysym_rtrn = 0;
310         return 0;
311     }
312
313     syms = XkbKeySymsPtr(xkb,key);
314
315     /* find the offset of the effective group */
316     col = 0;
317     effectiveGroup= XkbGroupForCoreState(mods);
318     if ( effectiveGroup>=nKeyGroups ) {
319         unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
320         switch (XkbOutOfRangeGroupAction(groupInfo)) {
321             default:
322                 effectiveGroup %= nKeyGroups;
323                 break;
324             case XkbClampIntoRange:
325                 effectiveGroup = nKeyGroups-1;
326                 break;
327             case XkbRedirectIntoRange:
328                 effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
329                 if (effectiveGroup>=nKeyGroups)
330                     effectiveGroup= 0;
331                 break;
332         }
333     }
334     col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
335     type = XkbKeyKeyType(xkb,key,effectiveGroup);
336
337     preserve= 0;
338     if (type->map) { /* find the column (shift level) within the group */
339         register int i;
340         struct xkb_kt_map_entry *entry;
341         /* ---- Begin section modified for GDK  ---- */
342         int found = 0;
343
344         for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
345             if (mods_rtrn) {
346                 int bits = 0;
347                 unsigned long tmp = entry->mods.mask;
348                 while (tmp) {
349                     if ((tmp & 1) == 1)
350                         bits++;
351                     tmp >>= 1;
352                 }
353                 /* We always add one-modifiers levels to mods_rtrn since
354                  * they can't wipe out bits in the state unless the
355                  * level would be triggered. But return other modifiers
356                  *
357                  */
358                 if (bits == 1 || (mods&type->mods.mask)==entry->mods.mask)
359                     *mods_rtrn |= entry->mods.mask;
360             }
361
362             if (!found&&entry->active&&((mods&type->mods.mask)==entry->mods.mask)) {
363                 col+= entry->level;
364                 if (type->preserve)
365                     preserve= type->preserve[i].mask;
366
367                 if (level_rtrn)
368                   *level_rtrn = entry->level;
369
370                 found = 1;
371             }
372         }
373         /* ---- End section modified for GDK ---- */
374     }
375
376     if (keysym_rtrn!=NULL)
377         *keysym_rtrn= syms[col];
378     if (mods_rtrn) {
379         /* ---- Begin section modified for GDK  ---- */
380         *mods_rtrn &= ~preserve;
381         /* ---- End section modified for GDK ---- */
382
383         /* ---- Begin stuff GDK comments out of the original Xlib version ---- */
384         /* This is commented out because xkb_info is a private struct */
385
386 #if 0
387         /* The Motif VTS doesn't get the help callback called if help
388          * is bound to Shift+<whatever>, and it appears as though it
389          * is XkbTranslateKeyCode that is causing the problem.  The
390          * core X version of XTranslateKey always OR's in ShiftMask
391          * and LockMask for mods_rtrn, so this "fix" keeps this behavior
392          * and solves the VTS problem.
393          */
394         if ((xkb->dpy)&&(xkb->dpy->xkb_info)&&
395             (xkb->dpy->xkb_info->xlib_ctrls&XkbLC_AlwaysConsumeShiftAndLock)) {            *mods_rtrn|= (ShiftMask|LockMask);
396         }
397 #endif
398
399         /* ---- End stuff GDK comments out of the original Xlib version ---- */
400     }
401
402     /* ---- Begin stuff GDK adds to the original Xlib version ---- */
403
404     if (group_rtrn)
405       *group_rtrn = effectiveGroup;
406
407     /* ---- End stuff GDK adds to the original Xlib version ---- */
408
409     return (syms[col] != 0);
410 }
411 #endif
412
413 static gboolean
414 gdk_wayland_keymap_translate_keyboard_state (GdkKeymap       *keymap,
415                                              guint            hardware_keycode,
416                                              GdkModifierType  state,
417                                              gint             group,
418                                              guint           *keyval,
419                                              gint            *effective_group,
420                                              gint            *level,
421                                              GdkModifierType *consumed_modifiers)
422 {
423 #if 0
424   GdkWaylandKeymap *wayland_keymap;
425   uint32_t tmp_keyval = 0;
426   guint tmp_modifiers;
427   struct xkb_desc *xkb;
428
429   g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
430   g_return_val_if_fail (group < 4, FALSE);
431
432   wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
433   xkb = wayland_keymap->xkb;
434
435   if (keyval)
436     *keyval = 0;
437   if (effective_group)
438     *effective_group = 0;
439   if (level)
440     *level = 0;
441   if (consumed_modifiers)
442     *consumed_modifiers = 0;
443
444   if (hardware_keycode < xkb->min_key_code ||
445       hardware_keycode > xkb->max_key_code)
446     return FALSE;
447
448
449   /* replace bits 13 and 14 with the provided group */
450   state &= ~(1 << 13 | 1 << 14);
451   state |= group << 13;
452
453   MyEnhancedXkbTranslateKeyCode (xkb,
454                                  hardware_keycode,
455                                  state,
456                                  &tmp_modifiers,
457                                  &tmp_keyval,
458                                  effective_group,
459                                  level);
460
461   if (state & ~tmp_modifiers & XKB_COMMON_LOCK_MASK)
462     tmp_keyval = gdk_keyval_to_upper (tmp_keyval);
463
464   /* We need to augment the consumed modifiers with LockMask, since
465    * we handle that ourselves, and also with the group bits
466    */
467   tmp_modifiers |= XKB_COMMON_LOCK_MASK | 1 << 13 | 1 << 14;
468
469
470   if (consumed_modifiers)
471     *consumed_modifiers = tmp_modifiers;
472
473   if (keyval)
474     *keyval = tmp_keyval;
475
476   return tmp_keyval != 0;
477 #endif
478   return FALSE;
479 }
480
481 #if 0
482 static void
483 update_modmap (GdkWaylandKeymap *wayland_keymap)
484 {
485   static struct {
486     const gchar *name;
487     uint32_t atom;
488     GdkModifierType mask;
489   } vmods[] = {
490     { "Meta", 0, GDK_META_MASK },
491     { "Super", 0, GDK_SUPER_MASK },
492     { "Hyper", 0, GDK_HYPER_MASK },
493     { NULL, 0, 0 }
494   };
495
496   gint i, j, k;
497
498   if (!vmods[0].atom)
499     for (i = 0; vmods[i].name; i++)
500       vmods[i].atom = xkb_atom(vmods[i].name);
501
502   for (i = 0; i < 8; i++)
503     wayland_keymap->modmap[i] = 1 << i;
504
505   for (i = 0; i < XkbNumVirtualMods; i++)
506     {
507       for (j = 0; vmods[j].atom; j++)
508         {
509           if (wayland_keymap->xkb->names->vmods[i] == vmods[j].atom)
510             {
511               for (k = 0; k < 8; k++)
512                 {
513                   if (wayland_keymap->xkb->server->vmods[i] & (1 << k))
514                     wayland_keymap->modmap[k] |= vmods[j].mask;
515                 }
516             }
517         }
518     }
519 }
520 #endif
521
522 static void
523 gdk_wayland_keymap_add_virtual_modifiers (GdkKeymap       *keymap,
524                                           GdkModifierType *state)
525 {
526   GdkWaylandKeymap *wayland_keymap;
527   int i;
528
529   wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
530
531   for (i = 4; i < 8; i++)
532     {
533       if ((1 << i) & *state)
534         {
535           if (wayland_keymap->modmap[i] & GDK_SUPER_MASK)
536             *state |= GDK_SUPER_MASK;
537           if (wayland_keymap->modmap[i] & GDK_HYPER_MASK)
538             *state |= GDK_HYPER_MASK;
539           if (wayland_keymap->modmap[i] & GDK_META_MASK)
540             *state |= GDK_META_MASK;
541         }
542     }
543 }
544
545 static gboolean
546 gdk_wayland_keymap_map_virtual_modifiers (GdkKeymap       *keymap,
547                                           GdkModifierType *state)
548 {
549   const guint vmods[] = {
550     GDK_SUPER_MASK, GDK_HYPER_MASK, GDK_META_MASK
551   };
552   int i, j;
553   GdkWaylandKeymap *wayland_keymap;
554   gboolean retval = TRUE;
555
556   wayland_keymap = GDK_WAYLAND_KEYMAP (keymap);
557
558   for (j = 0; j < 3; j++)
559     {
560       if (*state & vmods[j])
561         {
562           for (i = 4; i < 8; i++)
563             {
564               if (wayland_keymap->modmap[i] & vmods[j])
565                 {
566                   if (*state & (1 << i))
567                     retval = FALSE;
568                   else
569                     *state |= 1 << i;
570                 }
571             }
572         }
573     }
574
575   return retval;
576 }
577
578 static void
579 _gdk_wayland_keymap_class_init (GdkWaylandKeymapClass *klass)
580 {
581   GObjectClass *object_class = G_OBJECT_CLASS (klass);
582   GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass);
583
584   object_class->finalize = gdk_wayland_keymap_finalize;
585
586   keymap_class->get_direction = gdk_wayland_keymap_get_direction;
587   keymap_class->have_bidi_layouts = gdk_wayland_keymap_have_bidi_layouts;
588   keymap_class->get_caps_lock_state = gdk_wayland_keymap_get_caps_lock_state;
589   keymap_class->get_num_lock_state = gdk_wayland_keymap_get_num_lock_state;
590   keymap_class->get_entries_for_keyval = gdk_wayland_keymap_get_entries_for_keyval;
591   keymap_class->get_entries_for_keycode = gdk_wayland_keymap_get_entries_for_keycode;
592   keymap_class->lookup_key = gdk_wayland_keymap_lookup_key;
593   keymap_class->translate_keyboard_state = gdk_wayland_keymap_translate_keyboard_state;
594   keymap_class->add_virtual_modifiers = gdk_wayland_keymap_add_virtual_modifiers;
595   keymap_class->map_virtual_modifiers = gdk_wayland_keymap_map_virtual_modifiers;
596 }
597
598 static void
599 _gdk_wayland_keymap_init (GdkWaylandKeymap *keymap)
600 {
601 }
602
603 #if 0
604 static void
605 update_keymaps (GdkWaylandKeymap *keymap)
606 {
607   struct xkb_desc *xkb = keymap->xkb;
608   gint keycode, total_syms, i, modifier;
609   uint32_t *entry;
610   guint mask;
611
612   for (keycode = xkb->min_key_code; keycode <= xkb->max_key_code; keycode++)
613     {
614       total_syms = XkbKeyNumSyms (xkb, keycode);
615
616       entry = XkbKeySymsPtr (xkb, keycode);
617       mask = 0;
618       for (i = 0; i < total_syms; i++)
619         {
620           switch (entry[i]) {
621           case GDK_KEY_Meta_L:
622           case GDK_KEY_Meta_R:
623             mask |= GDK_META_MASK;
624             break;
625           case GDK_KEY_Hyper_L:
626           case GDK_KEY_Hyper_R:
627             mask |= GDK_HYPER_MASK;
628             break;
629           case GDK_KEY_Super_L:
630           case GDK_KEY_Super_R:
631             mask |= GDK_SUPER_MASK;
632             break;
633           }
634         }
635
636       modifier = g_bit_nth_lsf(xkb->map->modmap[keycode], -1);
637       keymap->modmap[modifier] |= mask;
638     }
639 }
640 #endif
641
642 GdkKeymap *
643 _gdk_wayland_keymap_new (GdkDisplay *display)
644 {
645   GdkWaylandKeymap *keymap;
646   struct xkb_rule_names names;
647
648   keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL);
649   GDK_KEYMAP (keymap)->display = display;
650 #if 0
651
652   names.rules = "evdev";
653   names.model = "pc105";
654   names.layout = "us";
655   names.variant = "";
656   names.options = "";
657   keymap->xkb = xkb_compile_keymap_from_rules(&names);
658   update_modmap (keymap);
659   update_keymaps (keymap);
660 #endif
661   return GDK_KEYMAP (keymap);
662 }
663
664 struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap)
665 {
666   return GDK_WAYLAND_KEYMAP (keymap)->xkb;
667 }