blob: 2b712dcd4ca4071d8bcc4fce743639bb802517e6 [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"
Jon Cruz867d50e2015-06-15 15:37:10 -070032#include "shared/helpers.h"
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +020033
34struct weston_binding {
35 uint32_t key;
36 uint32_t button;
37 uint32_t axis;
38 uint32_t modifier;
39 void *handler;
40 void *data;
41 struct wl_list link;
42};
43
44static struct weston_binding *
45weston_compositor_add_binding(struct weston_compositor *compositor,
46 uint32_t key, uint32_t button, uint32_t axis,
47 uint32_t modifier, void *handler, void *data)
48{
49 struct weston_binding *binding;
50
51 binding = malloc(sizeof *binding);
52 if (binding == NULL)
53 return NULL;
54
55 binding->key = key;
56 binding->button = button;
57 binding->axis = axis;
58 binding->modifier = modifier;
59 binding->handler = handler;
60 binding->data = data;
61
62 return binding;
63}
64
65WL_EXPORT struct weston_binding *
66weston_compositor_add_key_binding(struct weston_compositor *compositor,
67 uint32_t key, uint32_t modifier,
68 weston_key_binding_handler_t handler,
69 void *data)
70{
71 struct weston_binding *binding;
72
73 binding = weston_compositor_add_binding(compositor, key, 0, 0,
74 modifier, handler, data);
75 if (binding == NULL)
76 return NULL;
77
78 wl_list_insert(compositor->key_binding_list.prev, &binding->link);
79
80 return binding;
81}
82
83WL_EXPORT struct weston_binding *
Daniel Stone96d47c02013-11-19 11:37:12 +010084weston_compositor_add_modifier_binding(struct weston_compositor *compositor,
85 uint32_t modifier,
86 weston_modifier_binding_handler_t handler,
87 void *data)
88{
89 struct weston_binding *binding;
90
91 binding = weston_compositor_add_binding(compositor, 0, 0, 0,
92 modifier, handler, data);
93 if (binding == NULL)
94 return NULL;
95
96 wl_list_insert(compositor->modifier_binding_list.prev, &binding->link);
97
98 return binding;
99}
100
101WL_EXPORT struct weston_binding *
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200102weston_compositor_add_button_binding(struct weston_compositor *compositor,
103 uint32_t button, uint32_t modifier,
104 weston_button_binding_handler_t handler,
105 void *data)
106{
107 struct weston_binding *binding;
108
109 binding = weston_compositor_add_binding(compositor, 0, button, 0,
110 modifier, handler, data);
111 if (binding == NULL)
112 return NULL;
113
114 wl_list_insert(compositor->button_binding_list.prev, &binding->link);
115
116 return binding;
117}
118
119WL_EXPORT struct weston_binding *
Neil Robertsa28c6932013-10-03 16:43:04 +0100120weston_compositor_add_touch_binding(struct weston_compositor *compositor,
121 uint32_t modifier,
122 weston_touch_binding_handler_t handler,
123 void *data)
124{
125 struct weston_binding *binding;
126
127 binding = weston_compositor_add_binding(compositor, 0, 0, 0,
128 modifier, handler, data);
129 if (binding == NULL)
130 return NULL;
131
132 wl_list_insert(compositor->touch_binding_list.prev, &binding->link);
133
134 return binding;
135}
136
137WL_EXPORT struct weston_binding *
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200138weston_compositor_add_axis_binding(struct weston_compositor *compositor,
139 uint32_t axis, uint32_t modifier,
140 weston_axis_binding_handler_t handler,
141 void *data)
142{
143 struct weston_binding *binding;
144
145 binding = weston_compositor_add_binding(compositor, 0, 0, axis,
146 modifier, handler, data);
147 if (binding == NULL)
148 return NULL;
149
150 wl_list_insert(compositor->axis_binding_list.prev, &binding->link);
151
152 return binding;
153}
154
155WL_EXPORT struct weston_binding *
156weston_compositor_add_debug_binding(struct weston_compositor *compositor,
157 uint32_t key,
158 weston_key_binding_handler_t handler,
159 void *data)
160{
161 struct weston_binding *binding;
162
163 binding = weston_compositor_add_binding(compositor, key, 0, 0, 0,
164 handler, data);
165
166 wl_list_insert(compositor->debug_binding_list.prev, &binding->link);
167
168 return binding;
169}
170
171WL_EXPORT void
172weston_binding_destroy(struct weston_binding *binding)
173{
174 wl_list_remove(&binding->link);
175 free(binding);
176}
177
Derek Foreman2e6485c2015-07-15 13:00:34 -0500178void
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200179weston_binding_list_destroy_all(struct wl_list *list)
180{
181 struct weston_binding *binding, *tmp;
182
183 wl_list_for_each_safe(binding, tmp, list, link)
184 weston_binding_destroy(binding);
185}
186
187struct binding_keyboard_grab {
188 uint32_t key;
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400189 struct weston_keyboard_grab grab;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200190};
191
192static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400193binding_key(struct weston_keyboard_grab *grab,
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200194 uint32_t time, uint32_t key, uint32_t state_w)
195{
196 struct binding_keyboard_grab *b =
197 container_of(grab, struct binding_keyboard_grab, grab);
198 struct wl_resource *resource;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200199 enum wl_keyboard_key_state state = state_w;
200 uint32_t serial;
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400201 struct weston_keyboard *keyboard = grab->keyboard;
Rob Bradford880ebc72013-07-22 17:31:38 +0100202 struct wl_display *display = keyboard->seat->compositor->wl_display;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200203
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200204 if (key == b->key) {
205 if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400206 weston_keyboard_end_grab(grab->keyboard);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200207 if (keyboard->input_method_resource)
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400208 keyboard->grab = &keyboard->input_method_grab;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200209 free(b);
Giulio Camuffo943b46e2014-12-05 18:02:58 +0200210 } else {
211 /* Don't send the key press event for the binding key */
212 return;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200213 }
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200214 }
215 if (!wl_list_empty(&keyboard->focus_resource_list)) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200216 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100217 wl_resource_for_each(resource, &keyboard->focus_resource_list) {
218 wl_keyboard_send_key(resource,
219 serial,
220 time,
221 key,
222 state);
223 }
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200224 }
225}
226
227static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400228binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200229 uint32_t mods_depressed, uint32_t mods_latched,
230 uint32_t mods_locked, uint32_t group)
231{
232 struct wl_resource *resource;
233
Neil Roberts96d790e2013-09-19 17:32:00 +0100234 wl_resource_for_each(resource, &grab->keyboard->focus_resource_list) {
235 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
236 mods_latched, mods_locked, group);
237 }
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200238}
239
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200240static void
241binding_cancel(struct weston_keyboard_grab *grab)
242{
243 struct binding_keyboard_grab *binding_grab =
244 container_of(grab, struct binding_keyboard_grab, grab);
245
246 weston_keyboard_end_grab(grab->keyboard);
247 free(binding_grab);
248}
249
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400250static const struct weston_keyboard_grab_interface binding_grab = {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200251 binding_key,
252 binding_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200253 binding_cancel,
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200254};
255
256static void
Derek Foremanb591a302015-07-15 13:00:42 -0500257install_binding_grab(struct weston_keyboard *keyboard, uint32_t time,
258 uint32_t key, struct weston_surface *focus)
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200259{
260 struct binding_keyboard_grab *grab;
261
262 grab = malloc(sizeof *grab);
263 grab->key = key;
264 grab->grab.interface = &binding_grab;
Derek Foremanb591a302015-07-15 13:00:42 -0500265 weston_keyboard_start_grab(keyboard, &grab->grab);
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200266
267 /* Notify the surface which had the focus before this binding
268 * triggered that we stole a keypress from under it, by forcing
269 * a wl_keyboard leave/enter pair. The enter event will contain
270 * the pressed key in the keys array, so the client will know
271 * the exact state of the keyboard.
272 * If the old focus surface is different than the new one it
273 * means it was changed in the binding handler, so it received
274 * the enter event already. */
Derek Foremanb591a302015-07-15 13:00:42 -0500275 if (focus && keyboard->focus == focus) {
276 weston_keyboard_set_focus(keyboard, NULL);
277 weston_keyboard_set_focus(keyboard, focus);
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200278 }
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200279}
280
Derek Foreman2e6485c2015-07-15 13:00:34 -0500281void
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200282weston_compositor_run_key_binding(struct weston_compositor *compositor,
283 struct weston_seat *seat,
284 uint32_t time, uint32_t key,
285 enum wl_keyboard_key_state state)
286{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300287 struct weston_binding *b, *tmp;
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200288 struct weston_surface *focus;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200289
290 if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
Pekka Paalanen86b53962014-11-19 13:43:32 +0200291 return;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200292
Daniel Stone96d47c02013-11-19 11:37:12 +0100293 /* Invalidate all active modifier bindings. */
294 wl_list_for_each(b, &compositor->modifier_binding_list, link)
295 b->key = key;
296
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300297 wl_list_for_each_safe(b, tmp, &compositor->key_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200298 if (b->key == key && b->modifier == seat->modifier_state) {
299 weston_key_binding_handler_t handler = b->handler;
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200300 focus = seat->keyboard->focus;
Derek Foreman8ae2db52015-07-15 13:00:36 -0500301 handler(seat->keyboard, time, key, b->data);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200302
303 /* If this was a key binding and it didn't
304 * install a keyboard grab, install one now to
Giulio Camuffo943b46e2014-12-05 18:02:58 +0200305 * swallow the key press. */
Kristian Høgsberge3148752013-05-06 23:19:49 -0400306 if (seat->keyboard->grab ==
307 &seat->keyboard->default_grab)
Derek Foremanb591a302015-07-15 13:00:42 -0500308 install_binding_grab(seat->keyboard,
309 time,
310 key,
311 focus);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200312 }
313 }
314}
315
Derek Foreman2e6485c2015-07-15 13:00:34 -0500316void
Daniel Stone96d47c02013-11-19 11:37:12 +0100317weston_compositor_run_modifier_binding(struct weston_compositor *compositor,
318 struct weston_seat *seat,
319 enum weston_keyboard_modifier modifier,
320 enum wl_keyboard_key_state state)
321{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300322 struct weston_binding *b, *tmp;
Daniel Stone96d47c02013-11-19 11:37:12 +0100323
Emilio Pozuelo Monfort1539ea22013-11-27 10:34:32 +0100324 if (seat->keyboard->grab != &seat->keyboard->default_grab)
325 return;
326
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300327 wl_list_for_each_safe(b, tmp, &compositor->modifier_binding_list, link) {
Daniel Stone96d47c02013-11-19 11:37:12 +0100328 weston_modifier_binding_handler_t handler = b->handler;
329
330 if (b->modifier != modifier)
331 continue;
332
333 /* Prime the modifier binding. */
334 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
335 b->key = 0;
336 continue;
337 }
338 /* Ignore the binding if a key was pressed in between. */
339 else if (b->key != 0) {
340 return;
341 }
342
Derek Foreman8ae2db52015-07-15 13:00:36 -0500343 handler(seat->keyboard, modifier, b->data);
Daniel Stone96d47c02013-11-19 11:37:12 +0100344 }
345}
346
Derek Foreman2e6485c2015-07-15 13:00:34 -0500347void
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200348weston_compositor_run_button_binding(struct weston_compositor *compositor,
349 struct weston_seat *seat,
350 uint32_t time, uint32_t button,
351 enum wl_pointer_button_state state)
352{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300353 struct weston_binding *b, *tmp;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200354
355 if (state == WL_POINTER_BUTTON_STATE_RELEASED)
356 return;
357
Daniel Stone96d47c02013-11-19 11:37:12 +0100358 /* Invalidate all active modifier bindings. */
359 wl_list_for_each(b, &compositor->modifier_binding_list, link)
360 b->key = button;
361
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300362 wl_list_for_each_safe(b, tmp, &compositor->button_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200363 if (b->button == button && b->modifier == seat->modifier_state) {
364 weston_button_binding_handler_t handler = b->handler;
Derek Foreman8ae2db52015-07-15 13:00:36 -0500365 handler(seat->pointer, time, button, b->data);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200366 }
367 }
368}
369
Derek Foreman2e6485c2015-07-15 13:00:34 -0500370void
Neil Robertsa28c6932013-10-03 16:43:04 +0100371weston_compositor_run_touch_binding(struct weston_compositor *compositor,
372 struct weston_seat *seat, uint32_t time,
373 int touch_type)
374{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300375 struct weston_binding *b, *tmp;
Neil Robertsa28c6932013-10-03 16:43:04 +0100376
Jonas Ådahl9484b692013-12-02 22:05:03 +0100377 if (seat->touch->num_tp != 1 || touch_type != WL_TOUCH_DOWN)
Neil Robertsa28c6932013-10-03 16:43:04 +0100378 return;
379
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300380 wl_list_for_each_safe(b, tmp, &compositor->touch_binding_list, link) {
Neil Robertsa28c6932013-10-03 16:43:04 +0100381 if (b->modifier == seat->modifier_state) {
382 weston_touch_binding_handler_t handler = b->handler;
Derek Foreman8ae2db52015-07-15 13:00:36 -0500383 handler(seat->touch, time, b->data);
Neil Robertsa28c6932013-10-03 16:43:04 +0100384 }
385 }
386}
387
Derek Foreman2e6485c2015-07-15 13:00:34 -0500388int
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200389weston_compositor_run_axis_binding(struct weston_compositor *compositor,
390 struct weston_seat *seat,
391 uint32_t time, uint32_t axis,
392 wl_fixed_t value)
393{
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300394 struct weston_binding *b, *tmp;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200395
Daniel Stone96d47c02013-11-19 11:37:12 +0100396 /* Invalidate all active modifier bindings. */
397 wl_list_for_each(b, &compositor->modifier_binding_list, link)
398 b->key = axis;
399
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300400 wl_list_for_each_safe(b, tmp, &compositor->axis_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200401 if (b->axis == axis && b->modifier == seat->modifier_state) {
402 weston_axis_binding_handler_t handler = b->handler;
Derek Foreman8ae2db52015-07-15 13:00:36 -0500403 handler(seat->pointer, time, axis, value, b->data);
Rune K. Svendsen14b2fe72013-03-07 21:50:00 +0100404 return 1;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200405 }
406 }
Rune K. Svendsen14b2fe72013-03-07 21:50:00 +0100407
408 return 0;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200409}
410
Derek Foreman2e6485c2015-07-15 13:00:34 -0500411int
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200412weston_compositor_run_debug_binding(struct weston_compositor *compositor,
413 struct weston_seat *seat,
414 uint32_t time, uint32_t key,
415 enum wl_keyboard_key_state state)
416{
417 weston_key_binding_handler_t handler;
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300418 struct weston_binding *binding, *tmp;
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200419 int count = 0;
420
Giulio Camuffo24b98d02014-10-03 23:36:34 +0300421 wl_list_for_each_safe(binding, tmp, &compositor->debug_binding_list, link) {
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200422 if (key != binding->key)
423 continue;
424
425 count++;
426 handler = binding->handler;
Derek Foreman8ae2db52015-07-15 13:00:36 -0500427 handler(seat->keyboard, time, key, binding->data);
Ander Conselvan de Oliveiracbdebc22013-02-21 18:35:16 +0200428 }
429
430 return count;
431}
Pekka Paalanen2829f7c2015-02-19 17:02:13 +0200432
433struct debug_binding_grab {
434 struct weston_keyboard_grab grab;
435 struct weston_seat *seat;
436 uint32_t key[2];
437 int key_released[2];
438};
439
440static void
441debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time,
442 uint32_t key, uint32_t state)
443{
444 struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
445 struct weston_compositor *ec = db->seat->compositor;
446 struct wl_display *display = ec->wl_display;
447 struct wl_resource *resource;
448 uint32_t serial;
449 int send = 0, terminate = 0;
450 int check_binding = 1;
451 int i;
452 struct wl_list *resource_list;
453
454 if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
455 /* Do not run bindings on key releases */
456 check_binding = 0;
457
458 for (i = 0; i < 2; i++)
459 if (key == db->key[i])
460 db->key_released[i] = 1;
461
462 if (db->key_released[0] && db->key_released[1]) {
463 /* All key releases been swalled so end the grab */
464 terminate = 1;
465 } else if (key != db->key[0] && key != db->key[1]) {
466 /* Should not swallow release of other keys */
467 send = 1;
468 }
469 } else if (key == db->key[0] && !db->key_released[0]) {
470 /* Do not check bindings for the first press of the binding
471 * key. This allows it to be used as a debug shortcut.
472 * We still need to swallow this event. */
473 check_binding = 0;
474 } else if (db->key[1]) {
475 /* If we already ran a binding don't process another one since
476 * we can't keep track of all the binding keys that were
477 * pressed in order to swallow the release events. */
478 send = 1;
479 check_binding = 0;
480 }
481
482 if (check_binding) {
483 if (weston_compositor_run_debug_binding(ec, db->seat, time,
484 key, state)) {
485 /* We ran a binding so swallow the press and keep the
486 * grab to swallow the released too. */
487 send = 0;
488 terminate = 0;
489 db->key[1] = key;
490 } else {
491 /* Terminate the grab since the key pressed is not a
492 * debug binding key. */
493 send = 1;
494 terminate = 1;
495 }
496 }
497
498 if (send) {
499 serial = wl_display_next_serial(display);
500 resource_list = &grab->keyboard->focus_resource_list;
501 wl_resource_for_each(resource, resource_list) {
502 wl_keyboard_send_key(resource, serial, time, key, state);
503 }
504 }
505
506 if (terminate) {
507 weston_keyboard_end_grab(grab->keyboard);
508 if (grab->keyboard->input_method_resource)
509 grab->keyboard->grab = &grab->keyboard->input_method_grab;
510 free(db);
511 }
512}
513
514static void
515debug_binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
516 uint32_t mods_depressed, uint32_t mods_latched,
517 uint32_t mods_locked, uint32_t group)
518{
519 struct wl_resource *resource;
520 struct wl_list *resource_list;
521
522 resource_list = &grab->keyboard->focus_resource_list;
523
524 wl_resource_for_each(resource, resource_list) {
525 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
526 mods_latched, mods_locked, group);
527 }
528}
529
530static void
531debug_binding_cancel(struct weston_keyboard_grab *grab)
532{
533 struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
534
535 weston_keyboard_end_grab(grab->keyboard);
536 free(db);
537}
538
539struct weston_keyboard_grab_interface debug_binding_keyboard_grab = {
540 debug_binding_key,
541 debug_binding_modifiers,
542 debug_binding_cancel,
543};
544
545static void
Derek Foreman8ae2db52015-07-15 13:00:36 -0500546debug_binding(struct weston_keyboard *keyboard, uint32_t time,
547 uint32_t key, void *data)
Pekka Paalanen2829f7c2015-02-19 17:02:13 +0200548{
549 struct debug_binding_grab *grab;
550
551 grab = calloc(1, sizeof *grab);
552 if (!grab)
553 return;
554
Derek Foreman8ae2db52015-07-15 13:00:36 -0500555 grab->seat = keyboard->seat;
Pekka Paalanen2829f7c2015-02-19 17:02:13 +0200556 grab->key[0] = key;
557 grab->grab.interface = &debug_binding_keyboard_grab;
Derek Foreman8ae2db52015-07-15 13:00:36 -0500558 weston_keyboard_start_grab(keyboard, &grab->grab);
Pekka Paalanen2829f7c2015-02-19 17:02:13 +0200559}
560
561/** Install the trigger binding for debug bindings.
562 *
563 * \param compositor The compositor.
564 * \param mod The modifier.
565 *
566 * This will add a key binding for modifier+SHIFT+SPACE that will trigger
567 * debug key bindings.
568 */
569WL_EXPORT void
570weston_install_debug_key_binding(struct weston_compositor *compositor,
571 uint32_t mod)
572{
573 weston_compositor_add_key_binding(compositor, KEY_SPACE,
574 mod | MODIFIER_SHIFT,
575 debug_binding, NULL);
576}