~elementary-os/ubuntu-package-imports/mutter-bionic

« back to all changes in this revision

Viewing changes to src/wayland/meta-wayland-keyboard.c

  • Committer: RabbitBot
  • Date: 2018-04-11 14:49:36 UTC
  • Revision ID: rabbitbot@elementary.io-20180411144936-hgymqa9d8d1xfpbh
Initial import, version 3.28.0-2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <glib.h>
 
51
#include <string.h>
 
52
#include <errno.h>
 
53
#include <stdlib.h>
 
54
#include <fcntl.h>
 
55
#include <unistd.h>
 
56
#include <sys/mman.h>
 
57
#include <clutter/evdev/clutter-evdev.h>
 
58
 
 
59
#include "display-private.h"
 
60
#include "backends/meta-backend-private.h"
 
61
 
 
62
#include "meta-wayland-private.h"
 
63
 
 
64
#ifdef HAVE_NATIVE_BACKEND
 
65
#include "backends/native/meta-backend-native.h"
 
66
#endif
 
67
 
 
68
#define GSD_KEYBOARD_SCHEMA "org.gnome.settings-daemon.peripherals.keyboard"
 
69
typedef enum
 
70
{
 
71
  GSD_KEYBOARD_NUM_LOCK_STATE_UNKNOWN,
 
72
  GSD_KEYBOARD_NUM_LOCK_STATE_ON,
 
73
  GSD_KEYBOARD_NUM_LOCK_STATE_OFF
 
74
} GsdKeyboardNumLockState;
 
75
 
 
76
G_DEFINE_TYPE (MetaWaylandKeyboard, meta_wayland_keyboard,
 
77
               META_TYPE_WAYLAND_INPUT_DEVICE)
 
78
 
 
79
static void meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard);
 
80
static void meta_wayland_keyboard_set_numlock (MetaWaylandKeyboard *keyboard,
 
81
                                               gboolean             numlock_state);
 
82
static void notify_modifiers (MetaWaylandKeyboard *keyboard);
 
83
static guint evdev_code (const ClutterKeyEvent *event);
 
84
 
 
85
static void
 
86
unbind_resource (struct wl_resource *resource)
 
87
{
 
88
  wl_list_remove (wl_resource_get_link (resource));
 
89
}
 
90
 
 
91
static int
 
92
create_anonymous_file (off_t size,
 
93
                       GError **error)
 
94
{
 
95
  static const char template[] = "mutter-shared-XXXXXX";
 
96
  char *path;
 
97
  int fd, flags;
 
98
 
 
99
  fd = g_file_open_tmp (template, &path, error);
 
100
 
 
101
  if (fd == -1)
 
102
    return -1;
 
103
 
 
104
  unlink (path);
 
105
  g_free (path);
 
106
 
 
107
  flags = fcntl (fd, F_GETFD);
 
108
  if (flags == -1)
 
109
    goto err;
 
110
 
 
111
  if (fcntl (fd, F_SETFD, flags | FD_CLOEXEC) == -1)
 
112
    goto err;
 
113
 
 
114
  if (ftruncate (fd, size) < 0)
 
115
    goto err;
 
116
 
 
117
  return fd;
 
118
 
 
119
 err:
 
120
  g_set_error_literal (error,
 
121
                       G_FILE_ERROR,
 
122
                       g_file_error_from_errno (errno),
 
123
                       strerror (errno));
 
124
  close (fd);
 
125
 
 
126
  return -1;
 
127
}
 
128
 
 
129
static void
 
130
inform_clients_of_new_keymap (MetaWaylandKeyboard *keyboard)
 
131
{
 
132
  struct wl_resource *keyboard_resource;
 
133
 
 
134
  wl_resource_for_each (keyboard_resource, &keyboard->resource_list)
 
135
    {
 
136
      wl_keyboard_send_keymap (keyboard_resource,
 
137
                               WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
 
138
                               keyboard->xkb_info.keymap_fd,
 
139
                               keyboard->xkb_info.keymap_size);
 
140
    }
 
141
  wl_resource_for_each (keyboard_resource, &keyboard->focus_resource_list)
 
142
    {
 
143
      wl_keyboard_send_keymap (keyboard_resource,
 
144
                               WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
 
145
                               keyboard->xkb_info.keymap_fd,
 
146
                               keyboard->xkb_info.keymap_size);
 
147
    }
 
148
}
 
149
 
 
150
static void
 
151
meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
 
152
                                   struct xkb_keymap   *keymap)
 
