compositor: drop wl_display_add_object()
[profile/ivi/weston.git] / compositor / shell.c
index ab6218b..2333ad6 100644 (file)
@@ -46,11 +46,8 @@ move_grab_motion(struct wl_grab *grab,
        struct wlsc_move_grab *move = (struct wlsc_move_grab *) grab;
        struct wlsc_surface *es = move->surface;
 
-       wlsc_surface_damage(es);
-       es->x = x + move->dx;
-       es->y = y + move->dy;
-       wlsc_surface_assign_output(es);
-       wlsc_surface_damage(es);
+       wlsc_surface_configure(es, x + move->dx, y + move->dy,
+                              es->width, es->height);
 }
 
 static void
@@ -80,7 +77,7 @@ static const struct wl_grab_interface move_grab_interface = {
 };
 
 static void
-shell_move(struct wl_client *client, struct wl_shell *shell,
+shell_move(struct wl_client *client, struct wl_resource *resource,
           struct wl_surface *surface,
           struct wl_input_device *device, uint32_t time)
 {
@@ -115,6 +112,7 @@ struct wlsc_resize_grab {
        int32_t dx, dy, width, height;
        struct wlsc_surface *surface;
        struct wl_shell *shell;
+       struct wl_resource resource;
 };
 
 static void
@@ -142,9 +140,9 @@ resize_grab_motion(struct wl_grab *grab,
                height = resize->height;
        }
 
-       wl_client_post_event(surface->client, &resize->shell->object,
-                            WL_SHELL_CONFIGURE, time, resize->edges,
-                            surface, width, height);
+       wl_resource_post_event(&resize->resource,
+                              WL_SHELL_CONFIGURE, time, resize->edges,
+                              surface, width, height);
 }
 
 static void
@@ -174,10 +172,11 @@ static const struct wl_grab_interface resize_grab_interface = {
 };
 
 static void
-shell_resize(struct wl_client *client, struct wl_shell *shell,
+shell_resize(struct wl_client *client, struct wl_resource *resource,
             struct wl_surface *surface,
             struct wl_input_device *device, uint32_t time, uint32_t edges)
 {
+       struct wl_shell *shell = resource->data;
        struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
        struct wlsc_resize_grab *resize;
        enum wlsc_pointer_type pointer = WLSC_POINTER_LEFT_PTR;
@@ -200,6 +199,9 @@ shell_resize(struct wl_client *client, struct wl_shell *shell,
        resize->surface = es;
        resize->shell = shell;
 
+       resize->resource.object = resource->object;
+       resize->resource.client = client;
+
        if (edges == 0 || edges > 15 ||
            (edges & 3) == 3 || (edges & 12) == 12)
                return;
@@ -240,7 +242,76 @@ shell_resize(struct wl_client *client, struct wl_shell *shell,
 }
 
 static void
-destroy_drag(struct wl_resource *resource, struct wl_client *client)
+shell_set_toplevel(struct wl_client *client,
+                  struct wl_resource *resource,
+                  struct wl_surface *surface)
+
+{
+       struct wlsc_surface *es = (struct wlsc_surface *) surface;
+       struct wlsc_compositor *ec = es->compositor;
+
+       if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN) {
+               es->x = es->saved_x;
+               es->y = es->saved_y;
+       } else if (es->map_type == WLSC_SURFACE_MAP_UNMAPPED) {
+               es->x = 10 + random() % 400;
+               es->y = 10 + random() % 400;
+               /* assign to first output */
+               es->output = container_of(ec->output_list.next,
+                                         struct wlsc_output, link);
+       }
+
+       wlsc_surface_damage(es);
+       es->map_type = WLSC_SURFACE_MAP_TOPLEVEL;
+       es->fullscreen_output = NULL;
+}
+
+static void
+shell_set_transient(struct wl_client *client,
+                   struct wl_resource *resource,
+                   struct wl_surface *surface,
+                   struct wl_surface *parent,
+                   int x, int y, uint32_t flags)
+{
+       struct wlsc_surface *es = (struct wlsc_surface *) surface;
+       struct wlsc_surface *pes = (struct wlsc_surface *) parent;
+
+       /* assign to parents output  */
+       es->output = pes->output;
+       es->x = pes->x + x;
+       es->y = pes->y + y;
+
+       wlsc_surface_damage(es);
+       es->map_type = WLSC_SURFACE_MAP_TRANSIENT;
+}
+
+static void
+shell_set_fullscreen(struct wl_client *client,
+                    struct wl_resource *resource,
+                    struct wl_surface *surface)
+
+{
+       struct wlsc_surface *es = (struct wlsc_surface *) surface;
+       struct wlsc_output *output;
+
+       /* FIXME: Fullscreen on first output */
+       /* FIXME: Handle output going away */
+       output = container_of(es->compositor->output_list.next,
+                             struct wlsc_output, link);
+       es->output = output;
+
+       es->saved_x = es->x;
+       es->saved_y = es->y;
+       es->x = (output->current->width - es->width) / 2;
+       es->y = (output->current->height - es->height) / 2;
+       es->fullscreen_output = output;
+       wlsc_surface_damage(es);
+       es->map_type = WLSC_SURFACE_MAP_FULLSCREEN;
+}
+
+static void
+destroy_drag(struct wl_resource *resource)
 {
        struct wl_drag *drag =
                container_of(resource, struct wl_drag, resource);
@@ -265,31 +336,30 @@ wl_drag_set_pointer_focus(struct wl_drag *drag,
                return;
 
        if (drag->drag_focus &&
-           (!surface || drag->drag_focus->client != surface->client))
-               wl_client_post_event(drag->drag_focus->client,
-                                     &drag->drag_offer.object,
+           (!surface ||
+            drag->drag_focus->resource.client != surface->resource.client))
+               wl_resource_post_event(&drag->drag_offer.resource,
                                      WL_DRAG_OFFER_POINTER_FOCUS,
                                      time, NULL, 0, 0, 0, 0);
 
        if (surface &&
            (!drag->drag_focus ||
-            drag->drag_focus->client != surface->client)) {
-               wl_client_post_global(surface->client,
-                                     &drag->drag_offer.object);
-
+            drag->drag_focus->resource.client != surface->resource.client)) {
+               wl_client_post_global(surface->resource.client,
+                                     &drag->drag_offer.resource.object);
+               
+               drag->drag_offer.resource.client = surface->resource.client;
                end = drag->types.data + drag->types.size;
                for (p = drag->types.data; p < end; p++)
-                       wl_client_post_event(surface->client,
-                                             &drag->drag_offer.object,
-                                             WL_DRAG_OFFER_OFFER, *p);
+                       wl_resource_post_event(&drag->drag_offer.resource,
+                                              WL_DRAG_OFFER_OFFER, *p);
        }
 
        if (surface) {
-               wl_client_post_event(surface->client,
-                                    &drag->drag_offer.object,
-                                    WL_DRAG_OFFER_POINTER_FOCUS,
-                                    time, surface,
-                                    x, y, sx, sy);
+               wl_resource_post_event(&drag->drag_offer.resource,
+                                      WL_DRAG_OFFER_POINTER_FOCUS,
+                                      time, surface,
+                                      x, y, sx, sy);
 
        }
 
@@ -299,14 +369,15 @@ wl_drag_set_pointer_focus(struct wl_drag *drag,
 
        wl_list_remove(&drag->drag_focus_listener.link);
        if (surface)
-               wl_list_insert(surface->destroy_listener_list.prev,
+               wl_list_insert(surface->resource.destroy_listener_list.prev,
                               &drag->drag_focus_listener.link);
 }
 
 static void
-drag_offer_accept(struct wl_client *client,
-                 struct wl_drag_offer *offer, uint32_t time, const char *type)
+drag_offer_accept(struct wl_client *client, struct wl_resource *resource,
+                 uint32_t time, const char *type)
 {
+       struct wl_drag_offer *offer = resource->data;
        struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
        char **p, **end;
 
@@ -325,28 +396,27 @@ drag_offer_accept(struct wl_client *client,
                if (type && strcmp(*p, type) == 0)
                        drag->type = *p;
 
-       wl_client_post_event(drag->source->client, &drag->resource.object,
-                            WL_DRAG_TARGET, drag->type);
+       wl_resource_post_event(&drag->resource, WL_DRAG_TARGET, drag->type);
 }
 
 static void
 drag_offer_receive(struct wl_client *client,
-                  struct wl_drag_offer *offer, int fd)
+                  struct wl_resource *resource, int fd)
 {
+       struct wl_drag_offer *offer = resource->data;
        struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
 
-       wl_client_post_event(drag->source->client, &drag->resource.object,
-                            WL_DRAG_FINISH, fd);
+       wl_resource_post_event(&drag->resource, WL_DRAG_FINISH, fd);
        close(fd);
 }
 
 static void
-drag_offer_reject(struct wl_client *client, struct wl_drag_offer *offer)
+drag_offer_reject(struct wl_client *client, struct wl_resource *resource)
 {
+       struct wl_drag_offer *offer = resource->data;
        struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
 
-       wl_client_post_event(drag->source->client, &drag->resource.object,
-                            WL_DRAG_REJECT);
+       wl_resource_post_event(&drag->resource, WL_DRAG_REJECT);
 }
 
 static const struct wl_drag_offer_interface drag_offer_interface = {
@@ -356,8 +426,10 @@ static const struct wl_drag_offer_interface drag_offer_interface = {
 };
 
 static void
-drag_offer(struct wl_client *client, struct wl_drag *drag, const char *type)
+drag_offer(struct wl_client *client,
+          struct wl_resource *resource, const char *type)
 {
+       struct wl_drag *drag = resource->data;
        char **p;
 
        p = wl_array_add(&drag->types, sizeof *p);
@@ -378,10 +450,9 @@ drag_grab_motion(struct wl_grab *grab,
        es = pick_surface(grab->input_device, &sx, &sy);
        wl_drag_set_pointer_focus(drag, &es->surface, time, x, y, sx, sy);
        if (es)
-               wl_client_post_event(es->surface.client,
-                                    &drag->drag_offer.object,
-                                    WL_DRAG_OFFER_MOTION,
-                                    time, x, y, sx, sy);
+               wl_resource_post_event(&drag->drag_offer.resource,
+                                      WL_DRAG_OFFER_MOTION,
+                                      time, x, y, sx, sy);
 }
 
 static void
@@ -399,9 +470,8 @@ drag_grab_end(struct wl_grab *grab, uint32_t time)
        int32_t sx, sy;
 
        if (drag->target)
-               wl_client_post_event(drag->target,
-                                    &drag->drag_offer.object,
-                                    WL_DRAG_OFFER_DROP);
+               wl_resource_post_event(&drag->drag_offer.resource,
+                                      WL_DRAG_OFFER_DROP);
 
        wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0);
 
@@ -419,10 +489,11 @@ static const struct wl_grab_interface drag_grab_interface = {
 
 static void
 drag_activate(struct wl_client *client,
-             struct wl_drag *drag,
+             struct wl_resource *resource,
              struct wl_surface *surface,
              struct wl_input_device *device, uint32_t time)
 {
+       struct wl_drag *drag = resource->data;
        struct wl_display *display = wl_client_get_display (client);
        struct wlsc_surface *target;
        int32_t sx, sy;
@@ -435,11 +506,12 @@ drag_activate(struct wl_client *client,
 
        drag->source = surface;
 
-       drag->drag_offer.object.interface = &wl_drag_offer_interface;
-       drag->drag_offer.object.implementation =
+       drag->drag_offer.resource.object.interface = &wl_drag_offer_interface;
+       drag->drag_offer.resource.object.implementation =
                (void (**)(void)) &drag_offer_interface;
 
-       wl_display_add_object(display, &drag->drag_offer.object);
+       wl_display_add_global(display,
+                             &drag->drag_offer.resource.object, NULL);
 
        target = pick_surface(device, &sx, &sy);
        wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
@@ -448,9 +520,9 @@ drag_activate(struct wl_client *client,
 }
 
 static void
-drag_destroy(struct wl_client *client, struct wl_drag *drag)
+drag_destroy(struct wl_client *client, struct wl_resource *resource)
 {
-       wl_resource_destroy(&drag->resource, client);
+       wl_resource_destroy(resource, wlsc_compositor_get_time());
 }
 
 static const struct wl_drag_interface drag_interface = {
@@ -461,10 +533,11 @@ static const struct wl_drag_interface drag_interface = {
 
 static void
 drag_handle_surface_destroy(struct wl_listener *listener,
-                           struct wl_surface *surface, uint32_t time)
+                           struct wl_resource *resource, uint32_t time)
 {
        struct wl_drag *drag =
                container_of(listener, struct wl_drag, drag_focus_listener);
+       struct wl_surface *surface = (struct wl_surface *) resource;
 
        if (drag->drag_focus == surface)
                wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0);
@@ -472,7 +545,7 @@ drag_handle_surface_destroy(struct wl_listener *listener,
 
 static void
 shell_create_drag(struct wl_client *client,
-                 struct wl_shell *shell, uint32_t id)
+                 struct wl_resource *resource, uint32_t id)
 {
        struct wl_drag *drag;
 
@@ -507,50 +580,48 @@ wlsc_selection_set_focus(struct wlsc_shell *shell,
                return;
 
        if (selection->selection_focus != NULL)
-               wl_client_post_event(selection->selection_focus->client,
-                                    &selection->selection_offer.object,
+               wl_resource_post_event(&selection->selection_offer.resource,
                                     WL_SELECTION_OFFER_KEYBOARD_FOCUS,
                                     NULL);
 
        if (surface) {
-               wl_client_post_global(surface->client,
-                                     &selection->selection_offer.object);
+               wl_client_post_global(surface->resource.client,
+                                     &selection->selection_offer.resource.object);
 
+               selection->selection_offer.resource.client = surface->resource.client;
                end = selection->types.data + selection->types.size;
                for (p = selection->types.data; p < end; p++)
-                       wl_client_post_event(surface->client,
-                                            &selection->selection_offer.object,
-                                            WL_SELECTION_OFFER_OFFER, *p);
+                       wl_resource_post_event(&selection->selection_offer.resource,
+                                              WL_SELECTION_OFFER_OFFER, *p);
 
                wl_list_remove(&selection->selection_focus_listener.link);
-               wl_list_insert(surface->destroy_listener_list.prev,
+               wl_list_insert(surface->resource.destroy_listener_list.prev,
                               &selection->selection_focus_listener.link);
 
-               wl_client_post_event(surface->client,
-                                    &selection->selection_offer.object,
-                                    WL_SELECTION_OFFER_KEYBOARD_FOCUS,
-                                    selection->input_device);
+               wl_resource_post_event(&selection->selection_offer.resource,
+                                      WL_SELECTION_OFFER_KEYBOARD_FOCUS,
+                                      selection->input_device);
        }
 
        selection->selection_focus = surface;
 
        wl_list_remove(&selection->selection_focus_listener.link);
        if (surface)
-               wl_list_insert(surface->destroy_listener_list.prev,
+               wl_list_insert(surface->resource.destroy_listener_list.prev,
                               &selection->selection_focus_listener.link);
 }
 
 static void
 selection_offer_receive(struct wl_client *client,
-                       struct wl_selection_offer *offer,
+                       struct wl_resource *resource,
                        const char *mime_type, int fd)
 {
+       struct wl_selection_offer *offer = resource->data;
        struct wl_selection *selection =
                container_of(offer, struct wl_selection, selection_offer);
 
-       wl_client_post_event(selection->client,
-                            &selection->resource.object,
-                            WL_SELECTION_SEND, mime_type, fd);
+       wl_resource_post_event(&selection->resource,
+                              WL_SELECTION_SEND, mime_type, fd);
        close(fd);
 }
 
@@ -560,8 +631,9 @@ static const struct wl_selection_offer_interface selection_offer_interface = {
 
 static void
 selection_offer(struct wl_client *client,
-               struct wl_selection *selection, const char *type)
+               struct wl_resource *resource, const char *type)
 {
+       struct wl_selection *selection = resource->data;
        char **p;
 
        p = wl_array_add(&selection->types, sizeof *p);
@@ -573,9 +645,10 @@ selection_offer(struct wl_client *client,
 
 static void
 selection_activate(struct wl_client *client,
-                  struct wl_selection *selection,
+                  struct wl_resource *resource,
                   struct wl_input_device *device, uint32_t time)
 {
+       struct wl_selection *selection = resource->data;
        struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
        struct wl_display *display = wl_client_get_display (client);
        struct wlsc_compositor *compositor =
@@ -583,17 +656,18 @@ selection_activate(struct wl_client *client,
 
        selection->input_device = device;
 
-       selection->selection_offer.object.interface =
+       selection->selection_offer.resource.object.interface =
                &wl_selection_offer_interface;
-       selection->selection_offer.object.implementation =
+       selection->selection_offer.resource.object.implementation =
                (void (**)(void)) &selection_offer_interface;
 
-       wl_display_add_object(display, &selection->selection_offer.object);
+       wl_display_add_global(display,
+                             &selection->selection_offer.resource.object,
+                             NULL);
 
        if (wd->selection) {
-               wl_client_post_event(wd->selection->client,
-                                    &wd->selection->resource.object,
-                                    WL_SELECTION_CANCELLED);
+               wl_resource_post_event(&wd->selection->resource,
+                                      WL_SELECTION_CANCELLED);
        }
        wd->selection = selection;
 
@@ -602,9 +676,9 @@ selection_activate(struct wl_client *client,
 }
 
 static void
-selection_destroy(struct wl_client *client, struct wl_selection *selection)
+selection_destroy(struct wl_client *client, struct wl_resource *resource)
 {
-       wl_resource_destroy(&selection->resource, client);
+       wl_resource_destroy(resource, wlsc_compositor_get_time());
 }
 
 static const struct wl_selection_interface selection_interface = {
@@ -614,7 +688,7 @@ static const struct wl_selection_interface selection_interface = {
 };
 
 static void
-destroy_selection(struct wl_resource *resource, struct wl_client *client)
+destroy_selection(struct wl_resource *resource)
 {
        struct wl_selection *selection =
                container_of(resource, struct wl_selection, resource);
@@ -636,13 +710,13 @@ destroy_selection(struct wl_resource *resource, struct wl_client *client)
 
 static void
 selection_handle_surface_destroy(struct wl_listener *listener,
-                                struct wl_surface *surface, uint32_t time)
+                                struct wl_resource *resource, uint32_t time)
 {
 }
 
 static void
 shell_create_selection(struct wl_client *client,
-                      struct wl_shell *shell, uint32_t id)
+                      struct wl_resource *resource, uint32_t id)
 {
        struct wl_selection *selection;
 
@@ -673,28 +747,29 @@ const static struct wl_shell_interface shell_interface = {
        shell_move,
        shell_resize,
        shell_create_drag,
-       shell_create_selection
+       shell_create_selection,
+       shell_set_toplevel,
+       shell_set_transient,
+       shell_set_fullscreen
 };
 
 static void
 move_binding(struct wl_input_device *device, uint32_t time,
             uint32_t key, uint32_t button, uint32_t state, void *data)
 {
-       struct wl_shell *shell = data;
        struct wlsc_surface *surface =
                (struct wlsc_surface *) device->pointer_focus;
 
        if (surface == NULL)
                return;
 
-       shell_move(NULL, shell, &surface->surface, device, time);
+       shell_move(NULL, NULL, &surface->surface, device, time);
 }
 
 static void
 resize_binding(struct wl_input_device *device, uint32_t time,
               uint32_t key, uint32_t button, uint32_t state, void *data)
 {
-       struct wl_shell *shell = data;
        struct wlsc_surface *surface =
                (struct wlsc_surface *) device->pointer_focus;
        uint32_t edges = 0;
@@ -720,7 +795,7 @@ resize_binding(struct wl_input_device *device, uint32_t time,
        else
                edges |= WL_SHELL_RESIZE_BOTTOM;
 
-       shell_resize(NULL, shell, &surface->surface, device, time, edges);
+       shell_resize(NULL, NULL, &surface->surface, device, time, edges);
 }
 
 static void
@@ -729,8 +804,12 @@ lock(struct wlsc_shell *shell)
 }
 
 static void
-attach(struct wlsc_shell *shell, struct wlsc_surface *surface)
+attach(struct wlsc_shell *shell, struct wlsc_surface *es)
 {
+       if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN) {
+               es->x = (es->fullscreen_output->current->width - es->width) / 2;
+               es->y = (es->fullscreen_output->current->height - es->height) / 2;
+       }
 }
 
 int
@@ -751,7 +830,6 @@ shell_init(struct wlsc_compositor *ec)
 
        shell->object.interface = &wl_shell_interface;
        shell->object.implementation = (void (**)(void)) &shell_interface;
-       wl_display_add_object(ec->wl_display, &shell->object);
        if (wl_display_add_global(ec->wl_display, &shell->object, NULL))
                return -1;