Feed motion events through compositor.
authorKristian Høgsberg <krh@redhat.com>
Wed, 10 Dec 2008 15:42:04 +0000 (10:42 -0500)
committerKristian Høgsberg <krh@redhat.com>
Wed, 10 Dec 2008 15:42:04 +0000 (10:42 -0500)
This lets us pass events only to the window that we're mousing over
and we can now transform input events back to the window coordinate space.

egl-compositor.c
wayland.c
wayland.h

index c70b2de..c05f363 100644 (file)
@@ -77,7 +77,8 @@ struct egl_surface {
        GLuint texture;
        struct wl_map map;
        EGLSurface surface;
-
+       struct wl_surface *wl_surface;
+       int width, height;
        struct wl_list link;
 };
 
@@ -616,6 +617,7 @@ notify_surface_create(struct wl_compositor *compositor,
                return;
 
        es->surface = EGL_NO_SURFACE;
+       es->wl_surface = surface;
        wl_surface_set_data(surface, es);
        wl_list_insert(ec->surface_list.prev, &es->link);
 
@@ -654,6 +656,8 @@ notify_surface_attach(struct wl_compositor *compositor,
        if (es->surface != EGL_NO_SURFACE)
                eglDestroySurface(ec->display, es->surface);
 
+       es->width = width;
+       es->height = height;
        es->surface = eglCreateSurfaceForName(ec->display, ec->config,
                                              name, width, height, stride, NULL);
 
@@ -722,18 +726,6 @@ notify_commit(struct wl_compositor *compositor)
        return ec->current_frame;
 }
 
-static void
-notify_pointer_motion(struct wl_compositor *compositor,
-                     struct wl_object *source, int x, int y)
-{
-       struct egl_compositor *ec = (struct egl_compositor *) compositor;
-       const int hotspot_x = 16, hotspot_y = 16;
-
-       ec->pointer->map.x = x - hotspot_x;
-       ec->pointer->map.y = y - hotspot_y;
-       schedule_repaint(ec);
-}
-
 static struct egl_surface *
 pick_surface(struct egl_compositor *ec, int32_t x, int32_t y)
 {
@@ -754,6 +746,28 @@ pick_surface(struct egl_compositor *ec, int32_t x, int32_t y)
 }
 
 static void
+notify_pointer_motion(struct wl_compositor *compositor,
+                     struct wl_object *source, int x, int y)
+{
+       struct egl_compositor *ec = (struct egl_compositor *) compositor;
+       struct egl_surface *es;
+       const int hotspot_x = 16, hotspot_y = 16;
+       int32_t sx, sy;
+
+       es = pick_surface(ec, x, y);
+       if (es) {
+               sx = (x - es->map.x) * es->width / es->map.width;
+               sy = (y - es->map.y) * es->height / es->map.height;
+               wl_display_post_surface_motion(ec->wl_display, es->wl_surface, 
+                                              source, x, y, sx, sy);
+       }
+
+       ec->pointer->map.x = x - hotspot_x;
+       ec->pointer->map.y = y - hotspot_y;
+       schedule_repaint(ec);
+}
+
+static void
 notify_pointer_button(struct wl_compositor *compositor,
                      struct wl_object *source,
                      int32_t button, int32_t state)
index 8a5f894..c1ccd74 100644 (file)
--- a/wayland.c
+++ b/wayland.c
@@ -70,6 +70,7 @@ struct wl_display {
 struct wl_surface {
        struct wl_object base;
 
+       struct wl_client *client;
        /* provided by client */
        int width, height;
        int buffer;
@@ -173,7 +174,8 @@ static const struct wl_interface surface_interface = {
 };
 
 static struct wl_surface *
-wl_surface_create(struct wl_display *display, uint32_t id)
+wl_surface_create(struct wl_display *display,
+                 struct wl_client *client, uint32_t id)
 {
        struct wl_surface *surface;
        const struct wl_compositor_interface *interface;
@@ -184,6 +186,7 @@ wl_surface_create(struct wl_display *display, uint32_t id)
 
        surface->base.id = id;
        surface->base.interface = &surface_interface;
+       surface->client = client;
 
        wl_list_insert(display->surface_list.prev, &surface->link);
 
@@ -500,7 +503,7 @@ wl_display_create_surface(struct wl_client *client,
        struct wl_surface *surface;
        struct wl_object_ref *ref;
 
-       surface = wl_surface_create(display, id);
+       surface = wl_surface_create(display, client, id);
 
        ref = malloc(sizeof *ref);
        if (ref == NULL) {
@@ -630,11 +633,28 @@ wl_display_send_event(struct wl_display *display, uint32_t *data, size_t size)
 #define WL_INPUT_KEY 2
 
 WL_EXPORT void
+wl_display_post_surface_motion(struct wl_display *display,
+                              struct wl_surface *surface,
+                              struct wl_object *source,
+                              int32_t x, int32_t y, int32_t sx, int32_t sy)
+{
+       uint32_t p[6];
+
+       p[0] = source->id;
+       p[1] = (sizeof p << 16) | WL_INPUT_MOTION;
+       p[2] = x;
+       p[3] = y;
+       p[4] = sx;
+       p[5] = sy;
+
+       wl_connection_write(surface->client->connection, p, sizeof p);
+}
+
+WL_EXPORT void
 wl_display_post_relative_event(struct wl_display *display,
                               struct wl_object *source, int dx, int dy)
 {
        const struct wl_compositor_interface *interface;
-       uint32_t p[4];
 
        display->pointer_x += dx;
        display->pointer_y += dy;
@@ -642,13 +662,6 @@ wl_display_post_relative_event(struct wl_display *display,
        interface = display->compositor->interface;
        interface->notify_pointer_motion(display->compositor, source,
                                         display->pointer_x, display->pointer_y);
-
-       p[0] = source->id;
-       p[1] = (sizeof p << 16) | WL_INPUT_MOTION;
-       p[2] = display->pointer_x;
-       p[3] = display->pointer_y;
-
-       wl_display_send_event(display, p, sizeof p);
 }
 
 WL_EXPORT void
@@ -656,7 +669,6 @@ wl_display_post_absolute_event(struct wl_display *display,
                               struct wl_object *source, int x, int y)
 {
        const struct wl_compositor_interface *interface;
-       uint32_t p[4];
 
        display->pointer_x = x;
        display->pointer_y = y;
@@ -664,13 +676,6 @@ wl_display_post_absolute_event(struct wl_display *display,
        interface = display->compositor->interface;
        interface->notify_pointer_motion(display->compositor, source,
                                         display->pointer_x, display->pointer_y);
-
-       p[0] = source->id;
-       p[1] = (sizeof p << 16) | WL_INPUT_MOTION;
-       p[2] = display->pointer_x;
-       p[3] = display->pointer_y;
-
-       wl_display_send_event(display, p, sizeof p);
 }
 
 WL_EXPORT void
index c9ff589..1f338af 100644 (file)
--- a/wayland.h
+++ b/wayland.h
@@ -135,6 +135,11 @@ wl_display_post_key_event(struct wl_display *display,
 void
 wl_display_post_frame(struct wl_display *display,
                      uint32_t frame, uint32_t msecs);
+void
+wl_display_post_surface_motion(struct wl_display *display,
+                              struct wl_surface *surface,
+                              struct wl_object *source,
+                              int x, int y, int sx, int sy);
 
 struct wl_compositor {
        const struct wl_compositor_interface *interface;