153
{
 
154
  MetaWaylandXkbInfo  *xkb_info = &keyboard->xkb_info;
 
155
  GError *error = NULL;
 
156
  char *keymap_str;
 
157
  size_t previous_size;
 
158
 
 
159
  if (keymap == NULL)
 
160
    {
 
161
      g_warning ("Attempting to set null keymap (compilation probably failed)");
 
162
      return;
 
163
    }
 
164
 
 
165
  xkb_keymap_unref (xkb_info->keymap);
 
166
  xkb_info->keymap = xkb_keymap_ref (keymap);
 
167
 
 
168
  meta_wayland_keyboard_update_xkb_state (keyboard);
 
169
 
 
170
  keymap_str = xkb_map_get_as_string (xkb_info->keymap);
 
171
  if (keymap_str == NULL)
 
172
    {
 
173
      g_warning ("failed to get string version of keymap");
 
174
      return;
 
175
    }
 
176
  previous_size = xkb_info->keymap_size;
 
177
  xkb_info->keymap_size = strlen (keymap_str) + 1;
 
178
 
 
179
  if (xkb_info->keymap_fd >= 0)
 
180
    close (xkb_info->keymap_fd);
 
181
 
 
182
  xkb_info->keymap_fd = create_anonymous_file (xkb_info->keymap_size, &error);
 
183
  if (xkb_info->keymap_fd < 0)
 
184
    {
 
185
      g_warning ("creating a keymap file for %lu bytes failed: %s",
 
186
                 (unsigned long) xkb_info->keymap_size,
 
187
                 error->message);
 
188
      g_clear_error (&error);
 
189
      goto err_keymap_str;
 
190
    }
 
191
 
 
192
  if (xkb_info->keymap_area)
 
193
    munmap (xkb_info->keymap_area, previous_size);
 
194
 
 
195
  xkb_info->keymap_area = mmap (NULL, xkb_info->keymap_size,
 
196
                                PROT_READ | PROT_WRITE,
 
197
                                MAP_SHARED, xkb_info->keymap_fd, 0);
 
198
  if (xkb_info->keymap_area == MAP_FAILED)
 
199
    {
 
200
      g_warning ("failed to mmap() %lu bytes\n",
 
201
                 (unsigned long) xkb_info->keymap_size);
 
202
      goto err_dev_zero;
 
203
    }
 
204
  strcpy (xkb_info->keymap_area, keymap_str);
 
205
  free (keymap_str);
 
206
 
 
207
  inform_clients_of_new_keymap (keyboard);
 
208
 
 
209
  notify_modifiers (keyboard);
 
210
 
 
211
  return;
 
212
 
 
213
err_dev_zero:
 
214
  close (xkb_info->keymap_fd);
 
215
  xkb_info->keymap_fd = -1;
 
216
err_keymap_str:
 
217
  free (keymap_str);
 
218
  return;
 
219
}
 
220
 
 
221
static xkb_mod_mask_t
 
222
kbd_a11y_apply_mask (MetaWaylandKeyboard *keyboard)
 
223
{
 
224
  xkb_mod_mask_t latched, locked, depressed, group;
 
225
  xkb_mod_mask_t update_mask = 0;
 
226
 
 
227
  depressed = xkb_state_serialize_mods(keyboard->xkb_info.state, XKB_STATE_DEPRESSED);
 
228
  latched = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LATCHED);
 
229
  locked = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LOCKED);
 
230
  group = xkb_state_serialize_layout (keyboard->xkb_info.state, XKB_STATE_LAYOUT_EFFECTIVE);
 
231
 
 
232
  if ((latched & keyboard->kbd_a11y_latched_mods) != keyboard->kbd_a11y_latched_mods)
 
233
    update_mask |= XKB_STATE_MODS_LATCHED;
 
234
 
 
235
  if ((locked & keyboard->kbd_a11y_locked_mods) != keyboard->kbd_a11y_locked_mods)
 
236
    update_mask |= XKB_STATE_MODS_LOCKED;
 
237
 
 
238
  if (update_mask)
 
239
    {
 
240
      latched |= keyboard->kbd_a11y_latched_mods;
 
241
      locked |= keyboard->kbd_a11y_locked_mods;
 
242
      xkb_state_update_mask (keyboard->xkb_info.state, depressed, latched, locked, 0, 0, group);
 
243
    }
 
244
 
 
245
  return update_mask;
 
246
}
 
247
 
 
248
static void
 
249
on_keymap_changed (MetaBackend *backend,
 
250
                   gpointer     data)
 
251
{
 
252
  MetaWaylandKeyboard *keyboard = data;
 
253
 
 
254
  meta_wayland_keyboard_take_keymap (keyboard, meta_backend_get_keymap (backend));
 
255
}
 
256
 
 
257
static void
 
258
on_keymap_layout_group_changed (MetaBackend *backend,
 
259
                                guint        idx,
 
260
                                gpointer     data)
 
261
{
 
262
  MetaWaylandKeyboard *keyboard = data;
 
263
  xkb_mod_mask_t depressed_mods;
 
264
  xkb_mod_mask_t latched_mods;
 
265
  xkb_mod_mask_t locked_mods;
 
266
  struct xkb_state *state;
 
267
 
 
268
  state = keyboard->xkb_info.state;
 
269
 
 
270
  depressed_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED);
 
271
  latched_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED);
 
272
  locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED);
 
273
 
 
274
  xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx);
 
275
  kbd_a11y_apply_mask (keyboard);
 
276
 
 
277
  notify_modifiers (keyboard);
 
278
}
 
279
 
 
280
static void
 
281
keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data)
 
282
{
 
283
  MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard,
 
284
                                                   focus_surface_listener);
 
285
 
 
286
  meta_wayland_keyboard_set_focus (keyboard, NULL);
 
287
}
 
288
 
 
289
static gboolean
 
290
meta_wayland_keyboard_broadcast_key (MetaWaylandKeyboard *keyboard,
 
291
                                     uint32_t             time,
 
292
                                     uint32_t             key,
 
293
                                     uint32_t             state)
 
294
{
 
295
  struct wl_resource *resource;
 
296
 
 
297
  if (!wl_list_empty (&keyboard->focus_resource_list))
 
298
    {
 
299
      MetaWaylandInputDevice *input_device =
 
300
        META_WAYLAND_INPUT_DEVICE (keyboard);
 
301
 
 
302
      keyboard->key_serial =
 
303
        meta_wayland_input_device_next_serial (input_device);
 
304
 
 
305
      wl_resource_for_each (resource, &keyboard->focus_resource_list)
 
306
        {
 
307
          wl_keyboard_send_key (resource, keyboard->key_serial, time, key, state);
 
308
        }
 
309
    }
 
310
 
 
311
  /* Eat the key events if we have a focused surface. */
 
312
  return (keyboard->focus_surface != NULL);
 
313
}
 
314
 
 
315
static gboolean
 
316
notify_key (MetaWaylandKeyboard *keyboard,
 
317
            const ClutterEvent  *event)
 
318
{
 
319
  return keyboard->grab->interface->key (keyboard->grab, event);
 
320
}
 
321
 
 
322
static xkb_mod_mask_t
 
323
add_vmod (xkb_mod_mask_t mask,
 
324
          xkb_mod_mask_t mod,
 
325
          xkb_mod_mask_t vmod,
 
326
          xkb_mod_mask_t *added)
 
327
{
 
328
  if ((mask & mod) && !(mod & *added))
 
329
    {
 
330
      mask |= vmod;
 
331
      *added |= mod;
 
332
    }
 
333
  return mask;
 
334
}
 
335
 
 
336
static xkb_mod_mask_t
 
337
add_virtual_mods (xkb_mod_mask_t mask)
 
338
{
 
339
  MetaKeyBindingManager *keys = &(meta_get_display ()->key_binding_manager);
 
340
  xkb_mod_mask_t added;
 
341
  guint i;
 
342
  /* Order is important here: if multiple vmods share the same real
 
343
     modifier we only want to add the first. */
 
344
  struct {
 
345
    xkb_mod_mask_t mod;
 
346
    xkb_mod_mask_t vmod;
 
347
  } mods[] = {
 
348
    { keys->super_mask, keys->virtual_super_mask },
 
349
    { keys->hyper_mask, keys->virtual_hyper_mask },
 
350
    { keys->meta_mask,  keys->virtual_meta_mask },
 
351
  };
 
352
 
 
353
  added = 0;
 
354
  for (i = 0; i < G_N_ELEMENTS (mods); ++i)
 
355
    mask = add_vmod (mask, mods[i].mod, mods[i].vmod, &added);
 
356
 
 
357
  return mask;
 
358
}
 
359
 
 
360
static void
 
361
keyboard_send_modifiers (MetaWaylandKeyboard *keyboard,
 
362
                         struct wl_resource  *resource,
 
363
                         uint32_t             serial)
 
364
{
 
365
  struct xkb_state *state = keyboard->xkb_info.state;
 
366
  xkb_mod_mask_t depressed, latched, locked;
 
367
 
 
368
  depressed = add_virtual_mods (xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED));
 
369
  latched = add_virtual_mods (xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED));
 
370
  locked = add_virtual_mods (xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED));
 
371
 
 
372
  wl_keyboard_send_modifiers (resource, serial, depressed, latched, locked,
 
373
                              xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
 
374
}
 
375
 
 
376
static void
 
377
meta_wayland_keyboard_broadcast_modifiers (MetaWaylandKeyboard *keyboard)
 
378
{
 
379
  struct wl_resource *resource;
 
380
 
 
381
  if (!wl_list_empty (&keyboard->focus_resource_list))
 
382
    {
 
383
      MetaWaylandInputDevice *input_device =
 
384
        META_WAYLAND_INPUT_DEVICE (keyboard);
 
385
      uint32_t serial;
 
386
 
 
387
      serial = meta_wayland_input_device_next_serial (input_device);
 
388
 
 
389
      wl_resource_for_each (resource, &keyboard->focus_resource_list)
 
390
        keyboard_send_modifiers (keyboard, resource, serial);
 
391
    }
 
392
}
 
393
 
 
394
static void
 
395
notify_modifiers (MetaWaylandKeyboard *keyboard)
 
396
{
 
397
  struct xkb_state *state;
 
398
 
 
399
  state = keyboard->xkb_info.state;
 
400
  keyboard->grab->interface->modifiers (keyboard->grab,
 
401
                                        xkb_state_serialize_mods (state, XKB_STATE_MODS_EFFECTIVE));
 
402
}
 
403
 
 
404
static void
 
405
numlock_set_xkb_state (MetaWaylandKeyboard    *keyboard,
 
406
                       GsdKeyboardNumLockState state)
 
407
{
 
408
  MetaBackend *backend = meta_get_backend ();
 
409
  gboolean numlock_state;
 
410
 
 
411
  if (state != GSD_KEYBOARD_NUM_LOCK_STATE_ON &&
 
412
      state != GSD_KEYBOARD_NUM_LOCK_STATE_OFF)
 
413
    return;
 
414
 
 
415
  numlock_state = (state == GSD_KEYBOARD_NUM_LOCK_STATE_ON);
 
416
  meta_verbose ("set numlock state %s\n", (numlock_state ? "ON" : "OFF"));
 
417
  meta_backend_set_numlock (backend, numlock_state);
 
418
  meta_wayland_keyboard_set_numlock (keyboard, numlock_state);
 
419
}
 
420
 
 
421
static void
 
422
maybe_restore_numlock_state (MetaWaylandKeyboard *keyboard)
 
