1 #include <stdlib.h>
2 
3 #include <wlr/config.h>
4 
5 #include <linux/input-event-codes.h>
6 
7 #include <xcb/xcb.h>
8 #include <xcb/xfixes.h>
9 #include <xcb/xinput.h>
10 
11 #include <wlr/interfaces/wlr_input_device.h>
12 #include <wlr/interfaces/wlr_keyboard.h>
13 #include <wlr/interfaces/wlr_pointer.h>
14 #include <wlr/interfaces/wlr_touch.h>
15 #include <wlr/util/log.h>
16 
17 #include "backend/x11.h"
18 #include "util/signal.h"
19 
send_key_event(struct wlr_x11_backend * x11,uint32_t key,enum wlr_key_state st,xcb_timestamp_t time)20 static void send_key_event(struct wlr_x11_backend *x11, uint32_t key,
21 		enum wlr_key_state st, xcb_timestamp_t time) {
22 	struct wlr_event_keyboard_key ev = {
23 		.time_msec = time,
24 		.keycode = key,
25 		.state = st,
26 		.update_state = true,
27 	};
28 	wlr_keyboard_notify_key(&x11->keyboard, &ev);
29 }
30 
send_button_event(struct wlr_x11_output * output,uint32_t key,enum wlr_button_state st,xcb_timestamp_t time)31 static void send_button_event(struct wlr_x11_output *output, uint32_t key,
32 		enum wlr_button_state st, xcb_timestamp_t time) {
33 	struct wlr_event_pointer_button ev = {
34 		.device = &output->pointer_dev,
35 		.time_msec = time,
36 		.button = key,
37 		.state = st,
38 	};
39 	wlr_signal_emit_safe(&output->pointer.events.button, &ev);
40 	wlr_signal_emit_safe(&output->pointer.events.frame, &output->pointer);
41 }
42 
send_axis_event(struct wlr_x11_output * output,int32_t delta,xcb_timestamp_t time)43 static void send_axis_event(struct wlr_x11_output *output, int32_t delta,
44 		xcb_timestamp_t time) {
45 	struct wlr_event_pointer_axis ev = {
46 		.device = &output->pointer_dev,
47 		.time_msec = time,
48 		.source = WLR_AXIS_SOURCE_WHEEL,
49 		.orientation = WLR_AXIS_ORIENTATION_VERTICAL,
50 		// 15 is a typical value libinput sends for one scroll
51 		.delta = delta * 15,
52 		.delta_discrete = delta,
53 	};
54 	wlr_signal_emit_safe(&output->pointer.events.axis, &ev);
55 	wlr_signal_emit_safe(&output->pointer.events.frame, &output->pointer);
56 }
57 
send_pointer_position_event(struct wlr_x11_output * output,int16_t x,int16_t y,xcb_timestamp_t time)58 static void send_pointer_position_event(struct wlr_x11_output *output,
59 		int16_t x, int16_t y, xcb_timestamp_t time) {
60 	struct wlr_event_pointer_motion_absolute ev = {
61 		.device = &output->pointer_dev,
62 		.time_msec = time,
63 		.x = (double)x / output->wlr_output.width,
64 		.y = (double)y / output->wlr_output.height,
65 	};
66 	wlr_signal_emit_safe(&output->pointer.events.motion_absolute, &ev);
67 	wlr_signal_emit_safe(&output->pointer.events.frame, &output->pointer);
68 }
69 
send_touch_down_event(struct wlr_x11_output * output,int16_t x,int16_t y,int32_t touch_id,xcb_timestamp_t time)70 static void send_touch_down_event(struct wlr_x11_output *output,
71 		int16_t x, int16_t y, int32_t touch_id, xcb_timestamp_t time) {
72 	struct wlr_event_touch_down ev = {
73 		.device = &output->touch_dev,
74 		.time_msec = time,
75 		.x = (double)x / output->wlr_output.width,
76 		.y = (double)y / output->wlr_output.height,
77 		.touch_id = touch_id,
78 	};
79 	wlr_signal_emit_safe(&output->touch.events.down, &ev);
80 }
81 
send_touch_motion_event(struct wlr_x11_output * output,int16_t x,int16_t y,int32_t touch_id,xcb_timestamp_t time)82 static void send_touch_motion_event(struct wlr_x11_output *output,
83 		int16_t x, int16_t y, int32_t touch_id, xcb_timestamp_t time) {
84 	struct wlr_event_touch_motion ev = {
85 		.device = &output->touch_dev,
86 		.time_msec = time,
87 		.x = (double)x / output->wlr_output.width,
88 		.y = (double)y / output->wlr_output.height,
89 		.touch_id = touch_id,
90 	};
91 	wlr_signal_emit_safe(&output->touch.events.motion, &ev);
92 }
93 
send_touch_up_event(struct wlr_x11_output * output,int32_t touch_id,xcb_timestamp_t time)94 static void send_touch_up_event(struct wlr_x11_output *output,
95 		int32_t touch_id, xcb_timestamp_t time) {
96 	struct wlr_event_touch_up ev = {
97 		.device = &output->touch_dev,
98 		.time_msec = time,
99 		.touch_id = touch_id,
100 	};
101 	wlr_signal_emit_safe(&output->touch.events.up, &ev);
102 }
103 
get_touchpoint_from_x11_touch_id(struct wlr_x11_output * output,uint32_t id)104 static struct wlr_x11_touchpoint* get_touchpoint_from_x11_touch_id(struct wlr_x11_output *output,
105 		uint32_t id) {
106 	struct wlr_x11_touchpoint *touchpoint;
107 	wl_list_for_each(touchpoint, &output->touchpoints, link) {
108 		if (touchpoint->x11_id == id) {
109 			return touchpoint;
110 		}
111 	}
112 	return NULL;
113 }
114 
handle_x11_xinput_event(struct wlr_x11_backend * x11,xcb_ge_generic_event_t * event)115 void handle_x11_xinput_event(struct wlr_x11_backend *x11,
116 		xcb_ge_generic_event_t *event) {
117 	struct wlr_x11_output *output;
118 
119 	switch (event->event_type) {
120 	case XCB_INPUT_KEY_PRESS: {
121 		xcb_input_key_press_event_t *ev =
122 			(xcb_input_key_press_event_t *)event;
123 
124 		wlr_keyboard_notify_modifiers(&x11->keyboard, ev->mods.base,
125 			ev->mods.latched, ev->mods.locked, ev->mods.effective);
126 		send_key_event(x11, ev->detail - 8, WLR_KEY_PRESSED, ev->time);
127 		x11->time = ev->time;
128 		break;
129 	}
130 	case XCB_INPUT_KEY_RELEASE: {
131 		xcb_input_key_release_event_t *ev =
132 			(xcb_input_key_release_event_t *)event;
133 
134 		wlr_keyboard_notify_modifiers(&x11->keyboard, ev->mods.base,
135 			ev->mods.latched, ev->mods.locked, ev->mods.effective);
136 		send_key_event(x11, ev->detail - 8, WLR_KEY_RELEASED, ev->time);
137 		x11->time = ev->time;
138 		break;
139 	}
140 	case XCB_INPUT_BUTTON_PRESS: {
141 		xcb_input_button_press_event_t *ev =
142 			(xcb_input_button_press_event_t *)event;
143 
144 		output = get_x11_output_from_window_id(x11, ev->event);
145 		if (!output) {
146 			return;
147 		}
148 
149 		switch (ev->detail) {
150 		case XCB_BUTTON_INDEX_1:
151 			send_button_event(output, BTN_LEFT, WLR_BUTTON_PRESSED,
152 				ev->time);
153 			break;
154 		case XCB_BUTTON_INDEX_2:
155 			send_button_event(output, BTN_MIDDLE, WLR_BUTTON_PRESSED,
156 				ev->time);
157 			break;
158 		case XCB_BUTTON_INDEX_3:
159 			send_button_event(output, BTN_RIGHT, WLR_BUTTON_PRESSED,
160 				ev->time);
161 			break;
162 		case XCB_BUTTON_INDEX_4:
163 			send_axis_event(output, -1, ev->time);
164 			break;
165 		case XCB_BUTTON_INDEX_5:
166 			send_axis_event(output, 1, ev->time);
167 			break;
168 		}
169 
170 		x11->time = ev->time;
171 		break;
172 	}
173 	case XCB_INPUT_BUTTON_RELEASE: {
174 		xcb_input_button_release_event_t *ev =
175 			(xcb_input_button_release_event_t *)event;
176 
177 		output = get_x11_output_from_window_id(x11, ev->event);
178 		if (!output) {
179 			return;
180 		}
181 
182 		switch (ev->detail) {
183 		case XCB_BUTTON_INDEX_1:
184 			send_button_event(output, BTN_LEFT, WLR_BUTTON_RELEASED,
185 				ev->time);
186 			break;
187 		case XCB_BUTTON_INDEX_2:
188 			send_button_event(output, BTN_MIDDLE, WLR_BUTTON_RELEASED,
189 				ev->time);
190 			break;
191 		case XCB_BUTTON_INDEX_3:
192 			send_button_event(output, BTN_RIGHT, WLR_BUTTON_RELEASED,
193 				ev->time);
194 			break;
195 		}
196 
197 		x11->time = ev->time;
198 		break;
199 	}
200 	case XCB_INPUT_MOTION: {
201 		xcb_input_motion_event_t *ev = (xcb_input_motion_event_t *)event;
202 
203 		output = get_x11_output_from_window_id(x11, ev->event);
204 		if (!output) {
205 			return;
206 		}
207 
208 		send_pointer_position_event(output, ev->event_x >> 16,
209 			ev->event_y >> 16, ev->time);
210 		x11->time = ev->time;
211 		break;
212 	}
213 	case XCB_INPUT_ENTER: {
214 		xcb_input_enter_event_t *ev = (xcb_input_enter_event_t *)event;
215 
216 		output = get_x11_output_from_window_id(x11, ev->event);
217 		if (!output) {
218 			return;
219 		}
220 
221 		if (!output->cursor_hidden) {
222 			xcb_xfixes_hide_cursor(x11->xcb, output->win);
223 			xcb_flush(x11->xcb);
224 			output->cursor_hidden = true;
225 		}
226 		break;
227 	}
228 	case XCB_INPUT_LEAVE: {
229 		xcb_input_leave_event_t *ev = (xcb_input_leave_event_t *)event;
230 
231 		output = get_x11_output_from_window_id(x11, ev->event);
232 		if (!output) {
233 			return;
234 		}
235 
236 		if (output->cursor_hidden) {
237 			xcb_xfixes_show_cursor(x11->xcb, output->win);
238 			xcb_flush(x11->xcb);
239 			output->cursor_hidden = false;
240 		}
241 		break;
242 	}
243 	case XCB_INPUT_TOUCH_BEGIN: {
244 		xcb_input_touch_begin_event_t *ev = (xcb_input_touch_begin_event_t *)event;
245 
246 		output = get_x11_output_from_window_id(x11, ev->event);
247 		if (!output) {
248 			return;
249 		}
250 
251 		int32_t id = 0;
252 		if (!wl_list_empty(&output->touchpoints)) {
253 			struct wlr_x11_touchpoint *last_touchpoint = wl_container_of(
254 				output->touchpoints.next, last_touchpoint, link);
255 			id = last_touchpoint->wayland_id + 1;
256 		}
257 
258 		struct wlr_x11_touchpoint *touchpoint = calloc(1, sizeof(struct wlr_x11_touchpoint));
259 		touchpoint->x11_id = ev->detail;
260 		touchpoint->wayland_id = id;
261 		wl_list_init(&touchpoint->link);
262 		wl_list_insert(&output->touchpoints, &touchpoint->link);
263 
264 		send_touch_down_event(output, ev->event_x >> 16,
265 			ev->event_y >> 16, touchpoint->wayland_id, ev->time);
266 		x11->time = ev->time;
267 		break;
268 	}
269 	case XCB_INPUT_TOUCH_END: {
270 		xcb_input_touch_end_event_t *ev = (xcb_input_touch_end_event_t *)event;
271 
272 		output = get_x11_output_from_window_id(x11, ev->event);
273 		if (!output) {
274 			return;
275 		}
276 
277 		struct wlr_x11_touchpoint *touchpoint = get_touchpoint_from_x11_touch_id(output, ev->detail);
278 		if (!touchpoint) {
279 			return;
280 		}
281 
282 		send_touch_up_event(output, touchpoint->wayland_id, ev->time);
283 		x11->time = ev->time;
284 
285 		wl_list_remove(&touchpoint->link);
286 		free(touchpoint);
287 		break;
288 	}
289 	case XCB_INPUT_TOUCH_UPDATE: {
290 		xcb_input_touch_update_event_t *ev = (xcb_input_touch_update_event_t *)event;
291 
292 		output = get_x11_output_from_window_id(x11, ev->event);
293 		if (!output) {
294 			return;
295 		}
296 
297 		struct wlr_x11_touchpoint *touchpoint = get_touchpoint_from_x11_touch_id(output, ev->detail);
298 		if (!touchpoint) {
299 			return;
300 		}
301 
302 		send_touch_motion_event(output, ev->event_x >> 16,
303 			ev->event_y >> 16, touchpoint->wayland_id, ev->time);
304 		x11->time = ev->time;
305 		break;
306 	}
307 	}
308 }
309 
input_device_destroy(struct wlr_input_device * wlr_device)310 static void input_device_destroy(struct wlr_input_device *wlr_device) {
311 	// Don't free the input device, it's on the stack
312 }
313 
314 const struct wlr_input_device_impl input_device_impl = {
315 	.destroy = input_device_destroy,
316 };
317 
keyboard_destroy(struct wlr_keyboard * wlr_keyboard)318 static void keyboard_destroy(struct wlr_keyboard *wlr_keyboard) {
319 	// Don't free the keyboard, it's on the stack
320 }
321 
322 const struct wlr_keyboard_impl keyboard_impl = {
323 	.destroy = keyboard_destroy,
324 };
325 
pointer_destroy(struct wlr_pointer * wlr_pointer)326 static void pointer_destroy(struct wlr_pointer *wlr_pointer) {
327 	// Don't free the pointer, it's on the stack
328 }
329 
330 const struct wlr_pointer_impl pointer_impl = {
331 	.destroy = pointer_destroy,
332 };
333 
touch_destroy(struct wlr_touch * wlr_touch)334 static void touch_destroy(struct wlr_touch *wlr_touch) {
335 	// Don't free the touch, it's on the stack
336 }
337 
338 const struct wlr_touch_impl touch_impl = {
339 	.destroy = touch_destroy,
340 };
341 
update_x11_pointer_position(struct wlr_x11_output * output,xcb_timestamp_t time)342 void update_x11_pointer_position(struct wlr_x11_output *output,
343 		xcb_timestamp_t time) {
344 	struct wlr_x11_backend *x11 = output->x11;
345 
346 	xcb_query_pointer_cookie_t cookie =
347 		xcb_query_pointer(x11->xcb, output->win);
348 	xcb_query_pointer_reply_t *reply =
349 		xcb_query_pointer_reply(x11->xcb, cookie, NULL);
350 	if (!reply) {
351 		return;
352 	}
353 
354 	send_pointer_position_event(output, reply->win_x, reply->win_y, time);
355 
356 	free(reply);
357 }
358 
wlr_input_device_is_x11(struct wlr_input_device * wlr_dev)359 bool wlr_input_device_is_x11(struct wlr_input_device *wlr_dev) {
360 	return wlr_dev->impl == &input_device_impl;
361 }
362