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