1 /*
2  * Wayland Support
3  *
4  * Copyright (C) 2013 Intel Corporation
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19  * 02111-1307, USA.
20  */
21 
22 /*
23  * Copyright © 2010-2011 Intel Corporation
24  * Copyright © 2008-2011 Kristian Høgsberg
25  * Copyright © 2012 Collabora, Ltd.
26  *
27  * Permission to use, copy, modify, distribute, and sell this software and
28  * its documentation for any purpose is hereby granted without fee, provided
29  * that the above copyright notice appear in all copies and that both that
30  * copyright notice and this permission notice appear in supporting
31  * documentation, and that the name of the copyright holders not be used in
32  * advertising or publicity pertaining to distribution of the software
33  * without specific, written prior permission.  The copyright holders make
34  * no representations about the suitability of this software for any
35  * purpose.  It is provided "as is" without express or implied warranty.
36  *
37  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
38  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
39  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
40  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
41  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
42  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
43  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44  */
45 
46 /* The file is based on src/input.c from Weston */
47 
48 #include "config.h"
49 
50 #include <errno.h>
51 #include <glib.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <unistd.h>
55 
56 #include "backends/meta-backend-private.h"
57 #include "core/display-private.h"
58 #include "core/meta-anonymous-file.h"
59 #include "wayland/meta-wayland-private.h"
60 
61 #define GSD_KEYBOARD_SCHEMA "org.gnome.settings-daemon.peripherals.keyboard"
62 
63 G_DEFINE_TYPE (MetaWaylandKeyboard, meta_wayland_keyboard,
64                META_TYPE_WAYLAND_INPUT_DEVICE)
65 
66 static void meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard);
67 static void notify_modifiers (MetaWaylandKeyboard *keyboard);
68 
69 static void
unbind_resource(struct wl_resource * resource)70 unbind_resource (struct wl_resource *resource)
71 {
72   wl_list_remove (wl_resource_get_link (resource));
73 }
74 
75 static void
send_keymap(MetaWaylandKeyboard * keyboard,struct wl_resource * resource)76 send_keymap (MetaWaylandKeyboard *keyboard,
77              struct wl_resource  *resource)
78 {
79   MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
80   int fd;
81   size_t size;
82   MetaAnonymousFileMapmode mapmode;
83 
84   if (wl_resource_get_version (resource) < 7)
85     mapmode = META_ANONYMOUS_FILE_MAPMODE_SHARED;
86   else
87     mapmode = META_ANONYMOUS_FILE_MAPMODE_PRIVATE;
88 
89   fd = meta_anonymous_file_open_fd (xkb_info->keymap_rofile, mapmode);
90   size = meta_anonymous_file_size (xkb_info->keymap_rofile);
91 
92   if (fd == -1)
93     {
94       g_warning ("Creating a keymap file failed: %s", strerror (errno));
95       return;
96     }
97 
98   wl_keyboard_send_keymap (resource,
99                            WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
100                            fd, size);
101 
102   meta_anonymous_file_close_fd (fd);
103 }
104 
105 static void
inform_clients_of_new_keymap(MetaWaylandKeyboard * keyboard)106 inform_clients_of_new_keymap (MetaWaylandKeyboard *keyboard)
107 {
108   struct wl_resource *keyboard_resource;
109 
110   wl_resource_for_each (keyboard_resource, &keyboard->resource_list)
111     send_keymap (keyboard, keyboard_resource);
112   wl_resource_for_each (keyboard_resource, &keyboard->focus_resource_list)
113     send_keymap (keyboard, keyboard_resource);
114 }
115 
116 static void
meta_wayland_keyboard_take_keymap(MetaWaylandKeyboard * keyboard,struct xkb_keymap * keymap)117 meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
118 				   struct xkb_keymap   *keymap)
119 {
120   MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
121   char *keymap_string;
122   size_t keymap_size;
123 
124   if (keymap == NULL)
125     {
126       g_warning ("Attempting to set null keymap (compilation probably failed)");
127       return;
128     }
129 
130   xkb_keymap_unref (xkb_info->keymap);
131   xkb_info->keymap = xkb_keymap_ref (keymap);
132 
133   meta_wayland_keyboard_update_xkb_state (keyboard);
134 
135   keymap_string =
136     xkb_keymap_get_as_string (xkb_info->keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
137   if (!keymap_string)
138     {
139       g_warning ("Failed to get string version of keymap");
140       return;
141     }
142   keymap_size = strlen (keymap_string) + 1;
143 
144   g_clear_pointer (&xkb_info->keymap_rofile, meta_anonymous_file_free);
145   xkb_info->keymap_rofile =
146     meta_anonymous_file_new (keymap_size, (const uint8_t *) keymap_string);
147 
148   free (keymap_string);
149 
150   if (!xkb_info->keymap_rofile)
151     {
152       g_warning ("Failed to create anonymous file for keymap");
153       return;
154     }
155 
156   inform_clients_of_new_keymap (keyboard);
157 
158   notify_modifiers (keyboard);
159 }
160 
161 static xkb_mod_mask_t
kbd_a11y_apply_mask(MetaWaylandKeyboard * keyboard)162 kbd_a11y_apply_mask (MetaWaylandKeyboard *keyboard)
163 {
164   xkb_mod_mask_t latched, locked, depressed, group;
165   xkb_mod_mask_t update_mask = 0;
166 
167   depressed = xkb_state_serialize_mods(keyboard->xkb_info.state, XKB_STATE_DEPRESSED);
168   latched = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LATCHED);
169   locked = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LOCKED);
170   group = xkb_state_serialize_layout (keyboard->xkb_info.state, XKB_STATE_LAYOUT_EFFECTIVE);
171 
172   if ((latched & keyboard->kbd_a11y_latched_mods) != keyboard->kbd_a11y_latched_mods)
173     update_mask |= XKB_STATE_MODS_LATCHED;
174 
175   if ((locked & keyboard->kbd_a11y_locked_mods) != keyboard->kbd_a11y_locked_mods)
176     update_mask |= XKB_STATE_MODS_LOCKED;
177 
178   if (update_mask)
179     {
180       latched |= keyboard->kbd_a11y_latched_mods;
181       locked |= keyboard->kbd_a11y_locked_mods;
182       xkb_state_update_mask (keyboard->xkb_info.state, depressed, latched, locked, 0, 0, group);
183     }
184 
185   return update_mask;
186 }
187 
188 static void
on_keymap_changed(MetaBackend * backend,gpointer data)189 on_keymap_changed (MetaBackend *backend,
190                    gpointer     data)
191 {
192   MetaWaylandKeyboard *keyboard = data;
193 
194   meta_wayland_keyboard_take_keymap (keyboard, meta_backend_get_keymap (backend));
195 }
196 
197 static void
on_keymap_layout_group_changed(MetaBackend * backend,guint idx,gpointer data)198 on_keymap_layout_group_changed (MetaBackend *backend,
199                                 guint        idx,
200                                 gpointer     data)
201 {
202   MetaWaylandKeyboard *keyboard = data;
203   xkb_mod_mask_t depressed_mods;
204   xkb_mod_mask_t latched_mods;
205   xkb_mod_mask_t locked_mods;
206   struct xkb_state *state;
207 
208   state = keyboard->xkb_info.state;
209 
210   depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED);
211   latched_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED);
212   locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED);
213 
214   xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx);
215   kbd_a11y_apply_mask (keyboard);
216 
217   notify_modifiers (keyboard);
218 }
219 
220 static void
keyboard_handle_focus_surface_destroy(struct wl_listener * listener,void * data)221 keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
222 {
223   MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard,
224                                                    focus_surface_listener);
225 
226   meta_wayland_keyboard_set_focus (keyboard, NULL);
227 }
228 
229 static gboolean
meta_wayland_keyboard_broadcast_key(MetaWaylandKeyboard * keyboard,uint32_t time,uint32_t key,uint32_t state)230 meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard,
231                                      uint32_t             time,
232                                      uint32_t             key,
233                                      uint32_t             state)
234 {
235   struct wl_resource *resource;
236 
237   if (!wl_list_empty (&keyboard->focus_resource_list))
238     {
239       MetaWaylandInputDevice *input_device =
240         META_WAYLAND_INPUT_DEVICE (keyboard);
241       uint32_t serial;
242 
243       serial = meta_wayland_input_device_next_serial (input_device);
244 
245       if (state)
246         {
247           keyboard->key_down_serial = serial;
248           keyboard->key_down_keycode = key;
249         }
250       else
251         {
252           keyboard->key_up_serial = serial;
253           keyboard->key_up_keycode = key;
254         }
255 
256       wl_resource_for_each (resource, &keyboard->focus_resource_list)
257         wl_keyboard_send_key (resource, serial, time, key, state);
258     }
259 
260   /* Eat the key events if we have a focused surface. */
261   return (keyboard->focus_surface != NULL);
262 }
263 
264 static gboolean
notify_key(MetaWaylandKeyboard * keyboard,const ClutterEvent * event)265 notify_key (MetaWaylandKeyboard *keyboard,
266             const ClutterEvent  *event)
267 {
268   return keyboard->grab->interface->key (keyboard->grab, event);
269 }
270 
271 static xkb_mod_mask_t
add_vmod(xkb_mod_mask_t mask,xkb_mod_mask_t mod,xkb_mod_mask_t vmod,xkb_mod_mask_t * added)272 add_vmod (xkb_mod_mask_t mask,
273           xkb_mod_mask_t mod,
274           xkb_mod_mask_t vmod,
275           xkb_mod_mask_t *added)
276 {
277   if ((mask & mod) && !(mod & *added))
278     {
279       mask |= vmod;
280       *added |= mod;
281     }
282   return mask;
283 }
284 
285 static xkb_mod_mask_t
add_virtual_mods(xkb_mod_mask_t mask)286 add_virtual_mods (xkb_mod_mask_t mask)
287 {
288   MetaKeyBindingManager *keys = &(meta_get_display ()->key_binding_manager);
289   xkb_mod_mask_t added;
290   guint i;
291   /* Order is important here: if multiple vmods share the same real
292      modifier we only want to add the first. */
293   struct {
294     xkb_mod_mask_t mod;
295     xkb_mod_mask_t vmod;
296   } mods[] = {
297     { keys->super_mask, keys->virtual_super_mask },
298     { keys->hyper_mask, keys->virtual_hyper_mask },
299     { keys->meta_mask,  keys->virtual_meta_mask },
300   };
301 
302   added = 0;
303   for (i = 0; i < G_N_ELEMENTS (mods); ++i)
304     mask = add_vmod (mask, mods[i].mod, mods[i].vmod, &added);
305 
306   return mask;
307 }
308 
309 static void
keyboard_send_modifiers(MetaWaylandKeyboard * keyboard,struct wl_resource * resource,uint32_t serial)310 keyboard_send_modifiers (MetaWaylandKeyboard *keyboard,
311                          struct wl_resource  *resource,
312                          uint32_t             serial)
313 {
314   struct xkb_state *state = keyboard->xkb_info.state;
315   xkb_mod_mask_t depressed, latched, locked;
316 
317   depressed = add_virtual_mods (xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED));
318   latched = add_virtual_mods (xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED));
319   locked = add_virtual_mods (xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED));
320 
321   wl_keyboard_send_modifiers (resource, serial, depressed, latched, locked,
322                               xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
323 }
324 
325 static void
meta_wayland_keyboard_broadcast_modifiers(MetaWaylandKeyboard * keyboard)326 meta_wayland_keyboard_broadcast_modifiers (MetaWaylandKeyboard *keyboard)
327 {
328   struct wl_resource *resource;
329 
330   if (!wl_list_empty (&keyboard->focus_resource_list))
331     {
332       MetaWaylandInputDevice *input_device =
333         META_WAYLAND_INPUT_DEVICE (keyboard);
334       uint32_t serial;
335 
336       serial = meta_wayland_input_device_next_serial (input_device);
337 
338       wl_resource_for_each (resource, &keyboard->focus_resource_list)
339         keyboard_send_modifiers (keyboard, resource, serial);
340     }
341 }
342 
343 static void
notify_modifiers(MetaWaylandKeyboard * keyboard)344 notify_modifiers (MetaWaylandKeyboard *keyboard)
345 {
346   struct xkb_state *state;
347 
348   state = keyboard->xkb_info.state;
349   keyboard->grab->interface->modifiers (keyboard->grab,
350                                         xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE));
351 }
352 
353 static void
meta_wayland_keyboard_update_xkb_state(MetaWaylandKeyboard * keyboard)354 meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard)
355 {
356   MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
357   xkb_mod_mask_t latched, locked, numlock;
358   MetaBackend *backend = meta_get_backend ();
359   xkb_layout_index_t layout_idx;
360   ClutterKeymap *keymap;
361   ClutterSeat *seat;
362 
363   /* Preserve latched/locked modifiers state */
364   if (xkb_info->state)
365     {
366       latched = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LATCHED);
367       locked = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LOCKED);
368       xkb_state_unref (xkb_info->state);
369     }
370   else
371     {
372       latched = locked = 0;
373     }
374 
375   seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
376   keymap = clutter_seat_get_keymap (seat);
377   numlock = (1 <<  xkb_keymap_mod_get_index (xkb_info->keymap, "Mod2"));
378 
379   if (clutter_keymap_get_num_lock_state (keymap))
380     locked |= numlock;
381   else
382     locked &= ~numlock;
383 
384   xkb_info->state = xkb_state_new (xkb_info->keymap);
385 
386   layout_idx = meta_backend_get_keymap_layout_group (backend);
387   xkb_state_update_mask (xkb_info->state, 0, latched, locked, 0, 0, layout_idx);
388 
389   kbd_a11y_apply_mask (keyboard);
390 }
391 
392 static void
on_kbd_a11y_mask_changed(ClutterSeat * seat,xkb_mod_mask_t new_latched_mods,xkb_mod_mask_t new_locked_mods,MetaWaylandKeyboard * keyboard)393 on_kbd_a11y_mask_changed (ClutterSeat         *seat,
394                           xkb_mod_mask_t       new_latched_mods,
395                           xkb_mod_mask_t       new_locked_mods,
396                           MetaWaylandKeyboard *keyboard)
397 {
398   xkb_mod_mask_t latched, locked, depressed, group;
399 
400   if (keyboard->xkb_info.state == NULL)
401     return;
402 
403   depressed = xkb_state_serialize_mods(keyboard->xkb_info.state, XKB_STATE_DEPRESSED);
404   latched = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LATCHED);
405   locked = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LOCKED);
406   group = xkb_state_serialize_layout (keyboard->xkb_info.state, XKB_STATE_LAYOUT_EFFECTIVE);
407 
408   /* Clear previous masks */
409   latched &= ~keyboard->kbd_a11y_latched_mods;
410   locked &= ~keyboard->kbd_a11y_locked_mods;
411   xkb_state_update_mask (keyboard->xkb_info.state, depressed, latched, locked, 0, 0, group);
412 
413   /* Apply new masks */
414   keyboard->kbd_a11y_latched_mods = new_latched_mods;
415   keyboard->kbd_a11y_locked_mods = new_locked_mods;
416   kbd_a11y_apply_mask (keyboard);
417 
418   notify_modifiers (keyboard);
419 }
420 
421 static void
notify_key_repeat_for_resource(MetaWaylandKeyboard * keyboard,struct wl_resource * keyboard_resource)422 notify_key_repeat_for_resource (MetaWaylandKeyboard *keyboard,
423                                 struct wl_resource  *keyboard_resource)
424 {
425   if (wl_resource_get_version (keyboard_resource) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
426     {
427       gboolean repeat;
428       unsigned int delay, rate;
429 
430       repeat = g_settings_get_boolean (keyboard->settings, "repeat");
431 
432       if (repeat)
433         {
434           unsigned int interval;
435           interval = g_settings_get_uint (keyboard->settings, "repeat-interval");
436           /* Our setting is in the milliseconds between keys. "rate" is the number
437            * of keys per second. */
438           if (interval > 0)
439             rate = (1000 / interval);
440           else
441             rate = 0;
442 
443           delay = g_settings_get_uint (keyboard->settings, "delay");
444         }
445       else
446         {
447           rate = 0;
448           delay = 0;
449         }
450 
451       wl_keyboard_send_repeat_info (keyboard_resource, rate, delay);
452     }
453 }
454 
455 static void
notify_key_repeat(MetaWaylandKeyboard * keyboard)456 notify_key_repeat (MetaWaylandKeyboard *keyboard)
457 {
458   struct wl_resource *keyboard_resource;
459 
460   wl_resource_for_each (keyboard_resource, &keyboard->resource_list)
461     {
462       notify_key_repeat_for_resource (keyboard, keyboard_resource);
463     }
464 
465   wl_resource_for_each (keyboard_resource, &keyboard->focus_resource_list)
466     {
467       notify_key_repeat_for_resource (keyboard, keyboard_resource);
468     }
469 }
470 
471 static void
settings_changed(GSettings * settings,const char * key,gpointer data)472 settings_changed (GSettings           *settings,
473                   const char          *key,
474                   gpointer             data)
475 {
476   MetaWaylandKeyboard *keyboard = data;
477 
478   notify_key_repeat (keyboard);
479 }
480 
481 static gboolean
default_grab_key(MetaWaylandKeyboardGrab * grab,const ClutterEvent * event)482 default_grab_key (MetaWaylandKeyboardGrab *grab,
483                   const ClutterEvent      *event)
484 {
485   MetaWaylandKeyboard *keyboard = grab->keyboard;
486   gboolean is_press = event->type == CLUTTER_KEY_PRESS;
487   guint32 code = 0;
488 
489   /* Ignore autorepeat events, as autorepeat in Wayland is done on the client
490    * side. */
491   if (event->key.flags & CLUTTER_EVENT_FLAG_REPEATED)
492     return FALSE;
493 
494   code = clutter_event_get_event_code (event);
495 
496   return meta_wayland_keyboard_broadcast_key (keyboard, event->key.time,
497                                               code, is_press);
498 }
499 
500 static void
default_grab_modifiers(MetaWaylandKeyboardGrab * grab,ClutterModifierType modifiers)501 default_grab_modifiers (MetaWaylandKeyboardGrab *grab,
502                         ClutterModifierType      modifiers)
503 {
504   meta_wayland_keyboard_broadcast_modifiers (grab->keyboard);
505 }
506 
507 static const MetaWaylandKeyboardGrabInterface default_keyboard_grab_interface = {
508   default_grab_key,
509   default_grab_modifiers
510 };
511 
512 void
meta_wayland_keyboard_enable(MetaWaylandKeyboard * keyboard)513 meta_wayland_keyboard_enable (MetaWaylandKeyboard *keyboard)
514 {
515   MetaBackend *backend = meta_get_backend ();
516   ClutterBackend *clutter_backend = clutter_get_default_backend ();
517 
518   keyboard->settings = g_settings_new ("org.gnome.desktop.peripherals.keyboard");
519   g_signal_connect (keyboard->settings, "changed",
520                     G_CALLBACK (settings_changed), keyboard);
521 
522   g_signal_connect (backend, "keymap-changed",
523                     G_CALLBACK (on_keymap_changed), keyboard);
524   g_signal_connect (backend, "keymap-layout-group-changed",
525                     G_CALLBACK (on_keymap_layout_group_changed), keyboard);
526 
527   g_signal_connect (clutter_backend_get_default_seat (clutter_backend),
528 		    "kbd-a11y-mods-state-changed",
529                     G_CALLBACK (on_kbd_a11y_mask_changed), keyboard);
530 
531   meta_wayland_keyboard_take_keymap (keyboard, meta_backend_get_keymap (backend));
532 }
533 
534 static void
meta_wayland_xkb_info_destroy(MetaWaylandXkbInfo * xkb_info)535 meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
536 {
537   g_clear_pointer (&xkb_info->keymap, xkb_keymap_unref);
538   g_clear_pointer (&xkb_info->state, xkb_state_unref);
539   g_clear_pointer (&xkb_info->keymap_rofile, meta_anonymous_file_free);
540 }
541 
542 void
meta_wayland_keyboard_disable(MetaWaylandKeyboard * keyboard)543 meta_wayland_keyboard_disable (MetaWaylandKeyboard *keyboard)
544 {
545   MetaBackend *backend = meta_get_backend ();
546 
547   g_signal_handlers_disconnect_by_func (backend, on_keymap_changed, keyboard);
548   g_signal_handlers_disconnect_by_func (backend, on_keymap_layout_group_changed, keyboard);
549 
550   meta_wayland_keyboard_end_grab (keyboard);
551   meta_wayland_keyboard_set_focus (keyboard, NULL);
552 
553   wl_list_remove (&keyboard->resource_list);
554   wl_list_init (&keyboard->resource_list);
555   wl_list_remove (&keyboard->focus_resource_list);
556   wl_list_init (&keyboard->focus_resource_list);
557 
558   g_clear_object (&keyboard->settings);
559 }
560 
561 void
meta_wayland_keyboard_update(MetaWaylandKeyboard * keyboard,const ClutterKeyEvent * event)562 meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard,
563                               const ClutterKeyEvent *event)
564 {
565   gboolean is_press = event->type == CLUTTER_KEY_PRESS;
566 
567   /* Only handle real, non-synthetic, events here. The IM is free to reemit
568    * key events (incl. modifiers), handling those additionally will result
569    * in doubly-pressed keys.
570    */
571   if ((event->flags &
572        (CLUTTER_EVENT_FLAG_SYNTHETIC | CLUTTER_EVENT_FLAG_INPUT_METHOD)) != 0)
573     return;
574 
575   /* If we get a key event but still have pending modifier state
576    * changes from a previous event that didn't get cleared, we need to
577    * send that state right away so that the new key event can be
578    * interpreted by clients correctly modified. */
579   if (keyboard->mods_changed)
580     notify_modifiers (keyboard);
581 
582   keyboard->mods_changed = xkb_state_update_key (keyboard->xkb_info.state,
583                                                  event->hardware_keycode,
584                                                  is_press ? XKB_KEY_DOWN : XKB_KEY_UP);
585   keyboard->mods_changed |= kbd_a11y_apply_mask (keyboard);
586 }
587 
588 gboolean
meta_wayland_keyboard_handle_event(MetaWaylandKeyboard * keyboard,const ClutterKeyEvent * event)589 meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
590                                     const ClutterKeyEvent *event)
591 {
592 #ifdef WITH_VERBOSE_MODE
593   gboolean is_press = event->type == CLUTTER_KEY_PRESS;
594 #endif
595   gboolean handled;
596 
597   /* Synthetic key events are for autorepeat. Ignore those, as
598    * autorepeat in Wayland is done on the client side. */
599   if ((event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC) &&
600       !(event->flags & CLUTTER_EVENT_FLAG_INPUT_METHOD))
601     return FALSE;
602 
603   meta_verbose ("Handling key %s event code %d",
604 		is_press ? "press" : "release",
605 		event->hardware_keycode);
606 
607   handled = notify_key (keyboard, (const ClutterEvent *) event);
608 
609   if (handled)
610     meta_verbose ("Sent event to wayland client");
611   else
612     meta_verbose ("No wayland surface is focused, continuing normal operation");
613 
614   if (keyboard->mods_changed != 0)
615     {
616       notify_modifiers (keyboard);
617       keyboard->mods_changed = 0;
618     }
619 
620   return handled;
621 }
622 
623 void
meta_wayland_keyboard_update_key_state(MetaWaylandKeyboard * keyboard,char * key_vector,int key_vector_len,int offset)624 meta_wayland_keyboard_update_key_state (MetaWaylandKeyboard *keyboard,
625                                         char                *key_vector,
626                                         int                  key_vector_len,
627                                         int                  offset)
628 {
629   gboolean mods_changed = FALSE;
630 
631   int i;
632   for (i = offset; i < key_vector_len * 8; i++)
633     {
634       gboolean set = (key_vector[i/8] & (1 << (i % 8))) != 0;
635 
636       /* The 'offset' parameter allows the caller to have the indices
637        * into key_vector to either be X-style (base 8) or evdev (base 0), or
638        * something else (unlikely). We subtract 'offset' to convert to evdev
639        * style, then add 8 to convert the "evdev" style keycode back to
640        * the X-style that xkbcommon expects.
641        */
642       mods_changed |= xkb_state_update_key (keyboard->xkb_info.state,
643                                             i - offset + 8,
644                                             set ? XKB_KEY_DOWN : XKB_KEY_UP);
645     }
646 
647   mods_changed |= kbd_a11y_apply_mask (keyboard);
648   if (mods_changed)
649     notify_modifiers (keyboard);
650 }
651 
652 static void
move_resources(struct wl_list * destination,struct wl_list * source)653 move_resources (struct wl_list *destination, struct wl_list *source)
654 {
655   wl_list_insert_list (destination, source);
656   wl_list_init (source);
657 }
658 
659 static void
move_resources_for_client(struct wl_list * destination,struct wl_list * source,struct wl_client * client)660 move_resources_for_client (struct wl_list *destination,
661 			   struct wl_list *source,
662 			   struct wl_client *client)
663 {
664   struct wl_resource *resource, *tmp;
665   wl_resource_for_each_safe (resource, tmp, source)
666     {
667       if (wl_resource_get_client (resource) == client)
668         {
669           wl_list_remove (wl_resource_get_link (resource));
670           wl_list_insert (destination, wl_resource_get_link (resource));
671         }
672     }
673 }
674 
675 static void
broadcast_focus(MetaWaylandKeyboard * keyboard,struct wl_resource * resource)676 broadcast_focus (MetaWaylandKeyboard *keyboard,
677                  struct wl_resource  *resource)
678 {
679   struct wl_array fake_keys;
680 
681   /* We never want to send pressed keys to wayland clients on
682    * enter. The protocol says that we should send them, presumably so
683    * that clients can trigger their own key repeat routine in case
684    * they are given focus and a key is physically pressed.
685    *
686    * Unfortunately this causes some clients, in particular Xwayland,
687    * to register key events that they really shouldn't handle,
688    * e.g. on an Alt+Tab keybinding, where Alt is released before Tab,
689    * clients would see Tab being pressed on enter followed by a key
690    * release event for Tab, meaning that Tab would be processed by
691    * the client when it really shouldn't.
692    *
693    * Since the use case for the pressed keys array on enter seems weak
694    * to us, we'll just fake that there are no pressed keys instead
695    * which should be spec compliant even if it might not be true.
696    */
697   wl_array_init (&fake_keys);
698 
699   keyboard_send_modifiers (keyboard, resource, keyboard->focus_serial);
700   wl_keyboard_send_enter (resource, keyboard->focus_serial,
701                           keyboard->focus_surface->resource,
702                           &fake_keys);
703 }
704 
705 void
meta_wayland_keyboard_set_focus(MetaWaylandKeyboard * keyboard,MetaWaylandSurface * surface)706 meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
707                                  MetaWaylandSurface *surface)
708 {
709   MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (keyboard);
710 
711   if (keyboard->focus_surface == surface)
712     return;
713 
714   if (keyboard->focus_surface != NULL)
715     {
716       if (!wl_list_empty (&keyboard->focus_resource_list))
717         {
718           struct wl_resource *resource;
719           uint32_t serial;
720 
721           serial = meta_wayland_input_device_next_serial (input_device);
722 
723           wl_resource_for_each (resource, &keyboard->focus_resource_list)
724             {
725               wl_keyboard_send_leave (resource, serial,
726                                       keyboard->focus_surface->resource);
727             }
728 
729           move_resources (&keyboard->resource_list,
730                           &keyboard->focus_resource_list);
731         }
732 
733       wl_list_remove (&keyboard->focus_surface_listener.link);
734       keyboard->focus_surface = NULL;
735     }
736 
737   if (surface != NULL)
738     {
739       struct wl_resource *focus_surface_resource;
740 
741       keyboard->focus_surface = surface;
742       focus_surface_resource = keyboard->focus_surface->resource;
743       wl_resource_add_destroy_listener (focus_surface_resource,
744                                         &keyboard->focus_surface_listener);
745 
746       move_resources_for_client (&keyboard->focus_resource_list,
747                                  &keyboard->resource_list,
748                                  wl_resource_get_client (focus_surface_resource));
749 
750       /* Make sure a11y masks are applied before braodcasting modifiers */
751       kbd_a11y_apply_mask (keyboard);
752 
753       if (!wl_list_empty (&keyboard->focus_resource_list))
754         {
755           struct wl_resource *resource;
756 
757           keyboard->focus_serial =
758             meta_wayland_input_device_next_serial (input_device);
759 
760           wl_resource_for_each (resource, &keyboard->focus_resource_list)
761             {
762               broadcast_focus (keyboard, resource);
763             }
764         }
765     }
766 }
767 
768 struct wl_client *
meta_wayland_keyboard_get_focus_client(MetaWaylandKeyboard * keyboard)769 meta_wayland_keyboard_get_focus_client (MetaWaylandKeyboard *keyboard)
770 {
771   if (keyboard->focus_surface)
772     return wl_resource_get_client (keyboard->focus_surface->resource);
773   else
774     return NULL;
775 }
776 
777 static void
keyboard_release(struct wl_client * client,struct wl_resource * resource)778 keyboard_release (struct wl_client *client,
779                   struct wl_resource *resource)
780 {
781   wl_resource_destroy (resource);
782 }
783 
784 static const struct wl_keyboard_interface keyboard_interface = {
785   keyboard_release,
786 };
787 
788 void
meta_wayland_keyboard_create_new_resource(MetaWaylandKeyboard * keyboard,struct wl_client * client,struct wl_resource * seat_resource,uint32_t id)789 meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
790                                            struct wl_client    *client,
791                                            struct wl_resource  *seat_resource,
792                                            uint32_t id)
793 {
794   struct wl_resource *resource;
795 
796   resource = wl_resource_create (client, &wl_keyboard_interface,
797                                  wl_resource_get_version (seat_resource), id);
798   wl_resource_set_implementation (resource, &keyboard_interface,
799                                   keyboard, unbind_resource);
800 
801   send_keymap (keyboard, resource);
802 
803   notify_key_repeat_for_resource (keyboard, resource);
804 
805   if (keyboard->focus_surface &&
806       wl_resource_get_client (keyboard->focus_surface->resource) == client)
807     {
808       wl_list_insert (&keyboard->focus_resource_list,
809                       wl_resource_get_link (resource));
810       broadcast_focus (keyboard, resource);
811     }
812   else
813     {
814       wl_list_insert (&keyboard->resource_list,
815                       wl_resource_get_link (resource));
816     }
817 }
818 
819 gboolean
meta_wayland_keyboard_can_popup(MetaWaylandKeyboard * keyboard,uint32_t serial)820 meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard,
821                                  uint32_t             serial)
822 {
823   return (keyboard->key_down_serial == serial ||
824           ((keyboard->key_down_keycode == keyboard->key_up_keycode) &&
825            keyboard->key_up_serial == serial));
826 }
827 
828 void
meta_wayland_keyboard_start_grab(MetaWaylandKeyboard * keyboard,MetaWaylandKeyboardGrab * grab)829 meta_wayland_keyboard_start_grab (MetaWaylandKeyboard     *keyboard,
830                                   MetaWaylandKeyboardGrab *grab)
831 {
832   meta_wayland_keyboard_set_focus (keyboard, NULL);
833   keyboard->grab = grab;
834   grab->keyboard = keyboard;
835 }
836 
837 void
meta_wayland_keyboard_end_grab(MetaWaylandKeyboard * keyboard)838 meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard)
839 {
840   keyboard->grab = &keyboard->default_grab;
841 }
842 
843 static void
meta_wayland_keyboard_init(MetaWaylandKeyboard * keyboard)844 meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard)
845 {
846   wl_list_init (&keyboard->resource_list);
847   wl_list_init (&keyboard->focus_resource_list);
848 
849   keyboard->default_grab.interface = &default_keyboard_grab_interface;
850   keyboard->default_grab.keyboard = keyboard;
851   keyboard->grab = &keyboard->default_grab;
852 
853   keyboard->focus_surface_listener.notify =
854     keyboard_handle_focus_surface_destroy;
855 }
856 
857 static void
meta_wayland_keyboard_finalize(GObject * object)858 meta_wayland_keyboard_finalize (GObject *object)
859 {
860   MetaWaylandKeyboard *keyboard = META_WAYLAND_KEYBOARD (object);
861 
862   meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
863 
864   G_OBJECT_CLASS (meta_wayland_keyboard_parent_class)->finalize (object);
865 }
866 
867 static void
meta_wayland_keyboard_class_init(MetaWaylandKeyboardClass * klass)868 meta_wayland_keyboard_class_init (MetaWaylandKeyboardClass *klass)
869 {
870   GObjectClass *object_class = G_OBJECT_CLASS (klass);
871 
872   object_class->finalize = meta_wayland_keyboard_finalize;
873 }
874