From 103db7fb56c4befa3c61c619d41ef0733d8d066a Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 8 May 2012 17:17:55 +0100 Subject: [PATCH] Convert wire input co-ordinates to fixed-point To add greater precision when working with transformed surfaces and/or high-resolution input devices. Signed-off-by: Daniel Stone --- clients/simple-touch.c | 19 +++++++--- clients/window.c | 22 ++++++++---- src/compositor-wayland.c | 8 +++-- src/compositor.c | 56 +++++++++++++++++++----------- src/shell.c | 90 ++++++++++++++++++++++++++++-------------------- tests/test-client.c | 17 ++++----- 6 files changed, 133 insertions(+), 79 deletions(-) diff --git a/clients/simple-touch.c b/clients/simple-touch.c index b8d9156..0dbf3db 100644 --- a/clients/simple-touch.c +++ b/clients/simple-touch.c @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -103,7 +104,9 @@ struct wl_shm_listener shm_listenter = { static void input_device_handle_motion(void *data, struct wl_input_device *input_device, - uint32_t time, int32_t sx, int32_t sy) + uint32_t time, + wl_fixed_t sx_w, + wl_fixed_t sy_w) { } @@ -132,7 +135,7 @@ static void input_device_handle_pointer_enter(void *data, struct wl_input_device *input_device, uint32_t serial, struct wl_surface *surface, - int32_t sx, int32_t sy) + wl_fixed_t sx_w, wl_fixed_t sy_w) { } @@ -197,9 +200,13 @@ input_device_handle_touch_down(void *data, struct wl_input_device *wl_input_device, uint32_t serial, uint32_t time, struct wl_surface *surface, - int32_t id, int32_t x, int32_t y) + int32_t id, + wl_fixed_t x_w, + wl_fixed_t y_w) { struct touch *touch = data; + GLfloat x = wl_fixed_to_double(x_w); + GLfloat y = wl_fixed_to_double(y_w); touch_paint(touch, x, y, id); } @@ -215,9 +222,13 @@ static void input_device_handle_touch_motion(void *data, struct wl_input_device *wl_input_device, uint32_t time, - int32_t id, int32_t x, int32_t y) + int32_t id, + wl_fixed_t x_w, + wl_fixed_t y_w) { struct touch *touch = data; + GLfloat x = wl_fixed_to_double(x_w); + GLfloat y = wl_fixed_to_double(y_w); touch_paint(touch, x, y, id); } diff --git a/clients/window.c b/clients/window.c index f5114bd..b47e969 100644 --- a/clients/window.c +++ b/clients/window.c @@ -1473,12 +1473,14 @@ input_set_focus_widget(struct input *input, struct widget *focus, static void input_handle_motion(void *data, struct wl_input_device *input_device, - uint32_t time, int32_t sx, int32_t sy) + uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) { struct input *input = data; struct window *window = input->pointer_focus; struct widget *widget; int pointer = POINTER_LEFT_PTR; + GLfloat sx = wl_fixed_to_double(sx_w); + GLfloat sy = wl_fixed_to_double(sy_w); input->sx = sx; input->sy = sy; @@ -1604,11 +1606,13 @@ static void input_handle_pointer_enter(void *data, struct wl_input_device *input_device, uint32_t serial, struct wl_surface *surface, - int32_t sx, int32_t sy) + wl_fixed_t sx_w, wl_fixed_t sy_w) { struct input *input = data; struct window *window; struct widget *widget; + GLfloat sx = wl_fixed_to_double(sx_w); + GLfloat sy = wl_fixed_to_double(sy_w); input->display->serial = serial; input->pointer_enter_serial = serial; @@ -1701,7 +1705,7 @@ input_handle_touch_down(void *data, struct wl_input_device *wl_input_device, uint32_t serial, uint32_t time, struct wl_surface *surface, - int32_t id, int32_t x, int32_t y) + int32_t id, wl_fixed_t x, wl_fixed_t y) { } @@ -1715,7 +1719,8 @@ input_handle_touch_up(void *data, static void input_handle_touch_motion(void *data, struct wl_input_device *wl_input_device, - uint32_t time, int32_t id, int32_t x, int32_t y) + uint32_t time, int32_t id, + wl_fixed_t x, wl_fixed_t y) { } @@ -1838,10 +1843,13 @@ data_device_data_offer(void *data, static void data_device_enter(void *data, struct wl_data_device *data_device, uint32_t serial, struct wl_surface *surface, - int32_t x, int32_t y, struct wl_data_offer *offer) + wl_fixed_t x_w, wl_fixed_t y_w, + struct wl_data_offer *offer) { struct input *input = data; struct window *window; + GLfloat x = wl_fixed_to_double(x_w); + GLfloat y = wl_fixed_to_double(y_w); char **p; input->pointer_enter_serial = serial; @@ -1870,10 +1878,12 @@ data_device_leave(void *data, struct wl_data_device *data_device) static void data_device_motion(void *data, struct wl_data_device *data_device, - uint32_t time, int32_t x, int32_t y) + uint32_t time, wl_fixed_t x_w, wl_fixed_t y_w) { struct input *input = data; struct window *window = input->pointer_focus; + GLfloat x = wl_fixed_to_double(x_w); + GLfloat y = wl_fixed_to_double(y_w); input->sx = x; input->sy = y; diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index 3260c8e..05669bc 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -508,10 +508,12 @@ static const struct wl_output_listener output_listener = { /* parent input interface */ static void input_handle_motion(void *data, struct wl_input_device *input_device, - uint32_t time, int32_t sx, int32_t sy) + uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) { struct wayland_input *input = data; struct wayland_compositor *c = input->compositor; + GLfloat sx = wl_fixed_to_double(sx_w); + GLfloat sy = wl_fixed_to_double(sy_w); notify_motion(c->base.input_device, time, sx - c->border.left, sy - c->border.top); @@ -552,11 +554,13 @@ static void input_handle_pointer_enter(void *data, struct wl_input_device *input_device, uint32_t time, struct wl_surface *surface, - int32_t sx, int32_t sy) + wl_fixed_t sx_w, wl_fixed_t sy_w) { struct wayland_input *input = data; struct wayland_output *output; struct wayland_compositor *c = input->compositor; + GLfloat sx = wl_fixed_to_double(sx_w); + GLfloat sy = wl_fixed_to_double(sy_w); output = wl_surface_get_user_data(surface); notify_pointer_focus(c->base.input_device, &output->base, sx, sy); diff --git a/src/compositor.c b/src/compositor.c index e3b4118..ab8be4d 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -600,14 +600,17 @@ weston_compositor_get_time(void) static struct weston_surface * weston_compositor_pick_surface(struct weston_compositor *compositor, - int32_t x, int32_t y, int32_t *sx, int32_t *sy) + wl_fixed_t x, wl_fixed_t y, + wl_fixed_t *sx, wl_fixed_t *sy) { struct weston_surface *surface; wl_list_for_each(surface, &compositor->surface_list, link) { - weston_surface_from_global(surface, x, y, sx, sy); + weston_surface_from_global_fixed(surface, x, y, sx, sy); if (pixman_region32_contains_point(&surface->input, - *sx, *sy, NULL)) + wl_fixed_to_int(*sx), + wl_fixed_to_int(*sy), + NULL)) return surface; } @@ -635,8 +638,9 @@ weston_device_repick(struct wl_input_device *device) focus = (struct weston_surface *) device->pointer_grab->focus; if (focus) - weston_surface_from_global(focus, device->x, device->y, - &device->pointer_grab->x, &device->pointer_grab->y); + weston_surface_from_global_fixed(focus, device->x, device->y, + &device->pointer_grab->x, + &device->pointer_grab->y); } WL_EXPORT void @@ -664,7 +668,9 @@ weston_surface_unmap(struct weston_surface *surface) if (device->keyboard_focus == &surface->surface) wl_input_device_set_keyboard_focus(device, NULL); if (device->pointer_focus == &surface->surface) - wl_input_device_set_pointer_focus(device, NULL, 0, 0); + wl_input_device_set_pointer_focus(device, NULL, + wl_fixed_from_int(0), + wl_fixed_from_int(0)); weston_compositor_schedule_repaint(surface->compositor); } @@ -1599,8 +1605,8 @@ notify_motion(struct wl_input_device *device, uint32_t time, GLfloat x, GLfloat weston_input_update_drag_surface(device, x - device->x, y - device->y); - device->x = x; - device->y = y; + device->x = wl_fixed_from_double(x); + device->y = wl_fixed_from_double(y); wl_list_for_each(output, &ec->output_list, link) if (output->zoom.active && @@ -1612,11 +1618,13 @@ notify_motion(struct wl_input_device *device, uint32_t time, GLfloat x, GLfloat interface->motion(device->pointer_grab, time, device->pointer_grab->x, device->pointer_grab->y); + x = wl_fixed_to_double(device->x); + y = wl_fixed_to_double(device->y); + if (wd->sprite) { weston_surface_set_position(wd->sprite, - device->x - wd->hotspot_x, - device->y - wd->hotspot_y); - + x - wd->hotspot_x, + y - wd->hotspot_y); weston_compositor_schedule_repaint(ec); } } @@ -1775,11 +1783,12 @@ notify_pointer_focus(struct wl_input_device *device, struct weston_compositor *compositor = wd->compositor; if (output) { - weston_input_update_drag_surface(device, x - device->x, - y - device->y); + weston_input_update_drag_surface(device, + x - wl_fixed_to_double(device->x), + y - wl_fixed_to_double(device->y)); - device->x = x; - device->y = y; + device->x = wl_fixed_from_double(x); + device->y = wl_fixed_from_double(y); compositor->focus = 1; weston_compositor_repick(compositor); } else { @@ -1922,9 +1931,12 @@ notify_touch(struct wl_input_device *device, uint32_t time, int touch_id, struct weston_input_device *wd = (struct weston_input_device *) device; struct weston_compositor *ec = wd->compositor; struct weston_surface *es; - int32_t sx, sy; + wl_fixed_t fx, fy, sx, sy; uint32_t serial = 0; + fx = wl_fixed_from_double(x); + fy = wl_fixed_from_double(y); + switch (touch_type) { case WL_INPUT_DEVICE_TOUCH_DOWN: weston_compositor_idle_inhibit(ec); @@ -1935,16 +1947,17 @@ notify_touch(struct wl_input_device *device, uint32_t time, int touch_id, * to that surface for the remainder of the touch session i.e. * until all touch points are up again. */ if (wd->num_tp == 1) { - es = weston_compositor_pick_surface(ec, x, y, &sx, &sy); + es = weston_compositor_pick_surface(ec, fx, fy, &sx, &sy); touch_set_focus(wd, &es->surface); } else if (wd->touch_focus) { es = (struct weston_surface *) wd->touch_focus; - weston_surface_from_global(es, x, y, &sx, &sy); + weston_surface_from_global_fixed(es, fx, fy, &sx, &sy); } if (wd->touch_focus_resource && wd->touch_focus) wl_input_device_send_touch_down(wd->touch_focus_resource, - serial, time, &wd->touch_focus->resource, + serial, time, + &wd->touch_focus->resource, touch_id, sx, sy); break; case WL_INPUT_DEVICE_TOUCH_MOTION: @@ -1952,7 +1965,7 @@ notify_touch(struct wl_input_device *device, uint32_t time, int touch_id, if (!es) break; - weston_surface_from_global(es, x, y, &sx, &sy); + weston_surface_from_global_fixed(es, fx, fy, &sx, &sy); if (wd->touch_focus_resource) wl_input_device_send_touch_motion(wd->touch_focus_resource, time, touch_id, sx, sy); @@ -2123,7 +2136,8 @@ device_setup_new_drag_surface(struct weston_input_device *device, device->drag_surface = surface; weston_surface_set_position(device->drag_surface, - input_device->x, input_device->y); + wl_fixed_to_double(input_device->x), + wl_fixed_to_double(input_device->y)); surface->configure = drag_surface_configure; diff --git a/src/shell.c b/src/shell.c index 5eb45dc..51b37e2 100644 --- a/src/shell.c +++ b/src/shell.c @@ -169,7 +169,7 @@ struct shell_grab { struct weston_move_grab { struct shell_grab base; - int32_t dx, dy; + wl_fixed_t dx, dy; }; struct rotate_grab { @@ -304,28 +304,28 @@ shell_configuration(struct desktop_shell *shell) static void noop_grab_focus(struct wl_pointer_grab *grab, - struct wl_surface *surface, int32_t x, int32_t y) + struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y) { grab->focus = NULL; } static void move_grab_motion(struct wl_pointer_grab *grab, - uint32_t time, int32_t x, int32_t y) + uint32_t time, wl_fixed_t x, wl_fixed_t y) { struct weston_move_grab *move = (struct weston_move_grab *) grab; struct wl_input_device *device = grab->input_device; struct shell_surface *shsurf = move->base.shsurf; struct weston_surface *es; + int dx = wl_fixed_to_int(device->x + move->dx); + int dy = wl_fixed_to_int(device->y + move->dy); if (!shsurf) return; es = shsurf->surface; - weston_surface_configure(es, - device->x + move->dx, - device->y + move->dy, + weston_surface_configure(es, dx, dy, es->geometry.width, es->geometry.height); } @@ -517,13 +517,15 @@ weston_surface_move(struct weston_surface *es, shell_grab_init(&move->base, &move_grab_interface, shsurf); - move->dx = es->geometry.x - wd->input_device.grab_x; - move->dy = es->geometry.y - wd->input_device.grab_y; + move->dx = wl_fixed_from_double(es->geometry.x) - wd->input_device.grab_x; + move->dy = wl_fixed_from_double(es->geometry.y) - wd->input_device.grab_y; wl_input_device_start_pointer_grab(&wd->input_device, &move->base.grab); - wl_input_device_set_pointer_focus(&wd->input_device, NULL, 0, 0); + wl_input_device_set_pointer_focus(&wd->input_device, NULL, + wl_fixed_from_int(0), + wl_fixed_from_int(0)); return 0; } @@ -552,37 +554,35 @@ struct weston_resize_grab { static void resize_grab_motion(struct wl_pointer_grab *grab, - uint32_t time, int32_t x, int32_t y) + uint32_t time, wl_fixed_t x, wl_fixed_t y) { struct weston_resize_grab *resize = (struct weston_resize_grab *) grab; struct wl_input_device *device = grab->input_device; int32_t width, height; - int32_t from_x, from_y; - int32_t to_x, to_y; + wl_fixed_t from_x, from_y; + wl_fixed_t to_x, to_y; if (!resize->base.shsurf) return; - weston_surface_from_global(resize->base.shsurf->surface, - device->grab_x, device->grab_y, - &from_x, &from_y); - weston_surface_from_global(resize->base.shsurf->surface, - device->x, device->y, &to_x, &to_y); + weston_surface_from_global_fixed(resize->base.shsurf->surface, + device->grab_x, device->grab_y, + &from_x, &from_y); + weston_surface_from_global_fixed(resize->base.shsurf->surface, + device->x, device->y, &to_x, &to_y); + width = resize->width; if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) { - width = resize->width + from_x - to_x; + width += wl_fixed_to_int(from_x - to_x); } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) { - width = resize->width + to_x - from_x; - } else { - width = resize->width; + width += wl_fixed_to_int(to_x - from_x); } + height = resize->height; if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) { - height = resize->height + from_y - to_y; + height += wl_fixed_to_int(from_y - to_y); } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) { - height = resize->height + to_y - from_y; - } else { - height = resize->height; + height += wl_fixed_to_int(to_y - from_y); } wl_shell_surface_send_configure(&resize->base.shsurf->resource, @@ -635,7 +635,9 @@ weston_surface_resize(struct shell_surface *shsurf, wl_input_device_start_pointer_grab(&wd->input_device, &resize->base.grab); - wl_input_device_set_pointer_focus(&wd->input_device, NULL, 0, 0); + wl_input_device_set_pointer_focus(&wd->input_device, NULL, + wl_fixed_from_int(0), + wl_fixed_from_int(0)); return 0; } @@ -1037,7 +1039,9 @@ shell_surface_set_fullscreen(struct wl_client *client, static void popup_grab_focus(struct wl_pointer_grab *grab, - struct wl_surface *surface, int32_t x, int32_t y) + struct wl_surface *surface, + wl_fixed_t x, + wl_fixed_t y) { struct wl_input_device *device = grab->input_device; struct shell_surface *priv = @@ -1048,14 +1052,16 @@ popup_grab_focus(struct wl_pointer_grab *grab, wl_input_device_set_pointer_focus(device, surface, x, y); grab->focus = surface; } else { - wl_input_device_set_pointer_focus(device, NULL, 0, 0); + wl_input_device_set_pointer_focus(device, NULL, + wl_fixed_from_int(0), + wl_fixed_from_int(0)); grab->focus = NULL; } } static void popup_grab_motion(struct wl_pointer_grab *grab, - uint32_t time, int32_t sx, int32_t sy) + uint32_t time, wl_fixed_t sx, wl_fixed_t sy) { struct wl_resource *resource; @@ -1554,7 +1560,9 @@ resize_binding(struct wl_input_device *device, uint32_t time, } weston_surface_from_global(surface, - device->grab_x, device->grab_y, &x, &y); + wl_fixed_to_int(device->grab_x), + wl_fixed_to_int(device->grab_y), + &x, &y); if (x < surface->geometry.width / 3) edges |= WL_SHELL_SURFACE_RESIZE_LEFT; @@ -1621,7 +1629,9 @@ zoom_binding(struct wl_input_device *device, uint32_t time, wl_list_for_each(output, &compositor->output_list, link) { if (pixman_region32_contains_point(&output->region, - device->x, device->y, NULL)) { + wl_fixed_to_double(device->x), + wl_fixed_to_double(device->y), + NULL)) { output->zoom.active = 1; output->zoom.level += output->zoom.increment * -value; @@ -1633,7 +1643,9 @@ zoom_binding(struct wl_input_device *device, uint32_t time, if (output->zoom.level < output->zoom.increment) output->zoom.level = output->zoom.increment; - weston_output_update_zoom(output, device->x, device->y); + weston_output_update_zoom(output, + wl_fixed_to_int(device->x), + wl_fixed_to_int(device->y)); } } } @@ -1650,7 +1662,7 @@ terminate_binding(struct wl_input_device *device, uint32_t time, static void rotate_grab_motion(struct wl_pointer_grab *grab, - uint32_t time, int32_t x, int32_t y) + uint32_t time, wl_fixed_t x, wl_fixed_t y) { struct rotate_grab *rotate = container_of(grab, struct rotate_grab, base.grab); @@ -1667,8 +1679,8 @@ rotate_grab_motion(struct wl_pointer_grab *grab, cx = 0.5f * surface->geometry.width; cy = 0.5f * surface->geometry.height; - dx = device->x - rotate->center.x; - dy = device->y - rotate->center.y; + dx = wl_fixed_to_double(device->x) - rotate->center.x; + dy = wl_fixed_to_double(device->y) - rotate->center.y; r = sqrtf(dx * dx + dy * dy); wl_list_remove(&shsurf->rotation.transform.link); @@ -1784,8 +1796,8 @@ rotate_binding(struct wl_input_device *device, uint32_t time, wl_input_device_start_pointer_grab(device, &rotate->base.grab); - dx = device->x - rotate->center.x; - dy = device->y - rotate->center.y; + dx = wl_fixed_to_double(device->x) - rotate->center.x; + dy = wl_fixed_to_double(device->y) - rotate->center.y; r = sqrtf(dx * dx + dy * dy); if (r > 20.0f) { struct weston_matrix inverse; @@ -1807,7 +1819,9 @@ rotate_binding(struct wl_input_device *device, uint32_t time, weston_matrix_init(&rotate->rotation); } - wl_input_device_set_pointer_focus(device, NULL, 0, 0); + wl_input_device_set_pointer_focus(device, NULL, + wl_fixed_from_int(0), + wl_fixed_from_int(0)); } static void diff --git a/tests/test-client.c b/tests/test-client.c index 05156bd..4331a1a 100644 --- a/tests/test-client.c +++ b/tests/test-client.c @@ -57,12 +57,12 @@ struct surface { static void input_handle_motion(void *data, struct wl_input_device *input_device, - uint32_t time, int32_t x, int32_t y) + uint32_t time, wl_fixed_t x, wl_fixed_t y) { struct input *input = data; - input->x = x; - input->y = y; + input->x = wl_fixed_to_double(x); + input->y = wl_fixed_to_double(y); } static void @@ -97,13 +97,13 @@ static void input_handle_pointer_enter(void *data, struct wl_input_device *input_device, uint32_t serial, struct wl_surface *surface, - int32_t x, int32_t y) + wl_fixed_t x, wl_fixed_t y) { struct input *input = data; input->pointer_focus = wl_surface_get_user_data(surface); - input->x = x; - input->y = y; + input->x = wl_fixed_to_double(x); + input->y = wl_fixed_to_double(y); } static void @@ -144,7 +144,7 @@ input_handle_touch_down(void *data, struct wl_input_device *wl_input_device, uint32_t serial, uint32_t time, struct wl_surface *surface, - int32_t id, int32_t x, int32_t y) + int32_t id, wl_fixed_t x, wl_fixed_t y) { } @@ -158,7 +158,8 @@ input_handle_touch_up(void *data, static void input_handle_touch_motion(void *data, struct wl_input_device *wl_input_device, - uint32_t time, int32_t id, int32_t x, int32_t y) + uint32_t time, int32_t id, + wl_fixed_t x, wl_fixed_t y) { } -- 2.7.4