From 093bfa3793f06eec992e0b6407c5b1dea604471c Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 27 Mar 2012 17:36:41 +0300 Subject: [PATCH] compositor: make surface_configure() a vfunc This allows us to move the logic that calls shell->map() or shell->configure() into shell while allowing it to be overriden for surfaces that should not be handle by the shell, such as drag icons. This patch adds a pointer function called configure to weston_surface, moves the currsent surface_configure() code into shell and implements a separate configure() for drag surfaces. --- src/compositor.c | 51 +++++++++++++++++++++++------------------------- src/compositor.h | 6 ++++++ src/shell.c | 39 +++++++++++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 2bf375c9..b02d7885 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1150,30 +1150,6 @@ weston_surface_assign_output(struct weston_surface *es) } } -static void -surface_configure(struct weston_surface *es, int32_t sx, int32_t sy) -{ - struct weston_shell *shell = es->compositor->shell; - - if (!weston_surface_is_mapped(es)) { - shell->map(shell, es, es->buffer->width, es->buffer->height, - sx, sy); - } else if (es->force_configure || sx != 0 || sy != 0 || - es->geometry.width != es->buffer->width || - es->geometry.height != es->buffer->height) { - GLfloat from_x, from_y; - GLfloat to_x, to_y; - - surface_to_global_float(es, 0, 0, &from_x, &from_y); - surface_to_global_float(es, sx, sy, &to_x, &to_y); - shell->configure(shell, es, - es->geometry.x + to_x - from_x, - es->geometry.y + to_y - from_y, - es->buffer->width, es->buffer->height); - es->force_configure = 0; - } -} - static void surface_attach(struct wl_client *client, struct wl_resource *resource, @@ -1187,8 +1163,8 @@ surface_attach(struct wl_client *client, weston_buffer_attach(buffer, &es->surface); - if (buffer) - surface_configure(es, sx, sy); + if (buffer && es->configure) + es->configure(es, sx, sy); } static void @@ -2013,23 +1989,43 @@ weston_input_device_release(struct weston_input_device *device) } static void +drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy) +{ + weston_surface_configure(es, + es->geometry.x + sx, es->geometry.y + sy, + es->buffer->width, es->buffer->height); +} + +static int device_setup_new_drag_surface(struct weston_input_device *device, struct weston_surface *surface) { struct wl_input_device *input_device = &device->input_device; + if (surface->configure) { + wl_resource_post_error(&surface->surface.resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "surface->configure already set"); + return 0; + } + device->drag_surface = surface; weston_surface_set_position(device->drag_surface, input_device->x, input_device->y); + surface->configure = drag_surface_configure; + wl_list_insert(surface->surface.resource.destroy_listener_list.prev, &device->drag_surface_destroy_listener.link); + + return 1; } static void device_release_drag_surface(struct weston_input_device *device) { + device->drag_surface->configure = NULL; undef_region(&device->drag_surface->input); wl_list_remove(&device->drag_surface_destroy_listener.link); device->drag_surface = NULL; @@ -2074,7 +2070,8 @@ weston_input_update_drag_surface(struct wl_input_device *input_device, if (!device->drag_surface || surface_changed) { struct weston_surface *surface = (struct weston_surface *) input_device->drag_surface; - device_setup_new_drag_surface(device, surface); + if (!device_setup_new_drag_surface(device, surface)) + return; } /* the client may not have attached a buffer to the drag surface diff --git a/src/compositor.h b/src/compositor.h index d76e99de..65aa48f8 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -335,6 +335,12 @@ struct weston_surface { struct wl_buffer *buffer; struct wl_listener buffer_destroy_listener; + /* + * If non-NULL, this function will be called on surface::attach after + * a new buffer has been set up for this surface. The integer params + * are the sx and sy paramerters supplied to surface::attach . + */ + void (*configure)(struct weston_surface *es, int32_t sx, int32_t sy); int force_configure; }; diff --git a/src/shell.c b/src/shell.c index e6935ce5..5c4a5cde 100644 --- a/src/shell.c +++ b/src/shell.c @@ -771,8 +771,10 @@ destroy_shell_surface(struct wl_resource *resource) wl_input_device_end_pointer_grab(shsurf->popup.grab.input_device, 0); /* in case cleaning up a dead client destroys shell_surface first */ - if (shsurf->surface) + if (shsurf->surface) { wl_list_remove(&shsurf->surface_destroy_listener.link); + shsurf->surface->configure = NULL; + } if (shsurf->fullscreen.black_surface) weston_surface_destroy(shsurf->fullscreen.black_surface); @@ -810,6 +812,9 @@ get_shell_surface(struct weston_surface *surface) return NULL; } +static void +shell_surface_configure(struct weston_surface *, int32_t, int32_t); + static void shell_get_shell_surface(struct wl_client *client, struct wl_resource *resource, @@ -826,12 +831,21 @@ shell_get_shell_surface(struct wl_client *client, return; } + if (surface->configure) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "surface->configure already set"); + return; + } + shsurf = calloc(1, sizeof *shsurf); if (!shsurf) { wl_resource_post_no_memory(resource); return; } + surface->configure = shell_surface_configure; + shsurf->resource.destroy = destroy_shell_surface; shsurf->resource.object.id = id; shsurf->resource.object.interface = &wl_shell_surface_interface; @@ -1705,6 +1719,29 @@ configure(struct weston_shell *base, struct weston_surface *surface, } } +static void +shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy) +{ + struct weston_shell *shell = es->compositor->shell; + + if (!weston_surface_is_mapped(es)) { + map(shell, es, es->buffer->width, es->buffer->height, sx, sy); + } else if (es->force_configure || sx != 0 || sy != 0 || + es->geometry.width != es->buffer->width || + es->geometry.height != es->buffer->height) { + GLfloat from_x, from_y; + GLfloat to_x, to_y; + + weston_surface_to_global_float(es, 0, 0, &from_x, &from_y); + weston_surface_to_global_float(es, sx, sy, &to_x, &to_y); + configure(shell, es, + es->geometry.x + to_x - from_x, + es->geometry.y + to_y - from_y, + es->buffer->width, es->buffer->height); + es->force_configure = 0; + } +} + static int launch_desktop_shell_process(struct wl_shell *shell); static void