blob: 5aa8b6e48d2b48b044b846399d895ac7e90f9eb1 [file] [log] [blame]
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +02001/*
Pekka Paalanen2829f7c2015-02-19 17:02:13 +02002 * Copyright © 2011-2012 Intel Corporation
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +02003 *
Bryce Harringtona0bbfea2015-06-11 15:35:43 -07004 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +020011 *
Bryce Harringtona0bbfea2015-06-11 15:35:43 -070012 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +020024 */
25
Daniel Stonec228e232013-05-22 18:03:19 +030026#include "config.h"
27
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +020028#include <stdlib.h>
Pekka Paalanen2829f7c2015-02-19 17:02:13 +020029#include <linux/input.h>
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +020030
31#include "compositor.h"
32
33struct weston_binding {
34 uint32_t key;
35 uint32_t button;
36 uint32_t axis;
37 uint32_t modifier;
38 void *handler;
39 void *data;
40 struct wl_list link;
41};
42
43static struct weston_binding *
44weston_compositor_add_binding(struct weston_compositor *compositor,
45 uint32_t key, uint32_t button, uint32_t axis,
46 uint32_t modifier, void *handler, void *data)
47{
48 struct weston_binding *binding;
49
50 binding = malloc(sizeof *binding);
51 if (binding == NULL)
52 return NULL;
53
54 binding->key = key;
55 binding->button = button;
56 binding->axis = axis;
57 binding->modifier = modifier;
58 binding->handler = handler;
59 binding->data = data;
60
61 return binding;
62}
63
64WL_EXPORT struct weston_binding *
65weston_compositor_add_key_binding(struct weston_compositor *compositor,
66 uint32_t key, uint32_t modifier,
67 weston_key_binding_handler_t handler,
68 void *data)
69{
70 struct weston_binding *binding;
71
72 binding = weston_compositor_add_binding(compositor, key, 0, 0,
73 modifier, handler, data);
74 if (binding == NULL)
75 return NULL;
76
77 wl_list_insert(compositor->key_binding_list.prev, &binding->link);
78
79 return binding;
80}
81
82WL_EXPORT struct weston_binding *
Daniel Stone96d47c02013-11-19 11:37:12 +010083weston_compositor_add_modifier_binding(struct weston_compositor *compositor,
84 uint32_t modifier,
85 weston_modifier_binding_handler_t handler,
86 void *data)
87{
88 struct weston_binding *binding;
89
90 binding = weston_compositor_add_binding(compositor, 0, 0, 0,
91 modifier, handler, data);
92 if (binding == NULL)
93 return NULL;
94
95 wl_list_insert(compositor->modifier_binding_list.prev, &binding->link);
96
97 return binding;
98}
99
100WL_EXPORT struct weston_binding *
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200101weston_compositor_add_button_binding(struct weston_compositor *compositor,
102 uint32_t button, uint32_t modifier,
103 weston_button_binding_handler_t handler,
104 void *data)
105{
106 struct weston_binding *binding;
107
108 binding = weston_compositor_add_binding(compositor, 0, button, 0,
109 modifier, handler, data);
110 if (binding == NULL)
111 return NULL;
112
113 wl_list_insert(compositor->button_binding_list.prev, &binding->link);
114
115 return binding;
116}
117
118WL_EXPORT struct weston_binding *
Neil Robertsa28c6932013-10-03 16:43:04 +0100119weston_compositor_add_touch_binding(struct weston_compositor *compositor,
120 uint32_t modifier,
121 weston_touch_binding_handler_t handler,
122 void *data)
123{
124 struct weston_binding *binding;
125
126 binding = weston_compositor_add_binding(compositor, 0, 0, 0,
127 modifier, handler, data);
128 if (binding == NULL)
129 return NULL;
130
131 wl_list_insert(compositor->touch_binding_list.prev, &binding->link);
132
133 return binding;
134}
135
136WL_EXPORT struct weston_binding *
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200137weston_compositor_add_axis_binding(struct weston_compositor *compositor,
138 uint32_t axis, uint32_t modifier,
139 weston_axis_binding_handler_t handler,
140 void *data)
141{
142 struct weston_binding *binding;
143
144 binding = weston_compositor_add_binding(compositor, 0, 0, axis,
145 modifier, handler, data);
146 if (binding == NULL)
147 return NULL;
148
149 wl_list_insert(compositor->axis_binding_list.prev, &binding->link);
150
151 return binding;
152}
153
154WL_EXPORT struct weston_binding *
155weston_compositor_add_debug_binding(struct weston_compositor *compositor,
156 uint32_t key,
157 weston_key_binding_handler_t handler,
158 void *data)
159{
160 struct weston_binding *binding;
161
162 binding = weston_compositor_add_binding(compositor, key, 0, 0, 0,
163 handler, data);
164
165 wl_list_insert(compositor->debug_binding_list.prev, &binding->link);
166
167 return binding;
168}
169
170WL_EXPORT void
171weston_binding_destroy(struct weston_binding *binding)
172{
173 wl_list_remove(&binding->link);
174 free(binding);
175}
176
177WL_EXPORT void
178weston_binding_list_destroy_all(struct wl_list *list)
179{
180 struct weston_binding *binding, *tmp;
181
182 wl_list_for_each_safe(binding, tmp, list, link)
183 weston_binding_destroy(binding);
184}
185
186struct binding_keyboard_grab {
187 uint32_t key;
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400188 struct weston_keyboard_grab grab;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200189};
190
191static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400192binding_key(struct weston_keyboard_grab *grab,
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200193 uint32_t time, uint32_t key, uint32_t state_w)
194{
195 struct binding_keyboard_grab *b =
196 container_of(grab, struct binding_keyboard_grab, grab);
197 struct wl_resource *resource;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200198 enum wl_keyboard_key_state state = state_w;
199 uint32_t serial;
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400200 struct weston_keyboard *keyboard = grab->keyboard;
Rob Bradford880ebc72013-07-22 17:31:38 +0100201 struct wl_display *display = keyboard->seat->compositor->wl_display;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200202
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200203 if (key == b->key) {
204 if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400205 weston_keyboard_end_grab(grab->keyboard);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200206 if (keyboard->input_method_resource)
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400207 keyboard->grab = &keyboard->input_method_grab;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200208 free(b);
Giulio Camuffo943b46e2014-12-05 18:02:58 +0200209 } else {
210 /* Don't send the key press event for the binding key */
211 return;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200212 }
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200213 }
214 if (!wl_list_empty(&keyboard->focus_resource_list)) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200215 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100216 wl_resource_for_each(resource, &keyboard->focus_resource_list) {
217 wl_keyboard_send_key(resource,
218 serial,
219 time,
220 key,
221 state);
222 }
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200223 }
224}
225
226static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400227binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200228 uint32_t mods_depressed, uint32_t mods_latched,
229 uint32_t mods_locked, uint32_t group)
230{
231 struct wl_resource *resource;
232
Neil Roberts96d790e2013-09-19 17:32:00 +0100233 wl_resource_for_each(resource, &grab->keyboard->focus_resource_list) {
234 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
235 mods_latched, mods_locked, group);
236 }
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200237}
238
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200239static void
240binding_cancel(struct weston_keyboard_grab *grab)
241{
242 struct binding_keyboard_grab *binding_grab =
243 container_of(grab, struct binding_keyboard_grab, grab);
244
245 weston_keyboard_end_grab(grab->keyboard);
246 free(binding_grab);
247}
248
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400249static const struct weston_keyboard_grab_interface binding_grab = {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200250 binding_key,
251 binding_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200252 binding_cancel,
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200253};
254
255static void
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200256install_binding_grab(struct weston_seat *seat, uint32_t time, uint32_t key,
257 struct weston_surface *focus)
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200258{
259 struct binding_keyboard_grab *grab;
260
261 grab = malloc(sizeof *grab);
262 grab->key = key;
263 grab->grab.interface = &binding_grab;
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400264 weston_keyboard_start_grab(seat->keyboard, &grab->grab);
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200265
266 /* Notify the surface which had the focus before this binding
267 * triggered that we stole a keypress from under it, by forcing
268 * a wl_keyboard leave/enter pair. The enter event will contain
269 * the pressed key in the keys array, so the client will know
270 * the exact state of the keyboard.
271 * If the old focus surface is different than the new one it
272 * means it was changed in the binding handler, so it received
273 * the enter event already. */
274 if (focus && seat->keyboard->focus == focus) {
275 weston_keyboard_set_focus(seat->keyboard, NULL);
276 weston_keyboard_set_focus(seat->keyboard, focus);
277 }
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200278}
279
Pekka Paalanen86b53962014-11-19 13:43:32 +0200280WL_EXPORT void
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200281weston_compositor_run_key_binding(struct weston_compositor *compositor,
282 struct weston_seat *seat,
283 uint32_t time, uint32_t key,
284 enum wl_keyboard_key_state state)
285{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300286 struct weston_binding *b, *tmp;
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200287 struct weston_surface *focus;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200288
289 if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
Pekka Paalanen86b53962014-11-19 13:43:32 +0200290 return;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200291
Daniel Stone96d47c02013-11-19 11:37:12 +0100292 /* Invalidate all active modifier bindings. */
293 wl_list_for_each(b, &compositor->modifier_binding_list, link)
294 b->key = key;
295
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300296 wl_list_for_each_safe(b, tmp, &compositor->key_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200297 if (b->key == key && b->modifier == seat->modifier_state) {
298 weston_key_binding_handler_t handler = b->handler;
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200299 focus = seat->keyboard->focus;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400300 handler(seat, time, key, b->data);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200301
302 /* If this was a key binding and it didn't
303 * install a keyboard grab, install one now to
Giulio Camuffo943b46e2014-12-05 18:02:58 +0200304 * swallow the key press. */
Kristian Høgsberge3148752013-05-06 23:19:49 -0400305 if (seat->keyboard->grab ==
306 &seat->keyboard->default_grab)
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200307 install_binding_grab(seat, time, key, focus);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200308 }
309 }
310}
311
312WL_EXPORT void
Daniel Stone96d47c02013-11-19 11:37:12 +0100313weston_compositor_run_modifier_binding(struct weston_compositor *compositor,
314 struct weston_seat *seat,
315 enum weston_keyboard_modifier modifier,
316 enum wl_keyboard_key_state state)
317{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300318 struct weston_binding *b, *tmp;
Daniel Stone96d47c02013-11-19 11:37:12 +0100319
Emilio Pozuelo Monfort1539ea22013-11-27 10:34:32 +0100320 if (seat->keyboard->grab != &seat->keyboard->default_grab)
321 return;
322
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300323 wl_list_for_each_safe(b, tmp, &compositor->modifier_binding_list, link) {
Daniel Stone96d47c02013-11-19 11:37:12 +0100324 weston_modifier_binding_handler_t handler = b->handler;
325
326 if (b->modifier != modifier)
327 continue;
328
329 /* Prime the modifier binding. */
330 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
331 b->key = 0;
332 continue;
333 }
334 /* Ignore the binding if a key was pressed in between. */
335 else if (b->key != 0) {
336 return;
337 }
338
339 handler(seat, modifier, b->data);
340 }
341}
342
343WL_EXPORT void
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200344weston_compositor_run_button_binding(struct weston_compositor *compositor,
345 struct weston_seat *seat,
346 uint32_t time, uint32_t button,
347 enum wl_pointer_button_state state)
348{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300349 struct weston_binding *b, *tmp;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200350
351 if (state == WL_POINTER_BUTTON_STATE_RELEASED)
352 return;
353
Daniel Stone96d47c02013-11-19 11:37:12 +0100354 /* Invalidate all active modifier bindings. */
355 wl_list_for_each(b, &compositor->modifier_binding_list, link)
356 b->key = button;
357
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300358 wl_list_for_each_safe(b, tmp, &compositor->button_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200359 if (b->button == button && b->modifier == seat->modifier_state) {
360 weston_button_binding_handler_t handler = b->handler;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400361 handler(seat, time, button, b->data);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200362 }
363 }
364}
365
Neil Robertsa28c6932013-10-03 16:43:04 +0100366WL_EXPORT void
367weston_compositor_run_touch_binding(struct weston_compositor *compositor,
368 struct weston_seat *seat, uint32_t time,
369 int touch_type)
370{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300371 struct weston_binding *b, *tmp;
Neil Robertsa28c6932013-10-03 16:43:04 +0100372
Jonas Ådahl9484b692013-12-02 22:05:03 +0100373 if (seat->touch->num_tp != 1 || touch_type != WL_TOUCH_DOWN)
Neil Robertsa28c6932013-10-03 16:43:04 +0100374 return;
375
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300376 wl_list_for_each_safe(b, tmp, &compositor->touch_binding_list, link) {
Neil Robertsa28c6932013-10-03 16:43:04 +0100377 if (b->modifier == seat->modifier_state) {
378 weston_touch_binding_handler_t handler = b->handler;
379 handler(seat, time, b->data);
380 }
381 }
382}
383
Rune K. Svendsen14b2fe72013-03-07 21:50:00 +0100384WL_EXPORT int
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200385weston_compositor_run_axis_binding(struct weston_compositor *compositor,
386 struct weston_seat *seat,
387 uint32_t time, uint32_t axis,
388 wl_fixed_t value)
389{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300390 struct weston_binding *b, *tmp;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200391
Daniel Stone96d47c02013-11-19 11:37:12 +0100392 /* Invalidate all active modifier bindings. */
393 wl_list_for_each(b, &compositor->modifier_binding_list, link)
394 b->key = axis;
395
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300396 wl_list_for_each_safe(b, tmp, &compositor->axis_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200397 if (b->axis == axis && b->modifier == seat->modifier_state) {
398 weston_axis_binding_handler_t handler = b->handler;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400399 handler(seat, time, axis, value, b->data);
Rune K. Svendsen14b2fe72013-03-07 21:50:00 +0100400 return 1;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200401 }
402 }
Rune K. Svendsen14b2fe72013-03-07 21:50:00 +0100403
404 return 0;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200405}
406
407WL_EXPORT int
408weston_compositor_run_debug_binding(struct weston_compositor *compositor,
409 struct weston_seat *seat,
410 uint32_t time, uint32_t key,
411 enum wl_keyboard_key_state state)
412{
413 weston_key_binding_handler_t handler;
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300414 struct weston_binding *binding, *tmp;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200415 int count = 0;
416
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300417 wl_list_for_each_safe(binding, tmp, &compositor->debug_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200418 if (key != binding->key)
419 continue;
420
421 count++;
422 handler = binding->handler;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400423 handler(seat, time, key, binding->data);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200424 }
425
426 return count;
427}
Pekka Paalanen2829f7c2015-02-19 17:02:13 +0200428
429struct debug_binding_grab {
430 struct weston_keyboard_grab grab;
431 struct weston_seat *seat;
432 uint32_t key[2];
433 int key_released[2];
434};
435
436static void
437debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time,
438 uint32_t key, uint32_t state)
439{
440 struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
441 struct weston_compositor *ec = db->seat->compositor;
442 struct wl_display *display = ec->wl_display;
443 struct wl_resource *resource;
444 uint32_t serial;
445 int send = 0, terminate = 0;
446 int check_binding = 1;
447 int i;
448 struct wl_list *resource_list;
449
450 if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
451 /* Do not run bindings on key releases */
452 check_binding = 0;
453
454 for (i = 0; i < 2; i++)
455 if (key == db->key[i])
456 db->key_released[i] = 1;
457
458 if (db->key_released[0] && db->key_released[1]) {
459 /* All key releases been swalled so end the grab */
460 terminate = 1;
461 } else if (key != db->key[0] && key != db->key[1]) {
462 /* Should not swallow release of other keys */
463 send = 1;
464 }
465 } else if (key == db->key[0] && !db->key_released[0]) {
466 /* Do not check bindings for the first press of the binding
467 * key. This allows it to be used as a debug shortcut.
468 * We still need to swallow this event. */
469 check_binding = 0;
470 } else if (db->key[1]) {
471 /* If we already ran a binding don't process another one since
472 * we can't keep track of all the binding keys that were
473 * pressed in order to swallow the release events. */
474 send = 1;
475 check_binding = 0;
476 }
477
478 if (check_binding) {
479 if (weston_compositor_run_debug_binding(ec, db->seat, time,
480 key, state)) {
481 /* We ran a binding so swallow the press and keep the
482 * grab to swallow the released too. */
483 send = 0;
484 terminate = 0;
485 db->key[1] = key;
486 } else {
487 /* Terminate the grab since the key pressed is not a
488 * debug binding key. */
489 send = 1;
490 terminate = 1;
491 }
492 }
493
494 if (send) {
495 serial = wl_display_next_serial(display);
496 resource_list = &grab->keyboard->focus_resource_list;
497 wl_resource_for_each(resource, resource_list) {
498 wl_keyboard_send_key(resource, serial, time, key, state);
499 }
500 }
501
502 if (terminate) {
503 weston_keyboard_end_grab(grab->keyboard);
504 if (grab->keyboard->input_method_resource)
505 grab->keyboard->grab = &grab->keyboard->input_method_grab;
506 free(db);
507 }
508}
509
510static void
511debug_binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
512 uint32_t mods_depressed, uint32_t mods_latched,
513 uint32_t mods_locked, uint32_t group)
514{
515 struct wl_resource *resource;
516 struct wl_list *resource_list;
517
518 resource_list = &grab->keyboard->focus_resource_list;
519
520 wl_resource_for_each(resource, resource_list) {
521 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
522 mods_latched, mods_locked, group);
523 }
524}
525
526static void
527debug_binding_cancel(struct weston_keyboard_grab *grab)
528{
529 struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
530
531 weston_keyboard_end_grab(grab->keyboard);
532 free(db);
533}
534
535struct weston_keyboard_grab_interface debug_binding_keyboard_grab = {
536 debug_binding_key,
537 debug_binding_modifiers,
538 debug_binding_cancel,
539};
540
541static void
542debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
543{
544 struct debug_binding_grab *grab;
545
546 grab = calloc(1, sizeof *grab);
547 if (!grab)
548 return;
549
550 grab->seat = seat;
551 grab->key[0] = key;
552 grab->grab.interface = &debug_binding_keyboard_grab;
553 weston_keyboard_start_grab(seat->keyboard, &grab->grab);
554}
555
556/** Install the trigger binding for debug bindings.
557 *
558 * \param compositor The compositor.
559 * \param mod The modifier.
560 *
561 * This will add a key binding for modifier+SHIFT+SPACE that will trigger
562 * debug key bindings.
563 */
564WL_EXPORT void
565weston_install_debug_key_binding(struct weston_compositor *compositor,
566 uint32_t mod)
567{
568 weston_compositor_add_key_binding(compositor, KEY_SPACE,
569 mod | MODIFIER_SHIFT,
570 debug_binding, NULL);
571}