window.c: Add touch handlers
This adds basic infrastructure for handling touch events in the toytoolkit.
This commit is contained in:
parent
f1407ff81d
commit
041815aa05
236
clients/window.c
236
clients/window.c
@ -274,6 +274,11 @@ struct widget {
|
||||
widget_leave_handler_t leave_handler;
|
||||
widget_motion_handler_t motion_handler;
|
||||
widget_button_handler_t button_handler;
|
||||
widget_touch_down_handler_t touch_down_handler;
|
||||
widget_touch_up_handler_t touch_up_handler;
|
||||
widget_touch_motion_handler_t touch_motion_handler;
|
||||
widget_touch_frame_handler_t touch_frame_handler;
|
||||
widget_touch_cancel_handler_t touch_cancel_handler;
|
||||
widget_axis_handler_t axis_handler;
|
||||
void *user_data;
|
||||
int opaque;
|
||||
@ -281,13 +286,22 @@ struct widget {
|
||||
int default_cursor;
|
||||
};
|
||||
|
||||
struct touch_point {
|
||||
int32_t id;
|
||||
struct widget *widget;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct input {
|
||||
struct display *display;
|
||||
struct wl_seat *seat;
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_keyboard *keyboard;
|
||||
struct wl_touch *touch;
|
||||
struct wl_list touch_point_list;
|
||||
struct window *pointer_focus;
|
||||
struct window *keyboard_focus;
|
||||
struct window *touch_focus;
|
||||
int current_cursor;
|
||||
uint32_t cursor_anim_start;
|
||||
struct wl_callback *cursor_frame_cb;
|
||||
@ -1889,6 +1903,41 @@ widget_set_button_handler(struct widget *widget,
|
||||
widget->button_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
widget_set_touch_up_handler(struct widget *widget,
|
||||
widget_touch_up_handler_t handler)
|
||||
{
|
||||
widget->touch_up_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
widget_set_touch_down_handler(struct widget *widget,
|
||||
widget_touch_down_handler_t handler)
|
||||
{
|
||||
widget->touch_down_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
widget_set_touch_motion_handler(struct widget *widget,
|
||||
widget_touch_motion_handler_t handler)
|
||||
{
|
||||
widget->touch_motion_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
widget_set_touch_frame_handler(struct widget *widget,
|
||||
widget_touch_frame_handler_t handler)
|
||||
{
|
||||
widget->touch_frame_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
widget_set_touch_cancel_handler(struct widget *widget,
|
||||
widget_touch_cancel_handler_t handler)
|
||||
{
|
||||
widget->touch_cancel_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
widget_set_axis_handler(struct widget *widget,
|
||||
widget_axis_handler_t handler)
|
||||
@ -2303,6 +2352,35 @@ frame_button_button_handler(struct widget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
frame_button_touch_down_handler(struct widget *widget, uint32_t serial,
|
||||
uint32_t time, int32_t id,
|
||||
float x, float y, void *data)
|
||||
{
|
||||
struct frame_button *frame_button = data;
|
||||
struct window *window = widget->window;
|
||||
|
||||
switch (frame_button->type) {
|
||||
case FRAME_BUTTON_CLOSE:
|
||||
if (window->close_handler)
|
||||
window->close_handler(window->parent,
|
||||
window->user_data);
|
||||
else
|
||||
display_exit(window->display);
|
||||
break;
|
||||
case FRAME_BUTTON_MINIMIZE:
|
||||
fprintf(stderr,"Minimize stub\n");
|
||||
break;
|
||||
case FRAME_BUTTON_MAXIMIZE:
|
||||
window_set_maximized(window, window->type != TYPE_MAXIMIZED);
|
||||
break;
|
||||
default:
|
||||
/* Unknown operation */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
frame_button_motion_handler(struct widget *widget,
|
||||
struct input *input, uint32_t time,
|
||||
@ -2402,6 +2480,7 @@ frame_button_create(struct frame *frame, void *data, enum frame_button_action ty
|
||||
widget_set_redraw_handler(frame_button->widget, frame_button_redraw_handler);
|
||||
widget_set_enter_handler(frame_button->widget, frame_button_enter_handler);
|
||||
widget_set_leave_handler(frame_button->widget, frame_button_leave_handler);
|
||||
widget_set_touch_down_handler(frame_button->widget, frame_button_touch_down_handler);
|
||||
widget_set_button_handler(frame_button->widget, frame_button_button_handler);
|
||||
widget_set_motion_handler(frame_button->widget, frame_button_motion_handler);
|
||||
return frame_button->widget;
|
||||
@ -3115,6 +3194,153 @@ static const struct wl_keyboard_listener keyboard_listener = {
|
||||
keyboard_handle_modifiers,
|
||||
};
|
||||
|
||||
static void
|
||||
touch_handle_down(void *data, struct wl_touch *wl_touch,
|
||||
uint32_t serial, uint32_t time, struct wl_surface *surface,
|
||||
int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
|
||||
{
|
||||
struct input *input = data;
|
||||
struct widget *widget;
|
||||
float sx = wl_fixed_to_double(x_w);
|
||||
float sy = wl_fixed_to_double(y_w);
|
||||
|
||||
DBG("touch_handle_down: %i %i\n", id, wl_list_length(&input->touch_point_list));
|
||||
|
||||
input->touch_focus = wl_surface_get_user_data(surface);
|
||||
if (!input->touch_focus) {
|
||||
DBG("Failed to find to touch focus for surface %p\n", surface);
|
||||
return;
|
||||
}
|
||||
|
||||
widget = window_find_widget(input->touch_focus,
|
||||
wl_fixed_to_double(x_w),
|
||||
wl_fixed_to_double(y_w));
|
||||
if (widget) {
|
||||
struct touch_point *tp = xmalloc(sizeof *tp);
|
||||
if (tp) {
|
||||
tp->id = id;
|
||||
tp->widget = widget;
|
||||
wl_list_insert(&input->touch_point_list, &tp->link);
|
||||
|
||||
if (widget->touch_down_handler)
|
||||
(*widget->touch_down_handler)(widget, serial,
|
||||
time, id,
|
||||
sx, sy,
|
||||
widget->user_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
touch_handle_up(void *data, struct wl_touch *wl_touch,
|
||||
uint32_t serial, uint32_t time, int32_t id)
|
||||
{
|
||||
struct input *input = data;
|
||||
struct touch_point *tp, *tmp;
|
||||
|
||||
DBG("touch_handle_up: %i %i\n", id, wl_list_length(&input->touch_point_list));
|
||||
|
||||
if (!input->touch_focus) {
|
||||
DBG("No touch focus found for touch up event!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
|
||||
if (tp->id != id)
|
||||
continue;
|
||||
|
||||
if (tp->widget->touch_up_handler)
|
||||
(*tp->widget->touch_up_handler)(tp->widget, serial,
|
||||
time, id,
|
||||
tp->widget->user_data);
|
||||
|
||||
wl_list_remove(&tp->link);
|
||||
free(tp);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
touch_handle_motion(void *data, struct wl_touch *wl_touch,
|
||||
uint32_t time, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
|
||||
{
|
||||
struct input *input = data;
|
||||
struct touch_point *tp;
|
||||
float sx = wl_fixed_to_double(x_w);
|
||||
float sy = wl_fixed_to_double(y_w);
|
||||
|
||||
DBG("touch_handle_motion: %i %i\n", id, wl_list_length(&input->touch_point_list));
|
||||
|
||||
if (!input->touch_focus) {
|
||||
DBG("No touch focus found for touch motion event!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_list_for_each(tp, &input->touch_point_list, link) {
|
||||
if (tp->id != id)
|
||||
continue;
|
||||
|
||||
if (tp->widget->touch_motion_handler)
|
||||
(*tp->widget->touch_motion_handler)(tp->widget, time,
|
||||
id, sx, sy,
|
||||
tp->widget->user_data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
touch_handle_frame(void *data, struct wl_touch *wl_touch)
|
||||
{
|
||||
struct input *input = data;
|
||||
struct touch_point *tp, *tmp;
|
||||
|
||||
DBG("touch_handle_frame\n");
|
||||
|
||||
if (!input->touch_focus) {
|
||||
DBG("No touch focus found for touch frame event!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
|
||||
if (tp->widget->touch_frame_handler)
|
||||
(*tp->widget->touch_frame_handler)(tp->widget, tp->widget->user_data);
|
||||
|
||||
wl_list_remove(&tp->link);
|
||||
free(tp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
touch_handle_cancel(void *data, struct wl_touch *wl_touch)
|
||||
{
|
||||
struct input *input = data;
|
||||
struct touch_point *tp, *tmp;
|
||||
|
||||
DBG("touch_handle_cancel\n");
|
||||
|
||||
if (!input->touch_focus) {
|
||||
DBG("No touch focus found for touch cancel event!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_list_for_each_safe(tp, tmp, &input->touch_point_list, link) {
|
||||
if (tp->widget->touch_cancel_handler)
|
||||
(*tp->widget->touch_cancel_handler)(tp->widget, tp->widget->user_data);
|
||||
|
||||
wl_list_remove(&tp->link);
|
||||
free(tp);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_touch_listener touch_listener = {
|
||||
touch_handle_down,
|
||||
touch_handle_up,
|
||||
touch_handle_motion,
|
||||
touch_handle_frame,
|
||||
touch_handle_cancel,
|
||||
};
|
||||
|
||||
static void
|
||||
seat_handle_capabilities(void *data, struct wl_seat *seat,
|
||||
enum wl_seat_capability caps)
|
||||
@ -3140,6 +3366,15 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
|
||||
wl_keyboard_destroy(input->keyboard);
|
||||
input->keyboard = NULL;
|
||||
}
|
||||
|
||||
if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
|
||||
input->touch = wl_seat_get_touch(seat);
|
||||
wl_touch_set_user_data(input->touch, input);
|
||||
wl_touch_add_listener(input->touch, &touch_listener, input);
|
||||
} else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
|
||||
wl_touch_destroy(input->touch);
|
||||
input->touch = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_seat_listener seat_listener = {
|
||||
@ -4693,6 +4928,7 @@ display_add_input(struct display *d, uint32_t id)
|
||||
input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1);
|
||||
input->pointer_focus = NULL;
|
||||
input->keyboard_focus = NULL;
|
||||
wl_list_init(&input->touch_point_list);
|
||||
wl_list_insert(d->input_list.prev, &input->link);
|
||||
|
||||
wl_seat_add_listener(input->seat, &seat_listener, input);
|
||||
|
@ -232,6 +232,26 @@ typedef void (*widget_button_handler_t)(struct widget *widget,
|
||||
uint32_t button,
|
||||
enum wl_pointer_button_state state,
|
||||
void *data);
|
||||
typedef void (*widget_touch_down_handler_t)(struct widget *widget,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
int32_t id,
|
||||
float x,
|
||||
float y,
|
||||
void *data);
|
||||
typedef void (*widget_touch_up_handler_t)(struct widget *widget,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
int32_t id,
|
||||
void *data);
|
||||
typedef void (*widget_touch_motion_handler_t)(struct widget *widget,
|
||||
uint32_t time,
|
||||
int32_t id,
|
||||
float x,
|
||||
float y,
|
||||
void *data);
|
||||
typedef void (*widget_touch_frame_handler_t)(struct widget *widget,void *data);
|
||||
typedef void (*widget_touch_cancel_handler_t)(struct widget *widget, void *data);
|
||||
typedef void (*widget_axis_handler_t)(struct widget *widget,
|
||||
struct input *input, uint32_t time,
|
||||
uint32_t axis,
|
||||
@ -457,9 +477,23 @@ void
|
||||
widget_set_button_handler(struct widget *widget,
|
||||
widget_button_handler_t handler);
|
||||
void
|
||||
widget_set_touch_down_handler(struct widget *widget,
|
||||
widget_touch_down_handler_t handler);
|
||||
void
|
||||
widget_set_touch_up_handler(struct widget *widget,
|
||||
widget_touch_up_handler_t handler);
|
||||
void
|
||||
widget_set_touch_motion_handler(struct widget *widget,
|
||||
widget_touch_motion_handler_t handler);
|
||||
void
|
||||
widget_set_touch_frame_handler(struct widget *widget,
|
||||
widget_touch_frame_handler_t handler);
|
||||
void
|
||||
widget_set_touch_cancel_handler(struct widget *widget,
|
||||
widget_touch_cancel_handler_t handler);
|
||||
void
|
||||
widget_set_axis_handler(struct widget *widget,
|
||||
widget_axis_handler_t handler);
|
||||
|
||||
void
|
||||
widget_schedule_redraw(struct widget *widget);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user