Convert wire input co-ordinates to fixed-point
authorDaniel Stone <daniel@fooishbar.org>
Tue, 8 May 2012 16:17:55 +0000 (17:17 +0100)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 8 May 2012 18:41:01 +0000 (14:41 -0400)
To add greater precision when working with transformed surfaces and/or
high-resolution input devices.

Signed-off-by: Daniel Stone <daniel@fooishbar.org>
clients/simple-touch.c
clients/window.c
src/compositor-wayland.c
src/compositor.c
src/shell.c
tests/test-client.c

index b8d9156..0dbf3db 100644 (file)
@@ -29,6 +29,7 @@
 #include <unistd.h>
 #include <sys/mman.h>
 
+#include <GLES2/gl2.h>
 #include <wayland-client.h>
 #include <wayland-egl.h>
 
@@ -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);
 }
index f5114bd..b47e969 100644 (file)
@@ -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;
index 3260c8e..05669bc 100644 (file)
@@ -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);
index e3b4118..ab8be4d 100644 (file)
@@ -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;
 
index 5eb45dc..51b37e2 100644 (file)
@@ -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
index 05156bd..4331a1a 100644 (file)
@@ -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)
 {
 }