pointer_set(struct wl_client * cl,struct wl_resource * res,uint32_t serial,struct wl_resource * surf_res,int32_t hot_x,int32_t hot_y)1 static void pointer_set(struct wl_client* cl, struct wl_resource* res,
2 	uint32_t serial, struct wl_resource* surf_res, int32_t hot_x, int32_t hot_y)
3 {
4 	trace(TRACE_SEAT, "cursor_set(%"PRIxPTR")", (uintptr_t)surf_res);
5 	struct seat* seat = wl_resource_get_user_data(res);
6 	struct bridge_client* bcl = find_client(cl);
7 
8 	bcl->cursor = surf_res;
9 
10 	if (bcl->hot_x != hot_x || bcl->hot_y != hot_y){
11 		trace(TRACE_SEAT, "hotspot:old=%d,%d:new=%d,%d",
12 			(int) bcl->hot_x, (int) bcl->hot_y, (int) hot_x, (int) hot_y);
13 		bcl->dirty_hot = true;
14 		bcl->hot_x = hot_x;
15 		bcl->hot_y = hot_y;
16 	}
17 
18 /* switch out who is responsible for events on the surface this round, this is
19  * important as it breaks the 0..1 mapping between comp_surf and acon (realloc
20  * on cursor each switch is too expensive) */
21 	struct acon_tag* tag = bcl->acursor.user;
22 	if (!tag){
23 		trace(TRACE_ALLOC, "error:unassigned pointer");
24 		return;
25 	}
26 
27 	if (surf_res){
28 		struct comp_surf* csurf = wl_resource_get_user_data(surf_res);
29 		snprintf(csurf->tracetag, SURF_TAGLEN, "cursor");
30 		csurf->rcon = &bcl->acursor;
31 		wl.groups[tag->group].slots[tag->slot].surface = csurf;
32 	}
33 /* set a 0-alpha buffer? */
34 	else {
35 		wl.groups[tag->group].slots[tag->slot].surface = NULL;
36 	}
37 }
38 
pointer_release(struct wl_client * cl,struct wl_resource * res)39 static void pointer_release(struct wl_client* cl, struct wl_resource* res)
40 {
41 	trace(TRACE_SEAT, "cursor_release");
42 	struct seat* seat = wl_resource_get_user_data(res);
43 	struct bridge_client* bcl = find_client(cl);
44 	seat->ptr = NULL;
45 	wl_resource_destroy(res);
46 }
47 
48 struct wl_pointer_interface pointer_if = {
49 	.set_cursor = pointer_set,
50 	.release = pointer_release
51 };
52 
seat_pointer(struct wl_client * cl,struct wl_resource * res,uint32_t id)53 static void seat_pointer(
54 	struct wl_client* cl,	struct wl_resource* res, uint32_t id)
55 {
56 	trace(TRACE_SEAT, "seat_pointer(%"PRIu32")", id);
57 	struct seat* seat = wl_resource_get_user_data(res);
58 
59 	struct wl_resource* ptr = wl_resource_create(
60 			cl, &wl_pointer_interface, wl_resource_get_version(res), id);
61 
62 	if (!ptr){
63 		wl_resource_post_no_memory(res);
64 		return;
65 	}
66 
67 	wl_resource_set_implementation(ptr, &pointer_if, seat, NULL);
68 	seat->ptr = ptr;
69 }
70 
kbd_release(struct wl_client * client,struct wl_resource * res)71 static void kbd_release(struct wl_client* client, struct wl_resource* res)
72 {
73 	trace(TRACE_SEAT, "kbd release");
74 
75 	struct seat* seat = wl_resource_get_user_data(res);
76 	seat->kbd = NULL;
77 	wl_resource_destroy(res);
78 }
79 
80 struct wl_keyboard_interface kbd_if = {
81 	.release = kbd_release
82 };
83 
seat_keyboard(struct wl_client * cl,struct wl_resource * res,uint32_t id)84 static void seat_keyboard(
85 	struct wl_client* cl, struct wl_resource* res, uint32_t id)
86 {
87 	trace(TRACE_SEAT, "seat_keyboard(%"PRIu32")", id);
88 	struct seat* seat = wl_resource_get_user_data(res);
89 
90 	struct wl_resource* kbd = wl_resource_create(cl,
91 		&wl_keyboard_interface, wl_resource_get_version(res), id);
92 
93 	if (!kbd){
94 		wl_resource_post_no_memory(res);
95 		return;
96 	}
97 
98 	size_t sz;
99 	int fd;
100 	int fmt;
101 	if (!waybridge_instance_keymap(seat, &fd, &fmt, &sz)){
102 		wl_resource_post_no_memory(res);
103 		wl_resource_destroy(res);
104 		return;
105 	}
106 
107 	seat->kbd = kbd;
108 	wl_resource_set_implementation(kbd, &kbd_if, seat, NULL);
109 
110 	if (wl_resource_get_version(kbd) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
111 		wl_keyboard_send_repeat_info(kbd, 25, 600);
112 
113 	wl_keyboard_send_keymap(seat->kbd, fmt, fd, sz);
114 }
115 
seat_touch(struct wl_client * cl,struct wl_resource * res,uint32_t id)116 static void seat_touch(
117 	struct wl_client* cl, struct wl_resource* res, uint32_t id)
118 {
119 	trace(TRACE_SEAT, "seat_touch(%"PRIu32")", id);
120 }
121 
seat_release(struct wl_client * cl,struct wl_resource * res)122 static void seat_release(
123 	struct wl_client* cl, struct wl_resource* res)
124 {
125 	trace(TRACE_SEAT, "seat_release");
126 	struct seat* seat = wl_resource_get_user_data(res);
127 	seat->used = false;
128 }
129