97e8b1ea4a71853a249354e06f6b76e3ff10f2c2
[profile/ivi/weston-ivi-shell.git] / desktop-shell / shell.c
1 /*
2  * Copyright © 2010-2012 Intel Corporation
3  * Copyright © 2011-2012 Collabora, Ltd.
4  * Copyright © 2013 Raspberry Pi Foundation
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and
7  * its documentation for any purpose is hereby granted without fee, provided
8  * that the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the copyright holders not be used in
11  * advertising or publicity pertaining to distribution of the software
12  * without specific, written prior permission.  The copyright holders make
13  * no representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied warranty.
15  *
16  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #include "config.h"
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <linux/input.h>
32 #include <assert.h>
33 #include <signal.h>
34 #include <math.h>
35 #include <sys/types.h>
36
37 #include "shell.h"
38 #include "desktop-shell-server-protocol.h"
39 #include "workspaces-server-protocol.h"
40 #include "../shared/config-parser.h"
41 #include "xdg-shell-server-protocol.h"
42
43 #define DEFAULT_NUM_WORKSPACES 1
44 #define DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH 200
45
46 #ifndef static_assert
47 #define static_assert(cond, msg)
48 #endif
49
50 struct focus_state {
51         struct weston_seat *seat;
52         struct workspace *ws;
53         struct weston_surface *keyboard_focus;
54         struct wl_list link;
55         struct wl_listener seat_destroy_listener;
56         struct wl_listener surface_destroy_listener;
57 };
58
59 enum shell_surface_type {
60         SHELL_SURFACE_NONE,
61         SHELL_SURFACE_TOPLEVEL,
62         SHELL_SURFACE_POPUP,
63         SHELL_SURFACE_XWAYLAND
64 };
65
66 /*
67  * Surface stacking and ordering.
68  *
69  * This is handled using several linked lists of surfaces, organised into
70  * ‘layers’. The layers are ordered, and each of the surfaces in one layer are
71  * above all of the surfaces in the layer below. The set of layers is static and
72  * in the following order (top-most first):
73  *  • Lock layer (only ever displayed on its own)
74  *  • Cursor layer
75  *  • Fullscreen layer
76  *  • Panel layer
77  *  • Input panel layer
78  *  • Workspace layers
79  *  • Background layer
80  *
81  * The list of layers may be manipulated to remove whole layers of surfaces from
82  * display. For example, when locking the screen, all layers except the lock
83  * layer are removed.
84  *
85  * A surface’s layer is modified on configuring the surface, in
86  * set_surface_type() (which is only called when the surface’s type change is
87  * _committed_). If a surface’s type changes (e.g. when making a window
88  * fullscreen) its layer changes too.
89  *
90  * In order to allow popup and transient surfaces to be correctly stacked above
91  * their parent surfaces, each surface tracks both its parent surface, and a
92  * linked list of its children. When a surface’s layer is updated, so are the
93  * layers of its children. Note that child surfaces are *not* the same as
94  * subsurfaces — child/parent surfaces are purely for maintaining stacking
95  * order.
96  *
97  * The children_link list of siblings of a surface (i.e. those surfaces which
98  * have the same parent) only contains weston_surfaces which have a
99  * shell_surface. Stacking is not implemented for non-shell_surface
100  * weston_surfaces. This means that the following implication does *not* hold:
101  *     (shsurf->parent != NULL) ⇒ !wl_list_is_empty(shsurf->children_link)
102  */
103
104 struct shell_surface {
105         struct wl_resource *resource;
106         struct wl_signal destroy_signal;
107
108         struct weston_surface *surface;
109         struct weston_view *view;
110         int32_t last_width, last_height;
111         struct wl_listener surface_destroy_listener;
112         struct wl_listener resource_destroy_listener;
113
114         struct weston_surface *parent;
115         struct wl_list children_list;  /* child surfaces of this one */
116         struct wl_list children_link;  /* sibling surfaces of this one */
117         struct desktop_shell *shell;
118
119         enum shell_surface_type type;
120         char *title, *class;
121         int32_t saved_x, saved_y;
122         int32_t saved_width, saved_height;
123         bool saved_position_valid;
124         bool saved_size_valid;
125         bool saved_rotation_valid;
126         int unresponsive, grabbed;
127         uint32_t resize_edges;
128
129         struct {
130                 struct weston_transform transform;
131                 struct weston_matrix rotation;
132         } rotation;
133
134         struct {
135                 struct wl_list grab_link;
136                 int32_t x, y;
137                 struct shell_seat *shseat;
138                 uint32_t serial;
139         } popup;
140
141         struct {
142                 int32_t x, y;
143                 uint32_t flags;
144         } transient;
145
146         struct {
147                 enum wl_shell_surface_fullscreen_method type;
148                 struct weston_transform transform; /* matrix from x, y */
149                 uint32_t framerate;
150                 struct weston_view *black_view;
151         } fullscreen;
152
153         struct weston_transform workspace_transform;
154
155         struct weston_output *fullscreen_output;
156         struct weston_output *output;
157         struct weston_output *recommended_output;
158         struct wl_list link;
159
160         const struct weston_shell_client *client;
161
162         struct {
163                 bool maximized;
164                 bool fullscreen;
165                 bool relative;
166         } state, next_state, requested_state; /* surface states */
167         bool state_changed;
168         bool state_requested;
169
170         int focus_count;
171 };
172
173 struct shell_grab {
174         struct weston_pointer_grab grab;
175         struct shell_surface *shsurf;
176         struct wl_listener shsurf_destroy_listener;
177 };
178
179 struct shell_touch_grab {
180         struct weston_touch_grab grab;
181         struct shell_surface *shsurf;
182         struct wl_listener shsurf_destroy_listener;
183         struct weston_touch *touch;
184 };
185
186 struct weston_move_grab {
187         struct shell_grab base;
188         wl_fixed_t dx, dy;
189 };
190
191 struct weston_touch_move_grab {
192         struct shell_touch_grab base;
193         int active;
194         wl_fixed_t dx, dy;
195 };
196
197 struct rotate_grab {
198         struct shell_grab base;
199         struct weston_matrix rotation;
200         struct {
201                 float x;
202                 float y;
203         } center;
204 };
205
206 struct shell_seat {
207         struct weston_seat *seat;
208         struct wl_listener seat_destroy_listener;
209         struct weston_surface *focused_surface;
210
211         struct {
212                 struct weston_pointer_grab grab;
213                 struct wl_list surfaces_list;
214                 struct wl_client *client;
215                 int32_t initial_up;
216         } popup_grab;
217 };
218
219 struct shell_client {
220         struct wl_resource *resource;
221         struct wl_client *client;
222         struct desktop_shell *shell;
223         struct wl_listener destroy_listener;
224         struct wl_event_source *ping_timer;
225         uint32_t ping_serial;
226         int unresponsive;
227 };
228
229 void
230 set_alpha_if_fullscreen(struct shell_surface *shsurf)
231 {
232         if (shsurf && shsurf->state.fullscreen)
233                 shsurf->fullscreen.black_view->alpha = 0.25;
234 }
235
236 static struct shell_client *
237 get_shell_client(struct wl_client *client);
238
239 static struct desktop_shell *
240 shell_surface_get_shell(struct shell_surface *shsurf);
241
242 static void
243 surface_rotate(struct shell_surface *surface, struct weston_seat *seat);
244
245 static void
246 shell_fade_startup(struct desktop_shell *shell);
247
248 static struct shell_seat *
249 get_shell_seat(struct weston_seat *seat);
250
251 static void
252 shell_surface_update_child_surface_layers(struct shell_surface *shsurf);
253
254 static bool
255 shell_surface_is_wl_shell_surface(struct shell_surface *shsurf);
256
257 static bool
258 shell_surface_is_xdg_surface(struct shell_surface *shsurf);
259
260 static bool
261 shell_surface_is_xdg_popup(struct shell_surface *shsurf);
262
263 static void
264 shell_surface_set_parent(struct shell_surface *shsurf,
265                          struct weston_surface *parent);
266
267 static bool
268 shell_surface_is_top_fullscreen(struct shell_surface *shsurf)
269 {
270         struct desktop_shell *shell;
271         struct weston_view *top_fs_ev;
272
273         shell = shell_surface_get_shell(shsurf);
274
275         if (wl_list_empty(&shell->fullscreen_layer.view_list))
276                 return false;
277
278         top_fs_ev = container_of(shell->fullscreen_layer.view_list.next,
279                                  struct weston_view,
280                                  layer_link);
281         return (shsurf == get_shell_surface(top_fs_ev->surface));
282 }
283
284 static void
285 destroy_shell_grab_shsurf(struct wl_listener *listener, void *data)
286 {
287         struct shell_grab *grab;
288
289         grab = container_of(listener, struct shell_grab,
290                             shsurf_destroy_listener);
291
292         grab->shsurf = NULL;
293 }
294
295 struct weston_view *
296 get_default_view(struct weston_surface *surface)
297 {
298         struct shell_surface *shsurf;
299         struct weston_view *view;
300
301         if (!surface || wl_list_empty(&surface->views))
302                 return NULL;
303
304         shsurf = get_shell_surface(surface);
305         if (shsurf)
306                 return shsurf->view;
307
308         wl_list_for_each(view, &surface->views, surface_link)
309                 if (weston_view_is_mapped(view))
310                         return view;
311
312         return container_of(surface->views.next, struct weston_view, surface_link);
313 }
314
315 static void
316 popup_grab_end(struct weston_pointer *pointer);
317
318 static void
319 shell_grab_start(struct shell_grab *grab,
320                  const struct weston_pointer_grab_interface *interface,
321                  struct shell_surface *shsurf,
322                  struct weston_pointer *pointer,
323                  enum desktop_shell_cursor cursor)
324 {
325         struct desktop_shell *shell = shsurf->shell;
326
327         popup_grab_end(pointer);
328
329         grab->grab.interface = interface;
330         grab->shsurf = shsurf;
331         grab->shsurf_destroy_listener.notify = destroy_shell_grab_shsurf;
332         wl_signal_add(&shsurf->destroy_signal,
333                       &grab->shsurf_destroy_listener);
334
335         shsurf->grabbed = 1;
336         weston_pointer_start_grab(pointer, &grab->grab);
337         if (shell->child.desktop_shell) {
338                 desktop_shell_send_grab_cursor(shell->child.desktop_shell,
339                                                cursor);
340                 weston_pointer_set_focus(pointer,
341                                          get_default_view(shell->grab_surface),
342                                          wl_fixed_from_int(0),
343                                          wl_fixed_from_int(0));
344         }
345 }
346
347 static void
348 shell_grab_end(struct shell_grab *grab)
349 {
350         if (grab->shsurf) {
351                 wl_list_remove(&grab->shsurf_destroy_listener.link);
352                 grab->shsurf->grabbed = 0;
353                 grab->shsurf->resize_edges = 0;
354         }
355
356         weston_pointer_end_grab(grab->grab.pointer);
357 }
358
359 static void
360 shell_touch_grab_start(struct shell_touch_grab *grab,
361                        const struct weston_touch_grab_interface *interface,
362                        struct shell_surface *shsurf,
363                        struct weston_touch *touch)
364 {
365         struct desktop_shell *shell = shsurf->shell;
366
367         grab->grab.interface = interface;
368         grab->shsurf = shsurf;
369         grab->shsurf_destroy_listener.notify = destroy_shell_grab_shsurf;
370         wl_signal_add(&shsurf->destroy_signal,
371                       &grab->shsurf_destroy_listener);
372
373         grab->touch = touch;
374         shsurf->grabbed = 1;
375
376         weston_touch_start_grab(touch, &grab->grab);
377         if (shell->child.desktop_shell)
378                 weston_touch_set_focus(touch->seat,
379                                        get_default_view(shell->grab_surface));
380 }
381
382 static void
383 shell_touch_grab_end(struct shell_touch_grab *grab)
384 {
385         if (grab->shsurf) {
386                 wl_list_remove(&grab->shsurf_destroy_listener.link);
387                 grab->shsurf->grabbed = 0;
388         }
389
390         weston_touch_end_grab(grab->touch);
391 }
392
393 static void
394 center_on_output(struct weston_view *view,
395                  struct weston_output *output);
396
397 static enum weston_keyboard_modifier
398 get_modifier(char *modifier)
399 {
400         if (!modifier)
401                 return MODIFIER_SUPER;
402
403         if (!strcmp("ctrl", modifier))
404                 return MODIFIER_CTRL;
405         else if (!strcmp("alt", modifier))
406                 return MODIFIER_ALT;
407         else if (!strcmp("super", modifier))
408                 return MODIFIER_SUPER;
409         else
410                 return MODIFIER_SUPER;
411 }
412
413 static enum animation_type
414 get_animation_type(char *animation)
415 {
416         if (!animation)
417                 return ANIMATION_NONE;
418
419         if (!strcmp("zoom", animation))
420                 return ANIMATION_ZOOM;
421         else if (!strcmp("fade", animation))
422                 return ANIMATION_FADE;
423         else if (!strcmp("dim-layer", animation))
424                 return ANIMATION_DIM_LAYER;
425         else
426                 return ANIMATION_NONE;
427 }
428
429 static void
430 shell_configuration(struct desktop_shell *shell)
431 {
432         struct weston_config_section *section;
433         int duration;
434         char *s;
435
436         section = weston_config_get_section(shell->compositor->config,
437                                             "screensaver", NULL, NULL);
438         weston_config_section_get_string(section,
439                                          "path", &shell->screensaver.path, NULL);
440         weston_config_section_get_int(section, "duration", &duration, 60);
441         shell->screensaver.duration = duration * 1000;
442
443         section = weston_config_get_section(shell->compositor->config,
444                                             "shell", NULL, NULL);
445         weston_config_section_get_string(section,
446                                          "client", &s, LIBEXECDIR "/" WESTON_SHELL_CLIENT);
447         shell->client = s;
448         weston_config_section_get_string(section,
449                                          "binding-modifier", &s, "super");
450         shell->binding_modifier = get_modifier(s);
451         free(s);
452
453         weston_config_section_get_string(section,
454                                          "exposay-modifier", &s, "none");
455         if (strcmp(s, "none") == 0)
456                 shell->exposay_modifier = 0;
457         else
458                 shell->exposay_modifier = get_modifier(s);
459         free(s);
460
461         weston_config_section_get_string(section, "animation", &s, "none");
462         shell->win_animation_type = get_animation_type(s);
463         free(s);
464         weston_config_section_get_string(section,
465                                          "startup-animation", &s, "fade");
466         shell->startup_animation_type = get_animation_type(s);
467         free(s);
468         if (shell->startup_animation_type == ANIMATION_ZOOM)
469                 shell->startup_animation_type = ANIMATION_NONE;
470         weston_config_section_get_string(section, "focus-animation", &s, "none");
471         shell->focus_animation_type = get_animation_type(s);
472         free(s);
473         weston_config_section_get_uint(section, "num-workspaces",
474                                        &shell->workspaces.num,
475                                        DEFAULT_NUM_WORKSPACES);
476 }
477
478 struct weston_output *
479 get_default_output(struct weston_compositor *compositor)
480 {
481         return container_of(compositor->output_list.next,
482                             struct weston_output, link);
483 }
484
485
486 /* no-op func for checking focus surface */
487 static void
488 focus_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
489 {
490 }
491
492 static struct focus_surface *
493 get_focus_surface(struct weston_surface *surface)
494 {
495         if (surface->configure == focus_surface_configure)
496                 return surface->configure_private;
497         else
498                 return NULL;
499 }
500
501 static bool
502 is_focus_surface (struct weston_surface *es)
503 {
504         return (es->configure == focus_surface_configure);
505 }
506
507 static bool
508 is_focus_view (struct weston_view *view)
509 {
510         return is_focus_surface (view->surface);
511 }
512
513 static struct focus_surface *
514 create_focus_surface(struct weston_compositor *ec,
515                      struct weston_output *output)
516 {
517         struct focus_surface *fsurf = NULL;
518         struct weston_surface *surface = NULL;
519
520         fsurf = malloc(sizeof *fsurf);
521         if (!fsurf)
522                 return NULL;
523
524         fsurf->surface = weston_surface_create(ec);
525         surface = fsurf->surface;
526         if (surface == NULL) {
527                 free(fsurf);
528                 return NULL;
529         }
530
531         surface->configure = focus_surface_configure;
532         surface->output = output;
533         surface->configure_private = fsurf;
534
535         fsurf->view = weston_view_create(surface);
536         if (fsurf->view == NULL) {
537                 weston_surface_destroy(surface);
538                 free(fsurf);
539                 return NULL;
540         }
541         fsurf->view->output = output;
542
543         weston_surface_set_size(surface, output->width, output->height);
544         weston_view_set_position(fsurf->view, output->x, output->y);
545         weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
546         pixman_region32_fini(&surface->opaque);
547         pixman_region32_init_rect(&surface->opaque, output->x, output->y,
548                                   output->width, output->height);
549         pixman_region32_fini(&surface->input);
550         pixman_region32_init(&surface->input);
551
552         wl_list_init(&fsurf->workspace_transform.link);
553
554         return fsurf;
555 }
556
557 static void
558 focus_surface_destroy(struct focus_surface *fsurf)
559 {
560         weston_surface_destroy(fsurf->surface);
561         free(fsurf);
562 }
563
564 static void
565 focus_animation_done(struct weston_view_animation *animation, void *data)
566 {
567         struct workspace *ws = data;
568
569         ws->focus_animation = NULL;
570 }
571
572 static void
573 focus_state_destroy(struct focus_state *state)
574 {
575         wl_list_remove(&state->seat_destroy_listener.link);
576         wl_list_remove(&state->surface_destroy_listener.link);
577         free(state);
578 }
579
580 static void
581 focus_state_seat_destroy(struct wl_listener *listener, void *data)
582 {
583         struct focus_state *state = container_of(listener,
584                                                  struct focus_state,
585                                                  seat_destroy_listener);
586
587         wl_list_remove(&state->link);
588         focus_state_destroy(state);
589 }
590
591 static void
592 focus_state_surface_destroy(struct wl_listener *listener, void *data)
593 {
594         struct focus_state *state = container_of(listener,
595                                                  struct focus_state,
596                                                  surface_destroy_listener);
597         struct desktop_shell *shell;
598         struct weston_surface *main_surface, *next;
599         struct weston_view *view;
600
601         main_surface = weston_surface_get_main_surface(state->keyboard_focus);
602
603         next = NULL;
604         wl_list_for_each(view, &state->ws->layer.view_list, layer_link) {
605                 if (view->surface == main_surface)
606                         continue;
607                 if (is_focus_view(view))
608                         continue;
609
610                 next = view->surface;
611                 break;
612         }
613
614         /* if the focus was a sub-surface, activate its main surface */
615         if (main_surface != state->keyboard_focus)
616                 next = main_surface;
617
618         shell = state->seat->compositor->shell_interface.shell;
619         if (next) {
620                 state->keyboard_focus = NULL;
621                 activate(shell, next, state->seat);
622         } else {
623                 if (shell->focus_animation_type == ANIMATION_DIM_LAYER) {
624                         if (state->ws->focus_animation)
625                                 weston_view_animation_destroy(state->ws->focus_animation);
626
627                         state->ws->focus_animation = weston_fade_run(
628                                 state->ws->fsurf_front->view,
629                                 state->ws->fsurf_front->view->alpha, 0.0, 300,
630                                 focus_animation_done, state->ws);
631                 }
632
633                 wl_list_remove(&state->link);
634                 focus_state_destroy(state);
635         }
636 }
637
638 static struct focus_state *
639 focus_state_create(struct weston_seat *seat, struct workspace *ws)
640 {
641         struct focus_state *state;
642
643         state = malloc(sizeof *state);
644         if (state == NULL)
645                 return NULL;
646
647         state->keyboard_focus = NULL;
648         state->ws = ws;
649         state->seat = seat;
650         wl_list_insert(&ws->focus_list, &state->link);
651
652         state->seat_destroy_listener.notify = focus_state_seat_destroy;
653         state->surface_destroy_listener.notify = focus_state_surface_destroy;
654         wl_signal_add(&seat->destroy_signal,
655                       &state->seat_destroy_listener);
656         wl_list_init(&state->surface_destroy_listener.link);
657
658         return state;
659 }
660
661 static struct focus_state *
662 ensure_focus_state(struct desktop_shell *shell, struct weston_seat *seat)
663 {
664         struct workspace *ws = get_current_workspace(shell);
665         struct focus_state *state;
666
667         wl_list_for_each(state, &ws->focus_list, link)
668                 if (state->seat == seat)
669                         break;
670
671         if (&state->link == &ws->focus_list)
672                 state = focus_state_create(seat, ws);
673
674         return state;
675 }
676
677 static void
678 focus_state_set_focus(struct focus_state *state,
679                       struct weston_surface *surface)
680 {
681         if (state->keyboard_focus) {
682                 wl_list_remove(&state->surface_destroy_listener.link);
683                 wl_list_init(&state->surface_destroy_listener.link);
684         }
685
686         state->keyboard_focus = surface;
687         if (surface)
688                 wl_signal_add(&surface->destroy_signal,
689                               &state->surface_destroy_listener);
690 }
691
692 static void
693 restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
694 {
695         struct focus_state *state, *next;
696         struct weston_surface *surface;
697
698         wl_list_for_each_safe(state, next, &ws->focus_list, link) {
699                 if (state->seat->keyboard == NULL)
700                         continue;
701
702                 surface = state->keyboard_focus;
703
704                 weston_keyboard_set_focus(state->seat->keyboard, surface);
705         }
706 }
707
708 static void
709 replace_focus_state(struct desktop_shell *shell, struct workspace *ws,
710                     struct weston_seat *seat)
711 {
712         struct focus_state *state;
713
714         wl_list_for_each(state, &ws->focus_list, link) {
715                 if (state->seat == seat) {
716                         focus_state_set_focus(state, seat->keyboard->focus);
717                         return;
718                 }
719         }
720 }
721
722 static void
723 drop_focus_state(struct desktop_shell *shell, struct workspace *ws,
724                  struct weston_surface *surface)
725 {
726         struct focus_state *state;
727
728         wl_list_for_each(state, &ws->focus_list, link)
729                 if (state->keyboard_focus == surface)
730                         focus_state_set_focus(state, NULL);
731 }
732
733 static void
734 animate_focus_change(struct desktop_shell *shell, struct workspace *ws,
735                      struct weston_view *from, struct weston_view *to)
736 {
737         struct weston_output *output;
738         bool focus_surface_created = false;
739
740         /* FIXME: Only support dim animation using two layers */
741         if (from == to || shell->focus_animation_type != ANIMATION_DIM_LAYER)
742                 return;
743
744         output = get_default_output(shell->compositor);
745         if (ws->fsurf_front == NULL && (from || to)) {
746                 ws->fsurf_front = create_focus_surface(shell->compositor, output);
747                 if (ws->fsurf_front == NULL)
748                         return;
749                 ws->fsurf_front->view->alpha = 0.0;
750
751                 ws->fsurf_back = create_focus_surface(shell->compositor, output);
752                 if (ws->fsurf_back == NULL) {
753                         focus_surface_destroy(ws->fsurf_front);
754                         return;
755                 }
756                 ws->fsurf_back->view->alpha = 0.0;
757
758                 focus_surface_created = true;
759         } else {
760                 wl_list_remove(&ws->fsurf_front->view->layer_link);
761                 wl_list_remove(&ws->fsurf_back->view->layer_link);
762         }
763
764         if (ws->focus_animation) {
765                 weston_view_animation_destroy(ws->focus_animation);
766                 ws->focus_animation = NULL;
767         }
768
769         if (to)
770                 wl_list_insert(&to->layer_link,
771                                &ws->fsurf_front->view->layer_link);
772         else if (from)
773                 wl_list_insert(&ws->layer.view_list,
774                                &ws->fsurf_front->view->layer_link);
775
776         if (focus_surface_created) {
777                 ws->focus_animation = weston_fade_run(
778                         ws->fsurf_front->view,
779                         ws->fsurf_front->view->alpha, 0.6, 300,
780                         focus_animation_done, ws);
781         } else if (from) {
782                 wl_list_insert(&from->layer_link,
783                                &ws->fsurf_back->view->layer_link);
784                 ws->focus_animation = weston_stable_fade_run(
785                         ws->fsurf_front->view, 0.0,
786                         ws->fsurf_back->view, 0.6,
787                         focus_animation_done, ws);
788         } else if (to) {
789                 wl_list_insert(&ws->layer.view_list,
790                                &ws->fsurf_back->view->layer_link);
791                 ws->focus_animation = weston_stable_fade_run(
792                         ws->fsurf_front->view, 0.0,
793                         ws->fsurf_back->view, 0.6,
794                         focus_animation_done, ws);
795         }
796 }
797
798 static void
799 workspace_destroy(struct workspace *ws)
800 {
801         struct focus_state *state, *next;
802
803         wl_list_for_each_safe(state, next, &ws->focus_list, link)
804                 focus_state_destroy(state);
805
806         if (ws->fsurf_front)
807                 focus_surface_destroy(ws->fsurf_front);
808         if (ws->fsurf_back)
809                 focus_surface_destroy(ws->fsurf_back);
810
811         free(ws);
812 }
813
814 static void
815 seat_destroyed(struct wl_listener *listener, void *data)
816 {
817         struct weston_seat *seat = data;
818         struct focus_state *state, *next;
819         struct workspace *ws = container_of(listener,
820                                             struct workspace,
821                                             seat_destroyed_listener);
822
823         wl_list_for_each_safe(state, next, &ws->focus_list, link)
824                 if (state->seat == seat)
825                         wl_list_remove(&state->link);
826 }
827
828 static struct workspace *
829 workspace_create(void)
830 {
831         struct workspace *ws = malloc(sizeof *ws);
832         if (ws == NULL)
833                 return NULL;
834
835         weston_layer_init(&ws->layer, NULL);
836
837         wl_list_init(&ws->focus_list);
838         wl_list_init(&ws->seat_destroyed_listener.link);
839         ws->seat_destroyed_listener.notify = seat_destroyed;
840         ws->fsurf_front = NULL;
841         ws->fsurf_back = NULL;
842         ws->focus_animation = NULL;
843
844         return ws;
845 }
846
847 static int
848 workspace_is_empty(struct workspace *ws)
849 {
850         return wl_list_empty(&ws->layer.view_list);
851 }
852
853 static struct workspace *
854 get_workspace(struct desktop_shell *shell, unsigned int index)
855 {
856         struct workspace **pws = shell->workspaces.array.data;
857         assert(index < shell->workspaces.num);
858         pws += index;
859         return *pws;
860 }
861
862 struct workspace *
863 get_current_workspace(struct desktop_shell *shell)
864 {
865         return get_workspace(shell, shell->workspaces.current);
866 }
867
868 static void
869 activate_workspace(struct desktop_shell *shell, unsigned int index)
870 {
871         struct workspace *ws;
872
873         ws = get_workspace(shell, index);
874         wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
875
876         shell->workspaces.current = index;
877 }
878
879 static unsigned int
880 get_output_height(struct weston_output *output)
881 {
882         return abs(output->region.extents.y1 - output->region.extents.y2);
883 }
884
885 static void
886 view_translate(struct workspace *ws, struct weston_view *view, double d)
887 {
888         struct weston_transform *transform;
889
890         if (is_focus_view(view)) {
891                 struct focus_surface *fsurf = get_focus_surface(view->surface);
892                 transform = &fsurf->workspace_transform;
893         } else {
894                 struct shell_surface *shsurf = get_shell_surface(view->surface);
895                 transform = &shsurf->workspace_transform;
896         }
897
898         if (wl_list_empty(&transform->link))
899                 wl_list_insert(view->geometry.transformation_list.prev,
900                                &transform->link);
901
902         weston_matrix_init(&transform->matrix);
903         weston_matrix_translate(&transform->matrix,
904                                 0.0, d, 0.0);
905         weston_view_geometry_dirty(view);
906 }
907
908 static void
909 workspace_translate_out(struct workspace *ws, double fraction)
910 {
911         struct weston_view *view;
912         unsigned int height;
913         double d;
914
915         wl_list_for_each(view, &ws->layer.view_list, layer_link) {
916                 height = get_output_height(view->surface->output);
917                 d = height * fraction;
918
919                 view_translate(ws, view, d);
920         }
921 }
922
923 static void
924 workspace_translate_in(struct workspace *ws, double fraction)
925 {
926         struct weston_view *view;
927         unsigned int height;
928         double d;
929
930         wl_list_for_each(view, &ws->layer.view_list, layer_link) {
931                 height = get_output_height(view->surface->output);
932
933                 if (fraction > 0)
934                         d = -(height - height * fraction);
935                 else
936                         d = height + height * fraction;
937
938                 view_translate(ws, view, d);
939         }
940 }
941
942 static void
943 broadcast_current_workspace_state(struct desktop_shell *shell)
944 {
945         struct wl_resource *resource;
946
947         wl_resource_for_each(resource, &shell->workspaces.client_list)
948                 workspace_manager_send_state(resource,
949                                              shell->workspaces.current,
950                                              shell->workspaces.num);
951 }
952
953 static void
954 reverse_workspace_change_animation(struct desktop_shell *shell,
955                                    unsigned int index,
956                                    struct workspace *from,
957                                    struct workspace *to)
958 {
959         shell->workspaces.current = index;
960
961         shell->workspaces.anim_to = to;
962         shell->workspaces.anim_from = from;
963         shell->workspaces.anim_dir = -1 * shell->workspaces.anim_dir;
964         shell->workspaces.anim_timestamp = 0;
965
966         weston_compositor_schedule_repaint(shell->compositor);
967 }
968
969 static void
970 workspace_deactivate_transforms(struct workspace *ws)
971 {
972         struct weston_view *view;
973         struct weston_transform *transform;
974
975         wl_list_for_each(view, &ws->layer.view_list, layer_link) {
976                 if (is_focus_view(view)) {
977                         struct focus_surface *fsurf = get_focus_surface(view->surface);
978                         transform = &fsurf->workspace_transform;
979                 } else {
980                         struct shell_surface *shsurf = get_shell_surface(view->surface);
981                         transform = &shsurf->workspace_transform;
982                 }
983
984                 if (!wl_list_empty(&transform->link)) {
985                         wl_list_remove(&transform->link);
986                         wl_list_init(&transform->link);
987                 }
988                 weston_view_geometry_dirty(view);
989         }
990 }
991
992 static void
993 finish_workspace_change_animation(struct desktop_shell *shell,
994                                   struct workspace *from,
995                                   struct workspace *to)
996 {
997         weston_compositor_schedule_repaint(shell->compositor);
998
999         wl_list_remove(&shell->workspaces.animation.link);
1000         workspace_deactivate_transforms(from);
1001         workspace_deactivate_transforms(to);
1002         shell->workspaces.anim_to = NULL;
1003
1004         wl_list_remove(&shell->workspaces.anim_from->layer.link);
1005 }
1006
1007 static void
1008 animate_workspace_change_frame(struct weston_animation *animation,
1009                                struct weston_output *output, uint32_t msecs)
1010 {
1011         struct desktop_shell *shell =
1012                 container_of(animation, struct desktop_shell,
1013                              workspaces.animation);
1014         struct workspace *from = shell->workspaces.anim_from;
1015         struct workspace *to = shell->workspaces.anim_to;
1016         uint32_t t;
1017         double x, y;
1018
1019         if (workspace_is_empty(from) && workspace_is_empty(to)) {
1020                 finish_workspace_change_animation(shell, from, to);
1021                 return;
1022         }
1023
1024         if (shell->workspaces.anim_timestamp == 0) {
1025                 if (shell->workspaces.anim_current == 0.0)
1026                         shell->workspaces.anim_timestamp = msecs;
1027                 else
1028                         shell->workspaces.anim_timestamp =
1029                                 msecs -
1030                                 /* Invers of movement function 'y' below. */
1031                                 (asin(1.0 - shell->workspaces.anim_current) *
1032                                  DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH *
1033                                  M_2_PI);
1034         }
1035
1036         t = msecs - shell->workspaces.anim_timestamp;
1037
1038         /*
1039          * x = [0, π/2]
1040          * y(x) = sin(x)
1041          */
1042         x = t * (1.0/DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH) * M_PI_2;
1043         y = sin(x);
1044
1045         if (t < DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH) {
1046                 weston_compositor_schedule_repaint(shell->compositor);
1047
1048                 workspace_translate_out(from, shell->workspaces.anim_dir * y);
1049                 workspace_translate_in(to, shell->workspaces.anim_dir * y);
1050                 shell->workspaces.anim_current = y;
1051
1052                 weston_compositor_schedule_repaint(shell->compositor);
1053         }
1054         else
1055                 finish_workspace_change_animation(shell, from, to);
1056 }
1057
1058 static void
1059 animate_workspace_change(struct desktop_shell *shell,
1060                          unsigned int index,
1061                          struct workspace *from,
1062                          struct workspace *to)
1063 {
1064         struct weston_output *output;
1065
1066         int dir;
1067
1068         if (index > shell->workspaces.current)
1069                 dir = -1;
1070         else
1071                 dir = 1;
1072
1073         shell->workspaces.current = index;
1074
1075         shell->workspaces.anim_dir = dir;
1076         shell->workspaces.anim_from = from;
1077         shell->workspaces.anim_to = to;
1078         shell->workspaces.anim_current = 0.0;
1079         shell->workspaces.anim_timestamp = 0;
1080
1081         output = container_of(shell->compositor->output_list.next,
1082                               struct weston_output, link);
1083         wl_list_insert(&output->animation_list,
1084                        &shell->workspaces.animation.link);
1085
1086         wl_list_insert(from->layer.link.prev, &to->layer.link);
1087
1088         workspace_translate_in(to, 0);
1089
1090         restore_focus_state(shell, to);
1091
1092         weston_compositor_schedule_repaint(shell->compositor);
1093 }
1094
1095 static void
1096 update_workspace(struct desktop_shell *shell, unsigned int index,
1097                  struct workspace *from, struct workspace *to)
1098 {
1099         shell->workspaces.current = index;
1100         wl_list_insert(&from->layer.link, &to->layer.link);
1101         wl_list_remove(&from->layer.link);
1102 }
1103
1104 static void
1105 change_workspace(struct desktop_shell *shell, unsigned int index)
1106 {
1107         struct workspace *from;
1108         struct workspace *to;
1109         struct focus_state *state;
1110
1111         if (index == shell->workspaces.current)
1112                 return;
1113
1114         /* Don't change workspace when there is any fullscreen surfaces. */
1115         if (!wl_list_empty(&shell->fullscreen_layer.view_list))
1116                 return;
1117
1118         from = get_current_workspace(shell);
1119         to = get_workspace(shell, index);
1120
1121         if (shell->workspaces.anim_from == to &&
1122             shell->workspaces.anim_to == from) {
1123                 restore_focus_state(shell, to);
1124                 reverse_workspace_change_animation(shell, index, from, to);
1125                 broadcast_current_workspace_state(shell);
1126                 return;
1127         }
1128
1129         if (shell->workspaces.anim_to != NULL)
1130                 finish_workspace_change_animation(shell,
1131                                                   shell->workspaces.anim_from,
1132                                                   shell->workspaces.anim_to);
1133
1134         restore_focus_state(shell, to);
1135
1136         if (shell->focus_animation_type != ANIMATION_NONE) {
1137                 wl_list_for_each(state, &from->focus_list, link)
1138                         if (state->keyboard_focus)
1139                                 animate_focus_change(shell, from,
1140                                                      get_default_view(state->keyboard_focus), NULL);
1141
1142                 wl_list_for_each(state, &to->focus_list, link)
1143                         if (state->keyboard_focus)
1144                                 animate_focus_change(shell, to,
1145                                                      NULL, get_default_view(state->keyboard_focus));
1146         }
1147
1148         if (workspace_is_empty(to) && workspace_is_empty(from))
1149                 update_workspace(shell, index, from, to);
1150         else
1151                 animate_workspace_change(shell, index, from, to);
1152
1153         broadcast_current_workspace_state(shell);
1154 }
1155
1156 static bool
1157 workspace_has_only(struct workspace *ws, struct weston_surface *surface)
1158 {
1159         struct wl_list *list = &ws->layer.view_list;
1160         struct wl_list *e;
1161
1162         if (wl_list_empty(list))
1163                 return false;
1164
1165         e = list->next;
1166
1167         if (e->next != list)
1168                 return false;
1169
1170         return container_of(e, struct weston_view, layer_link)->surface == surface;
1171 }
1172
1173 static void
1174 move_surface_to_workspace(struct desktop_shell *shell,
1175                           struct shell_surface *shsurf,
1176                           uint32_t workspace)
1177 {
1178         struct workspace *from;
1179         struct workspace *to;
1180         struct weston_seat *seat;
1181         struct weston_surface *focus;
1182         struct weston_view *view;
1183
1184         if (workspace == shell->workspaces.current)
1185                 return;
1186
1187         view = get_default_view(shsurf->surface);
1188         if (!view)
1189                 return;
1190
1191         assert(weston_surface_get_main_surface(view->surface) == view->surface);
1192
1193         if (workspace >= shell->workspaces.num)
1194                 workspace = shell->workspaces.num - 1;
1195
1196         from = get_current_workspace(shell);
1197         to = get_workspace(shell, workspace);
1198
1199         wl_list_remove(&view->layer_link);
1200         wl_list_insert(&to->layer.view_list, &view->layer_link);
1201
1202         shell_surface_update_child_surface_layers(shsurf);
1203
1204         drop_focus_state(shell, from, view->surface);
1205         wl_list_for_each(seat, &shell->compositor->seat_list, link) {
1206                 if (!seat->keyboard)
1207                         continue;
1208
1209                 focus = weston_surface_get_main_surface(seat->keyboard->focus);
1210                 if (focus == view->surface)
1211                         weston_keyboard_set_focus(seat->keyboard, NULL);
1212         }
1213
1214         weston_view_damage_below(view);
1215 }
1216
1217 static void
1218 take_surface_to_workspace_by_seat(struct desktop_shell *shell,
1219                                   struct weston_seat *seat,
1220                                   unsigned int index)
1221 {
1222         struct weston_surface *surface;
1223         struct weston_view *view;
1224         struct shell_surface *shsurf;
1225         struct workspace *from;
1226         struct workspace *to;
1227         struct focus_state *state;
1228
1229         surface = weston_surface_get_main_surface(seat->keyboard->focus);
1230         view = get_default_view(surface);
1231         if (view == NULL ||
1232             index == shell->workspaces.current ||
1233             is_focus_view(view))
1234                 return;
1235
1236         from = get_current_workspace(shell);
1237         to = get_workspace(shell, index);
1238
1239         wl_list_remove(&view->layer_link);
1240         wl_list_insert(&to->layer.view_list, &view->layer_link);
1241
1242         shsurf = get_shell_surface(surface);
1243         if (shsurf != NULL)
1244                 shell_surface_update_child_surface_layers(shsurf);
1245
1246         replace_focus_state(shell, to, seat);
1247         drop_focus_state(shell, from, surface);
1248
1249         if (shell->workspaces.anim_from == to &&
1250             shell->workspaces.anim_to == from) {
1251                 wl_list_remove(&to->layer.link);
1252                 wl_list_insert(from->layer.link.prev, &to->layer.link);
1253
1254                 reverse_workspace_change_animation(shell, index, from, to);
1255                 broadcast_current_workspace_state(shell);
1256
1257                 return;
1258         }
1259
1260         if (shell->workspaces.anim_to != NULL)
1261                 finish_workspace_change_animation(shell,
1262                                                   shell->workspaces.anim_from,
1263                                                   shell->workspaces.anim_to);
1264
1265         if (workspace_is_empty(from) &&
1266             workspace_has_only(to, surface))
1267                 update_workspace(shell, index, from, to);
1268         else {
1269                 if (shsurf != NULL &&
1270                     wl_list_empty(&shsurf->workspace_transform.link))
1271                         wl_list_insert(&shell->workspaces.anim_sticky_list,
1272                                        &shsurf->workspace_transform.link);
1273
1274                 animate_workspace_change(shell, index, from, to);
1275         }
1276
1277         broadcast_current_workspace_state(shell);
1278
1279         state = ensure_focus_state(shell, seat);
1280         if (state != NULL)
1281                 focus_state_set_focus(state, surface);
1282 }
1283
1284 static void
1285 workspace_manager_move_surface(struct wl_client *client,
1286                                struct wl_resource *resource,
1287                                struct wl_resource *surface_resource,
1288                                uint32_t workspace)
1289 {
1290         struct desktop_shell *shell = wl_resource_get_user_data(resource);
1291         struct weston_surface *surface =
1292                 wl_resource_get_user_data(surface_resource);
1293         struct weston_surface *main_surface;
1294         struct shell_surface *shell_surface;
1295
1296         main_surface = weston_surface_get_main_surface(surface);
1297         shell_surface = get_shell_surface(main_surface);
1298         if (shell_surface == NULL)
1299                 return;
1300
1301         move_surface_to_workspace(shell, shell_surface, workspace);
1302 }
1303
1304 static const struct workspace_manager_interface workspace_manager_implementation = {
1305         workspace_manager_move_surface,
1306 };
1307
1308 static void
1309 unbind_resource(struct wl_resource *resource)
1310 {
1311         wl_list_remove(wl_resource_get_link(resource));
1312 }
1313
1314 static void
1315 bind_workspace_manager(struct wl_client *client,
1316                        void *data, uint32_t version, uint32_t id)
1317 {
1318         struct desktop_shell *shell = data;
1319         struct wl_resource *resource;
1320
1321         resource = wl_resource_create(client,
1322                                       &workspace_manager_interface, 1, id);
1323
1324         if (resource == NULL) {
1325                 weston_log("couldn't add workspace manager object");
1326                 return;
1327         }
1328
1329         wl_resource_set_implementation(resource,
1330                                        &workspace_manager_implementation,
1331                                        shell, unbind_resource);
1332         wl_list_insert(&shell->workspaces.client_list,
1333                        wl_resource_get_link(resource));
1334
1335         workspace_manager_send_state(resource,
1336                                      shell->workspaces.current,
1337                                      shell->workspaces.num);
1338 }
1339
1340 static void
1341 touch_move_grab_down(struct weston_touch_grab *grab, uint32_t time,
1342                      int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1343 {
1344 }
1345
1346 static void
1347 touch_move_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id)
1348 {
1349         struct weston_touch_move_grab *move =
1350                 (struct weston_touch_move_grab *) container_of(
1351                         grab, struct shell_touch_grab, grab);
1352
1353         if (touch_id == 0)
1354                 move->active = 0;
1355
1356         if (grab->touch->num_tp == 0) {
1357                 shell_touch_grab_end(&move->base);
1358                 free(move);
1359         }
1360 }
1361
1362 static void
1363 touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
1364                        int touch_id, wl_fixed_t sx, wl_fixed_t sy)
1365 {
1366         struct weston_touch_move_grab *move = (struct weston_touch_move_grab *) grab;
1367         struct shell_surface *shsurf = move->base.shsurf;
1368         struct weston_surface *es;
1369         int dx = wl_fixed_to_int(grab->touch->grab_x + move->dx);
1370         int dy = wl_fixed_to_int(grab->touch->grab_y + move->dy);
1371
1372         if (!shsurf || !move->active)
1373                 return;
1374
1375         es = shsurf->surface;
1376
1377         weston_view_set_position(shsurf->view, dx, dy);
1378
1379         weston_compositor_schedule_repaint(es->compositor);
1380 }
1381
1382 static void
1383 touch_move_grab_cancel(struct weston_touch_grab *grab)
1384 {
1385         struct weston_touch_move_grab *move =
1386                 (struct weston_touch_move_grab *) container_of(
1387                         grab, struct shell_touch_grab, grab);
1388
1389         shell_touch_grab_end(&move->base);
1390         free(move);
1391 }
1392
1393 static const struct weston_touch_grab_interface touch_move_grab_interface = {
1394         touch_move_grab_down,
1395         touch_move_grab_up,
1396         touch_move_grab_motion,
1397         touch_move_grab_cancel,
1398 };
1399
1400 static int
1401 surface_touch_move(struct shell_surface *shsurf, struct weston_seat *seat)
1402 {
1403         struct weston_touch_move_grab *move;
1404
1405         if (!shsurf)
1406                 return -1;
1407
1408         if (shsurf->state.fullscreen)
1409                 return 0;
1410         if (shsurf->grabbed)
1411                 return 0;
1412
1413         move = malloc(sizeof *move);
1414         if (!move)
1415                 return -1;
1416
1417         move->active = 1;
1418         move->dx = wl_fixed_from_double(shsurf->view->geometry.x) -
1419                         seat->touch->grab_x;
1420         move->dy = wl_fixed_from_double(shsurf->view->geometry.y) -
1421                         seat->touch->grab_y;
1422
1423         shell_touch_grab_start(&move->base, &touch_move_grab_interface, shsurf,
1424                                seat->touch);
1425
1426         return 0;
1427 }
1428
1429 static void
1430 noop_grab_focus(struct weston_pointer_grab *grab)
1431 {
1432 }
1433
1434 static void
1435 move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
1436                  wl_fixed_t x, wl_fixed_t y)
1437 {
1438         struct weston_move_grab *move = (struct weston_move_grab *) grab;
1439         struct weston_pointer *pointer = grab->pointer;
1440         struct shell_surface *shsurf = move->base.shsurf;
1441         int dx, dy;
1442
1443         weston_pointer_move(pointer, x, y);
1444         dx = wl_fixed_to_int(pointer->x + move->dx);
1445         dy = wl_fixed_to_int(pointer->y + move->dy);
1446
1447         if (!shsurf)
1448                 return;
1449
1450         weston_view_set_position(shsurf->view, dx, dy);
1451
1452         weston_compositor_schedule_repaint(shsurf->surface->compositor);
1453 }
1454
1455 static void
1456 move_grab_button(struct weston_pointer_grab *grab,
1457                  uint32_t time, uint32_t button, uint32_t state_w)
1458 {
1459         struct shell_grab *shell_grab = container_of(grab, struct shell_grab,
1460                                                     grab);
1461         struct weston_pointer *pointer = grab->pointer;
1462         enum wl_pointer_button_state state = state_w;
1463
1464         if (pointer->button_count == 0 &&
1465             state == WL_POINTER_BUTTON_STATE_RELEASED) {
1466                 shell_grab_end(shell_grab);
1467                 free(grab);
1468         }
1469 }
1470
1471 static void
1472 move_grab_cancel(struct weston_pointer_grab *grab)
1473 {
1474         struct shell_grab *shell_grab =
1475                 container_of(grab, struct shell_grab, grab);
1476
1477         shell_grab_end(shell_grab);
1478         free(grab);
1479 }
1480
1481 static const struct weston_pointer_grab_interface move_grab_interface = {
1482         noop_grab_focus,
1483         move_grab_motion,
1484         move_grab_button,
1485         move_grab_cancel,
1486 };
1487
1488 static int
1489 surface_move(struct shell_surface *shsurf, struct weston_seat *seat)
1490 {
1491         struct weston_move_grab *move;
1492
1493         if (!shsurf)
1494                 return -1;
1495
1496         if (shsurf->grabbed)
1497                 return 0;
1498         if (shsurf->state.fullscreen || shsurf->state.maximized)
1499                 return 0;
1500
1501         move = malloc(sizeof *move);
1502         if (!move)
1503                 return -1;
1504
1505         move->dx = wl_fixed_from_double(shsurf->view->geometry.x) -
1506                         seat->pointer->grab_x;
1507         move->dy = wl_fixed_from_double(shsurf->view->geometry.y) -
1508                         seat->pointer->grab_y;
1509
1510         shell_grab_start(&move->base, &move_grab_interface, shsurf,
1511                          seat->pointer, DESKTOP_SHELL_CURSOR_MOVE);
1512
1513         return 0;
1514 }
1515
1516 static void
1517 common_surface_move(struct wl_resource *resource,
1518                     struct wl_resource *seat_resource, uint32_t serial)
1519 {
1520         struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
1521         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
1522         struct weston_surface *surface;
1523
1524         if (seat->pointer &&
1525             seat->pointer->focus &&
1526             seat->pointer->button_count > 0 &&
1527             seat->pointer->grab_serial == serial) {
1528                 surface = weston_surface_get_main_surface(seat->pointer->focus->surface);
1529                 if ((surface == shsurf->surface) &&
1530                     (surface_move(shsurf, seat) < 0))
1531                         wl_resource_post_no_memory(resource);
1532         } else if (seat->touch &&
1533                    seat->touch->focus &&
1534                    seat->touch->grab_serial == serial) {
1535                 surface = weston_surface_get_main_surface(seat->touch->focus->surface);
1536                 if ((surface == shsurf->surface) &&
1537                     (surface_touch_move(shsurf, seat) < 0))
1538                         wl_resource_post_no_memory(resource);
1539         }
1540 }
1541
1542 static void
1543 shell_surface_move(struct wl_client *client, struct wl_resource *resource,
1544                    struct wl_resource *seat_resource, uint32_t serial)
1545 {
1546         common_surface_move(resource, seat_resource, serial);
1547 }
1548
1549 struct weston_resize_grab {
1550         struct shell_grab base;
1551         uint32_t edges;
1552         int32_t width, height;
1553 };
1554
1555 static void
1556 resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
1557                    wl_fixed_t x, wl_fixed_t y)
1558 {
1559         struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
1560         struct weston_pointer *pointer = grab->pointer;
1561         struct shell_surface *shsurf = resize->base.shsurf;
1562         int32_t width, height;
1563         wl_fixed_t from_x, from_y;
1564         wl_fixed_t to_x, to_y;
1565
1566         weston_pointer_move(pointer, x, y);
1567
1568         if (!shsurf)
1569                 return;
1570
1571         weston_view_from_global_fixed(shsurf->view,
1572                                       pointer->grab_x, pointer->grab_y,
1573                                       &from_x, &from_y);
1574         weston_view_from_global_fixed(shsurf->view,
1575                                       pointer->x, pointer->y, &to_x, &to_y);
1576
1577         width = resize->width;
1578         if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
1579                 width += wl_fixed_to_int(from_x - to_x);
1580         } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) {
1581                 width += wl_fixed_to_int(to_x - from_x);
1582         }
1583
1584         height = resize->height;
1585         if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) {
1586                 height += wl_fixed_to_int(from_y - to_y);
1587         } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) {
1588                 height += wl_fixed_to_int(to_y - from_y);
1589         }
1590
1591         shsurf->client->send_configure(shsurf->surface,
1592                                        resize->edges, width, height);
1593 }
1594
1595 static void
1596 send_configure(struct weston_surface *surface,
1597                uint32_t edges, int32_t width, int32_t height)
1598 {
1599         struct shell_surface *shsurf = get_shell_surface(surface);
1600
1601         assert(shsurf);
1602
1603         wl_shell_surface_send_configure(shsurf->resource,
1604                                         edges, width, height);
1605 }
1606
1607 static const struct weston_shell_client shell_client = {
1608         send_configure
1609 };
1610
1611 static void
1612 resize_grab_button(struct weston_pointer_grab *grab,
1613                    uint32_t time, uint32_t button, uint32_t state_w)
1614 {
1615         struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
1616         struct weston_pointer *pointer = grab->pointer;
1617         enum wl_pointer_button_state state = state_w;
1618
1619         if (pointer->button_count == 0 &&
1620             state == WL_POINTER_BUTTON_STATE_RELEASED) {
1621                 shell_grab_end(&resize->base);
1622                 free(grab);
1623         }
1624 }
1625
1626 static void
1627 resize_grab_cancel(struct weston_pointer_grab *grab)
1628 {
1629         struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
1630
1631         shell_grab_end(&resize->base);
1632         free(grab);
1633 }
1634
1635 static const struct weston_pointer_grab_interface resize_grab_interface = {
1636         noop_grab_focus,
1637         resize_grab_motion,
1638         resize_grab_button,
1639         resize_grab_cancel,
1640 };
1641
1642 /*
1643  * Returns the bounding box of a surface and all its sub-surfaces,
1644  * in the surface coordinates system. */
1645 static void
1646 surface_subsurfaces_boundingbox(struct weston_surface *surface, int32_t *x,
1647                                 int32_t *y, int32_t *w, int32_t *h) {
1648         pixman_region32_t region;
1649         pixman_box32_t *box;
1650         struct weston_subsurface *subsurface;
1651
1652         pixman_region32_init_rect(&region, 0, 0,
1653                                   surface->width,
1654                                   surface->height);
1655
1656         wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
1657                 pixman_region32_union_rect(&region, &region,
1658                                            subsurface->position.x,
1659                                            subsurface->position.y,
1660                                            subsurface->surface->width,
1661                                            subsurface->surface->height);
1662         }
1663
1664         box = pixman_region32_extents(&region);
1665         if (x)
1666                 *x = box->x1;
1667         if (y)
1668                 *y = box->y1;
1669         if (w)
1670                 *w = box->x2 - box->x1;
1671         if (h)
1672                 *h = box->y2 - box->y1;
1673
1674         pixman_region32_fini(&region);
1675 }
1676
1677 static int
1678 surface_resize(struct shell_surface *shsurf,
1679                struct weston_seat *seat, uint32_t edges)
1680 {
1681         struct weston_resize_grab *resize;
1682
1683         if (shsurf->state.fullscreen || shsurf->state.maximized)
1684                 return 0;
1685
1686         if (edges == 0 || edges > 15 ||
1687             (edges & 3) == 3 || (edges & 12) == 12)
1688                 return 0;
1689
1690         resize = malloc(sizeof *resize);
1691         if (!resize)
1692                 return -1;
1693
1694         resize->edges = edges;
1695         surface_subsurfaces_boundingbox(shsurf->surface, NULL, NULL,
1696                                         &resize->width, &resize->height);
1697
1698         shsurf->resize_edges = edges;
1699         shell_grab_start(&resize->base, &resize_grab_interface, shsurf,
1700                          seat->pointer, edges);
1701
1702         return 0;
1703 }
1704
1705 static void
1706 common_surface_resize(struct wl_resource *resource,
1707                       struct wl_resource *seat_resource, uint32_t serial,
1708                       uint32_t edges)
1709 {
1710         struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
1711         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
1712         struct weston_surface *surface;
1713
1714         if (shsurf->state.fullscreen)
1715                 return;
1716
1717         if (seat->pointer->button_count == 0 ||
1718             seat->pointer->grab_serial != serial ||
1719             seat->pointer->focus == NULL)
1720                 return;
1721
1722         surface = weston_surface_get_main_surface(seat->pointer->focus->surface);
1723         if (surface != shsurf->surface)
1724                 return;
1725
1726         if (surface_resize(shsurf, seat, edges) < 0)
1727                 wl_resource_post_no_memory(resource);
1728 }
1729
1730 static void
1731 shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
1732                      struct wl_resource *seat_resource, uint32_t serial,
1733                      uint32_t edges)
1734 {
1735         common_surface_resize(resource, seat_resource, serial, edges);
1736 }
1737
1738 static void
1739 busy_cursor_grab_focus(struct weston_pointer_grab *base)
1740 {
1741         struct shell_grab *grab = (struct shell_grab *) base;
1742         struct weston_pointer *pointer = base->pointer;
1743         struct weston_view *view;
1744         wl_fixed_t sx, sy;
1745
1746         view = weston_compositor_pick_view(pointer->seat->compositor,
1747                                            pointer->x, pointer->y,
1748                                            &sx, &sy);
1749
1750         if (!grab->shsurf || grab->shsurf->surface != view->surface) {
1751                 shell_grab_end(grab);
1752                 free(grab);
1753         }
1754 }
1755
1756 static void
1757 busy_cursor_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
1758                         wl_fixed_t x, wl_fixed_t y)
1759 {
1760         weston_pointer_move(grab->pointer, x, y);
1761 }
1762
1763 static void
1764 busy_cursor_grab_button(struct weston_pointer_grab *base,
1765                         uint32_t time, uint32_t button, uint32_t state)
1766 {
1767         struct shell_grab *grab = (struct shell_grab *) base;
1768         struct shell_surface *shsurf = grab->shsurf;
1769         struct weston_seat *seat = grab->grab.pointer->seat;
1770
1771         if (shsurf && button == BTN_LEFT && state) {
1772                 activate(shsurf->shell, shsurf->surface, seat);
1773                 surface_move(shsurf, seat);
1774         } else if (shsurf && button == BTN_RIGHT && state) {
1775                 activate(shsurf->shell, shsurf->surface, seat);
1776                 surface_rotate(shsurf, seat);
1777         }
1778 }
1779
1780 static void
1781 busy_cursor_grab_cancel(struct weston_pointer_grab *base)
1782 {
1783         struct shell_grab *grab = (struct shell_grab *) base;
1784
1785         shell_grab_end(grab);
1786         free(grab);
1787 }
1788
1789 static const struct weston_pointer_grab_interface busy_cursor_grab_interface = {
1790         busy_cursor_grab_focus,
1791         busy_cursor_grab_motion,
1792         busy_cursor_grab_button,
1793         busy_cursor_grab_cancel,
1794 };
1795
1796 static void
1797 set_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer)
1798 {
1799         struct shell_grab *grab;
1800
1801         if (pointer->grab->interface == &busy_cursor_grab_interface)
1802                 return;
1803
1804         grab = malloc(sizeof *grab);
1805         if (!grab)
1806                 return;
1807
1808         shell_grab_start(grab, &busy_cursor_grab_interface, shsurf, pointer,
1809                          DESKTOP_SHELL_CURSOR_BUSY);
1810 }
1811
1812 static void
1813 end_busy_cursor(struct weston_compositor *compositor, struct wl_client *client)
1814 {
1815         struct shell_grab *grab;
1816         struct weston_seat *seat;
1817
1818         wl_list_for_each(seat, &compositor->seat_list, link) {
1819                 if (seat->pointer == NULL)
1820                         continue;
1821
1822                 grab = (struct shell_grab *) seat->pointer->grab;
1823                 if (grab->grab.interface == &busy_cursor_grab_interface &&
1824                     wl_resource_get_client(grab->shsurf->resource) == client) {
1825                         shell_grab_end(grab);
1826                         free(grab);
1827                 }
1828         }
1829 }
1830
1831 static void
1832 handle_shell_client_destroy(struct wl_listener *listener, void *data);
1833
1834 static int
1835 xdg_ping_timeout_handler(void *data)
1836 {
1837         struct shell_client *sc = data;
1838         struct weston_seat *seat;
1839         struct shell_surface *shsurf;
1840
1841         /* Client is not responding */
1842         sc->unresponsive = 1;
1843         wl_list_for_each(seat, &sc->shell->compositor->seat_list, link) {
1844                 if (seat->pointer == NULL || seat->pointer->focus == NULL)
1845                         continue;
1846                 if (seat->pointer->focus->surface->resource == NULL)
1847                         continue;
1848                 
1849                 shsurf = get_shell_surface(seat->pointer->focus->surface);
1850                 if (shsurf &&
1851                     wl_resource_get_client(shsurf->resource) == sc->client)
1852                         set_busy_cursor(shsurf, seat->pointer);
1853         }
1854
1855         return 1;
1856 }
1857
1858 static void
1859 handle_xdg_ping(struct shell_surface *shsurf, uint32_t serial)
1860 {
1861         struct weston_compositor *compositor = shsurf->shell->compositor;
1862         struct wl_client *client = wl_resource_get_client(shsurf->resource);
1863         struct shell_client *sc;
1864         struct wl_event_loop *loop;
1865         static const int ping_timeout = 200;
1866
1867         sc = get_shell_client(client);
1868         if (sc->unresponsive) {
1869                 xdg_ping_timeout_handler(sc);
1870                 return;
1871         }
1872
1873         sc->ping_serial = serial;
1874         loop = wl_display_get_event_loop(compositor->wl_display);
1875         if (sc->ping_timer == NULL)
1876                 sc->ping_timer =
1877                         wl_event_loop_add_timer(loop,
1878                                                 xdg_ping_timeout_handler, sc);
1879         if (sc->ping_timer == NULL)
1880                 return;
1881
1882         wl_event_source_timer_update(sc->ping_timer, ping_timeout);
1883
1884         if (shell_surface_is_xdg_surface(shsurf) ||
1885             shell_surface_is_xdg_popup(shsurf))
1886                 xdg_shell_send_ping(sc->resource, serial);
1887         else if (shell_surface_is_wl_shell_surface(shsurf))
1888                 wl_shell_surface_send_ping(shsurf->resource, serial);
1889 }
1890
1891 static void
1892 ping_handler(struct weston_surface *surface, uint32_t serial)
1893 {
1894         struct shell_surface *shsurf = get_shell_surface(surface);
1895
1896         if (!shsurf)
1897                 return;
1898         if (!shsurf->resource)
1899                 return;
1900         if (shsurf->surface == shsurf->shell->grab_surface)
1901                 return;
1902
1903         handle_xdg_ping(shsurf, serial);
1904 }
1905
1906 static void
1907 handle_pointer_focus(struct wl_listener *listener, void *data)
1908 {
1909         struct weston_pointer *pointer = data;
1910         struct weston_view *view = pointer->focus;
1911         struct weston_compositor *compositor;
1912         uint32_t serial;
1913
1914         if (!view)
1915                 return;
1916
1917         compositor = view->surface->compositor;
1918         serial = wl_display_next_serial(compositor->wl_display);
1919         ping_handler(view->surface, serial);
1920 }
1921
1922 static void
1923 create_pointer_focus_listener(struct weston_seat *seat)
1924 {
1925         struct wl_listener *listener;
1926
1927         if (!seat->pointer)
1928                 return;
1929
1930         listener = malloc(sizeof *listener);
1931         listener->notify = handle_pointer_focus;
1932         wl_signal_add(&seat->pointer->focus_signal, listener);
1933 }
1934
1935 static void
1936 shell_surface_lose_keyboard_focus(struct shell_surface *shsurf)
1937 {
1938         if (--shsurf->focus_count == 0)
1939                 if (shell_surface_is_xdg_surface(shsurf))
1940                         xdg_surface_send_deactivated(shsurf->resource);
1941 }
1942
1943 static void
1944 shell_surface_gain_keyboard_focus(struct shell_surface *shsurf)
1945 {
1946         if (shsurf->focus_count++ == 0)
1947                 if (shell_surface_is_xdg_surface(shsurf))
1948                         xdg_surface_send_activated(shsurf->resource);
1949 }
1950
1951 static void
1952 handle_keyboard_focus(struct wl_listener *listener, void *data)
1953 {
1954         struct weston_keyboard *keyboard = data;
1955         struct shell_seat *seat = get_shell_seat(keyboard->seat);
1956
1957         if (seat->focused_surface) {
1958                 struct shell_surface *shsurf = get_shell_surface(seat->focused_surface);
1959                 if (shsurf)
1960                         shell_surface_lose_keyboard_focus(shsurf);
1961         }
1962
1963         seat->focused_surface = keyboard->focus;
1964
1965         if (seat->focused_surface) {
1966                 struct shell_surface *shsurf = get_shell_surface(seat->focused_surface);
1967                 if (shsurf)
1968                         shell_surface_gain_keyboard_focus(shsurf);
1969         }
1970 }
1971
1972 static void
1973 create_keyboard_focus_listener(struct weston_seat *seat)
1974 {
1975         struct wl_listener *listener;
1976
1977         if (!seat->keyboard)
1978                 return;
1979
1980         listener = malloc(sizeof *listener);
1981         listener->notify = handle_keyboard_focus;
1982         wl_signal_add(&seat->keyboard->focus_signal, listener);
1983 }
1984
1985 static struct shell_client *
1986 get_shell_client(struct wl_client *client)
1987 {
1988         struct wl_listener *listener;
1989
1990         listener = wl_client_get_destroy_listener(client,
1991                                                   handle_shell_client_destroy);
1992         if (listener == NULL)
1993                 return NULL;
1994
1995         return container_of(listener, struct shell_client, destroy_listener);
1996 }
1997
1998 static void
1999 shell_client_pong(struct shell_client *sc, uint32_t serial)
2000 {
2001         if (sc->ping_serial != serial)
2002                 return;
2003
2004         sc->unresponsive = 0;
2005         end_busy_cursor(sc->shell->compositor, sc->client);
2006
2007         if (sc->ping_timer) {
2008                 wl_event_source_remove(sc->ping_timer);
2009                 sc->ping_timer = NULL;
2010         }
2011
2012 }
2013
2014 static void
2015 shell_surface_pong(struct wl_client *client,
2016                    struct wl_resource *resource, uint32_t serial)
2017 {
2018         struct shell_client *sc;
2019
2020         sc = get_shell_client(client);
2021         shell_client_pong(sc, serial);
2022 }
2023
2024 static void
2025 set_title(struct shell_surface *shsurf, const char *title)
2026 {
2027         free(shsurf->title);
2028         shsurf->title = strdup(title);
2029 }
2030
2031 static void
2032 shell_surface_set_title(struct wl_client *client,
2033                         struct wl_resource *resource, const char *title)
2034 {
2035         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2036
2037         set_title(shsurf, title);
2038 }
2039
2040 static void
2041 shell_surface_set_class(struct wl_client *client,
2042                         struct wl_resource *resource, const char *class)
2043 {
2044         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2045
2046         free(shsurf->class);
2047         shsurf->class = strdup(class);
2048 }
2049
2050 static void
2051 restore_output_mode(struct weston_output *output)
2052 {
2053         if (output->current_mode != output->original_mode ||
2054             (int32_t)output->current_scale != output->original_scale)
2055                 weston_output_switch_mode(output,
2056                                           output->original_mode,
2057                                           output->original_scale,
2058                                           WESTON_MODE_SWITCH_RESTORE_NATIVE);
2059 }
2060
2061 static void
2062 restore_all_output_modes(struct weston_compositor *compositor)
2063 {
2064         struct weston_output *output;
2065
2066         wl_list_for_each(output, &compositor->output_list, link)
2067                 restore_output_mode(output);
2068 }
2069
2070 static int
2071 get_output_panel_height(struct desktop_shell *shell,
2072                         struct weston_output *output)
2073 {
2074         struct weston_view *view;
2075         int panel_height = 0;
2076
2077         if (!output)
2078                 return 0;
2079
2080         wl_list_for_each(view, &shell->panel_layer.view_list, layer_link) {
2081                 if (view->surface->output == output) {
2082                         panel_height = view->surface->height;
2083                         break;
2084                 }
2085         }
2086
2087         return panel_height;
2088 }
2089
2090 /* The surface will be inserted into the list immediately after the link
2091  * returned by this function (i.e. will be stacked immediately above the
2092  * returned link). */
2093 static struct wl_list *
2094 shell_surface_calculate_layer_link (struct shell_surface *shsurf)
2095 {
2096         struct workspace *ws;
2097         struct weston_view *parent;
2098
2099         switch (shsurf->type) {
2100         case SHELL_SURFACE_POPUP:
2101         case SHELL_SURFACE_TOPLEVEL:
2102                 if (shsurf->state.fullscreen) {
2103                         return &shsurf->shell->fullscreen_layer.view_list;
2104                 } else if (shsurf->parent) {
2105                         /* Move the surface to its parent layer so
2106                          * that surfaces which are transient for
2107                          * fullscreen surfaces don't get hidden by the
2108                          * fullscreen surfaces. */
2109
2110                         /* TODO: Handle a parent with multiple views */
2111                         parent = get_default_view(shsurf->parent);
2112                         if (parent)
2113                                 return parent->layer_link.prev;
2114                 }
2115                 break;
2116
2117         case SHELL_SURFACE_XWAYLAND:
2118                 return &shsurf->shell->fullscreen_layer.view_list;
2119
2120         case SHELL_SURFACE_NONE:
2121         default:
2122                 /* Go to the fallback, below. */
2123                 break;
2124         }
2125
2126         /* Move the surface to a normal workspace layer so that surfaces
2127          * which were previously fullscreen or transient are no longer
2128          * rendered on top. */
2129         ws = get_current_workspace(shsurf->shell);
2130         return &ws->layer.view_list;
2131 }
2132
2133 static void
2134 shell_surface_update_child_surface_layers (struct shell_surface *shsurf)
2135 {
2136         struct shell_surface *child;
2137
2138         /* Move the child layers to the same workspace as shsurf. They will be
2139          * stacked above shsurf. */
2140         wl_list_for_each_reverse(child, &shsurf->children_list, children_link) {
2141                 if (shsurf->view->layer_link.prev != &child->view->layer_link) {
2142                         weston_view_geometry_dirty(child->view);
2143                         wl_list_remove(&child->view->layer_link);
2144                         wl_list_insert(shsurf->view->layer_link.prev,
2145                                        &child->view->layer_link);
2146                         weston_view_geometry_dirty(child->view);
2147                         weston_surface_damage(child->surface);
2148
2149                         /* Recurse. We don’t expect this to recurse very far (if
2150                          * at all) because that would imply we have transient
2151                          * (or popup) children of transient surfaces, which
2152                          * would be unusual. */
2153                         shell_surface_update_child_surface_layers(child);
2154                 }
2155         }
2156 }
2157
2158 /* Update the surface’s layer. Mark both the old and new views as having dirty
2159  * geometry to ensure the changes are redrawn.
2160  *
2161  * If any child surfaces exist and are mapped, ensure they’re in the same layer
2162  * as this surface. */
2163 static void
2164 shell_surface_update_layer(struct shell_surface *shsurf)
2165 {
2166         struct wl_list *new_layer_link;
2167
2168         new_layer_link = shell_surface_calculate_layer_link(shsurf);
2169
2170         if (new_layer_link == &shsurf->view->layer_link)
2171                 return;
2172
2173         weston_view_geometry_dirty(shsurf->view);
2174         wl_list_remove(&shsurf->view->layer_link);
2175         wl_list_insert(new_layer_link, &shsurf->view->layer_link);
2176         weston_view_geometry_dirty(shsurf->view);
2177         weston_surface_damage(shsurf->surface);
2178
2179         shell_surface_update_child_surface_layers(shsurf);
2180 }
2181
2182 static void
2183 shell_surface_set_parent(struct shell_surface *shsurf,
2184                          struct weston_surface *parent)
2185 {
2186         shsurf->parent = parent;
2187
2188         wl_list_remove(&shsurf->children_link);
2189         wl_list_init(&shsurf->children_link);
2190
2191         /* Insert into the parent surface’s child list. */
2192         if (parent != NULL) {
2193                 struct shell_surface *parent_shsurf = get_shell_surface(parent);
2194                 if (parent_shsurf != NULL)
2195                         wl_list_insert(&parent_shsurf->children_list,
2196                                        &shsurf->children_link);
2197         }
2198 }
2199
2200 static void
2201 shell_surface_set_output(struct shell_surface *shsurf,
2202                          struct weston_output *output)
2203 {
2204         struct weston_surface *es = shsurf->surface;
2205
2206         /* get the default output, if the client set it as NULL
2207            check whether the ouput is available */
2208         if (output)
2209                 shsurf->output = output;
2210         else if (es->output)
2211                 shsurf->output = es->output;
2212         else
2213                 shsurf->output = get_default_output(es->compositor);
2214 }
2215
2216 static void
2217 surface_clear_next_states(struct shell_surface *shsurf)
2218 {
2219         shsurf->next_state.maximized = false;
2220         shsurf->next_state.fullscreen = false;
2221
2222         if ((shsurf->next_state.maximized != shsurf->state.maximized) ||
2223             (shsurf->next_state.fullscreen != shsurf->state.fullscreen))
2224                 shsurf->state_changed = true;
2225 }
2226
2227 static void
2228 set_toplevel(struct shell_surface *shsurf)
2229 {
2230         shell_surface_set_parent(shsurf, NULL);
2231         surface_clear_next_states(shsurf);
2232         shsurf->type = SHELL_SURFACE_TOPLEVEL;
2233
2234         /* The layer_link is updated in set_surface_type(),
2235          * called from configure. */
2236 }
2237
2238 static void
2239 shell_surface_set_toplevel(struct wl_client *client,
2240                            struct wl_resource *resource)
2241 {
2242         struct shell_surface *surface = wl_resource_get_user_data(resource);
2243
2244         set_toplevel(surface);
2245 }
2246
2247 static void
2248 set_transient(struct shell_surface *shsurf,
2249               struct weston_surface *parent, int x, int y, uint32_t flags)
2250 {
2251         assert(parent != NULL);
2252
2253         shell_surface_set_parent(shsurf, parent);
2254
2255         surface_clear_next_states(shsurf);
2256
2257         shsurf->transient.x = x;
2258         shsurf->transient.y = y;
2259         shsurf->transient.flags = flags;
2260
2261         shsurf->next_state.relative = true;
2262         shsurf->state_changed = true;
2263         shsurf->type = SHELL_SURFACE_TOPLEVEL;
2264
2265         /* The layer_link is updated in set_surface_type(),
2266          * called from configure. */
2267 }
2268
2269 static void
2270 shell_surface_set_transient(struct wl_client *client,
2271                             struct wl_resource *resource,
2272                             struct wl_resource *parent_resource,
2273                             int x, int y, uint32_t flags)
2274 {
2275         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2276         struct weston_surface *parent =
2277                 wl_resource_get_user_data(parent_resource);
2278
2279         set_transient(shsurf, parent, x, y, flags);
2280 }
2281
2282 static void
2283 set_fullscreen(struct shell_surface *shsurf,
2284                uint32_t method,
2285                uint32_t framerate,
2286                struct weston_output *output)
2287 {
2288         shell_surface_set_output(shsurf, output);
2289
2290         shsurf->fullscreen_output = shsurf->output;
2291         shsurf->fullscreen.type = method;
2292         shsurf->fullscreen.framerate = framerate;
2293
2294         shsurf->type = SHELL_SURFACE_TOPLEVEL;
2295
2296         shsurf->client->send_configure(shsurf->surface, 0,
2297                                        shsurf->output->width,
2298                                        shsurf->output->height);
2299
2300         /* The layer_link is updated in set_surface_type(),
2301          * called from configure. */
2302 }
2303
2304 static void
2305 weston_view_set_initial_position(struct weston_view *view,
2306                                  struct desktop_shell *shell);
2307
2308 static void
2309 unset_fullscreen(struct shell_surface *shsurf)
2310 {
2311         /* Unset the fullscreen output, driver configuration and transforms. */
2312         if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER &&
2313             shell_surface_is_top_fullscreen(shsurf)) {
2314                 restore_output_mode(shsurf->fullscreen_output);
2315         }
2316         shsurf->fullscreen_output = NULL;
2317
2318         shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
2319         shsurf->fullscreen.framerate = 0;
2320
2321         wl_list_remove(&shsurf->fullscreen.transform.link);
2322         wl_list_init(&shsurf->fullscreen.transform.link);
2323
2324         if (shsurf->fullscreen.black_view)
2325                 weston_surface_destroy(shsurf->fullscreen.black_view->surface);
2326         shsurf->fullscreen.black_view = NULL;
2327
2328         if (shsurf->saved_position_valid)
2329                 weston_view_set_position(shsurf->view,
2330                                          shsurf->saved_x, shsurf->saved_y);
2331         else
2332                 weston_view_set_initial_position(shsurf->view, shsurf->shell);
2333
2334         if (shsurf->saved_rotation_valid) {
2335                 wl_list_insert(&shsurf->view->geometry.transformation_list,
2336                                &shsurf->rotation.transform.link);
2337                 shsurf->saved_rotation_valid = false;
2338         }
2339
2340         /* Layer is updated in set_surface_type(). */
2341 }
2342
2343 static void
2344 shell_surface_set_fullscreen(struct wl_client *client,
2345                              struct wl_resource *resource,
2346                              uint32_t method,
2347                              uint32_t framerate,
2348                              struct wl_resource *output_resource)
2349 {
2350         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2351         struct weston_output *output;
2352
2353         if (output_resource)
2354                 output = wl_resource_get_user_data(output_resource);
2355         else
2356                 output = NULL;
2357
2358         shell_surface_set_parent(shsurf, NULL);
2359
2360         surface_clear_next_states(shsurf);
2361         set_fullscreen(shsurf, method, framerate, output);
2362
2363         shsurf->next_state.fullscreen = true;
2364         shsurf->state_changed = true;
2365 }
2366
2367 static void
2368 set_popup(struct shell_surface *shsurf,
2369           struct weston_surface *parent,
2370           struct weston_seat *seat,
2371           uint32_t serial,
2372           int32_t x,
2373           int32_t y)
2374 {
2375         assert(parent != NULL);
2376
2377         shsurf->popup.shseat = get_shell_seat(seat);
2378         shsurf->popup.serial = serial;
2379         shsurf->popup.x = x;
2380         shsurf->popup.y = y;
2381
2382         shsurf->type = SHELL_SURFACE_POPUP;
2383 }
2384
2385 static void
2386 shell_surface_set_popup(struct wl_client *client,
2387                         struct wl_resource *resource,
2388                         struct wl_resource *seat_resource,
2389                         uint32_t serial,
2390                         struct wl_resource *parent_resource,
2391                         int32_t x, int32_t y, uint32_t flags)
2392 {
2393         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2394         struct weston_surface *parent =
2395                 wl_resource_get_user_data(parent_resource);
2396
2397         shell_surface_set_parent(shsurf, parent);
2398
2399         surface_clear_next_states(shsurf);
2400         set_popup(shsurf,
2401                   parent,
2402                   wl_resource_get_user_data(seat_resource),
2403                   serial, x, y);
2404 }
2405
2406 static void
2407 set_maximized(struct shell_surface *shsurf,
2408               struct weston_output *output)
2409 {
2410         struct desktop_shell *shell;
2411         uint32_t edges = 0, panel_height = 0;
2412
2413         shell_surface_set_output(shsurf, output);
2414
2415         shell = shell_surface_get_shell(shsurf);
2416         panel_height = get_output_panel_height(shell, shsurf->output);
2417         edges = WL_SHELL_SURFACE_RESIZE_TOP | WL_SHELL_SURFACE_RESIZE_LEFT;
2418
2419         shsurf->client->send_configure(shsurf->surface, edges,
2420                                        shsurf->output->width,
2421                                        shsurf->output->height - panel_height);
2422
2423         shsurf->type = SHELL_SURFACE_TOPLEVEL;
2424 }
2425
2426 static void
2427 unset_maximized(struct shell_surface *shsurf)
2428 {
2429         /* undo all maximized things here */
2430         shsurf->output = get_default_output(shsurf->surface->compositor);
2431
2432         if (shsurf->saved_position_valid)
2433                 weston_view_set_position(shsurf->view,
2434                                          shsurf->saved_x, shsurf->saved_y);
2435         else
2436                 weston_view_set_initial_position(shsurf->view, shsurf->shell);
2437
2438         if (shsurf->saved_rotation_valid) {
2439                 wl_list_insert(&shsurf->view->geometry.transformation_list,
2440                                &shsurf->rotation.transform.link);
2441                 shsurf->saved_rotation_valid = false;
2442         }
2443
2444         /* Layer is updated in set_surface_type(). */
2445 }
2446
2447 static void
2448 set_minimized(struct weston_surface *surface, uint32_t is_true)
2449 {
2450         struct shell_surface *shsurf;
2451         struct workspace *current_ws;
2452         struct weston_seat *seat;
2453         struct weston_surface *focus;
2454         struct weston_view *view;
2455
2456         view = get_default_view(surface);
2457         if (!view)
2458                 return;
2459
2460         assert(weston_surface_get_main_surface(view->surface) == view->surface);
2461
2462         shsurf = get_shell_surface(surface);
2463         current_ws = get_current_workspace(shsurf->shell);
2464
2465         wl_list_remove(&view->layer_link);
2466          /* hide or show, depending on the state */
2467         if (is_true) {
2468                 wl_list_insert(&shsurf->shell->minimized_layer.view_list, &view->layer_link);
2469
2470                 drop_focus_state(shsurf->shell, current_ws, view->surface);
2471                 wl_list_for_each(seat, &shsurf->shell->compositor->seat_list, link) {
2472                         if (!seat->keyboard)
2473                                 continue;
2474                         focus = weston_surface_get_main_surface(seat->keyboard->focus);
2475                         if (focus == view->surface)
2476                                 weston_keyboard_set_focus(seat->keyboard, NULL);
2477                 }
2478         }
2479         else {
2480                 wl_list_insert(&current_ws->layer.view_list, &view->layer_link);
2481
2482                 wl_list_for_each(seat, &shsurf->shell->compositor->seat_list, link) {
2483                         if (!seat->keyboard)
2484                                 continue;
2485                         activate(shsurf->shell, view->surface, seat);
2486                 }
2487         }
2488
2489         shell_surface_update_child_surface_layers(shsurf);
2490
2491         weston_view_damage_below(view);
2492 }
2493
2494 static void
2495 shell_surface_set_maximized(struct wl_client *client,
2496                             struct wl_resource *resource,
2497                             struct wl_resource *output_resource)
2498 {
2499         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2500         struct weston_output *output;
2501
2502         if (output_resource)
2503                 output = wl_resource_get_user_data(output_resource);
2504         else
2505                 output = NULL;
2506
2507         shell_surface_set_parent(shsurf, NULL);
2508
2509         surface_clear_next_states(shsurf);
2510         set_maximized(shsurf, output);
2511
2512         shsurf->next_state.maximized = true;
2513         shsurf->state_changed = true;
2514 }
2515
2516 /* This is only ever called from set_surface_type(), so there’s no need to
2517  * update layer_links here, since they’ll be updated when we return. */
2518 static int
2519 reset_surface_type(struct shell_surface *surface)
2520 {
2521         if (surface->state.fullscreen)
2522                 unset_fullscreen(surface);
2523         if (surface->state.maximized)
2524                 unset_maximized(surface);
2525
2526         return 0;
2527 }
2528
2529 static void
2530 set_full_output(struct shell_surface *shsurf)
2531 {
2532         shsurf->saved_x = shsurf->view->geometry.x;
2533         shsurf->saved_y = shsurf->view->geometry.y;
2534         shsurf->saved_width = shsurf->surface->width;
2535         shsurf->saved_height = shsurf->surface->height;
2536         shsurf->saved_size_valid = true;
2537         shsurf->saved_position_valid = true;
2538
2539         if (!wl_list_empty(&shsurf->rotation.transform.link)) {
2540                 wl_list_remove(&shsurf->rotation.transform.link);
2541                 wl_list_init(&shsurf->rotation.transform.link);
2542                 weston_view_geometry_dirty(shsurf->view);
2543                 shsurf->saved_rotation_valid = true;
2544         }
2545 }
2546
2547 static void
2548 set_surface_type(struct shell_surface *shsurf)
2549 {
2550         struct weston_surface *pes = shsurf->parent;
2551         struct weston_view *pev = get_default_view(pes);
2552
2553         reset_surface_type(shsurf);
2554
2555         shsurf->state = shsurf->next_state;
2556         shsurf->state_changed = false;
2557
2558         switch (shsurf->type) {
2559         case SHELL_SURFACE_TOPLEVEL:
2560                 if (shsurf->state.maximized || shsurf->state.fullscreen) {
2561                         set_full_output(shsurf);
2562                 } else if (shsurf->state.relative && pev) {
2563                         weston_view_set_position(shsurf->view,
2564                                                  pev->geometry.x + shsurf->transient.x,
2565                                                  pev->geometry.y + shsurf->transient.y);
2566                 }
2567                 break;
2568
2569         case SHELL_SURFACE_XWAYLAND:
2570                 weston_view_set_position(shsurf->view, shsurf->transient.x,
2571                                          shsurf->transient.y);
2572                 break;
2573
2574         case SHELL_SURFACE_POPUP:
2575         case SHELL_SURFACE_NONE:
2576         default:
2577                 break;
2578         }
2579
2580         /* Update the surface’s layer. */
2581         shell_surface_update_layer(shsurf);
2582 }
2583
2584 static struct desktop_shell *
2585 shell_surface_get_shell(struct shell_surface *shsurf)
2586 {
2587         return shsurf->shell;
2588 }
2589
2590 static void
2591 black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy);
2592
2593 static struct weston_view *
2594 create_black_surface(struct weston_compositor *ec,
2595                      struct weston_surface *fs_surface,
2596                      float x, float y, int w, int h)
2597 {
2598         struct weston_surface *surface = NULL;
2599         struct weston_view *view;
2600
2601         surface = weston_surface_create(ec);
2602         if (surface == NULL) {
2603                 weston_log("no memory\n");
2604                 return NULL;
2605         }
2606         view = weston_view_create(surface);
2607         if (surface == NULL) {
2608                 weston_log("no memory\n");
2609                 weston_surface_destroy(surface);
2610                 return NULL;
2611         }
2612
2613         surface->configure = black_surface_configure;
2614         surface->configure_private = fs_surface;
2615         weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1);
2616         pixman_region32_fini(&surface->opaque);
2617         pixman_region32_init_rect(&surface->opaque, 0, 0, w, h);
2618         pixman_region32_fini(&surface->input);
2619         pixman_region32_init_rect(&surface->input, 0, 0, w, h);
2620
2621         weston_surface_set_size(surface, w, h);
2622         weston_view_set_position(view, x, y);
2623
2624         return view;
2625 }
2626
2627 static void
2628 shell_ensure_fullscreen_black_view(struct shell_surface *shsurf)
2629 {
2630         struct weston_output *output = shsurf->fullscreen_output;
2631
2632         assert(shsurf->state.fullscreen);
2633
2634         if (!shsurf->fullscreen.black_view)
2635                 shsurf->fullscreen.black_view =
2636                         create_black_surface(shsurf->surface->compositor,
2637                                              shsurf->surface,
2638                                              output->x, output->y,
2639                                              output->width,
2640                                              output->height);
2641
2642         weston_view_geometry_dirty(shsurf->fullscreen.black_view);
2643         wl_list_remove(&shsurf->fullscreen.black_view->layer_link);
2644         wl_list_insert(&shsurf->view->layer_link,
2645                        &shsurf->fullscreen.black_view->layer_link);
2646         weston_view_geometry_dirty(shsurf->fullscreen.black_view);
2647         weston_surface_damage(shsurf->surface);
2648 }
2649
2650 /* Create black surface and append it to the associated fullscreen surface.
2651  * Handle size dismatch and positioning according to the method. */
2652 static void
2653 shell_configure_fullscreen(struct shell_surface *shsurf)
2654 {
2655         struct weston_output *output = shsurf->fullscreen_output;
2656         struct weston_surface *surface = shsurf->surface;
2657         struct weston_matrix *matrix;
2658         float scale, output_aspect, surface_aspect, x, y;
2659         int32_t surf_x, surf_y, surf_width, surf_height;
2660
2661         if (shsurf->fullscreen.type != WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER)
2662                 restore_output_mode(output);
2663
2664         shell_ensure_fullscreen_black_view(shsurf);
2665
2666         surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y,
2667                                         &surf_width, &surf_height);
2668
2669         switch (shsurf->fullscreen.type) {
2670         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT:
2671                 if (surface->buffer_ref.buffer)
2672                         center_on_output(shsurf->view, shsurf->fullscreen_output);
2673                 break;
2674         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE:
2675                 /* 1:1 mapping between surface and output dimensions */
2676                 if (output->width == surf_width &&
2677                         output->height == surf_height) {
2678                         weston_view_set_position(shsurf->view,
2679                                                  output->x - surf_x,
2680                                                  output->y - surf_y);
2681                         break;
2682                 }
2683
2684                 matrix = &shsurf->fullscreen.transform.matrix;
2685                 weston_matrix_init(matrix);
2686
2687                 output_aspect = (float) output->width /
2688                         (float) output->height;
2689                 /* XXX: Use surf_width and surf_height here? */
2690                 surface_aspect = (float) surface->width /
2691                         (float) surface->height;
2692                 if (output_aspect < surface_aspect)
2693                         scale = (float) output->width /
2694                                 (float) surf_width;
2695                 else
2696                         scale = (float) output->height /
2697                                 (float) surf_height;
2698
2699                 weston_matrix_scale(matrix, scale, scale, 1);
2700                 wl_list_remove(&shsurf->fullscreen.transform.link);
2701                 wl_list_insert(&shsurf->view->geometry.transformation_list,
2702                                &shsurf->fullscreen.transform.link);
2703                 x = output->x + (output->width - surf_width * scale) / 2 - surf_x;
2704                 y = output->y + (output->height - surf_height * scale) / 2 - surf_y;
2705                 weston_view_set_position(shsurf->view, x, y);
2706
2707                 break;
2708         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER:
2709                 if (shell_surface_is_top_fullscreen(shsurf)) {
2710                         struct weston_mode mode = {0,
2711                                 surf_width * surface->buffer_viewport.buffer.scale,
2712                                 surf_height * surface->buffer_viewport.buffer.scale,
2713                                 shsurf->fullscreen.framerate};
2714
2715                         if (weston_output_switch_mode(output, &mode, surface->buffer_viewport.buffer.scale,
2716                                         WESTON_MODE_SWITCH_SET_TEMPORARY) == 0) {
2717                                 weston_view_set_position(shsurf->view,
2718                                                          output->x - surf_x,
2719                                                          output->y - surf_y);
2720                                 shsurf->fullscreen.black_view->surface->width = output->width;
2721                                 shsurf->fullscreen.black_view->surface->height = output->height;
2722                                 weston_view_set_position(shsurf->fullscreen.black_view,
2723                                                          output->x - surf_x,
2724                                                          output->y - surf_y);
2725                                 break;
2726                         } else {
2727                                 restore_output_mode(output);
2728                                 center_on_output(shsurf->view, output);
2729                         }
2730                 }
2731                 break;
2732         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL:
2733                 center_on_output(shsurf->view, output);
2734                 break;
2735         default:
2736                 break;
2737         }
2738 }
2739
2740 static void
2741 shell_map_fullscreen(struct shell_surface *shsurf)
2742 {
2743         shell_configure_fullscreen(shsurf);
2744 }
2745
2746 static void
2747 set_xwayland(struct shell_surface *shsurf, int x, int y, uint32_t flags)
2748 {
2749         /* XXX: using the same fields for transient type */
2750         surface_clear_next_states(shsurf);
2751         shsurf->transient.x = x;
2752         shsurf->transient.y = y;
2753         shsurf->transient.flags = flags;
2754
2755         shell_surface_set_parent(shsurf, NULL);
2756
2757         shsurf->type = SHELL_SURFACE_XWAYLAND;
2758         shsurf->state_changed = true;
2759 }
2760
2761 static const struct weston_pointer_grab_interface popup_grab_interface;
2762
2763 static void
2764 destroy_shell_seat(struct wl_listener *listener, void *data)
2765 {
2766         struct shell_seat *shseat =
2767                 container_of(listener,
2768                              struct shell_seat, seat_destroy_listener);
2769         struct shell_surface *shsurf, *prev = NULL;
2770
2771         if (shseat->popup_grab.grab.interface == &popup_grab_interface) {
2772                 weston_pointer_end_grab(shseat->popup_grab.grab.pointer);
2773                 shseat->popup_grab.client = NULL;
2774
2775                 wl_list_for_each(shsurf, &shseat->popup_grab.surfaces_list, popup.grab_link) {
2776                         shsurf->popup.shseat = NULL;
2777                         if (prev) {
2778                                 wl_list_init(&prev->popup.grab_link);
2779                         }
2780                         prev = shsurf;
2781                 }
2782                 wl_list_init(&prev->popup.grab_link);
2783         }
2784
2785         wl_list_remove(&shseat->seat_destroy_listener.link);
2786         free(shseat);
2787 }
2788
2789 static struct shell_seat *
2790 create_shell_seat(struct weston_seat *seat)
2791 {
2792         struct shell_seat *shseat;
2793
2794         shseat = calloc(1, sizeof *shseat);
2795         if (!shseat) {
2796                 weston_log("no memory to allocate shell seat\n");
2797                 return NULL;
2798         }
2799
2800         shseat->seat = seat;
2801         wl_list_init(&shseat->popup_grab.surfaces_list);
2802
2803         shseat->seat_destroy_listener.notify = destroy_shell_seat;
2804         wl_signal_add(&seat->destroy_signal,
2805                       &shseat->seat_destroy_listener);
2806
2807         return shseat;
2808 }
2809
2810 static struct shell_seat *
2811 get_shell_seat(struct weston_seat *seat)
2812 {
2813         struct wl_listener *listener;
2814
2815         listener = wl_signal_get(&seat->destroy_signal, destroy_shell_seat);
2816         if (listener == NULL)
2817                 return create_shell_seat(seat);
2818
2819         return container_of(listener,
2820                             struct shell_seat, seat_destroy_listener);
2821 }
2822
2823 static void
2824 popup_grab_focus(struct weston_pointer_grab *grab)
2825 {
2826         struct weston_pointer *pointer = grab->pointer;
2827         struct weston_view *view;
2828         struct shell_seat *shseat =
2829             container_of(grab, struct shell_seat, popup_grab.grab);
2830         struct wl_client *client = shseat->popup_grab.client;
2831         wl_fixed_t sx, sy;
2832
2833         view = weston_compositor_pick_view(pointer->seat->compositor,
2834                                            pointer->x, pointer->y,
2835                                            &sx, &sy);
2836
2837         if (view && view->surface->resource &&
2838             wl_resource_get_client(view->surface->resource) == client) {
2839                 weston_pointer_set_focus(pointer, view, sx, sy);
2840         } else {
2841                 weston_pointer_set_focus(pointer, NULL,
2842                                          wl_fixed_from_int(0),
2843                                          wl_fixed_from_int(0));
2844         }
2845 }
2846
2847 static void
2848 popup_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
2849                   wl_fixed_t x, wl_fixed_t y)
2850 {
2851         struct weston_pointer *pointer = grab->pointer;
2852         struct wl_resource *resource;
2853         wl_fixed_t sx, sy;
2854
2855         weston_pointer_move(pointer, x, y);
2856
2857         wl_resource_for_each(resource, &pointer->focus_resource_list) {
2858                 weston_view_from_global_fixed(pointer->focus,
2859                                               pointer->x, pointer->y,
2860                                               &sx, &sy);
2861                 wl_pointer_send_motion(resource, time, sx, sy);
2862         }
2863 }
2864
2865 static void
2866 popup_grab_button(struct weston_pointer_grab *grab,
2867                   uint32_t time, uint32_t button, uint32_t state_w)
2868 {
2869         struct wl_resource *resource;
2870         struct shell_seat *shseat =
2871             container_of(grab, struct shell_seat, popup_grab.grab);
2872         struct wl_display *display = shseat->seat->compositor->wl_display;
2873         enum wl_pointer_button_state state = state_w;
2874         uint32_t serial;
2875         struct wl_list *resource_list;
2876
2877         resource_list = &grab->pointer->focus_resource_list;
2878         if (!wl_list_empty(resource_list)) {
2879                 serial = wl_display_get_serial(display);
2880                 wl_resource_for_each(resource, resource_list) {
2881                         wl_pointer_send_button(resource, serial,
2882                                                time, button, state);
2883                 }
2884         } else if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
2885                    (shseat->popup_grab.initial_up ||
2886                     time - shseat->seat->pointer->grab_time > 500)) {
2887                 popup_grab_end(grab->pointer);
2888         }
2889
2890         if (state == WL_POINTER_BUTTON_STATE_RELEASED)
2891                 shseat->popup_grab.initial_up = 1;
2892 }
2893
2894 static void
2895 popup_grab_cancel(struct weston_pointer_grab *grab)
2896 {
2897         popup_grab_end(grab->pointer);
2898 }
2899
2900 static const struct weston_pointer_grab_interface popup_grab_interface = {
2901         popup_grab_focus,
2902         popup_grab_motion,
2903         popup_grab_button,
2904         popup_grab_cancel,
2905 };
2906
2907 static void
2908 shell_surface_send_popup_done(struct shell_surface *shsurf)
2909 {
2910         if (shell_surface_is_wl_shell_surface(shsurf))
2911                 wl_shell_surface_send_popup_done(shsurf->resource);
2912         else if (shell_surface_is_xdg_popup(shsurf))
2913                 xdg_popup_send_popup_done(shsurf->resource,
2914                                           shsurf->popup.serial);
2915 }
2916
2917 static void
2918 popup_grab_end(struct weston_pointer *pointer)
2919 {
2920         struct weston_pointer_grab *grab = pointer->grab;
2921         struct shell_seat *shseat =
2922             container_of(grab, struct shell_seat, popup_grab.grab);
2923         struct shell_surface *shsurf;
2924         struct shell_surface *prev = NULL;
2925
2926         if (pointer->grab->interface == &popup_grab_interface) {
2927                 weston_pointer_end_grab(grab->pointer);
2928                 shseat->popup_grab.client = NULL;
2929                 shseat->popup_grab.grab.interface = NULL;
2930                 assert(!wl_list_empty(&shseat->popup_grab.surfaces_list));
2931                 /* Send the popup_done event to all the popups open */
2932                 wl_list_for_each(shsurf, &shseat->popup_grab.surfaces_list, popup.grab_link) {
2933                         shell_surface_send_popup_done(shsurf);
2934                         shsurf->popup.shseat = NULL;
2935                         if (prev) {
2936                                 wl_list_init(&prev->popup.grab_link);
2937                         }
2938                         prev = shsurf;
2939                 }
2940                 wl_list_init(&prev->popup.grab_link);
2941                 wl_list_init(&shseat->popup_grab.surfaces_list);
2942         }
2943 }
2944
2945 static void
2946 add_popup_grab(struct shell_surface *shsurf, struct shell_seat *shseat)
2947 {
2948         struct weston_seat *seat = shseat->seat;
2949
2950         if (wl_list_empty(&shseat->popup_grab.surfaces_list)) {
2951                 shseat->popup_grab.client = wl_resource_get_client(shsurf->resource);
2952                 shseat->popup_grab.grab.interface = &popup_grab_interface;
2953                 /* We must make sure here that this popup was opened after
2954                  * a mouse press, and not just by moving around with other
2955                  * popups already open. */
2956                 if (shseat->seat->pointer->button_count > 0)
2957                         shseat->popup_grab.initial_up = 0;
2958
2959                 wl_list_insert(&shseat->popup_grab.surfaces_list, &shsurf->popup.grab_link);
2960                 weston_pointer_start_grab(seat->pointer, &shseat->popup_grab.grab);
2961         } else {
2962                 wl_list_insert(&shseat->popup_grab.surfaces_list, &shsurf->popup.grab_link);
2963         }
2964 }
2965
2966 static void
2967 remove_popup_grab(struct shell_surface *shsurf)
2968 {
2969         struct shell_seat *shseat = shsurf->popup.shseat;
2970
2971         wl_list_remove(&shsurf->popup.grab_link);
2972         wl_list_init(&shsurf->popup.grab_link);
2973         if (wl_list_empty(&shseat->popup_grab.surfaces_list)) {
2974                 weston_pointer_end_grab(shseat->popup_grab.grab.pointer);
2975                 shseat->popup_grab.grab.interface = NULL;
2976         }
2977 }
2978
2979 static void
2980 shell_map_popup(struct shell_surface *shsurf)
2981 {
2982         struct shell_seat *shseat = shsurf->popup.shseat;
2983         struct weston_view *parent_view = get_default_view(shsurf->parent);
2984
2985         shsurf->surface->output = parent_view->output;
2986         shsurf->view->output = parent_view->output;
2987
2988         weston_view_set_transform_parent(shsurf->view, parent_view);
2989         weston_view_set_position(shsurf->view, shsurf->popup.x, shsurf->popup.y);
2990         weston_view_update_transform(shsurf->view);
2991
2992         if (shseat->seat->pointer->grab_serial == shsurf->popup.serial) {
2993                 add_popup_grab(shsurf, shseat);
2994         } else {
2995                 shell_surface_send_popup_done(shsurf);
2996                 shseat->popup_grab.client = NULL;
2997         }
2998 }
2999
3000 static const struct wl_shell_surface_interface shell_surface_implementation = {
3001         shell_surface_pong,
3002         shell_surface_move,
3003         shell_surface_resize,
3004         shell_surface_set_toplevel,
3005         shell_surface_set_transient,
3006         shell_surface_set_fullscreen,
3007         shell_surface_set_popup,
3008         shell_surface_set_maximized,
3009         shell_surface_set_title,
3010         shell_surface_set_class
3011 };
3012
3013 static void
3014 destroy_shell_surface(struct shell_surface *shsurf)
3015 {
3016         struct shell_surface *child, *next;
3017
3018         wl_signal_emit(&shsurf->destroy_signal, shsurf);
3019
3020         if (!wl_list_empty(&shsurf->popup.grab_link)) {
3021                 remove_popup_grab(shsurf);
3022         }
3023
3024         if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER &&
3025             shell_surface_is_top_fullscreen(shsurf))
3026                 restore_output_mode (shsurf->fullscreen_output);
3027
3028         if (shsurf->fullscreen.black_view)
3029                 weston_surface_destroy(shsurf->fullscreen.black_view->surface);
3030
3031         /* As destroy_resource() use wl_list_for_each_safe(),
3032          * we can always remove the listener.
3033          */
3034         wl_list_remove(&shsurf->surface_destroy_listener.link);
3035         shsurf->surface->configure = NULL;
3036         free(shsurf->title);
3037
3038         weston_view_destroy(shsurf->view);
3039
3040         wl_list_remove(&shsurf->children_link);
3041         wl_list_for_each_safe(child, next, &shsurf->children_list, children_link)
3042                 shell_surface_set_parent(child, NULL);
3043
3044         wl_list_remove(&shsurf->link);
3045         free(shsurf);
3046 }
3047
3048 static void
3049 shell_destroy_shell_surface(struct wl_resource *resource)
3050 {
3051         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3052
3053         shsurf->resource = NULL;
3054 }
3055
3056 static void
3057 shell_handle_surface_destroy(struct wl_listener *listener, void *data)
3058 {
3059         struct shell_surface *shsurf = container_of(listener,
3060                                                     struct shell_surface,
3061                                                     surface_destroy_listener);
3062
3063         if (shsurf->resource)
3064                 wl_resource_destroy(shsurf->resource);
3065         else
3066                 destroy_shell_surface(shsurf);
3067 }
3068
3069 static void
3070 fade_out_done(struct weston_view_animation *animation, void *data)
3071 {
3072         struct shell_surface *shsurf = data;
3073
3074         weston_surface_destroy(shsurf->surface);
3075 }
3076
3077 static void
3078 handle_resource_destroy(struct wl_listener *listener, void *data)
3079 {
3080         struct shell_surface *shsurf =
3081                 container_of(listener, struct shell_surface,
3082                              resource_destroy_listener);
3083
3084         shsurf->surface->ref_count++;
3085
3086         pixman_region32_fini(&shsurf->surface->pending.input);
3087         pixman_region32_init(&shsurf->surface->pending.input);
3088         pixman_region32_fini(&shsurf->surface->input);
3089         pixman_region32_init(&shsurf->surface->input);
3090         if (weston_surface_is_mapped(shsurf->surface))
3091                 weston_fade_run(shsurf->view, 1.0, 0.0, 300.0,
3092                                 fade_out_done, shsurf);
3093 }
3094
3095 static void
3096 shell_surface_configure(struct weston_surface *, int32_t, int32_t);
3097
3098 struct shell_surface *
3099 get_shell_surface(struct weston_surface *surface)
3100 {
3101         if (surface->configure == shell_surface_configure)
3102                 return surface->configure_private;
3103         else
3104                 return NULL;
3105 }
3106
3107 static struct shell_surface *
3108 create_common_surface(void *shell, struct weston_surface *surface,
3109                       const struct weston_shell_client *client)
3110 {
3111         struct shell_surface *shsurf;
3112
3113         if (surface->configure) {
3114                 weston_log("surface->configure already set\n");
3115                 return NULL;
3116         }
3117
3118         shsurf = calloc(1, sizeof *shsurf);
3119         if (!shsurf) {
3120                 weston_log("no memory to allocate shell surface\n");
3121                 return NULL;
3122         }
3123
3124         shsurf->view = weston_view_create(surface);
3125         if (!shsurf->view) {
3126                 weston_log("no memory to allocate shell surface\n");
3127                 free(shsurf);
3128                 return NULL;
3129         }
3130
3131         surface->configure = shell_surface_configure;
3132         surface->configure_private = shsurf;
3133
3134         shsurf->resource_destroy_listener.notify = handle_resource_destroy;
3135         wl_resource_add_destroy_listener(surface->resource,
3136                                          &shsurf->resource_destroy_listener);
3137
3138         shsurf->shell = (struct desktop_shell *) shell;
3139         shsurf->unresponsive = 0;
3140         shsurf->saved_position_valid = false;
3141         shsurf->saved_size_valid = false;
3142         shsurf->saved_rotation_valid = false;
3143         shsurf->surface = surface;
3144         shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
3145         shsurf->fullscreen.framerate = 0;
3146         shsurf->fullscreen.black_view = NULL;
3147         wl_list_init(&shsurf->fullscreen.transform.link);
3148
3149         wl_signal_init(&shsurf->destroy_signal);
3150         shsurf->surface_destroy_listener.notify = shell_handle_surface_destroy;
3151         wl_signal_add(&surface->destroy_signal,
3152                       &shsurf->surface_destroy_listener);
3153
3154         /* init link so its safe to always remove it in destroy_shell_surface */
3155         wl_list_init(&shsurf->link);
3156         wl_list_init(&shsurf->popup.grab_link);
3157
3158         /* empty when not in use */
3159         wl_list_init(&shsurf->rotation.transform.link);
3160         weston_matrix_init(&shsurf->rotation.rotation);
3161
3162         wl_list_init(&shsurf->workspace_transform.link);
3163
3164         wl_list_init(&shsurf->children_link);
3165         wl_list_init(&shsurf->children_list);
3166         shsurf->parent = NULL;
3167
3168         shsurf->type = SHELL_SURFACE_NONE;
3169
3170         shsurf->client = client;
3171
3172         return shsurf;
3173 }
3174
3175 static struct shell_surface *
3176 create_shell_surface(void *shell, struct weston_surface *surface,
3177                      const struct weston_shell_client *client)
3178 {
3179         return create_common_surface(shell, surface, client);
3180 }
3181
3182 static struct weston_view *
3183 get_primary_view(void *shell, struct shell_surface *shsurf)
3184 {
3185         return shsurf->view;
3186 }
3187
3188 static void
3189 shell_get_shell_surface(struct wl_client *client,
3190                         struct wl_resource *resource,
3191                         uint32_t id,
3192                         struct wl_resource *surface_resource)
3193 {
3194         struct weston_surface *surface =
3195                 wl_resource_get_user_data(surface_resource);
3196         struct desktop_shell *shell = wl_resource_get_user_data(resource);
3197         struct shell_surface *shsurf;
3198
3199         if (get_shell_surface(surface)) {
3200                 wl_resource_post_error(surface_resource,
3201                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3202                                        "desktop_shell::get_shell_surface already requested");
3203                 return;
3204         }
3205
3206         shsurf = create_shell_surface(shell, surface, &shell_client);
3207         if (!shsurf) {
3208                 wl_resource_post_error(surface_resource,
3209                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3210                                        "surface->configure already set");
3211                 return;
3212         }
3213
3214         shsurf->resource =
3215                 wl_resource_create(client,
3216                                    &wl_shell_surface_interface, 1, id);
3217         wl_resource_set_implementation(shsurf->resource,
3218                                        &shell_surface_implementation,
3219                                        shsurf, shell_destroy_shell_surface);
3220 }
3221
3222 static bool
3223 shell_surface_is_wl_shell_surface(struct shell_surface *shsurf)
3224 {
3225         /* A shell surface without a resource is created from xwayland
3226          * and is considered a wl_shell surface for now. */
3227
3228         return shsurf->resource == NULL ||
3229                 wl_resource_instance_of(shsurf->resource,
3230                                         &wl_shell_surface_interface,
3231                                         &shell_surface_implementation);
3232 }
3233
3234 static const struct wl_shell_interface shell_implementation = {
3235         shell_get_shell_surface
3236 };
3237
3238 /****************************
3239  * xdg-shell implementation */
3240
3241 static void
3242 xdg_surface_destroy(struct wl_client *client,
3243                     struct wl_resource *resource)
3244 {
3245         wl_resource_destroy(resource);
3246 }
3247
3248 static void
3249 xdg_surface_set_transient_for(struct wl_client *client,
3250                              struct wl_resource *resource,
3251                              struct wl_resource *parent_resource)
3252 {
3253         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3254         struct weston_surface *parent;
3255
3256         if (parent_resource)
3257                 parent = wl_resource_get_user_data(parent_resource);
3258         else
3259                 parent = NULL;
3260
3261         shell_surface_set_parent(shsurf, parent);
3262 }
3263
3264 static void
3265 xdg_surface_set_margin(struct wl_client *client,
3266                              struct wl_resource *resource,
3267                              int32_t left,
3268                              int32_t right,
3269                              int32_t top,
3270                              int32_t bottom)
3271 {
3272         /* Do nothing, Weston doesn't try to constrain or place
3273          * surfaces in any special manner... */
3274 }
3275
3276 static void
3277 xdg_surface_set_app_id(struct wl_client *client,
3278                        struct wl_resource *resource,
3279                        const char *app_id)
3280 {
3281         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3282
3283         free(shsurf->class);
3284         shsurf->class = strdup(app_id);
3285 }
3286
3287 static void
3288 xdg_surface_set_title(struct wl_client *client,
3289                         struct wl_resource *resource, const char *title)
3290 {
3291         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3292
3293         set_title(shsurf, title);
3294 }
3295
3296 static void
3297 xdg_surface_move(struct wl_client *client, struct wl_resource *resource,
3298                  struct wl_resource *seat_resource, uint32_t serial)
3299 {
3300         common_surface_move(resource, seat_resource, serial);
3301 }
3302
3303 static void
3304 xdg_surface_resize(struct wl_client *client, struct wl_resource *resource,
3305                    struct wl_resource *seat_resource, uint32_t serial,
3306                    uint32_t edges)
3307 {
3308         common_surface_resize(resource, seat_resource, serial, edges);
3309 }
3310
3311 static void
3312 xdg_surface_set_output(struct wl_client *client,
3313                        struct wl_resource *resource,
3314                        struct wl_resource *output_resource)
3315 {
3316         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3317         struct weston_output *output;
3318
3319         if (output_resource)
3320                 output = wl_resource_get_user_data(output_resource);
3321         else
3322                 output = NULL;
3323
3324         shsurf->recommended_output = output;
3325 }
3326
3327 static void
3328 xdg_surface_change_state(struct shell_surface *shsurf,
3329                          uint32_t state, uint32_t value, uint32_t serial)
3330 {
3331         xdg_surface_send_change_state(shsurf->resource, state, value, serial);
3332         shsurf->state_requested = true;
3333
3334         switch (state) {
3335         case XDG_SURFACE_STATE_MAXIMIZED:
3336                 shsurf->requested_state.maximized = value;
3337                 if (value)
3338                         set_maximized(shsurf, NULL);
3339                 break;
3340         case XDG_SURFACE_STATE_FULLSCREEN:
3341                 shsurf->requested_state.fullscreen = value;
3342
3343                 if (value)
3344                         set_fullscreen(shsurf,
3345                                        WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
3346                                        0, shsurf->recommended_output);
3347                 break;
3348         }
3349 }
3350
3351 static void
3352 xdg_surface_request_change_state(struct wl_client *client,
3353                                  struct wl_resource *resource,
3354                                  uint32_t state,
3355                                  uint32_t value,
3356                                  uint32_t serial)
3357 {
3358         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3359
3360         /* The client can't know what the current state is, so we need
3361            to always send a state change in response. */
3362
3363         if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
3364                 return;
3365
3366         switch (state) {
3367         case XDG_SURFACE_STATE_MAXIMIZED:
3368         case XDG_SURFACE_STATE_FULLSCREEN:
3369                 break;
3370         default:
3371                 /* send error? ignore? send change state with value 0? */
3372                 return;
3373         }
3374
3375         xdg_surface_change_state(shsurf, state, value, serial);
3376 }
3377
3378 static void
3379 xdg_surface_ack_change_state(struct wl_client *client,
3380                              struct wl_resource *resource,
3381                              uint32_t state,
3382                              uint32_t value,
3383                              uint32_t serial)
3384 {
3385         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3386
3387         if (shsurf->state_requested) {
3388                 shsurf->next_state = shsurf->requested_state;
3389                 shsurf->state_changed = true;
3390                 shsurf->state_requested = false;
3391         }
3392 }
3393
3394 static void
3395 xdg_surface_set_minimized(struct wl_client *client,
3396                             struct wl_resource *resource)
3397 {
3398         struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3399
3400         if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
3401                 return;
3402
3403          /* apply compositor's own minimization logic (hide) */
3404         set_minimized(shsurf->surface, 1);
3405 }
3406
3407 static const struct xdg_surface_interface xdg_surface_implementation = {
3408         xdg_surface_destroy,
3409         xdg_surface_set_transient_for,
3410         xdg_surface_set_margin,
3411         xdg_surface_set_title,
3412         xdg_surface_set_app_id,
3413         xdg_surface_move,
3414         xdg_surface_resize,
3415         xdg_surface_set_output,
3416         xdg_surface_request_change_state,
3417         xdg_surface_ack_change_state,
3418         xdg_surface_set_minimized
3419 };
3420
3421 static void
3422 xdg_send_configure(struct weston_surface *surface,
3423                uint32_t edges, int32_t width, int32_t height)
3424 {
3425         struct shell_surface *shsurf = get_shell_surface(surface);
3426
3427         assert(shsurf);
3428
3429         xdg_surface_send_configure(shsurf->resource, width, height);
3430 }
3431
3432 static const struct weston_shell_client xdg_client = {
3433         xdg_send_configure
3434 };
3435
3436 static void
3437 xdg_use_unstable_version(struct wl_client *client,
3438                          struct wl_resource *resource,
3439                          int32_t version)
3440 {
3441         if (version > 1) {
3442                 wl_resource_post_error(resource,
3443                                        1,
3444                                        "xdg-shell:: version not implemented yet.");
3445                 return;
3446         }
3447 }
3448
3449 static struct shell_surface *
3450 create_xdg_surface(void *shell, struct weston_surface *surface,
3451                    const struct weston_shell_client *client)
3452 {
3453         struct shell_surface *shsurf;
3454
3455         shsurf = create_common_surface(shell, surface, client);
3456         shsurf->type = SHELL_SURFACE_TOPLEVEL;
3457
3458         return shsurf;
3459 }
3460
3461 static void
3462 xdg_get_xdg_surface(struct wl_client *client,
3463                     struct wl_resource *resource,
3464                     uint32_t id,
3465                     struct wl_resource *surface_resource)
3466 {
3467         struct weston_surface *surface =
3468                 wl_resource_get_user_data(surface_resource);
3469         struct shell_client *sc = wl_resource_get_user_data(resource);
3470         struct desktop_shell *shell = sc->shell;
3471         struct shell_surface *shsurf;
3472
3473         if (get_shell_surface(surface)) {
3474                 wl_resource_post_error(surface_resource,
3475                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3476                                        "xdg_shell::get_xdg_surface already requested");
3477                 return;
3478         }
3479
3480         shsurf = create_xdg_surface(shell, surface, &xdg_client);
3481         if (!shsurf) {
3482                 wl_resource_post_error(surface_resource,
3483                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3484                                        "surface->configure already set");
3485                 return;
3486         }
3487
3488         shsurf->resource =
3489                 wl_resource_create(client,
3490                                    &xdg_surface_interface, 1, id);
3491         wl_resource_set_implementation(shsurf->resource,
3492                                        &xdg_surface_implementation,
3493                                        shsurf, shell_destroy_shell_surface);
3494 }
3495
3496 static bool
3497 shell_surface_is_xdg_surface(struct shell_surface *shsurf)
3498 {
3499         return shsurf->resource &&
3500                 wl_resource_instance_of(shsurf->resource,
3501                                         &xdg_surface_interface,
3502                                         &xdg_surface_implementation);
3503 }
3504
3505 /* xdg-popup implementation */
3506
3507 static void
3508 xdg_popup_destroy(struct wl_client *client,
3509                   struct wl_resource *resource)
3510 {
3511         wl_resource_destroy(resource);
3512 }
3513
3514 static const struct xdg_popup_interface xdg_popup_implementation = {
3515         xdg_popup_destroy,
3516 };
3517
3518 static void
3519 xdg_popup_send_configure(struct weston_surface *surface,
3520                          uint32_t edges, int32_t width, int32_t height)
3521 {
3522 }
3523
3524 static const struct weston_shell_client xdg_popup_client = {
3525         xdg_popup_send_configure
3526 };
3527
3528 static struct shell_surface *
3529 create_xdg_popup(void *shell, struct weston_surface *surface,
3530                  const struct weston_shell_client *client,
3531                  struct weston_surface *parent,
3532                  struct shell_seat *seat,
3533                  uint32_t serial,
3534                  int32_t x, int32_t y)
3535 {
3536         struct shell_surface *shsurf;
3537
3538         shsurf = create_common_surface(shell, surface, client);
3539         shsurf->type = SHELL_SURFACE_POPUP;
3540         shsurf->popup.shseat = seat;
3541         shsurf->popup.serial = serial;
3542         shsurf->popup.x = x;
3543         shsurf->popup.y = y;
3544         shell_surface_set_parent(shsurf, parent);
3545
3546         return shsurf;
3547 }
3548
3549 static void
3550 xdg_get_xdg_popup(struct wl_client *client,
3551                   struct wl_resource *resource,
3552                   uint32_t id,
3553                   struct wl_resource *surface_resource,
3554                   struct wl_resource *parent_resource,
3555                   struct wl_resource *seat_resource,
3556                   uint32_t serial,
3557                   int32_t x, int32_t y, uint32_t flags)
3558 {
3559         struct weston_surface *surface =
3560                 wl_resource_get_user_data(surface_resource);
3561         struct shell_client *sc = wl_resource_get_user_data(resource);
3562         struct desktop_shell *shell = sc->shell;
3563         struct shell_surface *shsurf;
3564         struct weston_surface *parent;
3565         struct shell_seat *seat;
3566
3567         if (get_shell_surface(surface)) {
3568                 wl_resource_post_error(surface_resource,
3569                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3570                                        "xdg_shell::get_xdg_popup already requested");
3571                 return;
3572         }
3573
3574         if (!parent_resource) {
3575                 wl_resource_post_error(surface_resource,
3576                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3577                                        "xdg_shell::get_xdg_popup requires a parent shell surface");
3578         }
3579
3580         parent = wl_resource_get_user_data(parent_resource);
3581         seat = get_shell_seat(wl_resource_get_user_data(seat_resource));;
3582
3583         shsurf = create_xdg_popup(shell, surface, &xdg_popup_client,
3584                                   parent, seat, serial, x, y);
3585         if (!shsurf) {
3586                 wl_resource_post_error(surface_resource,
3587                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3588                                        "surface->configure already set");
3589                 return;
3590         }
3591
3592         shsurf->resource =
3593                 wl_resource_create(client,
3594                                    &xdg_popup_interface, 1, id);
3595         wl_resource_set_implementation(shsurf->resource,
3596                                        &xdg_popup_implementation,
3597                                        shsurf, shell_destroy_shell_surface);
3598 }
3599
3600 static void
3601 xdg_pong(struct wl_client *client,
3602          struct wl_resource *resource, uint32_t serial)
3603 {
3604         struct shell_client *sc = wl_resource_get_user_data(resource);
3605
3606         shell_client_pong(sc, serial);
3607 }
3608
3609 static bool
3610 shell_surface_is_xdg_popup(struct shell_surface *shsurf)
3611 {
3612         return wl_resource_instance_of(shsurf->resource,
3613                                        &xdg_popup_interface,
3614                                        &xdg_popup_implementation);
3615 }
3616
3617 static const struct xdg_shell_interface xdg_implementation = {
3618         xdg_use_unstable_version,
3619         xdg_get_xdg_surface,
3620         xdg_get_xdg_popup,
3621         xdg_pong
3622 };
3623
3624 static int
3625 xdg_shell_unversioned_dispatch(const void *implementation,
3626                                void *_target, uint32_t opcode,
3627                                const struct wl_message *message,
3628                                union wl_argument *args)
3629 {
3630         struct wl_resource *resource = _target;
3631         struct shell_client *sc = wl_resource_get_user_data(resource);
3632
3633         if (opcode != 0) {
3634                 wl_resource_post_error(resource,
3635                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3636                                        "must call use_unstable_version first");
3637                 return 0;
3638         }
3639
3640 #define XDG_SERVER_VERSION 3
3641
3642         static_assert(XDG_SERVER_VERSION == XDG_SHELL_VERSION_CURRENT,
3643                       "shell implementation doesn't match protocol version");
3644
3645         if (args[0].i != XDG_SERVER_VERSION) {
3646                 wl_resource_post_error(resource,
3647                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3648                                        "incompatible version, server is %d "
3649                                        "client wants %d",
3650                                        XDG_SERVER_VERSION, args[0].i);
3651                 return 0;
3652         }
3653
3654         wl_resource_set_implementation(resource, &xdg_implementation,
3655                                        sc, NULL);
3656
3657         return 1;
3658 }
3659
3660 /* end of xdg-shell implementation */
3661 /***********************************/
3662
3663 static void
3664 shell_fade(struct desktop_shell *shell, enum fade_type type);
3665
3666 static int
3667 screensaver_timeout(void *data)
3668 {
3669         struct desktop_shell *shell = data;
3670
3671         shell_fade(shell, FADE_OUT);
3672
3673         return 1;
3674 }
3675
3676 static void
3677 handle_screensaver_sigchld(struct weston_process *proc, int status)
3678 {
3679         struct desktop_shell *shell =
3680                 container_of(proc, struct desktop_shell, screensaver.process);
3681
3682         proc->pid = 0;
3683
3684         if (shell->locked)
3685                 weston_compositor_sleep(shell->compositor);
3686 }
3687
3688 static void
3689 launch_screensaver(struct desktop_shell *shell)
3690 {
3691         if (shell->screensaver.binding)
3692                 return;
3693
3694         if (!shell->screensaver.path) {
3695                 weston_compositor_sleep(shell->compositor);
3696                 return;
3697         }
3698
3699         if (shell->screensaver.process.pid != 0) {
3700                 weston_log("old screensaver still running\n");
3701                 return;
3702         }
3703
3704         weston_client_launch(shell->compositor,
3705                            &shell->screensaver.process,
3706                            shell->screensaver.path,
3707                            handle_screensaver_sigchld);
3708 }
3709
3710 static void
3711 terminate_screensaver(struct desktop_shell *shell)
3712 {
3713         if (shell->screensaver.process.pid == 0)
3714                 return;
3715
3716         kill(shell->screensaver.process.pid, SIGTERM);
3717 }
3718
3719 static void
3720 configure_static_view(struct weston_view *ev, struct weston_layer *layer)
3721 {
3722         struct weston_view *v, *next;
3723
3724         wl_list_for_each_safe(v, next, &layer->view_list, layer_link) {
3725                 if (v->output == ev->output && v != ev) {
3726                         weston_view_unmap(v);
3727                         v->surface->configure = NULL;
3728                 }
3729         }
3730
3731         weston_view_set_position(ev, ev->output->x, ev->output->y);
3732
3733         if (wl_list_empty(&ev->layer_link)) {
3734                 wl_list_insert(&layer->view_list, &ev->layer_link);
3735                 weston_compositor_schedule_repaint(ev->surface->compositor);
3736         }
3737 }
3738
3739 static void
3740 background_configure(struct weston_surface *es, int32_t sx, int32_t sy)
3741 {
3742         struct desktop_shell *shell = es->configure_private;
3743         struct weston_view *view;
3744
3745         view = container_of(es->views.next, struct weston_view, surface_link);
3746
3747         configure_static_view(view, &shell->background_layer);
3748 }
3749
3750 static void
3751 desktop_shell_set_background(struct wl_client *client,
3752                              struct wl_resource *resource,
3753                              struct wl_resource *output_resource,
3754                              struct wl_resource *surface_resource)
3755 {
3756         struct desktop_shell *shell = wl_resource_get_user_data(resource);
3757         struct weston_surface *surface =
3758                 wl_resource_get_user_data(surface_resource);
3759         struct weston_view *view, *next;
3760
3761         if (surface->configure) {
3762                 wl_resource_post_error(surface_resource,
3763                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3764                                        "surface role already assigned");
3765                 return;
3766         }
3767
3768         wl_list_for_each_safe(view, next, &surface->views, surface_link)
3769                 weston_view_destroy(view);
3770         view = weston_view_create(surface);
3771
3772         surface->configure = background_configure;
3773         surface->configure_private = shell;
3774         surface->output = wl_resource_get_user_data(output_resource);
3775         view->output = surface->output;
3776         desktop_shell_send_configure(resource, 0,
3777                                      surface_resource,
3778                                      surface->output->width,
3779                                      surface->output->height);
3780 }
3781
3782 static void
3783 panel_configure(struct weston_surface *es, int32_t sx, int32_t sy)
3784 {
3785         struct desktop_shell *shell = es->configure_private;
3786         struct weston_view *view;
3787
3788         view = container_of(es->views.next, struct weston_view, surface_link);
3789
3790         configure_static_view(view, &shell->panel_layer);
3791 }
3792
3793 static void
3794 desktop_shell_set_panel(struct wl_client *client,
3795                         struct wl_resource *resource,
3796                         struct wl_resource *output_resource,
3797                         struct wl_resource *surface_resource)
3798 {
3799         struct desktop_shell *shell = wl_resource_get_user_data(resource);
3800         struct weston_surface *surface =
3801                 wl_resource_get_user_data(surface_resource);
3802         struct weston_view *view, *next;
3803
3804         if (surface->configure) {
3805                 wl_resource_post_error(surface_resource,
3806                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3807                                        "surface role already assigned");
3808                 return;
3809         }
3810
3811         wl_list_for_each_safe(view, next, &surface->views, surface_link)
3812                 weston_view_destroy(view);
3813         view = weston_view_create(surface);
3814
3815         surface->configure = panel_configure;
3816         surface->configure_private = shell;
3817         surface->output = wl_resource_get_user_data(output_resource);
3818         view->output = surface->output;
3819         desktop_shell_send_configure(resource, 0,
3820                                      surface_resource,
3821                                      surface->output->width,
3822                                      surface->output->height);
3823 }
3824
3825 static void
3826 lock_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
3827 {
3828         struct desktop_shell *shell = surface->configure_private;
3829         struct weston_view *view;
3830
3831         view = container_of(surface->views.next, struct weston_view, surface_link);
3832
3833         if (surface->width == 0)
3834                 return;
3835
3836         center_on_output(view, get_default_output(shell->compositor));
3837
3838         if (!weston_surface_is_mapped(surface)) {
3839                 wl_list_insert(&shell->lock_layer.view_list,
3840                                &view->layer_link);
3841                 weston_view_update_transform(view);
3842                 shell_fade(shell, FADE_IN);
3843         }
3844 }
3845
3846 static void
3847 handle_lock_surface_destroy(struct wl_listener *listener, void *data)
3848 {
3849         struct desktop_shell *shell =
3850             container_of(listener, struct desktop_shell, lock_surface_listener);
3851
3852         weston_log("lock surface gone\n");
3853         shell->lock_surface = NULL;
3854 }
3855
3856 static void
3857 desktop_shell_set_lock_surface(struct wl_client *client,
3858                                struct wl_resource *resource,
3859                                struct wl_resource *surface_resource)
3860 {
3861         struct desktop_shell *shell = wl_resource_get_user_data(resource);
3862         struct weston_surface *surface =
3863                 wl_resource_get_user_data(surface_resource);
3864
3865         shell->prepare_event_sent = false;
3866
3867         if (!shell->locked)
3868                 return;
3869
3870         shell->lock_surface = surface;
3871
3872         shell->lock_surface_listener.notify = handle_lock_surface_destroy;
3873         wl_signal_add(&surface->destroy_signal,
3874                       &shell->lock_surface_listener);
3875
3876         weston_view_create(surface);
3877         surface->configure = lock_surface_configure;
3878         surface->configure_private = shell;
3879 }
3880
3881 static void
3882 resume_desktop(struct desktop_shell *shell)
3883 {
3884         struct workspace *ws = get_current_workspace(shell);
3885
3886         terminate_screensaver(shell);
3887
3888         wl_list_remove(&shell->lock_layer.link);
3889         wl_list_insert(&shell->compositor->cursor_layer.link,
3890                        &shell->fullscreen_layer.link);
3891         wl_list_insert(&shell->fullscreen_layer.link,
3892                        &shell->panel_layer.link);
3893         if (shell->showing_input_panels) {
3894                 wl_list_insert(&shell->panel_layer.link,
3895                                &shell->input_panel_layer.link);
3896                 wl_list_insert(&shell->input_panel_layer.link,
3897                                &ws->layer.link);
3898         } else {
3899                 wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
3900         }
3901
3902         restore_focus_state(shell, get_current_workspace(shell));
3903
3904         shell->locked = false;
3905         shell_fade(shell, FADE_IN);
3906         weston_compositor_damage_all(shell->compositor);
3907 }
3908
3909 static void
3910 desktop_shell_unlock(struct wl_client *client,
3911                      struct wl_resource *resource)
3912 {
3913         struct desktop_shell *shell = wl_resource_get_user_data(resource);
3914
3915         shell->prepare_event_sent = false;
3916
3917         if (shell->locked)
3918                 resume_desktop(shell);
3919 }
3920
3921 static void
3922 desktop_shell_set_grab_surface(struct wl_client *client,
3923                                struct wl_resource *resource,
3924                                struct wl_resource *surface_resource)
3925 {
3926         struct desktop_shell *shell = wl_resource_get_user_data(resource);
3927
3928         shell->grab_surface = wl_resource_get_user_data(surface_resource);
3929         weston_view_create(shell->grab_surface);
3930 }
3931
3932 static void
3933 desktop_shell_desktop_ready(struct wl_client *client,
3934                             struct wl_resource *resource)
3935 {
3936         struct desktop_shell *shell = wl_resource_get_user_data(resource);
3937
3938         shell_fade_startup(shell);
3939 }
3940
3941 static const struct desktop_shell_interface desktop_shell_implementation = {
3942         desktop_shell_set_background,
3943         desktop_shell_set_panel,
3944         desktop_shell_set_lock_surface,
3945         desktop_shell_unlock,
3946         desktop_shell_set_grab_surface,
3947         desktop_shell_desktop_ready
3948 };
3949
3950 static enum shell_surface_type
3951 get_shell_surface_type(struct weston_surface *surface)
3952 {
3953         struct shell_surface *shsurf;
3954
3955         shsurf = get_shell_surface(surface);
3956         if (!shsurf)
3957                 return SHELL_SURFACE_NONE;
3958         return shsurf->type;
3959 }
3960
3961 static void
3962 move_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
3963 {
3964         struct weston_surface *focus;
3965         struct weston_surface *surface;
3966         struct shell_surface *shsurf;
3967
3968         if (seat->pointer->focus == NULL)
3969                 return;
3970
3971         focus = seat->pointer->focus->surface;
3972
3973         surface = weston_surface_get_main_surface(focus);
3974         if (surface == NULL)
3975                 return;
3976
3977         shsurf = get_shell_surface(surface);
3978         if (shsurf == NULL || shsurf->state.fullscreen ||
3979             shsurf->state.maximized)
3980                 return;
3981
3982         surface_move(shsurf, (struct weston_seat *) seat);
3983 }
3984
3985 static void
3986 maximize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
3987 {
3988         struct weston_surface *focus = seat->keyboard->focus;
3989         struct weston_surface *surface;
3990         struct shell_surface *shsurf;
3991         uint32_t serial;
3992
3993         surface = weston_surface_get_main_surface(focus);
3994         if (surface == NULL)
3995                 return;
3996
3997         shsurf = get_shell_surface(surface);
3998         if (shsurf == NULL)
3999                 return;
4000
4001         if (!shell_surface_is_xdg_surface(shsurf))
4002                 return;
4003
4004         serial = wl_display_next_serial(seat->compositor->wl_display);
4005         xdg_surface_change_state(shsurf, XDG_SURFACE_STATE_MAXIMIZED,
4006                                  !shsurf->state.maximized, serial);
4007 }
4008
4009 static void
4010 fullscreen_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
4011 {
4012         struct weston_surface *focus = seat->keyboard->focus;
4013         struct weston_surface *surface;
4014         struct shell_surface *shsurf;
4015         uint32_t serial;
4016
4017         surface = weston_surface_get_main_surface(focus);
4018         if (surface == NULL)
4019                 return;
4020
4021         shsurf = get_shell_surface(surface);
4022         if (shsurf == NULL)
4023                 return;
4024
4025         if (!shell_surface_is_xdg_surface(shsurf))
4026                 return;
4027
4028         serial = wl_display_next_serial(seat->compositor->wl_display);
4029         xdg_surface_change_state(shsurf, XDG_SURFACE_STATE_FULLSCREEN,
4030                                  !shsurf->state.fullscreen, serial);
4031 }
4032
4033 static void
4034 touch_move_binding(struct weston_seat *seat, uint32_t time, void *data)
4035 {
4036         struct weston_surface *focus = seat->touch->focus->surface;
4037         struct weston_surface *surface;
4038         struct shell_surface *shsurf;
4039
4040         surface = weston_surface_get_main_surface(focus);
4041         if (surface == NULL)
4042                 return;
4043
4044         shsurf = get_shell_surface(surface);
4045         if (shsurf == NULL || shsurf->state.fullscreen ||
4046             shsurf->state.maximized)
4047                 return;
4048
4049         surface_touch_move(shsurf, (struct weston_seat *) seat);
4050 }
4051
4052 static void
4053 resize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
4054 {
4055         struct weston_surface *focus;
4056         struct weston_surface *surface;
4057         uint32_t edges = 0;
4058         int32_t x, y;
4059         struct shell_surface *shsurf;
4060
4061         if (seat->pointer->focus == NULL)
4062                 return;
4063
4064         focus = seat->pointer->focus->surface;
4065
4066         surface = weston_surface_get_main_surface(focus);
4067         if (surface == NULL)
4068                 return;
4069
4070         shsurf = get_shell_surface(surface);
4071         if (shsurf == NULL || shsurf->state.fullscreen ||
4072             shsurf->state.maximized)
4073                 return;
4074
4075         weston_view_from_global(shsurf->view,
4076                                 wl_fixed_to_int(seat->pointer->grab_x),
4077                                 wl_fixed_to_int(seat->pointer->grab_y),
4078                                 &x, &y);
4079
4080         if (x < shsurf->surface->width / 3)
4081                 edges |= WL_SHELL_SURFACE_RESIZE_LEFT;
4082         else if (x < 2 * shsurf->surface->width / 3)
4083                 edges |= 0;
4084         else
4085                 edges |= WL_SHELL_SURFACE_RESIZE_RIGHT;
4086
4087         if (y < shsurf->surface->height / 3)
4088                 edges |= WL_SHELL_SURFACE_RESIZE_TOP;
4089         else if (y < 2 * shsurf->surface->height / 3)
4090                 edges |= 0;
4091         else
4092                 edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
4093
4094         surface_resize(shsurf, (struct weston_seat *) seat, edges);
4095 }
4096
4097 static void
4098 surface_opacity_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
4099                         wl_fixed_t value, void *data)
4100 {
4101         float step = 0.005;
4102         struct shell_surface *shsurf;
4103         struct weston_surface *focus = seat->pointer->focus->surface;
4104         struct weston_surface *surface;
4105
4106         /* XXX: broken for windows containing sub-surfaces */
4107         surface = weston_surface_get_main_surface(focus);
4108         if (surface == NULL)
4109                 return;
4110
4111         shsurf = get_shell_surface(surface);
4112         if (!shsurf)
4113                 return;
4114
4115         shsurf->view->alpha -= wl_fixed_to_double(value) * step;
4116
4117         if (shsurf->view->alpha > 1.0)
4118                 shsurf->view->alpha = 1.0;
4119         if (shsurf->view->alpha < step)
4120                 shsurf->view->alpha = step;
4121
4122         weston_view_geometry_dirty(shsurf->view);
4123         weston_surface_damage(surface);
4124 }
4125
4126 static void
4127 do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
4128         wl_fixed_t value)
4129 {
4130         struct weston_seat *ws = (struct weston_seat *) seat;
4131         struct weston_compositor *compositor = ws->compositor;
4132         struct weston_output *output;
4133         float increment;
4134
4135         wl_list_for_each(output, &compositor->output_list, link) {
4136                 if (pixman_region32_contains_point(&output->region,
4137                                                    wl_fixed_to_double(seat->pointer->x),
4138                                                    wl_fixed_to_double(seat->pointer->y),
4139                                                    NULL)) {
4140                         if (key == KEY_PAGEUP)
4141                                 increment = output->zoom.increment;
4142                         else if (key == KEY_PAGEDOWN)
4143                                 increment = -output->zoom.increment;
4144                         else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
4145                                 /* For every pixel zoom 20th of a step */
4146                                 increment = output->zoom.increment *
4147                                             -wl_fixed_to_double(value) / 20.0;
4148                         else
4149                                 increment = 0;
4150
4151                         output->zoom.level += increment;
4152
4153                         if (output->zoom.level < 0.0)
4154                                 output->zoom.level = 0.0;
4155                         else if (output->zoom.level > output->zoom.max_level)
4156                                 output->zoom.level = output->zoom.max_level;
4157                         else if (!output->zoom.active) {
4158                                 weston_output_activate_zoom(output);
4159                         }
4160
4161                         output->zoom.spring_z.target = output->zoom.level;
4162
4163                         weston_output_update_zoom(output);
4164                 }
4165         }
4166 }
4167
4168 static void
4169 zoom_axis_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
4170                   wl_fixed_t value, void *data)
4171 {
4172         do_zoom(seat, time, 0, axis, value);
4173 }
4174
4175 static void
4176 zoom_key_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
4177                  void *data)
4178 {
4179         do_zoom(seat, time, key, 0, 0);
4180 }
4181
4182 static void
4183 terminate_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
4184                   void *data)
4185 {
4186         struct weston_compositor *compositor = data;
4187
4188         wl_display_terminate(compositor->wl_display);
4189 }
4190
4191 static void
4192 rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
4193                    wl_fixed_t x, wl_fixed_t y)
4194 {
4195         struct rotate_grab *rotate =
4196                 container_of(grab, struct rotate_grab, base.grab);
4197         struct weston_pointer *pointer = grab->pointer;
4198         struct shell_surface *shsurf = rotate->base.shsurf;
4199         float cx, cy, dx, dy, cposx, cposy, dposx, dposy, r;
4200
4201         weston_pointer_move(pointer, x, y);
4202
4203         if (!shsurf)
4204                 return;
4205
4206         cx = 0.5f * shsurf->surface->width;
4207         cy = 0.5f * shsurf->surface->height;
4208
4209         dx = wl_fixed_to_double(pointer->x) - rotate->center.x;
4210         dy = wl_fixed_to_double(pointer->y) - rotate->center.y;
4211         r = sqrtf(dx * dx + dy * dy);
4212
4213         wl_list_remove(&shsurf->rotation.transform.link);
4214         weston_view_geometry_dirty(shsurf->view);
4215
4216         if (r > 20.0f) {
4217                 struct weston_matrix *matrix =
4218                         &shsurf->rotation.transform.matrix;
4219
4220                 weston_matrix_init(&rotate->rotation);
4221                 weston_matrix_rotate_xy(&rotate->rotation, dx / r, dy / r);
4222
4223                 weston_matrix_init(matrix);
4224                 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
4225                 weston_matrix_multiply(matrix, &shsurf->rotation.rotation);
4226                 weston_matrix_multiply(matrix, &rotate->rotation);
4227                 weston_matrix_translate(matrix, cx, cy, 0.0f);
4228
4229                 wl_list_insert(
4230                         &shsurf->view->geometry.transformation_list,
4231                         &shsurf->rotation.transform.link);
4232         } else {
4233                 wl_list_init(&shsurf->rotation.transform.link);
4234                 weston_matrix_init(&shsurf->rotation.rotation);
4235                 weston_matrix_init(&rotate->rotation);
4236         }
4237
4238         /* We need to adjust the position of the surface
4239          * in case it was resized in a rotated state before */
4240         cposx = shsurf->view->geometry.x + cx;
4241         cposy = shsurf->view->geometry.y + cy;
4242         dposx = rotate->center.x - cposx;
4243         dposy = rotate->center.y - cposy;
4244         if (dposx != 0.0f || dposy != 0.0f) {
4245                 weston_view_set_position(shsurf->view,
4246                                          shsurf->view->geometry.x + dposx,
4247                                          shsurf->view->geometry.y + dposy);
4248         }
4249
4250         /* Repaint implies weston_surface_update_transform(), which
4251          * lazily applies the damage due to rotation update.
4252          */
4253         weston_compositor_schedule_repaint(shsurf->surface->compositor);
4254 }
4255
4256 static void
4257 rotate_grab_button(struct weston_pointer_grab *grab,
4258                    uint32_t time, uint32_t button, uint32_t state_w)
4259 {
4260         struct rotate_grab *rotate =
4261                 container_of(grab, struct rotate_grab, base.grab);
4262         struct weston_pointer *pointer = grab->pointer;
4263         struct shell_surface *shsurf = rotate->base.shsurf;
4264         enum wl_pointer_button_state state = state_w;
4265
4266         if (pointer->button_count == 0 &&
4267             state == WL_POINTER_BUTTON_STATE_RELEASED) {
4268                 if (shsurf)
4269                         weston_matrix_multiply(&shsurf->rotation.rotation,
4270                                                &rotate->rotation);
4271                 shell_grab_end(&rotate->base);
4272                 free(rotate);
4273         }
4274 }
4275
4276 static void
4277 rotate_grab_cancel(struct weston_pointer_grab *grab)
4278 {
4279         struct rotate_grab *rotate =
4280                 container_of(grab, struct rotate_grab, base.grab);
4281
4282         shell_grab_end(&rotate->base);
4283         free(rotate);
4284 }
4285
4286 static const struct weston_pointer_grab_interface rotate_grab_interface = {
4287         noop_grab_focus,
4288         rotate_grab_motion,
4289         rotate_grab_button,
4290         rotate_grab_cancel,
4291 };
4292
4293 static void
4294 surface_rotate(struct shell_surface *surface, struct weston_seat *seat)
4295 {
4296         struct rotate_grab *rotate;
4297         float dx, dy;
4298         float r;
4299
4300         rotate = malloc(sizeof *rotate);
4301         if (!rotate)
4302                 return;
4303
4304         weston_view_to_global_float(surface->view,
4305                                     surface->surface->width * 0.5f,
4306                                     surface->surface->height * 0.5f,
4307                                     &rotate->center.x, &rotate->center.y);
4308
4309         dx = wl_fixed_to_double(seat->pointer->x) - rotate->center.x;
4310         dy = wl_fixed_to_double(seat->pointer->y) - rotate->center.y;
4311         r = sqrtf(dx * dx + dy * dy);
4312         if (r > 20.0f) {
4313                 struct weston_matrix inverse;
4314
4315                 weston_matrix_init(&inverse);
4316                 weston_matrix_rotate_xy(&inverse, dx / r, -dy / r);
4317                 weston_matrix_multiply(&surface->rotation.rotation, &inverse);
4318
4319                 weston_matrix_init(&rotate->rotation);
4320                 weston_matrix_rotate_xy(&rotate->rotation, dx / r, dy / r);
4321         } else {
4322                 weston_matrix_init(&surface->rotation.rotation);
4323                 weston_matrix_init(&rotate->rotation);
4324         }
4325
4326         shell_grab_start(&rotate->base, &rotate_grab_interface, surface,
4327                          seat->pointer, DESKTOP_SHELL_CURSOR_ARROW);
4328 }
4329
4330 static void
4331 rotate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
4332                void *data)
4333 {
4334         struct weston_surface *focus;
4335         struct weston_surface *base_surface;
4336         struct shell_surface *surface;
4337
4338         if (seat->pointer->focus == NULL)
4339                 return;
4340
4341         focus = seat->pointer->focus->surface;
4342
4343         base_surface = weston_surface_get_main_surface(focus);
4344         if (base_surface == NULL)
4345                 return;
4346
4347         surface = get_shell_surface(base_surface);
4348         if (surface == NULL || surface->state.fullscreen ||
4349             surface->state.maximized)
4350                 return;
4351
4352         surface_rotate(surface, seat);
4353 }
4354
4355 /* Move all fullscreen layers down to the current workspace in a non-reversible
4356  * manner. This should be used when implementing shell-wide overlays, such as
4357  * the alt-tab switcher, which need to de-promote fullscreen layers. */
4358 void
4359 lower_fullscreen_layer(struct desktop_shell *shell)
4360 {
4361         struct workspace *ws;
4362         struct weston_view *view, *prev;
4363
4364         ws = get_current_workspace(shell);
4365         wl_list_for_each_reverse_safe(view, prev,
4366                                       &shell->fullscreen_layer.view_list,
4367                                       layer_link) {
4368                 wl_list_remove(&view->layer_link);
4369                 wl_list_insert(&ws->layer.view_list, &view->layer_link);
4370                 weston_view_damage_below(view);
4371                 weston_surface_damage(view->surface);
4372         }
4373 }
4374
4375 void
4376 activate(struct desktop_shell *shell, struct weston_surface *es,
4377          struct weston_seat *seat)
4378 {
4379         struct weston_surface *main_surface;
4380         struct focus_state *state;
4381         struct workspace *ws;
4382         struct weston_surface *old_es;
4383         struct shell_surface *shsurf;
4384
4385         main_surface = weston_surface_get_main_surface(es);
4386
4387         weston_surface_activate(es, seat);
4388
4389         state = ensure_focus_state(shell, seat);
4390         if (state == NULL)
4391                 return;
4392
4393         old_es = state->keyboard_focus;
4394         focus_state_set_focus(state, es);
4395
4396         shsurf = get_shell_surface(main_surface);
4397         assert(shsurf);
4398
4399         if (shsurf->state.fullscreen)
4400                 shell_configure_fullscreen(shsurf);
4401         else
4402                 restore_all_output_modes(shell->compositor);
4403
4404         /* Update the surface’s layer. This brings it to the top of the stacking
4405          * order as appropriate. */
4406         shell_surface_update_layer(shsurf);
4407
4408         if (shell->focus_animation_type != ANIMATION_NONE) {
4409                 ws = get_current_workspace(shell);
4410                 animate_focus_change(shell, ws, get_default_view(old_es), get_default_view(es));
4411         }
4412 }
4413
4414 /* no-op func for checking black surface */
4415 static void
4416 black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
4417 {
4418 }
4419
4420 static bool
4421 is_black_surface (struct weston_surface *es, struct weston_surface **fs_surface)
4422 {
4423         if (es->configure == black_surface_configure) {
4424                 if (fs_surface)
4425                         *fs_surface = (struct weston_surface *)es->configure_private;
4426                 return true;
4427         }
4428         return false;
4429 }
4430
4431 static void
4432 activate_binding(struct weston_seat *seat,
4433                  struct desktop_shell *shell,
4434                  struct weston_surface *focus)
4435 {
4436         struct weston_surface *main_surface;
4437
4438         if (!focus)
4439                 return;
4440
4441         if (is_black_surface(focus, &main_surface))
4442                 focus = main_surface;
4443
4444         main_surface = weston_surface_get_main_surface(focus);
4445         if (get_shell_surface_type(main_surface) == SHELL_SURFACE_NONE)
4446                 return;
4447
4448         activate(shell, focus, seat);
4449 }
4450
4451 static void
4452 click_to_activate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
4453                           void *data)
4454 {
4455         if (seat->pointer->grab != &seat->pointer->default_grab)
4456                 return;
4457         if (seat->pointer->focus == NULL)
4458                 return;
4459
4460         activate_binding(seat, data, seat->pointer->focus->surface);
4461 }
4462
4463 static void
4464 touch_to_activate_binding(struct weston_seat *seat, uint32_t time, void *data)
4465 {
4466         if (seat->touch->grab != &seat->touch->default_grab)
4467                 return;
4468         if (seat->touch->focus == NULL)
4469                 return;
4470
4471         activate_binding(seat, data, seat->touch->focus->surface);
4472 }
4473
4474 static void
4475 lock(struct desktop_shell *shell)
4476 {
4477         struct workspace *ws = get_current_workspace(shell);
4478
4479         if (shell->locked) {
4480                 weston_compositor_sleep(shell->compositor);
4481                 return;
4482         }
4483
4484         shell->locked = true;
4485
4486         /* Hide all surfaces by removing the fullscreen, panel and
4487          * toplevel layers.  This way nothing else can show or receive
4488          * input events while we are locked. */
4489
4490         wl_list_remove(&shell->panel_layer.link);
4491         wl_list_remove(&shell->fullscreen_layer.link);
4492         if (shell->showing_input_panels)
4493                 wl_list_remove(&shell->input_panel_layer.link);
4494         wl_list_remove(&ws->layer.link);
4495         wl_list_insert(&shell->compositor->cursor_layer.link,
4496                        &shell->lock_layer.link);
4497
4498         launch_screensaver(shell);
4499
4500         /* TODO: disable bindings that should not work while locked. */
4501
4502         /* All this must be undone in resume_desktop(). */
4503 }
4504
4505 static void
4506 unlock(struct desktop_shell *shell)
4507 {
4508         if (!shell->locked || shell->lock_surface) {
4509                 shell_fade(shell, FADE_IN);
4510                 return;
4511         }
4512
4513         /* If desktop-shell client has gone away, unlock immediately. */
4514         if (!shell->child.desktop_shell) {
4515                 resume_desktop(shell);
4516                 return;
4517         }
4518
4519         if (shell->prepare_event_sent)
4520                 return;
4521
4522         desktop_shell_send_prepare_lock_surface(shell->child.desktop_shell);
4523         shell->prepare_event_sent = true;
4524 }
4525
4526 static void
4527 shell_fade_done(struct weston_view_animation *animation, void *data)
4528 {
4529         struct desktop_shell *shell = data;
4530
4531         shell->fade.animation = NULL;
4532
4533         switch (shell->fade.type) {
4534         case FADE_IN:
4535                 weston_surface_destroy(shell->fade.view->surface);
4536                 shell->fade.view = NULL;
4537                 break;
4538         case FADE_OUT:
4539                 lock(shell);
4540                 break;
4541         default:
4542                 break;
4543         }
4544 }
4545
4546 static struct weston_view *
4547 shell_fade_create_surface(struct desktop_shell *shell)
4548 {
4549         struct weston_compositor *compositor = shell->compositor;
4550         struct weston_surface *surface;
4551         struct weston_view *view;
4552
4553         surface = weston_surface_create(compositor);
4554         if (!surface)
4555                 return NULL;
4556
4557         view = weston_view_create(surface);
4558         if (!view) {
4559                 weston_surface_destroy(surface);
4560                 return NULL;
4561         }
4562
4563         weston_surface_set_size(surface, 8192, 8192);
4564         weston_view_set_position(view, 0, 0);
4565         weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
4566         wl_list_insert(&compositor->fade_layer.view_list,
4567                        &view->layer_link);
4568         pixman_region32_init(&surface->input);
4569
4570         return view;
4571 }
4572
4573 static void
4574 shell_fade(struct desktop_shell *shell, enum fade_type type)
4575 {
4576         float tint;
4577
4578         switch (type) {
4579         case FADE_IN:
4580                 tint = 0.0;
4581                 break;
4582         case FADE_OUT:
4583                 tint = 1.0;
4584                 break;
4585         default:
4586                 weston_log("shell: invalid fade type\n");
4587                 return;
4588         }
4589
4590         shell->fade.type = type;
4591
4592         if (shell->fade.view == NULL) {
4593                 shell->fade.view = shell_fade_create_surface(shell);
4594                 if (!shell->fade.view)
4595                         return;
4596
4597                 shell->fade.view->alpha = 1.0 - tint;
4598                 weston_view_update_transform(shell->fade.view);
4599         }
4600
4601         if (shell->fade.view->output == NULL) {
4602                 /* If the black view gets a NULL output, we lost the
4603                  * last output and we'll just cancel the fade.  This
4604                  * happens when you close the last window under the
4605                  * X11 or Wayland backends. */
4606                 shell->locked = false;
4607                 weston_surface_destroy(shell->fade.view->surface);
4608                 shell->fade.view = NULL;
4609         } else if (shell->fade.animation) {
4610                 weston_fade_update(shell->fade.animation, tint);
4611         } else {
4612                 shell->fade.animation =
4613                         weston_fade_run(shell->fade.view,
4614                                         1.0 - tint, tint, 300.0,
4615                                         shell_fade_done, shell);
4616         }
4617 }
4618
4619 static void
4620 do_shell_fade_startup(void *data)
4621 {
4622         struct desktop_shell *shell = data;
4623
4624         if (shell->startup_animation_type == ANIMATION_FADE)
4625                 shell_fade(shell, FADE_IN);
4626         else if (shell->startup_animation_type == ANIMATION_NONE) {
4627                 weston_surface_destroy(shell->fade.view->surface);
4628                 shell->fade.view = NULL;
4629         }
4630 }
4631
4632 static void
4633 shell_fade_startup(struct desktop_shell *shell)
4634 {
4635         struct wl_event_loop *loop;
4636
4637         if (!shell->fade.startup_timer)
4638                 return;
4639
4640         wl_event_source_remove(shell->fade.startup_timer);
4641         shell->fade.startup_timer = NULL;
4642
4643         loop = wl_display_get_event_loop(shell->compositor->wl_display);
4644         wl_event_loop_add_idle(loop, do_shell_fade_startup, shell);
4645 }
4646
4647 static int
4648 fade_startup_timeout(void *data)
4649 {
4650         struct desktop_shell *shell = data;
4651
4652         shell_fade_startup(shell);
4653         return 0;
4654 }
4655
4656 static void
4657 shell_fade_init(struct desktop_shell *shell)
4658 {
4659         /* Make compositor output all black, and wait for the desktop-shell
4660          * client to signal it is ready, then fade in. The timer triggers a
4661          * fade-in, in case the desktop-shell client takes too long.
4662          */
4663
4664         struct wl_event_loop *loop;
4665
4666         if (shell->fade.view != NULL) {
4667                 weston_log("%s: warning: fade surface already exists\n",
4668                            __func__);
4669                 return;
4670         }
4671
4672         shell->fade.view = shell_fade_create_surface(shell);
4673         if (!shell->fade.view)
4674                 return;
4675
4676         weston_view_update_transform(shell->fade.view);
4677         weston_surface_damage(shell->fade.view->surface);
4678
4679         loop = wl_display_get_event_loop(shell->compositor->wl_display);
4680         shell->fade.startup_timer =
4681                 wl_event_loop_add_timer(loop, fade_startup_timeout, shell);
4682         wl_event_source_timer_update(shell->fade.startup_timer, 15000);
4683 }
4684
4685 static void
4686 idle_handler(struct wl_listener *listener, void *data)
4687 {
4688         struct desktop_shell *shell =
4689                 container_of(listener, struct desktop_shell, idle_listener);
4690         struct weston_seat *seat;
4691
4692         wl_list_for_each(seat, &shell->compositor->seat_list, link)
4693                 if (seat->pointer)
4694                         popup_grab_end(seat->pointer);
4695
4696         shell_fade(shell, FADE_OUT);
4697         /* lock() is called from shell_fade_done() */
4698 }
4699
4700 static void
4701 wake_handler(struct wl_listener *listener, void *data)
4702 {
4703         struct desktop_shell *shell =
4704                 container_of(listener, struct desktop_shell, wake_listener);
4705
4706         unlock(shell);
4707 }
4708
4709 static void
4710 center_on_output(struct weston_view *view, struct weston_output *output)
4711 {
4712         int32_t surf_x, surf_y, width, height;
4713         float x, y;
4714
4715         surface_subsurfaces_boundingbox(view->surface, &surf_x, &surf_y, &width, &height);
4716
4717         x = output->x + (output->width - width) / 2 - surf_x / 2;
4718         y = output->y + (output->height - height) / 2 - surf_y / 2;
4719
4720         weston_view_set_position(view, x, y);
4721 }
4722
4723 static void
4724 weston_view_set_initial_position(struct weston_view *view,
4725                                  struct desktop_shell *shell)
4726 {
4727         struct weston_compositor *compositor = shell->compositor;
4728         int ix = 0, iy = 0;
4729         int range_x, range_y;
4730         int dx, dy, x, y, panel_height;
4731         struct weston_output *output, *target_output = NULL;
4732         struct weston_seat *seat;
4733
4734         /* As a heuristic place the new window on the same output as the
4735          * pointer. Falling back to the output containing 0, 0.
4736          *
4737          * TODO: Do something clever for touch too?
4738          */
4739         wl_list_for_each(seat, &compositor->seat_list, link) {
4740                 if (seat->pointer) {
4741                         ix = wl_fixed_to_int(seat->pointer->x);
4742                         iy = wl_fixed_to_int(seat->pointer->y);
4743                         break;
4744                 }
4745         }
4746
4747         wl_list_for_each(output, &compositor->output_list, link) {
4748                 if (pixman_region32_contains_point(&output->region, ix, iy, NULL)) {
4749                         target_output = output;
4750                         break;
4751                 }
4752         }
4753
4754         if (!target_output) {
4755                 weston_view_set_position(view, 10 + random() % 400,
4756                                          10 + random() % 400);
4757                 return;
4758         }
4759
4760         /* Valid range within output where the surface will still be onscreen.
4761          * If this is negative it means that the surface is bigger than
4762          * output.
4763          */
4764         panel_height = get_output_panel_height(shell, target_output);
4765         range_x = target_output->width - view->surface->width;
4766         range_y = (target_output->height - panel_height) -
4767                   view->surface->height;
4768
4769         if (range_x > 0)
4770                 dx = random() % range_x;
4771         else
4772                 dx = 0;
4773
4774         if (range_y > 0)
4775                 dy = panel_height + random() % range_y;
4776         else
4777                 dy = panel_height;
4778
4779         x = target_output->x + dx;
4780         y = target_output->y + dy;
4781
4782         weston_view_set_position(view, x, y);
4783 }
4784
4785 static void
4786 map(struct desktop_shell *shell, struct shell_surface *shsurf,
4787     int32_t sx, int32_t sy)
4788 {
4789         struct weston_compositor *compositor = shell->compositor;
4790         struct weston_seat *seat;
4791         int panel_height = 0;
4792         int32_t surf_x, surf_y;
4793
4794         /* initial positioning, see also configure() */
4795         switch (shsurf->type) {
4796         case SHELL_SURFACE_TOPLEVEL:
4797                 if (shsurf->state.fullscreen) {
4798                         center_on_output(shsurf->view, shsurf->fullscreen_output);
4799                         shell_map_fullscreen(shsurf);
4800                 } else if (shsurf->state.maximized) {
4801                         /* use surface configure to set the geometry */
4802                         panel_height = get_output_panel_height(shell, shsurf->output);
4803                         surface_subsurfaces_boundingbox(shsurf->surface,
4804                                                         &surf_x, &surf_y, NULL, NULL);
4805                         weston_view_set_position(shsurf->view,
4806                                                  shsurf->output->x - surf_x,
4807                                                  shsurf->output->y +
4808                                                  panel_height - surf_y);
4809                 } else if (!shsurf->state.relative) {
4810                         weston_view_set_initial_position(shsurf->view, shell);
4811                 }
4812                 break;
4813         case SHELL_SURFACE_POPUP:
4814                 shell_map_popup(shsurf);
4815                 break;
4816         case SHELL_SURFACE_NONE:
4817                 weston_view_set_position(shsurf->view,
4818                                          shsurf->view->geometry.x + sx,
4819                                          shsurf->view->geometry.y + sy);
4820                 break;
4821         case SHELL_SURFACE_XWAYLAND:
4822         default:
4823                 ;
4824         }
4825
4826         /* Surface stacking order, see also activate(). */
4827         shell_surface_update_layer(shsurf);
4828
4829         if (shsurf->type != SHELL_SURFACE_NONE) {
4830                 weston_view_update_transform(shsurf->view);
4831                 if (shsurf->state.maximized) {
4832                         shsurf->surface->output = shsurf->output;
4833                         shsurf->view->output = shsurf->output;
4834                 }
4835         }
4836
4837         switch (shsurf->type) {
4838         /* XXX: xwayland's using the same fields for transient type */
4839         case SHELL_SURFACE_XWAYLAND:
4840                 if (shsurf->transient.flags ==
4841                                 WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
4842                         break;
4843         case SHELL_SURFACE_TOPLEVEL:
4844                 if (shsurf->state.relative &&
4845                     shsurf->transient.flags == WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
4846                         break;
4847                 if (shell->locked)
4848                         break;
4849                 wl_list_for_each(seat, &compositor->seat_list, link)
4850                         activate(shell, shsurf->surface, seat);
4851                 break;
4852         case SHELL_SURFACE_POPUP:
4853         case SHELL_SURFACE_NONE:
4854         default:
4855                 break;
4856         }
4857
4858         if (shsurf->type == SHELL_SURFACE_TOPLEVEL &&
4859             !shsurf->state.maximized && !shsurf->state.fullscreen)
4860         {
4861                 switch (shell->win_animation_type) {
4862                 case ANIMATION_FADE:
4863                         weston_fade_run(shsurf->view, 0.0, 1.0, 300.0, NULL, NULL);
4864                         break;
4865                 case ANIMATION_ZOOM:
4866                         weston_zoom_run(shsurf->view, 0.5, 1.0, NULL, NULL);
4867                         break;
4868                 case ANIMATION_NONE:
4869                 default:
4870                         break;
4871                 }
4872         }
4873 }
4874
4875 static void
4876 configure(struct desktop_shell *shell, struct weston_surface *surface,
4877           float x, float y)
4878 {
4879         struct shell_surface *shsurf;
4880         struct weston_view *view;
4881         int32_t mx, my, surf_x, surf_y;
4882
4883         shsurf = get_shell_surface(surface);
4884
4885         assert(shsurf);
4886
4887         if (shsurf->state.fullscreen)
4888                 shell_configure_fullscreen(shsurf);
4889         else if (shsurf->state.maximized) {
4890                 /* setting x, y and using configure to change that geometry */
4891                 surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y,
4892                                                                  NULL, NULL);
4893                 mx = shsurf->output->x - surf_x;
4894                 my = shsurf->output->y +
4895                      get_output_panel_height(shell,shsurf->output) - surf_y;
4896                 weston_view_set_position(shsurf->view, mx, my);
4897         } else {
4898                 weston_view_set_position(shsurf->view, x, y);
4899         }
4900
4901         /* XXX: would a fullscreen surface need the same handling? */
4902         if (surface->output) {
4903                 wl_list_for_each(view, &surface->views, surface_link)
4904                         weston_view_update_transform(view);
4905
4906                 if (shsurf->state.maximized)
4907                         surface->output = shsurf->output;
4908         }
4909 }
4910
4911 static void
4912 shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
4913 {
4914         struct shell_surface *shsurf = get_shell_surface(es);
4915         struct desktop_shell *shell;
4916         int type_changed = 0;
4917
4918         assert(shsurf);
4919
4920         shell = shsurf->shell;
4921
4922         if (!weston_surface_is_mapped(es) &&
4923             !wl_list_empty(&shsurf->popup.grab_link)) {
4924                 remove_popup_grab(shsurf);
4925         }
4926
4927         if (es->width == 0)
4928                 return;
4929
4930         if (shsurf->state_changed) {
4931                 set_surface_type(shsurf);
4932                 type_changed = 1;
4933         }
4934
4935         if (!weston_surface_is_mapped(es)) {
4936                 map(shell, shsurf, sx, sy);
4937         } else if (type_changed || sx != 0 || sy != 0 ||
4938                    shsurf->last_width != es->width ||
4939                    shsurf->last_height != es->height) {
4940                 float from_x, from_y;
4941                 float to_x, to_y;
4942
4943                 if (shsurf->resize_edges) {
4944                         sx = 0;
4945                         sy = 0;
4946                 }
4947
4948                 if (shsurf->resize_edges & WL_SHELL_SURFACE_RESIZE_LEFT)
4949                         sx = shsurf->last_width - es->width;
4950                 if (shsurf->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP)
4951                         sy = shsurf->last_height - es->height;
4952
4953                 shsurf->last_width = es->width;
4954                 shsurf->last_height = es->height;
4955
4956                 weston_view_to_global_float(shsurf->view, 0, 0, &from_x, &from_y);
4957                 weston_view_to_global_float(shsurf->view, sx, sy, &to_x, &to_y);
4958                 configure(shell, es,
4959                           shsurf->view->geometry.x + to_x - from_x,
4960                           shsurf->view->geometry.y + to_y - from_y);
4961         }
4962 }
4963
4964 static void launch_desktop_shell_process(void *data);
4965
4966 static void
4967 desktop_shell_sigchld(struct weston_process *process, int status)
4968 {
4969         uint32_t time;
4970         struct desktop_shell *shell =
4971                 container_of(process, struct desktop_shell, child.process);
4972
4973         shell->child.process.pid = 0;
4974         shell->child.client = NULL; /* already destroyed by wayland */
4975
4976         /* if desktop-shell dies more than 5 times in 30 seconds, give up */
4977         time = weston_compositor_get_time();
4978         if (time - shell->child.deathstamp > 30000) {
4979                 shell->child.deathstamp = time;
4980                 shell->child.deathcount = 0;
4981         }
4982
4983         shell->child.deathcount++;
4984         if (shell->child.deathcount > 5) {
4985                 weston_log("%s died, giving up.\n", shell->client);
4986                 return;
4987         }
4988
4989         weston_log("%s died, respawning...\n", shell->client);
4990         launch_desktop_shell_process(shell);
4991         shell_fade_startup(shell);
4992 }
4993
4994 static void
4995 desktop_shell_client_destroy(struct wl_listener *listener, void *data)
4996 {
4997         struct desktop_shell *shell;
4998
4999         shell = container_of(listener, struct desktop_shell,
5000                              child.client_destroy_listener);
5001
5002         shell->child.client = NULL;
5003 }
5004
5005 static void
5006 launch_desktop_shell_process(void *data)
5007 {
5008         struct desktop_shell *shell = data;
5009
5010         shell->child.client = weston_client_launch(shell->compositor,
5011                                                  &shell->child.process,
5012                                                  shell->client,
5013                                                  desktop_shell_sigchld);
5014
5015         if (!shell->child.client)
5016                 weston_log("not able to start %s\n", shell->client);
5017
5018         shell->child.client_destroy_listener.notify =
5019                 desktop_shell_client_destroy;
5020         wl_client_add_destroy_listener(shell->child.client,
5021                                        &shell->child.client_destroy_listener);
5022 }
5023
5024 static void
5025 handle_shell_client_destroy(struct wl_listener *listener, void *data)
5026 {
5027         struct shell_client *sc =
5028                 container_of(listener, struct shell_client, destroy_listener);
5029
5030         if (sc->ping_timer)
5031                 wl_event_source_remove(sc->ping_timer);
5032         free(sc);
5033 }
5034
5035 static struct shell_client *
5036 shell_client_create(struct wl_client *client, struct desktop_shell *shell,
5037                     const struct wl_interface *interface, uint32_t id)
5038 {
5039         struct shell_client *sc;
5040
5041         sc = zalloc(sizeof *sc);
5042         if (sc == NULL) {
5043                 wl_client_post_no_memory(client);
5044                 return NULL;
5045         }
5046
5047         sc->resource = wl_resource_create(client, interface, 1, id);
5048         if (sc->resource == NULL) {
5049                 free(sc);
5050                 wl_client_post_no_memory(client);
5051                 return NULL;
5052         }
5053
5054         sc->client = client;
5055         sc->shell = shell;
5056         sc->destroy_listener.notify = handle_shell_client_destroy;
5057         wl_client_add_destroy_listener(client, &sc->destroy_listener);
5058
5059         return sc;
5060 }
5061
5062 static void
5063 bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
5064 {
5065         struct desktop_shell *shell = data;
5066         struct shell_client *sc;
5067
5068         sc = shell_client_create(client, shell, &wl_shell_interface, id);
5069         if (sc)
5070                 wl_resource_set_implementation(sc->resource,
5071                                                &shell_implementation,
5072                                                shell, NULL);
5073 }
5074
5075 static void
5076 bind_xdg_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
5077 {
5078         struct desktop_shell *shell = data;
5079         struct shell_client *sc;
5080
5081         sc = shell_client_create(client, shell, &xdg_shell_interface, id);
5082         if (sc)
5083                 wl_resource_set_dispatcher(sc->resource,
5084                                            xdg_shell_unversioned_dispatch,
5085                                            NULL, sc, NULL);
5086 }
5087
5088 static void
5089 unbind_desktop_shell(struct wl_resource *resource)
5090 {
5091         struct desktop_shell *shell = wl_resource_get_user_data(resource);
5092
5093         if (shell->locked)
5094                 resume_desktop(shell);
5095
5096         shell->child.desktop_shell = NULL;
5097         shell->prepare_event_sent = false;
5098 }
5099
5100 static void
5101 bind_desktop_shell(struct wl_client *client,
5102                    void *data, uint32_t version, uint32_t id)
5103 {
5104         struct desktop_shell *shell = data;
5105         struct wl_resource *resource;
5106
5107         resource = wl_resource_create(client, &desktop_shell_interface,
5108                                       MIN(version, 2), id);
5109
5110         if (client == shell->child.client) {
5111                 wl_resource_set_implementation(resource,
5112                                                &desktop_shell_implementation,
5113                                                shell, unbind_desktop_shell);
5114                 shell->child.desktop_shell = resource;
5115
5116                 if (version < 2)
5117                         shell_fade_startup(shell);
5118
5119                 return;
5120         }
5121
5122         wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
5123                                "permission to bind desktop_shell denied");
5124         wl_resource_destroy(resource);
5125 }
5126
5127 static void
5128 screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
5129 {
5130         struct desktop_shell *shell = surface->configure_private;
5131         struct weston_view *view;
5132
5133         if (surface->width == 0)
5134                 return;
5135
5136         /* XXX: starting weston-screensaver beforehand does not work */
5137         if (!shell->locked)
5138                 return;
5139
5140         view = container_of(surface->views.next, struct weston_view, surface_link);
5141         center_on_output(view, surface->output);
5142
5143         if (wl_list_empty(&view->layer_link)) {
5144                 wl_list_insert(shell->lock_layer.view_list.prev,
5145                                &view->layer_link);
5146                 weston_view_update_transform(view);
5147                 wl_event_source_timer_update(shell->screensaver.timer,
5148                                              shell->screensaver.duration);
5149                 shell_fade(shell, FADE_IN);
5150         }
5151 }
5152
5153 static void
5154 screensaver_set_surface(struct wl_client *client,
5155                         struct wl_resource *resource,
5156                         struct wl_resource *surface_resource,
5157                         struct wl_resource *output_resource)
5158 {
5159         struct desktop_shell *shell = wl_resource_get_user_data(resource);
5160         struct weston_surface *surface =
5161                 wl_resource_get_user_data(surface_resource);
5162         struct weston_output *output = wl_resource_get_user_data(output_resource);
5163         struct weston_view *view, *next;
5164
5165         /* Make sure we only have one view */
5166         wl_list_for_each_safe(view, next, &surface->views, surface_link)
5167                 weston_view_destroy(view);
5168         weston_view_create(surface);
5169
5170         surface->configure = screensaver_configure;
5171         surface->configure_private = shell;
5172         surface->output = output;
5173 }
5174
5175 static const struct screensaver_interface screensaver_implementation = {
5176         screensaver_set_surface
5177 };
5178
5179 static void
5180 unbind_screensaver(struct wl_resource *resource)
5181 {
5182         struct desktop_shell *shell = wl_resource_get_user_data(resource);
5183
5184         shell->screensaver.binding = NULL;
5185 }
5186
5187 static void
5188 bind_screensaver(struct wl_client *client,
5189                  void *data, uint32_t version, uint32_t id)
5190 {
5191         struct desktop_shell *shell = data;
5192         struct wl_resource *resource;
5193
5194         resource = wl_resource_create(client, &screensaver_interface, 1, id);
5195
5196         if (shell->screensaver.binding == NULL) {
5197                 wl_resource_set_implementation(resource,
5198                                                &screensaver_implementation,
5199                                                shell, unbind_screensaver);
5200                 shell->screensaver.binding = resource;
5201                 return;
5202         }
5203
5204         wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
5205                                "interface object already bound");
5206         wl_resource_destroy(resource);
5207 }
5208
5209 struct switcher {
5210         struct desktop_shell *shell;
5211         struct weston_surface *current;
5212         struct wl_listener listener;
5213         struct weston_keyboard_grab grab;
5214         struct wl_array minimized_array;
5215 };
5216
5217 static void
5218 switcher_next(struct switcher *switcher)
5219 {
5220         struct weston_view *view;
5221         struct weston_surface *first = NULL, *prev = NULL, *next = NULL;
5222         struct shell_surface *shsurf;
5223         struct workspace *ws = get_current_workspace(switcher->shell);
5224
5225          /* temporary re-display minimized surfaces */
5226         struct weston_view *tmp;
5227         struct weston_view **minimized;
5228         wl_list_for_each_safe(view, tmp, &switcher->shell->minimized_layer.view_list, layer_link) {
5229                 wl_list_remove(&view->layer_link);
5230                 wl_list_insert(&ws->layer.view_list, &view->layer_link);
5231                 minimized = wl_array_add(&switcher->minimized_array, sizeof *minimized);
5232                 *minimized = view;
5233         }
5234
5235         wl_list_for_each(view, &ws->layer.view_list, layer_link) {
5236                 shsurf = get_shell_surface(view->surface);
5237                 if (shsurf &&
5238                     shsurf->type == SHELL_SURFACE_TOPLEVEL &&
5239                     shsurf->parent == NULL) {
5240                         if (first == NULL)
5241                                 first = view->surface;
5242                         if (prev == switcher->current)
5243                                 next = view->surface;
5244                         prev = view->surface;
5245                         view->alpha = 0.25;
5246                         weston_view_geometry_dirty(view);
5247                         weston_surface_damage(view->surface);
5248                 }
5249
5250                 if (is_black_surface(view->surface, NULL)) {
5251                         view->alpha = 0.25;
5252                         weston_view_geometry_dirty(view);
5253                         weston_surface_damage(view->surface);
5254                 }
5255         }
5256
5257         if (next == NULL)
5258                 next = first;
5259
5260         if (next == NULL)
5261                 return;
5262
5263         wl_list_remove(&switcher->listener.link);
5264         wl_signal_add(&next->destroy_signal, &switcher->listener);
5265
5266         switcher->current = next;
5267         wl_list_for_each(view, &next->views, surface_link)
5268                 view->alpha = 1.0;
5269
5270         shsurf = get_shell_surface(switcher->current);
5271         if (shsurf && shsurf->state.fullscreen)
5272                 shsurf->fullscreen.black_view->alpha = 1.0;
5273 }
5274
5275 static void
5276 switcher_handle_surface_destroy(struct wl_listener *listener, void *data)
5277 {
5278         struct switcher *switcher =
5279                 container_of(listener, struct switcher, listener);
5280
5281         switcher_next(switcher);
5282 }
5283
5284 static void
5285 switcher_destroy(struct switcher *switcher)
5286 {
5287         struct weston_view *view;
5288         struct weston_keyboard *keyboard = switcher->grab.keyboard;
5289         struct workspace *ws = get_current_workspace(switcher->shell);
5290
5291         wl_list_for_each(view, &ws->layer.view_list, layer_link) {
5292                 if (is_focus_view(view))
5293                         continue;
5294
5295                 view->alpha = 1.0;
5296                 weston_surface_damage(view->surface);
5297         }
5298
5299         if (switcher->current)
5300                 activate(switcher->shell, switcher->current,
5301                          (struct weston_seat *) keyboard->seat);
5302         wl_list_remove(&switcher->listener.link);
5303         weston_keyboard_end_grab(keyboard);
5304         if (keyboard->input_method_resource)
5305                 keyboard->grab = &keyboard->input_method_grab;
5306
5307          /* re-hide surfaces that were temporary shown during the switch */
5308         struct weston_view **minimized;
5309         wl_array_for_each(minimized, &switcher->minimized_array) {
5310                 /* with the exception of the current selected */
5311                 if ((*minimized)->surface != switcher->current) {
5312                         wl_list_remove(&(*minimized)->layer_link);
5313                         wl_list_insert(&switcher->shell->minimized_layer.view_list, &(*minimized)->layer_link);
5314                         weston_view_damage_below(*minimized);
5315                 }
5316         }
5317         wl_array_release(&switcher->minimized_array);
5318
5319         free(switcher);
5320 }
5321
5322 static void
5323 switcher_key(struct weston_keyboard_grab *grab,
5324              uint32_t time, uint32_t key, uint32_t state_w)
5325 {
5326         struct switcher *switcher = container_of(grab, struct switcher, grab);
5327         enum wl_keyboard_key_state state = state_w;
5328
5329         if (key == KEY_TAB && state == WL_KEYBOARD_KEY_STATE_PRESSED)
5330                 switcher_next(switcher);
5331 }
5332
5333 static void
5334 switcher_modifier(struct weston_keyboard_grab *grab, uint32_t serial,
5335                   uint32_t mods_depressed, uint32_t mods_latched,
5336                   uint32_t mods_locked, uint32_t group)
5337 {
5338         struct switcher *switcher = container_of(grab, struct switcher, grab);
5339         struct weston_seat *seat = (struct weston_seat *) grab->keyboard->seat;
5340
5341         if ((seat->modifier_state & switcher->shell->binding_modifier) == 0)
5342                 switcher_destroy(switcher);
5343 }
5344
5345 static void
5346 switcher_cancel(struct weston_keyboard_grab *grab)
5347 {
5348         struct switcher *switcher = container_of(grab, struct switcher, grab);
5349
5350         switcher_destroy(switcher);
5351 }
5352
5353 static const struct weston_keyboard_grab_interface switcher_grab = {
5354         switcher_key,
5355         switcher_modifier,
5356         switcher_cancel,
5357 };
5358
5359 static void
5360 switcher_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
5361                  void *data)
5362 {
5363         struct desktop_shell *shell = data;
5364         struct switcher *switcher;
5365
5366         switcher = malloc(sizeof *switcher);
5367         switcher->shell = shell;
5368         switcher->current = NULL;
5369         switcher->listener.notify = switcher_handle_surface_destroy;
5370         wl_list_init(&switcher->listener.link);
5371         wl_array_init(&switcher->minimized_array);
5372
5373         restore_all_output_modes(shell->compositor);
5374         lower_fullscreen_layer(switcher->shell);
5375         switcher->grab.interface = &switcher_grab;
5376         weston_keyboard_start_grab(seat->keyboard, &switcher->grab);
5377         weston_keyboard_set_focus(seat->keyboard, NULL);
5378         switcher_next(switcher);
5379 }
5380
5381 static void
5382 backlight_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
5383                   void *data)
5384 {
5385         struct weston_compositor *compositor = data;
5386         struct weston_output *output;
5387         long backlight_new = 0;
5388
5389         /* TODO: we're limiting to simple use cases, where we assume just
5390          * control on the primary display. We'd have to extend later if we
5391          * ever get support for setting backlights on random desktop LCD
5392          * panels though */
5393         output = get_default_output(compositor);
5394         if (!output)
5395                 return;
5396
5397         if (!output->set_backlight)
5398                 return;
5399
5400         if (key == KEY_F9 || key == KEY_BRIGHTNESSDOWN)
5401                 backlight_new = output->backlight_current - 25;
5402         else if (key == KEY_F10 || key == KEY_BRIGHTNESSUP)
5403                 backlight_new = output->backlight_current + 25;
5404
5405         if (backlight_new < 5)
5406                 backlight_new = 5;
5407         if (backlight_new > 255)
5408                 backlight_new = 255;
5409
5410         output->backlight_current = backlight_new;
5411         output->set_backlight(output, output->backlight_current);
5412 }
5413
5414 struct debug_binding_grab {
5415         struct weston_keyboard_grab grab;
5416         struct weston_seat *seat;
5417         uint32_t key[2];
5418         int key_released[2];
5419 };
5420
5421 static void
5422 debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time,
5423                   uint32_t key, uint32_t state)
5424 {
5425         struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
5426         struct weston_compositor *ec = db->seat->compositor;
5427         struct wl_display *display = ec->wl_display;
5428         struct wl_resource *resource;
5429         uint32_t serial;
5430         int send = 0, terminate = 0;
5431         int check_binding = 1;
5432         int i;
5433         struct wl_list *resource_list;
5434
5435         if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
5436                 /* Do not run bindings on key releases */
5437                 check_binding = 0;
5438
5439                 for (i = 0; i < 2; i++)
5440                         if (key == db->key[i])
5441                                 db->key_released[i] = 1;
5442
5443                 if (db->key_released[0] && db->key_released[1]) {
5444                         /* All key releases been swalled so end the grab */
5445                         terminate = 1;
5446                 } else if (key != db->key[0] && key != db->key[1]) {
5447                         /* Should not swallow release of other keys */
5448                         send = 1;
5449                 }
5450         } else if (key == db->key[0] && !db->key_released[0]) {
5451                 /* Do not check bindings for the first press of the binding
5452                  * key. This allows it to be used as a debug shortcut.
5453                  * We still need to swallow this event. */
5454                 check_binding = 0;
5455         } else if (db->key[1]) {
5456                 /* If we already ran a binding don't process another one since
5457                  * we can't keep track of all the binding keys that were
5458                  * pressed in order to swallow the release events. */
5459                 send = 1;
5460                 check_binding = 0;
5461         }
5462
5463         if (check_binding) {
5464                 if (weston_compositor_run_debug_binding(ec, db->seat, time,
5465                                                         key, state)) {
5466                         /* We ran a binding so swallow the press and keep the
5467                          * grab to swallow the released too. */
5468                         send = 0;
5469                         terminate = 0;
5470                         db->key[1] = key;
5471                 } else {
5472                         /* Terminate the grab since the key pressed is not a
5473                          * debug binding key. */
5474                         send = 1;
5475                         terminate = 1;
5476                 }
5477         }
5478
5479         if (send) {
5480                 serial = wl_display_next_serial(display);
5481                 resource_list = &grab->keyboard->focus_resource_list;
5482                 wl_resource_for_each(resource, resource_list) {
5483                         wl_keyboard_send_key(resource, serial, time, key, state);
5484                 }
5485         }
5486
5487         if (terminate) {
5488                 weston_keyboard_end_grab(grab->keyboard);
5489                 if (grab->keyboard->input_method_resource)
5490                         grab->keyboard->grab = &grab->keyboard->input_method_grab;
5491                 free(db);
5492         }
5493 }
5494
5495 static void
5496 debug_binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
5497                         uint32_t mods_depressed, uint32_t mods_latched,
5498                         uint32_t mods_locked, uint32_t group)
5499 {
5500         struct wl_resource *resource;
5501         struct wl_list *resource_list;
5502
5503         resource_list = &grab->keyboard->focus_resource_list;
5504
5505         wl_resource_for_each(resource, resource_list) {
5506                 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
5507                                            mods_latched, mods_locked, group);
5508         }
5509 }
5510
5511 static void
5512 debug_binding_cancel(struct weston_keyboard_grab *grab)
5513 {
5514         struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
5515
5516         weston_keyboard_end_grab(grab->keyboard);
5517         free(db);
5518 }
5519
5520 struct weston_keyboard_grab_interface debug_binding_keyboard_grab = {
5521         debug_binding_key,
5522         debug_binding_modifiers,
5523         debug_binding_cancel,
5524 };
5525
5526 static void
5527 debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
5528 {
5529         struct debug_binding_grab *grab;
5530
5531         grab = calloc(1, sizeof *grab);
5532         if (!grab)
5533                 return;
5534
5535         grab->seat = (struct weston_seat *) seat;
5536         grab->key[0] = key;
5537         grab->grab.interface = &debug_binding_keyboard_grab;
5538         weston_keyboard_start_grab(seat->keyboard, &grab->grab);
5539 }
5540
5541 static void
5542 force_kill_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
5543                    void *data)
5544 {
5545         struct weston_surface *focus_surface;
5546         struct wl_client *client;
5547         struct desktop_shell *shell = data;
5548         struct weston_compositor *compositor = shell->compositor;
5549         pid_t pid;
5550
5551         focus_surface = seat->keyboard->focus;
5552         if (!focus_surface)
5553                 return;
5554
5555         wl_signal_emit(&compositor->kill_signal, focus_surface);
5556
5557         client = wl_resource_get_client(focus_surface->resource);
5558         wl_client_get_credentials(client, &pid, NULL, NULL);
5559
5560         /* Skip clients that we launched ourselves (the credentials of
5561          * the socketpair is ours) */
5562         if (pid == getpid())
5563                 return;
5564
5565         kill(pid, SIGKILL);
5566 }
5567
5568 static void
5569 workspace_up_binding(struct weston_seat *seat, uint32_t time,
5570                      uint32_t key, void *data)
5571 {
5572         struct desktop_shell *shell = data;
5573         unsigned int new_index = shell->workspaces.current;
5574
5575         if (shell->locked)
5576                 return;
5577         if (new_index != 0)
5578                 new_index--;
5579
5580         change_workspace(shell, new_index);
5581 }
5582
5583 static void
5584 workspace_down_binding(struct weston_seat *seat, uint32_t time,
5585                        uint32_t key, void *data)
5586 {
5587         struct desktop_shell *shell = data;
5588         unsigned int new_index = shell->workspaces.current;
5589
5590         if (shell->locked)
5591                 return;
5592         if (new_index < shell->workspaces.num - 1)
5593                 new_index++;
5594
5595         change_workspace(shell, new_index);
5596 }
5597
5598 static void
5599 workspace_f_binding(struct weston_seat *seat, uint32_t time,
5600                     uint32_t key, void *data)
5601 {
5602         struct desktop_shell *shell = data;
5603         unsigned int new_index;
5604
5605         if (shell->locked)
5606                 return;
5607         new_index = key - KEY_F1;
5608         if (new_index >= shell->workspaces.num)
5609                 new_index = shell->workspaces.num - 1;
5610
5611         change_workspace(shell, new_index);
5612 }
5613
5614 static void
5615 workspace_move_surface_up_binding(struct weston_seat *seat, uint32_t time,
5616                                   uint32_t key, void *data)
5617 {
5618         struct desktop_shell *shell = data;
5619         unsigned int new_index = shell->workspaces.current;
5620
5621         if (shell->locked)
5622                 return;
5623
5624         if (new_index != 0)
5625                 new_index--;
5626
5627         take_surface_to_workspace_by_seat(shell, seat, new_index);
5628 }
5629
5630 static void
5631 workspace_move_surface_down_binding(struct weston_seat *seat, uint32_t time,
5632                                     uint32_t key, void *data)
5633 {
5634         struct desktop_shell *shell = data;
5635         unsigned int new_index = shell->workspaces.current;
5636
5637         if (shell->locked)
5638                 return;
5639
5640         if (new_index < shell->workspaces.num - 1)
5641                 new_index++;
5642
5643         take_surface_to_workspace_by_seat(shell, seat, new_index);
5644 }
5645
5646 static void
5647 shell_reposition_view_on_output_destroy(struct weston_view *view)
5648 {
5649         struct weston_output *output, *first_output;
5650         struct weston_compositor *ec = view->surface->compositor;
5651         struct shell_surface *shsurf;
5652         float x, y;
5653         int visible;
5654
5655         x = view->geometry.x;
5656         y = view->geometry.y;
5657
5658         /* At this point the destroyed output is not in the list anymore.
5659          * If the view is still visible somewhere, we leave where it is,
5660          * otherwise, move it to the first output. */
5661         visible = 0;
5662         wl_list_for_each(output, &ec->output_list, link) {
5663                 if (pixman_region32_contains_point(&output->region,
5664                                                    x, y, NULL)) {
5665                         visible = 1;
5666                         break;
5667                 }
5668         }
5669
5670         if (!visible) {
5671                 first_output = container_of(ec->output_list.next,
5672                                             struct weston_output, link);
5673
5674                 x = first_output->x + first_output->width / 4;
5675                 y = first_output->y + first_output->height / 4;
5676         }
5677
5678         weston_view_set_position(view, x, y);
5679
5680         shsurf = get_shell_surface(view->surface);
5681
5682         if (shsurf) {
5683                 shsurf->saved_position_valid = false;
5684                 shsurf->next_state.maximized = false;
5685                 shsurf->next_state.fullscreen = false;
5686                 shsurf->state_changed = true;
5687         }
5688 }
5689
5690 static void
5691 shell_reposition_views_on_output_destroy(struct shell_output *shell_output)
5692 {
5693         struct desktop_shell *shell = shell_output->shell;
5694         struct weston_output *output = shell_output->output;
5695         struct weston_layer *layer;
5696         struct weston_view *view;
5697
5698         /* Move all views in the layers owned by the shell */
5699         wl_list_for_each(layer, shell->fullscreen_layer.link.prev, link) {
5700                 wl_list_for_each(view, &layer->view_list, layer_link) {
5701                         if (view->output != output)
5702                                 continue;
5703
5704                         shell_reposition_view_on_output_destroy(view);
5705                 }
5706
5707                 /* We don't start from the beggining of the layer list, so
5708                  * make sure we don't wrap around it. */
5709                 if (layer == &shell->background_layer)
5710                         break;
5711         }
5712 }
5713
5714 static void
5715 handle_output_destroy(struct wl_listener *listener, void *data)
5716 {
5717         struct shell_output *output_listener =
5718                 container_of(listener, struct shell_output, destroy_listener);
5719
5720         shell_reposition_views_on_output_destroy(output_listener);
5721
5722         wl_list_remove(&output_listener->destroy_listener.link);
5723         wl_list_remove(&output_listener->link);
5724         free(output_listener);
5725 }
5726
5727 static void
5728 create_shell_output(struct desktop_shell *shell,
5729                                         struct weston_output *output)
5730 {
5731         struct shell_output *shell_output;
5732
5733         shell_output = zalloc(sizeof *shell_output);
5734         if (shell_output == NULL)
5735                 return;
5736
5737         shell_output->output = output;
5738         shell_output->shell = shell;
5739         shell_output->destroy_listener.notify = handle_output_destroy;
5740         wl_signal_add(&output->destroy_signal,
5741                       &shell_output->destroy_listener);
5742         wl_list_insert(shell->output_list.prev, &shell_output->link);
5743 }
5744
5745 static void
5746 handle_output_create(struct wl_listener *listener, void *data)
5747 {
5748         struct desktop_shell *shell =
5749                 container_of(listener, struct desktop_shell, output_create_listener);
5750         struct weston_output *output = (struct weston_output *)data;
5751
5752         create_shell_output(shell, output);
5753 }
5754
5755 static void
5756 handle_output_move(struct wl_listener *listener, void *data)
5757 {
5758         struct desktop_shell *shell;
5759         struct weston_output *output;
5760         struct weston_layer *layer;
5761         struct weston_view *view;
5762         float x, y;
5763
5764         shell = container_of(listener, struct desktop_shell,
5765                              output_move_listener);
5766         output = data;
5767
5768         /* Move all views in the layers owned by the shell */
5769         wl_list_for_each(layer, shell->fullscreen_layer.link.prev, link) {
5770                 wl_list_for_each(view, &layer->view_list, layer_link) {
5771                         if (view->output != output)
5772                                 continue;
5773
5774                         x = view->geometry.x + output->move_x;
5775                         y = view->geometry.y + output->move_y;
5776                         weston_view_set_position(view, x, y);
5777                 }
5778
5779                 /* We don't start from the beggining of the layer list, so
5780                  * make sure we don't wrap around it. */
5781                 if (layer == &shell->background_layer)
5782                         break;
5783         }
5784 }
5785
5786 static void
5787 setup_output_destroy_handler(struct weston_compositor *ec,
5788                                                         struct desktop_shell *shell)
5789 {
5790         struct weston_output *output;
5791
5792         wl_list_init(&shell->output_list);
5793         wl_list_for_each(output, &ec->output_list, link)
5794                 create_shell_output(shell, output);
5795
5796         shell->output_create_listener.notify = handle_output_create;
5797         wl_signal_add(&ec->output_created_signal,
5798                                 &shell->output_create_listener);
5799
5800         shell->output_move_listener.notify = handle_output_move;
5801         wl_signal_add(&ec->output_moved_signal, &shell->output_move_listener);
5802 }
5803
5804 static void
5805 shell_destroy(struct wl_listener *listener, void *data)
5806 {
5807         struct desktop_shell *shell =
5808                 container_of(listener, struct desktop_shell, destroy_listener);
5809         struct workspace **ws;
5810         struct shell_output *shell_output, *tmp;
5811
5812         /* Force state to unlocked so we don't try to fade */
5813         shell->locked = false;
5814         if (shell->child.client)
5815                 wl_client_destroy(shell->child.client);
5816
5817         wl_list_remove(&shell->idle_listener.link);
5818         wl_list_remove(&shell->wake_listener.link);
5819
5820         input_panel_destroy(shell);
5821
5822         wl_list_for_each_safe(shell_output, tmp, &shell->output_list, link) {
5823                 wl_list_remove(&shell_output->destroy_listener.link);
5824                 wl_list_remove(&shell_output->link);
5825                 free(shell_output);
5826         }
5827
5828         wl_list_remove(&shell->output_create_listener.link);
5829
5830         wl_array_for_each(ws, &shell->workspaces.array)
5831                 workspace_destroy(*ws);
5832         wl_array_release(&shell->workspaces.array);
5833
5834         free(shell->screensaver.path);
5835         free(shell->client);
5836         free(shell);
5837 }
5838
5839 static void
5840 shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
5841 {
5842         uint32_t mod;
5843         int i, num_workspace_bindings;
5844
5845         /* fixed bindings */
5846         weston_compositor_add_key_binding(ec, KEY_BACKSPACE,
5847                                           MODIFIER_CTRL | MODIFIER_ALT,
5848                                           terminate_binding, ec);
5849         weston_compositor_add_button_binding(ec, BTN_LEFT, 0,
5850                                              click_to_activate_binding,
5851                                              shell);
5852         weston_compositor_add_touch_binding(ec, 0,
5853                                             touch_to_activate_binding,
5854                                             shell);
5855         weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL,
5856                                            MODIFIER_SUPER | MODIFIER_ALT,
5857                                            surface_opacity_binding, NULL);
5858         weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL,
5859                                            MODIFIER_SUPER, zoom_axis_binding,
5860                                            NULL);
5861
5862         /* configurable bindings */
5863         mod = shell->binding_modifier;
5864         weston_compositor_add_key_binding(ec, KEY_PAGEUP, mod,
5865                                           zoom_key_binding, NULL);
5866         weston_compositor_add_key_binding(ec, KEY_PAGEDOWN, mod,
5867                                           zoom_key_binding, NULL);
5868         weston_compositor_add_key_binding(ec, KEY_M, mod | MODIFIER_SHIFT,
5869                                           maximize_binding, NULL);
5870         weston_compositor_add_key_binding(ec, KEY_F, mod | MODIFIER_SHIFT,
5871                                           fullscreen_binding, NULL);
5872         weston_compositor_add_button_binding(ec, BTN_LEFT, mod, move_binding,
5873                                              shell);
5874         weston_compositor_add_touch_binding(ec, mod, touch_move_binding, shell);
5875         weston_compositor_add_button_binding(ec, BTN_MIDDLE, mod,
5876                                              resize_binding, shell);
5877         weston_compositor_add_button_binding(ec, BTN_LEFT,
5878                                              mod | MODIFIER_SHIFT,
5879                                              resize_binding, shell);
5880
5881         if (ec->capabilities & WESTON_CAP_ROTATION_ANY)
5882                 weston_compositor_add_button_binding(ec, BTN_RIGHT, mod,
5883                                                      rotate_binding, NULL);
5884
5885         weston_compositor_add_key_binding(ec, KEY_TAB, mod, switcher_binding,
5886                                           shell);
5887         weston_compositor_add_key_binding(ec, KEY_F9, mod, backlight_binding,
5888                                           ec);
5889         weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSDOWN, 0,
5890                                           backlight_binding, ec);
5891         weston_compositor_add_key_binding(ec, KEY_F10, mod, backlight_binding,
5892                                           ec);
5893         weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSUP, 0,
5894                                           backlight_binding, ec);
5895         weston_compositor_add_key_binding(ec, KEY_K, mod,
5896                                           force_kill_binding, shell);
5897         weston_compositor_add_key_binding(ec, KEY_UP, mod,
5898                                           workspace_up_binding, shell);
5899         weston_compositor_add_key_binding(ec, KEY_DOWN, mod,
5900                                           workspace_down_binding, shell);
5901         weston_compositor_add_key_binding(ec, KEY_UP, mod | MODIFIER_SHIFT,
5902                                           workspace_move_surface_up_binding,
5903                                           shell);
5904         weston_compositor_add_key_binding(ec, KEY_DOWN, mod | MODIFIER_SHIFT,
5905                                           workspace_move_surface_down_binding,
5906                                           shell);
5907
5908         if (shell->exposay_modifier)
5909                 weston_compositor_add_modifier_binding(ec, shell->exposay_modifier,
5910                                                        exposay_binding, shell);
5911
5912         /* Add bindings for mod+F[1-6] for workspace 1 to 6. */
5913         if (shell->workspaces.num > 1) {
5914                 num_workspace_bindings = shell->workspaces.num;
5915                 if (num_workspace_bindings > 6)
5916                         num_workspace_bindings = 6;
5917                 for (i = 0; i < num_workspace_bindings; i++)
5918                         weston_compositor_add_key_binding(ec, KEY_F1 + i, mod,
5919                                                           workspace_f_binding,
5920                                                           shell);
5921         }
5922
5923         /* Debug bindings */
5924         weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_SHIFT,
5925                                           debug_binding, shell);
5926 }
5927
5928 WL_EXPORT int
5929 module_init(struct weston_compositor *ec,
5930             int *argc, char *argv[])
5931 {
5932         struct weston_seat *seat;
5933         struct desktop_shell *shell;
5934         struct workspace **pws;
5935         unsigned int i;
5936         struct wl_event_loop *loop;
5937
5938         shell = zalloc(sizeof *shell);
5939         if (shell == NULL)
5940                 return -1;
5941
5942         shell->compositor = ec;
5943
5944         shell->destroy_listener.notify = shell_destroy;
5945         wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
5946         shell->idle_listener.notify = idle_handler;
5947         wl_signal_add(&ec->idle_signal, &shell->idle_listener);
5948         shell->wake_listener.notify = wake_handler;
5949         wl_signal_add(&ec->wake_signal, &shell->wake_listener);
5950
5951         ec->shell_interface.shell = shell;
5952         ec->shell_interface.create_shell_surface = create_shell_surface;
5953         ec->shell_interface.get_primary_view = get_primary_view;
5954         ec->shell_interface.set_toplevel = set_toplevel;
5955         ec->shell_interface.set_transient = set_transient;
5956         ec->shell_interface.set_fullscreen = set_fullscreen;
5957         ec->shell_interface.set_xwayland = set_xwayland;
5958         ec->shell_interface.move = surface_move;
5959         ec->shell_interface.resize = surface_resize;
5960         ec->shell_interface.set_title = set_title;
5961
5962         weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
5963         weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
5964         weston_layer_init(&shell->background_layer, &shell->panel_layer.link);
5965         weston_layer_init(&shell->lock_layer, NULL);
5966         weston_layer_init(&shell->input_panel_layer, NULL);
5967
5968         wl_array_init(&shell->workspaces.array);
5969         wl_list_init(&shell->workspaces.client_list);
5970
5971         if (input_panel_setup(shell) < 0)
5972                 return -1;
5973
5974         shell_configuration(shell);
5975
5976         shell->exposay.state_cur = EXPOSAY_LAYOUT_INACTIVE;
5977         shell->exposay.state_target = EXPOSAY_TARGET_CANCEL;
5978
5979         for (i = 0; i < shell->workspaces.num; i++) {
5980                 pws = wl_array_add(&shell->workspaces.array, sizeof *pws);
5981                 if (pws == NULL)
5982                         return -1;
5983
5984                 *pws = workspace_create();
5985                 if (*pws == NULL)
5986                         return -1;
5987         }
5988         activate_workspace(shell, 0);
5989
5990         weston_layer_init(&shell->minimized_layer, NULL);
5991
5992         wl_list_init(&shell->workspaces.anim_sticky_list);
5993         wl_list_init(&shell->workspaces.animation.link);
5994         shell->workspaces.animation.frame = animate_workspace_change_frame;
5995
5996         if (wl_global_create(ec->wl_display, &wl_shell_interface, 1,
5997                                   shell, bind_shell) == NULL)
5998                 return -1;
5999
6000         if (wl_global_create(ec->wl_display, &xdg_shell_interface, 1,
6001                                   shell, bind_xdg_shell) == NULL)
6002                 return -1;
6003
6004         if (wl_global_create(ec->wl_display,
6005                              &desktop_shell_interface, 2,
6006                              shell, bind_desktop_shell) == NULL)
6007                 return -1;
6008
6009         if (wl_global_create(ec->wl_display, &screensaver_interface, 1,
6010                              shell, bind_screensaver) == NULL)
6011                 return -1;
6012
6013         if (wl_global_create(ec->wl_display, &workspace_manager_interface, 1,
6014                              shell, bind_workspace_manager) == NULL)
6015                 return -1;
6016
6017         shell->child.deathstamp = weston_compositor_get_time();
6018
6019         setup_output_destroy_handler(ec, shell);
6020
6021         loop = wl_display_get_event_loop(ec->wl_display);
6022         wl_event_loop_add_idle(loop, launch_desktop_shell_process, shell);
6023
6024         shell->screensaver.timer =
6025                 wl_event_loop_add_timer(loop, screensaver_timeout, shell);
6026
6027         wl_list_for_each(seat, &ec->seat_list, link) {
6028                 create_pointer_focus_listener(seat);
6029                 create_keyboard_focus_listener(seat);
6030         }
6031
6032         shell_add_bindings(ec, shell);
6033
6034         shell_fade_init(shell);
6035
6036         return 0;
6037 }