blob: c8c798ef6bbed41934b59e39cfe5c94c9c2edec5 [file] [log] [blame]
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001/*
2 * Copyright © 2013 Intel Corporation
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
Daniel Stone8e7a8bd2013-08-15 01:10:24 +010023#include "config.h"
24
Kristian Høgsberg2158a882013-04-18 15:07:39 -040025#include <stdlib.h>
26#include <stdint.h>
27#include <string.h>
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040028#include <sys/mman.h>
29#include <assert.h>
30#include <unistd.h>
Matt Roper01a92732013-06-24 16:52:44 +010031#include <fcntl.h>
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +020032#include <limits.h>
Kristian Høgsberg2158a882013-04-18 15:07:39 -040033
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040034#include "../shared/os-compatibility.h"
Kristian Høgsberg2158a882013-04-18 15:07:39 -040035#include "compositor.h"
36
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040037static void
38empty_region(pixman_region32_t *region)
39{
40 pixman_region32_fini(region);
41 pixman_region32_init(region);
42}
43
44static void unbind_resource(struct wl_resource *resource)
45{
Jason Ekstrand44a38632013-06-14 10:08:00 -050046 wl_list_remove(wl_resource_get_link(resource));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040047}
48
Jonas Ådahl3042ffe2013-10-17 23:04:08 +020049WL_EXPORT void
Kristian Høgsberga71e8b22013-05-06 21:51:21 -040050weston_seat_repick(struct weston_seat *seat)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040051{
Kristian Høgsbergda751b82013-07-04 00:58:07 -040052 const struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040053
Kristian Høgsbergda751b82013-07-04 00:58:07 -040054 if (pointer == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040055 return;
56
Kristian Høgsbergda751b82013-07-04 00:58:07 -040057 pointer->grab->interface->focus(seat->pointer->grab);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040058}
59
60static void
61weston_compositor_idle_inhibit(struct weston_compositor *compositor)
62{
63 weston_compositor_wake(compositor);
64 compositor->idle_inhibit++;
65}
66
67static void
68weston_compositor_idle_release(struct weston_compositor *compositor)
69{
70 compositor->idle_inhibit--;
71 weston_compositor_wake(compositor);
72}
73
Kristian Høgsberg2158a882013-04-18 15:07:39 -040074static void
Giulio Camuffo576fe2a2013-11-20 18:00:24 +010075pointer_focus_view_destroyed(struct wl_listener *listener, void *data)
76{
77 struct weston_pointer *pointer =
78 container_of(listener, struct weston_pointer,
79 focus_view_listener);
80
81 weston_pointer_set_focus(pointer, NULL, 0, 0);
82}
83
84static void
85pointer_focus_resource_destroyed(struct wl_listener *listener, void *data)
86{
87 struct weston_pointer *pointer =
88 container_of(listener, struct weston_pointer,
89 focus_resource_listener);
90
91 weston_pointer_set_focus(pointer, NULL, 0, 0);
92}
93
94static void
95keyboard_focus_resource_destroyed(struct wl_listener *listener, void *data)
96{
97 struct weston_keyboard *keyboard =
98 container_of(listener, struct weston_keyboard,
99 focus_resource_listener);
100
101 weston_keyboard_set_focus(keyboard, NULL);
102}
103
104static void
105touch_focus_view_destroyed(struct wl_listener *listener, void *data)
106{
107 struct weston_touch *touch =
108 container_of(listener, struct weston_touch,
109 focus_view_listener);
110
111 weston_touch_set_focus(touch->seat, NULL);
112}
113
114static void
115touch_focus_resource_destroyed(struct wl_listener *listener, void *data)
116{
117 struct weston_touch *touch =
118 container_of(listener, struct weston_touch,
119 focus_resource_listener);
120
121 weston_touch_set_focus(touch->seat, NULL);
122}
123
124static void
Neil Roberts96d790e2013-09-19 17:32:00 +0100125move_resources(struct wl_list *destination, struct wl_list *source)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400126{
Neil Roberts96d790e2013-09-19 17:32:00 +0100127 wl_list_insert_list(destination, source);
128 wl_list_init(source);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400129}
130
131static void
Neil Roberts96d790e2013-09-19 17:32:00 +0100132move_resources_for_client(struct wl_list *destination,
133 struct wl_list *source,
134 struct wl_client *client)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400135{
Neil Roberts96d790e2013-09-19 17:32:00 +0100136 struct wl_resource *resource, *tmp;
137 wl_resource_for_each_safe(resource, tmp, source) {
138 if (wl_resource_get_client(resource) == client) {
139 wl_list_remove(wl_resource_get_link(resource));
140 wl_list_insert(destination,
141 wl_resource_get_link(resource));
142 }
143 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400144}
145
146static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700147default_grab_pointer_focus(struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400148{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400149 struct weston_pointer *pointer = grab->pointer;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500150 struct weston_view *view;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400151 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400152
153 if (pointer->button_count > 0)
154 return;
155
Jason Ekstranda7af7042013-10-12 22:38:11 -0500156 view = weston_compositor_pick_view(pointer->seat->compositor,
157 pointer->x, pointer->y,
158 &sx, &sy);
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400159
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800160 if (pointer->focus != view || pointer->sx != sx || pointer->sy != sy)
Jason Ekstranda7af7042013-10-12 22:38:11 -0500161 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400162}
163
164static void
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100165default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
166 wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400167{
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400168 struct weston_pointer *pointer = grab->pointer;
Neil Roberts96d790e2013-09-19 17:32:00 +0100169 struct wl_list *resource_list;
170 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400171
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800172 if (pointer->focus)
173 weston_view_from_global_fixed(pointer->focus, x, y,
174 &pointer->sx, &pointer->sy);
175
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100176 weston_pointer_move(pointer, x, y);
177
Neil Roberts96d790e2013-09-19 17:32:00 +0100178 resource_list = &pointer->focus_resource_list;
179 wl_resource_for_each(resource, resource_list) {
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800180 wl_pointer_send_motion(resource, time,
181 pointer->sx, pointer->sy);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400182 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400183}
184
185static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700186default_grab_pointer_button(struct weston_pointer_grab *grab,
187 uint32_t time, uint32_t button, uint32_t state_w)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400188{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400189 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400190 struct weston_compositor *compositor = pointer->seat->compositor;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500191 struct weston_view *view;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400192 struct wl_resource *resource;
193 uint32_t serial;
194 enum wl_pointer_button_state state = state_w;
Rob Bradford880ebc72013-07-22 17:31:38 +0100195 struct wl_display *display = compositor->wl_display;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400196 wl_fixed_t sx, sy;
Neil Roberts96d790e2013-09-19 17:32:00 +0100197 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400198
Neil Roberts96d790e2013-09-19 17:32:00 +0100199 resource_list = &pointer->focus_resource_list;
200 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400201 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100202 wl_resource_for_each(resource, resource_list)
203 wl_pointer_send_button(resource,
204 serial,
205 time,
206 button,
207 state_w);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400208 }
209
210 if (pointer->button_count == 0 &&
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400211 state == WL_POINTER_BUTTON_STATE_RELEASED) {
Jason Ekstranda7af7042013-10-12 22:38:11 -0500212 view = weston_compositor_pick_view(compositor,
213 pointer->x, pointer->y,
214 &sx, &sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400215
Jason Ekstranda7af7042013-10-12 22:38:11 -0500216 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400217 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400218}
219
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200220static void
221default_grab_pointer_cancel(struct weston_pointer_grab *grab)
222{
223}
224
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400225static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400226 default_pointer_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700227 default_grab_pointer_focus,
228 default_grab_pointer_motion,
229 default_grab_pointer_button,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200230 default_grab_pointer_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400231};
232
Kristian Høgsberge329f362013-05-06 22:19:57 -0400233static void
234default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
235 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400236{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400237 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100238 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400239 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100240 struct wl_resource *resource;
241 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400242
Neil Roberts96d790e2013-09-19 17:32:00 +0100243 resource_list = &touch->focus_resource_list;
244
245 if (!wl_list_empty(resource_list) && touch->focus) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400246 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100247 wl_resource_for_each(resource, resource_list)
248 wl_touch_send_down(resource, serial, time,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500249 touch->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100250 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400251 }
252}
253
Kristian Høgsberge329f362013-05-06 22:19:57 -0400254static void
255default_grab_touch_up(struct weston_touch_grab *grab,
256 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400257{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400258 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100259 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400260 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100261 struct wl_resource *resource;
262 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400263
Neil Roberts96d790e2013-09-19 17:32:00 +0100264 resource_list = &touch->focus_resource_list;
265
266 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400267 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100268 wl_resource_for_each(resource, resource_list)
269 wl_touch_send_up(resource, serial, time, touch_id);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400270 }
271}
272
Kristian Høgsberge329f362013-05-06 22:19:57 -0400273static void
274default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
275 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400276{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400277 struct weston_touch *touch = grab->touch;
Neil Roberts96d790e2013-09-19 17:32:00 +0100278 struct wl_resource *resource;
279 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400280
Neil Roberts96d790e2013-09-19 17:32:00 +0100281 resource_list = &touch->focus_resource_list;
282
283 wl_resource_for_each(resource, resource_list) {
284 wl_touch_send_motion(resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400285 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400286 }
287}
288
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200289static void
290default_grab_touch_cancel(struct weston_touch_grab *grab)
291{
292}
293
Kristian Høgsberge329f362013-05-06 22:19:57 -0400294static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400295 default_grab_touch_down,
296 default_grab_touch_up,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200297 default_grab_touch_motion,
298 default_grab_touch_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400299};
300
301static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700302default_grab_keyboard_key(struct weston_keyboard_grab *grab,
303 uint32_t time, uint32_t key, uint32_t state)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400304{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400305 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400306 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100307 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400308 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100309 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400310
Neil Roberts96d790e2013-09-19 17:32:00 +0100311 resource_list = &keyboard->focus_resource_list;
312 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400313 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100314 wl_resource_for_each(resource, resource_list)
315 wl_keyboard_send_key(resource,
316 serial,
317 time,
318 key,
319 state);
320 }
321}
322
323static void
324send_modifiers_to_resource(struct weston_keyboard *keyboard,
325 struct wl_resource *resource,
326 uint32_t serial)
327{
328 wl_keyboard_send_modifiers(resource,
329 serial,
330 keyboard->modifiers.mods_depressed,
331 keyboard->modifiers.mods_latched,
332 keyboard->modifiers.mods_locked,
333 keyboard->modifiers.group);
334}
335
336static void
337send_modifiers_to_client_in_list(struct wl_client *client,
338 struct wl_list *list,
339 uint32_t serial,
340 struct weston_keyboard *keyboard)
341{
342 struct wl_resource *resource;
343
344 wl_resource_for_each(resource, list) {
345 if (wl_resource_get_client(resource) == client)
346 send_modifiers_to_resource(keyboard,
347 resource,
348 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400349 }
350}
351
352static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400353find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400354{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400355 if (!surface)
356 return NULL;
357
Jason Ekstrand44a38632013-06-14 10:08:00 -0500358 if (!surface->resource)
359 return NULL;
Stefan Schmidtfda26522013-09-17 10:54:09 +0100360
Jason Ekstrand44a38632013-06-14 10:08:00 -0500361 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400362}
363
Jason Ekstranda7af7042013-10-12 22:38:11 -0500364static struct wl_resource *
365find_resource_for_view(struct wl_list *list, struct weston_view *view)
366{
367 if (!view)
368 return NULL;
369
370 return find_resource_for_surface(list, view->surface);
371}
372
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400373static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700374default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
375 uint32_t serial, uint32_t mods_depressed,
376 uint32_t mods_latched,
377 uint32_t mods_locked, uint32_t group)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400378{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400379 struct weston_keyboard *keyboard = grab->keyboard;
Neil Roberts96d790e2013-09-19 17:32:00 +0100380 struct weston_pointer *pointer = grab->keyboard->seat->pointer;
381 struct wl_resource *resource;
382 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400383
Neil Roberts96d790e2013-09-19 17:32:00 +0100384 resource_list = &keyboard->focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400385
Neil Roberts96d790e2013-09-19 17:32:00 +0100386 wl_resource_for_each(resource, resource_list) {
387 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
388 mods_latched, mods_locked, group);
389 }
Jason Ekstrand42133d42013-11-14 20:06:16 -0600390 if (pointer && pointer->focus && pointer->focus->surface->resource &&
391 pointer->focus->surface != keyboard->focus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100392 struct wl_client *pointer_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500393 wl_resource_get_client(pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100394 send_modifiers_to_client_in_list(pointer_client,
395 &keyboard->resource_list,
396 serial,
397 keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400398 }
399}
400
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200401static void
402default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
403{
404}
405
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400406static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400407 default_keyboard_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700408 default_grab_keyboard_key,
409 default_grab_keyboard_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200410 default_grab_keyboard_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400411};
412
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400413static void
414pointer_unmap_sprite(struct weston_pointer *pointer)
415{
Jason Ekstranda7af7042013-10-12 22:38:11 -0500416 if (weston_surface_is_mapped(pointer->sprite->surface))
417 weston_surface_unmap(pointer->sprite->surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400418
419 wl_list_remove(&pointer->sprite_destroy_listener.link);
Jason Ekstranda7af7042013-10-12 22:38:11 -0500420 pointer->sprite->surface->configure = NULL;
421 pointer->sprite->surface->configure_private = NULL;
422 weston_view_destroy(pointer->sprite);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400423 pointer->sprite = NULL;
424}
425
426static void
427pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
428{
429 struct weston_pointer *pointer =
430 container_of(listener, struct weston_pointer,
431 sprite_destroy_listener);
432
433 pointer->sprite = NULL;
434}
435
Jonas Ådahl3e12e632013-12-02 22:05:05 +0100436static void
437weston_pointer_reset_state(struct weston_pointer *pointer)
438{
439 pointer->button_count = 0;
440}
441
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200442static void
443weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
444
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400445WL_EXPORT struct weston_pointer *
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100446weston_pointer_create(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400447{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400448 struct weston_pointer *pointer;
449
Peter Huttererf3d62272013-08-08 11:57:05 +1000450 pointer = zalloc(sizeof *pointer);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400451 if (pointer == NULL)
452 return NULL;
453
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400454 wl_list_init(&pointer->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100455 wl_list_init(&pointer->focus_resource_list);
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100456 weston_pointer_set_default_grab(pointer,
457 seat->compositor->default_pointer_grab);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100458 wl_list_init(&pointer->focus_resource_listener.link);
459 pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400460 pointer->default_grab.pointer = pointer;
461 pointer->grab = &pointer->default_grab;
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100462 wl_signal_init(&pointer->motion_signal);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100463 wl_signal_init(&pointer->focus_signal);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100464 wl_list_init(&pointer->focus_view_listener.link);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400465
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400466 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
467
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400468 /* FIXME: Pick better co-ords. */
469 pointer->x = wl_fixed_from_int(100);
470 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400471
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200472 pointer->output_destroy_listener.notify =
473 weston_pointer_handle_output_destroy;
474 wl_signal_add(&seat->compositor->output_destroyed_signal,
475 &pointer->output_destroy_listener);
476
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400477 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400478}
479
480WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400481weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400482{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400483 if (pointer->sprite)
484 pointer_unmap_sprite(pointer);
485
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400486 /* XXX: What about pointer->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100487
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100488 wl_list_remove(&pointer->focus_resource_listener.link);
489 wl_list_remove(&pointer->focus_view_listener.link);
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200490 wl_list_remove(&pointer->output_destroy_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400491 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400492}
493
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100494void
495weston_pointer_set_default_grab(struct weston_pointer *pointer,
496 const struct weston_pointer_grab_interface *interface)
497{
498 if (interface)
499 pointer->default_grab.interface = interface;
500 else
501 pointer->default_grab.interface =
502 &default_pointer_grab_interface;
503}
504
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400505WL_EXPORT struct weston_keyboard *
506weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400507{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400508 struct weston_keyboard *keyboard;
509
Peter Huttererf3d62272013-08-08 11:57:05 +1000510 keyboard = zalloc(sizeof *keyboard);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400511 if (keyboard == NULL)
Neil Roberts96d790e2013-09-19 17:32:00 +0100512 return NULL;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400513
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400514 wl_list_init(&keyboard->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100515 wl_list_init(&keyboard->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100516 wl_list_init(&keyboard->focus_resource_listener.link);
517 keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400518 wl_array_init(&keyboard->keys);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400519 keyboard->default_grab.interface = &default_keyboard_grab_interface;
520 keyboard->default_grab.keyboard = keyboard;
521 keyboard->grab = &keyboard->default_grab;
522 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400523
524 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400525}
526
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100527static void
528weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
529
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400530WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400531weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400532{
533 /* XXX: What about keyboard->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100534
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100535#ifdef ENABLE_XKBCOMMON
536 if (keyboard->seat->compositor->use_xkbcommon) {
537 if (keyboard->xkb_state.state != NULL)
538 xkb_state_unref(keyboard->xkb_state.state);
539 if (keyboard->xkb_info)
540 weston_xkb_info_destroy(keyboard->xkb_info);
541 if (keyboard->pending_keymap)
542 xkb_keymap_unref(keyboard->pending_keymap);
543 }
544#endif
545
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400546 wl_array_release(&keyboard->keys);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100547 wl_list_remove(&keyboard->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400548 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400549}
550
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +0100551static void
552weston_touch_reset_state(struct weston_touch *touch)
553{
554 touch->num_tp = 0;
555}
556
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400557WL_EXPORT struct weston_touch *
558weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400559{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400560 struct weston_touch *touch;
561
Peter Huttererf3d62272013-08-08 11:57:05 +1000562 touch = zalloc(sizeof *touch);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400563 if (touch == NULL)
564 return NULL;
565
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400566 wl_list_init(&touch->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100567 wl_list_init(&touch->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100568 wl_list_init(&touch->focus_view_listener.link);
569 touch->focus_view_listener.notify = touch_focus_view_destroyed;
570 wl_list_init(&touch->focus_resource_listener.link);
571 touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400572 touch->default_grab.interface = &default_touch_grab_interface;
573 touch->default_grab.touch = touch;
574 touch->grab = &touch->default_grab;
575 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400576
577 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400578}
579
580WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400581weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400582{
583 /* XXX: What about touch->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100584
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100585 wl_list_remove(&touch->focus_view_listener.link);
586 wl_list_remove(&touch->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400587 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400588}
589
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400590static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400591seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400592{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400593 enum wl_seat_capability caps = 0;
Rob Bradford6e737f52013-09-06 17:48:19 +0100594 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400595
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200596 if (seat->pointer_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400597 caps |= WL_SEAT_CAPABILITY_POINTER;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200598 if (seat->keyboard_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400599 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200600 if (seat->touch_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400601 caps |= WL_SEAT_CAPABILITY_TOUCH;
602
Rob Bradford6e737f52013-09-06 17:48:19 +0100603 wl_resource_for_each(resource, &seat->base_resource_list) {
604 wl_seat_send_capabilities(resource, caps);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500605 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400606}
607
608WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400609weston_pointer_set_focus(struct weston_pointer *pointer,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500610 struct weston_view *view,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400611 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400612{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400613 struct weston_keyboard *kbd = pointer->seat->keyboard;
Neil Roberts96d790e2013-09-19 17:32:00 +0100614 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100615 struct wl_display *display = pointer->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400616 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100617 struct wl_list *focus_resource_list;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800618 int refocus = 0;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500619
620 if ((!pointer->focus && view) ||
621 (pointer->focus && !view) ||
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800622 (pointer->focus && pointer->focus->surface != view->surface) ||
623 pointer->sx != sx || pointer->sy != sy)
624 refocus = 1;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400625
Neil Roberts96d790e2013-09-19 17:32:00 +0100626 focus_resource_list = &pointer->focus_resource_list;
627
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800628 if (!wl_list_empty(focus_resource_list) && refocus) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400629 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100630 wl_resource_for_each(resource, focus_resource_list) {
631 wl_pointer_send_leave(resource, serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500632 pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100633 }
634
635 move_resources(&pointer->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400636 }
637
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800638 if (find_resource_for_view(&pointer->resource_list, view) && refocus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100639 struct wl_client *surface_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500640 wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100641
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400642 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100643
Jason Ekstranda7af7042013-10-12 22:38:11 -0500644 if (kbd && kbd->focus != view->surface)
Kristian Høgsbergcb406f12013-10-09 10:54:03 -0700645 send_modifiers_to_client_in_list(surface_client,
646 &kbd->resource_list,
647 serial,
648 kbd);
649
Neil Roberts96d790e2013-09-19 17:32:00 +0100650 move_resources_for_client(focus_resource_list,
651 &pointer->resource_list,
652 surface_client);
653
654 wl_resource_for_each(resource, focus_resource_list) {
655 wl_pointer_send_enter(resource,
656 serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500657 view->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100658 sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400659 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100660
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400661 pointer->focus_serial = serial;
662 }
663
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100664 wl_list_remove(&pointer->focus_view_listener.link);
665 wl_list_init(&pointer->focus_view_listener.link);
666 wl_list_remove(&pointer->focus_resource_listener.link);
667 wl_list_init(&pointer->focus_resource_listener.link);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100668 if (view)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100669 wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100670 if (view && view->surface->resource)
671 wl_resource_add_destroy_listener(view->surface->resource,
672 &pointer->focus_resource_listener);
673
674 pointer->focus = view;
675 pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800676 pointer->sx = sx;
677 pointer->sy = sy;
678
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400679 wl_signal_emit(&pointer->focus_signal, pointer);
680}
681
Neil Roberts96d790e2013-09-19 17:32:00 +0100682static void
683send_enter_to_resource_list(struct wl_list *list,
684 struct weston_keyboard *keyboard,
685 struct weston_surface *surface,
686 uint32_t serial)
687{
688 struct wl_resource *resource;
689
690 wl_resource_for_each(resource, list) {
691 send_modifiers_to_resource(keyboard, resource, serial);
692 wl_keyboard_send_enter(resource, serial,
693 surface->resource,
694 &keyboard->keys);
695 }
696}
697
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400698WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400699weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400700 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400701{
702 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100703 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400704 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100705 struct wl_list *focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400706
Neil Roberts96d790e2013-09-19 17:32:00 +0100707 focus_resource_list = &keyboard->focus_resource_list;
708
709 if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400710 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100711 wl_resource_for_each(resource, focus_resource_list) {
712 wl_keyboard_send_leave(resource, serial,
713 keyboard->focus->resource);
714 }
715 move_resources(&keyboard->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400716 }
717
Neil Roberts96d790e2013-09-19 17:32:00 +0100718 if (find_resource_for_surface(&keyboard->resource_list, surface) &&
719 keyboard->focus != surface) {
720 struct wl_client *surface_client =
721 wl_resource_get_client(surface->resource);
722
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400723 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100724
725 move_resources_for_client(focus_resource_list,
726 &keyboard->resource_list,
727 surface_client);
728 send_enter_to_resource_list(focus_resource_list,
729 keyboard,
730 surface,
731 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400732 keyboard->focus_serial = serial;
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100733 }
734
735 wl_list_remove(&keyboard->focus_resource_listener.link);
736 wl_list_init(&keyboard->focus_resource_listener.link);
737 if (surface && surface->resource)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100738 wl_resource_add_destroy_listener(surface->resource,
739 &keyboard->focus_resource_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400740
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400741 keyboard->focus = surface;
742 wl_signal_emit(&keyboard->focus_signal, keyboard);
743}
744
745WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400746weston_keyboard_start_grab(struct weston_keyboard *keyboard,
747 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400748{
749 keyboard->grab = grab;
750 grab->keyboard = keyboard;
751
752 /* XXX focus? */
753}
754
755WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400756weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400757{
758 keyboard->grab = &keyboard->default_grab;
759}
760
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200761static void
762weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
763{
764 keyboard->grab->interface->cancel(keyboard->grab);
765}
766
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400767WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400768weston_pointer_start_grab(struct weston_pointer *pointer,
769 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400770{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400771 pointer->grab = grab;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400772 grab->pointer = pointer;
Kristian Høgsbergda751b82013-07-04 00:58:07 -0400773 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400774}
775
776WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400777weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400778{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400779 pointer->grab = &pointer->default_grab;
Kristian Høgsbergda751b82013-07-04 00:58:07 -0400780 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400781}
782
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200783static void
784weston_pointer_cancel_grab(struct weston_pointer *pointer)
785{
786 pointer->grab->interface->cancel(pointer->grab);
787}
788
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400789WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400790weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400791{
792 touch->grab = grab;
793 grab->touch = touch;
794}
795
796WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400797weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400798{
799 touch->grab = &touch->default_grab;
800}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400801
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200802static void
803weston_touch_cancel_grab(struct weston_touch *touch)
804{
805 touch->grab->interface->cancel(touch->grab);
806}
807
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200808static void
809weston_pointer_clamp_for_output(struct weston_pointer *pointer,
810 struct weston_output *output,
811 wl_fixed_t *fx, wl_fixed_t *fy)
812{
813 int x, y;
814
815 x = wl_fixed_to_int(*fx);
816 y = wl_fixed_to_int(*fy);
817
818 if (x < output->x)
819 *fx = wl_fixed_from_int(output->x);
820 else if (x >= output->x + output->width)
821 *fx = wl_fixed_from_int(output->x +
822 output->width - 1);
823 if (y < output->y)
824 *fy = wl_fixed_from_int(output->y);
825 else if (y >= output->y + output->height)
826 *fy = wl_fixed_from_int(output->y +
827 output->height - 1);
828}
829
Rob Bradford806d8c02013-06-25 18:56:41 +0100830WL_EXPORT void
831weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400832{
Rob Bradford806d8c02013-06-25 18:56:41 +0100833 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400834 struct weston_output *output, *prev = NULL;
835 int x, y, old_x, old_y, valid = 0;
836
837 x = wl_fixed_to_int(*fx);
838 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +0100839 old_x = wl_fixed_to_int(pointer->x);
840 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400841
842 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +0100843 if (pointer->seat->output && pointer->seat->output != output)
844 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400845 if (pixman_region32_contains_point(&output->region,
846 x, y, NULL))
847 valid = 1;
848 if (pixman_region32_contains_point(&output->region,
849 old_x, old_y, NULL))
850 prev = output;
851 }
852
Rob Bradford66bd9f52013-06-25 18:56:42 +0100853 if (!prev)
854 prev = pointer->seat->output;
855
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200856 if (prev && !valid)
857 weston_pointer_clamp_for_output(pointer, prev, fx, fy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400858}
859
860/* Takes absolute values */
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100861WL_EXPORT void
862weston_pointer_move(struct weston_pointer *pointer, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400863{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400864 int32_t ix, iy;
865
Rob Bradford806d8c02013-06-25 18:56:41 +0100866 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400867
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400868 pointer->x = x;
869 pointer->y = y;
870
871 ix = wl_fixed_to_int(x);
872 iy = wl_fixed_to_int(y);
873
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400874 if (pointer->sprite) {
Jason Ekstranda7af7042013-10-12 22:38:11 -0500875 weston_view_set_position(pointer->sprite,
876 ix - pointer->hotspot_x,
877 iy - pointer->hotspot_y);
878 weston_view_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400879 }
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100880
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100881 pointer->grab->interface->focus(pointer->grab);
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100882 wl_signal_emit(&pointer->motion_signal, pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400883}
884
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200885/** Verify if the pointer is in a valid position and move it if it isn't.
886 */
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200887static void
888weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200889{
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200890 struct weston_pointer *pointer;
891 struct weston_compositor *ec;
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200892 struct weston_output *output, *closest = NULL;
893 int x, y, distance, min = INT_MAX;
894 wl_fixed_t fx, fy;
895
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200896 pointer = container_of(listener, struct weston_pointer,
897 output_destroy_listener);
898 ec = pointer->seat->compositor;
899
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +0200900 x = wl_fixed_to_int(pointer->x);
901 y = wl_fixed_to_int(pointer->y);
902
903 wl_list_for_each(output, &ec->output_list, link) {
904 if (pixman_region32_contains_point(&output->region,
905 x, y, NULL))
906 return;
907
908 /* Aproximante the distance from the pointer to the center of
909 * the output. */
910 distance = abs(output->x + output->width / 2 - x) +
911 abs(output->y + output->height / 2 - y);
912 if (distance < min) {
913 min = distance;
914 closest = output;
915 }
916 }
917
918 /* Nothing to do if there's no output left. */
919 if (!closest)
920 return;
921
922 fx = pointer->x;
923 fy = pointer->y;
924
925 weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
926 weston_pointer_move(pointer, fx, fy);
927}
928
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400929WL_EXPORT void
930notify_motion(struct weston_seat *seat,
931 uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
932{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400933 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400934 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400935
936 weston_compositor_wake(ec);
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100937 pointer->grab->interface->motion(pointer->grab, time, pointer->x + dx, pointer->y + dy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400938}
939
Daniel Stone96d47c02013-11-19 11:37:12 +0100940static void
941run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
942{
943 struct weston_compositor *compositor = seat->compositor;
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100944 struct weston_keyboard *keyboard = seat->keyboard;
Daniel Stone96d47c02013-11-19 11:37:12 +0100945 uint32_t diff;
946 unsigned int i;
947 struct {
948 uint32_t xkb;
949 enum weston_keyboard_modifier weston;
950 } mods[] = {
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100951 { keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
952 { keyboard->xkb_info->alt_mod, MODIFIER_ALT },
953 { keyboard->xkb_info->super_mod, MODIFIER_SUPER },
954 { keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
Daniel Stone96d47c02013-11-19 11:37:12 +0100955 };
956
957 diff = new & ~old;
958 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
959 if (diff & (1 << mods[i].xkb))
960 weston_compositor_run_modifier_binding(compositor,
961 seat,
962 mods[i].weston,
963 WL_KEYBOARD_KEY_STATE_PRESSED);
964 }
965
966 diff = old & ~new;
967 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
968 if (diff & (1 << mods[i].xkb))
969 weston_compositor_run_modifier_binding(compositor,
970 seat,
971 mods[i].weston,
972 WL_KEYBOARD_KEY_STATE_RELEASED);
973 }
974}
975
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400976WL_EXPORT void
977notify_motion_absolute(struct weston_seat *seat,
978 uint32_t time, wl_fixed_t x, wl_fixed_t y)
979{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400980 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400981 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400982
983 weston_compositor_wake(ec);
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100984 pointer->grab->interface->motion(pointer->grab, time, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400985}
986
987WL_EXPORT void
988weston_surface_activate(struct weston_surface *surface,
989 struct weston_seat *seat)
990{
991 struct weston_compositor *compositor = seat->compositor;
992
Kristian Høgsberge3148752013-05-06 23:19:49 -0400993 if (seat->keyboard) {
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400994 weston_keyboard_set_focus(seat->keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -0400995 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400996 }
997
998 wl_signal_emit(&compositor->activate_signal, surface);
999}
1000
1001WL_EXPORT void
1002notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1003 enum wl_pointer_button_state state)
1004{
1005 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001006 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001007
1008 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001009 weston_compositor_idle_inhibit(compositor);
1010 if (pointer->button_count == 0) {
1011 pointer->grab_button = button;
1012 pointer->grab_time = time;
1013 pointer->grab_x = pointer->x;
1014 pointer->grab_y = pointer->y;
1015 }
1016 pointer->button_count++;
1017 } else {
1018 weston_compositor_idle_release(compositor);
1019 pointer->button_count--;
1020 }
1021
1022 weston_compositor_run_button_binding(compositor, seat, time, button,
1023 state);
1024
1025 pointer->grab->interface->button(pointer->grab, time, button, state);
1026
1027 if (pointer->button_count == 1)
1028 pointer->grab_serial =
1029 wl_display_get_serial(compositor->wl_display);
1030}
1031
1032WL_EXPORT void
1033notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
1034 wl_fixed_t value)
1035{
1036 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001037 struct weston_pointer *pointer = seat->pointer;
Neil Roberts96d790e2013-09-19 17:32:00 +01001038 struct wl_resource *resource;
1039 struct wl_list *resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001040
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001041 weston_compositor_wake(compositor);
1042
1043 if (!value)
1044 return;
1045
1046 if (weston_compositor_run_axis_binding(compositor, seat,
1047 time, axis, value))
1048 return;
1049
Neil Roberts96d790e2013-09-19 17:32:00 +01001050 resource_list = &pointer->focus_resource_list;
1051 wl_resource_for_each(resource, resource_list)
1052 wl_pointer_send_axis(resource, time, axis,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001053 value);
1054}
1055
Rob Bradford382ff462013-06-24 16:52:45 +01001056#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001057WL_EXPORT void
1058notify_modifiers(struct weston_seat *seat, uint32_t serial)
1059{
Kristian Høgsberge3148752013-05-06 23:19:49 -04001060 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001061 struct weston_keyboard_grab *grab = keyboard->grab;
1062 uint32_t mods_depressed, mods_latched, mods_locked, group;
1063 uint32_t mods_lookup;
1064 enum weston_led leds = 0;
1065 int changed = 0;
1066
1067 /* Serialize and update our internal state, checking to see if it's
1068 * different to the previous state. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001069 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001070 XKB_STATE_DEPRESSED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001071 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001072 XKB_STATE_LATCHED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001073 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001074 XKB_STATE_LOCKED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001075 group = xkb_state_serialize_group(keyboard->xkb_state.state,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001076 XKB_STATE_EFFECTIVE);
1077
Kristian Høgsberge3148752013-05-06 23:19:49 -04001078 if (mods_depressed != seat->keyboard->modifiers.mods_depressed ||
1079 mods_latched != seat->keyboard->modifiers.mods_latched ||
1080 mods_locked != seat->keyboard->modifiers.mods_locked ||
1081 group != seat->keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001082 changed = 1;
1083
Daniel Stone96d47c02013-11-19 11:37:12 +01001084 run_modifier_bindings(seat, seat->keyboard->modifiers.mods_depressed,
1085 mods_depressed);
1086
Kristian Høgsberge3148752013-05-06 23:19:49 -04001087 seat->keyboard->modifiers.mods_depressed = mods_depressed;
1088 seat->keyboard->modifiers.mods_latched = mods_latched;
1089 seat->keyboard->modifiers.mods_locked = mods_locked;
1090 seat->keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001091
1092 /* And update the modifier_state for bindings. */
1093 mods_lookup = mods_depressed | mods_latched;
1094 seat->modifier_state = 0;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001095 if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001096 seat->modifier_state |= MODIFIER_CTRL;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001097 if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001098 seat->modifier_state |= MODIFIER_ALT;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001099 if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001100 seat->modifier_state |= MODIFIER_SUPER;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001101 if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001102 seat->modifier_state |= MODIFIER_SHIFT;
1103
1104 /* Finally, notify the compositor that LEDs have changed. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001105 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1106 keyboard->xkb_info->num_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001107 leds |= LED_NUM_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001108 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1109 keyboard->xkb_info->caps_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001110 leds |= LED_CAPS_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001111 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1112 keyboard->xkb_info->scroll_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001113 leds |= LED_SCROLL_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001114 if (leds != keyboard->xkb_state.leds && seat->led_update)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001115 seat->led_update(seat, leds);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001116 keyboard->xkb_state.leds = leds;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001117
1118 if (changed) {
1119 grab->interface->modifiers(grab,
1120 serial,
1121 keyboard->modifiers.mods_depressed,
1122 keyboard->modifiers.mods_latched,
1123 keyboard->modifiers.mods_locked,
1124 keyboard->modifiers.group);
1125 }
1126}
1127
1128static void
1129update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1130 enum wl_keyboard_key_state state)
1131{
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001132 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001133 enum xkb_key_direction direction;
1134
Matt Roper01a92732013-06-24 16:52:44 +01001135 /* Keyboard modifiers don't exist in raw keyboard mode */
1136 if (!seat->compositor->use_xkbcommon)
1137 return;
1138
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001139 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1140 direction = XKB_KEY_DOWN;
1141 else
1142 direction = XKB_KEY_UP;
1143
1144 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1145 * broken keycode system, which starts at 8. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001146 xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001147
1148 notify_modifiers(seat, serial);
1149}
Rui Matos65196bc2013-10-10 19:44:19 +02001150
1151static void
1152send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
1153{
1154 wl_keyboard_send_keymap(resource,
1155 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1156 xkb_info->keymap_fd,
1157 xkb_info->keymap_size);
1158}
1159
1160static void
1161send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
1162{
1163 wl_keyboard_send_modifiers(resource, serial,
1164 keyboard->modifiers.mods_depressed,
1165 keyboard->modifiers.mods_latched,
1166 keyboard->modifiers.mods_locked,
1167 keyboard->modifiers.group);
1168}
1169
1170static struct weston_xkb_info *
1171weston_xkb_info_create(struct xkb_keymap *keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001172
1173static void
1174update_keymap(struct weston_seat *seat)
1175{
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001176 struct weston_keyboard *keyboard = seat->keyboard;
Rui Matos65196bc2013-10-10 19:44:19 +02001177 struct wl_resource *resource;
1178 struct weston_xkb_info *xkb_info;
1179 struct xkb_state *state;
1180 xkb_mod_mask_t latched_mods;
1181 xkb_mod_mask_t locked_mods;
1182
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001183 xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001184
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001185 xkb_keymap_unref(keyboard->pending_keymap);
1186 keyboard->pending_keymap = NULL;
Rui Matos65196bc2013-10-10 19:44:19 +02001187
1188 if (!xkb_info) {
1189 weston_log("failed to create XKB info\n");
1190 return;
1191 }
1192
1193 state = xkb_state_new(xkb_info->keymap);
1194 if (!state) {
1195 weston_log("failed to initialise XKB state\n");
1196 weston_xkb_info_destroy(xkb_info);
1197 return;
1198 }
1199
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001200 latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1201 XKB_STATE_MODS_LATCHED);
1202 locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1203 XKB_STATE_MODS_LOCKED);
Rui Matos65196bc2013-10-10 19:44:19 +02001204 xkb_state_update_mask(state,
1205 0, /* depressed */
1206 latched_mods,
1207 locked_mods,
1208 0, 0, 0);
1209
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001210 weston_xkb_info_destroy(keyboard->xkb_info);
1211 keyboard->xkb_info = xkb_info;
Rui Matos65196bc2013-10-10 19:44:19 +02001212
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001213 xkb_state_unref(keyboard->xkb_state.state);
1214 keyboard->xkb_state.state = state;
Rui Matos65196bc2013-10-10 19:44:19 +02001215
1216 wl_resource_for_each(resource, &seat->keyboard->resource_list)
1217 send_keymap(resource, xkb_info);
1218 wl_resource_for_each(resource, &seat->keyboard->focus_resource_list)
1219 send_keymap(resource, xkb_info);
1220
1221 notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
1222
1223 if (!latched_mods && !locked_mods)
1224 return;
1225
1226 wl_resource_for_each(resource, &seat->keyboard->resource_list)
1227 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), seat->keyboard);
1228 wl_resource_for_each(resource, &seat->keyboard->focus_resource_list)
1229 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), seat->keyboard);
1230}
Rob Bradford382ff462013-06-24 16:52:45 +01001231#else
1232WL_EXPORT void
1233notify_modifiers(struct weston_seat *seat, uint32_t serial)
1234{
1235}
1236
1237static void
1238update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1239 enum wl_keyboard_key_state state)
1240{
1241}
Rui Matos65196bc2013-10-10 19:44:19 +02001242
1243static void
1244update_keymap(struct weston_seat *seat)
1245{
1246}
Rob Bradford382ff462013-06-24 16:52:45 +01001247#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001248
1249WL_EXPORT void
1250notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1251 enum wl_keyboard_key_state state,
1252 enum weston_key_state_update update_state)
1253{
1254 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001255 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001256 struct weston_keyboard_grab *grab = keyboard->grab;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001257 uint32_t *k, *end;
1258
1259 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001260 weston_compositor_idle_inhibit(compositor);
1261 keyboard->grab_key = key;
1262 keyboard->grab_time = time;
1263 } else {
1264 weston_compositor_idle_release(compositor);
1265 }
1266
1267 end = keyboard->keys.data + keyboard->keys.size;
1268 for (k = keyboard->keys.data; k < end; k++) {
1269 if (*k == key) {
1270 /* Ignore server-generated repeats. */
1271 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1272 return;
1273 *k = *--end;
1274 }
1275 }
1276 keyboard->keys.size = (void *) end - keyboard->keys.data;
1277 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1278 k = wl_array_add(&keyboard->keys, sizeof *k);
1279 *k = key;
1280 }
1281
1282 if (grab == &keyboard->default_grab ||
1283 grab == &keyboard->input_method_grab) {
1284 weston_compositor_run_key_binding(compositor, seat, time, key,
1285 state);
1286 grab = keyboard->grab;
1287 }
1288
1289 grab->interface->key(grab, time, key, state);
1290
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001291 if (keyboard->pending_keymap &&
Rui Matos65196bc2013-10-10 19:44:19 +02001292 keyboard->keys.size == 0)
1293 update_keymap(seat);
1294
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001295 if (update_state == STATE_UPDATE_AUTOMATIC) {
1296 update_modifier_state(seat,
1297 wl_display_get_serial(compositor->wl_display),
1298 key,
1299 state);
1300 }
1301}
1302
1303WL_EXPORT void
1304notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
1305 wl_fixed_t x, wl_fixed_t y)
1306{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001307 if (output) {
Giulio Camuffo1959ab82013-11-14 23:42:52 +01001308 weston_pointer_move(seat->pointer, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001309 } else {
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001310 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001311 * NULL) here, but somehow that breaks re-entry... */
1312 }
1313}
1314
1315static void
1316destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1317{
1318 struct weston_seat *ws;
1319
1320 ws = container_of(listener, struct weston_seat,
1321 saved_kbd_focus_listener);
1322
1323 ws->saved_kbd_focus = NULL;
1324}
1325
1326WL_EXPORT void
1327notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1328 enum weston_key_state_update update_state)
1329{
1330 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001331 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001332 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001333 uint32_t *k, serial;
1334
1335 serial = wl_display_next_serial(compositor->wl_display);
1336 wl_array_copy(&keyboard->keys, keys);
1337 wl_array_for_each(k, &keyboard->keys) {
1338 weston_compositor_idle_inhibit(compositor);
1339 if (update_state == STATE_UPDATE_AUTOMATIC)
1340 update_modifier_state(seat, serial, *k,
1341 WL_KEYBOARD_KEY_STATE_PRESSED);
1342 }
1343
1344 /* Run key bindings after we've updated the state. */
1345 wl_array_for_each(k, &keyboard->keys) {
1346 weston_compositor_run_key_binding(compositor, seat, 0, *k,
1347 WL_KEYBOARD_KEY_STATE_PRESSED);
1348 }
1349
1350 surface = seat->saved_kbd_focus;
1351
1352 if (surface) {
1353 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1354 weston_keyboard_set_focus(keyboard, surface);
1355 seat->saved_kbd_focus = NULL;
1356 }
1357}
1358
1359WL_EXPORT void
1360notify_keyboard_focus_out(struct weston_seat *seat)
1361{
1362 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001363 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001364 uint32_t *k, serial;
1365
1366 serial = wl_display_next_serial(compositor->wl_display);
1367 wl_array_for_each(k, &keyboard->keys) {
1368 weston_compositor_idle_release(compositor);
1369 update_modifier_state(seat, serial, *k,
1370 WL_KEYBOARD_KEY_STATE_RELEASED);
1371 }
1372
1373 seat->modifier_state = 0;
1374
1375 if (keyboard->focus) {
1376 seat->saved_kbd_focus = keyboard->focus;
1377 seat->saved_kbd_focus_listener.notify =
1378 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001379 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001380 &seat->saved_kbd_focus_listener);
1381 }
1382
1383 weston_keyboard_set_focus(keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001384 weston_keyboard_cancel_grab(keyboard);
Kristian Høgsbergebd5fd42013-11-22 21:12:19 -08001385 if (seat->pointer)
1386 weston_pointer_cancel_grab(seat->pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001387}
1388
Michael Fua2bb7912013-07-23 15:51:06 +08001389WL_EXPORT void
Jason Ekstranda7af7042013-10-12 22:38:11 -05001390weston_touch_set_focus(struct weston_seat *seat, struct weston_view *view)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001391{
Neil Roberts96d790e2013-09-19 17:32:00 +01001392 struct wl_list *focus_resource_list;
1393
1394 focus_resource_list = &seat->touch->focus_resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001395
Kristian Høgsbergc3244d72013-10-24 14:21:53 -07001396 if (view && seat->touch->focus &&
1397 seat->touch->focus->surface == view->surface) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001398 seat->touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001399 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001400 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001401
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001402 wl_list_remove(&seat->touch->focus_resource_listener.link);
1403 wl_list_init(&seat->touch->focus_resource_listener.link);
1404 wl_list_remove(&seat->touch->focus_view_listener.link);
1405 wl_list_init(&seat->touch->focus_view_listener.link);
1406
Neil Roberts96d790e2013-09-19 17:32:00 +01001407 if (!wl_list_empty(focus_resource_list)) {
1408 move_resources(&seat->touch->resource_list,
1409 focus_resource_list);
1410 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001411
Jason Ekstranda7af7042013-10-12 22:38:11 -05001412 if (view) {
Neil Roberts96d790e2013-09-19 17:32:00 +01001413 struct wl_client *surface_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -05001414 wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +01001415 move_resources_for_client(focus_resource_list,
1416 &seat->touch->resource_list,
1417 surface_client);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001418 wl_resource_add_destroy_listener(view->surface->resource,
1419 &seat->touch->focus_resource_listener);
1420 wl_signal_add(&view->destroy_signal, &seat->touch->focus_view_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001421 }
Jason Ekstranda7af7042013-10-12 22:38:11 -05001422 seat->touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001423}
1424
1425/**
1426 * notify_touch - emulates button touches and notifies surfaces accordingly.
1427 *
1428 * It assumes always the correct cycle sequence until it gets here: touch_down
1429 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1430 * for sending along such order.
1431 *
1432 */
1433WL_EXPORT void
1434notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1435 wl_fixed_t x, wl_fixed_t y, int touch_type)
1436{
1437 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001438 struct weston_touch *touch = seat->touch;
Kristian Høgsberge329f362013-05-06 22:19:57 -04001439 struct weston_touch_grab *grab = touch->grab;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001440 struct weston_view *ev;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001441 wl_fixed_t sx, sy;
1442
1443 /* Update grab's global coordinates. */
Neil Roberts306fe082013-10-03 16:43:06 +01001444 if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
1445 touch->grab_x = x;
1446 touch->grab_y = y;
1447 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001448
1449 switch (touch_type) {
1450 case WL_TOUCH_DOWN:
1451 weston_compositor_idle_inhibit(ec);
1452
Jonas Ådahl9484b692013-12-02 22:05:03 +01001453 touch->num_tp++;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001454
Jason Ekstranda7af7042013-10-12 22:38:11 -05001455 /* the first finger down picks the view, and all further go
1456 * to that view for the remainder of the touch session i.e.
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001457 * until all touch points are up again. */
Jonas Ådahl9484b692013-12-02 22:05:03 +01001458 if (touch->num_tp == 1) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001459 ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
1460 weston_touch_set_focus(seat, ev);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001461 } else if (touch->focus) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001462 ev = touch->focus;
1463 weston_view_from_global_fixed(ev, x, y, &sx, &sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001464 } else {
1465 /* Unexpected condition: We have non-initial touch but
1466 * there is no focused surface.
1467 */
1468 weston_log("touch event received with %d points down"
Jonas Ådahl9484b692013-12-02 22:05:03 +01001469 "but no surface focused\n", touch->num_tp);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001470 return;
1471 }
1472
Kristian Høgsbergc8964012014-02-05 14:25:18 -08001473 weston_compositor_run_touch_binding(ec, seat,
1474 time, touch_type);
1475
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001476 grab->interface->down(grab, time, touch_id, sx, sy);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001477 if (touch->num_tp == 1) {
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001478 touch->grab_serial =
1479 wl_display_get_serial(ec->wl_display);
Neil Roberts306fe082013-10-03 16:43:06 +01001480 touch->grab_touch_id = touch_id;
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001481 touch->grab_time = time;
1482 touch->grab_x = x;
1483 touch->grab_y = y;
1484 }
1485
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001486 break;
1487 case WL_TOUCH_MOTION:
Jason Ekstranda7af7042013-10-12 22:38:11 -05001488 ev = touch->focus;
1489 if (!ev)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001490 break;
1491
Jason Ekstranda7af7042013-10-12 22:38:11 -05001492 weston_view_from_global_fixed(ev, x, y, &sx, &sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001493 grab->interface->motion(grab, time, touch_id, sx, sy);
1494 break;
1495 case WL_TOUCH_UP:
Kristian Høgsberga30e29a2014-01-08 22:29:20 -08001496 if (touch->num_tp == 0) {
1497 /* This can happen if we start out with one or
1498 * more fingers on the touch screen, in which
1499 * case we didn't get the corresponding down
1500 * event. */
1501 weston_log("unmatched touch up event\n");
1502 break;
1503 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001504 weston_compositor_idle_release(ec);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001505 touch->num_tp--;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001506
1507 grab->interface->up(grab, time, touch_id);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001508 if (touch->num_tp == 0)
Michael Fua2bb7912013-07-23 15:51:06 +08001509 weston_touch_set_focus(seat, NULL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001510 break;
1511 }
1512}
1513
1514static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001515pointer_cursor_surface_configure(struct weston_surface *es,
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001516 int32_t dx, int32_t dy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001517{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001518 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001519 int x, y;
1520
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001521 if (es->width == 0)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001522 return;
1523
Jason Ekstranda7af7042013-10-12 22:38:11 -05001524 assert(es == pointer->sprite->surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001525
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001526 pointer->hotspot_x -= dx;
1527 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001528
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001529 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1530 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001531
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001532 weston_view_set_position(pointer->sprite, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001533
1534 empty_region(&es->pending.input);
Ander Conselvan de Oliveira23900f72014-01-31 16:07:51 +02001535 empty_region(&es->input);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001536
1537 if (!weston_surface_is_mapped(es)) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001538 wl_list_insert(&es->compositor->cursor_layer.view_list,
1539 &pointer->sprite->layer_link);
1540 weston_view_update_transform(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001541 }
1542}
1543
1544static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001545pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1546 uint32_t serial, struct wl_resource *surface_resource,
1547 int32_t x, int32_t y)
1548{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001549 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001550 struct weston_surface *surface = NULL;
1551
1552 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001553 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001554
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001555 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001556 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001557 /* pointer->focus->surface->resource can be NULL. Surfaces like the
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001558 black_surface used in shell.c for fullscreen don't have
1559 a resource, but can still have focus */
Jason Ekstranda7af7042013-10-12 22:38:11 -05001560 if (pointer->focus->surface->resource == NULL)
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001561 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001562 if (wl_resource_get_client(pointer->focus->surface->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001563 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001564 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001565 return;
1566
Jason Ekstranda7af7042013-10-12 22:38:11 -05001567 if (surface && pointer->sprite && surface != pointer->sprite->surface) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001568 if (surface->configure) {
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001569 wl_resource_post_error(surface->resource,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001570 WL_DISPLAY_ERROR_INVALID_OBJECT,
1571 "surface->configure already "
1572 "set");
1573 return;
1574 }
1575 }
1576
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001577 if (pointer->sprite)
1578 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001579
1580 if (!surface)
1581 return;
1582
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001583 wl_signal_add(&surface->destroy_signal,
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001584 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001585
1586 surface->configure = pointer_cursor_surface_configure;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001587 surface->configure_private = pointer;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001588 pointer->sprite = weston_view_create(surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001589 pointer->hotspot_x = x;
1590 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001591
1592 if (surface->buffer_ref.buffer)
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001593 pointer_cursor_surface_configure(surface, 0, 0);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001594}
1595
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001596static void
1597pointer_release(struct wl_client *client, struct wl_resource *resource)
1598{
1599 wl_resource_destroy(resource);
1600}
1601
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001602static const struct wl_pointer_interface pointer_interface = {
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001603 pointer_set_cursor,
1604 pointer_release
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001605};
1606
1607static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001608seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
1609 uint32_t id)
1610{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001611 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001612 struct wl_resource *cr;
1613
Kristian Høgsberge3148752013-05-06 23:19:49 -04001614 if (!seat->pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001615 return;
1616
Jason Ekstranda85118c2013-06-27 20:17:02 -05001617 cr = wl_resource_create(client, &wl_pointer_interface,
1618 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07001619 if (cr == NULL) {
1620 wl_client_post_no_memory(client);
1621 return;
1622 }
1623
Neil Roberts96d790e2013-09-19 17:32:00 +01001624 /* May be moved to focused list later by either
1625 * weston_pointer_set_focus or directly if this client is already
1626 * focused */
Jason Ekstrand44a38632013-06-14 10:08:00 -05001627 wl_list_insert(&seat->pointer->resource_list, wl_resource_get_link(cr));
Jason Ekstranda85118c2013-06-27 20:17:02 -05001628 wl_resource_set_implementation(cr, &pointer_interface, seat->pointer,
1629 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001630
Jason Ekstranda7af7042013-10-12 22:38:11 -05001631 if (seat->pointer->focus && seat->pointer->focus->surface->resource &&
1632 wl_resource_get_client(seat->pointer->focus->surface->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001633 wl_fixed_t sx, sy;
1634
Jason Ekstranda7af7042013-10-12 22:38:11 -05001635 weston_view_from_global_fixed(seat->pointer->focus,
1636 seat->pointer->x,
1637 seat->pointer->y,
1638 &sx, &sy);
Neil Roberts96d790e2013-09-19 17:32:00 +01001639
1640 wl_list_remove(wl_resource_get_link(cr));
1641 wl_list_insert(&seat->pointer->focus_resource_list,
1642 wl_resource_get_link(cr));
1643 wl_pointer_send_enter(cr,
1644 seat->pointer->focus_serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -05001645 seat->pointer->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01001646 sx, sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001647 }
1648}
1649
1650static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001651keyboard_release(struct wl_client *client, struct wl_resource *resource)
1652{
1653 wl_resource_destroy(resource);
1654}
1655
1656static const struct wl_keyboard_interface keyboard_interface = {
1657 keyboard_release
1658};
1659
Neil Roberts96d790e2013-09-19 17:32:00 +01001660static int
1661should_send_modifiers_to_client(struct weston_seat *seat,
1662 struct wl_client *client)
1663{
1664 if (seat->keyboard &&
1665 seat->keyboard->focus &&
Jason Ekstrand42133d42013-11-14 20:06:16 -06001666 seat->keyboard->focus->resource &&
Neil Roberts96d790e2013-09-19 17:32:00 +01001667 wl_resource_get_client(seat->keyboard->focus->resource) == client)
1668 return 1;
1669
1670 if (seat->pointer &&
1671 seat->pointer->focus &&
Jason Ekstrand42133d42013-11-14 20:06:16 -06001672 seat->pointer->focus->surface->resource &&
Jason Ekstranda7af7042013-10-12 22:38:11 -05001673 wl_resource_get_client(seat->pointer->focus->surface->resource) == client)
Neil Roberts96d790e2013-09-19 17:32:00 +01001674 return 1;
1675
1676 return 0;
1677}
1678
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001679static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001680seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
1681 uint32_t id)
1682{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001683 struct weston_seat *seat = wl_resource_get_user_data(resource);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001684 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001685 struct wl_resource *cr;
1686
Kristian Høgsberge3148752013-05-06 23:19:49 -04001687 if (!seat->keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001688 return;
1689
Jason Ekstranda85118c2013-06-27 20:17:02 -05001690 cr = wl_resource_create(client, &wl_keyboard_interface,
1691 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07001692 if (cr == NULL) {
1693 wl_client_post_no_memory(client);
1694 return;
1695 }
1696
Neil Roberts96d790e2013-09-19 17:32:00 +01001697 /* May be moved to focused list later by either
1698 * weston_keyboard_set_focus or directly if this client is already
1699 * focused */
Jason Ekstrand44a38632013-06-14 10:08:00 -05001700 wl_list_insert(&seat->keyboard->resource_list, wl_resource_get_link(cr));
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001701 wl_resource_set_implementation(cr, &keyboard_interface,
1702 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001703
Matt Roper01a92732013-06-24 16:52:44 +01001704 if (seat->compositor->use_xkbcommon) {
1705 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001706 keyboard->xkb_info->keymap_fd,
1707 keyboard->xkb_info->keymap_size);
Matt Roper01a92732013-06-24 16:52:44 +01001708 } else {
1709 int null_fd = open("/dev/null", O_RDONLY);
1710 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
1711 null_fd,
1712 0);
1713 close(null_fd);
1714 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001715
Neil Roberts96d790e2013-09-19 17:32:00 +01001716 if (should_send_modifiers_to_client(seat, client)) {
1717 send_modifiers_to_resource(seat->keyboard,
1718 cr,
1719 seat->keyboard->focus_serial);
1720 }
1721
Kristian Høgsberge3148752013-05-06 23:19:49 -04001722 if (seat->keyboard->focus &&
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001723 wl_resource_get_client(seat->keyboard->focus->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01001724 struct weston_surface *surface =
1725 (struct weston_surface *) seat->keyboard->focus;
1726
1727 wl_list_remove(wl_resource_get_link(cr));
1728 wl_list_insert(&seat->keyboard->focus_resource_list,
1729 wl_resource_get_link(cr));
1730 wl_keyboard_send_enter(cr,
1731 seat->keyboard->focus_serial,
1732 surface->resource,
1733 &seat->keyboard->keys);
1734
1735 /* If this is the first keyboard resource for this
1736 * client... */
1737 if (seat->keyboard->focus_resource_list.prev ==
1738 wl_resource_get_link(cr))
1739 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001740 }
1741}
1742
1743static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001744touch_release(struct wl_client *client, struct wl_resource *resource)
1745{
1746 wl_resource_destroy(resource);
1747}
1748
1749static const struct wl_touch_interface touch_interface = {
1750 touch_release
1751};
1752
1753static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001754seat_get_touch(struct wl_client *client, struct wl_resource *resource,
1755 uint32_t id)
1756{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001757 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001758 struct wl_resource *cr;
1759
Kristian Høgsberge3148752013-05-06 23:19:49 -04001760 if (!seat->touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001761 return;
1762
Jason Ekstranda85118c2013-06-27 20:17:02 -05001763 cr = wl_resource_create(client, &wl_touch_interface,
1764 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07001765 if (cr == NULL) {
1766 wl_client_post_no_memory(client);
1767 return;
1768 }
1769
Neil Roberts96d790e2013-09-19 17:32:00 +01001770 if (seat->touch->focus &&
Jason Ekstranda7af7042013-10-12 22:38:11 -05001771 wl_resource_get_client(seat->touch->focus->surface->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01001772 wl_list_insert(&seat->touch->resource_list,
1773 wl_resource_get_link(cr));
1774 } else {
1775 wl_list_insert(&seat->touch->focus_resource_list,
1776 wl_resource_get_link(cr));
1777 }
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001778 wl_resource_set_implementation(cr, &touch_interface,
1779 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001780}
1781
1782static const struct wl_seat_interface seat_interface = {
1783 seat_get_pointer,
1784 seat_get_keyboard,
1785 seat_get_touch,
1786};
1787
1788static void
1789bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1790{
Kristian Høgsberge3148752013-05-06 23:19:49 -04001791 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001792 struct wl_resource *resource;
1793 enum wl_seat_capability caps = 0;
1794
Jason Ekstranda85118c2013-06-27 20:17:02 -05001795 resource = wl_resource_create(client,
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001796 &wl_seat_interface, MIN(version, 3), id);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001797 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
Jason Ekstranda85118c2013-06-27 20:17:02 -05001798 wl_resource_set_implementation(resource, &seat_interface, data,
1799 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001800
1801 if (seat->pointer)
1802 caps |= WL_SEAT_CAPABILITY_POINTER;
1803 if (seat->keyboard)
1804 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
1805 if (seat->touch)
1806 caps |= WL_SEAT_CAPABILITY_TOUCH;
1807
1808 wl_seat_send_capabilities(resource, caps);
Rob Bradforde445ae62013-05-31 18:09:51 +01001809 if (version >= 2)
1810 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001811}
1812
Rob Bradford382ff462013-06-24 16:52:45 +01001813#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001814int
1815weston_compositor_xkb_init(struct weston_compositor *ec,
1816 struct xkb_rule_names *names)
1817{
Rob Bradford382ff462013-06-24 16:52:45 +01001818 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01001819
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001820 if (ec->xkb_context == NULL) {
1821 ec->xkb_context = xkb_context_new(0);
1822 if (ec->xkb_context == NULL) {
1823 weston_log("failed to create XKB context\n");
1824 return -1;
1825 }
1826 }
1827
1828 if (names)
1829 ec->xkb_names = *names;
1830 if (!ec->xkb_names.rules)
1831 ec->xkb_names.rules = strdup("evdev");
1832 if (!ec->xkb_names.model)
1833 ec->xkb_names.model = strdup("pc105");
1834 if (!ec->xkb_names.layout)
1835 ec->xkb_names.layout = strdup("us");
1836
1837 return 0;
1838}
1839
Stefan Schmidtfda26522013-09-17 10:54:09 +01001840static void
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001841weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001842{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001843 if (--xkb_info->ref_count > 0)
1844 return;
1845
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001846 if (xkb_info->keymap)
1847 xkb_map_unref(xkb_info->keymap);
1848
1849 if (xkb_info->keymap_area)
1850 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
1851 if (xkb_info->keymap_fd >= 0)
1852 close(xkb_info->keymap_fd);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001853 free(xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001854}
1855
1856void
1857weston_compositor_xkb_destroy(struct weston_compositor *ec)
1858{
Matt Roper01a92732013-06-24 16:52:44 +01001859 /*
1860 * If we're operating in raw keyboard mode, we never initialized
1861 * libxkbcommon so there's no cleanup to do either.
1862 */
1863 if (!ec->use_xkbcommon)
1864 return;
1865
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001866 free((char *) ec->xkb_names.rules);
1867 free((char *) ec->xkb_names.model);
1868 free((char *) ec->xkb_names.layout);
1869 free((char *) ec->xkb_names.variant);
1870 free((char *) ec->xkb_names.options);
Stefan Schmidtfda26522013-09-17 10:54:09 +01001871
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001872 if (ec->xkb_info)
1873 weston_xkb_info_destroy(ec->xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001874 xkb_context_unref(ec->xkb_context);
1875}
1876
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001877static struct weston_xkb_info *
1878weston_xkb_info_create(struct xkb_keymap *keymap)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001879{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001880 struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
1881 if (xkb_info == NULL)
1882 return NULL;
1883
1884 xkb_info->keymap = xkb_map_ref(keymap);
1885 xkb_info->ref_count = 1;
1886
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001887 char *keymap_str;
1888
1889 xkb_info->shift_mod = xkb_map_mod_get_index(xkb_info->keymap,
1890 XKB_MOD_NAME_SHIFT);
1891 xkb_info->caps_mod = xkb_map_mod_get_index(xkb_info->keymap,
1892 XKB_MOD_NAME_CAPS);
1893 xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
1894 XKB_MOD_NAME_CTRL);
1895 xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
1896 XKB_MOD_NAME_ALT);
1897 xkb_info->mod2_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod2");
1898 xkb_info->mod3_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod3");
1899 xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
1900 XKB_MOD_NAME_LOGO);
1901 xkb_info->mod5_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod5");
1902
1903 xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
1904 XKB_LED_NAME_NUM);
1905 xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
1906 XKB_LED_NAME_CAPS);
1907 xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
1908 XKB_LED_NAME_SCROLL);
1909
1910 keymap_str = xkb_map_get_as_string(xkb_info->keymap);
1911 if (keymap_str == NULL) {
1912 weston_log("failed to get string version of keymap\n");
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001913 goto err_keymap;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001914 }
1915 xkb_info->keymap_size = strlen(keymap_str) + 1;
1916
1917 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
1918 if (xkb_info->keymap_fd < 0) {
1919 weston_log("creating a keymap file for %lu bytes failed: %m\n",
1920 (unsigned long) xkb_info->keymap_size);
1921 goto err_keymap_str;
1922 }
1923
1924 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
1925 PROT_READ | PROT_WRITE,
1926 MAP_SHARED, xkb_info->keymap_fd, 0);
1927 if (xkb_info->keymap_area == MAP_FAILED) {
1928 weston_log("failed to mmap() %lu bytes\n",
1929 (unsigned long) xkb_info->keymap_size);
1930 goto err_dev_zero;
1931 }
1932 strcpy(xkb_info->keymap_area, keymap_str);
1933 free(keymap_str);
1934
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001935 return xkb_info;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001936
1937err_dev_zero:
1938 close(xkb_info->keymap_fd);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001939err_keymap_str:
1940 free(keymap_str);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001941err_keymap:
1942 xkb_map_unref(xkb_info->keymap);
1943 free(xkb_info);
1944 return NULL;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001945}
1946
1947static int
1948weston_compositor_build_global_keymap(struct weston_compositor *ec)
1949{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001950 struct xkb_keymap *keymap;
1951
1952 if (ec->xkb_info != NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001953 return 0;
1954
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001955 keymap = xkb_map_new_from_names(ec->xkb_context,
1956 &ec->xkb_names,
1957 0);
1958 if (keymap == NULL) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001959 weston_log("failed to compile global XKB keymap\n");
1960 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
1961 "options %s\n",
1962 ec->xkb_names.rules, ec->xkb_names.model,
1963 ec->xkb_names.layout, ec->xkb_names.variant,
1964 ec->xkb_names.options);
1965 return -1;
1966 }
1967
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00001968 ec->xkb_info = weston_xkb_info_create(keymap);
Rui Matos73d93952013-10-24 19:28:41 +02001969 xkb_keymap_unref(keymap);
Stefan Schmidtfda26522013-09-17 10:54:09 +01001970 if (ec->xkb_info == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001971 return -1;
1972
1973 return 0;
1974}
Rob Bradford382ff462013-06-24 16:52:45 +01001975#else
1976int
1977weston_compositor_xkb_init(struct weston_compositor *ec,
1978 struct xkb_rule_names *names)
1979{
1980 return 0;
1981}
1982
1983void
1984weston_compositor_xkb_destroy(struct weston_compositor *ec)
1985{
1986}
1987#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001988
Rui Matos65196bc2013-10-10 19:44:19 +02001989WL_EXPORT void
1990weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
1991{
1992 if (!seat->keyboard || !keymap)
1993 return;
1994
1995#ifdef ENABLE_XKBCOMMON
1996 if (!seat->compositor->use_xkbcommon)
1997 return;
1998
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001999 xkb_keymap_unref(seat->keyboard->pending_keymap);
2000 seat->keyboard->pending_keymap = xkb_keymap_ref(keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02002001
2002 if (seat->keyboard->keys.size == 0)
2003 update_keymap(seat);
2004#endif
2005}
2006
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002007WL_EXPORT int
2008weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2009{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002010 struct weston_keyboard *keyboard;
2011
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002012 if (seat->keyboard) {
2013 seat->keyboard_device_count += 1;
2014 if (seat->keyboard_device_count == 1)
2015 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002016 return 0;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002017 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002018
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002019 keyboard = weston_keyboard_create();
2020 if (keyboard == NULL) {
2021 weston_log("failed to allocate weston keyboard struct\n");
2022 return -1;
2023 }
2024
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002025#ifdef ENABLE_XKBCOMMON
2026 if (seat->compositor->use_xkbcommon) {
2027 if (keymap != NULL) {
2028 keyboard->xkb_info = weston_xkb_info_create(keymap);
2029 if (keyboard->xkb_info == NULL)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002030 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002031 } else {
2032 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002033 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002034 keyboard->xkb_info = seat->compositor->xkb_info;
2035 keyboard->xkb_info->ref_count++;
2036 }
2037
2038 keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
2039 if (keyboard->xkb_state.state == NULL) {
2040 weston_log("failed to initialise XKB state\n");
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002041 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002042 }
2043
2044 keyboard->xkb_state.leds = 0;
2045 }
2046#endif
2047
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002048 seat->keyboard = keyboard;
2049 seat->keyboard_device_count = 1;
2050 keyboard->seat = seat;
2051
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002052 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002053
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002054 return 0;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002055
2056err:
2057 if (keyboard->xkb_info)
2058 weston_xkb_info_destroy(keyboard->xkb_info);
2059 free(keyboard);
2060
2061 return -1;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002062}
2063
Jonas Ådahl91fed542013-12-03 09:14:27 +01002064static void
2065weston_keyboard_reset_state(struct weston_keyboard *keyboard)
2066{
2067 struct weston_seat *seat = keyboard->seat;
2068 struct xkb_state *state;
2069
2070#ifdef ENABLE_XKBCOMMON
2071 if (seat->compositor->use_xkbcommon) {
2072 state = xkb_state_new(keyboard->xkb_info->keymap);
2073 if (!state) {
2074 weston_log("failed to reset XKB state\n");
2075 return;
2076 }
2077 xkb_state_unref(keyboard->xkb_state.state);
2078 keyboard->xkb_state.state = state;
2079
2080 keyboard->xkb_state.leds = 0;
2081 }
2082#endif
2083
2084 seat->modifier_state = 0;
2085}
2086
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002087WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002088weston_seat_release_keyboard(struct weston_seat *seat)
2089{
2090 seat->keyboard_device_count--;
2091 if (seat->keyboard_device_count == 0) {
Jonas Ådahl630bae82013-10-17 23:04:06 +02002092 weston_keyboard_set_focus(seat->keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002093 weston_keyboard_cancel_grab(seat->keyboard);
Jonas Ådahl91fed542013-12-03 09:14:27 +01002094 weston_keyboard_reset_state(seat->keyboard);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002095 seat_send_updated_caps(seat);
2096 }
2097}
2098
2099WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002100weston_seat_init_pointer(struct weston_seat *seat)
2101{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002102 struct weston_pointer *pointer;
2103
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002104 if (seat->pointer) {
2105 seat->pointer_device_count += 1;
2106 if (seat->pointer_device_count == 1)
2107 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002108 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002109 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002110
Giulio Camuffocdb4d292013-11-14 23:42:53 +01002111 pointer = weston_pointer_create(seat);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002112 if (pointer == NULL)
2113 return;
2114
2115 seat->pointer = pointer;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002116 seat->pointer_device_count = 1;
2117 pointer->seat = seat;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002118
2119 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002120}
2121
2122WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002123weston_seat_release_pointer(struct weston_seat *seat)
2124{
2125 struct weston_pointer *pointer = seat->pointer;
2126
2127 seat->pointer_device_count--;
2128 if (seat->pointer_device_count == 0) {
Jonas Ådahl630bae82013-10-17 23:04:06 +02002129 weston_pointer_set_focus(pointer, NULL,
2130 wl_fixed_from_int(0),
2131 wl_fixed_from_int(0));
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002132 weston_pointer_cancel_grab(pointer);
Jonas Ådahl630bae82013-10-17 23:04:06 +02002133
Jonas Ådahla4932742013-10-17 23:04:07 +02002134 if (pointer->sprite)
2135 pointer_unmap_sprite(pointer);
2136
Jonas Ådahl3e12e632013-12-02 22:05:05 +01002137 weston_pointer_reset_state(pointer);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002138 seat_send_updated_caps(seat);
2139 }
2140}
2141
2142WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002143weston_seat_init_touch(struct weston_seat *seat)
2144{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002145 struct weston_touch *touch;
2146
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002147 if (seat->touch) {
2148 seat->touch_device_count += 1;
2149 if (seat->touch_device_count == 1)
2150 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002151 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002152 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002153
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002154 touch = weston_touch_create();
2155 if (touch == NULL)
2156 return;
2157
2158 seat->touch = touch;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002159 seat->touch_device_count = 1;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002160 touch->seat = seat;
2161
2162 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002163}
2164
2165WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002166weston_seat_release_touch(struct weston_seat *seat)
2167{
2168 seat->touch_device_count--;
2169 if (seat->touch_device_count == 0) {
Jonas Ådahl630bae82013-10-17 23:04:06 +02002170 weston_touch_set_focus(seat, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002171 weston_touch_cancel_grab(seat->touch);
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +01002172 weston_touch_reset_state(seat->touch);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002173 seat_send_updated_caps(seat);
2174 }
2175}
2176
2177WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002178weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
2179 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002180{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002181 memset(seat, 0, sizeof *seat);
2182
Kristian Høgsberge3148752013-05-06 23:19:49 -04002183 seat->selection_data_source = NULL;
2184 wl_list_init(&seat->base_resource_list);
2185 wl_signal_init(&seat->selection_signal);
2186 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002187 wl_signal_init(&seat->destroy_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002188
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002189 seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 3,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002190 seat, bind_seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002191
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002192 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002193 seat->modifier_state = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002194 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002195
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002196 wl_list_insert(ec->seat_list.prev, &seat->link);
2197
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002198 clipboard_create(seat);
2199
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002200 wl_signal_emit(&ec->seat_created_signal, seat);
2201}
2202
2203WL_EXPORT void
2204weston_seat_release(struct weston_seat *seat)
2205{
2206 wl_list_remove(&seat->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002207
Jonas Ådahl1afb2382014-01-03 19:46:51 +01002208 if (seat->saved_kbd_focus)
2209 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2210
Kristian Høgsberge3148752013-05-06 23:19:49 -04002211 if (seat->pointer)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002212 weston_pointer_destroy(seat->pointer);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002213 if (seat->keyboard)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002214 weston_keyboard_destroy(seat->keyboard);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002215 if (seat->touch)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002216 weston_touch_destroy(seat->touch);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002217
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002218 free (seat->seat_name);
2219
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002220 wl_global_destroy(seat->global);
Kristian Høgsbergaaadc772013-07-08 16:20:31 -04002221
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002222 wl_signal_emit(&seat->destroy_signal, seat);
2223}