mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Merge branch 'master' into laggy-move-resize
This commit is contained in:
		
						commit
						7904b625f0
					
				
					 25 changed files with 1061 additions and 294 deletions
				
			
		| 
						 | 
					@ -33,7 +33,7 @@ void handle_touch_down(struct libinput_event *event,
 | 
				
			||||||
	wlr_event.device = wlr_dev;
 | 
						wlr_event.device = wlr_dev;
 | 
				
			||||||
	wlr_event.time_msec =
 | 
						wlr_event.time_msec =
 | 
				
			||||||
		usec_to_msec(libinput_event_touch_get_time_usec(tevent));
 | 
							usec_to_msec(libinput_event_touch_get_time_usec(tevent));
 | 
				
			||||||
	wlr_event.slot = libinput_event_touch_get_slot(tevent);
 | 
						wlr_event.touch_id = libinput_event_touch_get_slot(tevent);
 | 
				
			||||||
	wlr_event.x_mm = libinput_event_touch_get_x(tevent);
 | 
						wlr_event.x_mm = libinput_event_touch_get_x(tevent);
 | 
				
			||||||
	wlr_event.y_mm = libinput_event_touch_get_y(tevent);
 | 
						wlr_event.y_mm = libinput_event_touch_get_y(tevent);
 | 
				
			||||||
	libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm);
 | 
						libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm);
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ void handle_touch_up(struct libinput_event *event,
 | 
				
			||||||
	wlr_event.device = wlr_dev;
 | 
						wlr_event.device = wlr_dev;
 | 
				
			||||||
	wlr_event.time_msec =
 | 
						wlr_event.time_msec =
 | 
				
			||||||
		usec_to_msec(libinput_event_touch_get_time_usec(tevent));
 | 
							usec_to_msec(libinput_event_touch_get_time_usec(tevent));
 | 
				
			||||||
	wlr_event.slot = libinput_event_touch_get_slot(tevent);
 | 
						wlr_event.touch_id = libinput_event_touch_get_slot(tevent);
 | 
				
			||||||
	wl_signal_emit(&wlr_dev->touch->events.up, &wlr_event);
 | 
						wl_signal_emit(&wlr_dev->touch->events.up, &wlr_event);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,7 +72,7 @@ void handle_touch_motion(struct libinput_event *event,
 | 
				
			||||||
	wlr_event.device = wlr_dev;
 | 
						wlr_event.device = wlr_dev;
 | 
				
			||||||
	wlr_event.time_msec =
 | 
						wlr_event.time_msec =
 | 
				
			||||||
		usec_to_msec(libinput_event_touch_get_time_usec(tevent));
 | 
							usec_to_msec(libinput_event_touch_get_time_usec(tevent));
 | 
				
			||||||
	wlr_event.slot = libinput_event_touch_get_slot(tevent);
 | 
						wlr_event.touch_id = libinput_event_touch_get_slot(tevent);
 | 
				
			||||||
	wlr_event.x_mm = libinput_event_touch_get_x(tevent);
 | 
						wlr_event.x_mm = libinput_event_touch_get_x(tevent);
 | 
				
			||||||
	wlr_event.y_mm = libinput_event_touch_get_y(tevent);
 | 
						wlr_event.y_mm = libinput_event_touch_get_y(tevent);
 | 
				
			||||||
	libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm);
 | 
						libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm);
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,6 @@ void handle_touch_cancel(struct libinput_event *event,
 | 
				
			||||||
	wlr_event.device = wlr_dev;
 | 
						wlr_event.device = wlr_dev;
 | 
				
			||||||
	wlr_event.time_msec =
 | 
						wlr_event.time_msec =
 | 
				
			||||||
		usec_to_msec(libinput_event_touch_get_time_usec(tevent));
 | 
							usec_to_msec(libinput_event_touch_get_time_usec(tevent));
 | 
				
			||||||
	wlr_event.slot = libinput_event_touch_get_slot(tevent);
 | 
						wlr_event.touch_id = libinput_event_touch_get_slot(tevent);
 | 
				
			||||||
	wl_signal_emit(&wlr_dev->touch->events.cancel, &wlr_event);
 | 
						wl_signal_emit(&wlr_dev->touch->events.cancel, &wlr_event);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,7 @@ struct sample_state {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct touch_point {
 | 
					struct touch_point {
 | 
				
			||||||
	int32_t slot;
 | 
						int32_t touch_id;
 | 
				
			||||||
	double x, y;
 | 
						double x, y;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -199,7 +199,7 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_event_touch_up *event = data;
 | 
						struct wlr_event_touch_up *event = data;
 | 
				
			||||||
	for (size_t i = 0; i < sample->touch_points->length; ++i) {
 | 
						for (size_t i = 0; i < sample->touch_points->length; ++i) {
 | 
				
			||||||
		struct touch_point *point = sample->touch_points->items[i];
 | 
							struct touch_point *point = sample->touch_points->items[i];
 | 
				
			||||||
		if (point->slot == event->slot) {
 | 
							if (point->touch_id == event->touch_id) {
 | 
				
			||||||
			wlr_list_del(sample->touch_points, i);
 | 
								wlr_list_del(sample->touch_points, i);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -212,7 +212,7 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct sample_state *sample = wl_container_of(listener, sample, touch_down);
 | 
						struct sample_state *sample = wl_container_of(listener, sample, touch_down);
 | 
				
			||||||
	struct wlr_event_touch_down *event = data;
 | 
						struct wlr_event_touch_down *event = data;
 | 
				
			||||||
	struct touch_point *point = calloc(1, sizeof(struct touch_point));
 | 
						struct touch_point *point = calloc(1, sizeof(struct touch_point));
 | 
				
			||||||
	point->slot = event->slot;
 | 
						point->touch_id = event->touch_id;
 | 
				
			||||||
	point->x = event->x_mm / event->width_mm;
 | 
						point->x = event->x_mm / event->width_mm;
 | 
				
			||||||
	point->y = event->y_mm / event->height_mm;
 | 
						point->y = event->y_mm / event->height_mm;
 | 
				
			||||||
	if (wlr_list_add(sample->touch_points, point) == -1) {
 | 
						if (wlr_list_add(sample->touch_points, point) == -1) {
 | 
				
			||||||
| 
						 | 
					@ -228,7 +228,7 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_event_touch_motion *event = data;
 | 
						struct wlr_event_touch_motion *event = data;
 | 
				
			||||||
	for (size_t i = 0; i < sample->touch_points->length; ++i) {
 | 
						for (size_t i = 0; i < sample->touch_points->length; ++i) {
 | 
				
			||||||
		struct touch_point *point = sample->touch_points->items[i];
 | 
							struct touch_point *point = sample->touch_points->items[i];
 | 
				
			||||||
		if (point->slot == event->slot) {
 | 
							if (point->touch_id == event->touch_id) {
 | 
				
			||||||
			point->x = event->x_mm / event->width_mm;
 | 
								point->x = event->x_mm / event->width_mm;
 | 
				
			||||||
			point->y = event->y_mm / event->height_mm;
 | 
								point->y = event->y_mm / event->height_mm;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -136,7 +136,7 @@ static void touch_down_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_event_touch_down *event = data;
 | 
						struct wlr_event_touch_down *event = data;
 | 
				
			||||||
	struct touch_state *tstate = wl_container_of(listener, tstate, down);
 | 
						struct touch_state *tstate = wl_container_of(listener, tstate, down);
 | 
				
			||||||
	if (tstate->compositor->touch_down_cb) {
 | 
						if (tstate->compositor->touch_down_cb) {
 | 
				
			||||||
		tstate->compositor->touch_down_cb(tstate, event->slot,
 | 
							tstate->compositor->touch_down_cb(tstate, event->touch_id,
 | 
				
			||||||
			event->x_mm, event->y_mm, event->width_mm, event->height_mm);
 | 
								event->x_mm, event->y_mm, event->width_mm, event->height_mm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -145,7 +145,7 @@ static void touch_motion_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_event_touch_motion *event = data;
 | 
						struct wlr_event_touch_motion *event = data;
 | 
				
			||||||
	struct touch_state *tstate = wl_container_of(listener, tstate, motion);
 | 
						struct touch_state *tstate = wl_container_of(listener, tstate, motion);
 | 
				
			||||||
	if (tstate->compositor->touch_motion_cb) {
 | 
						if (tstate->compositor->touch_motion_cb) {
 | 
				
			||||||
		tstate->compositor->touch_motion_cb(tstate, event->slot,
 | 
							tstate->compositor->touch_motion_cb(tstate, event->touch_id,
 | 
				
			||||||
			event->x_mm, event->y_mm, event->width_mm, event->height_mm);
 | 
								event->x_mm, event->y_mm, event->width_mm, event->height_mm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -154,7 +154,7 @@ static void touch_up_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_event_touch_up *event = data;
 | 
						struct wlr_event_touch_up *event = data;
 | 
				
			||||||
	struct touch_state *tstate = wl_container_of(listener, tstate, up);
 | 
						struct touch_state *tstate = wl_container_of(listener, tstate, up);
 | 
				
			||||||
	if (tstate->compositor->touch_up_cb) {
 | 
						if (tstate->compositor->touch_up_cb) {
 | 
				
			||||||
		tstate->compositor->touch_up_cb(tstate, event->slot);
 | 
							tstate->compositor->touch_up_cb(tstate, event->touch_id);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,7 +162,7 @@ static void touch_cancel_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_event_touch_cancel *event = data;
 | 
						struct wlr_event_touch_cancel *event = data;
 | 
				
			||||||
	struct touch_state *tstate = wl_container_of(listener, tstate, cancel);
 | 
						struct touch_state *tstate = wl_container_of(listener, tstate, cancel);
 | 
				
			||||||
	if (tstate->compositor->touch_cancel_cb) {
 | 
						if (tstate->compositor->touch_cancel_cb) {
 | 
				
			||||||
		tstate->compositor->touch_cancel_cb(tstate, event->slot);
 | 
							tstate->compositor->touch_cancel_cb(tstate, event->touch_id);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,12 +95,12 @@ struct compositor_state {
 | 
				
			||||||
		enum wlr_axis_source source,
 | 
							enum wlr_axis_source source,
 | 
				
			||||||
		enum wlr_axis_orientation orientation,
 | 
							enum wlr_axis_orientation orientation,
 | 
				
			||||||
		double delta);
 | 
							double delta);
 | 
				
			||||||
	void (*touch_down_cb)(struct touch_state *s, int32_t slot,
 | 
						void (*touch_down_cb)(struct touch_state *s, int32_t touch_id,
 | 
				
			||||||
		double x, double y, double width, double height);
 | 
							double x, double y, double width, double height);
 | 
				
			||||||
	void (*touch_motion_cb)(struct touch_state *s, int32_t slot,
 | 
						void (*touch_motion_cb)(struct touch_state *s, int32_t touch_id,
 | 
				
			||||||
		double x, double y, double width, double height);
 | 
							double x, double y, double width, double height);
 | 
				
			||||||
	void (*touch_up_cb)(struct touch_state *s, int32_t slot);
 | 
						void (*touch_up_cb)(struct touch_state *s, int32_t touch_id);
 | 
				
			||||||
	void (*touch_cancel_cb)(struct touch_state *s, int32_t slot);
 | 
						void (*touch_cancel_cb)(struct touch_state *s, int32_t touch_id);
 | 
				
			||||||
	void (*tool_axis_cb)(struct tablet_tool_state *s,
 | 
						void (*tool_axis_cb)(struct tablet_tool_state *s,
 | 
				
			||||||
			struct wlr_event_tablet_tool_axis *event);
 | 
								struct wlr_event_tablet_tool_axis *event);
 | 
				
			||||||
	void (*tool_proximity_cb)(struct tablet_tool_state *s,
 | 
						void (*tool_proximity_cb)(struct tablet_tool_state *s,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ struct sample_state {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct touch_point {
 | 
					struct touch_point {
 | 
				
			||||||
	int32_t slot;
 | 
						int32_t touch_id;
 | 
				
			||||||
	double x, y;
 | 
						double x, y;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,11 +58,11 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts
 | 
				
			||||||
	wlr_output_swap_buffers(wlr_output);
 | 
						wlr_output_swap_buffers(wlr_output);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_touch_down(struct touch_state *tstate, int32_t slot,
 | 
					static void handle_touch_down(struct touch_state *tstate, int32_t touch_id,
 | 
				
			||||||
		double x, double y, double width, double height) {
 | 
							double x, double y, double width, double height) {
 | 
				
			||||||
	struct sample_state *sample = tstate->compositor->data;
 | 
						struct sample_state *sample = tstate->compositor->data;
 | 
				
			||||||
	struct touch_point *point = calloc(1, sizeof(struct touch_point));
 | 
						struct touch_point *point = calloc(1, sizeof(struct touch_point));
 | 
				
			||||||
	point->slot = slot;
 | 
						point->touch_id = touch_id;
 | 
				
			||||||
	point->x = x / width;
 | 
						point->x = x / width;
 | 
				
			||||||
	point->y = y / height;
 | 
						point->y = y / height;
 | 
				
			||||||
	if (wlr_list_add(sample->touch_points, point) == -1) {
 | 
						if (wlr_list_add(sample->touch_points, point) == -1) {
 | 
				
			||||||
| 
						 | 
					@ -70,23 +70,23 @@ static void handle_touch_down(struct touch_state *tstate, int32_t slot,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_touch_up(struct touch_state *tstate, int32_t slot) {
 | 
					static void handle_touch_up(struct touch_state *tstate, int32_t touch_id) {
 | 
				
			||||||
	struct sample_state *sample = tstate->compositor->data;
 | 
						struct sample_state *sample = tstate->compositor->data;
 | 
				
			||||||
	for (size_t i = 0; i < sample->touch_points->length; ++i) {
 | 
						for (size_t i = 0; i < sample->touch_points->length; ++i) {
 | 
				
			||||||
		struct touch_point *point = sample->touch_points->items[i];
 | 
							struct touch_point *point = sample->touch_points->items[i];
 | 
				
			||||||
		if (point->slot == slot) {
 | 
							if (point->touch_id == touch_id) {
 | 
				
			||||||
			wlr_list_del(sample->touch_points, i);
 | 
								wlr_list_del(sample->touch_points, i);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_touch_motion(struct touch_state *tstate, int32_t slot,
 | 
					static void handle_touch_motion(struct touch_state *tstate, int32_t touch_id,
 | 
				
			||||||
		double x, double y, double width, double height) {
 | 
							double x, double y, double width, double height) {
 | 
				
			||||||
	struct sample_state *sample = tstate->compositor->data;
 | 
						struct sample_state *sample = tstate->compositor->data;
 | 
				
			||||||
	for (size_t i = 0; i < sample->touch_points->length; ++i) {
 | 
						for (size_t i = 0; i < sample->touch_points->length; ++i) {
 | 
				
			||||||
		struct touch_point *point = sample->touch_points->items[i];
 | 
							struct touch_point *point = sample->touch_points->items[i];
 | 
				
			||||||
		if (point->slot == slot) {
 | 
							if (point->touch_id == touch_id) {
 | 
				
			||||||
			point->x = x / width;
 | 
								point->x = x / width;
 | 
				
			||||||
			point->y = y / height;
 | 
								point->y = y / height;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,8 @@
 | 
				
			||||||
#include <wlr/types/wlr_output_layout.h>
 | 
					#include <wlr/types/wlr_output_layout.h>
 | 
				
			||||||
#include <wlr/types/wlr_input_device.h>
 | 
					#include <wlr/types/wlr_input_device.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ROOTS_CONFIG_DEFAULT_SEAT_NAME "seat0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct roots_output_config {
 | 
					struct roots_output_config {
 | 
				
			||||||
	char *name;
 | 
						char *name;
 | 
				
			||||||
	enum wl_output_transform transform;
 | 
						enum wl_output_transform transform;
 | 
				
			||||||
| 
						 | 
					@ -17,9 +19,9 @@ struct roots_output_config {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct roots_device_config {
 | 
					struct roots_device_config {
 | 
				
			||||||
	char *name;
 | 
						char *name;
 | 
				
			||||||
 | 
						char *seat;
 | 
				
			||||||
	char *mapped_output;
 | 
						char *mapped_output;
 | 
				
			||||||
	struct wlr_box *mapped_box;
 | 
						struct wlr_box *mapped_box;
 | 
				
			||||||
	char *seat;
 | 
					 | 
				
			||||||
	struct wl_list link;
 | 
						struct wl_list link;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +35,7 @@ struct roots_binding_config {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct roots_keyboard_config {
 | 
					struct roots_keyboard_config {
 | 
				
			||||||
	char *name;
 | 
						char *name;
 | 
				
			||||||
 | 
						char *seat;
 | 
				
			||||||
	uint32_t meta_key;
 | 
						uint32_t meta_key;
 | 
				
			||||||
	char *rules;
 | 
						char *rules;
 | 
				
			||||||
	char *model;
 | 
						char *model;
 | 
				
			||||||
| 
						 | 
					@ -42,18 +45,22 @@ struct roots_keyboard_config {
 | 
				
			||||||
	struct wl_list link;
 | 
						struct wl_list link;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct roots_cursor_config {
 | 
				
			||||||
 | 
						char *seat;
 | 
				
			||||||
 | 
						char *mapped_output;
 | 
				
			||||||
 | 
						struct wlr_box *mapped_box;
 | 
				
			||||||
 | 
						char *theme;
 | 
				
			||||||
 | 
						struct wl_list link;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct roots_config {
 | 
					struct roots_config {
 | 
				
			||||||
	bool xwayland;
 | 
						bool xwayland;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct {
 | 
					 | 
				
			||||||
		char *mapped_output;
 | 
					 | 
				
			||||||
		struct wlr_box *mapped_box;
 | 
					 | 
				
			||||||
	} cursor;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wl_list outputs;
 | 
						struct wl_list outputs;
 | 
				
			||||||
	struct wl_list devices;
 | 
						struct wl_list devices;
 | 
				
			||||||
	struct wl_list bindings;
 | 
						struct wl_list bindings;
 | 
				
			||||||
	struct wl_list keyboards;
 | 
						struct wl_list keyboards;
 | 
				
			||||||
 | 
						struct wl_list cursors;
 | 
				
			||||||
	char *config_path;
 | 
						char *config_path;
 | 
				
			||||||
	char *startup_cmd;
 | 
						char *startup_cmd;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -89,6 +96,13 @@ struct roots_device_config *roots_config_get_device(struct roots_config *config,
 | 
				
			||||||
 * returns NULL. A NULL device returns the default config for keyboards.
 | 
					 * returns NULL. A NULL device returns the default config for keyboards.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct roots_keyboard_config *roots_config_get_keyboard(
 | 
					struct roots_keyboard_config *roots_config_get_keyboard(
 | 
				
			||||||
		struct roots_config *config, struct wlr_input_device *device);
 | 
						struct roots_config *config, struct wlr_input_device *device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Get configuration for the cursor. If the cursor is not configured, returns
 | 
				
			||||||
 | 
					 * NULL. A NULL seat_name returns the default config for cursors.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct roots_cursor_config *roots_config_get_cursor(struct roots_config *config,
 | 
				
			||||||
 | 
						const char *seat_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,6 @@ struct roots_cursor {
 | 
				
			||||||
	uint32_t resize_edges;
 | 
						uint32_t resize_edges;
 | 
				
			||||||
	// Ring buffer of input events that could trigger move/resize/rotate
 | 
						// Ring buffer of input events that could trigger move/resize/rotate
 | 
				
			||||||
	int input_events_idx;
 | 
						int input_events_idx;
 | 
				
			||||||
	struct wl_list touch_points;
 | 
					 | 
				
			||||||
	struct roots_input_event input_events[16];
 | 
						struct roots_input_event input_events[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener motion;
 | 
						struct wl_listener motion;
 | 
				
			||||||
| 
						 | 
					@ -54,9 +53,6 @@ struct roots_cursor {
 | 
				
			||||||
	struct wl_listener tool_axis;
 | 
						struct wl_listener tool_axis;
 | 
				
			||||||
	struct wl_listener tool_tip;
 | 
						struct wl_listener tool_tip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener pointer_grab_begin;
 | 
					 | 
				
			||||||
	struct wl_listener pointer_grab_end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wl_listener request_set_cursor;
 | 
						struct wl_listener request_set_cursor;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,10 +90,4 @@ void roots_cursor_handle_tool_tip(struct roots_cursor *cursor,
 | 
				
			||||||
void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor,
 | 
					void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor,
 | 
				
			||||||
		struct wlr_seat_pointer_request_set_cursor_event *event);
 | 
							struct wlr_seat_pointer_request_set_cursor_event *event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor,
 | 
					 | 
				
			||||||
		struct wlr_seat_pointer_grab *grab);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor,
 | 
					 | 
				
			||||||
		struct wlr_seat_pointer_grab *grab);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,7 @@ struct roots_desktop {
 | 
				
			||||||
#ifdef HAS_XWAYLAND
 | 
					#ifdef HAS_XWAYLAND
 | 
				
			||||||
	struct wlr_xwayland *xwayland;
 | 
						struct wlr_xwayland *xwayland;
 | 
				
			||||||
	struct wl_listener xwayland_surface;
 | 
						struct wl_listener xwayland_surface;
 | 
				
			||||||
 | 
						struct wl_listener xwayland_ready;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,24 +4,15 @@
 | 
				
			||||||
#include "rootston/input.h"
 | 
					#include "rootston/input.h"
 | 
				
			||||||
#include "rootston/keyboard.h"
 | 
					#include "rootston/keyboard.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct roots_drag_icon {
 | 
					 | 
				
			||||||
	struct wlr_surface *surface;
 | 
					 | 
				
			||||||
	struct wl_list link; // roots_seat::drag_icons
 | 
					 | 
				
			||||||
	bool mapped;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int32_t sx;
 | 
					 | 
				
			||||||
	int32_t sy;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wl_listener surface_destroy;
 | 
					 | 
				
			||||||
	struct wl_listener surface_commit;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct roots_seat {
 | 
					struct roots_seat {
 | 
				
			||||||
	struct roots_input *input;
 | 
						struct roots_input *input;
 | 
				
			||||||
	struct wlr_seat *seat;
 | 
						struct wlr_seat *seat;
 | 
				
			||||||
	struct roots_cursor *cursor;
 | 
						struct roots_cursor *cursor;
 | 
				
			||||||
	struct wl_list link;
 | 
						struct wl_list link;
 | 
				
			||||||
	struct wl_list drag_icons;
 | 
					
 | 
				
			||||||
 | 
						// coordinates of the first touch point if it exists
 | 
				
			||||||
 | 
						int32_t touch_id;
 | 
				
			||||||
 | 
						double touch_x, touch_y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct roots_view *focus;
 | 
						struct roots_view *focus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,13 +34,6 @@ struct roots_touch {
 | 
				
			||||||
	struct wl_list link;
 | 
						struct wl_list link;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct roots_touch_point {
 | 
					 | 
				
			||||||
	struct roots_touch *device;
 | 
					 | 
				
			||||||
	int32_t slot;
 | 
					 | 
				
			||||||
	double x, y;
 | 
					 | 
				
			||||||
	struct wl_list link;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct roots_tablet_tool {
 | 
					struct roots_tablet_tool {
 | 
				
			||||||
	struct roots_seat *seat;
 | 
						struct roots_seat *seat;
 | 
				
			||||||
	struct wlr_input_device *device;
 | 
						struct wlr_input_device *device;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,4 +126,11 @@ void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_box *box);
 | 
				
			||||||
void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
 | 
					void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
 | 
				
			||||||
	struct wlr_input_device *dev, struct wlr_box *box);
 | 
						struct wlr_input_device *dev, struct wlr_box *box);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Convert absolute coordinates to layout coordinates for the device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur,
 | 
				
			||||||
 | 
							struct wlr_input_device *device, double x_mm, double y_mm,
 | 
				
			||||||
 | 
							double width_mm, double height_mm, double *lx, double *ly);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,9 @@ wlr_pointer_grab_interface wlr_data_device_pointer_drag_interface;
 | 
				
			||||||
extern const struct
 | 
					extern const struct
 | 
				
			||||||
wlr_keyboard_grab_interface wlr_data_device_keyboard_drag_interface;
 | 
					wlr_keyboard_grab_interface wlr_data_device_keyboard_drag_interface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const struct
 | 
				
			||||||
 | 
					wlr_touch_grab_interface wlr_data_device_touch_drag_interface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_data_device_manager {
 | 
					struct wlr_data_device_manager {
 | 
				
			||||||
	struct wl_global *global;
 | 
						struct wl_global *global;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -50,22 +53,49 @@ struct wlr_data_source {
 | 
				
			||||||
	} events;
 | 
						} events;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_drag_icon {
 | 
				
			||||||
 | 
						struct wlr_surface *surface;
 | 
				
			||||||
 | 
						struct wlr_seat_client *client;
 | 
				
			||||||
 | 
						struct wl_list link; // wlr_seat::drag_icons
 | 
				
			||||||
 | 
						bool mapped;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool is_pointer;
 | 
				
			||||||
 | 
						int32_t touch_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int32_t sx;
 | 
				
			||||||
 | 
						int32_t sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct wl_signal destroy;
 | 
				
			||||||
 | 
						} events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_listener surface_destroy;
 | 
				
			||||||
 | 
						struct wl_listener surface_commit;
 | 
				
			||||||
 | 
						struct wl_listener seat_client_destroy;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_drag {
 | 
					struct wlr_drag {
 | 
				
			||||||
	struct wlr_seat_pointer_grab pointer_grab;
 | 
						struct wlr_seat_pointer_grab pointer_grab;
 | 
				
			||||||
	struct wlr_seat_keyboard_grab keyboard_grab;
 | 
						struct wlr_seat_keyboard_grab keyboard_grab;
 | 
				
			||||||
 | 
						struct wlr_seat_touch_grab touch_grab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_seat *seat;
 | 
				
			||||||
	struct wlr_seat_client *seat_client;
 | 
						struct wlr_seat_client *seat_client;
 | 
				
			||||||
	struct wlr_seat_client *focus_client;
 | 
						struct wlr_seat_client *focus_client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_surface *icon;
 | 
						bool is_pointer_grab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_drag_icon *icon;
 | 
				
			||||||
	struct wlr_surface *focus;
 | 
						struct wlr_surface *focus;
 | 
				
			||||||
	struct wlr_data_source *source;
 | 
						struct wlr_data_source *source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool cancelling;
 | 
						bool cancelling;
 | 
				
			||||||
 | 
						int32_t grab_touch_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener icon_destroy;
 | 
						struct wl_listener point_destroy;
 | 
				
			||||||
	struct wl_listener source_destroy;
 | 
						struct wl_listener source_destroy;
 | 
				
			||||||
	struct wl_listener seat_client_unbound;
 | 
						struct wl_listener seat_client_destroy;
 | 
				
			||||||
 | 
						struct wl_listener icon_destroy;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,30 @@ struct wlr_seat_client {
 | 
				
			||||||
	struct wl_resource *touch;
 | 
						struct wl_resource *touch;
 | 
				
			||||||
	struct wl_resource *data_device;
 | 
						struct wl_resource *data_device;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct wl_signal destroy;
 | 
				
			||||||
 | 
						} events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_list link;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_touch_point {
 | 
				
			||||||
 | 
						int32_t touch_id;
 | 
				
			||||||
 | 
						struct wlr_surface *surface;
 | 
				
			||||||
 | 
						struct wlr_seat_client *client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_surface *focus_surface;
 | 
				
			||||||
 | 
						struct wlr_seat_client *focus_client;
 | 
				
			||||||
 | 
						double sx, sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_listener surface_destroy;
 | 
				
			||||||
 | 
						struct wl_listener focus_surface_destroy;
 | 
				
			||||||
 | 
						struct wl_listener resource_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct wl_signal destroy;
 | 
				
			||||||
 | 
						} events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_list link;
 | 
						struct wl_list link;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +73,32 @@ struct wlr_keyboard_grab_interface {
 | 
				
			||||||
	void (*cancel)(struct wlr_seat_keyboard_grab *grab);
 | 
						void (*cancel)(struct wlr_seat_keyboard_grab *grab);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_seat_touch_grab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_touch_grab_interface {
 | 
				
			||||||
 | 
						uint32_t (*down)(struct wlr_seat_touch_grab *grab, uint32_t time,
 | 
				
			||||||
 | 
								struct wlr_touch_point *point);
 | 
				
			||||||
 | 
						void (*up)(struct wlr_seat_touch_grab *grab, uint32_t time,
 | 
				
			||||||
 | 
								struct wlr_touch_point *point);
 | 
				
			||||||
 | 
						void (*motion)(struct wlr_seat_touch_grab *grab, uint32_t time,
 | 
				
			||||||
 | 
								struct wlr_touch_point *point);
 | 
				
			||||||
 | 
						void (*enter)(struct wlr_seat_touch_grab *grab, uint32_t time,
 | 
				
			||||||
 | 
								struct wlr_touch_point *point);
 | 
				
			||||||
 | 
						// XXX this will conflict with the actual touch cancel which is different so
 | 
				
			||||||
 | 
						// we need to rename this
 | 
				
			||||||
 | 
						void (*cancel)(struct wlr_seat_touch_grab *grab);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Passed to `wlr_seat_touch_start_grab()` to start a grab of the touch device.
 | 
				
			||||||
 | 
					 * The grabber is responsible for handling touch events for the seat.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct wlr_seat_touch_grab {
 | 
				
			||||||
 | 
						const struct wlr_touch_grab_interface *interface;
 | 
				
			||||||
 | 
						struct wlr_seat *seat;
 | 
				
			||||||
 | 
						void *data;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Passed to `wlr_seat_keyboard_start_grab()` to start a grab of the keyboard.
 | 
					 * Passed to `wlr_seat_keyboard_start_grab()` to start a grab of the keyboard.
 | 
				
			||||||
 * The grabber is responsible for handling keyboard events for the seat.
 | 
					 * The grabber is responsible for handling keyboard events for the seat.
 | 
				
			||||||
| 
						 | 
					@ -86,6 +136,7 @@ struct wlr_seat_pointer_state {
 | 
				
			||||||
	struct wl_listener resource_destroy;
 | 
						struct wl_listener resource_destroy;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: May be useful to be able to simulate keyboard input events
 | 
				
			||||||
struct wlr_seat_keyboard_state {
 | 
					struct wlr_seat_keyboard_state {
 | 
				
			||||||
	struct wlr_seat *seat;
 | 
						struct wlr_seat *seat;
 | 
				
			||||||
	struct wlr_keyboard *keyboard;
 | 
						struct wlr_keyboard *keyboard;
 | 
				
			||||||
| 
						 | 
					@ -103,10 +154,23 @@ struct wlr_seat_keyboard_state {
 | 
				
			||||||
	struct wlr_seat_keyboard_grab *default_grab;
 | 
						struct wlr_seat_keyboard_grab *default_grab;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_seat_touch_state {
 | 
				
			||||||
 | 
						struct wlr_seat *seat;
 | 
				
			||||||
 | 
						struct wl_list touch_points; // wlr_touch_point::link
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t grab_serial;
 | 
				
			||||||
 | 
						uint32_t grab_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_seat_touch_grab *grab;
 | 
				
			||||||
 | 
						struct wlr_seat_touch_grab *default_grab;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_seat {
 | 
					struct wlr_seat {
 | 
				
			||||||
	struct wl_global *wl_global;
 | 
						struct wl_global *wl_global;
 | 
				
			||||||
	struct wl_display *display;
 | 
						struct wl_display *display;
 | 
				
			||||||
	struct wl_list clients;
 | 
						struct wl_list clients;
 | 
				
			||||||
 | 
						struct wl_list drag_icons; // wlr_drag_icon::link
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char *name;
 | 
						char *name;
 | 
				
			||||||
	uint32_t capabilities;
 | 
						uint32_t capabilities;
 | 
				
			||||||
	struct timespec last_event;
 | 
						struct timespec last_event;
 | 
				
			||||||
| 
						 | 
					@ -117,19 +181,20 @@ struct wlr_seat {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_seat_pointer_state pointer_state;
 | 
						struct wlr_seat_pointer_state pointer_state;
 | 
				
			||||||
	struct wlr_seat_keyboard_state keyboard_state;
 | 
						struct wlr_seat_keyboard_state keyboard_state;
 | 
				
			||||||
 | 
						struct wlr_seat_touch_state touch_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_listener selection_data_source_destroy;
 | 
						struct wl_listener selection_data_source_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		struct wl_signal client_bound;
 | 
					 | 
				
			||||||
		struct wl_signal client_unbound;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		struct wl_signal pointer_grab_begin;
 | 
							struct wl_signal pointer_grab_begin;
 | 
				
			||||||
		struct wl_signal pointer_grab_end;
 | 
							struct wl_signal pointer_grab_end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct wl_signal keyboard_grab_begin;
 | 
							struct wl_signal keyboard_grab_begin;
 | 
				
			||||||
		struct wl_signal keyboard_grab_end;
 | 
							struct wl_signal keyboard_grab_end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct wl_signal touch_grab_begin;
 | 
				
			||||||
 | 
							struct wl_signal touch_grab_end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct wl_signal request_set_cursor;
 | 
							struct wl_signal request_set_cursor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct wl_signal selection;
 | 
							struct wl_signal selection;
 | 
				
			||||||
| 
						 | 
					@ -259,6 +324,11 @@ uint32_t wlr_seat_pointer_notify_button(struct wlr_seat *wlr_seat,
 | 
				
			||||||
void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time,
 | 
					void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time,
 | 
				
			||||||
		enum wlr_axis_orientation orientation, double value);
 | 
							enum wlr_axis_orientation orientation, double value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Whether or not the pointer has a grab other than the default grab.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool wlr_seat_pointer_has_grab(struct wlr_seat *seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Set this keyboard as the active keyboard for the seat.
 | 
					 * Set this keyboard as the active keyboard for the seat.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -326,6 +396,108 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat,
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void wlr_seat_keyboard_clear_focus(struct wlr_seat *wlr_seat);
 | 
					void wlr_seat_keyboard_clear_focus(struct wlr_seat *wlr_seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: May be useful to be able to simulate keyboard input events
 | 
					/**
 | 
				
			||||||
 | 
					 * Whether or not the keyboard has a grab other than the default grab
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool wlr_seat_keyboard_has_grab(struct wlr_seat *seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Start a grab of the touch device of this seat. The grabber is responsible for
 | 
				
			||||||
 | 
					 * handling all touch events until the grab ends.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_seat_touch_start_grab(struct wlr_seat *wlr_seat,
 | 
				
			||||||
 | 
							struct wlr_seat_touch_grab *grab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * End the grab of the touch device of this seat. This reverts the grab back to
 | 
				
			||||||
 | 
					 * the default grab for the touch device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_seat_touch_end_grab(struct wlr_seat *wlr_seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Get the active touch point with the given `touch_id`. If the touch point does
 | 
				
			||||||
 | 
					 * not exist or is no longer active, returns NULL.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct wlr_touch_point *wlr_seat_touch_get_point(struct wlr_seat *seat,
 | 
				
			||||||
 | 
							int32_t touch_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Notify the seat of a touch down on the given surface. Defers to any grab of
 | 
				
			||||||
 | 
					 * the touch device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32_t wlr_seat_touch_notify_down(struct wlr_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_surface *surface, uint32_t time, int32_t touch_id, double sx,
 | 
				
			||||||
 | 
							double sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Notify the seat that the touch point given by `touch_id` is up. Defers to any
 | 
				
			||||||
 | 
					 * grab of the touch device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_seat_touch_notify_up(struct wlr_seat *seat, uint32_t time,
 | 
				
			||||||
 | 
							int32_t touch_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Notify the seat that the touch point given by `touch_id` has moved. Defers to
 | 
				
			||||||
 | 
					 * any grab of the touch device. The seat should be notified of touch motion
 | 
				
			||||||
 | 
					 * even if the surface is not the owner of the touch point for processing by
 | 
				
			||||||
 | 
					 * grabs.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_seat_touch_notify_motion(struct wlr_seat *seat, uint32_t time,
 | 
				
			||||||
 | 
							int32_t touch_id, double sx, double sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Notify the seat that the touch point given by `touch_id` has entered a new
 | 
				
			||||||
 | 
					 * surface. The surface is required. To clear focus, use
 | 
				
			||||||
 | 
					 * `wlr_seat_touch_point_clear_focus()`.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_seat_touch_point_focus(struct wlr_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_surface *surface, uint32_t time, int32_t touch_id, double sx,
 | 
				
			||||||
 | 
							double sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Clear the focused surface for the touch point given by `touch_id`.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_seat_touch_point_clear_focus(struct wlr_seat *seat, uint32_t time,
 | 
				
			||||||
 | 
							int32_t touch_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Send a touch down event to the client of the given surface. All future touch
 | 
				
			||||||
 | 
					 * events for this point will go to this surface. If the touch down is valid,
 | 
				
			||||||
 | 
					 * this will add a new touch point with the given `touch_id`. The touch down may
 | 
				
			||||||
 | 
					 * not be valid if the surface seat client does not accept touch input.
 | 
				
			||||||
 | 
					 * Coordinates are surface-local. Compositors should use
 | 
				
			||||||
 | 
					 * `wlr_seat_touch_notify_down()` to respect any grabs of the touch device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					uint32_t wlr_seat_touch_send_down(struct wlr_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_surface *surface, uint32_t time, int32_t touch_id, double sx,
 | 
				
			||||||
 | 
							double sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Send a touch up event for the touch point given by the `touch_id`. The event
 | 
				
			||||||
 | 
					 * will go to the client for the surface given in the cooresponding touch down
 | 
				
			||||||
 | 
					 * event. This will remove the touch point. Compositors should use
 | 
				
			||||||
 | 
					 * `wlr_seat_touch_notify_up()` to respect any grabs of the touch device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_seat_touch_send_up(struct wlr_seat *seat, uint32_t time,
 | 
				
			||||||
 | 
							int32_t touch_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Send a touch motion event for the touch point given by the `touch_id`. The
 | 
				
			||||||
 | 
					 * event will go to the client for the surface given in the corresponding touch
 | 
				
			||||||
 | 
					 * down event. Compositors should use `wlr_seat_touch_notify_motion()` to
 | 
				
			||||||
 | 
					 * respect any grabs of the touch device.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time,
 | 
				
			||||||
 | 
							int32_t touch_id, double sx, double sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * How many touch points are currently down for the seat.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int wlr_seat_touch_num_points(struct wlr_seat *seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Whether or not the seat has a touch grab other than the default grab.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool wlr_seat_touch_has_grab(struct wlr_seat *seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ struct wlr_touch {
 | 
				
			||||||
struct wlr_event_touch_down {
 | 
					struct wlr_event_touch_down {
 | 
				
			||||||
	struct wlr_input_device *device;
 | 
						struct wlr_input_device *device;
 | 
				
			||||||
	uint32_t time_msec;
 | 
						uint32_t time_msec;
 | 
				
			||||||
	int32_t slot;
 | 
						int32_t touch_id;
 | 
				
			||||||
	double x_mm, y_mm;
 | 
						double x_mm, y_mm;
 | 
				
			||||||
	double width_mm, height_mm;
 | 
						double width_mm, height_mm;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -30,13 +30,13 @@ struct wlr_event_touch_down {
 | 
				
			||||||
struct wlr_event_touch_up {
 | 
					struct wlr_event_touch_up {
 | 
				
			||||||
	struct wlr_input_device *device;
 | 
						struct wlr_input_device *device;
 | 
				
			||||||
	uint32_t time_msec;
 | 
						uint32_t time_msec;
 | 
				
			||||||
	int32_t slot;
 | 
						int32_t touch_id;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_event_touch_motion {
 | 
					struct wlr_event_touch_motion {
 | 
				
			||||||
	struct wlr_input_device *device;
 | 
						struct wlr_input_device *device;
 | 
				
			||||||
	uint32_t time_msec;
 | 
						uint32_t time_msec;
 | 
				
			||||||
	int32_t slot;
 | 
						int32_t touch_id;
 | 
				
			||||||
	double x_mm, y_mm;
 | 
						double x_mm, y_mm;
 | 
				
			||||||
	double width_mm, height_mm;
 | 
						double width_mm, height_mm;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,7 @@ struct wlr_event_touch_motion {
 | 
				
			||||||
struct wlr_event_touch_cancel {
 | 
					struct wlr_event_touch_cancel {
 | 
				
			||||||
	struct wlr_input_device *device;
 | 
						struct wlr_input_device *device;
 | 
				
			||||||
	uint32_t time_msec;
 | 
						uint32_t time_msec;
 | 
				
			||||||
	int32_t slot;
 | 
						int32_t touch_id;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,6 +150,37 @@ void add_binding_config(struct wl_list *bindings, const char* combination,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void config_handle_cursor(struct roots_config *config,
 | 
				
			||||||
 | 
							const char *seat_name, const char *name, const char *value) {
 | 
				
			||||||
 | 
						struct roots_cursor_config *cc;
 | 
				
			||||||
 | 
						bool found = false;
 | 
				
			||||||
 | 
						wl_list_for_each(cc, &config->cursors, link) {
 | 
				
			||||||
 | 
							if (strcmp(cc->seat, seat_name) == 0) {
 | 
				
			||||||
 | 
								found = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!found) {
 | 
				
			||||||
 | 
							cc = calloc(1, sizeof(struct roots_cursor_config));
 | 
				
			||||||
 | 
							cc->seat = strdup(seat_name);
 | 
				
			||||||
 | 
							wl_list_insert(&config->cursors, &cc->link);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (strcmp(name, "map-to-output") == 0) {
 | 
				
			||||||
 | 
							free(cc->mapped_output);
 | 
				
			||||||
 | 
							cc->mapped_output = strdup(value);
 | 
				
			||||||
 | 
						} else if (strcmp(name, "geometry") == 0) {
 | 
				
			||||||
 | 
							free(cc->mapped_box);
 | 
				
			||||||
 | 
							cc->mapped_box = parse_geometry(value);
 | 
				
			||||||
 | 
						} else if (strcmp(name, "theme") == 0) {
 | 
				
			||||||
 | 
							free(cc->theme);
 | 
				
			||||||
 | 
							cc->theme = strdup(value);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "got unknown cursor config: %s", name);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void config_handle_keyboard(struct roots_config *config,
 | 
					static void config_handle_keyboard(struct roots_config *config,
 | 
				
			||||||
		const char *device_name, const char *name, const char *value) {
 | 
							const char *device_name, const char *name, const char *value) {
 | 
				
			||||||
	struct roots_keyboard_config *kc;
 | 
						struct roots_keyboard_config *kc;
 | 
				
			||||||
| 
						 | 
					@ -190,6 +221,7 @@ static void config_handle_keyboard(struct roots_config *config,
 | 
				
			||||||
static const char *output_prefix = "output:";
 | 
					static const char *output_prefix = "output:";
 | 
				
			||||||
static const char *device_prefix = "device:";
 | 
					static const char *device_prefix = "device:";
 | 
				
			||||||
static const char *keyboard_prefix = "keyboard:";
 | 
					static const char *keyboard_prefix = "keyboard:";
 | 
				
			||||||
 | 
					static const char *cursor_prefix = "cursor:";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int config_ini_handler(void *user, const char *section, const char *name,
 | 
					static int config_ini_handler(void *user, const char *section, const char *name,
 | 
				
			||||||
		const char *value) {
 | 
							const char *value) {
 | 
				
			||||||
| 
						 | 
					@ -269,16 +301,12 @@ static int config_ini_handler(void *user, const char *section, const char *name,
 | 
				
			||||||
					oc->name, oc->mode.width, oc->mode.height,
 | 
										oc->name, oc->mode.width, oc->mode.height,
 | 
				
			||||||
					oc->mode.refresh_rate);
 | 
										oc->mode.refresh_rate);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} else if (strncmp(cursor_prefix, section, strlen(cursor_prefix)) == 0) {
 | 
				
			||||||
 | 
							const char *seat_name = section + strlen(cursor_prefix);
 | 
				
			||||||
 | 
							config_handle_cursor(config, seat_name, name, value);
 | 
				
			||||||
	} else if (strcmp(section, "cursor") == 0) {
 | 
						} else if (strcmp(section, "cursor") == 0) {
 | 
				
			||||||
		if (strcmp(name, "map-to-output") == 0) {
 | 
							config_handle_cursor(config, ROOTS_CONFIG_DEFAULT_SEAT_NAME, name,
 | 
				
			||||||
			free(config->cursor.mapped_output);
 | 
								value);
 | 
				
			||||||
			config->cursor.mapped_output = strdup(value);
 | 
					 | 
				
			||||||
		} else if (strcmp(name, "geometry") == 0) {
 | 
					 | 
				
			||||||
			free(config->cursor.mapped_box);
 | 
					 | 
				
			||||||
			config->cursor.mapped_box = parse_geometry(value);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			wlr_log(L_ERROR, "got unknown cursor config: %s", name);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else if (strncmp(device_prefix, section, strlen(device_prefix)) == 0) {
 | 
						} else if (strncmp(device_prefix, section, strlen(device_prefix)) == 0) {
 | 
				
			||||||
		const char *device_name = section + strlen(device_prefix);
 | 
							const char *device_name = section + strlen(device_prefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -294,7 +322,7 @@ static int config_ini_handler(void *user, const char *section, const char *name,
 | 
				
			||||||
		if (!found) {
 | 
							if (!found) {
 | 
				
			||||||
			dc = calloc(1, sizeof(struct roots_device_config));
 | 
								dc = calloc(1, sizeof(struct roots_device_config));
 | 
				
			||||||
			dc->name = strdup(device_name);
 | 
								dc->name = strdup(device_name);
 | 
				
			||||||
			dc->seat = strdup("seat0");
 | 
								dc->seat = strdup(ROOTS_CONFIG_DEFAULT_SEAT_NAME);
 | 
				
			||||||
			wl_list_insert(&config->devices, &dc->link);
 | 
								wl_list_insert(&config->devices, &dc->link);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -335,6 +363,7 @@ struct roots_config *roots_config_create_from_args(int argc, char *argv[]) {
 | 
				
			||||||
	wl_list_init(&config->outputs);
 | 
						wl_list_init(&config->outputs);
 | 
				
			||||||
	wl_list_init(&config->devices);
 | 
						wl_list_init(&config->devices);
 | 
				
			||||||
	wl_list_init(&config->keyboards);
 | 
						wl_list_init(&config->keyboards);
 | 
				
			||||||
 | 
						wl_list_init(&config->cursors);
 | 
				
			||||||
	wl_list_init(&config->bindings);
 | 
						wl_list_init(&config->bindings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int c;
 | 
						int c;
 | 
				
			||||||
| 
						 | 
					@ -415,6 +444,15 @@ void roots_config_destroy(struct roots_config *config) {
 | 
				
			||||||
		free(kc);
 | 
							free(kc);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct roots_cursor_config *cc, *ctmp = NULL;
 | 
				
			||||||
 | 
						wl_list_for_each_safe(cc, ctmp, &config->cursors, link) {
 | 
				
			||||||
 | 
							free(cc->seat);
 | 
				
			||||||
 | 
							free(cc->mapped_output);
 | 
				
			||||||
 | 
							free(cc->mapped_box);
 | 
				
			||||||
 | 
							free(cc->theme);
 | 
				
			||||||
 | 
							free(cc);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct roots_binding_config *bc, *btmp = NULL;
 | 
						struct roots_binding_config *bc, *btmp = NULL;
 | 
				
			||||||
	wl_list_for_each_safe(bc, btmp, &config->bindings, link) {
 | 
						wl_list_for_each_safe(bc, btmp, &config->bindings, link) {
 | 
				
			||||||
		free(bc->keysyms);
 | 
							free(bc->keysyms);
 | 
				
			||||||
| 
						 | 
					@ -423,8 +461,6 @@ void roots_config_destroy(struct roots_config *config) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(config->config_path);
 | 
						free(config->config_path);
 | 
				
			||||||
	free(config->cursor.mapped_output);
 | 
					 | 
				
			||||||
	free(config->cursor.mapped_box);
 | 
					 | 
				
			||||||
	free(config);
 | 
						free(config);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -454,13 +490,33 @@ struct roots_device_config *roots_config_get_device(struct roots_config *config,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct roots_keyboard_config *roots_config_get_keyboard(
 | 
					struct roots_keyboard_config *roots_config_get_keyboard(
 | 
				
			||||||
		struct roots_config *config, struct wlr_input_device *device) {
 | 
							struct roots_config *config, struct wlr_input_device *device) {
 | 
				
			||||||
 | 
						const char *device_name = "";
 | 
				
			||||||
 | 
						if (device != NULL) {
 | 
				
			||||||
 | 
							device_name = device->name;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct roots_keyboard_config *kc;
 | 
						struct roots_keyboard_config *kc;
 | 
				
			||||||
	wl_list_for_each(kc, &config->keyboards, link) {
 | 
						wl_list_for_each(kc, &config->keyboards, link) {
 | 
				
			||||||
		if ((device != NULL && strcmp(kc->name, device->name) == 0) ||
 | 
							if (strcmp(kc->name, device_name) == 0) {
 | 
				
			||||||
				(device == NULL && strcmp(kc->name, "") == 0)) {
 | 
					 | 
				
			||||||
			return kc;
 | 
								return kc;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct roots_cursor_config *roots_config_get_cursor(struct roots_config *config,
 | 
				
			||||||
 | 
							const char *seat_name) {
 | 
				
			||||||
 | 
						if (seat_name == NULL) {
 | 
				
			||||||
 | 
							seat_name = ROOTS_CONFIG_DEFAULT_SEAT_NAME;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct roots_cursor_config *cc;
 | 
				
			||||||
 | 
						wl_list_for_each(cc, &config->cursors, link) {
 | 
				
			||||||
 | 
							if (strcmp(cc->seat, seat_name) == 0) {
 | 
				
			||||||
 | 
								return cc;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,8 @@ void roots_cursor_destroy(struct roots_cursor *cursor) {
 | 
				
			||||||
	// TODO
 | 
						// TODO
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) {
 | 
					static void roots_cursor_update_position(struct roots_cursor *cursor,
 | 
				
			||||||
 | 
							uint32_t time) {
 | 
				
			||||||
	struct roots_desktop *desktop = cursor->seat->input->server->desktop;
 | 
						struct roots_desktop *desktop = cursor->seat->input->server->desktop;
 | 
				
			||||||
	struct roots_seat *seat = cursor->seat;
 | 
						struct roots_seat *seat = cursor->seat;
 | 
				
			||||||
	struct roots_view *view;
 | 
						struct roots_view *view;
 | 
				
			||||||
| 
						 | 
					@ -122,15 +123,18 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void roots_cursor_press_button(struct roots_cursor *cursor,
 | 
					static void roots_cursor_press_button(struct roots_cursor *cursor,
 | 
				
			||||||
		struct wlr_input_device *device, uint32_t time, uint32_t button,
 | 
							struct wlr_input_device *device, uint32_t time, uint32_t button,
 | 
				
			||||||
		uint32_t state) {
 | 
							uint32_t state, double lx, double ly) {
 | 
				
			||||||
	struct roots_seat *seat = cursor->seat;
 | 
						struct roots_seat *seat = cursor->seat;
 | 
				
			||||||
	struct roots_desktop *desktop = seat->input->server->desktop;
 | 
						struct roots_desktop *desktop = seat->input->server->desktop;
 | 
				
			||||||
 | 
						bool is_touch = device->type == WLR_INPUT_DEVICE_TOUCH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_surface *surface;
 | 
						struct wlr_surface *surface;
 | 
				
			||||||
	double sx, sy;
 | 
						double sx, sy;
 | 
				
			||||||
	struct roots_view *view = view_at(desktop,
 | 
						struct roots_view *view = view_at(desktop, lx, ly, &surface, &sx, &sy);
 | 
				
			||||||
		cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) {
 | 
						if (state == WLR_BUTTON_PRESSED &&
 | 
				
			||||||
 | 
								view &&
 | 
				
			||||||
 | 
								roots_seat_has_meta_pressed(seat)) {
 | 
				
			||||||
		roots_seat_focus_view(seat, view);
 | 
							roots_seat_focus_view(seat, view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		uint32_t edges;
 | 
							uint32_t edges;
 | 
				
			||||||
| 
						 | 
					@ -159,14 +163,21 @@ static void roots_cursor_press_button(struct roots_cursor *cursor,
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint32_t serial =
 | 
						uint32_t serial;
 | 
				
			||||||
		wlr_seat_pointer_notify_button(seat->seat, time, button, state);
 | 
						if (is_touch) {
 | 
				
			||||||
 | 
							serial = wl_display_get_serial(desktop->server->wl_display);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							serial =
 | 
				
			||||||
 | 
								wlr_seat_pointer_notify_button(seat->seat, time, button, state);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	switch (state) {
 | 
						switch (state) {
 | 
				
			||||||
	case WLR_BUTTON_RELEASED:
 | 
						case WLR_BUTTON_RELEASED:
 | 
				
			||||||
		seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH;
 | 
							seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH;
 | 
				
			||||||
		roots_cursor_update_position(cursor, time);
 | 
							if (!is_touch) {
 | 
				
			||||||
 | 
								roots_cursor_update_position(cursor, time);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case WLR_BUTTON_PRESSED:
 | 
						case WLR_BUTTON_PRESSED:
 | 
				
			||||||
		i = cursor->input_events_idx;
 | 
							i = cursor->input_events_idx;
 | 
				
			||||||
| 
						 | 
					@ -197,7 +208,7 @@ void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor,
 | 
				
			||||||
void roots_cursor_handle_button(struct roots_cursor *cursor,
 | 
					void roots_cursor_handle_button(struct roots_cursor *cursor,
 | 
				
			||||||
		struct wlr_event_pointer_button *event) {
 | 
							struct wlr_event_pointer_button *event) {
 | 
				
			||||||
	roots_cursor_press_button(cursor, event->device, event->time_msec,
 | 
						roots_cursor_press_button(cursor, event->device, event->time_msec,
 | 
				
			||||||
		event->button, event->state);
 | 
							event->button, event->state, cursor->cursor->x, cursor->cursor->y);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void roots_cursor_handle_axis(struct roots_cursor *cursor,
 | 
					void roots_cursor_handle_axis(struct roots_cursor *cursor,
 | 
				
			||||||
| 
						 | 
					@ -208,50 +219,86 @@ void roots_cursor_handle_axis(struct roots_cursor *cursor,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void roots_cursor_handle_touch_down(struct roots_cursor *cursor,
 | 
					void roots_cursor_handle_touch_down(struct roots_cursor *cursor,
 | 
				
			||||||
		struct wlr_event_touch_down *event) {
 | 
							struct wlr_event_touch_down *event) {
 | 
				
			||||||
	struct roots_touch_point *point =
 | 
						struct roots_desktop *desktop = cursor->seat->input->server->desktop;
 | 
				
			||||||
		calloc(1, sizeof(struct roots_touch_point));
 | 
						struct wlr_surface *surface = NULL;
 | 
				
			||||||
	if (!point) {
 | 
						double lx, ly;
 | 
				
			||||||
		wlr_log(L_ERROR, "could not allocate memory for touch point");
 | 
						bool result =
 | 
				
			||||||
 | 
							wlr_cursor_absolute_to_layout_coords(cursor->cursor,
 | 
				
			||||||
 | 
								event->device, event->x_mm, event->y_mm, event->width_mm,
 | 
				
			||||||
 | 
								event->height_mm, &lx, &ly);
 | 
				
			||||||
 | 
						if (!result) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						double sx, sy;
 | 
				
			||||||
 | 
						view_at(desktop, lx, ly, &surface, &sx, &sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	point->device = event->device->data;
 | 
						uint32_t serial = 0;
 | 
				
			||||||
	point->slot = event->slot;
 | 
						if (surface) {
 | 
				
			||||||
	point->x = event->x_mm / event->width_mm;
 | 
							serial = wlr_seat_touch_notify_down(cursor->seat->seat, surface,
 | 
				
			||||||
	point->y = event->y_mm / event->height_mm;
 | 
								event->time_msec, event->touch_id, sx, sy);
 | 
				
			||||||
	wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y);
 | 
						}
 | 
				
			||||||
	roots_cursor_update_position(cursor, event->time_msec);
 | 
					
 | 
				
			||||||
	wl_list_insert(&cursor->touch_points, &point->link);
 | 
						if (serial && wlr_seat_touch_num_points(cursor->seat->seat) == 1) {
 | 
				
			||||||
	roots_cursor_press_button(cursor,  event->device,
 | 
							cursor->seat->touch_id = event->touch_id;
 | 
				
			||||||
		event->time_msec, BTN_LEFT, 1);
 | 
							cursor->seat->touch_x = lx;
 | 
				
			||||||
 | 
							cursor->seat->touch_y = ly;
 | 
				
			||||||
 | 
							roots_cursor_press_button(cursor, event->device, event->time_msec,
 | 
				
			||||||
 | 
								BTN_LEFT, 1, lx, ly);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void roots_cursor_handle_touch_up(struct roots_cursor *cursor,
 | 
					void roots_cursor_handle_touch_up(struct roots_cursor *cursor,
 | 
				
			||||||
		struct wlr_event_touch_up *event) {
 | 
							struct wlr_event_touch_up *event) {
 | 
				
			||||||
	struct roots_touch_point *point;
 | 
						struct wlr_touch_point *point =
 | 
				
			||||||
	wl_list_for_each(point, &cursor->touch_points, link) {
 | 
							wlr_seat_touch_get_point(cursor->seat->seat, event->touch_id);
 | 
				
			||||||
		if (point->slot == event->slot) {
 | 
						if (!point) {
 | 
				
			||||||
			wl_list_remove(&point->link);
 | 
							return;
 | 
				
			||||||
			free(point);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	roots_cursor_press_button(cursor, event->device,
 | 
					
 | 
				
			||||||
		event->time_msec, BTN_LEFT, 0);
 | 
						if (wlr_seat_touch_num_points(cursor->seat->seat) == 1) {
 | 
				
			||||||
 | 
							roots_cursor_press_button(cursor, event->device, event->time_msec,
 | 
				
			||||||
 | 
								BTN_LEFT, 0, cursor->seat->touch_x, cursor->seat->touch_y);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_seat_touch_notify_up(cursor->seat->seat, event->time_msec,
 | 
				
			||||||
 | 
							event->touch_id);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void roots_cursor_handle_touch_motion(struct roots_cursor *cursor,
 | 
					void roots_cursor_handle_touch_motion(struct roots_cursor *cursor,
 | 
				
			||||||
		struct wlr_event_touch_motion *event) {
 | 
							struct wlr_event_touch_motion *event) {
 | 
				
			||||||
	struct roots_touch_point *point;
 | 
						struct roots_desktop *desktop = cursor->seat->input->server->desktop;
 | 
				
			||||||
	wl_list_for_each(point, &cursor->touch_points, link) {
 | 
						struct wlr_touch_point *point =
 | 
				
			||||||
		if (point->slot == event->slot) {
 | 
							wlr_seat_touch_get_point(cursor->seat->seat, event->touch_id);
 | 
				
			||||||
			point->x = event->x_mm / event->width_mm;
 | 
						if (!point) {
 | 
				
			||||||
			point->y = event->y_mm / event->height_mm;
 | 
							return;
 | 
				
			||||||
			wlr_cursor_warp_absolute(cursor->cursor, event->device,
 | 
						}
 | 
				
			||||||
					point->x, point->y);
 | 
					
 | 
				
			||||||
			roots_cursor_update_position(cursor, event->time_msec);
 | 
						struct wlr_surface *surface = NULL;
 | 
				
			||||||
			break;
 | 
						double lx, ly;
 | 
				
			||||||
		}
 | 
						bool result =
 | 
				
			||||||
 | 
							wlr_cursor_absolute_to_layout_coords(cursor->cursor,
 | 
				
			||||||
 | 
								event->device, event->x_mm, event->y_mm, event->width_mm,
 | 
				
			||||||
 | 
								event->height_mm, &lx, &ly);
 | 
				
			||||||
 | 
						if (!result) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						double sx, sy;
 | 
				
			||||||
 | 
						view_at(desktop, lx, ly, &surface, &sx, &sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (surface) {
 | 
				
			||||||
 | 
							wlr_seat_touch_point_focus(cursor->seat->seat, surface,
 | 
				
			||||||
 | 
								event->time_msec, event->touch_id, sx, sy);
 | 
				
			||||||
 | 
							wlr_seat_touch_notify_motion(cursor->seat->seat, event->time_msec,
 | 
				
			||||||
 | 
								event->touch_id, sx, sy);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							wlr_seat_touch_point_clear_focus(cursor->seat->seat, event->time_msec,
 | 
				
			||||||
 | 
								event->touch_id);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (event->touch_id == cursor->seat->touch_id) {
 | 
				
			||||||
 | 
							cursor->seat->touch_x = lx;
 | 
				
			||||||
 | 
							cursor->seat->touch_y = ly;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -276,14 +323,16 @@ void roots_cursor_handle_tool_axis(struct roots_cursor *cursor,
 | 
				
			||||||
void roots_cursor_handle_tool_tip(struct roots_cursor *cursor,
 | 
					void roots_cursor_handle_tool_tip(struct roots_cursor *cursor,
 | 
				
			||||||
		struct wlr_event_tablet_tool_tip *event) {
 | 
							struct wlr_event_tablet_tool_tip *event) {
 | 
				
			||||||
	roots_cursor_press_button(cursor, event->device,
 | 
						roots_cursor_press_button(cursor, event->device,
 | 
				
			||||||
		event->time_msec, BTN_LEFT, event->state);
 | 
							event->time_msec, BTN_LEFT, event->state, cursor->cursor->x,
 | 
				
			||||||
 | 
							cursor->cursor->y);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor,
 | 
					void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor,
 | 
				
			||||||
		struct wlr_seat_pointer_request_set_cursor_event *event) {
 | 
							struct wlr_seat_pointer_request_set_cursor_event *event) {
 | 
				
			||||||
	struct wlr_surface *focused_surface =
 | 
						struct wlr_surface *focused_surface =
 | 
				
			||||||
		event->seat_client->seat->pointer_state.focused_surface;
 | 
							event->seat_client->seat->pointer_state.focused_surface;
 | 
				
			||||||
	bool has_focused = focused_surface != NULL && focused_surface->resource != NULL;
 | 
						bool has_focused =
 | 
				
			||||||
 | 
							focused_surface != NULL && focused_surface->resource != NULL;
 | 
				
			||||||
	struct wl_client *focused_client = NULL;
 | 
						struct wl_client *focused_client = NULL;
 | 
				
			||||||
	if (has_focused) {
 | 
						if (has_focused) {
 | 
				
			||||||
		focused_client = wl_resource_get_client(focused_surface->resource);
 | 
							focused_client = wl_resource_get_client(focused_surface->resource);
 | 
				
			||||||
| 
						 | 
					@ -299,65 +348,3 @@ void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor,
 | 
				
			||||||
		event->hotspot_y);
 | 
							event->hotspot_y);
 | 
				
			||||||
	cursor->cursor_client = event->seat_client->client;
 | 
						cursor->cursor_client = event->seat_client->client;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
static void handle_drag_icon_commit(struct wl_listener *listener, void *data) {
 | 
					 | 
				
			||||||
	struct roots_drag_icon *drag_icon =
 | 
					 | 
				
			||||||
		wl_container_of(listener, drag_icon, surface_commit);
 | 
					 | 
				
			||||||
	drag_icon->sx += drag_icon->surface->current->sx;
 | 
					 | 
				
			||||||
	drag_icon->sy += drag_icon->surface->current->sy;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) {
 | 
					 | 
				
			||||||
	struct roots_drag_icon *drag_icon =
 | 
					 | 
				
			||||||
		wl_container_of(listener, drag_icon, surface_destroy);
 | 
					 | 
				
			||||||
	wl_list_remove(&drag_icon->link);
 | 
					 | 
				
			||||||
	wl_list_remove(&drag_icon->surface_destroy.link);
 | 
					 | 
				
			||||||
	wl_list_remove(&drag_icon->surface_commit.link);
 | 
					 | 
				
			||||||
	free(drag_icon);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor,
 | 
					 | 
				
			||||||
		struct wlr_seat_pointer_grab *grab) {
 | 
					 | 
				
			||||||
	struct roots_seat *seat = cursor->seat;
 | 
					 | 
				
			||||||
	if (grab->interface == &wlr_data_device_pointer_drag_interface) {
 | 
					 | 
				
			||||||
		struct wlr_drag *drag = grab->data;
 | 
					 | 
				
			||||||
		if (drag->icon) {
 | 
					 | 
				
			||||||
			struct roots_drag_icon *iter_icon;
 | 
					 | 
				
			||||||
			wl_list_for_each(iter_icon, &seat->drag_icons, link) {
 | 
					 | 
				
			||||||
				if (iter_icon->surface == drag->icon) {
 | 
					 | 
				
			||||||
					// already in the list
 | 
					 | 
				
			||||||
					return;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			struct roots_drag_icon *drag_icon =
 | 
					 | 
				
			||||||
				calloc(1, sizeof(struct roots_drag_icon));
 | 
					 | 
				
			||||||
			drag_icon->mapped = true;
 | 
					 | 
				
			||||||
			drag_icon->surface = drag->icon;
 | 
					 | 
				
			||||||
			wl_list_insert(&seat->drag_icons, &drag_icon->link);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wl_signal_add(&drag->icon->events.destroy,
 | 
					 | 
				
			||||||
				&drag_icon->surface_destroy);
 | 
					 | 
				
			||||||
			drag_icon->surface_destroy.notify = handle_drag_icon_destroy;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			wl_signal_add(&drag->icon->events.commit,
 | 
					 | 
				
			||||||
				&drag_icon->surface_commit);
 | 
					 | 
				
			||||||
			drag_icon->surface_commit.notify = handle_drag_icon_commit;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor,
 | 
					 | 
				
			||||||
		struct wlr_seat_pointer_grab *grab) {
 | 
					 | 
				
			||||||
	if (grab->interface == &wlr_data_device_pointer_drag_interface) {
 | 
					 | 
				
			||||||
		struct wlr_drag *drag = grab->data;
 | 
					 | 
				
			||||||
		struct roots_drag_icon *icon;
 | 
					 | 
				
			||||||
		wl_list_for_each(icon, &cursor->seat->drag_icons, link) {
 | 
					 | 
				
			||||||
			if (icon->surface == drag->icon) {
 | 
					 | 
				
			||||||
				icon->mapped = false;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	roots_cursor_update_position(cursor, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -343,10 +343,18 @@ struct roots_desktop *desktop_create(struct roots_server *server,
 | 
				
			||||||
	desktop->server = server;
 | 
						desktop->server = server;
 | 
				
			||||||
	desktop->config = config;
 | 
						desktop->config = config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	desktop->xcursor_manager = wlr_xcursor_manager_create(NULL,
 | 
						const char *cursor_theme = NULL;
 | 
				
			||||||
 | 
						struct roots_cursor_config *cc =
 | 
				
			||||||
 | 
							roots_config_get_cursor(config, ROOTS_CONFIG_DEFAULT_SEAT_NAME);
 | 
				
			||||||
 | 
						if (cc != NULL) {
 | 
				
			||||||
 | 
							cursor_theme = cc->theme;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						desktop->xcursor_manager = wlr_xcursor_manager_create(cursor_theme,
 | 
				
			||||||
		ROOTS_XCURSOR_SIZE);
 | 
							ROOTS_XCURSOR_SIZE);
 | 
				
			||||||
	if (desktop->xcursor_manager == NULL) {
 | 
						if (desktop->xcursor_manager == NULL) {
 | 
				
			||||||
		wlr_log(L_ERROR, "Cannot create XCursor manager");
 | 
							wlr_log(L_ERROR, "Cannot create XCursor manager for theme %s",
 | 
				
			||||||
 | 
								cursor_theme);
 | 
				
			||||||
		wlr_list_free(desktop->views);
 | 
							wlr_list_free(desktop->views);
 | 
				
			||||||
		free(desktop);
 | 
							free(desktop);
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,7 @@ static void input_add_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_input_device *device = data;
 | 
						struct wlr_input_device *device = data;
 | 
				
			||||||
	struct roots_input *input = wl_container_of(listener, input, input_add);
 | 
						struct roots_input *input = wl_container_of(listener, input, input_add);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char *seat_name = "seat0";
 | 
						char *seat_name = ROOTS_CONFIG_DEFAULT_SEAT_NAME;
 | 
				
			||||||
	struct roots_device_config *dc =
 | 
						struct roots_device_config *dc =
 | 
				
			||||||
		roots_config_get_device(input->config, device);
 | 
							roots_config_get_device(input->config, device);
 | 
				
			||||||
	if (dc) {
 | 
						if (dc) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,8 +59,9 @@ int main(int argc, char **argv) {
 | 
				
			||||||
	ready(NULL, NULL);
 | 
						ready(NULL, NULL);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	if (server.desktop->xwayland != NULL) {
 | 
						if (server.desktop->xwayland != NULL) {
 | 
				
			||||||
		struct wl_listener xwayland_ready = { .notify = ready };
 | 
							wl_signal_add(&server.desktop->xwayland->events.ready,
 | 
				
			||||||
		wl_signal_add(&server.desktop->xwayland->events.ready, &xwayland_ready);
 | 
								&server.desktop->xwayland_ready);
 | 
				
			||||||
 | 
							server.desktop->xwayland_ready.notify = ready;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ready(NULL, NULL);
 | 
							ready(NULL, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,18 +191,29 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
		render_view(view, desktop, wlr_output, &now);
 | 
							render_view(view, desktop, wlr_output, &now);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct roots_drag_icon *drag_icon = NULL;
 | 
						struct wlr_drag_icon *drag_icon = NULL;
 | 
				
			||||||
	struct roots_seat *seat = NULL;
 | 
						struct roots_seat *seat = NULL;
 | 
				
			||||||
	wl_list_for_each(seat, &server->input->seats, link) {
 | 
						wl_list_for_each(seat, &server->input->seats, link) {
 | 
				
			||||||
		wl_list_for_each(drag_icon, &seat->drag_icons, link) {
 | 
							wl_list_for_each(drag_icon, &seat->seat->drag_icons, link) {
 | 
				
			||||||
			if (!drag_icon->mapped) {
 | 
								if (!drag_icon->mapped) {
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			struct wlr_surface *icon = drag_icon->surface;
 | 
								struct wlr_surface *icon = drag_icon->surface;
 | 
				
			||||||
			struct wlr_cursor *cursor = seat->cursor->cursor;
 | 
								struct wlr_cursor *cursor = seat->cursor->cursor;
 | 
				
			||||||
			double icon_x = cursor->x + drag_icon->sx;
 | 
								double icon_x = 0, icon_y = 0;
 | 
				
			||||||
			double icon_y = cursor->y + drag_icon->sy;
 | 
								if (drag_icon->is_pointer) {
 | 
				
			||||||
			render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0);
 | 
									icon_x = cursor->x + drag_icon->sx;
 | 
				
			||||||
 | 
									icon_y = cursor->y + drag_icon->sy;
 | 
				
			||||||
 | 
									render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									struct wlr_touch_point *point =
 | 
				
			||||||
 | 
										wlr_seat_touch_get_point(seat->seat, drag_icon->touch_id);
 | 
				
			||||||
 | 
									if (point) {
 | 
				
			||||||
 | 
										icon_x = seat->touch_x + drag_icon->sx;
 | 
				
			||||||
 | 
										icon_y = seat->touch_y + drag_icon->sy;
 | 
				
			||||||
 | 
										render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,8 @@ rotate = 90
 | 
				
			||||||
map-to-output = VGA-1
 | 
					map-to-output = VGA-1
 | 
				
			||||||
# Restrict cursor movements to concrete rectangle
 | 
					# Restrict cursor movements to concrete rectangle
 | 
				
			||||||
geometry = 2500x800
 | 
					geometry = 2500x800
 | 
				
			||||||
 | 
					# Load a custom XCursor theme
 | 
				
			||||||
 | 
					theme = default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Single device configuration. String after semicolon must match device's name.
 | 
					# Single device configuration. String after semicolon must match device's name.
 | 
				
			||||||
[device:PixArt Dell MS116 USB Optical Mouse]
 | 
					[device:PixArt Dell MS116 USB Optical Mouse]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,8 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	roots_cursor_handle_motion(cursor, event);
 | 
						roots_cursor_handle_motion(cursor, event);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) {
 | 
					static void handle_cursor_motion_absolute(struct wl_listener *listener,
 | 
				
			||||||
 | 
							void *data) {
 | 
				
			||||||
	struct roots_cursor *cursor =
 | 
						struct roots_cursor *cursor =
 | 
				
			||||||
		wl_container_of(listener, cursor, motion_absolute);
 | 
							wl_container_of(listener, cursor, motion_absolute);
 | 
				
			||||||
	struct wlr_event_pointer_motion_absolute *event = data;
 | 
						struct wlr_event_pointer_motion_absolute *event = data;
 | 
				
			||||||
| 
						 | 
					@ -95,23 +96,8 @@ static void handle_request_set_cursor(struct wl_listener *listener,
 | 
				
			||||||
	roots_cursor_handle_request_set_cursor(cursor, event);
 | 
						roots_cursor_handle_request_set_cursor(cursor, event);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_pointer_grab_begin(struct wl_listener *listener,
 | 
					static void seat_reset_device_mappings(struct roots_seat *seat,
 | 
				
			||||||
		void *data) {
 | 
							struct wlr_input_device *device) {
 | 
				
			||||||
	struct roots_cursor *cursor =
 | 
					 | 
				
			||||||
		wl_container_of(listener, cursor, pointer_grab_begin);
 | 
					 | 
				
			||||||
	struct wlr_seat_pointer_grab *grab = data;
 | 
					 | 
				
			||||||
	roots_cursor_handle_pointer_grab_begin(cursor, grab);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void handle_pointer_grab_end(struct wl_listener *listener,
 | 
					 | 
				
			||||||
		void *data) {
 | 
					 | 
				
			||||||
	struct roots_cursor *cursor =
 | 
					 | 
				
			||||||
		wl_container_of(listener, cursor, pointer_grab_end);
 | 
					 | 
				
			||||||
	struct wlr_seat_pointer_grab *grab = data;
 | 
					 | 
				
			||||||
	roots_cursor_handle_pointer_grab_end(cursor, grab);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) {
 | 
					 | 
				
			||||||
	struct wlr_cursor *cursor = seat->cursor->cursor;
 | 
						struct wlr_cursor *cursor = seat->cursor->cursor;
 | 
				
			||||||
	struct roots_config *config = seat->input->config;
 | 
						struct roots_config *config = seat->input->config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -157,20 +143,29 @@ void roots_seat_configure_cursor(struct roots_seat *seat) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// configure device to output mappings
 | 
						// configure device to output mappings
 | 
				
			||||||
	const char *mapped_output = config->cursor.mapped_output;
 | 
						const char *mapped_output = NULL;
 | 
				
			||||||
 | 
						struct roots_cursor_config *cc =
 | 
				
			||||||
 | 
							roots_config_get_cursor(config, seat->seat->name);
 | 
				
			||||||
 | 
						if (cc != NULL) {
 | 
				
			||||||
 | 
							mapped_output = cc->mapped_output;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	wl_list_for_each(output, &desktop->outputs, link) {
 | 
						wl_list_for_each(output, &desktop->outputs, link) {
 | 
				
			||||||
		if (mapped_output && strcmp(mapped_output, output->wlr_output->name) == 0) {
 | 
							if (mapped_output &&
 | 
				
			||||||
 | 
									strcmp(mapped_output, output->wlr_output->name) == 0) {
 | 
				
			||||||
			wlr_cursor_map_to_output(cursor, output->wlr_output);
 | 
								wlr_cursor_map_to_output(cursor, output->wlr_output);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wl_list_for_each(pointer, &seat->pointers, link) {
 | 
							wl_list_for_each(pointer, &seat->pointers, link) {
 | 
				
			||||||
			seat_set_device_output_mappings(seat, pointer->device, output->wlr_output);
 | 
								seat_set_device_output_mappings(seat, pointer->device,
 | 
				
			||||||
 | 
									output->wlr_output);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		wl_list_for_each(tablet_tool, &seat->tablet_tools, link) {
 | 
							wl_list_for_each(tablet_tool, &seat->tablet_tools, link) {
 | 
				
			||||||
			seat_set_device_output_mappings(seat, tablet_tool->device, output->wlr_output);
 | 
								seat_set_device_output_mappings(seat, tablet_tool->device,
 | 
				
			||||||
 | 
									output->wlr_output);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		wl_list_for_each(touch, &seat->touch, link) {
 | 
							wl_list_for_each(touch, &seat->touch, link) {
 | 
				
			||||||
			seat_set_device_output_mappings(seat, touch->device, output->wlr_output);
 | 
								seat_set_device_output_mappings(seat, touch->device,
 | 
				
			||||||
 | 
									output->wlr_output);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -185,11 +180,6 @@ static void roots_seat_init_cursor(struct roots_seat *seat) {
 | 
				
			||||||
	struct roots_desktop *desktop = seat->input->server->desktop;
 | 
						struct roots_desktop *desktop = seat->input->server->desktop;
 | 
				
			||||||
	wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout);
 | 
						wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: be able to configure per-seat cursor themes
 | 
					 | 
				
			||||||
	seat->cursor->xcursor_manager = desktop->xcursor_manager;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wl_list_init(&seat->cursor->touch_points);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	roots_seat_configure_cursor(seat);
 | 
						roots_seat_configure_cursor(seat);
 | 
				
			||||||
	roots_seat_configure_xcursor(seat);
 | 
						roots_seat_configure_xcursor(seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,10 +203,12 @@ static void roots_seat_init_cursor(struct roots_seat *seat) {
 | 
				
			||||||
	wl_signal_add(&wlr_cursor->events.touch_up, &seat->cursor->touch_up);
 | 
						wl_signal_add(&wlr_cursor->events.touch_up, &seat->cursor->touch_up);
 | 
				
			||||||
	seat->cursor->touch_up.notify = handle_touch_up;
 | 
						seat->cursor->touch_up.notify = handle_touch_up;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_add(&wlr_cursor->events.touch_motion, &seat->cursor->touch_motion);
 | 
						wl_signal_add(&wlr_cursor->events.touch_motion,
 | 
				
			||||||
 | 
							&seat->cursor->touch_motion);
 | 
				
			||||||
	seat->cursor->touch_motion.notify = handle_touch_motion;
 | 
						seat->cursor->touch_motion.notify = handle_touch_motion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_add(&wlr_cursor->events.tablet_tool_axis, &seat->cursor->tool_axis);
 | 
						wl_signal_add(&wlr_cursor->events.tablet_tool_axis,
 | 
				
			||||||
 | 
							&seat->cursor->tool_axis);
 | 
				
			||||||
	seat->cursor->tool_axis.notify = handle_tool_axis;
 | 
						seat->cursor->tool_axis.notify = handle_tool_axis;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &seat->cursor->tool_tip);
 | 
						wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &seat->cursor->tool_tip);
 | 
				
			||||||
| 
						 | 
					@ -225,14 +217,6 @@ static void roots_seat_init_cursor(struct roots_seat *seat) {
 | 
				
			||||||
	wl_signal_add(&seat->seat->events.request_set_cursor,
 | 
						wl_signal_add(&seat->seat->events.request_set_cursor,
 | 
				
			||||||
			&seat->cursor->request_set_cursor);
 | 
								&seat->cursor->request_set_cursor);
 | 
				
			||||||
	seat->cursor->request_set_cursor.notify = handle_request_set_cursor;
 | 
						seat->cursor->request_set_cursor.notify = handle_request_set_cursor;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	wl_signal_add(&seat->seat->events.pointer_grab_begin,
 | 
					 | 
				
			||||||
			&seat->cursor->pointer_grab_begin);
 | 
					 | 
				
			||||||
	seat->cursor->pointer_grab_begin.notify = handle_pointer_grab_begin;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wl_signal_add(&seat->seat->events.pointer_grab_end,
 | 
					 | 
				
			||||||
			&seat->cursor->pointer_grab_end);
 | 
					 | 
				
			||||||
	seat->cursor->pointer_grab_end.notify = handle_pointer_grab_end;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct roots_seat *roots_seat_create(struct roots_input *input, char *name) {
 | 
					struct roots_seat *roots_seat_create(struct roots_input *input, char *name) {
 | 
				
			||||||
| 
						 | 
					@ -245,7 +229,6 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) {
 | 
				
			||||||
	wl_list_init(&seat->pointers);
 | 
						wl_list_init(&seat->pointers);
 | 
				
			||||||
	wl_list_init(&seat->touch);
 | 
						wl_list_init(&seat->touch);
 | 
				
			||||||
	wl_list_init(&seat->tablet_tools);
 | 
						wl_list_init(&seat->tablet_tools);
 | 
				
			||||||
	wl_list_init(&seat->drag_icons);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	seat->input = input;
 | 
						seat->input = input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -276,9 +259,11 @@ void roots_seat_destroy(struct roots_seat *seat) {
 | 
				
			||||||
	// TODO
 | 
						// TODO
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) {
 | 
					static void seat_add_keyboard(struct roots_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_input_device *device) {
 | 
				
			||||||
	assert(device->type == WLR_INPUT_DEVICE_KEYBOARD);
 | 
						assert(device->type == WLR_INPUT_DEVICE_KEYBOARD);
 | 
				
			||||||
	struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input);
 | 
						struct roots_keyboard *keyboard =
 | 
				
			||||||
 | 
							roots_keyboard_create(device, seat->input);
 | 
				
			||||||
	if (keyboard == NULL) {
 | 
						if (keyboard == NULL) {
 | 
				
			||||||
		wlr_log(L_ERROR, "could not allocate keyboard for seat");
 | 
							wlr_log(L_ERROR, "could not allocate keyboard for seat");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -299,7 +284,8 @@ static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *
 | 
				
			||||||
	wlr_seat_set_keyboard(seat->seat, device);
 | 
						wlr_seat_set_keyboard(seat->seat, device);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void seat_add_pointer(struct roots_seat *seat, struct wlr_input_device *device) {
 | 
					static void seat_add_pointer(struct roots_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_input_device *device) {
 | 
				
			||||||
	struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1);
 | 
						struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1);
 | 
				
			||||||
	if (!pointer) {
 | 
						if (!pointer) {
 | 
				
			||||||
		wlr_log(L_ERROR, "could not allocate pointer for seat");
 | 
							wlr_log(L_ERROR, "could not allocate pointer for seat");
 | 
				
			||||||
| 
						 | 
					@ -314,7 +300,8 @@ static void seat_add_pointer(struct roots_seat *seat, struct wlr_input_device *d
 | 
				
			||||||
	roots_seat_configure_cursor(seat);
 | 
						roots_seat_configure_cursor(seat);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void seat_add_touch(struct roots_seat *seat, struct wlr_input_device *device) {
 | 
					static void seat_add_touch(struct roots_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_input_device *device) {
 | 
				
			||||||
	struct roots_touch *touch = calloc(sizeof(struct roots_touch), 1);
 | 
						struct roots_touch *touch = calloc(sizeof(struct roots_touch), 1);
 | 
				
			||||||
	if (!touch) {
 | 
						if (!touch) {
 | 
				
			||||||
		wlr_log(L_ERROR, "could not allocate touch for seat");
 | 
							wlr_log(L_ERROR, "could not allocate touch for seat");
 | 
				
			||||||
| 
						 | 
					@ -329,12 +316,15 @@ static void seat_add_touch(struct roots_seat *seat, struct wlr_input_device *dev
 | 
				
			||||||
	roots_seat_configure_cursor(seat);
 | 
						roots_seat_configure_cursor(seat);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void seat_add_tablet_pad(struct roots_seat *seat, struct wlr_input_device *device) {
 | 
					static void seat_add_tablet_pad(struct roots_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_input_device *device) {
 | 
				
			||||||
	// TODO
 | 
						// TODO
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void seat_add_tablet_tool(struct roots_seat *seat, struct wlr_input_device *device) {
 | 
					static void seat_add_tablet_tool(struct roots_seat *seat,
 | 
				
			||||||
	struct roots_tablet_tool *tablet_tool = calloc(sizeof(struct roots_tablet_tool), 1);
 | 
							struct wlr_input_device *device) {
 | 
				
			||||||
 | 
						struct roots_tablet_tool *tablet_tool =
 | 
				
			||||||
 | 
							calloc(sizeof(struct roots_tablet_tool), 1);
 | 
				
			||||||
	if (!tablet_tool) {
 | 
						if (!tablet_tool) {
 | 
				
			||||||
		wlr_log(L_ERROR, "could not allocate tablet_tool for seat");
 | 
							wlr_log(L_ERROR, "could not allocate tablet_tool for seat");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -446,6 +436,21 @@ void roots_seat_remove_device(struct roots_seat *seat,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void roots_seat_configure_xcursor(struct roots_seat *seat) {
 | 
					void roots_seat_configure_xcursor(struct roots_seat *seat) {
 | 
				
			||||||
 | 
						const char *cursor_theme = NULL;
 | 
				
			||||||
 | 
						struct roots_cursor_config *cc =
 | 
				
			||||||
 | 
							roots_config_get_cursor(seat->input->config, seat->seat->name);
 | 
				
			||||||
 | 
						if (cc != NULL) {
 | 
				
			||||||
 | 
							cursor_theme = cc->theme;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						seat->cursor->xcursor_manager =
 | 
				
			||||||
 | 
							wlr_xcursor_manager_create(cursor_theme, ROOTS_XCURSOR_SIZE);
 | 
				
			||||||
 | 
						if (seat->cursor->xcursor_manager == NULL) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "Cannot create XCursor manager for theme %s",
 | 
				
			||||||
 | 
								cursor_theme);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct roots_output *output;
 | 
						struct roots_output *output;
 | 
				
			||||||
	wl_list_for_each(output, &seat->input->server->desktop->outputs, link) {
 | 
						wl_list_for_each(output, &seat->input->server->desktop->outputs, link) {
 | 
				
			||||||
		if (wlr_xcursor_manager_load(seat->cursor->xcursor_manager,
 | 
							if (wlr_xcursor_manager_load(seat->cursor->xcursor_manager,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -637,3 +637,21 @@ void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c_device->mapped_box = box;
 | 
						c_device->mapped_box = box;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur,
 | 
				
			||||||
 | 
							struct wlr_input_device *device, double x_mm, double y_mm,
 | 
				
			||||||
 | 
							double width_mm, double height_mm, double *lx, double *ly) {
 | 
				
			||||||
 | 
						if (width_mm <= 0 || height_mm <= 0) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_box *mapping = get_mapping(cur, device);
 | 
				
			||||||
 | 
						if (!mapping) {
 | 
				
			||||||
 | 
							mapping = wlr_output_layout_get_box(cur->state->layout, NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*lx = x_mm > 0 ? mapping->width * (x_mm / width_mm) + mapping->x : cur->x;
 | 
				
			||||||
 | 
						*ly = y_mm > 0 ? mapping->height * (y_mm / height_mm) + mapping->y : cur->y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -275,7 +275,8 @@ void wlr_seat_client_send_selection(struct wlr_seat_client *seat_client) {
 | 
				
			||||||
		struct wlr_data_offer *offer =
 | 
							struct wlr_data_offer *offer =
 | 
				
			||||||
			wlr_data_source_send_offer(seat_client->seat->selection_source,
 | 
								wlr_data_source_send_offer(seat_client->seat->selection_source,
 | 
				
			||||||
				seat_client->data_device);
 | 
									seat_client->data_device);
 | 
				
			||||||
		wl_data_device_send_selection(seat_client->data_device, offer->resource);
 | 
							wl_data_device_send_selection(seat_client->data_device,
 | 
				
			||||||
 | 
								offer->resource);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		wl_data_device_send_selection(seat_client->data_device, NULL);
 | 
							wl_data_device_send_selection(seat_client->data_device, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -351,15 +352,13 @@ static void data_device_release(struct wl_client *client,
 | 
				
			||||||
	wl_resource_destroy(resource);
 | 
						wl_resource_destroy(resource);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void drag_client_seat_unbound(struct wl_listener *listener, void *data) {
 | 
					static void handle_drag_seat_client_destroy(struct wl_listener *listener,
 | 
				
			||||||
 | 
							void *data) {
 | 
				
			||||||
	struct wlr_drag *drag =
 | 
						struct wlr_drag *drag =
 | 
				
			||||||
		wl_container_of(listener, drag, seat_client_unbound);
 | 
							wl_container_of(listener, drag, seat_client_destroy);
 | 
				
			||||||
	struct wlr_seat_client *unbound_client = data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (drag->focus_client == unbound_client) {
 | 
						drag->focus_client = NULL;
 | 
				
			||||||
		drag->focus_client = NULL;
 | 
						wl_list_remove(&drag->seat_client_destroy.link);
 | 
				
			||||||
		wl_list_remove(&drag->seat_client_unbound.link);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void wlr_drag_set_focus(struct wlr_drag *drag,
 | 
					static void wlr_drag_set_focus(struct wlr_drag *drag,
 | 
				
			||||||
| 
						 | 
					@ -369,7 +368,7 @@ static void wlr_drag_set_focus(struct wlr_drag *drag,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (drag->focus_client && drag->focus_client->data_device) {
 | 
						if (drag->focus_client && drag->focus_client->data_device) {
 | 
				
			||||||
		wl_list_remove(&drag->seat_client_unbound.link);
 | 
							wl_list_remove(&drag->seat_client_destroy.link);
 | 
				
			||||||
		wl_data_device_send_leave(drag->focus_client->data_device);
 | 
							wl_data_device_send_leave(drag->focus_client->data_device);
 | 
				
			||||||
		drag->focus_client = NULL;
 | 
							drag->focus_client = NULL;
 | 
				
			||||||
		drag->focus = NULL;
 | 
							drag->focus = NULL;
 | 
				
			||||||
| 
						 | 
					@ -429,16 +428,20 @@ static void wlr_drag_set_focus(struct wlr_drag *drag,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drag->focus = surface;
 | 
						drag->focus = surface;
 | 
				
			||||||
	drag->focus_client = focus_client;
 | 
						drag->focus_client = focus_client;
 | 
				
			||||||
	drag->seat_client_unbound.notify = drag_client_seat_unbound;
 | 
						drag->seat_client_destroy.notify = handle_drag_seat_client_destroy;
 | 
				
			||||||
	wl_signal_add(&focus_client->seat->events.client_unbound,
 | 
						wl_signal_add(&focus_client->events.destroy,
 | 
				
			||||||
		&drag->seat_client_unbound);
 | 
							&drag->seat_client_destroy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void wlr_drag_end(struct wlr_drag *drag) {
 | 
					static void wlr_drag_end(struct wlr_drag *drag) {
 | 
				
			||||||
	if (!drag->cancelling) {
 | 
						if (!drag->cancelling) {
 | 
				
			||||||
		drag->cancelling = true;
 | 
							drag->cancelling = true;
 | 
				
			||||||
		wlr_seat_pointer_end_grab(drag->pointer_grab.seat);
 | 
							if (drag->is_pointer_grab) {
 | 
				
			||||||
		wlr_seat_keyboard_end_grab(drag->keyboard_grab.seat);
 | 
								wlr_seat_pointer_end_grab(drag->seat);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								wlr_seat_touch_end_grab(drag->seat);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							wlr_seat_keyboard_end_grab(drag->seat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (drag->source) {
 | 
							if (drag->source) {
 | 
				
			||||||
			wl_list_remove(&drag->source_destroy.link);
 | 
								wl_list_remove(&drag->source_destroy.link);
 | 
				
			||||||
| 
						 | 
					@ -447,6 +450,7 @@ static void wlr_drag_end(struct wlr_drag *drag) {
 | 
				
			||||||
		wlr_drag_set_focus(drag, NULL, 0, 0);
 | 
							wlr_drag_set_focus(drag, NULL, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (drag->icon) {
 | 
							if (drag->icon) {
 | 
				
			||||||
 | 
								drag->icon->mapped = false;
 | 
				
			||||||
			wl_list_remove(&drag->icon_destroy.link);
 | 
								wl_list_remove(&drag->icon_destroy.link);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -521,6 +525,54 @@ wlr_pointer_grab_interface wlr_data_device_pointer_drag_interface = {
 | 
				
			||||||
	.cancel = pointer_drag_cancel,
 | 
						.cancel = pointer_drag_cancel,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t touch_drag_down(struct wlr_seat_touch_grab *grab,
 | 
				
			||||||
 | 
							uint32_t time, struct wlr_touch_point *point) {
 | 
				
			||||||
 | 
						// eat the event
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void touch_drag_up(struct wlr_seat_touch_grab *grab, uint32_t time,
 | 
				
			||||||
 | 
							struct wlr_touch_point *point) {
 | 
				
			||||||
 | 
						struct wlr_drag *drag = grab->data;
 | 
				
			||||||
 | 
						if (drag->grab_touch_id != point->touch_id) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (drag->focus_client && drag->focus_client->data_device) {
 | 
				
			||||||
 | 
							wl_data_device_send_drop(drag->focus_client->data_device);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_drag_end(drag);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void touch_drag_motion(struct wlr_seat_touch_grab *grab, uint32_t time,
 | 
				
			||||||
 | 
							struct wlr_touch_point *point) {
 | 
				
			||||||
 | 
						struct wlr_drag *drag = grab->data;
 | 
				
			||||||
 | 
						if (drag->focus && drag->focus_client && drag->focus_client->data_device) {
 | 
				
			||||||
 | 
							wl_data_device_send_motion(drag->focus_client->data_device, time,
 | 
				
			||||||
 | 
								wl_fixed_from_double(point->sx), wl_fixed_from_double(point->sy));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void touch_drag_enter(struct wlr_seat_touch_grab *grab, uint32_t time,
 | 
				
			||||||
 | 
							struct wlr_touch_point *point) {
 | 
				
			||||||
 | 
						struct wlr_drag *drag = grab->data;
 | 
				
			||||||
 | 
						wlr_drag_set_focus(drag, point->focus_surface, point->sx, point->sy);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void touch_drag_cancel(struct wlr_seat_touch_grab *grab) {
 | 
				
			||||||
 | 
						struct wlr_drag *drag = grab->data;
 | 
				
			||||||
 | 
						wlr_drag_end(drag);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct wlr_touch_grab_interface wlr_data_device_touch_drag_interface = {
 | 
				
			||||||
 | 
						.down = touch_drag_down,
 | 
				
			||||||
 | 
						.up = touch_drag_up,
 | 
				
			||||||
 | 
						.motion = touch_drag_motion,
 | 
				
			||||||
 | 
						.enter = touch_drag_enter,
 | 
				
			||||||
 | 
						.cancel = touch_drag_cancel,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void keyboard_drag_enter(struct wlr_seat_keyboard_grab *grab,
 | 
					static void keyboard_drag_enter(struct wlr_seat_keyboard_grab *grab,
 | 
				
			||||||
		struct wlr_surface *surface) {
 | 
							struct wlr_surface *surface) {
 | 
				
			||||||
	// nothing has keyboard focus during drags
 | 
						// nothing has keyboard focus during drags
 | 
				
			||||||
| 
						 | 
					@ -561,20 +613,119 @@ static void drag_handle_drag_source_destroy(struct wl_listener *listener,
 | 
				
			||||||
	wlr_drag_end(drag);
 | 
						wlr_drag_end(drag);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void wlr_drag_icon_destroy(struct wlr_drag_icon *icon) {
 | 
				
			||||||
 | 
						if (!icon) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						wl_signal_emit(&icon->events.destroy, icon);
 | 
				
			||||||
 | 
						wl_list_remove(&icon->surface_commit.link);
 | 
				
			||||||
 | 
						wl_list_remove(&icon->surface_destroy.link);
 | 
				
			||||||
 | 
						wl_list_remove(&icon->seat_client_destroy.link);
 | 
				
			||||||
 | 
						wl_list_remove(&icon->link);
 | 
				
			||||||
 | 
						free(icon);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_drag_icon_surface_destroy(struct wl_listener *listener,
 | 
				
			||||||
 | 
							void *data) {
 | 
				
			||||||
 | 
						struct wlr_drag_icon *icon =
 | 
				
			||||||
 | 
							wl_container_of(listener, icon, surface_destroy);
 | 
				
			||||||
 | 
						wlr_drag_icon_destroy(icon);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_drag_icon_surface_commit(struct wl_listener *listener,
 | 
				
			||||||
 | 
							void *data) {
 | 
				
			||||||
 | 
						struct wlr_drag_icon *icon =
 | 
				
			||||||
 | 
							wl_container_of(listener, icon, surface_commit);
 | 
				
			||||||
 | 
						icon->sx += icon->surface->current->sx;
 | 
				
			||||||
 | 
						icon->sy += icon->surface->current->sy;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_drag_icon_seat_client_destroy(struct wl_listener *listener,
 | 
				
			||||||
 | 
							void *data) {
 | 
				
			||||||
 | 
						struct wlr_drag_icon *icon =
 | 
				
			||||||
 | 
							wl_container_of(listener, icon, seat_client_destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_drag_icon_destroy(icon);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct wlr_drag_icon *wlr_drag_icon_create(
 | 
				
			||||||
 | 
							struct wlr_surface *icon_surface, struct wlr_seat_client *client,
 | 
				
			||||||
 | 
							bool is_pointer, int32_t touch_id) {
 | 
				
			||||||
 | 
						struct wlr_drag_icon *icon = calloc(1, sizeof(struct wlr_drag_icon));
 | 
				
			||||||
 | 
						if (!icon) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						icon->surface = icon_surface;
 | 
				
			||||||
 | 
						icon->client = client;
 | 
				
			||||||
 | 
						icon->is_pointer = is_pointer;
 | 
				
			||||||
 | 
						icon->touch_id = touch_id;
 | 
				
			||||||
 | 
						icon->mapped = true;
 | 
				
			||||||
 | 
						wl_list_insert(&client->seat->drag_icons, &icon->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_init(&icon->events.destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_add(&icon->surface->events.destroy, &icon->surface_destroy);
 | 
				
			||||||
 | 
						icon->surface_destroy.notify = handle_drag_icon_surface_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_add(&icon->surface->events.commit, &icon->surface_commit);
 | 
				
			||||||
 | 
						icon->surface_commit.notify = handle_drag_icon_surface_commit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_add(&client->events.destroy, &icon->seat_client_destroy);
 | 
				
			||||||
 | 
						icon->seat_client_destroy.notify = handle_drag_icon_seat_client_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return icon;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool seat_client_start_drag(struct wlr_seat_client *client,
 | 
					static bool seat_client_start_drag(struct wlr_seat_client *client,
 | 
				
			||||||
		struct wlr_data_source *source, struct wlr_surface *icon) {
 | 
							struct wlr_data_source *source, struct wlr_surface *icon_surface,
 | 
				
			||||||
 | 
							struct wlr_surface *origin, uint32_t serial) {
 | 
				
			||||||
	struct wlr_drag *drag = calloc(1, sizeof(struct wlr_drag));
 | 
						struct wlr_drag *drag = calloc(1, sizeof(struct wlr_drag));
 | 
				
			||||||
	if (drag == NULL) {
 | 
						if (drag == NULL) {
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_seat *seat = client->seat;
 | 
						drag->seat = client->seat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drag->is_pointer_grab = client->pointer != NULL &&
 | 
				
			||||||
 | 
							client->seat->pointer_state.button_count == 1 &&
 | 
				
			||||||
 | 
							client->seat->pointer_state.grab_serial == serial &&
 | 
				
			||||||
 | 
							client->seat->pointer_state.focused_surface &&
 | 
				
			||||||
 | 
							client->seat->pointer_state.focused_surface == origin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool is_touch_grab = client->touch &&
 | 
				
			||||||
 | 
							wlr_seat_touch_num_points(client->seat) == 1 &&
 | 
				
			||||||
 | 
							client->seat->touch_state.grab_serial == serial;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// set in the iteration
 | 
				
			||||||
 | 
						struct wlr_touch_point *point = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (is_touch_grab) {
 | 
				
			||||||
 | 
							wl_list_for_each(point, &client->seat->touch_state.touch_points, link) {
 | 
				
			||||||
 | 
								is_touch_grab = point->surface && point->surface == origin;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!drag->is_pointer_grab && !is_touch_grab) {
 | 
				
			||||||
 | 
							free(drag);
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (icon_surface) {
 | 
				
			||||||
 | 
							int32_t touch_id = (point ? point->touch_id : 0);
 | 
				
			||||||
 | 
							struct wlr_drag_icon *icon =
 | 
				
			||||||
 | 
								wlr_drag_icon_create(icon_surface, client, drag->is_pointer_grab,
 | 
				
			||||||
 | 
									touch_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!icon) {
 | 
				
			||||||
 | 
								free(drag);
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (icon) {
 | 
					 | 
				
			||||||
		drag->icon = icon;
 | 
							drag->icon = icon;
 | 
				
			||||||
		drag->icon_destroy.notify = drag_handle_icon_destroy;
 | 
							drag->icon_destroy.notify = drag_handle_icon_destroy;
 | 
				
			||||||
		wl_signal_add(&icon->events.destroy, &drag->icon_destroy);
 | 
							wl_signal_add(&icon->events.destroy, &drag->icon_destroy);
 | 
				
			||||||
		drag->icon = icon;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (source) {
 | 
						if (source) {
 | 
				
			||||||
| 
						 | 
					@ -587,13 +738,23 @@ static bool seat_client_start_drag(struct wlr_seat_client *client,
 | 
				
			||||||
	drag->pointer_grab.data = drag;
 | 
						drag->pointer_grab.data = drag;
 | 
				
			||||||
	drag->pointer_grab.interface = &wlr_data_device_pointer_drag_interface;
 | 
						drag->pointer_grab.interface = &wlr_data_device_pointer_drag_interface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drag->touch_grab.data = drag;
 | 
				
			||||||
 | 
						drag->touch_grab.interface = &wlr_data_device_touch_drag_interface;
 | 
				
			||||||
 | 
						drag->grab_touch_id = drag->seat->touch_state.grab_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drag->keyboard_grab.data = drag;
 | 
						drag->keyboard_grab.data = drag;
 | 
				
			||||||
	drag->keyboard_grab.interface = &wlr_data_device_keyboard_drag_interface;
 | 
						drag->keyboard_grab.interface = &wlr_data_device_keyboard_drag_interface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_seat_pointer_clear_focus(seat);
 | 
						wlr_seat_keyboard_start_grab(drag->seat, &drag->keyboard_grab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_seat_keyboard_start_grab(seat, &drag->keyboard_grab);
 | 
						if (drag->is_pointer_grab) {
 | 
				
			||||||
	wlr_seat_pointer_start_grab(seat, &drag->pointer_grab);
 | 
							wlr_seat_pointer_clear_focus(drag->seat);
 | 
				
			||||||
 | 
							wlr_seat_pointer_start_grab(drag->seat, &drag->pointer_grab);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							assert(point);
 | 
				
			||||||
 | 
							wlr_seat_touch_start_grab(drag->seat, &drag->touch_grab);
 | 
				
			||||||
 | 
							wlr_drag_set_focus(drag, point->surface, point->sx, point->sy);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -603,21 +764,12 @@ static void data_device_start_drag(struct wl_client *client,
 | 
				
			||||||
		struct wl_resource *source_resource,
 | 
							struct wl_resource *source_resource,
 | 
				
			||||||
		struct wl_resource *origin_resource, struct wl_resource *icon_resource,
 | 
							struct wl_resource *origin_resource, struct wl_resource *icon_resource,
 | 
				
			||||||
		uint32_t serial) {
 | 
							uint32_t serial) {
 | 
				
			||||||
	struct wlr_seat_client *seat_client = wl_resource_get_user_data(device_resource);
 | 
						struct wlr_seat_client *seat_client =
 | 
				
			||||||
	struct wlr_seat *seat = seat_client->seat;
 | 
							wl_resource_get_user_data(device_resource);
 | 
				
			||||||
	struct wlr_surface *origin = wl_resource_get_user_data(origin_resource);
 | 
						struct wlr_surface *origin = wl_resource_get_user_data(origin_resource);
 | 
				
			||||||
	struct wlr_data_source *source = NULL;
 | 
						struct wlr_data_source *source = NULL;
 | 
				
			||||||
	struct wlr_surface *icon = NULL;
 | 
						struct wlr_surface *icon = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool is_pointer_grab = seat->pointer_state.button_count == 1 &&
 | 
					 | 
				
			||||||
		seat->pointer_state.grab_serial == serial &&
 | 
					 | 
				
			||||||
		seat->pointer_state.focused_surface &&
 | 
					 | 
				
			||||||
		seat->pointer_state.focused_surface == origin;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!is_pointer_grab) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (source_resource) {
 | 
						if (source_resource) {
 | 
				
			||||||
		source = wl_resource_get_user_data(source_resource);
 | 
							source = wl_resource_get_user_data(source_resource);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -632,9 +784,7 @@ static void data_device_start_drag(struct wl_client *client,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO touch grab
 | 
						if (!seat_client_start_drag(seat_client, source, icon, origin, serial)) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!seat_client_start_drag(seat_client, source, icon)) {
 | 
					 | 
				
			||||||
		wl_resource_post_no_memory(device_resource);
 | 
							wl_resource_post_no_memory(device_resource);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -653,7 +803,8 @@ static const struct wl_data_device_interface data_device_impl = {
 | 
				
			||||||
void data_device_manager_get_data_device(struct wl_client *client,
 | 
					void data_device_manager_get_data_device(struct wl_client *client,
 | 
				
			||||||
		struct wl_resource *manager_resource, uint32_t id,
 | 
							struct wl_resource *manager_resource, uint32_t id,
 | 
				
			||||||
		struct wl_resource *seat_resource) {
 | 
							struct wl_resource *seat_resource) {
 | 
				
			||||||
	struct wlr_seat_client *seat_client = wl_resource_get_user_data(seat_resource);
 | 
						struct wlr_seat_client *seat_client =
 | 
				
			||||||
 | 
							wl_resource_get_user_data(seat_resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_resource *resource =
 | 
						struct wl_resource *resource =
 | 
				
			||||||
		wl_resource_create(client,
 | 
							wl_resource_create(client,
 | 
				
			||||||
| 
						 | 
					@ -820,9 +971,9 @@ struct wlr_data_device_manager *wlr_data_device_manager_create(
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager) {
 | 
					void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager) {
 | 
				
			||||||
  if (!manager) {
 | 
						if (!manager) {
 | 
				
			||||||
    return;
 | 
							return;
 | 
				
			||||||
  }
 | 
						}
 | 
				
			||||||
  wl_global_destroy(manager->global);
 | 
						wl_global_destroy(manager->global);
 | 
				
			||||||
  free(manager);
 | 
						free(manager);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										342
									
								
								types/wlr_seat.c
									
										
									
									
									
								
							
							
						
						
									
										342
									
								
								types/wlr_seat.c
									
										
									
									
									
								
							| 
						 | 
					@ -181,7 +181,7 @@ static void wl_seat_get_touch(struct wl_client *client,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void wlr_seat_client_resource_destroy(struct wl_resource *resource) {
 | 
					static void wlr_seat_client_resource_destroy(struct wl_resource *resource) {
 | 
				
			||||||
	struct wlr_seat_client *client = wl_resource_get_user_data(resource);
 | 
						struct wlr_seat_client *client = wl_resource_get_user_data(resource);
 | 
				
			||||||
	wl_signal_emit(&client->seat->events.client_unbound, client);
 | 
						wl_signal_emit(&client->events.destroy, client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (client == client->seat->pointer_state.focused_client) {
 | 
						if (client == client->seat->pointer_state.focused_client) {
 | 
				
			||||||
		client->seat->pointer_state.focused_client = NULL;
 | 
							client->seat->pointer_state.focused_client = NULL;
 | 
				
			||||||
| 
						 | 
					@ -240,7 +240,7 @@ static void wl_seat_bind(struct wl_client *client, void *_wlr_seat,
 | 
				
			||||||
		wl_seat_send_name(seat_client->wl_resource, wlr_seat->name);
 | 
							wl_seat_send_name(seat_client->wl_resource, wlr_seat->name);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wl_seat_send_capabilities(seat_client->wl_resource, wlr_seat->capabilities);
 | 
						wl_seat_send_capabilities(seat_client->wl_resource, wlr_seat->capabilities);
 | 
				
			||||||
	wl_signal_emit(&wlr_seat->events.client_bound, seat_client);
 | 
						wl_signal_init(&seat_client->events.destroy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void default_pointer_enter(struct wlr_seat_pointer_grab *grab,
 | 
					static void default_pointer_enter(struct wlr_seat_pointer_grab *grab,
 | 
				
			||||||
| 
						 | 
					@ -300,12 +300,50 @@ static const struct wlr_keyboard_grab_interface default_keyboard_grab_impl = {
 | 
				
			||||||
	.cancel = default_keyboard_cancel,
 | 
						.cancel = default_keyboard_cancel,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t default_touch_down(struct wlr_seat_touch_grab *grab, uint32_t time,
 | 
				
			||||||
 | 
							struct wlr_touch_point *point) {
 | 
				
			||||||
 | 
						return wlr_seat_touch_send_down(grab->seat, point->surface, time,
 | 
				
			||||||
 | 
								point->touch_id, point->sx, point->sy);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void default_touch_up(struct wlr_seat_touch_grab *grab, uint32_t time,
 | 
				
			||||||
 | 
							struct wlr_touch_point *point) {
 | 
				
			||||||
 | 
						wlr_seat_touch_send_up(grab->seat, time, point->touch_id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void default_touch_motion(struct wlr_seat_touch_grab *grab,
 | 
				
			||||||
 | 
							uint32_t time, struct wlr_touch_point *point) {
 | 
				
			||||||
 | 
						if (!point->focus_surface || point->focus_surface == point->surface) {
 | 
				
			||||||
 | 
							wlr_seat_touch_send_motion(grab->seat, time, point->touch_id, point->sx,
 | 
				
			||||||
 | 
								point->sy);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void default_touch_enter(struct wlr_seat_touch_grab *grab,
 | 
				
			||||||
 | 
							uint32_t time, struct wlr_touch_point *point) {
 | 
				
			||||||
 | 
						// not handled by default
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void default_touch_cancel(struct wlr_seat_touch_grab *grab) {
 | 
				
			||||||
 | 
						// cannot be cancelled
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct wlr_touch_grab_interface default_touch_grab_impl = {
 | 
				
			||||||
 | 
						.down = default_touch_down,
 | 
				
			||||||
 | 
						.up = default_touch_up,
 | 
				
			||||||
 | 
						.motion = default_touch_motion,
 | 
				
			||||||
 | 
						.enter = default_touch_enter,
 | 
				
			||||||
 | 
						.cancel = default_touch_cancel,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
 | 
					struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
 | 
				
			||||||
	struct wlr_seat *wlr_seat = calloc(1, sizeof(struct wlr_seat));
 | 
						struct wlr_seat *wlr_seat = calloc(1, sizeof(struct wlr_seat));
 | 
				
			||||||
	if (!wlr_seat) {
 | 
						if (!wlr_seat) {
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// pointer state
 | 
				
			||||||
	wlr_seat->pointer_state.seat = wlr_seat;
 | 
						wlr_seat->pointer_state.seat = wlr_seat;
 | 
				
			||||||
	wl_list_init(&wlr_seat->pointer_state.surface_destroy.link);
 | 
						wl_list_init(&wlr_seat->pointer_state.surface_destroy.link);
 | 
				
			||||||
	wl_list_init(&wlr_seat->pointer_state.resource_destroy.link);
 | 
						wl_list_init(&wlr_seat->pointer_state.resource_destroy.link);
 | 
				
			||||||
| 
						 | 
					@ -321,6 +359,7 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
 | 
				
			||||||
	wlr_seat->pointer_state.default_grab = pointer_grab;
 | 
						wlr_seat->pointer_state.default_grab = pointer_grab;
 | 
				
			||||||
	wlr_seat->pointer_state.grab = pointer_grab;
 | 
						wlr_seat->pointer_state.grab = pointer_grab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// keyboard state
 | 
				
			||||||
	struct wlr_seat_keyboard_grab *keyboard_grab =
 | 
						struct wlr_seat_keyboard_grab *keyboard_grab =
 | 
				
			||||||
		calloc(1, sizeof(struct wlr_seat_keyboard_grab));
 | 
							calloc(1, sizeof(struct wlr_seat_keyboard_grab));
 | 
				
			||||||
	if (!keyboard_grab) {
 | 
						if (!keyboard_grab) {
 | 
				
			||||||
| 
						 | 
					@ -338,6 +377,23 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
 | 
				
			||||||
	wl_list_init(
 | 
						wl_list_init(
 | 
				
			||||||
		&wlr_seat->keyboard_state.surface_destroy.link);
 | 
							&wlr_seat->keyboard_state.surface_destroy.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// touch state
 | 
				
			||||||
 | 
						struct wlr_seat_touch_grab *touch_grab =
 | 
				
			||||||
 | 
							calloc(1, sizeof(struct wlr_seat_touch_grab));
 | 
				
			||||||
 | 
						if (!touch_grab) {
 | 
				
			||||||
 | 
							free(pointer_grab);
 | 
				
			||||||
 | 
							free(keyboard_grab);
 | 
				
			||||||
 | 
							free(wlr_seat);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						touch_grab->interface = &default_touch_grab_impl;
 | 
				
			||||||
 | 
						touch_grab->seat = wlr_seat;
 | 
				
			||||||
 | 
						wlr_seat->touch_state.default_grab = touch_grab;
 | 
				
			||||||
 | 
						wlr_seat->touch_state.grab = touch_grab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_seat->touch_state.seat = wlr_seat;
 | 
				
			||||||
 | 
						wl_list_init(&wlr_seat->touch_state.touch_points);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_global *wl_global = wl_global_create(display,
 | 
						struct wl_global *wl_global = wl_global_create(display,
 | 
				
			||||||
		&wl_seat_interface, 6, wlr_seat, wl_seat_bind);
 | 
							&wl_seat_interface, 6, wlr_seat, wl_seat_bind);
 | 
				
			||||||
	if (!wl_global) {
 | 
						if (!wl_global) {
 | 
				
			||||||
| 
						 | 
					@ -348,9 +404,7 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
 | 
				
			||||||
	wlr_seat->display = display;
 | 
						wlr_seat->display = display;
 | 
				
			||||||
	wlr_seat->name = strdup(name);
 | 
						wlr_seat->name = strdup(name);
 | 
				
			||||||
	wl_list_init(&wlr_seat->clients);
 | 
						wl_list_init(&wlr_seat->clients);
 | 
				
			||||||
 | 
						wl_list_init(&wlr_seat->drag_icons);
 | 
				
			||||||
	wl_signal_init(&wlr_seat->events.client_bound);
 | 
					 | 
				
			||||||
	wl_signal_init(&wlr_seat->events.client_unbound);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_init(&wlr_seat->events.request_set_cursor);
 | 
						wl_signal_init(&wlr_seat->events.request_set_cursor);
 | 
				
			||||||
	wl_signal_init(&wlr_seat->events.selection);
 | 
						wl_signal_init(&wlr_seat->events.selection);
 | 
				
			||||||
| 
						 | 
					@ -361,6 +415,9 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
 | 
				
			||||||
	wl_signal_init(&wlr_seat->events.keyboard_grab_begin);
 | 
						wl_signal_init(&wlr_seat->events.keyboard_grab_begin);
 | 
				
			||||||
	wl_signal_init(&wlr_seat->events.keyboard_grab_end);
 | 
						wl_signal_init(&wlr_seat->events.keyboard_grab_end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_init(&wlr_seat->events.touch_grab_begin);
 | 
				
			||||||
 | 
						wl_signal_init(&wlr_seat->events.touch_grab_end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return wlr_seat;
 | 
						return wlr_seat;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -378,6 +435,7 @@ void wlr_seat_destroy(struct wlr_seat *wlr_seat) {
 | 
				
			||||||
	wl_global_destroy(wlr_seat->wl_global);
 | 
						wl_global_destroy(wlr_seat->wl_global);
 | 
				
			||||||
	free(wlr_seat->pointer_state.default_grab);
 | 
						free(wlr_seat->pointer_state.default_grab);
 | 
				
			||||||
	free(wlr_seat->keyboard_state.default_grab);
 | 
						free(wlr_seat->keyboard_state.default_grab);
 | 
				
			||||||
 | 
						free(wlr_seat->touch_state.default_grab);
 | 
				
			||||||
	free(wlr_seat->data_device);
 | 
						free(wlr_seat->data_device);
 | 
				
			||||||
	free(wlr_seat->name);
 | 
						free(wlr_seat->name);
 | 
				
			||||||
	free(wlr_seat);
 | 
						free(wlr_seat);
 | 
				
			||||||
| 
						 | 
					@ -550,7 +608,9 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_seat_pointer_start_grab(struct wlr_seat *wlr_seat,
 | 
					void wlr_seat_pointer_start_grab(struct wlr_seat *wlr_seat,
 | 
				
			||||||
		struct wlr_seat_pointer_grab *grab) {
 | 
							struct wlr_seat_pointer_grab *grab) {
 | 
				
			||||||
 | 
						assert(wlr_seat);
 | 
				
			||||||
	grab->seat = wlr_seat;
 | 
						grab->seat = wlr_seat;
 | 
				
			||||||
 | 
						assert(grab->seat);
 | 
				
			||||||
	wlr_seat->pointer_state.grab = grab;
 | 
						wlr_seat->pointer_state.grab = grab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_emit(&wlr_seat->events.pointer_grab_begin, grab);
 | 
						wl_signal_emit(&wlr_seat->events.pointer_grab_begin, grab);
 | 
				
			||||||
| 
						 | 
					@ -596,7 +656,7 @@ uint32_t wlr_seat_pointer_notify_button(struct wlr_seat *wlr_seat,
 | 
				
			||||||
	struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab;
 | 
						struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab;
 | 
				
			||||||
	uint32_t serial = grab->interface->button(grab, time, button, state);
 | 
						uint32_t serial = grab->interface->button(grab, time, button, state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (wlr_seat->pointer_state.button_count == 1) {
 | 
						if (serial && wlr_seat->pointer_state.button_count == 1) {
 | 
				
			||||||
		wlr_seat->pointer_state.grab_serial = serial;
 | 
							wlr_seat->pointer_state.grab_serial = serial;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -610,6 +670,10 @@ void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time,
 | 
				
			||||||
	grab->interface->axis(grab, time, orientation, value);
 | 
						grab->interface->axis(grab, time, orientation, value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool wlr_seat_pointer_has_grab(struct wlr_seat *seat) {
 | 
				
			||||||
 | 
						return seat->pointer_state.grab->interface != &default_pointer_grab_impl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_seat_keyboard_send_key(struct wlr_seat *wlr_seat, uint32_t time,
 | 
					void wlr_seat_keyboard_send_key(struct wlr_seat *wlr_seat, uint32_t time,
 | 
				
			||||||
		uint32_t key, uint32_t state) {
 | 
							uint32_t key, uint32_t state) {
 | 
				
			||||||
	struct wlr_seat_client *client = wlr_seat->keyboard_state.focused_client;
 | 
						struct wlr_seat_client *client = wlr_seat->keyboard_state.focused_client;
 | 
				
			||||||
| 
						 | 
					@ -807,6 +871,10 @@ void wlr_seat_keyboard_clear_focus(struct wlr_seat *seat) {
 | 
				
			||||||
	wlr_seat_keyboard_enter(seat, NULL);
 | 
						wlr_seat_keyboard_enter(seat, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool wlr_seat_keyboard_has_grab(struct wlr_seat *seat) {
 | 
				
			||||||
 | 
						return seat->keyboard_state.grab->interface != &default_keyboard_grab_impl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat) {
 | 
					void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat) {
 | 
				
			||||||
	clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
 | 
						clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
 | 
				
			||||||
	struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab;
 | 
						struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab;
 | 
				
			||||||
| 
						 | 
					@ -819,3 +887,265 @@ void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time,
 | 
				
			||||||
	struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab;
 | 
						struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab;
 | 
				
			||||||
	grab->interface->key(grab, time, key, state);
 | 
						grab->interface->key(grab, time, key, state);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_seat_touch_start_grab(struct wlr_seat *wlr_seat,
 | 
				
			||||||
 | 
							struct wlr_seat_touch_grab *grab) {
 | 
				
			||||||
 | 
						grab->seat = wlr_seat;
 | 
				
			||||||
 | 
						wlr_seat->touch_state.grab = grab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_emit(&wlr_seat->events.touch_grab_begin, grab);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_seat_touch_end_grab(struct wlr_seat *wlr_seat) {
 | 
				
			||||||
 | 
						struct wlr_seat_touch_grab *grab = wlr_seat->touch_state.grab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (grab != wlr_seat->touch_state.default_grab) {
 | 
				
			||||||
 | 
							wlr_seat->touch_state.grab = wlr_seat->touch_state.default_grab;
 | 
				
			||||||
 | 
							wl_signal_emit(&wlr_seat->events.touch_grab_end, grab);
 | 
				
			||||||
 | 
							if (grab->interface->cancel) {
 | 
				
			||||||
 | 
								grab->interface->cancel(grab);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void touch_point_clear_focus(struct wlr_touch_point *point) {
 | 
				
			||||||
 | 
						if (point->focus_surface) {
 | 
				
			||||||
 | 
							wl_list_remove(&point->focus_surface_destroy.link);
 | 
				
			||||||
 | 
							point->focus_client = NULL;
 | 
				
			||||||
 | 
							point->focus_surface = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void touch_point_destroy(struct wlr_touch_point *point) {
 | 
				
			||||||
 | 
						wl_signal_emit(&point->events.destroy, point);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						touch_point_clear_focus(point);
 | 
				
			||||||
 | 
						wl_list_remove(&point->surface_destroy.link);
 | 
				
			||||||
 | 
						wl_list_remove(&point->resource_destroy.link);
 | 
				
			||||||
 | 
						wl_list_remove(&point->link);
 | 
				
			||||||
 | 
						free(point);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void handle_touch_point_resource_destroy(struct wl_listener *listener,
 | 
				
			||||||
 | 
							void *data) {
 | 
				
			||||||
 | 
						struct wlr_touch_point *point =
 | 
				
			||||||
 | 
							wl_container_of(listener, point, resource_destroy);
 | 
				
			||||||
 | 
						touch_point_destroy(point);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_touch_point_surface_destroy(struct wl_listener *listener,
 | 
				
			||||||
 | 
							void *data) {
 | 
				
			||||||
 | 
						struct wlr_touch_point *point =
 | 
				
			||||||
 | 
							wl_container_of(listener, point, surface_destroy);
 | 
				
			||||||
 | 
						touch_point_destroy(point);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct wlr_touch_point *touch_point_create(
 | 
				
			||||||
 | 
							struct wlr_seat *seat, int32_t touch_id,
 | 
				
			||||||
 | 
							struct wlr_surface *surface, double sx, double sy) {
 | 
				
			||||||
 | 
						struct wl_client *wl_client = wl_resource_get_client(surface->resource);
 | 
				
			||||||
 | 
						struct wlr_seat_client *client = wlr_seat_client_for_wl_client(seat, wl_client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!client || !client->touch) {
 | 
				
			||||||
 | 
							// touch points are not valid without a connected client with touch
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_touch_point *point = calloc(1, sizeof(struct wlr_touch_point));
 | 
				
			||||||
 | 
						if (!point) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						point->touch_id = touch_id;
 | 
				
			||||||
 | 
						point->surface = surface;
 | 
				
			||||||
 | 
						point->client = client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						point->sx = sx;
 | 
				
			||||||
 | 
						point->sy = sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_init(&point->events.destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_add(&surface->events.destroy, &point->surface_destroy);
 | 
				
			||||||
 | 
						point->surface_destroy.notify = handle_touch_point_surface_destroy;
 | 
				
			||||||
 | 
						wl_resource_add_destroy_listener(surface->resource,
 | 
				
			||||||
 | 
							&point->resource_destroy);
 | 
				
			||||||
 | 
						point->resource_destroy.notify = handle_touch_point_resource_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_insert(&seat->touch_state.touch_points, &point->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return point;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_touch_point *wlr_seat_touch_get_point(
 | 
				
			||||||
 | 
							struct wlr_seat *seat, int32_t touch_id) {
 | 
				
			||||||
 | 
						struct wlr_touch_point *point = NULL;
 | 
				
			||||||
 | 
						wl_list_for_each(point, &seat->touch_state.touch_points, link) {
 | 
				
			||||||
 | 
							if (point->touch_id == touch_id) {
 | 
				
			||||||
 | 
								return point;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t wlr_seat_touch_notify_down(struct wlr_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_surface *surface, uint32_t time, int32_t touch_id, double sx,
 | 
				
			||||||
 | 
							double sy) {
 | 
				
			||||||
 | 
						clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
 | 
				
			||||||
 | 
						struct wlr_seat_touch_grab *grab = seat->touch_state.grab;
 | 
				
			||||||
 | 
						struct wlr_touch_point *point =
 | 
				
			||||||
 | 
							touch_point_create(seat, touch_id, surface, sx, sy);
 | 
				
			||||||
 | 
						if (!point) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "could not create touch point");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t serial = grab->interface->down(grab, time, point);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (serial && wlr_seat_touch_num_points(seat) == 1) {
 | 
				
			||||||
 | 
							seat->touch_state.grab_serial = serial;
 | 
				
			||||||
 | 
							seat->touch_state.grab_id = touch_id;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return serial;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_seat_touch_notify_up(struct wlr_seat *seat, uint32_t time,
 | 
				
			||||||
 | 
							int32_t touch_id) {
 | 
				
			||||||
 | 
						clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
 | 
				
			||||||
 | 
						struct wlr_seat_touch_grab *grab = seat->touch_state.grab;
 | 
				
			||||||
 | 
						struct wlr_touch_point *point = wlr_seat_touch_get_point(seat, touch_id);
 | 
				
			||||||
 | 
						if (!point) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "got touch up for unknown touch point");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grab->interface->up(grab, time, point);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						touch_point_destroy(point);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_seat_touch_notify_motion(struct wlr_seat *seat, uint32_t time,
 | 
				
			||||||
 | 
							int32_t touch_id, double sx, double sy) {
 | 
				
			||||||
 | 
						clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
 | 
				
			||||||
 | 
						struct wlr_seat_touch_grab *grab = seat->touch_state.grab;
 | 
				
			||||||
 | 
						struct wlr_touch_point *point = wlr_seat_touch_get_point(seat, touch_id);
 | 
				
			||||||
 | 
						if (!point) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "got touch motion for unknown touch point");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						point->sx = sx;
 | 
				
			||||||
 | 
						point->sy = sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grab->interface->motion(grab, time, point);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_point_focus_destroy(struct wl_listener *listener,
 | 
				
			||||||
 | 
							void *data) {
 | 
				
			||||||
 | 
						struct wlr_touch_point *point =
 | 
				
			||||||
 | 
							wl_container_of(listener, point, focus_surface_destroy);
 | 
				
			||||||
 | 
						touch_point_clear_focus(point);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void touch_point_set_focus(struct wlr_touch_point *point,
 | 
				
			||||||
 | 
							struct wlr_surface *surface, double sx, double sy) {
 | 
				
			||||||
 | 
						if (point->focus_surface == surface) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						touch_point_clear_focus(point);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (surface && surface->resource) {
 | 
				
			||||||
 | 
							struct wlr_seat_client *client =
 | 
				
			||||||
 | 
								wlr_seat_client_for_wl_client(point->client->seat,
 | 
				
			||||||
 | 
									wl_resource_get_client(surface->resource));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (client && client->touch) {
 | 
				
			||||||
 | 
								wl_signal_add(&surface->events.destroy, &point->focus_surface_destroy);
 | 
				
			||||||
 | 
								point->focus_surface_destroy.notify = handle_point_focus_destroy;
 | 
				
			||||||
 | 
								point->focus_surface = surface;
 | 
				
			||||||
 | 
								point->focus_client = client;
 | 
				
			||||||
 | 
								point->sx = sx;
 | 
				
			||||||
 | 
								point->sy = sy;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_seat_touch_point_focus(struct wlr_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_surface *surface, uint32_t time, int32_t touch_id, double sx,
 | 
				
			||||||
 | 
							double sy) {
 | 
				
			||||||
 | 
						assert(surface);
 | 
				
			||||||
 | 
						struct wlr_touch_point *point = wlr_seat_touch_get_point(seat, touch_id);
 | 
				
			||||||
 | 
						if (!point) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "got touch point focus for unknown touch point");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						struct wlr_surface *focus = point->focus_surface;
 | 
				
			||||||
 | 
						touch_point_set_focus(point, surface, sx, sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (focus != point->focus_surface) {
 | 
				
			||||||
 | 
							struct wlr_seat_touch_grab *grab = seat->touch_state.grab;
 | 
				
			||||||
 | 
							grab->interface->enter(grab, time, point);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_seat_touch_point_clear_focus(struct wlr_seat *seat, uint32_t time,
 | 
				
			||||||
 | 
							int32_t touch_id) {
 | 
				
			||||||
 | 
						struct wlr_touch_point *point = wlr_seat_touch_get_point(seat, touch_id);
 | 
				
			||||||
 | 
						if (!point) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "got touch point focus for unknown touch point");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						touch_point_clear_focus(point);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t wlr_seat_touch_send_down(struct wlr_seat *seat,
 | 
				
			||||||
 | 
							struct wlr_surface *surface, uint32_t time, int32_t touch_id, double sx,
 | 
				
			||||||
 | 
							double sy) {
 | 
				
			||||||
 | 
						struct wlr_touch_point *point = wlr_seat_touch_get_point(seat, touch_id);
 | 
				
			||||||
 | 
						if (!point) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "got touch down for unknown touch point");
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t serial = wl_display_next_serial(seat->display);
 | 
				
			||||||
 | 
						wl_touch_send_down(point->client->touch, serial, time, surface->resource,
 | 
				
			||||||
 | 
							touch_id, wl_fixed_from_double(sx), wl_fixed_from_double(sy));
 | 
				
			||||||
 | 
						wl_touch_send_frame(point->client->touch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return serial;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_seat_touch_send_up(struct wlr_seat *seat, uint32_t time, int32_t touch_id) {
 | 
				
			||||||
 | 
						struct wlr_touch_point *point = wlr_seat_touch_get_point(seat, touch_id);
 | 
				
			||||||
 | 
						if (!point) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "got touch up for unknown touch point");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t serial = wl_display_next_serial(seat->display);
 | 
				
			||||||
 | 
						wl_touch_send_up(point->client->touch, serial, time, touch_id);
 | 
				
			||||||
 | 
						wl_touch_send_frame(point->client->touch);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time, int32_t touch_id,
 | 
				
			||||||
 | 
							double sx, double sy) {
 | 
				
			||||||
 | 
						struct wlr_touch_point *point = wlr_seat_touch_get_point(seat, touch_id);
 | 
				
			||||||
 | 
						if (!point) {
 | 
				
			||||||
 | 
							wlr_log(L_ERROR, "got touch motion for unknown touch point");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_touch_send_motion(point->client->touch, time, touch_id,
 | 
				
			||||||
 | 
							wl_fixed_from_double(sx), wl_fixed_from_double(sy));
 | 
				
			||||||
 | 
						wl_touch_send_frame(point->client->touch);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int wlr_seat_touch_num_points(struct wlr_seat *seat) {
 | 
				
			||||||
 | 
						return wl_list_length(&seat->touch_state.touch_points);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool wlr_seat_touch_has_grab(struct wlr_seat *seat) {
 | 
				
			||||||
 | 
						return seat->touch_state.grab->interface != &default_touch_grab_impl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager,
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	theme->scale = scale;
 | 
						theme->scale = scale;
 | 
				
			||||||
	theme->theme = wlr_xcursor_theme_load(NULL, manager->size * scale);
 | 
						theme->theme = wlr_xcursor_theme_load(manager->name, manager->size * scale);
 | 
				
			||||||
	if (theme->theme == NULL) {
 | 
						if (theme->theme == NULL) {
 | 
				
			||||||
		free(theme);
 | 
							free(theme);
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue