Update surface.attach and change surface.map to surface.map_toplevel
authorKristian Høgsberg <krh@bitplanet.net>
Fri, 17 Dec 2010 14:53:12 +0000 (09:53 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 17 Dec 2010 14:53:12 +0000 (09:53 -0500)
The new map_toplevel() request no longer specifies a position and takes
the size from the attached buffer.  The attach request now takes a
position relative to the top-left corner of the old buffer to let
clients specify the relative position of the new buffer.

13 files changed:
clients/dnd.c
clients/flower.c
clients/gears.c
clients/image.c
clients/resizor.c
clients/smoke.c
clients/terminal.c
clients/view.c
clients/window.c
clients/window.h
compositor/compositor-wayland.c
compositor/compositor.c
protocol/wayland.xml

index e6dd091..b7f9f39 100644 (file)
@@ -633,7 +633,7 @@ dnd_create(struct display *display)
 
        title = g_strdup_printf("Wayland Drag and Drop Demo");
 
-       dnd->window = window_create(display, title, 100, 100, 500, 400);
+       dnd->window = window_create(display, title, 500, 400);
        dnd->display = display;
        dnd->key = 100;
 
index b919cf5..de7c1d4 100644 (file)
@@ -30,6 +30,7 @@
 #include <math.h>
 #include <time.h>
 #include <cairo.h>
+#include <sys/time.h>
 #include <glib.h>
 
 #include "wayland-client.h"
@@ -97,31 +98,36 @@ draw_stuff(cairo_surface_t *surface, int width, int height)
        cairo_destroy(cr);
 }
 
-struct flower {
-       struct display *display;
-       struct window *window;
-       int x, y, width, height;
-       int offset;
-};
+static int
+motion_handler(struct window *window,
+              struct input *input, uint32_t time,
+              int32_t x, int32_t y,
+              int32_t sx, int32_t sy, void *data)
+{
+       return POINTER_HAND1;
+}
 
 static void
-frame_callback(void *data, uint32_t time)
+button_handler(struct window *window,
+              struct input *input, uint32_t time,
+              int button, int state, void *data)
 {
-       struct flower *flower = data;
-
-       window_move(flower->window, 
-                   flower->x + cos((flower->offset + time) / 400.0) * 400 - flower->width / 2,
-                   flower->y + sin((flower->offset + time) / 320.0) * 300 - flower->height / 2);
-       wl_display_frame_callback(display_get_display(flower->display),
-                                 frame_callback, flower);
+       if (state)
+               window_move(window, input, time);
 }
 