423
{
 
424
  gboolean remember_numlock;
 
425
 
 
426
  if (!keyboard->gsd_settings)
 
427
    return;
 
428
 
 
429
  /* We are cheating for now, we use g-s-d settings... */
 
430
  remember_numlock = g_settings_get_boolean (keyboard->gsd_settings,
 
431
                                             "remember-numlock-state");
 
432
 
 
433
  if (remember_numlock)
 
434
    {
 
435
      GsdKeyboardNumLockState state;
 
436
 
 
437
      state = g_settings_get_enum (keyboard->gsd_settings, "numlock-state");
 
438
      numlock_set_xkb_state (keyboard, state);
 
439
    }
 
440
}
 
441
 
 
442
static void
 
443
maybe_save_numlock_state (MetaWaylandKeyboard *keyboard)
 
444
{
 
445
#ifdef HAVE_NATIVE_BACKEND
 
446
  MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
 
447
  GsdKeyboardNumLockState numlock_state;
 
448
  int numlock_active;
 
449
 
 
450
  if (!META_IS_BACKEND_NATIVE (meta_get_backend ()))
 
451
    return;
 
452
 
 
453
  if (!xkb_info->state)
 
454
    return;
 
455
 
 
456
  if (!keyboard->gsd_settings)
 
457
    return;
 
458
 
 
459
  if (!g_settings_get_boolean (keyboard->gsd_settings, "remember-numlock-state"))
 
460
    return;
 
461
 
 
462
  numlock_active = xkb_state_mod_name_is_active(xkb_info->state,
 
463
                                                "Mod2",
 
464
                                                XKB_STATE_MODS_LOCKED);
 
465
  switch (numlock_active)
 
466
    {
 
467
    case -1:
 
468
      numlock_state = GSD_KEYBOARD_NUM_LOCK_STATE_UNKNOWN;
 
469
      break;
 
470
    case 0:
 
471
      numlock_state = GSD_KEYBOARD_NUM_LOCK_STATE_OFF;
 
472
      break;
 
473
    default:
 
474
      numlock_state = GSD_KEYBOARD_NUM_LOCK_STATE_ON;
 
475
      break;
 
476
    }
 
477
  g_settings_set_enum (keyboard->gsd_settings, "numlock-state", numlock_state);
 
478
#endif
 
479
}
 
480
 
 
481
static void
 
482
meta_wayland_keyboard_set_numlock (MetaWaylandKeyboard *keyboard,
 
483
                                   gboolean     numlock_state)
 
484
{
 
485
  MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
 
486
  xkb_mod_mask_t latched, locked, group, depressed;
 
487
  xkb_mod_mask_t numlock;
 
488
 
 
489
  meta_verbose ("backend numlock state %s\n", (numlock_state ? "ON" : "OFF"));
 
490
 
 
491
  latched = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LATCHED);
 
492
  locked = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LOCKED);
 
493
  group = xkb_state_serialize_layout (xkb_info->state, XKB_STATE_LAYOUT_EFFECTIVE);
 
494
  depressed = xkb_state_serialize_mods(xkb_info->state, XKB_STATE_DEPRESSED);
 
495
  numlock = (1 <<  xkb_keymap_mod_get_index(xkb_info->keymap, "Mod2"));
 
496
 
 
497
  if (numlock_state == TRUE)
 
498
    locked |= numlock;
 
499
  else
 
500
    locked &= ~numlock;
 
501
 
 
502
  xkb_state_update_mask (xkb_info->state, depressed, latched, locked, 0, 0, group);
 
503
  kbd_a11y_apply_mask (keyboard);
 
504
 
 
505
  notify_modifiers (keyboard);
 
506
}
 
507
 
 
508
static void
 
509
meta_wayland_keyboard_update_xkb_state (MetaWaylandKeyboard *keyboard)
 
510
{
 
511
  MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
 
512
  xkb_mod_mask_t latched, locked;
 
513
  MetaBackend *backend = meta_get_backend ();
 
514
  xkb_layout_index_t layout_idx;
 
515
 
 
516
  /* Preserve latched/locked modifiers state */
 
517
  if (xkb_info->state)
 
518
    {
 
519
      latched = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LATCHED);
 
520
      locked = xkb_state_serialize_mods (xkb_info->state, XKB_STATE_MODS_LOCKED);
 
521
      xkb_state_unref (xkb_info->state);
 
522
    }
 
523
  else
 
524
    {
 
525
      latched = locked = 0;
 
526
    }
 
527
 
 
528
  xkb_info->state = xkb_state_new (xkb_info->keymap);
 
529
 
 
530
  layout_idx = meta_backend_get_keymap_layout_group (backend);
 
531
  xkb_state_update_mask (xkb_info->state, 0, latched, locked, 0, 0, layout_idx);
 
532
 
 
533
  kbd_a11y_apply_mask (keyboard);
 
534
}
 
535
 
 
536
static void
 
537
on_kbd_a11y_mask_changed (ClutterDeviceManager   *device_manager,
 
538
                          xkb_mod_mask_t          new_latched_mods,
 
539
                          xkb_mod_mask_t          new_locked_mods,
 
540
                          MetaWaylandKeyboard    *keyboard)
 
541
{
 
542
  xkb_mod_mask_t latched, locked, depressed, group;
 
543
 
 
544
  if (keyboard->xkb_info.state == NULL)
 
545
    return;
 
546
 
 
547
  depressed = xkb_state_serialize_mods(keyboard->xkb_info.state, XKB_STATE_DEPRESSED);
 
548
  latched = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LATCHED);
 
549
  locked = xkb_state_serialize_mods (keyboard->xkb_info.state, XKB_STATE_MODS_LOCKED);
 
550
  group = xkb_state_serialize_layout (keyboard->xkb_info.state, XKB_STATE_LAYOUT_EFFECTIVE);
 
