From: Kristian Høgsberg Date: Mon, 9 Aug 2010 18:43:33 +0000 (-0400) Subject: Introduce 'buffer' object for attaching, image cahce and cursor images X-Git-Tag: upstream/0.1.8~3853 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5fcd0aa58e243caf24f4deb080ac76e83d52213f;p=profile%2Fivi%2Fweston-ivi-shell.git Introduce 'buffer' object for attaching, image cahce and cursor images The buffer object is created by a 'drm' object, which encapsulates the buffer sharing and authentication mechanism. Once the buffer is created it can be attached to a surface. --- diff --git a/Makefile b/Makefile index cf449be..3de68cb 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,8 @@ compositor : \ compositor-drm.o \ compositor-x11.o \ screenshooter.o \ - cairo-util.o + cairo-util.o \ + drm.o compositor : CFLAGS += $(COMPOSITOR_CFLAGS) compositor : LDLIBS += ./libwayland-server.so $(COMPOSITOR_LIBS) -rdynamic -lrt -lEGL -lm diff --git a/clients/window.c b/clients/window.c index b2c4f03..864a5e4 100644 --- a/clients/window.c +++ b/clients/window.c @@ -53,6 +53,7 @@ struct display { struct wl_display *display; struct wl_compositor *compositor; struct wl_shell *shell; + struct wl_drm *drm; struct wl_output *output; struct rectangle screen_allocation; EGLDisplay dpy; @@ -178,6 +179,8 @@ static void window_attach_surface(struct window *window) { struct wl_visual *visual; + struct display *display = window->display; + struct wl_buffer *buffer; struct surface_data *data; EGLint name, stride; @@ -192,13 +195,16 @@ window_attach_surface(struct window *window) eglExportDRMImageMESA(window->display->dpy, data->image, &name, NULL, &stride); - visual = wl_display_get_premultiplied_argb_visual(window->display->display); - wl_surface_attach(window->surface, - name, - window->allocation.width, - window->allocation.height, - stride, - visual); + visual = wl_display_get_premultiplied_argb_visual(display->display); + buffer = wl_drm_create_buffer(display->drm, + name, + window->allocation.width, + window->allocation.height, + stride, + visual); + + wl_surface_attach(window->surface, buffer); + wl_buffer_destroy(buffer); wl_surface_map(window->surface, window->allocation.x, @@ -679,15 +685,22 @@ window_create(struct display *display, const char *title, } static void -display_handle_device(void *data, - struct wl_compositor *compositor, - const char *device) +drm_handle_device(void *data, struct wl_drm *drm, const char *device) { struct display *d = data; d->device_name = strdup(device); } +static void drm_handle_authenticated(void *data, struct wl_drm *drm) +{ +} + +static const struct wl_drm_listener drm_listener = { + drm_handle_device, + drm_handle_authenticated +}; + static void display_handle_acknowledge(void *data, struct wl_compositor *compositor, @@ -726,7 +739,6 @@ display_handle_frame(void *data, } static const struct wl_compositor_listener compositor_listener = { - display_handle_device, display_handle_acknowledge, display_handle_frame, }; @@ -785,6 +797,9 @@ display_handle_global(struct wl_display *display, } else if (wl_object_implements(object, "shell", 1)) { d->shell = (struct wl_shell *) object; wl_shell_add_listener(d->shell, &shell_listener, d); + } else if (wl_object_implements(object, "drm", 1)) { + d->drm = (struct wl_drm *) object; + wl_drm_add_listener(d->drm, &drm_listener, d); } } diff --git a/compositor-drm.c b/compositor-drm.c index b893fc4..6d156bb 100644 --- a/compositor-drm.c +++ b/compositor-drm.c @@ -41,7 +41,6 @@ struct drm_compositor { struct udev *udev; struct wl_event_source *drm_source; - int drm_fd; struct wl_event_source *term_signal_source; @@ -272,7 +271,7 @@ drm_compositor_present(struct wlsc_compositor *ec) GL_RENDERBUFFER, output->rbo[output->current]); - drmModePageFlip(c->drm_fd, output->crtc_id, + drmModePageFlip(c->base.drm.fd, output->crtc_id, output->fb_id[output->current ^ 1], DRM_MODE_PAGE_FLIP_EVENT, output); } @@ -305,22 +304,25 @@ static int init_egl(struct drm_compositor *ec, struct udev_device *device) { EGLint major, minor; - const char *extensions; + const char *extensions, *filename; + int fd; static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - ec->base.base.device = strdup(udev_device_get_devnode(device)); - ec->drm_fd = open(ec->base.base.device, O_RDWR); - if (ec->drm_fd < 0) { + filename = udev_device_get_devnode(device); + fd = open(filename, O_RDWR); + if (fd < 0) { /* Probably permissions error */ fprintf(stderr, "couldn't open %s, skipping\n", udev_device_get_devnode(device)); return -1; } - ec->base.display = eglGetDRMDisplayMESA(ec->drm_fd); + wlsc_drm_init(&ec->base, fd, filename); + + ec->base.display = eglGetDRMDisplayMESA(ec->base.drm.fd); if (ec->base.display == NULL) { fprintf(stderr, "failed to create display\n"); return -1; @@ -390,7 +392,7 @@ create_output_for_connector(struct drm_compositor *ec, else mode = &builtin_1024x768; - encoder = drmModeGetEncoder(ec->drm_fd, connector->encoders[0]); + encoder = drmModeGetEncoder(ec->base.drm.fd, connector->encoders[0]); if (encoder == NULL) { fprintf(stderr, "No encoder for connector.\n"); return -1; @@ -428,7 +430,7 @@ create_output_for_connector(struct drm_compositor *ec, eglExportDRMImageMESA(ec->base.display, output->image[i], NULL, &handle, &stride); - ret = drmModeAddFB(ec->drm_fd, + ret = drmModeAddFB(ec->base.drm.fd, output->base.width, output->base.height, 32, 32, stride, handle, &output->fb_id[i]); if (ret) { @@ -442,7 +444,7 @@ create_output_for_connector(struct drm_compositor *ec, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, output->rbo[output->current]); - ret = drmModeSetCrtc(ec->drm_fd, output->crtc_id, + ret = drmModeSetCrtc(ec->base.drm.fd, output->crtc_id, output->fb_id[output->current ^ 1], 0, 0, &output->connector_id, 1, &output->mode); if (ret) { @@ -462,14 +464,14 @@ create_outputs(struct drm_compositor *ec) drmModeRes *resources; int i; - resources = drmModeGetResources(ec->drm_fd); + resources = drmModeGetResources(ec->base.drm.fd); if (!resources) { fprintf(stderr, "drmModeGetResources failed\n"); return -1; } for (i = 0; i < resources->count_connectors; i++) { - connector = drmModeGetConnector(ec->drm_fd, resources->connectors[i]); + connector = drmModeGetConnector(ec->base.drm.fd, resources->connectors[i]); if (connector == NULL) continue; @@ -498,7 +500,7 @@ static void on_enter_vt(int signal_number, void *data) struct drm_output *output; int ret; - ret = drmSetMaster(ec->drm_fd); + ret = drmSetMaster(ec->base.drm.fd); if (ret) { fprintf(stderr, "failed to set drm master\n"); kill(0, SIGTERM); @@ -511,7 +513,7 @@ static void on_enter_vt(int signal_number, void *data) ec->vt_active = 1; wl_list_for_each(output, &ec->base.output_list, base.link) { - ret = drmModeSetCrtc(ec->drm_fd, output->crtc_id, + ret = drmModeSetCrtc(ec->base.drm.fd, output->crtc_id, output->fb_id[output->current ^ 1], 0, 0, &output->connector_id, 1, &output->mode); if (ret) @@ -526,7 +528,7 @@ static void on_leave_vt(int signal_number, void *data) struct drm_compositor *ec = data; int ret; - ret = drmDropMaster(ec->drm_fd); + ret = drmDropMaster(ec->base.drm.fd); if (ret) { fprintf(stderr, "failed to drop drm master\n"); kill(0, SIGTERM); @@ -644,6 +646,7 @@ drm_compositor_create(struct wl_display *display) return NULL; } + ec->base.wl_display = display; if (init_egl(ec, device) < 0) { fprintf(stderr, "failed to initialize egl\n"); return NULL; @@ -662,7 +665,7 @@ drm_compositor_create(struct wl_display *display) loop = wl_display_get_event_loop(ec->base.wl_display); ec->drm_source = - wl_event_loop_add_fd(loop, ec->drm_fd, + wl_event_loop_add_fd(loop, ec->base.drm.fd, WL_EVENT_READABLE, on_drm_input, ec); setup_tty(ec, loop); ec->base.present = drm_compositor_present; diff --git a/compositor-x11.c b/compositor-x11.c index 9c4f845..27bf328 100644 --- a/compositor-x11.c +++ b/compositor-x11.c @@ -50,7 +50,6 @@ struct x11_compositor { xcb_cursor_t null_cursor; int dri2_major; int dri2_minor; - int drm_fd; struct wl_event_source *xcb_source; struct { xcb_atom_t wm_protocols; @@ -104,6 +103,8 @@ dri2_connect(struct x11_compositor *c) xcb_dri2_connect_reply_t *connect; xcb_dri2_connect_cookie_t connect_cookie; xcb_generic_error_t *error; + char path[256]; + int fd; xcb_prefetch_extension_data (c->conn, &xcb_xfixes_id); xcb_prefetch_extension_data (c->conn, &xcb_dri2_id); @@ -152,17 +153,19 @@ dri2_connect(struct x11_compositor *c) return -1; } - c->base.base.device = - strndup(xcb_dri2_connect_device_name (connect), - xcb_dri2_connect_device_name_length (connect)); - - if (c->base.base.device == NULL) { - free(connect); + snprintf(path, sizeof path, "%.*s", + xcb_dri2_connect_device_name_length (connect), + xcb_dri2_connect_device_name (connect)); + free(connect); + + fd = open(path, O_RDWR); + if (fd < 0) { + fprintf(stderr, + "DRI2: could not open %s (%s)", path, strerror(errno)); return -1; } - free(connect); - return 0; + return wlsc_drm_init(&c->base, fd, path); } static int @@ -172,7 +175,7 @@ dri2_authenticate(struct x11_compositor *c) xcb_dri2_authenticate_cookie_t authenticate_cookie; drm_magic_t magic; - if (drmGetMagic(c->drm_fd, &magic)) { + if (drmGetMagic(c->base.drm.fd, &magic)) { fprintf(stderr, "DRI2: failed to get drm magic"); return -1; } @@ -207,18 +210,10 @@ x11_compositor_init_egl(struct x11_compositor *c) if (dri2_connect(c) < 0) return -1; - c->drm_fd = open(c->base.base.device, O_RDWR); - if (c->drm_fd == -1) { - fprintf(stderr, - "DRI2: could not open %s (%s)", c->base.base.device, - strerror(errno)); - return -1; - } - if (dri2_authenticate(c) < 0) return -1; - c->base.display = eglGetDRMDisplayMESA(c->drm_fd); + c->base.display = eglGetDRMDisplayMESA(c->base.drm.fd); if (c->base.display == NULL) { fprintf(stderr, "failed to create display\n"); return -1; @@ -641,6 +636,7 @@ x11_compositor_create(struct wl_display *display) x11_compositor_get_resources(c); + c->base.wl_display = display; x11_compositor_init_egl(c); /* Can't init base class until we have a current egl context */ diff --git a/compositor.c b/compositor.c index 6d7a627..8f50aef 100644 --- a/compositor.c +++ b/compositor.c @@ -30,13 +30,6 @@ #include #include -#define GL_GLEXT_PROTOTYPES -#define EGL_EGLEXT_PROTOTYPES -#include -#include -#include -#include - #include "wayland.h" #include "wayland-server-protocol.h" #include "cairo-util.h" @@ -180,14 +173,15 @@ wlsc_surface_create_from_cairo_surface(struct wlsc_compositor *ec, } static void -wlsc_surface_destroy(struct wlsc_surface *surface, - struct wlsc_compositor *compositor) +destroy_surface(struct wl_resource *resource, struct wl_client *client) { + struct wlsc_surface *surface = + container_of(resource, struct wlsc_surface, base.base); + struct wlsc_compositor *compositor = surface->compositor; struct wlsc_listener *l; wl_list_remove(&surface->link); glDeleteTextures(1, &surface->texture); - wl_client_remove_surface(surface->base.client, &surface->base); wl_list_for_each(l, &compositor->surface_destroy_listener_list, link) l->func(l, surface); @@ -427,73 +421,26 @@ surface_destroy(struct wl_client *client, struct wl_surface *surface) { struct wlsc_surface *es = (struct wlsc_surface *) surface; - struct wlsc_compositor *ec = es->compositor; - wlsc_surface_destroy(es, ec); + wl_resource_destroy(&surface->base, client); - wlsc_compositor_schedule_repaint(ec); + wlsc_compositor_schedule_repaint(es->compositor); } static void surface_attach(struct wl_client *client, - struct wl_surface *surface, uint32_t name, - int32_t width, int32_t height, uint32_t stride, - struct wl_visual *visual) + struct wl_surface *surface, struct wl_buffer *buffer_base) { struct wlsc_surface *es = (struct wlsc_surface *) surface; - struct wlsc_compositor *ec = es->compositor; - EGLImageKHR image; - EGLint attribs[] = { - EGL_WIDTH, 0, - EGL_HEIGHT, 0, - EGL_IMAGE_STRIDE_MESA, 0, - EGL_IMAGE_FORMAT_MESA, EGL_IMAGE_FORMAT_ARGB8888_MESA, - EGL_NONE - }; - - attribs[1] = width; - attribs[3] = height; - attribs[5] = stride / 4; - - image = eglCreateImageKHR(ec->display, ec->context, - EGL_DRM_IMAGE_MESA, - (EGLClientBuffer) name, attribs); - if (image == NULL) { - /* FIXME: Define a real exception event instead of - * abusing this one */ - wl_client_post_event(client, ec->wl_display, - WL_DISPLAY_INVALID_OBJECT, 0); - fprintf(stderr, "failed to create image for name %d\n", name); - return; - } - - if (visual == &ec->argb_visual) - es->visual = &ec->argb_visual; - else if (visual == &ec->premultiplied_argb_visual) - es->visual = &ec->premultiplied_argb_visual; - else if (visual == &ec->rgb_visual) - es->visual = &ec->rgb_visual; - else { - /* FIXME: Define a real exception event instead of - * abusing this one */ - wl_client_post_event(client, ec->display, - WL_DISPLAY_INVALID_OBJECT, 0); - fprintf(stderr, "invalid visual in surface_attach\n"); - return; - } + struct wlsc_buffer *buffer = (struct wlsc_buffer *) buffer_base; glBindTexture(GL_TEXTURE_2D, es->texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - if (es->image) - eglDestroyImageKHR(ec->display, es->image); - - es->image = image; - - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, es->image); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, buffer->image); + es->visual = buffer->visual; } static void @@ -577,13 +524,17 @@ compositor_create_surface(struct wl_client *client, struct wlsc_surface *surface; surface = malloc(sizeof *surface); - if (surface == NULL) - /* FIXME: Send OOM event. */ + if (surface == NULL) { + wl_client_post_event(client, + (struct wl_object *) ec->wl_display, + WL_DISPLAY_NO_MEMORY, 0); return; + } wlsc_surface_init(surface, ec, NULL, 0, 0, 0, 0); wl_list_insert(ec->surface_list.prev, &surface->link); + surface->base.base.destroy = destroy_surface; wl_client_add_surface(client, &surface->base, &surface_interface, id); } @@ -921,6 +872,7 @@ wlsc_input_device_init(struct wlsc_input_device *device, device->base.implementation = NULL; wl_display_add_object(ec->wl_display, &device->base); wl_display_add_global(ec->wl_display, &device->base, NULL); + device->x = 100; device->y = 100; device->ec = ec; diff --git a/compositor.h b/compositor.h index f1ffbd9..fe9779e 100644 --- a/compositor.h +++ b/compositor.h @@ -26,6 +26,10 @@ #include "wayland.h" #include "wayland-util.h" +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES +#include +#include #include #include @@ -93,10 +97,23 @@ struct wlsc_input_device { struct wlsc_listener listener; }; +struct wlsc_drm { + struct wl_object base; + int fd; + char *filename; +}; + +struct wlsc_buffer { + struct wl_buffer base; + EGLImageKHR image; + struct wl_visual *visual; +}; + struct wlsc_compositor { struct wl_compositor base; struct wl_visual argb_visual, premultiplied_argb_visual, rgb_visual; + struct wlsc_drm drm; EGLDisplay display; EGLContext context; GLuint fbo, vbo; @@ -124,6 +141,7 @@ struct wlsc_compositor { uint32_t focus; + void (*authenticate)(struct wlsc_compositor *c, uint32_t id); void (*present)(struct wlsc_compositor *c); }; @@ -138,13 +156,12 @@ struct wlsc_vector { struct wlsc_surface { struct wl_surface base; struct wlsc_compositor *compositor; - struct wl_visual *visual; GLuint texture; - EGLImageKHR image; int32_t x, y, width, height; struct wl_list link; struct wlsc_matrix matrix; struct wlsc_matrix matrix_inv; + struct wl_visual *visual; }; void @@ -170,6 +187,8 @@ wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c, void wlsc_input_device_init(struct wlsc_input_device *device, struct wlsc_compositor *ec); +int +wlsc_drm_init(struct wlsc_compositor *ec, int fd, const char *filename); struct wlsc_compositor * x11_compositor_create(struct wl_display *display); diff --git a/protocol.xml b/protocol.xml index 50a3480..63927be 100644 --- a/protocol.xml +++ b/protocol.xml @@ -32,10 +32,6 @@ - - - - @@ -47,6 +43,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -78,11 +100,7 @@ - - - - - + diff --git a/wayland-client.c b/wayland-client.c index b55511e..8fcc809 100644 --- a/wayland-client.c +++ b/wayland-client.c @@ -87,6 +87,14 @@ struct wl_shell { struct wl_proxy proxy; }; +struct wl_drm { + struct wl_proxy proxy; +}; + +struct wl_buffer { + struct wl_proxy proxy; +}; + struct wl_input_device { struct wl_proxy proxy; }; @@ -258,6 +266,49 @@ wl_shell_resize(struct wl_shell *shell, WL_SHELL_RESIZE, surface, device, time, edges); } +WL_EXPORT int +wl_drm_add_listener(struct wl_drm *drm, + const struct wl_drm_listener *listener, + void *data) +{ + return wl_proxy_add_listener(&drm->proxy, + (void (**)(void)) listener, data); +} + +WL_EXPORT void +wl_drm_authenticate(struct wl_drm *drm, uint32_t id) +{ + wl_proxy_marshal(&drm->proxy, WL_DRM_AUTHENTICATE, id); +} + +WL_EXPORT struct wl_buffer * +wl_drm_create_buffer(struct wl_drm *drm, uint32_t name, + int32_t width, int32_t height, + uint32_t stride, struct wl_visual *visual) +{ + struct wl_buffer *buffer; + + buffer = malloc(sizeof *buffer); + if (buffer == NULL) + return NULL; + + buffer->proxy.base.interface = &wl_buffer_interface; + buffer->proxy.base.id = wl_display_allocate_id(drm->proxy.display); + buffer->proxy.display = drm->proxy.display; + wl_hash_table_insert(drm->proxy.display->objects, + drm->proxy.base.id, buffer); + wl_proxy_marshal(&drm->proxy, WL_DRM_CREATE_BUFFER, + buffer, name, width, height, stride, visual); + + return buffer; +} + +WL_EXPORT void +wl_buffer_destroy(struct wl_buffer *buffer) +{ + wl_proxy_marshal(&buffer->proxy, WL_BUFFER_DESTROY); +} + static void add_visual(struct wl_display *display, struct wl_global *global) { @@ -360,6 +411,9 @@ display_handle_global(void *data, else if (strcmp(global->interface, "shell") == 0) wl_proxy_create_for_global(display, global, &wl_shell_interface); + else if (strcmp(global->interface, "drm") == 0) + wl_proxy_create_for_global(display, global, + &wl_drm_interface); } static void @@ -589,12 +643,9 @@ wl_surface_destroy(struct wl_surface *surface) } WL_EXPORT void -wl_surface_attach(struct wl_surface *surface, uint32_t name, - int32_t width, int32_t height, uint32_t stride, - struct wl_visual *visual) +wl_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer) { - wl_proxy_marshal(&surface->proxy, WL_SURFACE_ATTACH, - name, width, height, stride, visual); + wl_proxy_marshal(&surface->proxy, WL_SURFACE_ATTACH, buffer); } WL_EXPORT void diff --git a/wayland-client.h b/wayland-client.h index 4f94a8b..572adc0 100644 --- a/wayland-client.h +++ b/wayland-client.h @@ -88,10 +88,20 @@ wl_shell_resize(struct wl_shell *shell, struct wl_surface *surface, struct wl_input_device *device, uint32_t time, uint32_t edges); +int +wl_drm_add_listener(struct wl_drm *drm, + const struct wl_drm_listener *listener, + void *data); +void +wl_drm_authenticate(struct wl_drm *drm, uint32_t id); +struct wl_buffer * +wl_drm_create_buffer(struct wl_drm *drm, uint32_t name, + int32_t width, int32_t height, + uint32_t stride, struct wl_visual *visual); +void wl_buffer_destroy(struct wl_buffer *buffer); + void wl_surface_destroy(struct wl_surface *surface); -void wl_surface_attach(struct wl_surface *surface, uint32_t name, - int32_t width, int32_t height, uint32_t stride, - struct wl_visual *visual); +void wl_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer); void wl_surface_map(struct wl_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height); void wl_surface_damage(struct wl_surface *surface, diff --git a/wayland-util.h b/wayland-util.h index 6ccc56a..575e657 100644 --- a/wayland-util.h +++ b/wayland-util.h @@ -98,6 +98,13 @@ int wl_list_empty(struct wl_list *list); &pos->member != (head); \ pos = __container_of(pos->member.next, pos, member)) +#define wl_list_for_each_safe(pos, tmp, head, member) \ + for (pos = __container_of((head)->next, pos, member), \ + tmp = __container_of((pos)->member.next, tmp, member); \ + &pos->member != (head); \ + pos = tmp, \ + tmp = __container_of(pos->member.next, tmp, member)) + #define wl_list_for_each_reverse(pos, head, member) \ for (pos = __container_of((head)->prev, pos, member); \ &pos->member != (head); \ diff --git a/wayland.c b/wayland.c index ee7150c..78059d4 100644 --- a/wayland.c +++ b/wayland.c @@ -42,7 +42,7 @@ struct wl_client { struct wl_connection *connection; struct wl_event_source *source; struct wl_display *display; - struct wl_list surface_list; + struct wl_list resource_list; struct wl_list link; uint32_t id_count; }; @@ -186,7 +186,7 @@ wl_client_create(struct wl_display *display, int fd) client->connection = wl_connection_create(fd, wl_client_connection_update, client); - wl_list_init(&client->surface_list); + wl_list_init(&client->resource_list); wl_list_init(&client->link); wl_display_post_range(display, client); @@ -205,30 +205,42 @@ wl_client_create(struct wl_display *display, int fd) return client; } -static void -wl_object_destroy(struct wl_object *object) +WL_EXPORT void +wl_client_add_resource(struct wl_client *client, + struct wl_resource *resource) +{ + struct wl_display *display = client->display; + + if (client->id_count-- < 64) + wl_display_post_range(display, client); + + wl_hash_table_insert(client->display->objects, + resource->base.id, resource); + wl_list_insert(client->resource_list.prev, &resource->link); +} + +WL_EXPORT void +wl_resource_destroy(struct wl_resource *resource, struct wl_client *client) { - const struct wl_surface_interface *interface = - (const struct wl_surface_interface *) object->implementation; + struct wl_display *display = client->display; - /* FIXME: Need generic object destructor. */ - interface->destroy(NULL, (struct wl_surface *) object); + wl_list_remove(&resource->link); + wl_hash_table_remove(display->objects, resource->base.id); + resource->destroy(resource, client); } WL_EXPORT void wl_client_destroy(struct wl_client *client) { - struct wl_surface *surface; + struct wl_resource *resource, *tmp; printf("disconnect from client %p\n", client); wl_list_remove(&client->link); - while (client->surface_list.next != &client->surface_list) { - surface = container_of(client->surface_list.next, - struct wl_surface, link); - wl_list_remove(&surface->link); - wl_object_destroy(&surface->base); + wl_list_for_each_safe(resource, tmp, &client->resource_list, link) { + wl_list_remove(&resource->link); + resource->destroy(resource, client); } wl_event_source_remove(client->source); @@ -242,33 +254,17 @@ wl_client_add_surface(struct wl_client *client, const struct wl_surface_interface *implementation, uint32_t id) { - struct wl_display *display = client->display; - - if (client->id_count-- < 64) - wl_display_post_range(display, client); - - surface->base.id = id; - surface->base.interface = &wl_surface_interface; - surface->base.implementation = (void (**)(void)) implementation; + surface->base.base.id = id; + surface->base.base.interface = &wl_surface_interface; + surface->base.base.implementation = (void (**)(void)) implementation; surface->client = client; - wl_hash_table_insert(display->objects, id, surface); - wl_list_insert(client->surface_list.prev, &surface->link); + wl_client_add_resource(client, &surface->base); return 0; } WL_EXPORT void -wl_client_remove_surface(struct wl_client *client, - struct wl_surface *surface) -{ - struct wl_display *display = client->display; - - wl_hash_table_remove(display->objects, surface->base.id); - wl_list_remove(&surface->link); -} - -WL_EXPORT void wl_client_send_acknowledge(struct wl_client *client, struct wl_compositor *compositor, uint32_t key, uint32_t frame) @@ -280,16 +276,6 @@ wl_client_send_acknowledge(struct wl_client *client, WL_COMPOSITOR_ACKNOWLEDGE, key, frame); } -static void -post_compositor_device(struct wl_client *client, struct wl_object *global) -{ - struct wl_compositor *compositor = - container_of(global, struct wl_compositor, base); - - wl_client_post_event(client, global, - WL_COMPOSITOR_DEVICE, compositor->device); -} - WL_EXPORT int wl_display_set_compositor(struct wl_display *display, struct wl_compositor *compositor, @@ -299,7 +285,7 @@ wl_display_set_compositor(struct wl_display *display, compositor->base.implementation = (void (**)(void)) implementation; wl_display_add_object(display, &compositor->base); - if (wl_display_add_global(display, &compositor->base, post_compositor_device)) + if (wl_display_add_global(display, &compositor->base, NULL)) return -1; return 0; diff --git a/wayland.h b/wayland.h index 96df34f..71869cd 100644 --- a/wayland.h +++ b/wayland.h @@ -70,14 +70,9 @@ struct wl_event_source *wl_event_loop_add_idle(struct wl_event_loop *loop, void *data); struct wl_client; - struct wl_display; struct wl_input_device; -struct wl_map { - int32_t x, y, width, height; -}; - struct wl_display *wl_display_create(void); struct wl_event_loop *wl_display_get_event_loop(struct wl_display *display); int wl_display_add_socket(struct wl_display *display, const char *name, size_t name_size); @@ -93,15 +88,24 @@ void wl_client_destroy(struct wl_client *client); struct wl_compositor { struct wl_object base; - const char *device; }; -struct wl_surface { +struct wl_resource { struct wl_object base; - struct wl_client *client; + void (*destroy)(struct wl_resource *resource, + struct wl_client *client); struct wl_list link; }; +struct wl_buffer { + struct wl_resource base; +}; + +struct wl_surface { + struct wl_resource base; + struct wl_client *client; +}; + void wl_client_post_event(struct wl_client *client, struct wl_object *sender, @@ -124,10 +128,6 @@ wl_client_add_surface(struct wl_client *client, uint32_t id); void -wl_client_remove_surface(struct wl_client *client, - struct wl_surface *surface); - -void wl_client_send_acknowledge(struct wl_client *client, struct wl_compositor *compositor, uint32_t key, uint32_t frame); @@ -137,6 +137,13 @@ wl_display_post_frame(struct wl_display *display, struct wl_compositor *compositor, uint32_t frame, uint32_t msecs); +void +wl_client_add_resource(struct wl_client *client, + struct wl_resource *resource); + +void +wl_resource_destroy(struct wl_resource *resource, struct wl_client *client); + #ifdef __cplusplus } #endif