>From 47a85346d2a6236283ea3241c626c5568225b21a Mon Sep 17 00:00:00 2001 From: Rusty Lynch <rusty.ly...@intel.com> Date: Fri, 26 Jul 2013 08:50:27 -0700 Subject: [PATCH 2/2] Add initial touch support to clients
--- clients/calibrator.c | 16 ++++ clients/desktop-shell.c | 15 ++++ clients/smoke.c | 22 +++-- clients/window.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++ clients/window.h | 36 +++++++- src/evdev.c | 2 +- src/input.c | 11 +++ src/shell.c | 8 +- 8 files changed, 328 insertions(+), 8 deletions(-) diff --git a/clients/calibrator.c b/clients/calibrator.c index cc6f4ed..9183e3e 100644 --- a/clients/calibrator.c +++ b/clients/calibrator.c @@ -163,6 +163,21 @@ button_handler(struct widget *widget, } static void +touch_handler(struct widget *widget, uint32_t serial, uint32_t time, + int32_t id, wl_fixed_t x_w, wl_fixed_t y_w, void *data) +{ + struct calibrator *calibrator = data; + calibrator->tests[calibrator->current_test].clicked_x = wl_fixed_to_int(x_w); + calibrator->tests[calibrator->current_test].clicked_y = wl_fixed_to_int(y_w); + calibrator->current_test--; + + if (calibrator->current_test < 0) + finish_calibration(calibrator); + + widget_schedule_redraw(widget); +} + +static void redraw_handler(struct widget *widget, void *data) { struct calibrator *calibrator = data; @@ -216,6 +231,7 @@ calibrator_create(struct display *display) calibrator->current_test = ARRAY_LENGTH(test_ratios) - 1; widget_set_button_handler(calibrator->widget, button_handler); + widget_set_touch_down_handler(calibrator->widget, touch_handler); widget_set_redraw_handler(calibrator->widget, redraw_handler); window_set_fullscreen(calibrator->window, 1); diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index 1062901..76474fe 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -318,6 +318,19 @@ panel_launcher_button_handler(struct widget *widget, widget_schedule_redraw(widget); if (state == WL_POINTER_BUTTON_STATE_RELEASED) panel_launcher_activate(launcher); + +} + +static void +panel_launcher_touch_down_handler(struct widget *widget, uint32_t serial, + uint32_t time, int32_t id, wl_fixed_t x_w, + wl_fixed_t y_w, void *data) +{ + struct panel_launcher *launcher; + + launcher = widget_get_user_data(widget); + widget_schedule_redraw(widget); + panel_launcher_activate(launcher); } static void @@ -640,6 +653,8 @@ panel_add_launcher(struct panel *panel, const char *icon, const char *path) panel_launcher_leave_handler); widget_set_button_handler(launcher->widget, panel_launcher_button_handler); + widget_set_touch_down_handler(launcher->widget, + panel_launcher_touch_down_handler); widget_set_redraw_handler(launcher->widget, panel_launcher_redraw_handler); widget_set_motion_handler(launcher->widget, diff --git a/clients/smoke.c b/clients/smoke.c index 5d7333d..bdebc25 100644 --- a/clients/smoke.c +++ b/clients/smoke.c @@ -226,11 +226,9 @@ redraw_handler(struct widget *widget, void *data) wl_surface_commit(window_get_wl_surface(smoke->window)); } -static int -smoke_motion_handler(struct widget *widget, struct input *input, - uint32_t time, float x, float y, void *data) +static void +smoke_motion_handler(struct smoke *smoke,float x, float y) { - struct smoke *smoke = data; int i, i0, i1, j, j0, j1, k, d = 5; if (x - d < 1) @@ -258,10 +256,23 @@ smoke_motion_handler(struct widget *widget, struct input *input, smoke->b[0].v[k] += 256 - (random() & 512); smoke->b[0].d[k] += 1; } +} +static int +mouse_motion_handler(struct widget *widget, struct input *input, + uint32_t time, float x, float y, void *data) +{ + smoke_motion_handler((struct smoke*)data, x, y); return CURSOR_HAND1; } +static int +touch_motion_handler(struct widget *widget, uint32_t time, + int32_t id, wl_fixed_t x_w, wl_fixed_t y_w, void *data) +{ + smoke_motion_handler((struct smoke*)data, wl_fixed_to_int(x_w), wl_fixed_to_int(y_w)); +} + static void resize_handler(struct widget *widget, int32_t width, int32_t height, void *data) @@ -305,7 +316,8 @@ int main(int argc, char *argv[]) smoke.b[1].u = calloc(size, sizeof(float)); smoke.b[1].v = calloc(size, sizeof(float)); - widget_set_motion_handler(smoke.widget, smoke_motion_handler); + widget_set_motion_handler(smoke.widget, mouse_motion_handler); + widget_set_touch_motion_handler(smoke.widget, touch_motion_handler); widget_set_resize_handler(smoke.widget, resize_handler); widget_set_redraw_handler(smoke.widget, redraw_handler); diff --git a/clients/window.c b/clients/window.c index cbfe12f..058dcb9 100644 --- a/clients/window.c +++ b/clients/window.c @@ -270,6 +270,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; @@ -277,13 +282,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; @@ -1873,6 +1887,41 @@ widget_set_button_handler(struct widget *widget, } 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) { @@ -2286,6 +2335,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, wl_fixed_t x_w, + wl_fixed_t y_w, 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, @@ -2387,6 +2465,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; @@ -3103,6 +3182,143 @@ static const struct wl_keyboard_listener keyboard_listener = { }; 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; + + 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 = (struct touch_point *)malloc(sizeof(struct touch_point)); + 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, x_w, y_w, 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 widget *widget; + 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)(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; + + 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, x_w, y_w, 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) { @@ -3127,6 +3343,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 = { @@ -4690,6 +4915,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); diff --git a/clients/window.h b/clients/window.h index a79b020..8bb05cd 100644 --- a/clients/window.h +++ b/clients/window.h @@ -220,6 +220,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, + wl_fixed_t x_w, + wl_fixed_t y_w, + 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, + wl_fixed_t x_w, + wl_fixed_t y_w, + 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, @@ -436,9 +456,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); diff --git a/src/evdev.c b/src/evdev.c index b3c99b3..2ec2b65 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -85,7 +85,7 @@ evdev_process_key(struct evdev_device *device, struct input_event *e, int time) case BTN_TOUCH: if (e->value == 0 && !device->is_mt) - notify_touch(device->seat, time, device->mt.slot, 0, 0, + notify_touch(device->seat, time, 0, 0, 0, WL_TOUCH_UP); break; default: diff --git a/src/input.c b/src/input.c index 1887e7f..e8f3a01 100644 --- a/src/input.c +++ b/src/input.c @@ -27,6 +27,7 @@ #include <assert.h> #include <unistd.h> #include <fcntl.h> +#include <linux/input.h> #include "../shared/os-compatibility.h" #include "compositor.h" @@ -1046,6 +1047,8 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id, if (seat->num_tp == 1) { es = weston_compositor_pick_surface(ec, x, y, &sx, &sy); touch_set_focus(seat, es); + weston_compositor_run_button_binding(ec, seat, time, BTN_TOUCH, + WL_POINTER_BUTTON_STATE_PRESSED); } else if (touch->focus) { es = (struct weston_surface *) touch->focus; weston_surface_from_global_fixed(es, x, y, &sx, &sy); @@ -1059,6 +1062,14 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id, } grab->interface->down(grab, time, touch_id, sx, sy); + if (seat->num_tp == 1) { + touch->grab_serial = + wl_display_get_serial(ec->wl_display); + touch->grab_time = time; + touch->grab_x = x; + touch->grab_y = y; + } + break; case WL_TOUCH_MOTION: es = (struct weston_surface *) touch->focus; diff --git a/src/shell.c b/src/shell.c index bcde789..265ab0d 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3008,7 +3008,10 @@ click_to_activate_binding(struct weston_seat *seat, uint32_t time, uint32_t butt struct weston_surface *focus; struct weston_surface *main_surface; - focus = (struct weston_surface *) seat->pointer->focus; + if (button == BTN_LEFT) + focus = (struct weston_surface *) seat->pointer->focus; + else + focus = (struct weston_surface *) seat->touch->focus; if (!focus) return; @@ -4373,6 +4376,9 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell) weston_compositor_add_button_binding(ec, BTN_LEFT, 0, click_to_activate_binding, shell); + weston_compositor_add_button_binding(ec, BTN_TOUCH, 0, + click_to_activate_binding, + shell); weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL, MODIFIER_SUPER | MODIFIER_ALT, surface_opacity_binding, NULL); -- 1.8.3.1 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel