1 /*
2  * Copyright © 2014-2015 David FORT <contact@hardening-consulting.com>
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22 #include "uwac-priv.h"
23 #include "uwac-utils.h"
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <errno.h>
30 #include <time.h>
31 #include <unistd.h>
32 #include <sys/mman.h>
33 #include <sys/timerfd.h>
34 #include <sys/epoll.h>
35 
36 #include "uwac-os.h"
37 #include "wayland-cursor.h"
38 #include "wayland-client-protocol.h"
39 
create_pointer_buffer(UwacSeat * seat,const void * src,size_t size)40 static struct wl_buffer* create_pointer_buffer(UwacSeat* seat, const void* src, size_t size)
41 {
42 	struct wl_buffer* buffer = NULL;
43 	int fd;
44 	void* data;
45 	struct wl_shm_pool* pool;
46 
47 	fd = uwac_create_anonymous_file(size);
48 
49 	if (fd < 0)
50 		return buffer;
51 
52 	data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
53 
54 	if (data == MAP_FAILED)
55 	{
56 		goto error_mmap;
57 	}
58 	memcpy(data, src, size);
59 
60 	pool = wl_shm_create_pool(seat->display->shm, fd, size);
61 
62 	if (!pool)
63 	{
64 		munmap(data, size);
65 		goto error_mmap;
66 	}
67 
68 	buffer =
69 	    wl_shm_pool_create_buffer(pool, 0, seat->pointer_image->width, seat->pointer_image->height,
70 	                              seat->pointer_image->width * 4, WL_SHM_FORMAT_ARGB8888);
71 	wl_shm_pool_destroy(pool);
72 
73 	if (munmap(data, size) < 0)
74 		fprintf(stderr, "%s: munmap(%p, %" PRIuz ") failed with [%d] %s\n", __FUNCTION__, data,
75 		        size, errno, strerror(errno));
76 
77 error_mmap:
78 	close(fd);
79 	return buffer;
80 }
81 
on_buffer_release(void * data,struct wl_buffer * wl_buffer)82 static void on_buffer_release(void* data, struct wl_buffer* wl_buffer)
83 {
84 	(void)data;
85 	wl_buffer_destroy(wl_buffer);
86 }
87 
88 const struct wl_buffer_listener buffer_release_listener = { on_buffer_release };
89 
set_cursor_image(UwacSeat * seat,uint32_t serial)90 static UwacReturnCode set_cursor_image(UwacSeat* seat, uint32_t serial)
91 {
92 	struct wl_buffer* buffer = NULL;
93 	struct wl_cursor* cursor;
94 	struct wl_cursor_image* image;
95 	struct wl_surface* surface = NULL;
96 	int32_t x = 0, y = 0;
97 	int buffer_add_listener_success = -1;
98 
99 	if (!seat || !seat->display || !seat->default_cursor || !seat->default_cursor->images)
100 		return UWAC_ERROR_INTERNAL;
101 
102 	switch (seat->pointer_type)
103 	{
104 		case 2: /* Custom poiner */
105 			image = seat->pointer_image;
106 			buffer = create_pointer_buffer(seat, seat->pointer_data, seat->pointer_size);
107 			if (!buffer)
108 				return UWAC_ERROR_INTERNAL;
109 			surface = seat->pointer_surface;
110 			x = image->hotspot_x;
111 			y = image->hotspot_y;
112 			break;
113 		case 1: /* NULL pointer */
114 			break;
115 		default: /* Default system pointer */
116 			cursor = seat->default_cursor;
117 			if (!cursor)
118 				return UWAC_ERROR_INTERNAL;
119 			image = cursor->images[0];
120 			if (!image)
121 				return UWAC_ERROR_INTERNAL;
122 			x = image->hotspot_x;
123 			y = image->hotspot_y;
124 			buffer = wl_cursor_image_get_buffer(image);
125 			if (!buffer)
126 				return UWAC_ERROR_INTERNAL;
127 			surface = seat->pointer_surface;
128 			break;
129 	}
130 
131 	if (buffer)
132 	{
133 		buffer_add_listener_success =
134 		    wl_buffer_add_listener(buffer, &buffer_release_listener, seat);
135 	}
136 
137 	if (surface && buffer_add_listener_success > -1)
138 	{
139 		wl_surface_attach(surface, buffer, -x, -y);
140 		wl_surface_damage(surface, 0, 0, image->width, image->height);
141 		wl_surface_commit(surface);
142 	}
143 
144 	wl_pointer_set_cursor(seat->pointer, serial, surface, x, y);
145 
146 	return UWAC_SUCCESS;
147 }
148 
keyboard_repeat_func(UwacTask * task,uint32_t events)149 static void keyboard_repeat_func(UwacTask* task, uint32_t events)
150 {
151 	UwacSeat* input = container_of(task, UwacSeat, repeat_task);
152 	UwacWindow* window = input->keyboard_focus;
153 	uint64_t exp;
154 
155 	if (read(input->repeat_timer_fd, &exp, sizeof exp) != sizeof exp)
156 		/* If we change the timer between the fd becoming
157 		 * readable and getting here, there'll be nothing to
158 		 * read and we get EAGAIN. */
159 		return;
160 
161 	if (window)
162 	{
163 		UwacKeyEvent* key;
164 
165 		key = (UwacKeyEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_KEY);
166 		if (!key)
167 			return;
168 
169 		key->window = window;
170 		key->sym = input->repeat_sym;
171 		key->raw_key = input->repeat_key;
172 		key->pressed = true;
173 	}
174 }
175 
keyboard_handle_keymap(void * data,struct wl_keyboard * keyboard,uint32_t format,int fd,uint32_t size)176 static void keyboard_handle_keymap(void* data, struct wl_keyboard* keyboard, uint32_t format,
177                                    int fd, uint32_t size)
178 {
179 	UwacSeat* input = data;
180 	struct xkb_keymap* keymap;
181 	struct xkb_state* state;
182 	char* map_str;
183 	int mapFlags = MAP_SHARED;
184 
185 	if (!data)
186 	{
187 		close(fd);
188 		return;
189 	}
190 
191 	if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
192 	{
193 		close(fd);
194 		return;
195 	}
196 
197 	if (input->seat_version >= 7)
198 		mapFlags = MAP_PRIVATE;
199 
200 	map_str = mmap(NULL, size, PROT_READ, mapFlags, fd, 0);
201 	if (map_str == MAP_FAILED)
202 	{
203 		close(fd);
204 		return;
205 	}
206 
207 	keymap = xkb_keymap_new_from_string(input->xkb_context, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
208 	munmap(map_str, size);
209 	close(fd);
210 
211 	if (!keymap)
212 	{
213 		assert(uwacErrorHandler(input->display, UWAC_ERROR_INTERNAL, "failed to compile keymap\n"));
214 		return;
215 	}
216 
217 	state = xkb_state_new(keymap);
218 	if (!state)
219 	{
220 		assert(
221 		    uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY, "failed to create XKB state\n"));
222 		xkb_keymap_unref(keymap);
223 		return;
224 	}
225 
226 	xkb_keymap_unref(input->xkb.keymap);
227 	xkb_state_unref(input->xkb.state);
228 	input->xkb.keymap = keymap;
229 	input->xkb.state = state;
230 
231 	input->xkb.control_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Control");
232 	input->xkb.alt_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Mod1");
233 	input->xkb.shift_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Shift");
234 	input->xkb.caps_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Lock");
235 	input->xkb.num_mask = 1 << xkb_keymap_mod_get_index(input->xkb.keymap, "Mod2");
236 }
237 
238 static void keyboard_handle_key(void* data, struct wl_keyboard* keyboard, uint32_t serial,
239                                 uint32_t time, uint32_t key, uint32_t state_w);
240 
keyboard_handle_enter(void * data,struct wl_keyboard * keyboard,uint32_t serial,struct wl_surface * surface,struct wl_array * keys)241 static void keyboard_handle_enter(void* data, struct wl_keyboard* keyboard, uint32_t serial,
242                                   struct wl_surface* surface, struct wl_array* keys)
243 {
244 	uint32_t *key, *pressedKey;
245 	UwacSeat* input = (UwacSeat*)data;
246 	size_t i, found;
247 	UwacKeyboardEnterLeaveEvent* event;
248 
249 	event = (UwacKeyboardEnterLeaveEvent*)UwacDisplayNewEvent(input->display,
250 	                                                          UWAC_EVENT_KEYBOARD_ENTER);
251 	if (!event)
252 		return;
253 
254 	event->window = input->keyboard_focus = (UwacWindow*)wl_surface_get_user_data(surface);
255 	event->seat = input;
256 
257 	/* look for keys that have been released */
258 	found = false;
259 	for (pressedKey = input->pressed_keys.data, i = 0; i < input->pressed_keys.size;
260 	     i += sizeof(uint32_t))
261 	{
262 		wl_array_for_each(key, keys)
263 		{
264 			if (*key == *pressedKey)
265 			{
266 				found = true;
267 				break;
268 			}
269 		}
270 
271 		if (!found)
272 		{
273 			keyboard_handle_key(data, keyboard, serial, 0, *pressedKey,
274 			                    WL_KEYBOARD_KEY_STATE_RELEASED);
275 		}
276 		else
277 		{
278 			pressedKey++;
279 		}
280 	}
281 
282 	/* handle keys that are now pressed */
283 	wl_array_for_each(key, keys)
284 	{
285 		keyboard_handle_key(data, keyboard, serial, 0, *key, WL_KEYBOARD_KEY_STATE_PRESSED);
286 	}
287 }
288 
keyboard_handle_leave(void * data,struct wl_keyboard * keyboard,uint32_t serial,struct wl_surface * surface)289 static void keyboard_handle_leave(void* data, struct wl_keyboard* keyboard, uint32_t serial,
290                                   struct wl_surface* surface)
291 {
292 	struct itimerspec its;
293 	UwacSeat* input;
294 	UwacPointerEnterLeaveEvent* event;
295 
296 	input = (UwacSeat*)data;
297 
298 	its.it_interval.tv_sec = 0;
299 	its.it_interval.tv_nsec = 0;
300 	its.it_value.tv_sec = 0;
301 	its.it_value.tv_nsec = 0;
302 	timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
303 
304 	event =
305 	    (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_LEAVE);
306 	if (!event)
307 		return;
308 
309 	event->window = input->keyboard_focus;
310 }
311 
update_key_pressed(UwacSeat * seat,uint32_t key)312 static int update_key_pressed(UwacSeat* seat, uint32_t key)
313 {
314 	uint32_t* keyPtr;
315 
316 	/* check if the key is not already pressed */
317 	wl_array_for_each(keyPtr, &seat->pressed_keys)
318 	{
319 		if (*keyPtr == key)
320 			return 1;
321 	}
322 
323 	keyPtr = wl_array_add(&seat->pressed_keys, sizeof(uint32_t));
324 	if (!keyPtr)
325 		return -1;
326 
327 	*keyPtr = key;
328 	return 0;
329 }
330 
update_key_released(UwacSeat * seat,uint32_t key)331 static int update_key_released(UwacSeat* seat, uint32_t key)
332 {
333 	uint32_t* keyPtr;
334 	size_t i, toMove;
335 	bool found = false;
336 
337 	for (i = 0, keyPtr = seat->pressed_keys.data; i < seat->pressed_keys.size; i++, keyPtr++)
338 	{
339 		if (*keyPtr == key)
340 		{
341 			found = true;
342 			break;
343 		}
344 	}
345 
346 	if (found)
347 	{
348 		toMove = seat->pressed_keys.size - ((i + 1) * sizeof(uint32_t));
349 		if (toMove)
350 			memmove(keyPtr, keyPtr + 1, toMove);
351 
352 		seat->pressed_keys.size -= sizeof(uint32_t);
353 	}
354 	return 1;
355 }
356 
keyboard_handle_key(void * data,struct wl_keyboard * keyboard,uint32_t serial,uint32_t time,uint32_t key,uint32_t state_w)357 static void keyboard_handle_key(void* data, struct wl_keyboard* keyboard, uint32_t serial,
358                                 uint32_t time, uint32_t key, uint32_t state_w)
359 {
360 	UwacSeat* input = (UwacSeat*)data;
361 	UwacWindow* window = input->keyboard_focus;
362 	UwacKeyEvent* keyEvent;
363 
364 	uint32_t code, num_syms;
365 	enum wl_keyboard_key_state state = state_w;
366 	const xkb_keysym_t* syms;
367 	xkb_keysym_t sym;
368 	struct itimerspec its;
369 
370 	if (state_w == WL_KEYBOARD_KEY_STATE_PRESSED)
371 		update_key_pressed(input, key);
372 	else
373 		update_key_released(input, key);
374 
375 	input->display->serial = serial;
376 	code = key + 8;
377 	if (!window || !input->xkb.state)
378 		return;
379 
380 	/* We only use input grabs for pointer events for now, so just
381 	 * ignore key presses if a grab is active.  We expand the key
382 	 * event delivery mechanism to route events to widgets to
383 	 * properly handle key grabs.  In the meantime, this prevents
384 	 * key event delivery while a grab is active. */
385 	/*if (input->grab && input->grab_button == 0)
386 	    return;*/
387 
388 	num_syms = xkb_state_key_get_syms(input->xkb.state, code, &syms);
389 
390 	sym = XKB_KEY_NoSymbol;
391 	if (num_syms == 1)
392 		sym = syms[0];
393 
394 	if (state == WL_KEYBOARD_KEY_STATE_RELEASED && key == input->repeat_key)
395 	{
396 		its.it_interval.tv_sec = 0;
397 		its.it_interval.tv_nsec = 0;
398 		its.it_value.tv_sec = 0;
399 		its.it_value.tv_nsec = 0;
400 		timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
401 	}
402 	else if (state == WL_KEYBOARD_KEY_STATE_PRESSED &&
403 	         xkb_keymap_key_repeats(input->xkb.keymap, code))
404 	{
405 		input->repeat_sym = sym;
406 		input->repeat_key = key;
407 		input->repeat_time = time;
408 		its.it_interval.tv_sec = input->repeat_rate_sec;
409 		its.it_interval.tv_nsec = input->repeat_rate_nsec;
410 		its.it_value.tv_sec = input->repeat_delay_sec;
411 		its.it_value.tv_nsec = input->repeat_delay_nsec;
412 		timerfd_settime(input->repeat_timer_fd, 0, &its, NULL);
413 	}
414 
415 	keyEvent = (UwacKeyEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_KEY);
416 	if (!keyEvent)
417 		return;
418 
419 	keyEvent->window = window;
420 	keyEvent->sym = sym;
421 	keyEvent->raw_key = key;
422 	keyEvent->pressed = (state == WL_KEYBOARD_KEY_STATE_PRESSED);
423 }
424 
keyboard_handle_modifiers(void * data,struct wl_keyboard * keyboard,uint32_t serial,uint32_t mods_depressed,uint32_t mods_latched,uint32_t mods_locked,uint32_t group)425 static void keyboard_handle_modifiers(void* data, struct wl_keyboard* keyboard, uint32_t serial,
426                                       uint32_t mods_depressed, uint32_t mods_latched,
427                                       uint32_t mods_locked, uint32_t group)
428 {
429 	UwacSeat* input = data;
430 	UwacKeyboardModifiersEvent* event;
431 	xkb_mod_mask_t mask;
432 
433 	/* If we're not using a keymap, then we don't handle PC-style modifiers */
434 	if (!input->xkb.keymap)
435 		return;
436 
437 	xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
438 	mask = xkb_state_serialize_mods(input->xkb.state, XKB_STATE_MODS_DEPRESSED |
439 	                                                      XKB_STATE_MODS_LATCHED |
440 	                                                      XKB_STATE_MODS_LOCKED);
441 	input->modifiers = 0;
442 	if (mask & input->xkb.control_mask)
443 		input->modifiers |= UWAC_MOD_CONTROL_MASK;
444 	if (mask & input->xkb.alt_mask)
445 		input->modifiers |= UWAC_MOD_ALT_MASK;
446 	if (mask & input->xkb.shift_mask)
447 		input->modifiers |= UWAC_MOD_SHIFT_MASK;
448 	if (mask & input->xkb.caps_mask)
449 		input->modifiers |= UWAC_MOD_CAPS_MASK;
450 	if (mask & input->xkb.num_mask)
451 		input->modifiers |= UWAC_MOD_NUM_MASK;
452 
453 	event = (UwacKeyboardModifiersEvent*)UwacDisplayNewEvent(input->display,
454 	                                                         UWAC_EVENT_KEYBOARD_MODIFIERS);
455 	if (!event)
456 		return;
457 
458 	event->modifiers = input->modifiers;
459 }
460 
set_repeat_info(UwacSeat * input,int32_t rate,int32_t delay)461 static void set_repeat_info(UwacSeat* input, int32_t rate, int32_t delay)
462 {
463 	input->repeat_rate_sec = input->repeat_rate_nsec = 0;
464 	input->repeat_delay_sec = input->repeat_delay_nsec = 0;
465 
466 	/* a rate of zero disables any repeating, regardless of the delay's
467 	 * value */
468 	if (rate == 0)
469 		return;
470 
471 	if (rate == 1)
472 		input->repeat_rate_sec = 1;
473 	else
474 		input->repeat_rate_nsec = 1000000000 / rate;
475 
476 	input->repeat_delay_sec = delay / 1000;
477 	delay -= (input->repeat_delay_sec * 1000);
478 	input->repeat_delay_nsec = delay * 1000 * 1000;
479 }
480 
keyboard_handle_repeat_info(void * data,struct wl_keyboard * keyboard,int32_t rate,int32_t delay)481 static void keyboard_handle_repeat_info(void* data, struct wl_keyboard* keyboard, int32_t rate,
482                                         int32_t delay)
483 {
484 	UwacSeat* input = data;
485 
486 	set_repeat_info(input, rate, delay);
487 }
488 
489 static const struct wl_keyboard_listener keyboard_listener = {
490 	keyboard_handle_keymap, keyboard_handle_enter,     keyboard_handle_leave,
491 	keyboard_handle_key,    keyboard_handle_modifiers, keyboard_handle_repeat_info
492 };
493 
touch_send_start_frame(UwacSeat * seat)494 static bool touch_send_start_frame(UwacSeat* seat)
495 {
496 	UwacTouchFrameBegin* ev;
497 
498 	ev = (UwacTouchFrameBegin*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_FRAME_BEGIN);
499 	if (!ev)
500 		return false;
501 
502 	seat->touch_frame_started = true;
503 	return true;
504 }
505 
touch_handle_down(void * data,struct wl_touch * wl_touch,uint32_t serial,uint32_t time,struct wl_surface * surface,int32_t id,wl_fixed_t x_w,wl_fixed_t y_w)506 static void touch_handle_down(void* data, struct wl_touch* wl_touch, uint32_t serial, uint32_t time,
507                               struct wl_surface* surface, int32_t id, wl_fixed_t x_w,
508                               wl_fixed_t y_w)
509 {
510 	UwacSeat* seat = data;
511 	UwacTouchDown* tdata;
512 
513 	seat->display->serial = serial;
514 	if (!seat->touch_frame_started && !touch_send_start_frame(seat))
515 		return;
516 
517 	tdata = (UwacTouchDown*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_DOWN);
518 	if (!tdata)
519 		return;
520 
521 	tdata->seat = seat;
522 	tdata->id = id;
523 
524 	float sx = wl_fixed_to_double(x_w);
525 	float sy = wl_fixed_to_double(y_w);
526 
527 	tdata->x = sx;
528 	tdata->y = sy;
529 
530 #if 0
531 	struct widget *widget;
532 	float sx = wl_fixed_to_double(x);
533 	float sy = wl_fixed_to_double(y);
534 
535 
536 	input->touch_focus = wl_surface_get_user_data(surface);
537 	if (!input->touch_focus) {
538 		DBG("Failed to find to touch focus for surface %p\n", (void*) surface);
539 		return;
540 	}
541 
542 	if (surface != input->touch_focus->main_surface->surface) {
543 		DBG("Ignoring input event from subsurface %p\n", (void*) surface);
544 		input->touch_focus = NULL;
545 		return;
546 	}
547 
548 	if (input->grab)
549 		widget = input->grab;
550 	else
551 		widget = window_find_widget(input->touch_focus,
552 					    wl_fixed_to_double(x),
553 					    wl_fixed_to_double(y));
554 	if (widget) {
555 		struct touch_point *tp = xmalloc(sizeof *tp);
556 		if (tp) {
557 			tp->id = id;
558 			tp->widget = widget;
559 			tp->x = sx;
560 			tp->y = sy;
561 			wl_list_insert(&input->touch_point_list, &tp->link);
562 
563 			if (widget->touch_down_handler)
564 				(*widget->touch_down_handler)(widget, input,
565 							      serial, time, id,
566 							      sx, sy,
567 							      widget->user_data);
568 		}
569 	}
570 #endif
571 }
572 
touch_handle_up(void * data,struct wl_touch * wl_touch,uint32_t serial,uint32_t time,int32_t id)573 static void touch_handle_up(void* data, struct wl_touch* wl_touch, uint32_t serial, uint32_t time,
574                             int32_t id)
575 {
576 	UwacSeat* seat = data;
577 	UwacTouchUp* tdata;
578 
579 	if (!seat->touch_frame_started && !touch_send_start_frame(seat))
580 		return;
581 
582 	tdata = (UwacTouchUp*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_UP);
583 	if (!tdata)
584 		return;
585 
586 	tdata->seat = seat;
587 	tdata->id = id;
588 
589 #if 0
590 	struct touch_point *tp, *tmp;
591 
592 	if (!input->touch_focus) {
593 		DBG("No touch focus found for touch up event!\n");
594 		return;
595 	}
596 
597 	wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
598 		if (tp->id != id)
599 			continue;
600 
601 		if (tp->widget->touch_up_handler)
602 			(*tp->widget->touch_up_handler)(tp->widget, input, serial,
603 							time, id,
604 							tp->widget->user_data);
605 
606 		wl_list_remove(&tp->link);
607 		free(tp);
608 
609 		return;
610 	}
611 #endif
612 }
613 
touch_handle_motion(void * data,struct wl_touch * wl_touch,uint32_t time,int32_t id,wl_fixed_t x_w,wl_fixed_t y_w)614 static void touch_handle_motion(void* data, struct wl_touch* wl_touch, uint32_t time, int32_t id,
615                                 wl_fixed_t x_w, wl_fixed_t y_w)
616 {
617 	UwacSeat* seat = data;
618 	UwacTouchMotion* tdata;
619 
620 	if (!seat->touch_frame_started && !touch_send_start_frame(seat))
621 		return;
622 
623 	tdata = (UwacTouchMotion*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_MOTION);
624 	if (!tdata)
625 		return;
626 
627 	tdata->seat = seat;
628 	tdata->id = id;
629 
630 	float sx = wl_fixed_to_double(x_w);
631 	float sy = wl_fixed_to_double(y_w);
632 
633 	tdata->x = sx;
634 	tdata->y = sy;
635 
636 #if 0
637 	struct touch_point *tp;
638 	float sx = wl_fixed_to_double(x);
639 	float sy = wl_fixed_to_double(y);
640 
641 	DBG("touch_handle_motion: %i %i\n", id, wl_list_length(&seat->touch_point_list));
642 
643 	if (!seat->touch_focus) {
644 		DBG("No touch focus found for touch motion event!\n");
645 		return;
646 	}
647 
648 	wl_list_for_each(tp, &seat->touch_point_list, link) {
649 		if (tp->id != id)
650 			continue;
651 
652 		tp->x = sx;
653 		tp->y = sy;
654 		if (tp->widget->touch_motion_handler)
655 			(*tp->widget->touch_motion_handler)(tp->widget, seat, time,
656 							    id, sx, sy,
657 							    tp->widget->user_data);
658 		return;
659 	}
660 #endif
661 }
662 
touch_handle_frame(void * data,struct wl_touch * wl_touch)663 static void touch_handle_frame(void* data, struct wl_touch* wl_touch)
664 {
665 	UwacSeat* seat = data;
666 	UwacTouchFrameEnd* ev;
667 
668 	ev = (UwacTouchFrameEnd*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_FRAME_END);
669 	if (!ev)
670 		return;
671 
672 	ev->seat = seat;
673 	seat->touch_frame_started = false;
674 }
675 
touch_handle_cancel(void * data,struct wl_touch * wl_touch)676 static void touch_handle_cancel(void* data, struct wl_touch* wl_touch)
677 {
678 	UwacSeat* seat = data;
679 	UwacTouchCancel* ev;
680 
681 	ev = (UwacTouchCancel*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_TOUCH_CANCEL);
682 	if (!ev)
683 		return;
684 
685 	ev->seat = seat;
686 	seat->touch_frame_started = false;
687 
688 #if 0
689 	struct touch_point *tp, *tmp;
690 
691 	DBG("touch_handle_cancel\n");
692 
693 	if (!input->touch_focus) {
694 		DBG("No touch focus found for touch cancel event!\n");
695 		return;
696 	}
697 
698 	wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
699 		if (tp->widget->touch_cancel_handler)
700 			(*tp->widget->touch_cancel_handler)(tp->widget, input,
701 							    tp->widget->user_data);
702 
703 		wl_list_remove(&tp->link);
704 		free(tp);
705 	}
706 #endif
707 }
708 
709 static const struct wl_touch_listener touch_listener = { touch_handle_down,
710 	                                                     touch_handle_up,
711 	                                                     touch_handle_motion,
712 	                                                     touch_handle_frame,
713 	                                                     touch_handle_cancel,
714 	                                                     NULL,
715 	                                                     NULL };
716 
pointer_handle_enter(void * data,struct wl_pointer * pointer,uint32_t serial,struct wl_surface * surface,wl_fixed_t sx_w,wl_fixed_t sy_w)717 static void pointer_handle_enter(void* data, struct wl_pointer* pointer, uint32_t serial,
718                                  struct wl_surface* surface, wl_fixed_t sx_w, wl_fixed_t sy_w)
719 {
720 	UwacSeat* input = data;
721 	UwacWindow* window;
722 	UwacPointerEnterLeaveEvent* event;
723 
724 	float sx = wl_fixed_to_double(sx_w);
725 	float sy = wl_fixed_to_double(sy_w);
726 
727 	if (!surface)
728 	{
729 		/* enter event for a window we've just destroyed */
730 		return;
731 	}
732 
733 	input->display->serial = serial;
734 	window = wl_surface_get_user_data(surface);
735 	if (window)
736 		window->pointer_enter_serial = serial;
737 	input->pointer_focus = window;
738 	input->sx = sx;
739 	input->sy = sy;
740 
741 	event =
742 	    (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_ENTER);
743 	if (!event)
744 		return;
745 
746 	event->seat = input;
747 	event->window = window;
748 	event->x = sx;
749 	event->y = sy;
750 
751 	/* Apply cursor theme */
752 	set_cursor_image(input, serial);
753 }
754 
pointer_handle_leave(void * data,struct wl_pointer * pointer,uint32_t serial,struct wl_surface * surface)755 static void pointer_handle_leave(void* data, struct wl_pointer* pointer, uint32_t serial,
756                                  struct wl_surface* surface)
757 {
758 	UwacPointerEnterLeaveEvent* event;
759 	UwacWindow* window;
760 	UwacSeat* input = data;
761 
762 	input->display->serial = serial;
763 
764 	event =
765 	    (UwacPointerEnterLeaveEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_LEAVE);
766 	if (!event)
767 		return;
768 
769 	window = wl_surface_get_user_data(surface);
770 
771 	event->seat = input;
772 	event->window = window;
773 }
774 
pointer_handle_motion(void * data,struct wl_pointer * pointer,uint32_t time,wl_fixed_t sx_w,wl_fixed_t sy_w)775 static void pointer_handle_motion(void* data, struct wl_pointer* pointer, uint32_t time,
776                                   wl_fixed_t sx_w, wl_fixed_t sy_w)
777 {
778 	UwacPointerMotionEvent* motion_event;
779 	UwacSeat* input = data;
780 	UwacWindow* window = input->pointer_focus;
781 
782 	float sx = wl_fixed_to_double(sx_w);
783 	float sy = wl_fixed_to_double(sy_w);
784 
785 	if (!window)
786 		return;
787 
788 	input->sx = sx;
789 	input->sy = sy;
790 
791 	motion_event =
792 	    (UwacPointerMotionEvent*)UwacDisplayNewEvent(input->display, UWAC_EVENT_POINTER_MOTION);
793 	if (!motion_event)
794 		return;
795 
796 	motion_event->seat = input;
797 	motion_event->window = window;
798 	motion_event->x = wl_fixed_to_int(sx_w);
799 	motion_event->y = wl_fixed_to_int(sy_w);
800 }
801 
pointer_handle_button(void * data,struct wl_pointer * pointer,uint32_t serial,uint32_t time,uint32_t button,uint32_t state_w)802 static void pointer_handle_button(void* data, struct wl_pointer* pointer, uint32_t serial,
803                                   uint32_t time, uint32_t button, uint32_t state_w)
804 {
805 	UwacPointerButtonEvent* event;
806 	UwacSeat* seat = data;
807 	UwacWindow* window = seat->pointer_focus;
808 
809 	seat->display->serial = serial;
810 
811 	event = (UwacPointerButtonEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_BUTTONS);
812 	if (!event)
813 		return;
814 
815 	event->seat = seat;
816 	event->window = window;
817 	event->x = seat->sx;
818 	event->y = seat->sy;
819 	event->button = button;
820 	event->state = (enum wl_pointer_button_state)state_w;
821 }
822 
pointer_handle_axis(void * data,struct wl_pointer * pointer,uint32_t time,uint32_t axis,wl_fixed_t value)823 static void pointer_handle_axis(void* data, struct wl_pointer* pointer, uint32_t time,
824                                 uint32_t axis, wl_fixed_t value)
825 {
826 	UwacPointerAxisEvent* event;
827 	UwacSeat* seat = data;
828 	UwacWindow* window = seat->pointer_focus;
829 
830 	if (!window)
831 		return;
832 
833 	event = (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS);
834 	if (!event)
835 		return;
836 
837 	event->seat = seat;
838 	event->window = window;
839 	event->x = seat->sx;
840 	event->y = seat->sy;
841 	event->axis = axis;
842 	event->value = value;
843 }
844 
pointer_frame(void * data,struct wl_pointer * wl_pointer)845 static void pointer_frame(void* data, struct wl_pointer* wl_pointer)
846 {
847 	/*UwacSeat *seat = data;*/
848 }
849 
pointer_axis_source(void * data,struct wl_pointer * wl_pointer,uint32_t axis_source)850 static void pointer_axis_source(void* data, struct wl_pointer* wl_pointer, uint32_t axis_source)
851 {
852 	/*UwacSeat *seat = data;*/
853 }
854 
pointer_axis_stop(void * data,struct wl_pointer * wl_pointer,uint32_t time,uint32_t axis)855 static void pointer_axis_stop(void* data, struct wl_pointer* wl_pointer, uint32_t time,
856                               uint32_t axis)
857 {
858 	/*UwacSeat *seat = data;*/
859 }
860 
pointer_axis_discrete(void * data,struct wl_pointer * wl_pointer,uint32_t axis,int32_t discrete)861 static void pointer_axis_discrete(void* data, struct wl_pointer* wl_pointer, uint32_t axis,
862                                   int32_t discrete)
863 {
864 	/*UwacSeat *seat = data;*/
865 	UwacPointerAxisEvent* event;
866 	UwacSeat* seat = data;
867 	UwacWindow* window = seat->pointer_focus;
868 
869 	if (!window)
870 		return;
871 
872 	event =
873 	    (UwacPointerAxisEvent*)UwacDisplayNewEvent(seat->display, UWAC_EVENT_POINTER_AXIS_DISCRETE);
874 	if (!event)
875 		return;
876 
877 	event->seat = seat;
878 	event->window = window;
879 	event->x = seat->sx;
880 	event->y = seat->sy;
881 	event->axis = axis;
882 	event->value = discrete;
883 }
884 
885 static const struct wl_pointer_listener pointer_listener = {
886 	pointer_handle_enter,  pointer_handle_leave, pointer_handle_motion,
887 	pointer_handle_button, pointer_handle_axis,  pointer_frame,
888 	pointer_axis_source,   pointer_axis_stop,    pointer_axis_discrete,
889 };
890 
seat_handle_capabilities(void * data,struct wl_seat * seat,enum wl_seat_capability caps)891 static void seat_handle_capabilities(void* data, struct wl_seat* seat, enum wl_seat_capability caps)
892 {
893 	UwacSeat* input = data;
894 
895 	if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer)
896 	{
897 		input->pointer = wl_seat_get_pointer(seat);
898 		wl_pointer_set_user_data(input->pointer, input);
899 		wl_pointer_add_listener(input->pointer, &pointer_listener, input);
900 
901 		input->cursor_theme = wl_cursor_theme_load(NULL, 32, input->display->shm);
902 		if (!input->cursor_theme)
903 		{
904 			assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
905 			                        "unable to get wayland cursor theme\n"));
906 			return;
907 		}
908 
909 		input->default_cursor = wl_cursor_theme_get_cursor(input->cursor_theme, "left_ptr");
910 		if (!input->default_cursor)
911 		{
912 			assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
913 			                        "unable to get wayland cursor left_ptr\n"));
914 			return;
915 		}
916 	}
917 	else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer)
918 	{
919 #ifdef WL_POINTER_RELEASE_SINCE_VERSION
920 		if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
921 			wl_pointer_release(input->pointer);
922 		else
923 #endif
924 			wl_pointer_destroy(input->pointer);
925 		if (input->cursor_theme)
926 			wl_cursor_theme_destroy(input->cursor_theme);
927 
928 		input->default_cursor = NULL;
929 		input->cursor_theme = NULL;
930 		input->pointer = NULL;
931 	}
932 
933 	if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard)
934 	{
935 		input->keyboard = wl_seat_get_keyboard(seat);
936 		wl_keyboard_set_user_data(input->keyboard, input);
937 		wl_keyboard_add_listener(input->keyboard, &keyboard_listener, input);
938 	}
939 	else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard)
940 	{
941 #ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
942 		if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
943 			wl_keyboard_release(input->keyboard);
944 		else
945 #endif
946 			wl_keyboard_destroy(input->keyboard);
947 		input->keyboard = NULL;
948 	}
949 
950 	if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch)
951 	{
952 		input->touch = wl_seat_get_touch(seat);
953 		wl_touch_set_user_data(input->touch, input);
954 		wl_touch_add_listener(input->touch, &touch_listener, input);
955 	}
956 	else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch)
957 	{
958 #ifdef WL_TOUCH_RELEASE_SINCE_VERSION
959 		if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
960 			wl_touch_release(input->touch);
961 		else
962 #endif
963 			wl_touch_destroy(input->touch);
964 		input->touch = NULL;
965 	}
966 }
967 
seat_handle_name(void * data,struct wl_seat * seat,const char * name)968 static void seat_handle_name(void* data, struct wl_seat* seat, const char* name)
969 {
970 	UwacSeat* input = data;
971 	if (input->name)
972 		free(input->name);
973 
974 	input->name = strdup(name);
975 	if (!input->name)
976 		assert(uwacErrorHandler(input->display, UWAC_ERROR_NOMEMORY,
977 		                        "unable to strdup seat's name\n"));
978 }
979 
980 static const struct wl_seat_listener seat_listener = {
981 	seat_handle_capabilities,
982 	seat_handle_name,
983 };
984 
UwacSeatNew(UwacDisplay * d,uint32_t id,uint32_t version)985 UwacSeat* UwacSeatNew(UwacDisplay* d, uint32_t id, uint32_t version)
986 {
987 	UwacSeat* ret;
988 
989 	ret = xzalloc(sizeof(UwacSeat));
990 	ret->display = d;
991 	ret->seat_id = id;
992 	ret->seat_version = version;
993 
994 	wl_array_init(&ret->pressed_keys);
995 	ret->xkb_context = xkb_context_new(0);
996 	if (!ret->xkb_context)
997 	{
998 		fprintf(stderr, "%s: unable to allocate a xkb_context\n", __FUNCTION__);
999 		goto error_xkb_context;
1000 	}
1001 
1002 	ret->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, version);
1003 	wl_seat_add_listener(ret->seat, &seat_listener, ret);
1004 	wl_seat_set_user_data(ret->seat, ret);
1005 
1006 	ret->repeat_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
1007 	if (ret->repeat_timer_fd < 0)
1008 	{
1009 		fprintf(stderr, "%s: error creating repeat timer\n", __FUNCTION__);
1010 		goto error_timer_fd;
1011 	}
1012 	ret->repeat_task.run = keyboard_repeat_func;
1013 	if (UwacDisplayWatchFd(d, ret->repeat_timer_fd, EPOLLIN, &ret->repeat_task) < 0)
1014 	{
1015 		fprintf(stderr, "%s: error polling repeat timer\n", __FUNCTION__);
1016 		goto error_watch_timerfd;
1017 	}
1018 
1019 	wl_list_insert(d->seats.prev, &ret->link);
1020 	return ret;
1021 
1022 error_watch_timerfd:
1023 	close(ret->repeat_timer_fd);
1024 error_timer_fd:
1025 	wl_seat_destroy(ret->seat);
1026 error_xkb_context:
1027 	free(ret);
1028 	return NULL;
1029 }
1030 
UwacSeatDestroy(UwacSeat * s)1031 void UwacSeatDestroy(UwacSeat* s)
1032 {
1033 	UwacSeatInhibitShortcuts(s, false);
1034 	if (s->seat)
1035 	{
1036 #ifdef WL_SEAT_RELEASE_SINCE_VERSION
1037 		if (s->seat_version >= WL_SEAT_RELEASE_SINCE_VERSION)
1038 			wl_seat_release(s->seat);
1039 		else
1040 #endif
1041 			wl_seat_destroy(s->seat);
1042 	}
1043 	s->seat = NULL;
1044 
1045 	free(s->name);
1046 	wl_array_release(&s->pressed_keys);
1047 
1048 	xkb_state_unref(s->xkb.state);
1049 	xkb_context_unref(s->xkb_context);
1050 
1051 	if (s->pointer)
1052 	{
1053 #ifdef WL_POINTER_RELEASE_SINCE_VERSION
1054 		if (s->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
1055 			wl_pointer_release(s->pointer);
1056 		else
1057 #endif
1058 			wl_pointer_destroy(s->pointer);
1059 	}
1060 
1061 	if (s->touch)
1062 	{
1063 #ifdef WL_TOUCH_RELEASE_SINCE_VERSION
1064 		if (s->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
1065 			wl_touch_release(s->touch);
1066 		else
1067 #endif
1068 			wl_touch_destroy(s->touch);
1069 	}
1070 
1071 	if (s->keyboard)
1072 	{
1073 #ifdef WL_KEYBOARD_RELEASE_SINCE_VERSION
1074 		if (s->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
1075 			wl_keyboard_release(s->keyboard);
1076 		else
1077 #endif
1078 			wl_keyboard_destroy(s->keyboard);
1079 	}
1080 
1081 	if (s->data_device)
1082 		wl_data_device_destroy(s->data_device);
1083 
1084 	if (s->data_source)
1085 		wl_data_source_destroy(s->data_source);
1086 
1087 	if (s->pointer_surface)
1088 		wl_surface_destroy(s->pointer_surface);
1089 
1090 	free(s->pointer_image);
1091 	free(s->pointer_data);
1092 
1093 	wl_list_remove(&s->link);
1094 	free(s);
1095 }
1096 
UwacSeatGetName(const UwacSeat * seat)1097 const char* UwacSeatGetName(const UwacSeat* seat)
1098 {
1099 	return seat->name;
1100 }
1101 
UwacSeatGetId(const UwacSeat * seat)1102 UwacSeatId UwacSeatGetId(const UwacSeat* seat)
1103 {
1104 	return seat->seat_id;
1105 }
1106 
UwacSeatInhibitShortcuts(UwacSeat * s,bool inhibit)1107 UwacReturnCode UwacSeatInhibitShortcuts(UwacSeat* s, bool inhibit)
1108 {
1109 	if (!s)
1110 		return UWAC_ERROR_CLOSED;
1111 
1112 	if (s->keyboard_inhibitor)
1113 		zwp_keyboard_shortcuts_inhibitor_v1_destroy(s->keyboard_inhibitor);
1114 	if (inhibit && s->display && s->display->keyboard_inhibit_manager)
1115 		s->keyboard_inhibitor = zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(
1116 		    s->display->keyboard_inhibit_manager, s->keyboard_focus->surface, s->seat);
1117 
1118 	if (!s->keyboard_inhibitor)
1119 		return UWAC_ERROR_INTERNAL;
1120 	return UWAC_SUCCESS;
1121 }
1122 
UwacSeatSetMouseCursor(UwacSeat * seat,const void * data,size_t length,size_t width,size_t height,size_t hot_x,size_t hot_y)1123 UwacReturnCode UwacSeatSetMouseCursor(UwacSeat* seat, const void* data, size_t length, size_t width,
1124                                       size_t height, size_t hot_x, size_t hot_y)
1125 {
1126 	if (!seat)
1127 		return UWAC_ERROR_CLOSED;
1128 
1129 	free(seat->pointer_image);
1130 	seat->pointer_image = NULL;
1131 
1132 	free(seat->pointer_data);
1133 	seat->pointer_data = NULL;
1134 	seat->pointer_size = 0;
1135 
1136 	/* There is a cursor provided */
1137 	if ((data != NULL) && (length != 0))
1138 	{
1139 		seat->pointer_image = xzalloc(sizeof(struct wl_cursor_image));
1140 		if (!seat->pointer_image)
1141 			return UWAC_ERROR_NOMEMORY;
1142 		seat->pointer_image->width = width;
1143 		seat->pointer_image->height = height;
1144 		seat->pointer_image->hotspot_x = hot_x;
1145 		seat->pointer_image->hotspot_y = hot_y;
1146 
1147 		free(seat->pointer_data);
1148 		seat->pointer_data = xmalloc(length);
1149 		memcpy(seat->pointer_data, data, length);
1150 		seat->pointer_size = length;
1151 
1152 		seat->pointer_type = 2;
1153 	}
1154 	/* We want to use the system cursor */
1155 	else if (length != 0)
1156 	{
1157 		seat->pointer_type = 0;
1158 	}
1159 	/* Hide the cursor */
1160 	else
1161 	{
1162 		seat->pointer_type = 1;
1163 	}
1164 	return set_cursor_image(seat, seat->display->serial);
1165 }
1166