blob: e2d33d61f08ec51628cea97d3971165d98e092ff [file] [log] [blame]
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001/*
2 * Copyright © 2013 Intel Corporation
3 *
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:
Kristian Høgsberg2158a882013-04-18 15:07:39 -040011 *
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.
Kristian Høgsberg2158a882013-04-18 15:07:39 -040024 */
25
Daniel Stone8e7a8bd2013-08-15 01:10:24 +010026#include "config.h"
27
Kristian Høgsberg2158a882013-04-18 15:07:39 -040028#include <stdlib.h>
29#include <stdint.h>
30#include <string.h>
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040031#include <sys/mman.h>
32#include <assert.h>
33#include <unistd.h>
Matt Roper01a92732013-06-24 16:52:44 +010034#include <fcntl.h>
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +020035#include <limits.h>
Kristian Høgsberg2158a882013-04-18 15:07:39 -040036
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040037#include "../shared/os-compatibility.h"
Kristian Høgsberg2158a882013-04-18 15:07:39 -040038#include "compositor.h"
39
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040040static void
41empty_region(pixman_region32_t *region)
42{
43 pixman_region32_fini(region);
44 pixman_region32_init(region);
45}
46
47static void unbind_resource(struct wl_resource *resource)
48{
Jason Ekstrand44a38632013-06-14 10:08:00 -050049 wl_list_remove(wl_resource_get_link(resource));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040050}
51
Jonas Ådahl3042ffe2013-10-17 23:04:08 +020052WL_EXPORT void
Kristian Høgsberga71e8b22013-05-06 21:51:21 -040053weston_seat_repick(struct weston_seat *seat)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040054{
Kristian Høgsbergda751b82013-07-04 00:58:07 -040055 const struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040056
Derek Foreman1b786ee2015-06-03 15:53:23 -050057 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040058 return;
59
Derek Foreman1b786ee2015-06-03 15:53:23 -050060 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040061}
62
63static void
64weston_compositor_idle_inhibit(struct weston_compositor *compositor)
65{
66 weston_compositor_wake(compositor);
67 compositor->idle_inhibit++;
68}
69
70static void
71weston_compositor_idle_release(struct weston_compositor *compositor)
72{
73 compositor->idle_inhibit--;
74 weston_compositor_wake(compositor);
75}
76
Kristian Høgsberg2158a882013-04-18 15:07:39 -040077static void
Giulio Camuffo576fe2a2013-11-20 18:00:24 +010078pointer_focus_view_destroyed(struct wl_listener *listener, void *data)
79{
80 struct weston_pointer *pointer =
81 container_of(listener, struct weston_pointer,
82 focus_view_listener);
83
84 weston_pointer_set_focus(pointer, NULL, 0, 0);
85}
86
87static void
88pointer_focus_resource_destroyed(struct wl_listener *listener, void *data)
89{
90 struct weston_pointer *pointer =
91 container_of(listener, struct weston_pointer,
92 focus_resource_listener);
93
94 weston_pointer_set_focus(pointer, NULL, 0, 0);
95}
96
97static void
98keyboard_focus_resource_destroyed(struct wl_listener *listener, void *data)
99{
100 struct weston_keyboard *keyboard =
101 container_of(listener, struct weston_keyboard,
102 focus_resource_listener);
103
104 weston_keyboard_set_focus(keyboard, NULL);
105}
106
107static void
108touch_focus_view_destroyed(struct wl_listener *listener, void *data)
109{
110 struct weston_touch *touch =
111 container_of(listener, struct weston_touch,
112 focus_view_listener);
113
Derek Foreman4c93c082015-04-30 16:45:41 -0500114 weston_touch_set_focus(touch, NULL);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100115}
116
117static void
118touch_focus_resource_destroyed(struct wl_listener *listener, void *data)
119{
120 struct weston_touch *touch =
121 container_of(listener, struct weston_touch,
122 focus_resource_listener);
123
Derek Foreman4c93c082015-04-30 16:45:41 -0500124 weston_touch_set_focus(touch, NULL);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100125}
126
127static void
Neil Roberts96d790e2013-09-19 17:32:00 +0100128move_resources(struct wl_list *destination, struct wl_list *source)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400129{
Neil Roberts96d790e2013-09-19 17:32:00 +0100130 wl_list_insert_list(destination, source);
131 wl_list_init(source);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400132}
133
134static void
Neil Roberts96d790e2013-09-19 17:32:00 +0100135move_resources_for_client(struct wl_list *destination,
136 struct wl_list *source,
137 struct wl_client *client)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400138{
Neil Roberts96d790e2013-09-19 17:32:00 +0100139 struct wl_resource *resource, *tmp;
140 wl_resource_for_each_safe(resource, tmp, source) {
141 if (wl_resource_get_client(resource) == client) {
142 wl_list_remove(wl_resource_get_link(resource));
143 wl_list_insert(destination,
144 wl_resource_get_link(resource));
145 }
146 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400147}
148
149static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700150default_grab_pointer_focus(struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400151{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400152 struct weston_pointer *pointer = grab->pointer;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500153 struct weston_view *view;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400154 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400155
156 if (pointer->button_count > 0)
157 return;
158
Jason Ekstranda7af7042013-10-12 22:38:11 -0500159 view = weston_compositor_pick_view(pointer->seat->compositor,
160 pointer->x, pointer->y,
161 &sx, &sy);
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400162
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800163 if (pointer->focus != view || pointer->sx != sx || pointer->sy != sy)
Jason Ekstranda7af7042013-10-12 22:38:11 -0500164 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400165}
166
167static void
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100168default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
169 wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400170{
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400171 struct weston_pointer *pointer = grab->pointer;
Neil Roberts96d790e2013-09-19 17:32:00 +0100172 struct wl_list *resource_list;
173 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400174
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800175 if (pointer->focus)
176 weston_view_from_global_fixed(pointer->focus, x, y,
177 &pointer->sx, &pointer->sy);
178
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100179 weston_pointer_move(pointer, x, y);
180
Neil Roberts96d790e2013-09-19 17:32:00 +0100181 resource_list = &pointer->focus_resource_list;
182 wl_resource_for_each(resource, resource_list) {
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800183 wl_pointer_send_motion(resource, time,
184 pointer->sx, pointer->sy);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400185 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400186}
187
188static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700189default_grab_pointer_button(struct weston_pointer_grab *grab,
190 uint32_t time, uint32_t button, uint32_t state_w)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400191{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400192 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400193 struct weston_compositor *compositor = pointer->seat->compositor;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500194 struct weston_view *view;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400195 struct wl_resource *resource;
196 uint32_t serial;
197 enum wl_pointer_button_state state = state_w;
Rob Bradford880ebc72013-07-22 17:31:38 +0100198 struct wl_display *display = compositor->wl_display;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400199 wl_fixed_t sx, sy;
Neil Roberts96d790e2013-09-19 17:32:00 +0100200 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400201
Neil Roberts96d790e2013-09-19 17:32:00 +0100202 resource_list = &pointer->focus_resource_list;
203 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400204 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100205 wl_resource_for_each(resource, resource_list)
206 wl_pointer_send_button(resource,
207 serial,
208 time,
209 button,
210 state_w);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400211 }
212
213 if (pointer->button_count == 0 &&
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400214 state == WL_POINTER_BUTTON_STATE_RELEASED) {
Jason Ekstranda7af7042013-10-12 22:38:11 -0500215 view = weston_compositor_pick_view(compositor,
216 pointer->x, pointer->y,
217 &sx, &sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400218
Jason Ekstranda7af7042013-10-12 22:38:11 -0500219 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400220 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400221}
222
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200223static void
224default_grab_pointer_cancel(struct weston_pointer_grab *grab)
225{
226}
227
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400228static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400229 default_pointer_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700230 default_grab_pointer_focus,
231 default_grab_pointer_motion,
232 default_grab_pointer_button,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200233 default_grab_pointer_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400234};
235
Kristian Høgsberge329f362013-05-06 22:19:57 -0400236static void
237default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
238 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400239{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400240 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100241 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400242 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100243 struct wl_resource *resource;
244 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400245
Neil Roberts96d790e2013-09-19 17:32:00 +0100246 resource_list = &touch->focus_resource_list;
247
248 if (!wl_list_empty(resource_list) && touch->focus) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400249 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100250 wl_resource_for_each(resource, resource_list)
251 wl_touch_send_down(resource, serial, time,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500252 touch->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100253 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400254 }
255}
256
Kristian Høgsberge329f362013-05-06 22:19:57 -0400257static void
258default_grab_touch_up(struct weston_touch_grab *grab,
259 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400260{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400261 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100262 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400263 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100264 struct wl_resource *resource;
265 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400266
Neil Roberts96d790e2013-09-19 17:32:00 +0100267 resource_list = &touch->focus_resource_list;
268
269 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400270 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100271 wl_resource_for_each(resource, resource_list)
272 wl_touch_send_up(resource, serial, time, touch_id);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400273 }
274}
275
Kristian Høgsberge329f362013-05-06 22:19:57 -0400276static void
277default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
278 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400279{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400280 struct weston_touch *touch = grab->touch;
Neil Roberts96d790e2013-09-19 17:32:00 +0100281 struct wl_resource *resource;
282 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400283
Neil Roberts96d790e2013-09-19 17:32:00 +0100284 resource_list = &touch->focus_resource_list;
285
286 wl_resource_for_each(resource, resource_list) {
287 wl_touch_send_motion(resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400288 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400289 }
290}
291
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200292static void
Jonas Ådahl1679f232014-04-12 09:39:51 +0200293default_grab_touch_frame(struct weston_touch_grab *grab)
294{
295 struct wl_resource *resource;
296
297 wl_resource_for_each(resource, &grab->touch->focus_resource_list)
298 wl_touch_send_frame(resource);
299}
300
301static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200302default_grab_touch_cancel(struct weston_touch_grab *grab)
303{
304}
305
Kristian Høgsberge329f362013-05-06 22:19:57 -0400306static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400307 default_grab_touch_down,
308 default_grab_touch_up,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200309 default_grab_touch_motion,
Jonas Ådahl1679f232014-04-12 09:39:51 +0200310 default_grab_touch_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200311 default_grab_touch_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400312};
313
314static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700315default_grab_keyboard_key(struct weston_keyboard_grab *grab,
316 uint32_t time, uint32_t key, uint32_t state)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400317{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400318 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400319 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100320 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400321 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100322 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400323
Neil Roberts96d790e2013-09-19 17:32:00 +0100324 resource_list = &keyboard->focus_resource_list;
325 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400326 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100327 wl_resource_for_each(resource, resource_list)
328 wl_keyboard_send_key(resource,
329 serial,
330 time,
331 key,
332 state);
333 }
334}
335
336static void
337send_modifiers_to_resource(struct weston_keyboard *keyboard,
338 struct wl_resource *resource,
339 uint32_t serial)
340{
341 wl_keyboard_send_modifiers(resource,
342 serial,
343 keyboard->modifiers.mods_depressed,
344 keyboard->modifiers.mods_latched,
345 keyboard->modifiers.mods_locked,
346 keyboard->modifiers.group);
347}
348
349static void
350send_modifiers_to_client_in_list(struct wl_client *client,
351 struct wl_list *list,
352 uint32_t serial,
353 struct weston_keyboard *keyboard)
354{
355 struct wl_resource *resource;
356
357 wl_resource_for_each(resource, list) {
358 if (wl_resource_get_client(resource) == client)
359 send_modifiers_to_resource(keyboard,
360 resource,
361 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400362 }
363}
364
365static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400366find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400367{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400368 if (!surface)
369 return NULL;
370
Jason Ekstrand44a38632013-06-14 10:08:00 -0500371 if (!surface->resource)
372 return NULL;
Stefan Schmidtfda26522013-09-17 10:54:09 +0100373
Jason Ekstrand44a38632013-06-14 10:08:00 -0500374 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400375}
376
Jason Ekstranda7af7042013-10-12 22:38:11 -0500377static struct wl_resource *
378find_resource_for_view(struct wl_list *list, struct weston_view *view)
379{
380 if (!view)
381 return NULL;
382
383 return find_resource_for_surface(list, view->surface);
384}
385
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400386static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700387default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
388 uint32_t serial, uint32_t mods_depressed,
389 uint32_t mods_latched,
390 uint32_t mods_locked, uint32_t group)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400391{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400392 struct weston_keyboard *keyboard = grab->keyboard;
Neil Roberts96d790e2013-09-19 17:32:00 +0100393 struct weston_pointer *pointer = grab->keyboard->seat->pointer;
394 struct wl_resource *resource;
395 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400396
Neil Roberts96d790e2013-09-19 17:32:00 +0100397 resource_list = &keyboard->focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400398
Neil Roberts96d790e2013-09-19 17:32:00 +0100399 wl_resource_for_each(resource, resource_list) {
400 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
401 mods_latched, mods_locked, group);
402 }
Jason Ekstrand42133d42013-11-14 20:06:16 -0600403 if (pointer && pointer->focus && pointer->focus->surface->resource &&
404 pointer->focus->surface != keyboard->focus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100405 struct wl_client *pointer_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500406 wl_resource_get_client(pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100407 send_modifiers_to_client_in_list(pointer_client,
408 &keyboard->resource_list,
409 serial,
410 keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400411 }
412}
413
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200414static void
415default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
416{
417}
418
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400419static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400420 default_keyboard_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700421 default_grab_keyboard_key,
422 default_grab_keyboard_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200423 default_grab_keyboard_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400424};
425
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400426static void
427pointer_unmap_sprite(struct weston_pointer *pointer)
428{
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200429 struct weston_surface *surface = pointer->sprite->surface;
430
431 if (weston_surface_is_mapped(surface))
432 weston_surface_unmap(surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400433
434 wl_list_remove(&pointer->sprite_destroy_listener.link);
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200435 surface->configure = NULL;
436 surface->configure_private = NULL;
Pekka Paalanen8274d902014-08-06 19:36:51 +0300437 weston_surface_set_label_func(surface, NULL);
Jason Ekstranda7af7042013-10-12 22:38:11 -0500438 weston_view_destroy(pointer->sprite);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400439 pointer->sprite = NULL;
440}
441
442static void
443pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
444{
445 struct weston_pointer *pointer =
446 container_of(listener, struct weston_pointer,
447 sprite_destroy_listener);
448
449 pointer->sprite = NULL;
450}
451
Jonas Ådahl3e12e632013-12-02 22:05:05 +0100452static void
453weston_pointer_reset_state(struct weston_pointer *pointer)
454{
455 pointer->button_count = 0;
456}
457
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200458static void
459weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
460
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400461WL_EXPORT struct weston_pointer *
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100462weston_pointer_create(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400463{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400464 struct weston_pointer *pointer;
465
Peter Huttererf3d62272013-08-08 11:57:05 +1000466 pointer = zalloc(sizeof *pointer);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400467 if (pointer == NULL)
468 return NULL;
469
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400470 wl_list_init(&pointer->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100471 wl_list_init(&pointer->focus_resource_list);
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100472 weston_pointer_set_default_grab(pointer,
473 seat->compositor->default_pointer_grab);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100474 wl_list_init(&pointer->focus_resource_listener.link);
475 pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400476 pointer->default_grab.pointer = pointer;
477 pointer->grab = &pointer->default_grab;
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100478 wl_signal_init(&pointer->motion_signal);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100479 wl_signal_init(&pointer->focus_signal);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100480 wl_list_init(&pointer->focus_view_listener.link);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400481
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400482 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
483
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400484 /* FIXME: Pick better co-ords. */
485 pointer->x = wl_fixed_from_int(100);
486 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400487
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200488 pointer->output_destroy_listener.notify =
489 weston_pointer_handle_output_destroy;
490 wl_signal_add(&seat->compositor->output_destroyed_signal,
491 &pointer->output_destroy_listener);
492
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400493 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400494}
495
496WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400497weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400498{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400499 if (pointer->sprite)
500 pointer_unmap_sprite(pointer);
501
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400502 /* XXX: What about pointer->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100503
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100504 wl_list_remove(&pointer->focus_resource_listener.link);
505 wl_list_remove(&pointer->focus_view_listener.link);
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200506 wl_list_remove(&pointer->output_destroy_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400507 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400508}
509
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100510void
511weston_pointer_set_default_grab(struct weston_pointer *pointer,
512 const struct weston_pointer_grab_interface *interface)
513{
514 if (interface)
515 pointer->default_grab.interface = interface;
516 else
517 pointer->default_grab.interface =
518 &default_pointer_grab_interface;
519}
520
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400521WL_EXPORT struct weston_keyboard *
522weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400523{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400524 struct weston_keyboard *keyboard;
525
Peter Huttererf3d62272013-08-08 11:57:05 +1000526 keyboard = zalloc(sizeof *keyboard);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400527 if (keyboard == NULL)
Neil Roberts96d790e2013-09-19 17:32:00 +0100528 return NULL;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400529
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400530 wl_list_init(&keyboard->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100531 wl_list_init(&keyboard->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100532 wl_list_init(&keyboard->focus_resource_listener.link);
533 keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400534 wl_array_init(&keyboard->keys);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400535 keyboard->default_grab.interface = &default_keyboard_grab_interface;
536 keyboard->default_grab.keyboard = keyboard;
537 keyboard->grab = &keyboard->default_grab;
538 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400539
540 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400541}
542
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100543static void
544weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
545
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400546WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400547weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400548{
549 /* XXX: What about keyboard->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100550
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100551#ifdef ENABLE_XKBCOMMON
552 if (keyboard->seat->compositor->use_xkbcommon) {
Ran Benitac9c74152014-08-19 23:59:52 +0300553 xkb_state_unref(keyboard->xkb_state.state);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100554 if (keyboard->xkb_info)
555 weston_xkb_info_destroy(keyboard->xkb_info);
Ran Benitac9c74152014-08-19 23:59:52 +0300556 xkb_keymap_unref(keyboard->pending_keymap);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100557 }
558#endif
559
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400560 wl_array_release(&keyboard->keys);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100561 wl_list_remove(&keyboard->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400562 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400563}
564
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +0100565static void
566weston_touch_reset_state(struct weston_touch *touch)
567{
568 touch->num_tp = 0;
569}
570
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400571WL_EXPORT struct weston_touch *
572weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400573{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400574 struct weston_touch *touch;
575
Peter Huttererf3d62272013-08-08 11:57:05 +1000576 touch = zalloc(sizeof *touch);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400577 if (touch == NULL)
578 return NULL;
579
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400580 wl_list_init(&touch->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100581 wl_list_init(&touch->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100582 wl_list_init(&touch->focus_view_listener.link);
583 touch->focus_view_listener.notify = touch_focus_view_destroyed;
584 wl_list_init(&touch->focus_resource_listener.link);
585 touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400586 touch->default_grab.interface = &default_touch_grab_interface;
587 touch->default_grab.touch = touch;
588 touch->grab = &touch->default_grab;
589 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400590
591 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400592}
593
594WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400595weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400596{
597 /* XXX: What about touch->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100598
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100599 wl_list_remove(&touch->focus_view_listener.link);
600 wl_list_remove(&touch->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400601 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400602}
603
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400604static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400605seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400606{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400607 enum wl_seat_capability caps = 0;
Rob Bradford6e737f52013-09-06 17:48:19 +0100608 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400609
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200610 if (seat->pointer_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400611 caps |= WL_SEAT_CAPABILITY_POINTER;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200612 if (seat->keyboard_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400613 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200614 if (seat->touch_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400615 caps |= WL_SEAT_CAPABILITY_TOUCH;
616
Rob Bradford6e737f52013-09-06 17:48:19 +0100617 wl_resource_for_each(resource, &seat->base_resource_list) {
618 wl_seat_send_capabilities(resource, caps);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500619 }
Jason Ekstranda4ab5422014-04-02 19:53:45 -0500620 wl_signal_emit(&seat->updated_caps_signal, seat);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400621}
622
623WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400624weston_pointer_set_focus(struct weston_pointer *pointer,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500625 struct weston_view *view,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400626 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400627{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400628 struct weston_keyboard *kbd = pointer->seat->keyboard;
Neil Roberts96d790e2013-09-19 17:32:00 +0100629 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100630 struct wl_display *display = pointer->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400631 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100632 struct wl_list *focus_resource_list;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800633 int refocus = 0;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500634
635 if ((!pointer->focus && view) ||
636 (pointer->focus && !view) ||
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800637 (pointer->focus && pointer->focus->surface != view->surface) ||
638 pointer->sx != sx || pointer->sy != sy)
639 refocus = 1;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400640
Neil Roberts96d790e2013-09-19 17:32:00 +0100641 focus_resource_list = &pointer->focus_resource_list;
642
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800643 if (!wl_list_empty(focus_resource_list) && refocus) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400644 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100645 wl_resource_for_each(resource, focus_resource_list) {
646 wl_pointer_send_leave(resource, serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500647 pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100648 }
649
650 move_resources(&pointer->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400651 }
652
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800653 if (find_resource_for_view(&pointer->resource_list, view) && refocus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100654 struct wl_client *surface_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500655 wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100656
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400657 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100658
Jason Ekstranda7af7042013-10-12 22:38:11 -0500659 if (kbd && kbd->focus != view->surface)
Kristian Høgsbergcb406f12013-10-09 10:54:03 -0700660 send_modifiers_to_client_in_list(surface_client,
661 &kbd->resource_list,
662 serial,
663 kbd);
664
Neil Roberts96d790e2013-09-19 17:32:00 +0100665 move_resources_for_client(focus_resource_list,
666 &pointer->resource_list,
667 surface_client);
668
669 wl_resource_for_each(resource, focus_resource_list) {
670 wl_pointer_send_enter(resource,
671 serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500672 view->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100673 sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400674 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100675
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400676 pointer->focus_serial = serial;
677 }
678
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100679 wl_list_remove(&pointer->focus_view_listener.link);
680 wl_list_init(&pointer->focus_view_listener.link);
681 wl_list_remove(&pointer->focus_resource_listener.link);
682 wl_list_init(&pointer->focus_resource_listener.link);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100683 if (view)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100684 wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100685 if (view && view->surface->resource)
686 wl_resource_add_destroy_listener(view->surface->resource,
687 &pointer->focus_resource_listener);
688
689 pointer->focus = view;
690 pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800691 pointer->sx = sx;
692 pointer->sy = sy;
693
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400694 wl_signal_emit(&pointer->focus_signal, pointer);
695}
696
Neil Roberts96d790e2013-09-19 17:32:00 +0100697static void
698send_enter_to_resource_list(struct wl_list *list,
699 struct weston_keyboard *keyboard,
700 struct weston_surface *surface,
701 uint32_t serial)
702{
703 struct wl_resource *resource;
704
705 wl_resource_for_each(resource, list) {
706 send_modifiers_to_resource(keyboard, resource, serial);
707 wl_keyboard_send_enter(resource, serial,
708 surface->resource,
709 &keyboard->keys);
710 }
711}
712
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400713WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400714weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400715 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400716{
717 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100718 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400719 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100720 struct wl_list *focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400721
Neil Roberts96d790e2013-09-19 17:32:00 +0100722 focus_resource_list = &keyboard->focus_resource_list;
723
724 if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400725 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100726 wl_resource_for_each(resource, focus_resource_list) {
727 wl_keyboard_send_leave(resource, serial,
728 keyboard->focus->resource);
729 }
730 move_resources(&keyboard->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400731 }
732
Neil Roberts96d790e2013-09-19 17:32:00 +0100733 if (find_resource_for_surface(&keyboard->resource_list, surface) &&
734 keyboard->focus != surface) {
735 struct wl_client *surface_client =
736 wl_resource_get_client(surface->resource);
737
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400738 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100739
740 move_resources_for_client(focus_resource_list,
741 &keyboard->resource_list,
742 surface_client);
743 send_enter_to_resource_list(focus_resource_list,
744 keyboard,
745 surface,
746 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400747 keyboard->focus_serial = serial;
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100748 }
749
750 wl_list_remove(&keyboard->focus_resource_listener.link);
751 wl_list_init(&keyboard->focus_resource_listener.link);
752 if (surface && surface->resource)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100753 wl_resource_add_destroy_listener(surface->resource,
754 &keyboard->focus_resource_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400755
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400756 keyboard->focus = surface;
757 wl_signal_emit(&keyboard->focus_signal, keyboard);
758}
759
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200760/* Users of this function must manually manage the keyboard focus */
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400761WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400762weston_keyboard_start_grab(struct weston_keyboard *keyboard,
763 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400764{
765 keyboard->grab = grab;
766 grab->keyboard = keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400767}
768
769WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400770weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400771{
772 keyboard->grab = &keyboard->default_grab;
773}
774
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200775static void
776weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
777{
778 keyboard->grab->interface->cancel(keyboard->grab);
779}
780
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400781WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400782weston_pointer_start_grab(struct weston_pointer *pointer,
783 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400784{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400785 pointer->grab = grab;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400786 grab->pointer = pointer;
Kristian Høgsbergda751b82013-07-04 00:58:07 -0400787 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400788}
789
790WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400791weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400792{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400793 pointer->grab = &pointer->default_grab;
Kristian Høgsbergda751b82013-07-04 00:58:07 -0400794 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400795}
796
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200797static void
798weston_pointer_cancel_grab(struct weston_pointer *pointer)
799{
800 pointer->grab->interface->cancel(pointer->grab);
801}
802
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400803WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400804weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400805{
806 touch->grab = grab;
807 grab->touch = touch;
808}
809
810WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400811weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400812{
813 touch->grab = &touch->default_grab;
814}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400815
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200816static void
817weston_touch_cancel_grab(struct weston_touch *touch)
818{
819 touch->grab->interface->cancel(touch->grab);
820}
821
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200822static void
823weston_pointer_clamp_for_output(struct weston_pointer *pointer,
824 struct weston_output *output,
825 wl_fixed_t *fx, wl_fixed_t *fy)
826{
827 int x, y;
828
829 x = wl_fixed_to_int(*fx);
830 y = wl_fixed_to_int(*fy);
831
832 if (x < output->x)
833 *fx = wl_fixed_from_int(output->x);
834 else if (x >= output->x + output->width)
835 *fx = wl_fixed_from_int(output->x +
836 output->width - 1);
837 if (y < output->y)
838 *fy = wl_fixed_from_int(output->y);
839 else if (y >= output->y + output->height)
840 *fy = wl_fixed_from_int(output->y +
841 output->height - 1);
842}
843
Rob Bradford806d8c02013-06-25 18:56:41 +0100844WL_EXPORT void
845weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400846{
Rob Bradford806d8c02013-06-25 18:56:41 +0100847 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400848 struct weston_output *output, *prev = NULL;
849 int x, y, old_x, old_y, valid = 0;
850
851 x = wl_fixed_to_int(*fx);
852 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +0100853 old_x = wl_fixed_to_int(pointer->x);
854 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400855
856 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +0100857 if (pointer->seat->output && pointer->seat->output != output)
858 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400859 if (pixman_region32_contains_point(&output->region,
860 x, y, NULL))
861 valid = 1;
862 if (pixman_region32_contains_point(&output->region,
863 old_x, old_y, NULL))
864 prev = output;
865 }
866
Rob Bradford66bd9f52013-06-25 18:56:42 +0100867 if (!prev)
868 prev = pointer->seat->output;
869
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200870 if (prev && !valid)
871 weston_pointer_clamp_for_output(pointer, prev, fx, fy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400872}
873
874/* Takes absolute values */
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100875WL_EXPORT void
876weston_pointer_move(struct weston_pointer *pointer, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400877{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400878 int32_t ix, iy;
879
Rob Bradford806d8c02013-06-25 18:56:41 +0100880 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400881
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400882 pointer->x = x;
883 pointer->y = y;
884
885 ix = wl_fixed_to_int(x);
886 iy = wl_fixed_to_int(y);
887
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400888 if (pointer->sprite) {
Jason Ekstranda7af7042013-10-12 22:38:11 -0500889 weston_view_set_position(pointer->sprite,
890 ix - pointer->hotspot_x,
891 iy - pointer->hotspot_y);
892 weston_view_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400893 }
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100894
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100895 pointer->grab->interface->focus(pointer->grab);
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100896 wl_signal_emit(&pointer->motion_signal, pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400897}
898
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200899/** Verify if the pointer is in a valid position and move it if it isn't.
900 */
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200901static void
902weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200903{
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200904 struct weston_pointer *pointer;
905 struct weston_compositor *ec;
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200906 struct weston_output *output, *closest = NULL;
907 int x, y, distance, min = INT_MAX;
908 wl_fixed_t fx, fy;
909
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200910 pointer = container_of(listener, struct weston_pointer,
911 output_destroy_listener);
912 ec = pointer->seat->compositor;
913
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200914 x = wl_fixed_to_int(pointer->x);
915 y = wl_fixed_to_int(pointer->y);
916
917 wl_list_for_each(output, &ec->output_list, link) {
918 if (pixman_region32_contains_point(&output->region,
919 x, y, NULL))
920 return;
921
922 /* Aproximante the distance from the pointer to the center of
923 * the output. */
924 distance = abs(output->x + output->width / 2 - x) +
925 abs(output->y + output->height / 2 - y);
926 if (distance < min) {
927 min = distance;
928 closest = output;
929 }
930 }
931
932 /* Nothing to do if there's no output left. */
933 if (!closest)
934 return;
935
936 fx = pointer->x;
937 fy = pointer->y;
938
939 weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
940 weston_pointer_move(pointer, fx, fy);
941}
942
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400943WL_EXPORT void
944notify_motion(struct weston_seat *seat,
945 uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
946{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400947 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400948 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400949
950 weston_compositor_wake(ec);
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100951 pointer->grab->interface->motion(pointer->grab, time, pointer->x + dx, pointer->y + dy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400952}
953
Daniel Stone96d47c02013-11-19 11:37:12 +0100954static void
955run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
956{
957 struct weston_compositor *compositor = seat->compositor;
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100958 struct weston_keyboard *keyboard = seat->keyboard;
Daniel Stone96d47c02013-11-19 11:37:12 +0100959 uint32_t diff;
960 unsigned int i;
961 struct {
962 uint32_t xkb;
963 enum weston_keyboard_modifier weston;
964 } mods[] = {
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100965 { keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
966 { keyboard->xkb_info->alt_mod, MODIFIER_ALT },
967 { keyboard->xkb_info->super_mod, MODIFIER_SUPER },
968 { keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
Daniel Stone96d47c02013-11-19 11:37:12 +0100969 };
970
971 diff = new & ~old;
972 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
973 if (diff & (1 << mods[i].xkb))
974 weston_compositor_run_modifier_binding(compositor,
975 seat,
976 mods[i].weston,
977 WL_KEYBOARD_KEY_STATE_PRESSED);
978 }
979
980 diff = old & ~new;
981 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
982 if (diff & (1 << mods[i].xkb))
983 weston_compositor_run_modifier_binding(compositor,
984 seat,
985 mods[i].weston,
986 WL_KEYBOARD_KEY_STATE_RELEASED);
987 }
988}
989
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400990WL_EXPORT void
991notify_motion_absolute(struct weston_seat *seat,
992 uint32_t time, wl_fixed_t x, wl_fixed_t y)
993{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400994 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400995 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400996
997 weston_compositor_wake(ec);
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100998 pointer->grab->interface->motion(pointer->grab, time, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400999}
1000
1001WL_EXPORT void
1002weston_surface_activate(struct weston_surface *surface,
1003 struct weston_seat *seat)
1004{
1005 struct weston_compositor *compositor = seat->compositor;
1006
Kristian Høgsberge3148752013-05-06 23:19:49 -04001007 if (seat->keyboard) {
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001008 weston_keyboard_set_focus(seat->keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001009 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001010 }
1011
1012 wl_signal_emit(&compositor->activate_signal, surface);
1013}
1014
1015WL_EXPORT void
1016notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1017 enum wl_pointer_button_state state)
1018{
1019 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001020 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001021
1022 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001023 weston_compositor_idle_inhibit(compositor);
1024 if (pointer->button_count == 0) {
1025 pointer->grab_button = button;
1026 pointer->grab_time = time;
1027 pointer->grab_x = pointer->x;
1028 pointer->grab_y = pointer->y;
1029 }
1030 pointer->button_count++;
1031 } else {
1032 weston_compositor_idle_release(compositor);
1033 pointer->button_count--;
1034 }
1035
1036 weston_compositor_run_button_binding(compositor, seat, time, button,
1037 state);
1038
1039 pointer->grab->interface->button(pointer->grab, time, button, state);
1040
1041 if (pointer->button_count == 1)
1042 pointer->grab_serial =
1043 wl_display_get_serial(compositor->wl_display);
1044}
1045
1046WL_EXPORT void
1047notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
1048 wl_fixed_t value)
1049{
1050 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001051 struct weston_pointer *pointer = seat->pointer;
Neil Roberts96d790e2013-09-19 17:32:00 +01001052 struct wl_resource *resource;
1053 struct wl_list *resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001054
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001055 weston_compositor_wake(compositor);
1056
1057 if (!value)
1058 return;
1059
1060 if (weston_compositor_run_axis_binding(compositor, seat,
1061 time, axis, value))
1062 return;
1063
Neil Roberts96d790e2013-09-19 17:32:00 +01001064 resource_list = &pointer->focus_resource_list;
1065 wl_resource_for_each(resource, resource_list)
1066 wl_pointer_send_axis(resource, time, axis,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001067 value);
1068}
1069
Giulio Camuffo6ef444d2014-08-28 19:44:09 +03001070WL_EXPORT int
1071weston_keyboard_set_locks(struct weston_keyboard *keyboard,
1072 uint32_t mask, uint32_t value)
1073{
1074#ifdef ENABLE_XKBCOMMON
1075 uint32_t serial;
1076 xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
1077 xkb_mod_mask_t num, caps;
1078
1079 /* We don't want the leds to go out of sync with the actual state
1080 * so if the backend has no way to change the leds don't try to
1081 * change the state */
1082 if (!keyboard->seat->led_update)
1083 return -1;
1084
1085 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
1086 XKB_STATE_DEPRESSED);
1087 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
1088 XKB_STATE_LATCHED);
1089 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
1090 XKB_STATE_LOCKED);
1091 group = xkb_state_serialize_group(keyboard->xkb_state.state,
1092 XKB_STATE_EFFECTIVE);
1093
1094 num = (1 << keyboard->xkb_info->mod2_mod);
1095 caps = (1 << keyboard->xkb_info->caps_mod);
1096 if (mask & WESTON_NUM_LOCK) {
1097 if (value & WESTON_NUM_LOCK)
1098 mods_locked |= num;
1099 else
1100 mods_locked &= ~num;
1101 }
1102 if (mask & WESTON_CAPS_LOCK) {
1103 if (value & WESTON_CAPS_LOCK)
1104 mods_locked |= caps;
1105 else
1106 mods_locked &= ~caps;
1107 }
1108
1109 xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
1110 mods_latched, mods_locked, 0, 0, group);
1111
1112 serial = wl_display_next_serial(
1113 keyboard->seat->compositor->wl_display);
1114 notify_modifiers(keyboard->seat, serial);
1115
1116 return 0;
1117#else
1118 return -1;
1119#endif
1120}
1121
Rob Bradford382ff462013-06-24 16:52:45 +01001122#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001123WL_EXPORT void
1124notify_modifiers(struct weston_seat *seat, uint32_t serial)
1125{
Kristian Høgsberge3148752013-05-06 23:19:49 -04001126 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001127 struct weston_keyboard_grab *grab = keyboard->grab;
1128 uint32_t mods_depressed, mods_latched, mods_locked, group;
1129 uint32_t mods_lookup;
1130 enum weston_led leds = 0;
1131 int changed = 0;
1132
1133 /* Serialize and update our internal state, checking to see if it's
1134 * different to the previous state. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001135 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001136 XKB_STATE_MODS_DEPRESSED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001137 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001138 XKB_STATE_MODS_LATCHED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001139 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001140 XKB_STATE_MODS_LOCKED);
1141 group = xkb_state_serialize_layout(keyboard->xkb_state.state,
1142 XKB_STATE_LAYOUT_EFFECTIVE);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001143
Derek Foreman244e99e2015-06-03 15:53:26 -05001144 if (mods_depressed != keyboard->modifiers.mods_depressed ||
1145 mods_latched != keyboard->modifiers.mods_latched ||
1146 mods_locked != keyboard->modifiers.mods_locked ||
1147 group != keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001148 changed = 1;
1149
Derek Foreman244e99e2015-06-03 15:53:26 -05001150 run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
Daniel Stone96d47c02013-11-19 11:37:12 +01001151 mods_depressed);
1152
Derek Foreman244e99e2015-06-03 15:53:26 -05001153 keyboard->modifiers.mods_depressed = mods_depressed;
1154 keyboard->modifiers.mods_latched = mods_latched;
1155 keyboard->modifiers.mods_locked = mods_locked;
1156 keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001157
1158 /* And update the modifier_state for bindings. */
1159 mods_lookup = mods_depressed | mods_latched;
1160 seat->modifier_state = 0;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001161 if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001162 seat->modifier_state |= MODIFIER_CTRL;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001163 if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001164 seat->modifier_state |= MODIFIER_ALT;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001165 if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001166 seat->modifier_state |= MODIFIER_SUPER;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001167 if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001168 seat->modifier_state |= MODIFIER_SHIFT;
1169
1170 /* Finally, notify the compositor that LEDs have changed. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001171 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1172 keyboard->xkb_info->num_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001173 leds |= LED_NUM_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001174 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1175 keyboard->xkb_info->caps_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001176 leds |= LED_CAPS_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001177 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1178 keyboard->xkb_info->scroll_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001179 leds |= LED_SCROLL_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001180 if (leds != keyboard->xkb_state.leds && seat->led_update)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001181 seat->led_update(seat, leds);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001182 keyboard->xkb_state.leds = leds;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001183
1184 if (changed) {
1185 grab->interface->modifiers(grab,
1186 serial,
1187 keyboard->modifiers.mods_depressed,
1188 keyboard->modifiers.mods_latched,
1189 keyboard->modifiers.mods_locked,
1190 keyboard->modifiers.group);
1191 }
1192}
1193
1194static void
1195update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1196 enum wl_keyboard_key_state state)
1197{
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001198 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001199 enum xkb_key_direction direction;
1200
Matt Roper01a92732013-06-24 16:52:44 +01001201 /* Keyboard modifiers don't exist in raw keyboard mode */
1202 if (!seat->compositor->use_xkbcommon)
1203 return;
1204
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001205 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1206 direction = XKB_KEY_DOWN;
1207 else
1208 direction = XKB_KEY_UP;
1209
1210 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1211 * broken keycode system, which starts at 8. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001212 xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001213
1214 notify_modifiers(seat, serial);
1215}
Rui Matos65196bc2013-10-10 19:44:19 +02001216
1217static void
1218send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
1219{
1220 wl_keyboard_send_keymap(resource,
1221 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1222 xkb_info->keymap_fd,
1223 xkb_info->keymap_size);
1224}
1225
1226static void
1227send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
1228{
1229 wl_keyboard_send_modifiers(resource, serial,
1230 keyboard->modifiers.mods_depressed,
1231 keyboard->modifiers.mods_latched,
1232 keyboard->modifiers.mods_locked,
1233 keyboard->modifiers.group);
1234}
1235
1236static struct weston_xkb_info *
1237weston_xkb_info_create(struct xkb_keymap *keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001238
1239static void
1240update_keymap(struct weston_seat *seat)
1241{
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001242 struct weston_keyboard *keyboard = seat->keyboard;
Rui Matos65196bc2013-10-10 19:44:19 +02001243 struct wl_resource *resource;
1244 struct weston_xkb_info *xkb_info;
1245 struct xkb_state *state;
1246 xkb_mod_mask_t latched_mods;
1247 xkb_mod_mask_t locked_mods;
1248
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001249 xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001250
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001251 xkb_keymap_unref(keyboard->pending_keymap);
1252 keyboard->pending_keymap = NULL;
Rui Matos65196bc2013-10-10 19:44:19 +02001253
1254 if (!xkb_info) {
1255 weston_log("failed to create XKB info\n");
1256 return;
1257 }
1258
1259 state = xkb_state_new(xkb_info->keymap);
1260 if (!state) {
1261 weston_log("failed to initialise XKB state\n");
1262 weston_xkb_info_destroy(xkb_info);
1263 return;
1264 }
1265
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001266 latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1267 XKB_STATE_MODS_LATCHED);
1268 locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1269 XKB_STATE_MODS_LOCKED);
Rui Matos65196bc2013-10-10 19:44:19 +02001270 xkb_state_update_mask(state,
1271 0, /* depressed */
1272 latched_mods,
1273 locked_mods,
1274 0, 0, 0);
1275
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001276 weston_xkb_info_destroy(keyboard->xkb_info);
1277 keyboard->xkb_info = xkb_info;
Rui Matos65196bc2013-10-10 19:44:19 +02001278
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001279 xkb_state_unref(keyboard->xkb_state.state);
1280 keyboard->xkb_state.state = state;
Rui Matos65196bc2013-10-10 19:44:19 +02001281
Derek Foremanbc91e542015-06-03 15:53:27 -05001282 wl_resource_for_each(resource, &keyboard->resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001283 send_keymap(resource, xkb_info);
Derek Foremanbc91e542015-06-03 15:53:27 -05001284 wl_resource_for_each(resource, &keyboard->focus_resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001285 send_keymap(resource, xkb_info);
1286
1287 notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
1288
1289 if (!latched_mods && !locked_mods)
1290 return;
1291
Derek Foremanbc91e542015-06-03 15:53:27 -05001292 wl_resource_for_each(resource, &keyboard->resource_list)
1293 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
1294 wl_resource_for_each(resource, &keyboard->focus_resource_list)
1295 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
Rui Matos65196bc2013-10-10 19:44:19 +02001296}
Rob Bradford382ff462013-06-24 16:52:45 +01001297#else
1298WL_EXPORT void
1299notify_modifiers(struct weston_seat *seat, uint32_t serial)
1300{
1301}
1302
1303static void
1304update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1305 enum wl_keyboard_key_state state)
1306{
1307}
Rui Matos65196bc2013-10-10 19:44:19 +02001308
1309static void
1310update_keymap(struct weston_seat *seat)
1311{
1312}
Rob Bradford382ff462013-06-24 16:52:45 +01001313#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001314
1315WL_EXPORT void
1316notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1317 enum wl_keyboard_key_state state,
1318 enum weston_key_state_update update_state)
1319{
1320 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001321 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001322 struct weston_keyboard_grab *grab = keyboard->grab;
Pekka Paalanen86b53962014-11-19 13:43:32 +02001323 uint32_t *k, *end;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001324
1325 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001326 weston_compositor_idle_inhibit(compositor);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001327 } else {
1328 weston_compositor_idle_release(compositor);
1329 }
1330
Pekka Paalanen86b53962014-11-19 13:43:32 +02001331 end = keyboard->keys.data + keyboard->keys.size;
1332 for (k = keyboard->keys.data; k < end; k++) {
1333 if (*k == key) {
1334 /* Ignore server-generated repeats. */
1335 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1336 return;
1337 *k = *--end;
1338 }
1339 }
1340 keyboard->keys.size = (void *) end - keyboard->keys.data;
1341 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1342 k = wl_array_add(&keyboard->keys, sizeof *k);
1343 *k = key;
1344 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001345
1346 if (grab == &keyboard->default_grab ||
1347 grab == &keyboard->input_method_grab) {
Pekka Paalanen86b53962014-11-19 13:43:32 +02001348 weston_compositor_run_key_binding(compositor, seat, time, key,
1349 state);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001350 grab = keyboard->grab;
1351 }
1352
1353 grab->interface->key(grab, time, key, state);
1354
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001355 if (keyboard->pending_keymap &&
Pekka Paalanen86b53962014-11-19 13:43:32 +02001356 keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02001357 update_keymap(seat);
1358
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001359 if (update_state == STATE_UPDATE_AUTOMATIC) {
1360 update_modifier_state(seat,
1361 wl_display_get_serial(compositor->wl_display),
1362 key,
1363 state);
1364 }
Giulio Camuffob6ddf6c2015-02-06 19:06:54 +02001365
1366 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1367 keyboard->grab_serial =
1368 wl_display_get_serial(compositor->wl_display);
1369 keyboard->grab_time = time;
1370 keyboard->grab_key = key;
1371 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001372}
1373
1374WL_EXPORT void
1375notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
1376 wl_fixed_t x, wl_fixed_t y)
1377{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001378 if (output) {
Giulio Camuffo1959ab82013-11-14 23:42:52 +01001379 weston_pointer_move(seat->pointer, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001380 } else {
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001381 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001382 * NULL) here, but somehow that breaks re-entry... */
1383 }
1384}
1385
1386static void
1387destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1388{
1389 struct weston_seat *ws;
1390
1391 ws = container_of(listener, struct weston_seat,
1392 saved_kbd_focus_listener);
1393
1394 ws->saved_kbd_focus = NULL;
1395}
1396
1397WL_EXPORT void
1398notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1399 enum weston_key_state_update update_state)
1400{
1401 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001402 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001403 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001404 uint32_t *k, serial;
1405
1406 serial = wl_display_next_serial(compositor->wl_display);
1407 wl_array_copy(&keyboard->keys, keys);
1408 wl_array_for_each(k, &keyboard->keys) {
1409 weston_compositor_idle_inhibit(compositor);
1410 if (update_state == STATE_UPDATE_AUTOMATIC)
1411 update_modifier_state(seat, serial, *k,
1412 WL_KEYBOARD_KEY_STATE_PRESSED);
1413 }
1414
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001415 surface = seat->saved_kbd_focus;
1416
1417 if (surface) {
1418 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1419 weston_keyboard_set_focus(keyboard, surface);
1420 seat->saved_kbd_focus = NULL;
1421 }
1422}
1423
1424WL_EXPORT void
1425notify_keyboard_focus_out(struct weston_seat *seat)
1426{
1427 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001428 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001429 uint32_t *k, serial;
1430
1431 serial = wl_display_next_serial(compositor->wl_display);
1432 wl_array_for_each(k, &keyboard->keys) {
1433 weston_compositor_idle_release(compositor);
1434 update_modifier_state(seat, serial, *k,
1435 WL_KEYBOARD_KEY_STATE_RELEASED);
1436 }
1437
1438 seat->modifier_state = 0;
1439
1440 if (keyboard->focus) {
1441 seat->saved_kbd_focus = keyboard->focus;
1442 seat->saved_kbd_focus_listener.notify =
1443 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001444 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001445 &seat->saved_kbd_focus_listener);
1446 }
1447
1448 weston_keyboard_set_focus(keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001449 weston_keyboard_cancel_grab(keyboard);
Kristian Høgsbergebd5fd42013-11-22 21:12:19 -08001450 if (seat->pointer)
1451 weston_pointer_cancel_grab(seat->pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001452}
1453
Michael Fua2bb7912013-07-23 15:51:06 +08001454WL_EXPORT void
Derek Foreman4c93c082015-04-30 16:45:41 -05001455weston_touch_set_focus(struct weston_touch *touch, struct weston_view *view)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001456{
Neil Roberts96d790e2013-09-19 17:32:00 +01001457 struct wl_list *focus_resource_list;
1458
Derek Foreman4c93c082015-04-30 16:45:41 -05001459 focus_resource_list = &touch->focus_resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001460
Derek Foreman4c93c082015-04-30 16:45:41 -05001461 if (view && touch->focus &&
1462 touch->focus->surface == view->surface) {
1463 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001464 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001465 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001466
Derek Foreman4c93c082015-04-30 16:45:41 -05001467 wl_list_remove(&touch->focus_resource_listener.link);
1468 wl_list_init(&touch->focus_resource_listener.link);
1469 wl_list_remove(&touch->focus_view_listener.link);
1470 wl_list_init(&touch->focus_view_listener.link);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001471
Neil Roberts96d790e2013-09-19 17:32:00 +01001472 if (!wl_list_empty(focus_resource_list)) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001473 move_resources(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001474 focus_resource_list);
1475 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001476
Jason Ekstranda7af7042013-10-12 22:38:11 -05001477 if (view) {
Derek Foreman362656b2014-09-04 10:23:05 -05001478 struct wl_client *surface_client;
1479
1480 if (!view->surface->resource) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001481 touch->focus = NULL;
Derek Foreman362656b2014-09-04 10:23:05 -05001482 return;
1483 }
1484
1485 surface_client = wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +01001486 move_resources_for_client(focus_resource_list,
Derek Foreman4c93c082015-04-30 16:45:41 -05001487 &touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001488 surface_client);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001489 wl_resource_add_destroy_listener(view->surface->resource,
Derek Foreman4c93c082015-04-30 16:45:41 -05001490 &touch->focus_resource_listener);
1491 wl_signal_add(&view->destroy_signal, &touch->focus_view_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001492 }
Derek Foreman4c93c082015-04-30 16:45:41 -05001493 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001494}
1495
1496/**
1497 * notify_touch - emulates button touches and notifies surfaces accordingly.
1498 *
1499 * It assumes always the correct cycle sequence until it gets here: touch_down
1500 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1501 * for sending along such order.
1502 *
1503 */
1504WL_EXPORT void
1505notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1506 wl_fixed_t x, wl_fixed_t y, int touch_type)
1507{
1508 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001509 struct weston_touch *touch = seat->touch;
Kristian Høgsberge329f362013-05-06 22:19:57 -04001510 struct weston_touch_grab *grab = touch->grab;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001511 struct weston_view *ev;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001512 wl_fixed_t sx, sy;
1513
1514 /* Update grab's global coordinates. */
Neil Roberts306fe082013-10-03 16:43:06 +01001515 if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
1516 touch->grab_x = x;
1517 touch->grab_y = y;
1518 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001519
1520 switch (touch_type) {
1521 case WL_TOUCH_DOWN:
1522 weston_compositor_idle_inhibit(ec);
1523
Jonas Ådahl9484b692013-12-02 22:05:03 +01001524 touch->num_tp++;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001525
Jason Ekstranda7af7042013-10-12 22:38:11 -05001526 /* the first finger down picks the view, and all further go
1527 * to that view for the remainder of the touch session i.e.
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001528 * until all touch points are up again. */
Jonas Ådahl9484b692013-12-02 22:05:03 +01001529 if (touch->num_tp == 1) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001530 ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
Derek Foreman4c93c082015-04-30 16:45:41 -05001531 weston_touch_set_focus(touch, ev);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001532 } else if (touch->focus) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001533 ev = touch->focus;
1534 weston_view_from_global_fixed(ev, x, y, &sx, &sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001535 } else {
1536 /* Unexpected condition: We have non-initial touch but
1537 * there is no focused surface.
1538 */
1539 weston_log("touch event received with %d points down"
Jonas Ådahl9484b692013-12-02 22:05:03 +01001540 "but no surface focused\n", touch->num_tp);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001541 return;
1542 }
1543
Kristian Høgsbergc8964012014-02-05 14:25:18 -08001544 weston_compositor_run_touch_binding(ec, seat,
1545 time, touch_type);
1546
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001547 grab->interface->down(grab, time, touch_id, sx, sy);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001548 if (touch->num_tp == 1) {
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001549 touch->grab_serial =
1550 wl_display_get_serial(ec->wl_display);
Neil Roberts306fe082013-10-03 16:43:06 +01001551 touch->grab_touch_id = touch_id;
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001552 touch->grab_time = time;
1553 touch->grab_x = x;
1554 touch->grab_y = y;
1555 }
1556
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001557 break;
1558 case WL_TOUCH_MOTION:
Jason Ekstranda7af7042013-10-12 22:38:11 -05001559 ev = touch->focus;
1560 if (!ev)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001561 break;
1562
Jason Ekstranda7af7042013-10-12 22:38:11 -05001563 weston_view_from_global_fixed(ev, x, y, &sx, &sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001564 grab->interface->motion(grab, time, touch_id, sx, sy);
1565 break;
1566 case WL_TOUCH_UP:
Kristian Høgsberga30e29a2014-01-08 22:29:20 -08001567 if (touch->num_tp == 0) {
1568 /* This can happen if we start out with one or
1569 * more fingers on the touch screen, in which
1570 * case we didn't get the corresponding down
1571 * event. */
1572 weston_log("unmatched touch up event\n");
1573 break;
1574 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001575 weston_compositor_idle_release(ec);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001576 touch->num_tp--;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001577
1578 grab->interface->up(grab, time, touch_id);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001579 if (touch->num_tp == 0)
Derek Foreman4c93c082015-04-30 16:45:41 -05001580 weston_touch_set_focus(touch, NULL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001581 break;
1582 }
1583}
1584
Jonas Ådahl1679f232014-04-12 09:39:51 +02001585WL_EXPORT void
1586notify_touch_frame(struct weston_seat *seat)
1587{
1588 struct weston_touch *touch = seat->touch;
1589 struct weston_touch_grab *grab = touch->grab;
1590
1591 grab->interface->frame(grab);
1592}
1593
Pekka Paalanen8274d902014-08-06 19:36:51 +03001594static int
1595pointer_cursor_surface_get_label(struct weston_surface *surface,
1596 char *buf, size_t len)
1597{
1598 return snprintf(buf, len, "cursor");
1599}
1600
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001601static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001602pointer_cursor_surface_configure(struct weston_surface *es,
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001603 int32_t dx, int32_t dy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001604{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001605 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001606 int x, y;
1607
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001608 if (es->width == 0)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001609 return;
1610
Jason Ekstranda7af7042013-10-12 22:38:11 -05001611 assert(es == pointer->sprite->surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001612
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001613 pointer->hotspot_x -= dx;
1614 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001615
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001616 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1617 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001618
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001619 weston_view_set_position(pointer->sprite, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001620
1621 empty_region(&es->pending.input);
Ander Conselvan de Oliveira23900f72014-01-31 16:07:51 +02001622 empty_region(&es->input);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001623
1624 if (!weston_surface_is_mapped(es)) {
Giulio Camuffo412e6a52014-07-09 22:12:56 +03001625 weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
1626 &pointer->sprite->layer_link);
Jason Ekstranda7af7042013-10-12 22:38:11 -05001627 weston_view_update_transform(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001628 }
1629}
1630
1631static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001632pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1633 uint32_t serial, struct wl_resource *surface_resource,
1634 int32_t x, int32_t y)
1635{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001636 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001637 struct weston_surface *surface = NULL;
1638
1639 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001640 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001641
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001642 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001643 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001644 /* pointer->focus->surface->resource can be NULL. Surfaces like the
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001645 black_surface used in shell.c for fullscreen don't have
1646 a resource, but can still have focus */
Jason Ekstranda7af7042013-10-12 22:38:11 -05001647 if (pointer->focus->surface->resource == NULL)
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001648 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001649 if (wl_resource_get_client(pointer->focus->surface->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001650 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001651 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001652 return;
1653
Derek Foreman4e53c532015-03-23 10:55:32 -05001654 if (!surface) {
1655 if (pointer->sprite)
1656 pointer_unmap_sprite(pointer);
1657 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001658 }
1659
Jonas Ådahlb4070242015-03-18 15:08:03 +08001660 if (pointer->sprite && pointer->sprite->surface == surface &&
1661 pointer->hotspot_x == x && pointer->hotspot_y == y)
1662 return;
1663
Derek Foreman4e53c532015-03-23 10:55:32 -05001664 if (!pointer->sprite || pointer->sprite->surface != surface) {
1665 if (weston_surface_set_role(surface, "wl_pointer-cursor",
1666 resource,
1667 WL_POINTER_ERROR_ROLE) < 0)
1668 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001669
Derek Foreman4e53c532015-03-23 10:55:32 -05001670 if (pointer->sprite)
1671 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001672
Derek Foreman4e53c532015-03-23 10:55:32 -05001673 wl_signal_add(&surface->destroy_signal,
1674 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001675
Derek Foreman4e53c532015-03-23 10:55:32 -05001676 surface->configure = pointer_cursor_surface_configure;
1677 surface->configure_private = pointer;
1678 weston_surface_set_label_func(surface,
1679 pointer_cursor_surface_get_label);
1680 pointer->sprite = weston_view_create(surface);
1681 }
1682
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001683 pointer->hotspot_x = x;
1684 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001685
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02001686 if (surface->buffer_ref.buffer) {
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001687 pointer_cursor_surface_configure(surface, 0, 0);
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02001688 weston_view_schedule_repaint(pointer->sprite);
1689 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001690}
1691
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001692static void
1693pointer_release(struct wl_client *client, struct wl_resource *resource)
1694{
1695 wl_resource_destroy(resource);
1696}
1697
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001698static const struct wl_pointer_interface pointer_interface = {
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001699 pointer_set_cursor,
1700 pointer_release
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001701};
1702
1703static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001704seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
1705 uint32_t id)
1706{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001707 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001708 struct wl_resource *cr;
1709
Kristian Høgsberge3148752013-05-06 23:19:49 -04001710 if (!seat->pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001711 return;
1712
Jason Ekstranda85118c2013-06-27 20:17:02 -05001713 cr = wl_resource_create(client, &wl_pointer_interface,
1714 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07001715 if (cr == NULL) {
1716 wl_client_post_no_memory(client);
1717 return;
1718 }
1719
Neil Roberts96d790e2013-09-19 17:32:00 +01001720 /* May be moved to focused list later by either
1721 * weston_pointer_set_focus or directly if this client is already
1722 * focused */
Jason Ekstrand44a38632013-06-14 10:08:00 -05001723 wl_list_insert(&seat->pointer->resource_list, wl_resource_get_link(cr));
Jason Ekstranda85118c2013-06-27 20:17:02 -05001724 wl_resource_set_implementation(cr, &pointer_interface, seat->pointer,
1725 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001726
Jason Ekstranda7af7042013-10-12 22:38:11 -05001727 if (seat->pointer->focus && seat->pointer->focus->surface->resource &&
1728 wl_resource_get_client(seat->pointer->focus->surface->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001729 wl_fixed_t sx, sy;
1730
Jason Ekstranda7af7042013-10-12 22:38:11 -05001731 weston_view_from_global_fixed(seat->pointer->focus,
1732 seat->pointer->x,
1733 seat->pointer->y,
1734 &sx, &sy);
Neil Roberts96d790e2013-09-19 17:32:00 +01001735
1736 wl_list_remove(wl_resource_get_link(cr));
1737 wl_list_insert(&seat->pointer->focus_resource_list,
1738 wl_resource_get_link(cr));
1739 wl_pointer_send_enter(cr,
1740 seat->pointer->focus_serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -05001741 seat->pointer->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01001742 sx, sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001743 }
1744}
1745
1746static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001747keyboard_release(struct wl_client *client, struct wl_resource *resource)
1748{
1749 wl_resource_destroy(resource);
1750}
1751
1752static const struct wl_keyboard_interface keyboard_interface = {
1753 keyboard_release
1754};
1755
Derek Foreman280e7dd2014-10-03 13:13:42 -05001756static bool
Neil Roberts96d790e2013-09-19 17:32:00 +01001757should_send_modifiers_to_client(struct weston_seat *seat,
1758 struct wl_client *client)
1759{
1760 if (seat->keyboard &&
1761 seat->keyboard->focus &&
Jason Ekstrand42133d42013-11-14 20:06:16 -06001762 seat->keyboard->focus->resource &&
Neil Roberts96d790e2013-09-19 17:32:00 +01001763 wl_resource_get_client(seat->keyboard->focus->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05001764 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01001765
1766 if (seat->pointer &&
1767 seat->pointer->focus &&
Jason Ekstrand42133d42013-11-14 20:06:16 -06001768 seat->pointer->focus->surface->resource &&
Jason Ekstranda7af7042013-10-12 22:38:11 -05001769 wl_resource_get_client(seat->pointer->focus->surface->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05001770 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01001771
Derek Foreman280e7dd2014-10-03 13:13:42 -05001772 return false;
Neil Roberts96d790e2013-09-19 17:32:00 +01001773}
1774
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001775static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001776seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
1777 uint32_t id)
1778{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001779 struct weston_seat *seat = wl_resource_get_user_data(resource);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001780 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001781 struct wl_resource *cr;
1782
Derek Foreman345c9f32015-06-03 15:53:28 -05001783 if (!keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001784 return;
1785
Jason Ekstranda85118c2013-06-27 20:17:02 -05001786 cr = wl_resource_create(client, &wl_keyboard_interface,
1787 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07001788 if (cr == NULL) {
1789 wl_client_post_no_memory(client);
1790 return;
1791 }
1792
Neil Roberts96d790e2013-09-19 17:32:00 +01001793 /* May be moved to focused list later by either
1794 * weston_keyboard_set_focus or directly if this client is already
1795 * focused */
Derek Foreman345c9f32015-06-03 15:53:28 -05001796 wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001797 wl_resource_set_implementation(cr, &keyboard_interface,
1798 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001799
Jonny Lamb66a41a02014-08-12 14:58:25 +02001800 if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
1801 wl_keyboard_send_repeat_info(cr,
1802 seat->compositor->kb_repeat_rate,
1803 seat->compositor->kb_repeat_delay);
1804 }
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04001805
Matt Roper01a92732013-06-24 16:52:44 +01001806 if (seat->compositor->use_xkbcommon) {
1807 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001808 keyboard->xkb_info->keymap_fd,
1809 keyboard->xkb_info->keymap_size);
Matt Roper01a92732013-06-24 16:52:44 +01001810 } else {
1811 int null_fd = open("/dev/null", O_RDONLY);
1812 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
1813 null_fd,
1814 0);
1815 close(null_fd);
1816 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001817
Neil Roberts96d790e2013-09-19 17:32:00 +01001818 if (should_send_modifiers_to_client(seat, client)) {
Derek Foreman345c9f32015-06-03 15:53:28 -05001819 send_modifiers_to_resource(keyboard,
Neil Roberts96d790e2013-09-19 17:32:00 +01001820 cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05001821 keyboard->focus_serial);
Neil Roberts96d790e2013-09-19 17:32:00 +01001822 }
1823
Derek Foreman345c9f32015-06-03 15:53:28 -05001824 if (keyboard->focus && keyboard->focus->resource &&
1825 wl_resource_get_client(keyboard->focus->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01001826 struct weston_surface *surface =
Derek Foreman345c9f32015-06-03 15:53:28 -05001827 (struct weston_surface *)keyboard->focus;
Neil Roberts96d790e2013-09-19 17:32:00 +01001828
1829 wl_list_remove(wl_resource_get_link(cr));
Derek Foreman345c9f32015-06-03 15:53:28 -05001830 wl_list_insert(&keyboard->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001831 wl_resource_get_link(cr));
1832 wl_keyboard_send_enter(cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05001833 keyboard->focus_serial,
Neil Roberts96d790e2013-09-19 17:32:00 +01001834 surface->resource,
Derek Foreman345c9f32015-06-03 15:53:28 -05001835 &keyboard->keys);
Neil Roberts96d790e2013-09-19 17:32:00 +01001836
1837 /* If this is the first keyboard resource for this
1838 * client... */
Derek Foreman345c9f32015-06-03 15:53:28 -05001839 if (keyboard->focus_resource_list.prev ==
Neil Roberts96d790e2013-09-19 17:32:00 +01001840 wl_resource_get_link(cr))
1841 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001842 }
1843}
1844
1845static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001846touch_release(struct wl_client *client, struct wl_resource *resource)
1847{
1848 wl_resource_destroy(resource);
1849}
1850
1851static const struct wl_touch_interface touch_interface = {
1852 touch_release
1853};
1854
1855static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001856seat_get_touch(struct wl_client *client, struct wl_resource *resource,
1857 uint32_t id)
1858{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001859 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001860 struct wl_resource *cr;
1861
Kristian Høgsberge3148752013-05-06 23:19:49 -04001862 if (!seat->touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001863 return;
1864
Jason Ekstranda85118c2013-06-27 20:17:02 -05001865 cr = wl_resource_create(client, &wl_touch_interface,
1866 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07001867 if (cr == NULL) {
1868 wl_client_post_no_memory(client);
1869 return;
1870 }
1871
Neil Roberts96d790e2013-09-19 17:32:00 +01001872 if (seat->touch->focus &&
Jason Ekstranda7af7042013-10-12 22:38:11 -05001873 wl_resource_get_client(seat->touch->focus->surface->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01001874 wl_list_insert(&seat->touch->resource_list,
1875 wl_resource_get_link(cr));
1876 } else {
1877 wl_list_insert(&seat->touch->focus_resource_list,
1878 wl_resource_get_link(cr));
1879 }
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001880 wl_resource_set_implementation(cr, &touch_interface,
1881 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001882}
1883
1884static const struct wl_seat_interface seat_interface = {
1885 seat_get_pointer,
1886 seat_get_keyboard,
1887 seat_get_touch,
1888};
1889
1890static void
1891bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1892{
Kristian Høgsberge3148752013-05-06 23:19:49 -04001893 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001894 struct wl_resource *resource;
1895 enum wl_seat_capability caps = 0;
1896
Jason Ekstranda85118c2013-06-27 20:17:02 -05001897 resource = wl_resource_create(client,
Jonny Lamb66a41a02014-08-12 14:58:25 +02001898 &wl_seat_interface, MIN(version, 4), id);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001899 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
Jason Ekstranda85118c2013-06-27 20:17:02 -05001900 wl_resource_set_implementation(resource, &seat_interface, data,
1901 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001902
1903 if (seat->pointer)
1904 caps |= WL_SEAT_CAPABILITY_POINTER;
1905 if (seat->keyboard)
1906 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
1907 if (seat->touch)
1908 caps |= WL_SEAT_CAPABILITY_TOUCH;
1909
1910 wl_seat_send_capabilities(resource, caps);
Jasper St. Pierre0013a292014-08-07 16:43:11 -04001911 if (version >= WL_SEAT_NAME_SINCE_VERSION)
Rob Bradforde445ae62013-05-31 18:09:51 +01001912 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001913}
1914
Rob Bradford382ff462013-06-24 16:52:45 +01001915#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001916int
1917weston_compositor_xkb_init(struct weston_compositor *ec,
1918 struct xkb_rule_names *names)
1919{
Rob Bradford382ff462013-06-24 16:52:45 +01001920 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01001921
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001922 if (ec->xkb_context == NULL) {
1923 ec->xkb_context = xkb_context_new(0);
1924 if (ec->xkb_context == NULL) {
1925 weston_log("failed to create XKB context\n");
1926 return -1;
1927 }
1928 }
1929
1930 if (names)
1931 ec->xkb_names = *names;
1932 if (!ec->xkb_names.rules)
1933 ec->xkb_names.rules = strdup("evdev");
1934 if (!ec->xkb_names.model)
1935 ec->xkb_names.model = strdup("pc105");
1936 if (!ec->xkb_names.layout)
1937 ec->xkb_names.layout = strdup("us");
1938
1939 return 0;
1940}
1941
Stefan Schmidtfda26522013-09-17 10:54:09 +01001942static void
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001943weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001944{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001945 if (--xkb_info->ref_count > 0)
1946 return;
1947
Ran Benitac9c74152014-08-19 23:59:52 +03001948 xkb_keymap_unref(xkb_info->keymap);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001949
1950 if (xkb_info->keymap_area)
1951 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
1952 if (xkb_info->keymap_fd >= 0)
1953 close(xkb_info->keymap_fd);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001954 free(xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001955}
1956
1957void
1958weston_compositor_xkb_destroy(struct weston_compositor *ec)
1959{
Matt Roper01a92732013-06-24 16:52:44 +01001960 /*
1961 * If we're operating in raw keyboard mode, we never initialized
1962 * libxkbcommon so there's no cleanup to do either.
1963 */
1964 if (!ec->use_xkbcommon)
1965 return;
1966
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001967 free((char *) ec->xkb_names.rules);
1968 free((char *) ec->xkb_names.model);
1969 free((char *) ec->xkb_names.layout);
1970 free((char *) ec->xkb_names.variant);
1971 free((char *) ec->xkb_names.options);
Stefan Schmidtfda26522013-09-17 10:54:09 +01001972
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001973 if (ec->xkb_info)
1974 weston_xkb_info_destroy(ec->xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001975 xkb_context_unref(ec->xkb_context);
1976}
1977
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001978static struct weston_xkb_info *
1979weston_xkb_info_create(struct xkb_keymap *keymap)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001980{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001981 struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
1982 if (xkb_info == NULL)
1983 return NULL;
1984
Ran Benita2e1968f2014-08-19 23:59:51 +03001985 xkb_info->keymap = xkb_keymap_ref(keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001986 xkb_info->ref_count = 1;
1987
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001988 char *keymap_str;
1989
Ran Benita2e1968f2014-08-19 23:59:51 +03001990 xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
1991 XKB_MOD_NAME_SHIFT);
1992 xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
1993 XKB_MOD_NAME_CAPS);
1994 xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
1995 XKB_MOD_NAME_CTRL);
1996 xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
1997 XKB_MOD_NAME_ALT);
1998 xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
1999 "Mod2");
2000 xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2001 "Mod3");
2002 xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2003 XKB_MOD_NAME_LOGO);
2004 xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2005 "Mod5");
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002006
Ran Benita2e1968f2014-08-19 23:59:51 +03002007 xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
2008 XKB_LED_NAME_NUM);
2009 xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
2010 XKB_LED_NAME_CAPS);
2011 xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
2012 XKB_LED_NAME_SCROLL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002013
Ran Benita2e1968f2014-08-19 23:59:51 +03002014 keymap_str = xkb_keymap_get_as_string(xkb_info->keymap,
2015 XKB_KEYMAP_FORMAT_TEXT_V1);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002016 if (keymap_str == NULL) {
2017 weston_log("failed to get string version of keymap\n");
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002018 goto err_keymap;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002019 }
2020 xkb_info->keymap_size = strlen(keymap_str) + 1;
2021
2022 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2023 if (xkb_info->keymap_fd < 0) {
2024 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2025 (unsigned long) xkb_info->keymap_size);
2026 goto err_keymap_str;
2027 }
2028
2029 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2030 PROT_READ | PROT_WRITE,
2031 MAP_SHARED, xkb_info->keymap_fd, 0);
2032 if (xkb_info->keymap_area == MAP_FAILED) {
2033 weston_log("failed to mmap() %lu bytes\n",
2034 (unsigned long) xkb_info->keymap_size);
2035 goto err_dev_zero;
2036 }
2037 strcpy(xkb_info->keymap_area, keymap_str);
2038 free(keymap_str);
2039
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002040 return xkb_info;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002041
2042err_dev_zero:
2043 close(xkb_info->keymap_fd);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002044err_keymap_str:
2045 free(keymap_str);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002046err_keymap:
Ran Benita2e1968f2014-08-19 23:59:51 +03002047 xkb_keymap_unref(xkb_info->keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002048 free(xkb_info);
2049 return NULL;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002050}
2051
2052static int
2053weston_compositor_build_global_keymap(struct weston_compositor *ec)
2054{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002055 struct xkb_keymap *keymap;
2056
2057 if (ec->xkb_info != NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002058 return 0;
2059
Ran Benita2e1968f2014-08-19 23:59:51 +03002060 keymap = xkb_keymap_new_from_names(ec->xkb_context,
2061 &ec->xkb_names,
2062 0);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002063 if (keymap == NULL) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002064 weston_log("failed to compile global XKB keymap\n");
2065 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
2066 "options %s\n",
2067 ec->xkb_names.rules, ec->xkb_names.model,
2068 ec->xkb_names.layout, ec->xkb_names.variant,
2069 ec->xkb_names.options);
2070 return -1;
2071 }
2072
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002073 ec->xkb_info = weston_xkb_info_create(keymap);
Rui Matos73d93952013-10-24 19:28:41 +02002074 xkb_keymap_unref(keymap);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002075 if (ec->xkb_info == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002076 return -1;
2077
2078 return 0;
2079}
Rob Bradford382ff462013-06-24 16:52:45 +01002080#else
2081int
2082weston_compositor_xkb_init(struct weston_compositor *ec,
2083 struct xkb_rule_names *names)
2084{
2085 return 0;
2086}
2087
2088void
2089weston_compositor_xkb_destroy(struct weston_compositor *ec)
2090{
2091}
2092#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002093
Rui Matos65196bc2013-10-10 19:44:19 +02002094WL_EXPORT void
2095weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
2096{
2097 if (!seat->keyboard || !keymap)
2098 return;
2099
2100#ifdef ENABLE_XKBCOMMON
2101 if (!seat->compositor->use_xkbcommon)
2102 return;
2103
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002104 xkb_keymap_unref(seat->keyboard->pending_keymap);
2105 seat->keyboard->pending_keymap = xkb_keymap_ref(keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02002106
Pekka Paalanen86b53962014-11-19 13:43:32 +02002107 if (seat->keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02002108 update_keymap(seat);
2109#endif
2110}
2111
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002112WL_EXPORT int
2113weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2114{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002115 struct weston_keyboard *keyboard;
2116
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002117 if (seat->keyboard) {
2118 seat->keyboard_device_count += 1;
2119 if (seat->keyboard_device_count == 1)
2120 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002121 return 0;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002122 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002123
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002124 keyboard = weston_keyboard_create();
2125 if (keyboard == NULL) {
2126 weston_log("failed to allocate weston keyboard struct\n");
2127 return -1;
2128 }
2129
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002130#ifdef ENABLE_XKBCOMMON
2131 if (seat->compositor->use_xkbcommon) {
2132 if (keymap != NULL) {
2133 keyboard->xkb_info = weston_xkb_info_create(keymap);
2134 if (keyboard->xkb_info == NULL)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002135 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002136 } else {
2137 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002138 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002139 keyboard->xkb_info = seat->compositor->xkb_info;
2140 keyboard->xkb_info->ref_count++;
2141 }
2142
2143 keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
2144 if (keyboard->xkb_state.state == NULL) {
2145 weston_log("failed to initialise XKB state\n");
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002146 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002147 }
2148
2149 keyboard->xkb_state.leds = 0;
2150 }
2151#endif
2152
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002153 seat->keyboard = keyboard;
2154 seat->keyboard_device_count = 1;
2155 keyboard->seat = seat;
2156
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002157 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002158
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002159 return 0;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002160
2161err:
2162 if (keyboard->xkb_info)
2163 weston_xkb_info_destroy(keyboard->xkb_info);
2164 free(keyboard);
2165
2166 return -1;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002167}
2168
Jonas Ådahl91fed542013-12-03 09:14:27 +01002169static void
2170weston_keyboard_reset_state(struct weston_keyboard *keyboard)
2171{
2172 struct weston_seat *seat = keyboard->seat;
2173 struct xkb_state *state;
2174
2175#ifdef ENABLE_XKBCOMMON
2176 if (seat->compositor->use_xkbcommon) {
2177 state = xkb_state_new(keyboard->xkb_info->keymap);
2178 if (!state) {
2179 weston_log("failed to reset XKB state\n");
2180 return;
2181 }
2182 xkb_state_unref(keyboard->xkb_state.state);
2183 keyboard->xkb_state.state = state;
2184
2185 keyboard->xkb_state.leds = 0;
2186 }
2187#endif
2188
2189 seat->modifier_state = 0;
2190}
2191
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002192WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002193weston_seat_release_keyboard(struct weston_seat *seat)
2194{
2195 seat->keyboard_device_count--;
Derek Foremand621df22014-11-19 11:04:12 -06002196 assert(seat->keyboard_device_count >= 0);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002197 if (seat->keyboard_device_count == 0) {
Jonas Ådahl630bae82013-10-17 23:04:06 +02002198 weston_keyboard_set_focus(seat->keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002199 weston_keyboard_cancel_grab(seat->keyboard);
Jonas Ådahl91fed542013-12-03 09:14:27 +01002200 weston_keyboard_reset_state(seat->keyboard);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002201 seat_send_updated_caps(seat);
2202 }
2203}
2204
2205WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002206weston_seat_init_pointer(struct weston_seat *seat)
2207{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002208 struct weston_pointer *pointer;
2209
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002210 if (seat->pointer) {
2211 seat->pointer_device_count += 1;
2212 if (seat->pointer_device_count == 1)
2213 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002214 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002215 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002216
Giulio Camuffocdb4d292013-11-14 23:42:53 +01002217 pointer = weston_pointer_create(seat);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002218 if (pointer == NULL)
2219 return;
2220
2221 seat->pointer = pointer;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002222 seat->pointer_device_count = 1;
2223 pointer->seat = seat;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002224
2225 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002226}
2227
2228WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002229weston_seat_release_pointer(struct weston_seat *seat)
2230{
2231 struct weston_pointer *pointer = seat->pointer;
2232
2233 seat->pointer_device_count--;
2234 if (seat->pointer_device_count == 0) {
Jonas Ådahl630bae82013-10-17 23:04:06 +02002235 weston_pointer_set_focus(pointer, NULL,
2236 wl_fixed_from_int(0),
2237 wl_fixed_from_int(0));
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002238 weston_pointer_cancel_grab(pointer);
Jonas Ådahl630bae82013-10-17 23:04:06 +02002239
Jonas Ådahla4932742013-10-17 23:04:07 +02002240 if (pointer->sprite)
2241 pointer_unmap_sprite(pointer);
2242
Jonas Ådahl3e12e632013-12-02 22:05:05 +01002243 weston_pointer_reset_state(pointer);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002244 seat_send_updated_caps(seat);
Derek Foremanfd5ca512015-01-07 15:00:25 -06002245
2246 /* seat->pointer is intentionally not destroyed so that
2247 * a newly attached pointer on this seat will retain
2248 * the previous cursor co-ordinates.
2249 */
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002250 }
2251}
2252
2253WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002254weston_seat_init_touch(struct weston_seat *seat)
2255{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002256 struct weston_touch *touch;
2257
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002258 if (seat->touch) {
2259 seat->touch_device_count += 1;
2260 if (seat->touch_device_count == 1)
2261 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002262 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002263 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002264
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002265 touch = weston_touch_create();
2266 if (touch == NULL)
2267 return;
2268
2269 seat->touch = touch;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002270 seat->touch_device_count = 1;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002271 touch->seat = seat;
2272
2273 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002274}
2275
2276WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002277weston_seat_release_touch(struct weston_seat *seat)
2278{
2279 seat->touch_device_count--;
2280 if (seat->touch_device_count == 0) {
Derek Foreman4c93c082015-04-30 16:45:41 -05002281 weston_touch_set_focus(seat->touch, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002282 weston_touch_cancel_grab(seat->touch);
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +01002283 weston_touch_reset_state(seat->touch);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002284 seat_send_updated_caps(seat);
2285 }
2286}
2287
2288WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002289weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
2290 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002291{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002292 memset(seat, 0, sizeof *seat);
2293
Kristian Høgsberge3148752013-05-06 23:19:49 -04002294 seat->selection_data_source = NULL;
2295 wl_list_init(&seat->base_resource_list);
2296 wl_signal_init(&seat->selection_signal);
2297 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002298 wl_signal_init(&seat->destroy_signal);
Jason Ekstranda4ab5422014-04-02 19:53:45 -05002299 wl_signal_init(&seat->updated_caps_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002300
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002301 seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 4,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002302 seat, bind_seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002303
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002304 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002305 seat->modifier_state = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002306 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002307
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002308 wl_list_insert(ec->seat_list.prev, &seat->link);
2309
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002310 clipboard_create(seat);
2311
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002312 wl_signal_emit(&ec->seat_created_signal, seat);
2313}
2314
2315WL_EXPORT void
2316weston_seat_release(struct weston_seat *seat)
2317{
2318 wl_list_remove(&seat->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002319
Jonas Ådahl1afb2382014-01-03 19:46:51 +01002320 if (seat->saved_kbd_focus)
2321 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2322
Kristian Høgsberge3148752013-05-06 23:19:49 -04002323 if (seat->pointer)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002324 weston_pointer_destroy(seat->pointer);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002325 if (seat->keyboard)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002326 weston_keyboard_destroy(seat->keyboard);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002327 if (seat->touch)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002328 weston_touch_destroy(seat->touch);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002329
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002330 free (seat->seat_name);
2331
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002332 wl_global_destroy(seat->global);
Kristian Høgsbergaaadc772013-07-08 16:20:31 -04002333
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002334 wl_signal_emit(&seat->destroy_signal, seat);
2335}