+struct flower {
+       struct display *display;
+       struct window *window;
+       int width, height;
+};
+
 int main(int argc, char *argv[])
 {
        cairo_surface_t *s;
-       struct timespec ts;
        struct flower flower;
        struct display *d;
+       struct timeval tv;
 
        d = display_create(&argc, &argv, NULL);
        if (d == NULL) {
@@ -129,18 +135,15 @@ int main(int argc, char *argv[])
                return -1;
        }
 
-       flower.x = 512;
-       flower.y = 384;
+       gettimeofday(&tv, NULL);
+       srandom(tv.tv_usec);
+
        flower.width = 200;
        flower.height = 200;
        flower.display = d;
-       flower.window = window_create(d, "flower", flower.x, flower.y,
+       flower.window = window_create(d, "flower",
                                      flower.width, flower.height);
 
-       clock_gettime(CLOCK_MONOTONIC, &ts);
-       srandom(ts.tv_nsec);
-       flower.offset = random();
-
        window_set_decoration(flower.window, 0);
        window_draw(flower.window);
        s = window_get_surface(flower.window);
@@ -154,10 +157,9 @@ int main(int argc, char *argv[])
        cairo_surface_destroy(s);
        window_flush(flower.window);
 
+       window_set_motion_handler(flower.window, motion_handler);
+       window_set_button_handler(flower.window, button_handler);
        window_set_user_data(flower.window, &flower);
-       wl_display_frame_callback(display_get_display(d),
-                                 frame_callback, &flower);
-
        display_run(d);
 
        return 0;
index 7d3c310..2f2eeda 100644 (file)
@@ -340,15 +340,14 @@ frame_callback(void *data, uint32_t time)
 static struct gears *
 gears_create(struct display *display)
 {
-       const int x = 200, y = 200, width = 450, height = 500;
+       const int width = 450, height = 500;
        struct gears *gears;
        int i;
 
        gears = malloc(sizeof *gears);
        memset(gears, 0, sizeof *gears);
        gears->d = display;
-       gears->window = window_create(display, "Wayland Gears",
-                                     x, y, width, height);
+       gears->window = window_create(display, "Wayland Gears", width, height);
 
        gears->display = display_get_egl_display(gears->d);
        if (gears->display == NULL)
index bb563ed..f9bbeb2 100644 (file)
@@ -213,7 +213,7 @@ image_create(struct display *display, uint32_t key, const char *filename)
 
        image->filename = g_strdup(filename);
 
-       image->window = window_create(display, title, 100 * key, 100 * key, 500, 400);
+       image->window = window_create(display, title, 500, 400);
        image->display = display;
 
        /* FIXME: Window uses key 1 for moves, need some kind of
index d5baf17..f308983 100644 (file)
@@ -162,8 +162,7 @@ resizor_create(struct display *display)
                return resizor;
        memset(resizor, 0, sizeof *resizor);
 
-       resizor->window = window_create(display, "Wayland Resizor",
-                                    100, 100, 500, 400);
+       resizor->window = window_create(display, "Wayland Resizor", 500, 400);
        resizor->display = display;
 
        window_set_key_handler(resizor->window, key_handler);
index 43226ad..7052cb4 100644 (file)
@@ -277,8 +277,7 @@ int main(int argc, char *argv[])
        smoke.width = 200;
        smoke.height = 200;
        smoke.display = d;
-       smoke.window = window_create(d, "smoke", smoke.x, smoke.y,
-                                     smoke.width, smoke.height);
+       smoke.window = window_create(d, "smoke", smoke.width, smoke.height);
 
        window_set_buffer_type(smoke.window, WINDOW_BUFFER_TYPE_SHM);
        clock_gettime(CLOCK_MONOTONIC, &ts);
index 2f12f8a..ecbf0a4 100644 (file)
@@ -464,7 +464,7 @@ terminal_create(struct display *display, int fullscreen)
        terminal->fullscreen = fullscreen;
        terminal->color_scheme = &jbarnes_colors;
        terminal->window = window_create(display, "Wayland Terminal",
-                                        500, 100, 500, 400);
+                                        500, 400);
        terminal->display = display;
        terminal->margin = 5;
 
index 67149fb..b085c67 100644 (file)
@@ -171,8 +171,7 @@ view_create(struct display *display, uint32_t key, const char *filename)
 
        view->filename = g_strdup(filename);
 
-       view->window = window_create(display, title,
-                                    100 * key, 100 * key, 500, 400);
+       view->window = window_create(display, title, 500, 400);
        view->display = display;
 
        /* FIXME: Window uses key 1 for moves, need some kind of
index 1bbc1b8..22cbd28 100644 (file)
@@ -86,7 +86,7 @@ struct window {
        struct display *display;
        struct wl_surface *surface;
        const char *title;
-       struct rectangle allocation, saved_allocation, pending_allocation;
+       struct rectangle allocation, saved_allocation, server_allocation;
        int resize_edges;
        int redraw_scheduled;
        int minimum_width, minimum_height;
@@ -97,6 +97,7 @@ struct window {
        struct input *keyboard_device;
        uint32_t name;
        enum window_buffer_type buffer_type;
+       int mapped;
 
        EGLImageKHR *image;
        cairo_surface_t *cairo_surface, *pending_surface;
@@ -128,6 +129,22 @@ enum {
        POINTER_UNSET
 };
 
+enum window_location {
+       WINDOW_INTERIOR = 0,
+       WINDOW_RESIZING_TOP = 1,
+       WINDOW_RESIZING_BOTTOM = 2,
+       WINDOW_RESIZING_LEFT = 4,
+       WINDOW_RESIZING_TOP_LEFT = 5,
+       WINDOW_RESIZING_BOTTOM_LEFT = 6,
+       WINDOW_RESIZING_RIGHT = 8,
+       WINDOW_RESIZING_TOP_RIGHT = 9,
+       WINDOW_RESIZING_BOTTOM_RIGHT = 10,
+       WINDOW_RESIZING_MASK = 15,
+       WINDOW_EXTERIOR = 16,
+       WINDOW_TITLEBAR = 17,
+       WINDOW_CLIENT_AREA = 18,
+};
+
 const char *option_xkb_layout = "us";
 const char *option_xkb_variant = "";
 const char *option_xkb_options = "";
@@ -547,6 +564,7 @@ window_attach_surface(struct window *window)
 {
        struct display *display = window->display;
        struct wl_buffer *buffer;
+       int32_t x, y;
 
        if (window->pending_surface != NULL)
                return;
@@ -556,15 +574,31 @@ window_attach_surface(struct window *window)
 
        buffer = display_get_buffer_for_surface(display,
                                                window->pending_surface);
-       wl_surface_attach(window->surface, buffer);
+       if (window->resize_edges & WINDOW_RESIZING_LEFT)
+               x = window->server_allocation.width -
+                       window->allocation.width;
+       else
+               x = 0;
 
-       wl_surface_map(window->surface,
-                      window->allocation.x,
-                      window->allocation.y,
-                      window->allocation.width,
-                      window->allocation.height);
+       if (window->resize_edges & WINDOW_RESIZING_TOP)
+               y = window->server_allocation.height -
+                       window->allocation.height;
+       else
+               y = 0;
 
+       window->server_allocation = window->allocation;
+       window->resize_edges = 0;
+       wl_surface_attach(window->surface, buffer, x, y);
        wl_display_sync_callback(display->display, free_surface, window);
+
+       if (!window->mapped) {
+               wl_surface_map_toplevel(window->surface);
+               window->mapped = 1;
+       }
+
+       wl_surface_damage(window->surface, 0, 0,
+                         window->allocation.width,
+                         window->allocation.height);
 }
 
 void
@@ -687,28 +721,15 @@ window_get_surface(struct window *window)
        return cairo_surface_reference(window->cairo_surface);
 }
 
-enum window_location {
-       WINDOW_INTERIOR = 0,
-       WINDOW_RESIZING_TOP = 1,
-       WINDOW_RESIZING_BOTTOM = 2,
-       WINDOW_RESIZING_LEFT = 4,
-       WINDOW_RESIZING_TOP_LEFT = 5,
-       WINDOW_RESIZING_BOTTOM_LEFT = 6,
-       WINDOW_RESIZING_RIGHT = 8,
-       WINDOW_RESIZING_TOP_RIGHT = 9,
-       WINDOW_RESIZING_BOTTOM_RIGHT = 10,
-       WINDOW_RESIZING_MASK = 15,
-       WINDOW_EXTERIOR = 16,
-       WINDOW_TITLEBAR = 17,
-       WINDOW_CLIENT_AREA = 18,
-};
-
 static int
 get_pointer_location(struct window *window, int32_t x, int32_t y)
 {
        int vlocation, hlocation, location;
        const int grip_size = 8;
 
+       if (!window->decoration)
+               return WINDOW_CLIENT_AREA;
+
        if (x < window->margin)
                hlocation = WINDOW_EXTERIOR;
        else if (window->margin <= x && x < window->margin + grip_size)
@@ -997,6 +1018,13 @@ window_create_drag(struct window *window)
 }
 
 void
+window_move(struct window *window, struct input *input, uint32_t time)
+{
+       wl_shell_move(window->display->shell,
+                     window->surface, input->input_device, time);
+}
+
+void
 window_activate_drag(struct wl_drag *drag, struct window *window,
                     struct input *input, uint32_t time)
 {
@@ -1006,27 +1034,18 @@ window_activate_drag(struct wl_drag *drag, struct window *window,
 static void
 handle_configure(void *data, struct wl_shell *shell,
                 uint32_t time, uint32_t edges,
-                struct wl_surface *surface,
-                int32_t x, int32_t y, int32_t width, int32_t height)
+                struct wl_surface *surface, int32_t width, int32_t height)
 {
        struct window *window = wl_surface_get_user_data(surface);
 
        window->resize_edges = edges;
-       window->pending_allocation.x = x;
-       window->pending_allocation.y = y;
-       window->pending_allocation.width = width;
-       window->pending_allocation.height = height;
-
-       if (edges & WINDOW_TITLEBAR) {
-               window->allocation.x = window->pending_allocation.x;
-               window->allocation.y = window->pending_allocation.y;
-       } else if (edges & WINDOW_RESIZING_MASK) {
-               if (window->resize_handler)
-                       (*window->resize_handler)(window,
-                                                 window->user_data);
-               else if (window->redraw_handler)
-                       window_schedule_redraw(window);
-       }
+       window->allocation.width = width;
+       window->allocation.height = height;
+
+       if (window->resize_handler)
+               (*window->resize_handler)(window, window->user_data);
+       if (window->redraw_handler)
+               window_schedule_redraw(window);
 }
 
 static const struct wl_shell_listener shell_listener = {
@@ -1051,21 +1070,11 @@ void
 window_set_child_size(struct window *window,
                      struct rectangle *rectangle)
 {
-       int32_t width, height;
-
        if (!window->fullscreen) {
-               width = rectangle->width + 20 + window->margin * 2;
-               height = rectangle->height + 60 + window->margin * 2;
-
-               if (window->resize_edges & WINDOW_RESIZING_LEFT)
-                       window->allocation.x +=
-                               window->allocation.width - width;
-               if (window->resize_edges & WINDOW_RESIZING_TOP)
-                       window->allocation.y +=
-                               window->allocation.height - height;
-
-               window->allocation.width = width;
-               window->allocation.height = height;
+               window->allocation.width =
+                       rectangle->width + 20 + window->margin * 2;
+               window->allocation.height =
+                       rectangle->height + 60 + window->margin * 2;
        }
 }
 
@@ -1098,13 +1107,9 @@ idle_redraw(void *data)
 {
        struct window *window = data;
 
-       if (window->resize_edges)
-               window->allocation = window->pending_allocation;
-
        window->redraw_handler(window, window->user_data);
 
        window->redraw_scheduled = 0;
-       window->resize_edges = 0;
 
        return FALSE;
 }
@@ -1191,19 +1196,6 @@ window_set_keyboard_focus_handler(struct window *window,
 }
 
 void
-window_move(struct window *window, int32_t x, int32_t y)
-{
-       window->allocation.x = x;
-       window->allocation.y = y;
-
-       wl_surface_map(window->surface,
-                      window->allocation.x - window->margin,
-                      window->allocation.y - window->margin,
-                      window->allocation.width,
-                      window->allocation.height);
-}
-
-void
 window_damage(struct window *window, int32_t x, int32_t y,
              int32_t width, int32_t height)
 {
@@ -1212,7 +1204,7 @@ window_damage(struct window *window, int32_t x, int32_t y,
 
 struct window *
 window_create(struct display *display, const char *title,
-             int32_t x, int32_t y, int32_t width, int32_t height)
+             int32_t width, int32_t height)
 {
        struct window *window;
 
@@ -1224,8 +1216,8 @@ window_create(struct display *display, const char *title,
        window->display = display;
        window->title = strdup(title);
        window->surface = wl_compositor_create_surface(display->compositor);
-       window->allocation.x = x;
-       window->allocation.y = y;
+       window->allocation.x = 0;
+       window->allocation.y = 0;
        window->allocation.width = width;
        window->allocation.height = height;
        window->saved_allocation = window->allocation;
index 74e95b6..341f602 100644 (file)
@@ -125,7 +125,10 @@ typedef void (*display_drag_offer_handler_t)(struct wl_drag_offer *offer,
 
 struct window *
 window_create(struct display *display, const char *title,
-             int32_t x, int32_t y, int32_t width, int32_t height);
+             int32_t width, int32_t height);
+
+void
+window_move(struct window *window, struct input *input, uint32_t time);
 
 void
 window_draw(struct window *window);
@@ -143,9 +146,6 @@ void
 window_schedule_redraw(struct window *window);
 
 void
-window_move(struct window *window, int32_t x, int32_t y);
-
-void
 window_damage(struct window *window, int32_t x, int32_t y,
              int32_t width, int32_t height);
 
index 40dee58..b216ebd 100644 (file)
@@ -193,7 +193,8 @@ wayland_compositor_present(struct wlsc_compositor *base)
                                          output->rbo[output->current]);
 
                wl_surface_attach(output->parent.surface,
-                                 output->parent.buffer[output->current ^ 1]);
+                                 output->parent.buffer[output->current ^ 1],
+                                 0, 0);
                wl_surface_damage(output->parent.surface, 0, 0,
                                  output->base.width, output->base.height);
        }
@@ -264,10 +265,8 @@ wayland_compositor_create_output(struct wayland_compositor *c,
                                  output->rbo[output->current]);
 
        wl_surface_attach(output->parent.surface,
-                         output->parent.buffer[output->current]);
-       wl_surface_map(output->parent.surface,
-                      output->base.x, output->base.y,
-                      output->base.width, output->base.height);
+                         output->parent.buffer[output->current], 0, 0);
+       wl_surface_map_toplevel(output->parent.surface);
 
        glClearColor(0, 0, 0, 0.5);
 
index 0e1323f..d9b81d8 100644 (file)
@@ -419,27 +419,31 @@ surface_destroy(struct wl_client *client,
 
 static void
 surface_attach(struct wl_client *client,
-              struct wl_surface *surface, struct wl_buffer *buffer)
+              struct wl_surface *surface, struct wl_buffer *buffer,
+              int32_t x, int32_t y)
 {
        struct wlsc_surface *es = (struct wlsc_surface *) surface;
 
        buffer->attach(buffer, surface);
        es->buffer = buffer;
+       es->x += x;
+       es->y += y;
+       es->width = buffer->width;
+       es->height = buffer->height;
+       wlsc_surface_update_matrix(es);
 }
 
 static void
-surface_map(struct wl_client *client,
-           struct wl_surface *surface,
-           int32_t x, int32_t y, int32_t width, int32_t height)
+surface_map_toplevel(struct wl_client *client,
+                    struct wl_surface *surface)
 {
        struct wlsc_surface *es = (struct wlsc_surface *) surface;
 
-       es->x = x;
-       es->y = y;
-       es->width = width;
-       es->height = height;
+       es->x = 10 + random() % 400;
+       es->y = 10 + random() % 400;
 
        wlsc_surface_update_matrix(es);
+       wl_list_insert(es->compositor->surface_list.prev, &es->link);
        wlsc_compositor_schedule_repaint(es->compositor);
 }
 
@@ -457,7 +461,7 @@ surface_damage(struct wl_client *client,
 const static struct wl_surface_interface surface_interface = {
        surface_destroy,
        surface_attach,
-       surface_map,
+       surface_map_toplevel,
        surface_damage
 };
 
@@ -557,17 +561,9 @@ move_grab_motion(struct wl_grab *grab,
        struct wlsc_move_grab *move = (struct wlsc_move_grab *) grab;
        struct wlsc_surface *es =
                (struct wlsc_surface *) grab->input_device->pointer_focus;
-       struct wlsc_compositor *ec =
-               (struct wlsc_compositor *) grab->input_device->compositor;
 
        es->x = x + move->dx;
        es->y = y + move->dy;
-       wl_client_post_event(es->surface.client, &ec->shell.object,
-                            WL_SHELL_CONFIGURE,
-                            time, WLSC_DEVICE_GRAB_MOVE,
-                            &es->surface, es->x, es->y,
-                            es->width, es->height);
-
        wlsc_surface_update_matrix(es);
 }
 
@@ -630,33 +626,27 @@ resize_grab_motion(struct wl_grab *grab,
        struct wlsc_compositor *ec =
                (struct wlsc_compositor *) device->compositor;
        struct wl_surface *surface = device->pointer_focus;
-       int32_t sx, sy, width, height;
+       int32_t width, height;
 
        if (resize->edges & WLSC_DEVICE_GRAB_RESIZE_LEFT) {
-               sx = x + resize->dx;
                width = device->grab_x - x + resize->width;
        } else if (resize->edges & WLSC_DEVICE_GRAB_RESIZE_RIGHT) {
-               sx = device->grab_x + resize->dx;
                width = x - device->grab_x + resize->width;
        } else {
-               sx = device->grab_x + resize->dx;
                width = resize->width;
        }
 
        if (resize->edges & WLSC_DEVICE_GRAB_RESIZE_TOP) {
-               sy = y + resize->dy;
                height = device->grab_y - y + resize->height;
        } else if (resize->edges & WLSC_DEVICE_GRAB_RESIZE_BOTTOM) {
-               sy = device->grab_y + resize->dy;
                height = y - device->grab_y + resize->height;
        } else {
-               sy = device->grab_y + resize->dy;
                height = resize->height;
        }
 
        wl_client_post_event(surface->client, &ec->shell.object,
                             WL_SHELL_CONFIGURE, time, resize->edges,
-                            surface, sx, sy, width, height);
+                            surface, width, height);
 }
 
 static void
@@ -814,7 +804,6 @@ compositor_create_surface(struct wl_client *client,
                return;
        }
 
-       wl_list_insert(ec->surface_list.prev, &surface->link);
        surface->surface.resource.destroy = destroy_surface;
 
        surface->surface.resource.object.id = id;
index 62d8a66..8799a64 100644 (file)
          received. -->
     <event name="configure">
       <arg name="time" type="uint"/>
-      <!-- Same as edges except also move (16) -->
-      <arg name="type" type="uint"/>
+      <arg name="edges" type="uint"/>
       <arg name="surface" type="object" interface="surface"/>
-      <arg name="x" type="int"/>
-      <arg name="y" type="int"/>
       <arg name="width" type="int"/>
       <arg name="height" type="int"/>
     </event>
     <!-- Deletes the surface and invalidates its object id. -->
     <request name="destroy" type="destructor"/>
 
-    <!-- Copy the contents of a buffer into this surface. -->
+    <!-- Copy the contents of a buffer into this surface. The x and y
+         arguments specify the location of the new buffers upper left
+         corner, relative to the old buffers upper left corner. -->
     <request name="attach">
       <arg name="buffer" type="object" interface="buffer"/>
-    </request>
-
-    <!-- Set the location on the screen that this surface will
-         be displayed. -->
-    <request name="map">
       <arg name="x" type="int"/>
       <arg name="y" type="int"/>
-      <arg name="width" type="int"/>
-      <arg name="height" type="int"/>
     </request>
 
+    <!-- Make the surface visible as a toplevel window. -->
+    <request name="map_toplevel"/>
+
     <!-- Notify the server that the attached buffer's contents have
          changed, and request a redraw. The arguments allow you to
          damage only a part of the surface, but the server may ignore