551
 
 
552
  /* Clear previous masks */
 
553
  latched &= ~keyboard->kbd_a11y_latched_mods;
 
554
  locked &= ~keyboard->kbd_a11y_locked_mods;
 
555
  xkb_state_update_mask (keyboard->xkb_info.state, depressed, latched, locked, 0, 0, group);
 
556
 
 
557
  /* Apply new masks */
 
558
  keyboard->kbd_a11y_latched_mods = new_latched_mods;
 
559
  keyboard->kbd_a11y_locked_mods = new_locked_mods;
 
560
  kbd_a11y_apply_mask (keyboard);
 
561
 
 
562
  notify_modifiers (keyboard);
 
563
}
 
564
 
 
565
static void
 
566
notify_key_repeat_for_resource (MetaWaylandKeyboard *keyboard,
 
567
                                struct wl_resource  *keyboard_resource)
 
568
{
 
569
  if (wl_resource_get_version (keyboard_resource) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
 
570
    {
 
571
      gboolean repeat;
 
572
      unsigned int delay, rate;
 
573
 
 
574
      repeat = g_settings_get_boolean (keyboard->settings, "repeat");
 
575
 
 
576
      if (repeat)
 
577
        {
 
578
          unsigned int interval;
 
579
          interval = g_settings_get_uint (keyboard->settings, "repeat-interval");
 
580
          /* Our setting is in the milliseconds between keys. "rate" is the number
 
581
           * of keys per second. */
 
582
          if (interval > 0)
 
583
            rate = (1000 / interval);
 
584
          else
 
585
            rate = 0;
 
586
 
 
587
          delay = g_settings_get_uint (keyboard->settings, "delay");
 
588
        }
 
589
      else
 
590
        {
 
591
          rate = 0;
 
592
          delay = 0;
 
593
        }
 
594
 
 
595
      wl_keyboard_send_repeat_info (keyboard_resource, rate, delay);
 
596
    }
 
597
}
 
598
 
 
599
static void
 
600
notify_key_repeat (MetaWaylandKeyboard *keyboard)
 
601
{
 
602
  struct wl_resource *keyboard_resource;
 
603
 
 
604
  wl_resource_for_each (keyboard_resource, &keyboard->resource_list)
 
605
    {
 
606
      notify_key_repeat_for_resource (keyboard, keyboard_resource);
 
607
    }
 
608
 
 
609
  wl_resource_for_each (keyboard_resource, &keyboard->focus_resource_list)
 
610
    {
 
611
      notify_key_repeat_for_resource (keyboard, keyboard_resource);
 
612
    }
 
613
}
 
614
 
 
615
static void
 
616
remember_numlock_state_changed (GSettings  *settings,
 
617
                                const char *key,
 
618
                                gpointer    data)
 
619
{
 
620
  MetaWaylandKeyboard *keyboard = data;
 
621
 
 
622
  maybe_save_numlock_state (keyboard);
 
623
}
 
624
 
 
625
static void
 
626
settings_changed (GSettings           *settings,
 
627
                  const char          *key,
 
628
                  gpointer             data)
 
629
{
 
630
  MetaWaylandKeyboard *keyboard = data;
 
631
 
 
632
  notify_key_repeat (keyboard);
 
633
}
 
634
 
 
635
static gboolean
 
636
default_grab_key (MetaWaylandKeyboardGrab *grab,
 
637
                  const ClutterEvent      *event)
 
638
{
 
639
  MetaWaylandKeyboard *keyboard = grab->keyboard;
 
640
  gboolean is_press = event->type == CLUTTER_KEY_PRESS;
 
641
  guint32 code;
 
642
#ifdef HAVE_NATIVE_BACKEND
 
643
  MetaBackend *backend = meta_get_backend ();
 
644
#endif
 
645
 
 
646
  /* Synthetic key events are for autorepeat. Ignore those, as
 
647
   * autorepeat in Wayland is done on the client side. */
 
648
  if ((event->key.flags & CLUTTER_EVENT_FLAG_SYNTHETIC) &&
 
649
      !(event->key.flags & CLUTTER_EVENT_FLAG_INPUT_METHOD))
 
650
    return FALSE;
 
651
 
 
652
#ifdef HAVE_NATIVE_BACKEND
 
653
  if (META_IS_BACKEND_NATIVE (backend))
 
654
    code = clutter_evdev_event_get_event_code (event);
 
655
  else
 
656
#endif
 
657
    code = evdev_code (&event->key);
 
658
 
 
659
  return meta_wayland_keyboard_broadcast_key (keyboard, event->key.time,
 
660
                                              code, is_press);
 
661
}
 
662
 
 
663
static void
 
664
default_grab_modifiers (MetaWaylandKeyboardGrab *grab,
 
665
                        ClutterModifierType      modifiers)
 
666
{
 
667
  meta_wayland_keyboard_broadcast_modifiers (grab->keyboard);
 
668
}
 
669
 
 
670
static const MetaWaylandKeyboardGrabInterface default_keyboard_grab_interface = {
 
671
  default_grab_key,
 
672
  default_grab_modifiers
 
673
};
 
674
 
 
675
void
 
676
meta_wayland_keyboard_enable (MetaWaylandKeyboard *keyboard)
 
677
{
 
678
  MetaBackend *backend = meta_get_backend ();
 
679
  GSettingsSchema *schema;
 
680
 
 
681
  keyboard->settings = g_settings_new ("org.gnome.desktop.peripherals.keyboard");
 
682
  g_signal_connect (keyboard->settings, "changed",
 
683
                    G_CALLBACK (settings_changed), keyboard);
 
684
 
 
685
  /* We are cheating for now, we use g-s-d settings... Check if available */
 
686
  schema = g_settings_schema_source_lookup (g_settings_schema_source_get_default (),
 
687
                                            GSD_KEYBOARD_SCHEMA,
 
688
                                            TRUE);
 
689
  if (schema)
 
690
    {
 
691
      keyboard->gsd_settings = g_settings_new_full (schema, NULL, NULL);
 
692
      g_settings_schema_unref (schema);
 
693
      g_signal_connect (keyboard->gsd_settings, "changed::remember-numlock-state",
 
694
                        G_CALLBACK (remember_numlock_state_changed), keyboard);
 
695
    }
 
696
 
 
697
  g_signal_connect (backend, "keymap-changed",
 
698
                    G_CALLBACK (on_keymap_changed), keyboard);
 
699
  g_signal_connect (backend, "keymap-layout-group-changed",
 
700
                    G_CALLBACK (on_keymap_layout_group_changed), keyboard);
 
701
 
 
702
  g_signal_connect (clutter_device_manager_get_default (), "kbd-a11y-mods-state-changed",
 
703
                    G_CALLBACK (on_kbd_a11y_mask_changed), keyboard);
 
704
 
 
705
  meta_wayland_keyboard_take_keymap (keyboard, meta_backend_get_keymap (backend));
 
706
 
 
707
  maybe_restore_numlock_state (keyboard);
 
708
}
 
709
 
 
710
static void
 
711
meta_wayland_xkb_info_init (MetaWaylandXkbInfo *xkb_info)
 
712
{
 
713
  xkb_info->keymap_fd = -1;
 
714
}
 
715
 
 
716
static void
 
717
meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
 
718
{
 
719
  g_clear_pointer (&xkb_info->keymap, xkb_keymap_unref);
 
720
  g_clear_pointer (&xkb_info->state, xkb_state_unref);
 
721
 
 
722
  if (xkb_info->keymap_area)
 
723
    {
 
724
      munmap (xkb_info->keymap_area, xkb_info->keymap_size);
 
725
      xkb_info->keymap_area = NULL;
 
726
    }
 
727
  if (xkb_info->keymap_fd >= 0)
 
728
    {
 
729
      close (xkb_info->keymap_fd);
 
730
      xkb_info->keymap_fd = -1;
 
731
    }
 
732
}
 
733
 
 
734
void
 
735
meta_wayland_keyboard_disable (MetaWaylandKeyboard *keyboard)
 
736
{
 
737
  MetaBackend *backend = meta_get_backend ();
 
738
 
 
739
  g_signal_handlers_disconnect_by_func (backend, on_keymap_changed, keyboard);
 
740
  g_signal_handlers_disconnect_by_func (backend, on_keymap_layout_group_changed, keyboard);
 
741
 
 
742
  meta_wayland_keyboard_end_grab (keyboard);
 
743
  meta_wayland_keyboard_set_focus (keyboard, NULL);
 
744
  meta_wayland_xkb_info_destroy (&keyboard->xkb_info);
 
745
 
 
746
  wl_list_remove (&keyboard->resource_list);
 
747
  wl_list_init (&keyboard->resource_list);
 
748
  wl_list_remove (&keyboard->focus_resource_list);
 
749
  wl_list_init (&keyboard->focus_resource_list);
 
750
 
 
751
  g_clear_object (&keyboard->settings);
 
752
  if (keyboard->gsd_settings)
 
753
    g_object_unref (keyboard->gsd_settings);
 
754
}
 
755
 
 
756
static guint
 
757
evdev_code (const ClutterKeyEvent *event)
 
758
{
 
759
  /* clutter-xkb-utils.c adds a fixed offset of 8 to go into XKB's
 
760
   * range, so we do the reverse here. */
 
761
  return event->hardware_keycode - 8;
 
762
}
 
763
 
 
764
void
 
765
meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard,
 
766
                              const ClutterKeyEvent *event)
 
