compositor: make surface_configure() a vfunc
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Tue, 27 Mar 2012 14:36:41 +0000 (17:36 +0300)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 27 Mar 2012 20:36:53 +0000 (16:36 -0400)
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
src/compositor.h
src/shell.c

index 2bf375c..b02d788 100644 (file)
@@ -1151,30 +1151,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,
               struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
@@ -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
index d76e99d..65aa48f 100644 (file)
@@ -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;
 };
 
index e6935ce..5c4a5cd 100644 (file)
@@ -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);
@@ -811,6 +813,9 @@ get_shell_surface(struct weston_surface *surface)
 }
 
 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,
                        uint32_t id,
@@ -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