diff --git a/egl-compositor.c b/egl-compositor.c index c37ea120..dbfd48dd 100644 --- a/egl-compositor.c +++ b/egl-compositor.c @@ -178,11 +178,36 @@ notify_surface_map(struct wl_compositor *compositor, schedule_repaint(ec); } +static void +notify_surface_copy(struct wl_compositor *compositor, + struct wl_surface *surface, + int32_t dst_x, int32_t dst_y, + uint32_t name, uint32_t stride, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + /* FIXME: Eek, how do we do this... extend the DRI CopyBuffer + * extension and expose it in eagle? Make the surface the + * draw buffer and the named buffer the read buffer and use + * glCopyPixels? */ +} + +static void +notify_surface_damage(struct wl_compositor *compositor, + struct wl_surface *surface) +{ + struct egl_compositor *ec = (struct egl_compositor *) compositor; + + /* FIXME: This need to take a damage region, of course. */ + schedule_repaint(ec); +} + static const struct wl_compositor_interface interface = { notify_surface_create, notify_surface_destroy, notify_surface_attach, - notify_surface_map + notify_surface_map, + notify_surface_copy, + notify_surface_damage }; static const char gem_device[] = "/dev/dri/card0"; diff --git a/glx-compositor.c b/glx-compositor.c index 574caaf6..2c3e7e3d 100644 --- a/glx-compositor.c +++ b/glx-compositor.c @@ -207,11 +207,32 @@ notify_surface_map(struct wl_compositor *compositor, schedule_repaint(gc); } +static void +notify_surface_copy(struct wl_compositor *compositor, + struct wl_surface *surface, + int32_t dst_x, int32_t dst_y, + uint32_t name, uint32_t stride, + int32_t x, int32_t y, int32_t width, int32_t height) +{ +} + +static void +notify_surface_damage(struct wl_compositor *compositor, + struct wl_surface *surface, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + struct glx_compositor *gc = (struct glx_compositor *) compositor; + + schedule_repaint(gc); +} + static const struct wl_compositor_interface interface = { notify_surface_create, notify_surface_destroy, notify_surface_attach, - notify_surface_map + notify_surface_map, + notify_surface_copy, + notify_surface_damage }; static const char gem_device[] = "/dev/dri/card0"; diff --git a/wayland-client.c b/wayland-client.c index 8f673cc1..8503a304 100644 --- a/wayland-client.c +++ b/wayland-client.c @@ -173,6 +173,8 @@ wl_display_create_surface(struct wl_display *display) #define WL_SURFACE_DESTROY 0 #define WL_SURFACE_ATTACH 1 #define WL_SURFACE_MAP 2 +#define WL_SURFACE_COPY 3 +#define WL_SURFACE_DAMAGE 4 void wl_surface_destroy(struct wl_surface *surface) { @@ -185,8 +187,8 @@ void wl_surface_destroy(struct wl_surface *surface) request, sizeof request); } -void wl_surface_attach(struct wl_surface *surface, - uint32_t name, int width, int height, int stride) +void wl_surface_attach(struct wl_surface *surface, uint32_t name, + int32_t width, int32_t height, uint32_t stride) { uint32_t request[6]; @@ -201,7 +203,6 @@ void wl_surface_attach(struct wl_surface *surface, request, sizeof request); } - void wl_surface_map(struct wl_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height) { @@ -217,3 +218,41 @@ void wl_surface_map(struct wl_surface *surface, wl_connection_write(surface->proxy.display->connection, request, sizeof request); } + +void wl_surface_copy(struct wl_surface *surface, int32_t dst_x, int32_t dst_y, + uint32_t name, uint32_t stride, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + uint32_t request[10]; + + request[0] = surface->proxy.id; + request[1] = WL_SURFACE_COPY | ((sizeof request) << 16); + request[2] = dst_x; + request[3] = dst_y; + request[4] = name; + request[5] = stride; + request[6] = x; + request[7] = y; + request[8] = width; + request[9] = height; + + wl_connection_write(surface->proxy.display->connection, + request, sizeof request); +} + +void wl_surface_damage(struct wl_surface *surface, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + uint32_t request[6]; + + request[0] = surface->proxy.id; + request[1] = WL_SURFACE_DAMAGE | ((sizeof request) << 16); + request[2] = x; + request[3] = y; + request[4] = width; + request[5] = height; + + wl_connection_write(surface->proxy.display->connection, + request, sizeof request); +} + diff --git a/wayland-client.h b/wayland-client.h index ce33b7b2..82b9b7ce 100644 --- a/wayland-client.h +++ b/wayland-client.h @@ -27,8 +27,13 @@ wl_display_create_surface(struct wl_display *display); void wl_surface_destroy(struct wl_surface *surface); void wl_surface_attach(struct wl_surface *surface, - uint32_t name, int width, int height, int stride); + uint32_t name, int32_t width, int32_t height, uint32_t stride); void wl_surface_map(struct wl_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height); +void wl_surface_copy(struct wl_surface *surface, int32_t dst_x, int32_t dst_y, + uint32_t name, uint32_t stride, + int32_t x, int32_t y, int32_t width, int32_t height); +void wl_surface_damage(struct wl_surface *surface, + int32_t x, int32_t y, int32_t width, int32_t height); #endif diff --git a/wayland.c b/wayland.c index b51d3877..65dd870f 100644 --- a/wayland.c +++ b/wayland.c @@ -152,13 +152,61 @@ static const struct wl_argument map_arguments[] = { { WL_ARGUMENT_UINT32 }, }; +void +wl_surface_copy(struct wl_client *client, struct wl_surface *surface, + int32_t dst_x, int32_t dst_y, uint32_t name, uint32_t stride, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + const struct wl_compositor_interface *interface; + + interface = client->display->compositor->interface; + interface->notify_surface_copy(client->display->compositor, + surface, dst_x, dst_y, + name, stride, x, y, width, height); +} + +static const struct wl_argument copy_arguments[] = { + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, +}; + +void +wl_surface_damage(struct wl_client *client, struct wl_surface *surface, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + const struct wl_compositor_interface *interface; + + interface = client->display->compositor->interface; + interface->notify_surface_damage(client->display->compositor, + surface, x, y, width, height); +} + +static const struct wl_argument damage_arguments[] = { + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, + { WL_ARGUMENT_UINT32 }, +}; + static const struct wl_method surface_methods[] = { { "destroy", wl_surface_destroy, 0, NULL }, { "attach", wl_surface_attach, ARRAY_LENGTH(attach_arguments), attach_arguments }, { "map", wl_surface_map, - ARRAY_LENGTH(map_arguments), map_arguments } + ARRAY_LENGTH(map_arguments), map_arguments }, + { "copy", wl_surface_copy, + ARRAY_LENGTH(copy_arguments), copy_arguments }, + { "damage", wl_surface_damage, + ARRAY_LENGTH(damage_arguments), damage_arguments } }; static const struct wl_interface surface_interface = { @@ -207,7 +255,7 @@ static void wl_client_demarshal(struct wl_client *client, struct wl_object *target, const struct wl_method *method, size_t size) { - ffi_type *types[10]; + ffi_type *types[20]; ffi_cif cif; uint32_t *p, result; int i; @@ -216,8 +264,8 @@ wl_client_demarshal(struct wl_client *client, struct wl_object *target, const char *string; void *object; uint32_t new_id; - } values[10]; - void *args[10]; + } values[20]; + void *args[20]; struct wl_object *object; uint32_t data[64]; @@ -741,7 +789,7 @@ load_compositor(struct wl_display *display, const char *path) int main(int argc, char *argv[]) { struct wl_display *display; - const char *compositor = "egl-compositor.so"; + const char *compositor = "./egl-compositor.so"; display = wl_display_create(); diff --git a/wayland.h b/wayland.h index ec28a44e..c834aca1 100644 --- a/wayland.h +++ b/wayland.h @@ -122,10 +122,24 @@ struct wl_compositor_interface { void (*notify_surface_destroy)(struct wl_compositor *compositor, struct wl_surface *surface); void (*notify_surface_attach)(struct wl_compositor *compositor, - struct wl_surface *surface, uint32_t name, - uint32_t width, uint32_t height, uint32_t stride); + struct wl_surface *surface, + uint32_t name, + uint32_t width, uint32_t height, + uint32_t stride); void (*notify_surface_map)(struct wl_compositor *compositor, - struct wl_surface *surface, struct wl_map *map); + struct wl_surface *surface, + struct wl_map *map); + void (*notify_surface_copy)(struct wl_compositor *compositor, + struct wl_surface *surface, + int32_t dst_x, int32_t dst_y, + uint32_t name, uint32_t stride, + int32_t x, int32_t y, + int32_t width, int32_t height); + void (*notify_surface_damage)(struct wl_compositor *compositor, + struct wl_surface *surface, + int32_t x, int32_t y, + int32_t width, int32_t height); + }; void wl_display_set_compositor(struct wl_display *display, diff --git a/window.c b/window.c index 3cc894f8..94cd2bfa 100644 --- a/window.c +++ b/window.c @@ -329,6 +329,8 @@ int main(int argc, char *argv[]) while (ret = poll(p, 1, 20), ret >= 0) { mask = 0; gears_draw(gears, angle); + wl_surface_damage(window.surface, 0, 0, + window.width, window.height); angle += 1; if (p[0].revents & POLLIN) mask |= WL_CONNECTION_READABLE;