767
{
 
768
  gboolean is_press = event->type == CLUTTER_KEY_PRESS;
 
769
 
 
770
  /* If we get a key event but still have pending modifier state
 
771
   * changes from a previous event that didn't get cleared, we need to
 
772
   * send that state right away so that the new key event can be
 
773
   * interpreted by clients correctly modified. */
 
774
  if (keyboard->mods_changed)
 
775
    notify_modifiers (keyboard);
 
776
 
 
777
  keyboard->mods_changed = xkb_state_update_key (keyboard->xkb_info.state,
 
778
                                                 event->hardware_keycode,
 
779
                                                 is_press ? XKB_KEY_DOWN : XKB_KEY_UP);
 
780
  keyboard->mods_changed |= kbd_a11y_apply_mask (keyboard);
 
781
}
 
782
 
 
783
gboolean
 
784
meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
 
785
                                    const ClutterKeyEvent *event)
 
786
{
 
787
  gboolean is_press = event->type == CLUTTER_KEY_PRESS;
 
788
  gboolean handled;
 
789
 
 
790
  /* Synthetic key events are for autorepeat. Ignore those, as
 
791
   * autorepeat in Wayland is done on the client side. */
 
792
  if ((event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC) &&
 
793
      !(event->flags & CLUTTER_EVENT_FLAG_INPUT_METHOD))
 
794
    return FALSE;
 
795
 
 
796
  meta_verbose ("Handling key %s event code %d\n",
 
797
                is_press ? "press" : "release",
 
798
                event->hardware_keycode);
 
799
 
 
800
  handled = notify_key (keyboard, (const ClutterEvent *) event);
 
801
 
 
802
  if (handled)
 
803
    meta_verbose ("Sent event to wayland client\n");
 
804
  else
 
805
    meta_verbose ("No wayland surface is focused, continuing normal operation\n");
 
806
 
 
807
  if (keyboard->mods_changed != 0)
 
808
    {
 
809
      if (keyboard->mods_changed & XKB_STATE_MODS_LOCKED)
 
810
        maybe_save_numlock_state (keyboard);
 
811
      notify_modifiers (keyboard);
 
812
      keyboard->mods_changed = 0;
 
813
    }
 
814
 
 
815
  return handled;
 
816
}
 
