window.c: Add touch handlers

This adds basic infrastructure for handling touch events in the toytoolkit.
dev
Rusty Lynch 11 years ago committed by Kristian Høgsberg
parent f1407ff81d
commit 041815aa05
  1. 236
      clients/window.c
  2. 36
      clients/window.h

@ -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…
Cancel
Save