diff options
| author | Kristian Høgsberg <krh@redhat.com> | 2008-12-15 20:35:24 -0500 |
|---|---|---|
| committer | Kristian Høgsberg <krh@redhat.com> | 2008-12-15 20:35:24 -0500 |
| commit | d2412e2c2ea463189550d5f7a5d95a7aab13a502 (patch) | |
| tree | 52663e9e69620646fc8e2cbff63948567b648b88 /wayland.c | |
| parent | Use gdk-pixbuf for saving the screenshot. (diff) | |
| download | wayland-d2412e2c2ea463189550d5f7a5d95a7aab13a502.tar wayland-d2412e2c2ea463189550d5f7a5d95a7aab13a502.tar.gz wayland-d2412e2c2ea463189550d5f7a5d95a7aab13a502.tar.bz2 wayland-d2412e2c2ea463189550d5f7a5d95a7aab13a502.tar.lz wayland-d2412e2c2ea463189550d5f7a5d95a7aab13a502.tar.xz wayland-d2412e2c2ea463189550d5f7a5d95a7aab13a502.tar.zst wayland-d2412e2c2ea463189550d5f7a5d95a7aab13a502.zip | |
Redesign the compositor / server interface.
This lets the compositor directly provide the implementation of the RMI
objects for the surface object and a new compositor object. We avoid the
manual forwarding of requests into the compositor and the clumsy compositor
interface struct.
Diffstat (limited to 'wayland.c')
| -rw-r--r-- | wayland.c | 288 |
1 files changed, 93 insertions, 195 deletions
@@ -43,7 +43,6 @@ struct wl_client { struct wl_display *display; struct wl_list object_list; struct wl_list link; - uint32_t pending_frame; }; struct wl_display { @@ -51,160 +50,18 @@ struct wl_display { struct wl_event_loop *loop; struct wl_hash *objects; - struct wl_object *pointer; - - struct wl_compositor *compositor; - struct wl_compositor_interface *compositor_interface; - - struct wl_list surface_list; - struct wl_list client_list; + struct wl_list pending_frame_list; uint32_t client_id_range; uint32_t id; struct wl_list global_list; }; -struct wl_surface { - struct wl_object base; - - struct wl_client *client; - /* provided by client */ - int width, height; - int buffer; - int stride; - - struct wl_map map; - struct wl_list link; - - /* how to convert buffer contents to pixels in screen format; - * yuv->rgb, indexed->rgb, svg->rgb, but mostly just rgb->rgb. */ - - /* how to transform/render rectangular contents to polygons. */ - - void *compositor_data; -}; - struct wl_object_ref { struct wl_object *object; struct wl_list link; }; -static void -wl_surface_destroy(struct wl_client *client, - struct wl_surface *surface) -{ - const struct wl_compositor_interface *interface; - - interface = client->display->compositor->interface; - interface->notify_surface_destroy(client->display->compositor, - surface); - wl_list_remove(&surface->link); -} - -static void -wl_surface_attach(struct wl_client *client, - struct wl_surface *surface, uint32_t name, - uint32_t width, uint32_t height, uint32_t stride) -{ - const struct wl_compositor_interface *interface; - - interface = client->display->compositor->interface; - interface->notify_surface_attach(client->display->compositor, - surface, name, width, height, stride); -} - -static void -wl_surface_map(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; - - /* FIXME: This needs to take a tri-mesh argument... - count - * and a list of tris. 0 tris means unmap. */ - - surface->map.x = x; - surface->map.y = y; - surface->map.width = width; - surface->map.height = height; - - interface = client->display->compositor->interface; - interface->notify_surface_map(client->display->compositor, - surface, &surface->map); -} - -static 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 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_method surface_methods[] = { - { "destroy", wl_surface_destroy, "" }, - { "attach", wl_surface_attach, "uuuu" }, - { "map", wl_surface_map, "iiii" }, - { "copy", wl_surface_copy, "iiuuiiii" }, - { "damage", wl_surface_damage, "iiii" } -}; - -static const struct wl_interface surface_interface = { - "surface", 1, - ARRAY_LENGTH(surface_methods), - surface_methods, -}; - -static struct wl_surface * -wl_surface_create(struct wl_display *display, - struct wl_client *client, uint32_t id) -{ - struct wl_surface *surface; - const struct wl_compositor_interface *interface; - - surface = malloc(sizeof *surface); - if (surface == NULL) - return NULL; - - surface->base.id = id; - surface->base.interface = &surface_interface; - surface->client = client; - - wl_list_insert(display->surface_list.prev, &surface->link); - - interface = display->compositor->interface; - interface->notify_surface_create(display->compositor, surface); - - return surface; -} - -WL_EXPORT void -wl_surface_set_data(struct wl_surface *surface, void *data) -{ - surface->compositor_data = data; -} - -WL_EXPORT void * -wl_surface_get_data(struct wl_surface *surface) -{ - return surface->compositor_data; -} - void wl_client_destroy(struct wl_client *client); @@ -264,8 +121,9 @@ wl_client_marshal(struct wl_client *client, struct wl_object *sender, static void wl_client_demarshal(struct wl_client *client, struct wl_object *target, - const struct wl_method *method, size_t size) + uint32_t opcode, size_t size) { + const struct wl_method *method; ffi_type *types[20]; ffi_cif cif; uint32_t *p, result; @@ -279,7 +137,9 @@ wl_client_demarshal(struct wl_client *client, struct wl_object *target, void *args[20]; struct wl_object *object; uint32_t data[64]; + void (*func)(void); + method = &target->interface->methods[opcode]; count = strlen(method->signature) + 2; if (count > ARRAY_LENGTH(types)) { printf("too many args (%d)\n", count); @@ -341,22 +201,20 @@ wl_client_demarshal(struct wl_client *client, struct wl_object *target, args[i] = &values[i]; } + func = target->implementation[opcode]; ffi_prep_cif(&cif, FFI_DEFAULT_ABI, count, &ffi_type_uint32, types); - ffi_call(&cif, FFI_FN(method->func), &result, args); + ffi_call(&cif, func, &result, args); } #define WL_DISPLAY_INVALID_OBJECT 0 #define WL_DISPLAY_INVALID_METHOD 1 #define WL_DISPLAY_NO_MEMORY 2 -#define WL_DISPLAY_ACKNOWLEDGE 3 -#define WL_DISPLAY_FRAME 4 static void wl_client_connection_data(int fd, uint32_t mask, void *data) { struct wl_client *client = data; struct wl_connection *connection = client->connection; - const struct wl_method *method; struct wl_object *object; uint32_t p[2], opcode, size; uint32_t cmask = 0; @@ -397,8 +255,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) continue; } - method = &object->interface->methods[opcode]; - wl_client_demarshal(client, object, method, size); + wl_client_demarshal(client, object, opcode, size); wl_connection_consume(connection, size); len -= size; } @@ -455,6 +312,7 @@ wl_client_create(struct wl_display *display, int fd) wl_client_connection_update, client); wl_list_init(&client->object_list); + wl_list_init(&client->link); wl_connection_write(client->connection, &display->client_id_range, @@ -474,11 +332,19 @@ wl_client_create(struct wl_display *display, int fd) struct wl_object_ref, link); } - wl_list_insert(display->client_list.prev, &client->link); - return client; } +static void +wl_object_destroy(struct wl_object *object) +{ + const struct wl_surface_interface *interface = + (const struct wl_surface_interface *) object->implementation; + + /* FIXME: Need generic object destructor. */ + interface->destroy(NULL, (struct wl_surface *) object); +} + void wl_client_destroy(struct wl_client *client) { @@ -492,7 +358,7 @@ wl_client_destroy(struct wl_client *client) ref = container_of(client->object_list.next, struct wl_object_ref, link); wl_list_remove(&ref->link); - wl_surface_destroy(client, (struct wl_surface *) ref->object); + wl_object_destroy(ref->object); free(ref); } @@ -501,14 +367,33 @@ wl_client_destroy(struct wl_client *client) free(client); } -static int -wl_display_create_surface(struct wl_client *client, - struct wl_display *display, uint32_t id) +static const struct wl_method surface_methods[] = { + { "destroy", "" }, + { "attach", "uuuu" }, + { "map", "iiii" }, + { "copy", "iiuuiiii" }, + { "damage", "iiii" } +}; + +static const struct wl_interface surface_interface = { + "surface", 1, + ARRAY_LENGTH(surface_methods), + surface_methods, +}; + +WL_EXPORT int +wl_client_add_surface(struct wl_client *client, + struct wl_surface *surface, + const struct wl_surface_interface *implementation, + uint32_t id) { - struct wl_surface *surface; + struct wl_display *display = client->display; struct wl_object_ref *ref; - surface = wl_surface_create(display, client, id); + surface->base.id = id; + surface->base.interface = &surface_interface; + surface->base.implementation = (void (**)(void)) implementation; + surface->client = client; ref = malloc(sizeof *ref); if (ref == NULL) { @@ -524,39 +409,61 @@ wl_display_create_surface(struct wl_client *client, return 0; } -static int -wl_display_commit(struct wl_client *client, - struct wl_display *display, uint32_t key) +#define WL_COMPOSITOR_ACKNOWLEDGE 0 +#define WL_COMPOSITOR_FRAME 1 + +WL_EXPORT void +wl_client_send_acknowledge(struct wl_client *client, + struct wl_compositor *compositor, + uint32_t key, uint32_t frame) { - const struct wl_compositor_interface *interface; - uint32_t frame; + wl_list_remove(&client->link); + wl_list_insert(client->display->pending_frame_list.prev, + &client->link); + wl_client_marshal(client, &compositor->base, + WL_COMPOSITOR_ACKNOWLEDGE, key, frame); +} + +static const struct wl_method compositor_methods[] = { + { "create_surface", "n" }, + { "commit", "u" } +}; + +static const struct wl_event compositor_events[] = { + { "acknowledge", "uu" }, + { "frame", "uu" } +}; + +static const struct wl_interface compositor_interface = { + "compositor", 1, + ARRAY_LENGTH(compositor_methods), compositor_methods, + ARRAY_LENGTH(compositor_events), compositor_events, +}; - client->pending_frame = 1; +WL_EXPORT int +wl_display_set_compositor(struct wl_display *display, + struct wl_compositor *compositor, + const struct wl_compositor_interface *implementation) +{ + compositor->base.interface = &compositor_interface; + compositor->base.implementation = (void (**)(void)) implementation; - interface = display->compositor->interface; - frame = interface->notify_commit(display->compositor); - wl_client_marshal(client, &display->base, - WL_DISPLAY_ACKNOWLEDGE, key, frame); + wl_display_add_object(display, &compositor->base); + if (wl_display_add_global(display, &compositor->base)) + return -1; return 0; } -static const struct wl_method display_methods[] = { - { "create_surface", wl_display_create_surface, "n" }, - { "commit", wl_display_commit, "u" } -}; - static const struct wl_event display_events[] = { { "invalid_object", "u" }, { "invalid_method", "uu" }, { "no_memory", "" }, - { "acknowledge", "uu" }, - { "frame", "uu" } }; static const struct wl_interface display_interface = { "display", 1, - ARRAY_LENGTH(display_methods), display_methods, + 0, NULL, ARRAY_LENGTH(display_events), display_events, }; @@ -581,14 +488,14 @@ wl_display_create(void) return NULL; } - wl_list_init(&display->surface_list); - wl_list_init(&display->client_list); + wl_list_init(&display->pending_frame_list); wl_list_init(&display->global_list); display->client_id_range = 256; /* Gah, arbitrary... */ display->id = 1; display->base.interface = &display_interface; + display->base.implementation = NULL; wl_display_add_object(display, &display->base); if (wl_display_add_global(display, &display->base)) { wl_event_loop_destroy(display->loop); @@ -636,9 +543,6 @@ wl_surface_post_event(struct wl_surface *surface, struct wl_input_device { struct wl_object base; struct wl_display *display; - uint32_t button_state[16]; - uint32_t button_count; - int32_t x, y; }; static const struct wl_method input_device_methods[] = { @@ -666,29 +570,23 @@ wl_input_device_get_interface(void) WL_EXPORT void wl_display_post_frame(struct wl_display *display, + struct wl_compositor *compositor, uint32_t frame, uint32_t msecs) { struct wl_client *client; - client = container_of(display->client_list.next, + client = container_of(display->pending_frame_list.next, struct wl_client, link); - while (&client->link != &display->client_list) { - if (client->pending_frame) { - wl_client_marshal(client, &display->base, - WL_DISPLAY_FRAME, frame, msecs); - client->pending_frame = 0; - } + while (&client->link != &display->pending_frame_list) { + wl_client_marshal(client, &compositor->base, + WL_COMPOSITOR_FRAME, frame, msecs); client = container_of(client->link.next, struct wl_client, link); } -} -WL_EXPORT void -wl_display_set_compositor(struct wl_display *display, - struct wl_compositor *compositor) -{ - display->compositor = compositor; + wl_list_remove(&display->pending_frame_list); + wl_list_init(&display->pending_frame_list); } WL_EXPORT struct wl_event_loop * |