817
 
 
818
void
 
819
meta_wayland_keyboard_update_key_state (MetaWaylandKeyboard *keyboard,
 
820
                                        char                *key_vector,
 
821
                                        int                  key_vector_len,
 
822
                                        int                  offset)
 
823
{
 
824
  gboolean mods_changed = FALSE;
 
825
 
 
826
  int i;
 
827
  for (i = offset; i < key_vector_len * 8; i++)
 
828
    {
 
829
      gboolean set = (key_vector[i/8] & (1 << (i % 8))) != 0;
 
830
 
 
831
      /* The 'offset' parameter allows the caller to have the indices
 
832
       * into key_vector to either be X-style (base 8) or evdev (base 0), or
 
833
       * something else (unlikely). We subtract 'offset' to convert to evdev
 
834
       * style, then add 8 to convert the "evdev" style keycode back to
 
835
       * the X-style that xkbcommon expects.
 
836
       */
 
837
      mods_changed |= xkb_state_update_key (keyboard->xkb_info.state,
 
838
                                            i - offset + 8,
 
839
                                            set ? XKB_KEY_DOWN : XKB_KEY_UP);
 
840
    }
 
841
 
 
842
  mods_changed |= kbd_a11y_apply_mask (keyboard);
 
843
  if (mods_changed)
 
844
    notify_modifiers (keyboard);
 
845
}
 
846
 
 
847
static void
 
848
move_resources (struct wl_list *destination, struct wl_list *source)
 
849
{
 
850
  wl_list_insert_list (destination, source);
 
851
  wl_list_init (source);
 
852
}
 
853
 
 
854
static void
 
855
move_resources_for_client (struct wl_list *destination,
 
856
                           struct wl_list *source,
 
857
                           struct wl_client *client)
 
858
{
 
859
  struct wl_resource *resource, *tmp;
 
860
  wl_resource_for_each_safe (resource, tmp, source)
 
861
    {
 
862
      if (wl_resource_get_client (resource) == client)
 
863
        {
 
864
          wl_list_remove (wl_resource_get_link (resource));
 
865
          wl_list_insert (destination, wl_resource_get_link (resource));
 
866
        }
 
867
    }
 
868
}
 
869
 
 
870
static void
 
871
broadcast_focus (MetaWaylandKeyboard *keyboard,
 
872
                 struct wl_resource  *resource)
 
873
{
 
874
  struct wl_array fake_keys;
 
875
 
 
876
  /* We never want to send pressed keys to wayland clients on
 
877
   * enter. The protocol says that we should send them, presumably so
 
878
   * that clients can trigger their own key repeat routine in case
 
879
   * they are given focus and a key is physically pressed.
 
880
   *
 
881
   * Unfortunately this causes some clients, in particular Xwayland,
 
882
   * to register key events that they really shouldn't handle,
 
883
   * e.g. on an Alt+Tab keybinding, where Alt is released before Tab,
 
884
   * clients would see Tab being pressed on enter followed by a key
 
885
   * release event for Tab, meaning that Tab would be processed by
 
886
   * the client when it really shouldn't.
 
887
   *
 
888
   * Since the use case for the pressed keys array on enter seems weak
 
889
   * to us, we'll just fake that there are no pressed keys instead
 
890
   * which should be spec compliant even if it might not be true.
 
891
   */
 
892
  wl_array_init (&fake_keys);
 
893
 
 
894
  keyboard_send_modifiers (keyboard, resource, keyboard->focus_serial);
 
895
  wl_keyboard_send_enter (resource, keyboard->focus_serial,
 
896
                          keyboard->focus_surface->resource,
 
897
                          &fake_keys);
 
898
}
 
899
 
 
900
void
 
901
meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
 
902
                                 MetaWaylandSurface *surface)
 
