blob: 6aeed916b5d95790dcb820d4b5ddb0c79a18eb62 [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 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
Daniel Stonec228e232013-05-22 18:03:19 +030023#include "config.h"
24
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +020025#include <stdlib.h>
Pekka Paalanen2829f7c2015-02-19 17:02:13 +020026#include <linux/input.h>
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +020027
28#include "compositor.h"
29
30struct weston_binding {
31 uint32_t key;
32 uint32_t button;
33 uint32_t axis;
34 uint32_t modifier;
35 void *handler;
36 void *data;
37 struct wl_list link;
38};
39
40static struct weston_binding *
41weston_compositor_add_binding(struct weston_compositor *compositor,
42 uint32_t key, uint32_t button, uint32_t axis,
43 uint32_t modifier, void *handler, void *data)
44{
45 struct weston_binding *binding;
46
47 binding = malloc(sizeof *binding);
48 if (binding == NULL)
49 return NULL;
50
51 binding->key = key;
52 binding->button = button;
53 binding->axis = axis;
54 binding->modifier = modifier;
55 binding->handler = handler;
56 binding->data = data;
57
58 return binding;
59}
60
61WL_EXPORT struct weston_binding *
62weston_compositor_add_key_binding(struct weston_compositor *compositor,
63 uint32_t key, uint32_t modifier,
64 weston_key_binding_handler_t handler,
65 void *data)
66{
67 struct weston_binding *binding;
68
69 binding = weston_compositor_add_binding(compositor, key, 0, 0,
70 modifier, handler, data);
71 if (binding == NULL)
72 return NULL;
73
74 wl_list_insert(compositor->key_binding_list.prev, &binding->link);
75
76 return binding;
77}
78
79WL_EXPORT struct weston_binding *
Daniel Stone96d47c02013-11-19 11:37:12 +010080weston_compositor_add_modifier_binding(struct weston_compositor *compositor,
81 uint32_t modifier,
82 weston_modifier_binding_handler_t handler,
83 void *data)
84{
85 struct weston_binding *binding;
86
87 binding = weston_compositor_add_binding(compositor, 0, 0, 0,
88 modifier, handler, data);
89 if (binding == NULL)
90 return NULL;
91
92 wl_list_insert(compositor->modifier_binding_list.prev, &binding->link);
93
94 return binding;
95}
96
97WL_EXPORT struct weston_binding *
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +020098weston_compositor_add_button_binding(struct weston_compositor *compositor,
99 uint32_t button, uint32_t modifier,
100 weston_button_binding_handler_t handler,
101 void *data)
102{
103 struct weston_binding *binding;
104
105 binding = weston_compositor_add_binding(compositor, 0, button, 0,
106 modifier, handler, data);
107 if (binding == NULL)
108 return NULL;
109
110 wl_list_insert(compositor->button_binding_list.prev, &binding->link);
111
112 return binding;
113}
114
115WL_EXPORT struct weston_binding *
Neil Robertsa28c6932013-10-03 16:43:04 +0100116weston_compositor_add_touch_binding(struct weston_compositor *compositor,
117 uint32_t modifier,
118 weston_touch_binding_handler_t handler,
119 void *data)
120{
121 struct weston_binding *binding;
122
123 binding = weston_compositor_add_binding(compositor, 0, 0, 0,
124 modifier, handler, data);
125 if (binding == NULL)
126 return NULL;
127
128 wl_list_insert(compositor->touch_binding_list.prev, &binding->link);
129
130 return binding;
131}
132
133WL_EXPORT struct weston_binding *
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200134weston_compositor_add_axis_binding(struct weston_compositor *compositor,
135 uint32_t axis, uint32_t modifier,
136 weston_axis_binding_handler_t handler,
137 void *data)
138{
139 struct weston_binding *binding;
140
141 binding = weston_compositor_add_binding(compositor, 0, 0, axis,
142 modifier, handler, data);
143 if (binding == NULL)
144 return NULL;
145
146 wl_list_insert(compositor->axis_binding_list.prev, &binding->link);
147
148 return binding;
149}
150
151WL_EXPORT struct weston_binding *
152weston_compositor_add_debug_binding(struct weston_compositor *compositor,
153 uint32_t key,
154 weston_key_binding_handler_t handler,
155 void *data)
156{
157 struct weston_binding *binding;
158
159 binding = weston_compositor_add_binding(compositor, key, 0, 0, 0,
160 handler, data);
161
162 wl_list_insert(compositor->debug_binding_list.prev, &binding->link);
163
164 return binding;
165}
166
167WL_EXPORT void
168weston_binding_destroy(struct weston_binding *binding)
169{
170 wl_list_remove(&binding->link);
171 free(binding);
172}
173
174WL_EXPORT void
175weston_binding_list_destroy_all(struct wl_list *list)
176{
177 struct weston_binding *binding, *tmp;
178
179 wl_list_for_each_safe(binding, tmp, list, link)
180 weston_binding_destroy(binding);
181}
182
183struct binding_keyboard_grab {
184 uint32_t key;
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400185 struct weston_keyboard_grab grab;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200186};
187
188static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400189binding_key(struct weston_keyboard_grab *grab,
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200190 uint32_t time, uint32_t key, uint32_t state_w)
191{
192 struct binding_keyboard_grab *b =
193 container_of(grab, struct binding_keyboard_grab, grab);
194 struct wl_resource *resource;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200195 enum wl_keyboard_key_state state = state_w;
196 uint32_t serial;
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400197 struct weston_keyboard *keyboard = grab->keyboard;
Rob Bradford880ebc72013-07-22 17:31:38 +0100198 struct wl_display *display = keyboard->seat->compositor->wl_display;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200199
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200200 if (key == b->key) {
201 if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400202 weston_keyboard_end_grab(grab->keyboard);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200203 if (keyboard->input_method_resource)
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400204 keyboard->grab = &keyboard->input_method_grab;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200205 free(b);
Giulio Camuffo943b46e2014-12-05 18:02:58 +0200206 } else {
207 /* Don't send the key press event for the binding key */
208 return;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200209 }
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200210 }
211 if (!wl_list_empty(&keyboard->focus_resource_list)) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200212 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100213 wl_resource_for_each(resource, &keyboard->focus_resource_list) {
214 wl_keyboard_send_key(resource,
215 serial,
216 time,
217 key,
218 state);
219 }
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200220 }
221}
222
223static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400224binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200225 uint32_t mods_depressed, uint32_t mods_latched,
226 uint32_t mods_locked, uint32_t group)
227{
228 struct wl_resource *resource;
229
Neil Roberts96d790e2013-09-19 17:32:00 +0100230 wl_resource_for_each(resource, &grab->keyboard->focus_resource_list) {
231 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
232 mods_latched, mods_locked, group);
233 }
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200234}
235
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200236static void
237binding_cancel(struct weston_keyboard_grab *grab)
238{
239 struct binding_keyboard_grab *binding_grab =
240 container_of(grab, struct binding_keyboard_grab, grab);
241
242 weston_keyboard_end_grab(grab->keyboard);
243 free(binding_grab);
244}
245
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400246static const struct weston_keyboard_grab_interface binding_grab = {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200247 binding_key,
248 binding_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200249 binding_cancel,
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200250};
251
252static void
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200253install_binding_grab(struct weston_seat *seat, uint32_t time, uint32_t key,
254 struct weston_surface *focus)
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200255{
256 struct binding_keyboard_grab *grab;
257
258 grab = malloc(sizeof *grab);
259 grab->key = key;
260 grab->grab.interface = &binding_grab;
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400261 weston_keyboard_start_grab(seat->keyboard, &grab->grab);
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200262
263 /* Notify the surface which had the focus before this binding
264 * triggered that we stole a keypress from under it, by forcing
265 * a wl_keyboard leave/enter pair. The enter event will contain
266 * the pressed key in the keys array, so the client will know
267 * the exact state of the keyboard.
268 * If the old focus surface is different than the new one it
269 * means it was changed in the binding handler, so it received
270 * the enter event already. */
271 if (focus && seat->keyboard->focus == focus) {
272 weston_keyboard_set_focus(seat->keyboard, NULL);
273 weston_keyboard_set_focus(seat->keyboard, focus);
274 }
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200275}
276
Pekka Paalanen86b53962014-11-19 13:43:32 +0200277WL_EXPORT void
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200278weston_compositor_run_key_binding(struct weston_compositor *compositor,
279 struct weston_seat *seat,
280 uint32_t time, uint32_t key,
281 enum wl_keyboard_key_state state)
282{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300283 struct weston_binding *b, *tmp;
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200284 struct weston_surface *focus;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200285
286 if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
Pekka Paalanen86b53962014-11-19 13:43:32 +0200287 return;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200288
Daniel Stone96d47c02013-11-19 11:37:12 +0100289 /* Invalidate all active modifier bindings. */
290 wl_list_for_each(b, &compositor->modifier_binding_list, link)
291 b->key = key;
292
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300293 wl_list_for_each_safe(b, tmp, &compositor->key_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200294 if (b->key == key && b->modifier == seat->modifier_state) {
295 weston_key_binding_handler_t handler = b->handler;
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200296 focus = seat->keyboard->focus;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400297 handler(seat, time, key, b->data);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200298
299 /* If this was a key binding and it didn't
300 * install a keyboard grab, install one now to
Giulio Camuffo943b46e2014-12-05 18:02:58 +0200301 * swallow the key press. */
Kristian Høgsberge3148752013-05-06 23:19:49 -0400302 if (seat->keyboard->grab ==
303 &seat->keyboard->default_grab)
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200304 install_binding_grab(seat, time, key, focus);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200305 }
306 }
307}
308
309WL_EXPORT void
Daniel Stone96d47c02013-11-19 11:37:12 +0100310weston_compositor_run_modifier_binding(struct weston_compositor *compositor,
311 struct weston_seat *seat,
312 enum weston_keyboard_modifier modifier,
313 enum wl_keyboard_key_state state)
314{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300315 struct weston_binding *b, *tmp;
Daniel Stone96d47c02013-11-19 11:37:12 +0100316
Emilio Pozuelo Monfort1539ea22013-11-27 10:34:32 +0100317 if (seat->keyboard->grab != &seat->keyboard->default_grab)
318 return;
319
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300320 wl_list_for_each_safe(b, tmp, &compositor->modifier_binding_list, link) {
Daniel Stone96d47c02013-11-19 11:37:12 +0100321 weston_modifier_binding_handler_t handler = b->handler;
322
323 if (b->modifier != modifier)
324 continue;
325
326 /* Prime the modifier binding. */
327 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
328 b->key = 0;
329 continue;
330 }
331 /* Ignore the binding if a key was pressed in between. */
332 else if (b->key != 0) {
333 return;
334 }
335
336 handler(seat, modifier, b->data);
337 }
338}
339
340WL_EXPORT void
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200341weston_compositor_run_button_binding(struct weston_compositor *compositor,
342 struct weston_seat *seat,
343 uint32_t time, uint32_t button,
344 enum wl_pointer_button_state state)
345{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300346 struct weston_binding *b, *tmp;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200347
348 if (state == WL_POINTER_BUTTON_STATE_RELEASED)
349 return;
350
Daniel Stone96d47c02013-11-19 11:37:12 +0100351 /* Invalidate all active modifier bindings. */
352 wl_list_for_each(b, &compositor->modifier_binding_list, link)
353 b->key = button;
354
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300355 wl_list_for_each_safe(b, tmp, &compositor->button_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200356 if (b->button == button && b->modifier == seat->modifier_state) {
357 weston_button_binding_handler_t handler = b->handler;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400358 handler(seat, time, button, b->data);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200359 }
360 }
361}
362
Neil Robertsa28c6932013-10-03 16:43:04 +0100363WL_EXPORT void
364weston_compositor_run_touch_binding(struct weston_compositor *compositor,
365 struct weston_seat *seat, uint32_t time,
366 int touch_type)
367{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300368 struct weston_binding *b, *tmp;
Neil Robertsa28c6932013-10-03 16:43:04 +0100369
Jonas Ådahl9484b692013-12-02 22:05:03 +0100370 if (seat->touch->num_tp != 1 || touch_type != WL_TOUCH_DOWN)
Neil Robertsa28c6932013-10-03 16:43:04 +0100371 return;
372
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300373 wl_list_for_each_safe(b, tmp, &compositor->touch_binding_list, link) {
Neil Robertsa28c6932013-10-03 16:43:04 +0100374 if (b->modifier == seat->modifier_state) {
375 weston_touch_binding_handler_t handler = b->handler;
376 handler(seat, time, b->data);
377 }
378 }
379}
380
Rune K. Svendsen14b2fe72013-03-07 21:50:00 +0100381WL_EXPORT int
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200382weston_compositor_run_axis_binding(struct weston_compositor *compositor,
383 struct weston_seat *seat,
384 uint32_t time, uint32_t axis,
385 wl_fixed_t value)
386{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300387 struct weston_binding *b, *tmp;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200388
Daniel Stone96d47c02013-11-19 11:37:12 +0100389 /* Invalidate all active modifier bindings. */
390 wl_list_for_each(b, &compositor->modifier_binding_list, link)
391 b->key = axis;
392
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300393 wl_list_for_each_safe(b, tmp, &compositor->axis_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200394 if (b->axis == axis && b->modifier == seat->modifier_state) {
395 weston_axis_binding_handler_t handler = b->handler;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400396 handler(seat, time, axis, value, b->data);
Rune K. Svendsen14b2fe72013-03-07 21:50:00 +0100397 return 1;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200398 }
399 }
Rune K. Svendsen14b2fe72013-03-07 21:50:00 +0100400
401 return 0;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200402}
403
404WL_EXPORT int
405weston_compositor_run_debug_binding(struct weston_compositor *compositor,
406 struct weston_seat *seat,
407 uint32_t time, uint32_t key,
408 enum wl_keyboard_key_state state)
409{
410 weston_key_binding_handler_t handler;
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300411 struct weston_binding *binding, *tmp;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200412 int count = 0;
413
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300414 wl_list_for_each_safe(binding, tmp, &compositor->debug_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200415 if (key != binding->key)
416 continue;
417
418 count++;
419 handler = binding->handler;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400420 handler(seat, time, key, binding->data);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200421 }
422
423 return count;
424}
Pekka Paalanen2829f7c2015-02-19 17:02:13 +0200425
426struct debug_binding_grab {
427 struct weston_keyboard_grab grab;
428 struct weston_seat *seat;
429 uint32_t key[2];
430 int key_released[2];
431};
432
433static void
434debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time,
435 uint32_t key, uint32_t state)
436{
437 struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
438 struct weston_compositor *ec = db->seat->compositor;
439 struct wl_display *display = ec->wl_display;
440 struct wl_resource *resource;
441 uint32_t serial;
442 int send = 0, terminate = 0;
443 int check_binding = 1;
444 int i;
445 struct wl_list *resource_list;
446
447 if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
448 /* Do not run bindings on key releases */
449 check_binding = 0;
450
451 for (i = 0; i < 2; i++)
452 if (key == db->key[i])
453 db->key_released[i] = 1;
454
455 if (db->key_released[0] && db->key_released[1]) {
456 /* All key releases been swalled so end the grab */
457 terminate = 1;
458 } else if (key != db->key[0] && key != db->key[1]) {
459 /* Should not swallow release of other keys */
460 send = 1;
461 }
462 } else if (key == db->key[0] && !db->key_released[0]) {
463 /* Do not check bindings for the first press of the binding
464 * key. This allows it to be used as a debug shortcut.
465 * We still need to swallow this event. */
466 check_binding = 0;
467 } else if (db->key[1]) {
468 /* If we already ran a binding don't process another one since
469 * we can't keep track of all the binding keys that were
470 * pressed in order to swallow the release events. */
471 send = 1;
472 check_binding = 0;
473 }
474
475 if (check_binding) {
476 if (weston_compositor_run_debug_binding(ec, db->seat, time,
477 key, state)) {
478 /* We ran a binding so swallow the press and keep the
479 * grab to swallow the released too. */
480 send = 0;
481 terminate = 0;
482 db->key[1] = key;
483 } else {
484 /* Terminate the grab since the key pressed is not a
485 * debug binding key. */
486 send = 1;
487 terminate = 1;
488 }
489 }
490
491 if (send) {
492 serial = wl_display_next_serial(display);
493 resource_list = &grab->keyboard->focus_resource_list;
494 wl_resource_for_each(resource, resource_list) {
495 wl_keyboard_send_key(resource, serial, time, key, state);
496 }
497 }
498
499 if (terminate) {
500 weston_keyboard_end_grab(grab->keyboard);
501 if (grab->keyboard->input_method_resource)
502 grab->keyboard->grab = &grab->keyboard->input_method_grab;
503 free(db);
504 }
505}
506
507static void
508debug_binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
509 uint32_t mods_depressed, uint32_t mods_latched,
510 uint32_t mods_locked, uint32_t group)
511{
512 struct wl_resource *resource;
513 struct wl_list *resource_list;
514
515 resource_list = &grab->keyboard->focus_resource_list;
516
517 wl_resource_for_each(resource, resource_list) {
518 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
519 mods_latched, mods_locked, group);
520 }
521}
522
523static void
524debug_binding_cancel(struct weston_keyboard_grab *grab)
525{
526 struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
527
528 weston_keyboard_end_grab(grab->keyboard);
529 free(db);
530}
531
532struct weston_keyboard_grab_interface debug_binding_keyboard_grab = {
533 debug_binding_key,
534 debug_binding_modifiers,
535 debug_binding_cancel,
536};
537
538static void
539debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
540{
541 struct debug_binding_grab *grab;
542
543 grab = calloc(1, sizeof *grab);
544 if (!grab)
545 return;
546
547 grab->seat = seat;
548 grab->key[0] = key;
549 grab->grab.interface = &debug_binding_keyboard_grab;
550 weston_keyboard_start_grab(seat->keyboard, &grab->grab);
551}
552
553/** Install the trigger binding for debug bindings.
554 *
555 * \param compositor The compositor.
556 * \param mod The modifier.
557 *
558 * This will add a key binding for modifier+SHIFT+SPACE that will trigger
559 * debug key bindings.
560 */
561WL_EXPORT void
562weston_install_debug_key_binding(struct weston_compositor *compositor,
563 uint32_t mod)
564{
565 weston_compositor_add_key_binding(compositor, KEY_SPACE,
566 mod | MODIFIER_SHIFT,
567 debug_binding, NULL);
568}