diff --git a/egl-compositor.c b/egl-compositor.c index c70b2ded..c05f3631 100644 --- a/egl-compositor.c +++ b/egl-compositor.c @@ -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) { @@ -753,6 +745,28 @@ pick_surface(struct egl_compositor *ec, int32_t x, int32_t y) return NULL; } +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, diff --git a/wayland.c b/wayland.c index 8a5f894e..c1ccd746 100644 --- 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) { @@ -629,12 +632,29 @@ wl_display_send_event(struct wl_display *display, uint32_t *data, size_t size) #define WL_INPUT_BUTTON 1 #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 diff --git a/wayland.h b/wayland.h index c9ff5894..1f338af2 100644 --- 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;