903
{
 
904
  MetaWaylandInputDevice *input_device = META_WAYLAND_INPUT_DEVICE (keyboard);
 
905
 
 
906
  if (keyboard->focus_surface == surface)
 
907
    return;
 
908
 
 
909
  if (keyboard->focus_surface != NULL)
 
910
    {
 
911
      if (!wl_list_empty (&keyboard->focus_resource_list))
 
912
        {
 
913
          struct wl_resource *resource;
 
914
          uint32_t serial;
 
915
 
 
916
          serial = meta_wayland_input_device_next_serial (input_device);
 
917
 
 
918
          wl_resource_for_each (resource, &keyboard->focus_resource_list)
 
919
            {
 
920
              wl_keyboard_send_leave (resource, serial,
 
921
                                      keyboard->focus_surface->resource);
 
922
            }
 
923
 
 
924
          move_resources (&keyboard->resource_list,
 
925
                          &keyboard->focus_resource_list);
 
926
        }
 
927
 
 
928
      wl_list_remove (&keyboard->focus_surface_listener.link);
 
929
      keyboard->focus_surface = NULL;
 
930
    }
 
931
 
 
932
  if (surface != NULL)
 
933
    {
 
934
      struct wl_resource *focus_surface_resource;
 
935
 
 
936
      keyboard->focus_surface = surface;
 
937
      focus_surface_resource = keyboard->focus_surface->resource;
 
938
      wl_resource_add_destroy_listener (focus_surface_resource,
 
939
                                        &keyboard->focus_surface_listener);
 
940
 
 
941
      move_resources_for_client (&keyboard->focus_resource_list,
 
942
                                 &keyboard->resource_list,
 
943
                                 wl_resource_get_client (focus_surface_resource));
 
944
 
 
945
      /* Make sure a11y masks are applied before braodcasting modifiers */
 
946
      kbd_a11y_apply_mask (keyboard);
 
947
 
 
948
      if (!wl_list_empty (&keyboard->focus_resource_list))
 
949
        {
 
950
          struct wl_resource *resource;
 
951
 
 
952
          keyboard->focus_serial =
 
953
            meta_wayland_input_device_next_serial (input_device);
 
954
 
 
955
          wl_resource_for_each (resource, &keyboard->focus_resource_list)
 
956
            {
 
957
              broadcast_focus (keyboard, resource);
 
958
            }
 
959
        }
 
960
    }
 
961
}
 
962
 
 
963
struct wl_client *
 
964
meta_wayland_keyboard_get_focus_client (MetaWaylandKeyboard *keyboard)
 
965
{
 
966
  if (keyboard->focus_surface)
 
967
    return wl_resource_get_client (keyboard->focus_surface->resource);
 
968
  else
 
969
    return NULL;
 
970
}
 
971
 
 
972
static void
 
973
keyboard_release (struct wl_client *client,
 
974
                  struct wl_resource *resource)
 
975
{
 
976
  wl_resource_destroy (resource);
 
977
}
 
978
 
 
979
static const struct wl_keyboard_interface keyboard_interface = {
 
980
  keyboard_release,
 
981
};
 
982
 
 
983
void
 
984
meta_wayland_keyboard_create_new_resource (MetaWaylandKeyboard *keyboard,
 
985
                                           struct wl_client    *client,
 
986
                                           struct wl_resource  *seat_resource,
 
987
                                           uint32_t id)
 
988
{
 
989
  struct wl_resource *resource;
 
990
 
 
991
  resource = wl_resource_create (client, &wl_keyboard_interface,
 
992
                                 wl_resource_get_version (seat_resource), id);
 
993
  wl_resource_set_implementation (resource, &keyboard_interface,
 
994
                                  keyboard, unbind_resource);
 
995
 
 
996
  wl_keyboard_send_keymap (resource,
 
997
                           WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
 
998
                           keyboard->xkb_info.keymap_fd,
 
999
                           keyboard->xkb_info.keymap_size);
 
1000
 
 
1001
  notify_key_repeat_for_resource (keyboard, resource);
 
1002
 
 
1003
  if (keyboard->focus_surface &&
 
1004
      wl_resource_get_client (keyboard->focus_surface->resource) == client)
 
1005
    {
 
1006
      wl_list_insert (&keyboard->focus_resource_list,
 
1007
                      wl_resource_get_link (resource));
 
1008
      broadcast_focus (keyboard, resource);
 
1009
    }
 
1010
  else
 
1011
    {
 
1012
      wl_list_insert (&keyboard->resource_list,
 
1013
                      wl_resource_get_link (resource));
 
1014
    }
 
1015
}
 
1016
 
 
1017
gboolean
 
1018
meta_wayland_keyboard_can_popup (MetaWaylandKeyboard *keyboard,
 
1019
                                 uint32_t             serial)
 
1020
{
 
1021
  return keyboard->key_serial == serial;
 
1022
}
 
1023
 
 
1024
void
 
1025
meta_wayland_keyboard_start_grab (MetaWaylandKeyboard     *keyboard,
 
1026
                                  MetaWaylandKeyboardGrab *grab)
 
1027
{
 
1028
  meta_wayland_keyboard_set_focus (keyboard, NULL);
 
1029
  keyboard->grab = grab;
 
1030
  grab->keyboard = keyboard;
 
1031
}
 
1032
 
 
1033
void
 
1034
meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard)
 
1035
{
 
1036
  keyboard->grab = &keyboard->default_grab;
 
1037
}
 
1038
 
 
1039
static void
 
1040
meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard)
 
1041
{
 
1042
  wl_list_init (&keyboard->resource_list);
 
1043
  wl_list_init (&keyboard->focus_resource_list);
 
1044
 
 
1045
  meta_wayland_xkb_info_init (&keyboard->xkb_info);
 
1046
 
 
1047
  keyboard->default_grab.interface = &default_keyboard_grab_interface;
 
1048
  keyboard->default_grab.keyboard = keyboard;
 
1049
  keyboard->grab = &keyboard->default_grab;
 
1050
 
 
1051
  keyboard->focus_surface_listener.notify =
 
1052
    keyboard_handle_focus_surface_destroy;
 
1053
}
 
1054
 
 
1055
static void
 
1056
meta_wayland_keyboard_class_init (MetaWaylandKeyboardClass *klass)
 
1057
{
 
1058
}