shell: position input panel layer above fullscreen layer
[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  *  • Input panel layer
76  *  • Fullscreen layer
77  *  • 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         if (shell->showing_input_panels) {
3890                 wl_list_insert(&shell->compositor->cursor_layer.link,
3891                                &shell->input_panel_layer.link);
3892                 wl_list_insert(&shell->input_panel_layer.link,
3893                                &shell->fullscreen_layer.link);
3894         } else {
3895                 wl_list_insert(&shell->compositor->cursor_layer.link,
3896                                &shell->fullscreen_layer.link);
3897         }
3898         wl_list_insert(&shell->fullscreen_layer.link,
3899                        &shell->panel_layer.link);
3900         wl_list_insert(&shell->panel_layer.link,
3901                        &ws->layer.link),
3902
3903         restore_focus_state(shell, get_current_workspace(shell));
3904
3905         shell->locked = false;
3906         shell_fade(shell, FADE_IN);
3907         weston_compositor_damage_all(shell->compositor);
3908 }
3909
3910 static void
3911 desktop_shell_unlock(struct wl_client *client,
3912                      struct wl_resource *resource)
3913 {
3914         struct desktop_shell *shell = wl_resource_get_user_data(resource);
3915
3916         shell->prepare_event_sent = false;
3917
3918         if (shell->locked)
3919                 resume_desktop(shell);
3920 }
3921
3922 static void
3923 desktop_shell_set_grab_surface(struct wl_client *client,
3924                                struct wl_resource *resource,
3925                                struct wl_resource *surface_resource)
3926 {
3927         struct desktop_shell *shell = wl_resource_get_user_data(resource);
3928
3929         shell->grab_surface = wl_resource_get_user_data(surface_resource);
3930         weston_view_create(shell->grab_surface);
3931 }
3932
3933 static void
3934 desktop_shell_desktop_ready(struct wl_client *client,
3935                             struct wl_resource *resource)
3936 {
3937         struct desktop_shell *shell = wl_resource_get_user_data(resource);
3938
3939         shell_fade_startup(shell);
3940 }
3941
3942 static const struct desktop_shell_interface desktop_shell_implementation = {
3943         desktop_shell_set_background,
3944         desktop_shell_set_panel,
3945         desktop_shell_set_lock_surface,
3946         desktop_shell_unlock,
3947         desktop_shell_set_grab_surface,
3948         desktop_shell_desktop_ready
3949 };
3950
3951 static enum shell_surface_type
3952 get_shell_surface_type(struct weston_surface *surface)
3953 {
3954         struct shell_surface *shsurf;
3955
3956         shsurf = get_shell_surface(surface);
3957         if (!shsurf)
3958                 return SHELL_SURFACE_NONE;
3959         return shsurf->type;
3960 }
3961
3962 static void
3963 move_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
3964 {
3965         struct weston_surface *focus;
3966         struct weston_surface *surface;
3967         struct shell_surface *shsurf;
3968
3969         if (seat->pointer->focus == NULL)
3970                 return;
3971
3972         focus = seat->pointer->focus->surface;
3973
3974         surface = weston_surface_get_main_surface(focus);
3975         if (surface == NULL)
3976                 return;
3977
3978         shsurf = get_shell_surface(surface);
3979         if (shsurf == NULL || shsurf->state.fullscreen ||
3980             shsurf->state.maximized)
3981                 return;
3982
3983         surface_move(shsurf, (struct weston_seat *) seat);
3984 }
3985
3986 static void
3987 maximize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
3988 {
3989         struct weston_surface *focus = seat->keyboard->focus;
3990         struct weston_surface *surface;
3991         struct shell_surface *shsurf;
3992         uint32_t serial;
3993
3994         surface = weston_surface_get_main_surface(focus);
3995         if (surface == NULL)
3996                 return;
3997
3998         shsurf = get_shell_surface(surface);
3999         if (shsurf == NULL)
4000                 return;
4001
4002         if (!shell_surface_is_xdg_surface(shsurf))
4003                 return;
4004
4005         serial = wl_display_next_serial(seat->compositor->wl_display);
4006         xdg_surface_change_state(shsurf, XDG_SURFACE_STATE_MAXIMIZED,
4007                                  !shsurf->state.maximized, serial);
4008 }
4009
4010 static void
4011 fullscreen_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
4012 {
4013         struct weston_surface *focus = seat->keyboard->focus;
4014         struct weston_surface *surface;
4015         struct shell_surface *shsurf;
4016         uint32_t serial;
4017
4018         surface = weston_surface_get_main_surface(focus);
4019         if (surface == NULL)
4020                 return;
4021
4022         shsurf = get_shell_surface(surface);
4023         if (shsurf == NULL)
4024                 return;
4025
4026         if (!shell_surface_is_xdg_surface(shsurf))
4027                 return;
4028
4029         serial = wl_display_next_serial(seat->compositor->wl_display);
4030         xdg_surface_change_state(shsurf, XDG_SURFACE_STATE_FULLSCREEN,
4031                                  !shsurf->state.fullscreen, serial);
4032 }
4033
4034 static void
4035 touch_move_binding(struct weston_seat *seat, uint32_t time, void *data)
4036 {
4037         struct weston_surface *focus = seat->touch->focus->surface;
4038         struct weston_surface *surface;
4039         struct shell_surface *shsurf;
4040
4041         surface = weston_surface_get_main_surface(focus);
4042         if (surface == NULL)
4043                 return;
4044
4045         shsurf = get_shell_surface(surface);
4046         if (shsurf == NULL || shsurf->state.fullscreen ||
4047             shsurf->state.maximized)
4048                 return;
4049
4050         surface_touch_move(shsurf, (struct weston_seat *) seat);
4051 }
4052
4053 static void
4054 resize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
4055 {
4056         struct weston_surface *focus;
4057         struct weston_surface *surface;
4058         uint32_t edges = 0;
4059         int32_t x, y;
4060         struct shell_surface *shsurf;
4061
4062         if (seat->pointer->focus == NULL)
4063                 return;
4064
4065         focus = seat->pointer->focus->surface;
4066
4067         surface = weston_surface_get_main_surface(focus);
4068         if (surface == NULL)
4069                 return;
4070
4071         shsurf = get_shell_surface(surface);
4072         if (shsurf == NULL || shsurf->state.fullscreen ||
4073             shsurf->state.maximized)
4074                 return;
4075
4076         weston_view_from_global(shsurf->view,
4077                                 wl_fixed_to_int(seat->pointer->grab_x),
4078                                 wl_fixed_to_int(seat->pointer->grab_y),
4079                                 &x, &y);
4080
4081         if (x < shsurf->surface->width / 3)
4082                 edges |= WL_SHELL_SURFACE_RESIZE_LEFT;
4083         else if (x < 2 * shsurf->surface->width / 3)
4084                 edges |= 0;
4085         else
4086                 edges |= WL_SHELL_SURFACE_RESIZE_RIGHT;
4087
4088         if (y < shsurf->surface->height / 3)
4089                 edges |= WL_SHELL_SURFACE_RESIZE_TOP;
4090         else if (y < 2 * shsurf->surface->height / 3)
4091                 edges |= 0;
4092         else
4093                 edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
4094
4095         surface_resize(shsurf, (struct weston_seat *) seat, edges);
4096 }
4097
4098 static void
4099 surface_opacity_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
4100                         wl_fixed_t value, void *data)
4101 {
4102         float step = 0.005;
4103         struct shell_surface *shsurf;
4104         struct weston_surface *focus = seat->pointer->focus->surface;
4105         struct weston_surface *surface;
4106
4107         /* XXX: broken for windows containing sub-surfaces */
4108         surface = weston_surface_get_main_surface(focus);
4109         if (surface == NULL)
4110                 return;
4111
4112         shsurf = get_shell_surface(surface);
4113         if (!shsurf)
4114                 return;
4115
4116         shsurf->view->alpha -= wl_fixed_to_double(value) * step;
4117
4118         if (shsurf->view->alpha > 1.0)
4119                 shsurf->view->alpha = 1.0;
4120         if (shsurf->view->alpha < step)
4121                 shsurf->view->alpha = step;
4122
4123         weston_view_geometry_dirty(shsurf->view);
4124         weston_surface_damage(surface);
4125 }
4126
4127 static void
4128 do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
4129         wl_fixed_t value)
4130 {
4131         struct weston_seat *ws = (struct weston_seat *) seat;
4132         struct weston_compositor *compositor = ws->compositor;
4133         struct weston_output *output;
4134         float increment;
4135
4136         wl_list_for_each(output, &compositor->output_list, link) {
4137                 if (pixman_region32_contains_point(&output->region,
4138                                                    wl_fixed_to_double(seat->pointer->x),
4139                                                    wl_fixed_to_double(seat->pointer->y),
4140                                                    NULL)) {
4141                         if (key == KEY_PAGEUP)
4142                                 increment = output->zoom.increment;
4143                         else if (key == KEY_PAGEDOWN)
4144                                 increment = -output->zoom.increment;
4145                         else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
4146                                 /* For every pixel zoom 20th of a step */
4147                                 increment = output->zoom.increment *
4148                                             -wl_fixed_to_double(value) / 20.0;
4149                         else
4150                                 increment = 0;
4151
4152                         output->zoom.level += increment;
4153
4154                         if (output->zoom.level < 0.0)
4155                                 output->zoom.level = 0.0;
4156                         else if (output->zoom.level > output->zoom.max_level)
4157                                 output->zoom.level = output->zoom.max_level;
4158                         else if (!output->zoom.active) {
4159                                 weston_output_activate_zoom(output);
4160                         }
4161
4162                         output->zoom.spring_z.target = output->zoom.level;
4163
4164                         weston_output_update_zoom(output);
4165                 }
4166         }
4167 }
4168
4169 static void
4170 zoom_axis_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
4171                   wl_fixed_t value, void *data)
4172 {
4173         do_zoom(seat, time, 0, axis, value);
4174 }
4175
4176 static void
4177 zoom_key_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
4178                  void *data)
4179 {
4180         do_zoom(seat, time, key, 0, 0);
4181 }
4182
4183 static void
4184 terminate_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
4185                   void *data)
4186 {
4187         struct weston_compositor *compositor = data;
4188
4189         wl_display_terminate(compositor->wl_display);
4190 }
4191
4192 static void
4193 rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
4194                    wl_fixed_t x, wl_fixed_t y)
4195 {
4196         struct rotate_grab *rotate =
4197                 container_of(grab, struct rotate_grab, base.grab);
4198         struct weston_pointer *pointer = grab->pointer;
4199         struct shell_surface *shsurf = rotate->base.shsurf;
4200         float cx, cy, dx, dy, cposx, cposy, dposx, dposy, r;
4201
4202         weston_pointer_move(pointer, x, y);
4203
4204         if (!shsurf)
4205                 return;
4206
4207         cx = 0.5f * shsurf->surface->width;
4208         cy = 0.5f * shsurf->surface->height;
4209
4210         dx = wl_fixed_to_double(pointer->x) - rotate->center.x;
4211         dy = wl_fixed_to_double(pointer->y) - rotate->center.y;
4212         r = sqrtf(dx * dx + dy * dy);
4213
4214         wl_list_remove(&shsurf->rotation.transform.link);
4215         weston_view_geometry_dirty(shsurf->view);
4216
4217         if (r > 20.0f) {
4218                 struct weston_matrix *matrix =
4219                         &shsurf->rotation.transform.matrix;
4220
4221                 weston_matrix_init(&rotate->rotation);
4222                 weston_matrix_rotate_xy(&rotate->rotation, dx / r, dy / r);
4223
4224                 weston_matrix_init(matrix);
4225                 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
4226                 weston_matrix_multiply(matrix, &shsurf->rotation.rotation);
4227                 weston_matrix_multiply(matrix, &rotate->rotation);
4228                 weston_matrix_translate(matrix, cx, cy, 0.0f);
4229
4230                 wl_list_insert(
4231                         &shsurf->view->geometry.transformation_list,
4232                         &shsurf->rotation.transform.link);
4233         } else {
4234                 wl_list_init(&shsurf->rotation.transform.link);
4235                 weston_matrix_init(&shsurf->rotation.rotation);
4236                 weston_matrix_init(&rotate->rotation);
4237         }
4238
4239         /* We need to adjust the position of the surface
4240          * in case it was resized in a rotated state before */
4241         cposx = shsurf->view->geometry.x + cx;
4242         cposy = shsurf->view->geometry.y + cy;
4243         dposx = rotate->center.x - cposx;
4244         dposy = rotate->center.y - cposy;
4245         if (dposx != 0.0f || dposy != 0.0f) {
4246                 weston_view_set_position(shsurf->view,
4247                                          shsurf->view->geometry.x + dposx,
4248                                          shsurf->view->geometry.y + dposy);
4249         }
4250
4251         /* Repaint implies weston_surface_update_transform(), which
4252          * lazily applies the damage due to rotation update.
4253          */
4254         weston_compositor_schedule_repaint(shsurf->surface->compositor);
4255 }
4256
4257 static void
4258 rotate_grab_button(struct weston_pointer_grab *grab,
4259                    uint32_t time, uint32_t button, uint32_t state_w)
4260 {
4261         struct rotate_grab *rotate =
4262                 container_of(grab, struct rotate_grab, base.grab);
4263         struct weston_pointer *pointer = grab->pointer;
4264         struct shell_surface *shsurf = rotate->base.shsurf;
4265         enum wl_pointer_button_state state = state_w;
4266
4267         if (pointer->button_count == 0 &&
4268             state == WL_POINTER_BUTTON_STATE_RELEASED) {
4269                 if (shsurf)
4270                         weston_matrix_multiply(&shsurf->rotation.rotation,
4271                                                &rotate->rotation);
4272                 shell_grab_end(&rotate->base);
4273                 free(rotate);
4274         }
4275 }
4276
4277 static void
4278 rotate_grab_cancel(struct weston_pointer_grab *grab)
4279 {
4280         struct rotate_grab *rotate =
4281                 container_of(grab, struct rotate_grab, base.grab);
4282
4283         shell_grab_end(&rotate->base);
4284         free(rotate);
4285 }
4286
4287 static const struct weston_pointer_grab_interface rotate_grab_interface = {
4288         noop_grab_focus,
4289         rotate_grab_motion,
4290         rotate_grab_button,
4291         rotate_grab_cancel,
4292 };
4293
4294 static void
4295 surface_rotate(struct shell_surface *surface, struct weston_seat *seat)
4296 {
4297         struct rotate_grab *rotate;
4298         float dx, dy;
4299         float r;
4300
4301         rotate = malloc(sizeof *rotate);
4302         if (!rotate)
4303                 return;
4304
4305         weston_view_to_global_float(surface->view,
4306                                     surface->surface->width * 0.5f,
4307                                     surface->surface->height * 0.5f,
4308                                     &rotate->center.x, &rotate->center.y);
4309
4310         dx = wl_fixed_to_double(seat->pointer->x) - rotate->center.x;
4311         dy = wl_fixed_to_double(seat->pointer->y) - rotate->center.y;
4312         r = sqrtf(dx * dx + dy * dy);
4313         if (r > 20.0f) {
4314                 struct weston_matrix inverse;
4315
4316                 weston_matrix_init(&inverse);
4317                 weston_matrix_rotate_xy(&inverse, dx / r, -dy / r);
4318                 weston_matrix_multiply(&surface->rotation.rotation, &inverse);
4319
4320                 weston_matrix_init(&rotate->rotation);
4321                 weston_matrix_rotate_xy(&rotate->rotation, dx / r, dy / r);
4322         } else {
4323                 weston_matrix_init(&surface->rotation.rotation);
4324                 weston_matrix_init(&rotate->rotation);
4325         }
4326
4327         shell_grab_start(&rotate->base, &rotate_grab_interface, surface,
4328                          seat->pointer, DESKTOP_SHELL_CURSOR_ARROW);
4329 }
4330
4331 static void
4332 rotate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
4333                void *data)
4334 {
4335         struct weston_surface *focus;
4336         struct weston_surface *base_surface;
4337         struct shell_surface *surface;
4338
4339         if (seat->pointer->focus == NULL)
4340                 return;
4341
4342         focus = seat->pointer->focus->surface;
4343
4344         base_surface = weston_surface_get_main_surface(focus);
4345         if (base_surface == NULL)
4346                 return;
4347
4348         surface = get_shell_surface(base_surface);
4349         if (surface == NULL || surface->state.fullscreen ||
4350             surface->state.maximized)
4351                 return;
4352
4353         surface_rotate(surface, seat);
4354 }
4355
4356 /* Move all fullscreen layers down to the current workspace in a non-reversible
4357  * manner. This should be used when implementing shell-wide overlays, such as
4358  * the alt-tab switcher, which need to de-promote fullscreen layers. */
4359 void
4360 lower_fullscreen_layer(struct desktop_shell *shell)
4361 {
4362         struct workspace *ws;
4363         struct weston_view *view, *prev;
4364
4365         ws = get_current_workspace(shell);
4366         wl_list_for_each_reverse_safe(view, prev,
4367                                       &shell->fullscreen_layer.view_list,
4368                                       layer_link) {
4369                 wl_list_remove(&view->layer_link);
4370                 wl_list_insert(&ws->layer.view_list, &view->layer_link);
4371                 weston_view_damage_below(view);
4372                 weston_surface_damage(view->surface);
4373         }
4374 }
4375
4376 void
4377 activate(struct desktop_shell *shell, struct weston_surface *es,
4378          struct weston_seat *seat)
4379 {
4380         struct weston_surface *main_surface;
4381         struct focus_state *state;
4382         struct workspace *ws;
4383         struct weston_surface *old_es;
4384         struct shell_surface *shsurf;
4385
4386         main_surface = weston_surface_get_main_surface(es);
4387
4388         weston_surface_activate(es, seat);
4389
4390         state = ensure_focus_state(shell, seat);
4391         if (state == NULL)
4392                 return;
4393
4394         old_es = state->keyboard_focus;
4395         focus_state_set_focus(state, es);
4396
4397         shsurf = get_shell_surface(main_surface);
4398         assert(shsurf);
4399
4400         if (shsurf->state.fullscreen)
4401                 shell_configure_fullscreen(shsurf);
4402         else
4403                 restore_all_output_modes(shell->compositor);
4404
4405         /* Update the surface’s layer. This brings it to the top of the stacking
4406          * order as appropriate. */
4407         shell_surface_update_layer(shsurf);
4408
4409         if (shell->focus_animation_type != ANIMATION_NONE) {
4410                 ws = get_current_workspace(shell);
4411                 animate_focus_change(shell, ws, get_default_view(old_es), get_default_view(es));
4412         }
4413 }
4414
4415 /* no-op func for checking black surface */
4416 static void
4417 black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
4418 {
4419 }
4420
4421 static bool
4422 is_black_surface (struct weston_surface *es, struct weston_surface **fs_surface)
4423 {
4424         if (es->configure == black_surface_configure) {
4425                 if (fs_surface)
4426                         *fs_surface = (struct weston_surface *)es->configure_private;
4427                 return true;
4428         }
4429         return false;
4430 }
4431
4432 static void
4433 activate_binding(struct weston_seat *seat,
4434                  struct desktop_shell *shell,
4435                  struct weston_surface *focus)
4436 {
4437         struct weston_surface *main_surface;
4438
4439         if (!focus)
4440                 return;
4441
4442         if (is_black_surface(focus, &main_surface))
4443                 focus = main_surface;
4444
4445         main_surface = weston_surface_get_main_surface(focus);
4446         if (get_shell_surface_type(main_surface) == SHELL_SURFACE_NONE)
4447                 return;
4448
4449         activate(shell, focus, seat);
4450 }
4451
4452 static void
4453 click_to_activate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
4454                           void *data)
4455 {
4456         if (seat->pointer->grab != &seat->pointer->default_grab)
4457                 return;
4458         if (seat->pointer->focus == NULL)
4459                 return;
4460
4461         activate_binding(seat, data, seat->pointer->focus->surface);
4462 }
4463
4464 static void
4465 touch_to_activate_binding(struct weston_seat *seat, uint32_t time, void *data)
4466 {
4467         if (seat->touch->grab != &seat->touch->default_grab)
4468                 return;
4469         if (seat->touch->focus == NULL)
4470                 return;
4471
4472         activate_binding(seat, data, seat->touch->focus->surface);
4473 }
4474
4475 static void
4476 lock(struct desktop_shell *shell)
4477 {
4478         struct workspace *ws = get_current_workspace(shell);
4479
4480         if (shell->locked) {
4481                 weston_compositor_sleep(shell->compositor);
4482                 return;
4483         }
4484
4485         shell->locked = true;
4486
4487         /* Hide all surfaces by removing the fullscreen, panel and
4488          * toplevel layers.  This way nothing else can show or receive
4489          * input events while we are locked. */
4490
4491         wl_list_remove(&shell->panel_layer.link);
4492         wl_list_remove(&shell->fullscreen_layer.link);
4493         if (shell->showing_input_panels)
4494                 wl_list_remove(&shell->input_panel_layer.link);
4495         wl_list_remove(&ws->layer.link);
4496         wl_list_insert(&shell->compositor->cursor_layer.link,
4497                        &shell->lock_layer.link);
4498
4499         launch_screensaver(shell);
4500
4501         /* TODO: disable bindings that should not work while locked. */
4502
4503         /* All this must be undone in resume_desktop(). */
4504 }
4505
4506 static void
4507 unlock(struct desktop_shell *shell)
4508 {
4509         if (!shell->locked || shell->lock_surface) {
4510                 shell_fade(shell, FADE_IN);
4511                 return;
4512         }
4513
4514         /* If desktop-shell client has gone away, unlock immediately. */
4515         if (!shell->child.desktop_shell) {
4516                 resume_desktop(shell);
4517                 return;
4518         }
4519
4520         if (shell->prepare_event_sent)
4521                 return;
4522
4523         desktop_shell_send_prepare_lock_surface(shell->child.desktop_shell);
4524         shell->prepare_event_sent = true;
4525 }
4526
4527 static void
4528 shell_fade_done(struct weston_view_animation *animation, void *data)
4529 {
4530         struct desktop_shell *shell = data;
4531
4532         shell->fade.animation = NULL;
4533
4534         switch (shell->fade.type) {
4535         case FADE_IN:
4536                 weston_surface_destroy(shell->fade.view->surface);
4537                 shell->fade.view = NULL;
4538                 break;
4539         case FADE_OUT:
4540                 lock(shell);
4541                 break;
4542         default:
4543                 break;
4544         }
4545 }
4546
4547 static struct weston_view *
4548 shell_fade_create_surface(struct desktop_shell *shell)
4549 {
4550         struct weston_compositor *compositor = shell->compositor;
4551         struct weston_surface *surface;
4552         struct weston_view *view;
4553
4554         surface = weston_surface_create(compositor);
4555         if (!surface)
4556                 return NULL;
4557
4558         view = weston_view_create(surface);
4559         if (!view) {
4560                 weston_surface_destroy(surface);
4561                 return NULL;
4562         }
4563
4564         weston_surface_set_size(surface, 8192, 8192);
4565         weston_view_set_position(view, 0, 0);
4566         weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
4567         wl_list_insert(&compositor->fade_layer.view_list,
4568                        &view->layer_link);
4569         pixman_region32_init(&surface->input);
4570
4571         return view;
4572 }
4573
4574 static void
4575 shell_fade(struct desktop_shell *shell, enum fade_type type)
4576 {
4577         float tint;
4578
4579         switch (type) {
4580         case FADE_IN:
4581                 tint = 0.0;
4582                 break;
4583         case FADE_OUT:
4584                 tint = 1.0;
4585                 break;
4586         default:
4587                 weston_log("shell: invalid fade type\n");
4588                 return;
4589         }
4590
4591         shell->fade.type = type;
4592
4593         if (shell->fade.view == NULL) {
4594                 shell->fade.view = shell_fade_create_surface(shell);
4595                 if (!shell->fade.view)
4596                         return;
4597
4598                 shell->fade.view->alpha = 1.0 - tint;
4599                 weston_view_update_transform(shell->fade.view);
4600         }
4601
4602         if (shell->fade.view->output == NULL) {
4603                 /* If the black view gets a NULL output, we lost the
4604                  * last output and we'll just cancel the fade.  This
4605                  * happens when you close the last window under the
4606                  * X11 or Wayland backends. */
4607                 shell->locked = false;
4608                 weston_surface_destroy(shell->fade.view->surface);
4609                 shell->fade.view = NULL;
4610         } else if (shell->fade.animation) {
4611                 weston_fade_update(shell->fade.animation, tint);
4612         } else {
4613                 shell->fade.animation =
4614                         weston_fade_run(shell->fade.view,
4615                                         1.0 - tint, tint, 300.0,
4616                                         shell_fade_done, shell);
4617         }
4618 }
4619
4620 static void
4621 do_shell_fade_startup(void *data)
4622 {
4623         struct desktop_shell *shell = data;
4624
4625         if (shell->startup_animation_type == ANIMATION_FADE)
4626                 shell_fade(shell, FADE_IN);
4627         else if (shell->startup_animation_type == ANIMATION_NONE) {
4628                 weston_surface_destroy(shell->fade.view->surface);
4629                 shell->fade.view = NULL;
4630         }
4631 }
4632
4633 static void
4634 shell_fade_startup(struct desktop_shell *shell)
4635 {
4636         struct wl_event_loop *loop;
4637
4638         if (!shell->fade.startup_timer)
4639                 return;
4640
4641         wl_event_source_remove(shell->fade.startup_timer);
4642         shell->fade.startup_timer = NULL;
4643
4644         loop = wl_display_get_event_loop(shell->compositor->wl_display);
4645         wl_event_loop_add_idle(loop, do_shell_fade_startup, shell);
4646 }
4647
4648 static int
4649 fade_startup_timeout(void *data)
4650 {
4651         struct desktop_shell *shell = data;
4652
4653         shell_fade_startup(shell);
4654         return 0;
4655 }
4656
4657 static void
4658 shell_fade_init(struct desktop_shell *shell)
4659 {
4660         /* Make compositor output all black, and wait for the desktop-shell
4661          * client to signal it is ready, then fade in. The timer triggers a
4662          * fade-in, in case the desktop-shell client takes too long.
4663          */
4664
4665         struct wl_event_loop *loop;
4666
4667         if (shell->fade.view != NULL) {
4668                 weston_log("%s: warning: fade surface already exists\n",
4669                            __func__);
4670                 return;
4671         }
4672
4673         shell->fade.view = shell_fade_create_surface(shell);
4674         if (!shell->fade.view)
4675                 return;
4676
4677         weston_view_update_transform(shell->fade.view);
4678         weston_surface_damage(shell->fade.view->surface);
4679
4680         loop = wl_display_get_event_loop(shell->compositor->wl_display);
4681         shell->fade.startup_timer =
4682                 wl_event_loop_add_timer(loop, fade_startup_timeout, shell);
4683         wl_event_source_timer_update(shell->fade.startup_timer, 15000);
4684 }
4685
4686 static void
4687 idle_handler(struct wl_listener *listener, void *data)
4688 {
4689         struct desktop_shell *shell =
4690                 container_of(listener, struct desktop_shell, idle_listener);
4691         struct weston_seat *seat;
4692
4693         wl_list_for_each(seat, &shell->compositor->seat_list, link)
4694                 if (seat->pointer)
4695                         popup_grab_end(seat->pointer);
4696
4697         shell_fade(shell, FADE_OUT);
4698         /* lock() is called from shell_fade_done() */
4699 }
4700
4701 static void
4702 wake_handler(struct wl_listener *listener, void *data)
4703 {
4704         struct desktop_shell *shell =
4705                 container_of(listener, struct desktop_shell, wake_listener);
4706
4707         unlock(shell);
4708 }
4709
4710 static void
4711 center_on_output(struct weston_view *view, struct weston_output *output)
4712 {
4713         int32_t surf_x, surf_y, width, height;
4714         float x, y;
4715
4716         surface_subsurfaces_boundingbox(view->surface, &surf_x, &surf_y, &width, &height);
4717
4718         x = output->x + (output->width - width) / 2 - surf_x / 2;
4719         y = output->y + (output->height - height) / 2 - surf_y / 2;
4720
4721         weston_view_set_position(view, x, y);
4722 }
4723
4724 static void
4725 weston_view_set_initial_position(struct weston_view *view,
4726                                  struct desktop_shell *shell)
4727 {
4728         struct weston_compositor *compositor = shell->compositor;
4729         int ix = 0, iy = 0;
4730         int range_x, range_y;
4731         int dx, dy, x, y, panel_height;
4732         struct weston_output *output, *target_output = NULL;
4733         struct weston_seat *seat;
4734
4735         /* As a heuristic place the new window on the same output as the
4736          * pointer. Falling back to the output containing 0, 0.
4737          *
4738          * TODO: Do something clever for touch too?
4739          */
4740         wl_list_for_each(seat, &compositor->seat_list, link) {
4741                 if (seat->pointer) {
4742                         ix = wl_fixed_to_int(seat->pointer->x);
4743                         iy = wl_fixed_to_int(seat->pointer->y);
4744                         break;
4745                 }
4746         }
4747
4748         wl_list_for_each(output, &compositor->output_list, link) {
4749                 if (pixman_region32_contains_point(&output->region, ix, iy, NULL)) {
4750                         target_output = output;
4751                         break;
4752                 }
4753         }
4754
4755         if (!target_output) {
4756                 weston_view_set_position(view, 10 + random() % 400,
4757                                          10 + random() % 400);
4758                 return;
4759         }
4760
4761         /* Valid range within output where the surface will still be onscreen.
4762          * If this is negative it means that the surface is bigger than
4763          * output.
4764          */
4765         panel_height = get_output_panel_height(shell, target_output);
4766         range_x = target_output->width - view->surface->width;
4767         range_y = (target_output->height - panel_height) -
4768                   view->surface->height;
4769
4770         if (range_x > 0)
4771                 dx = random() % range_x;
4772         else
4773                 dx = 0;
4774
4775         if (range_y > 0)
4776                 dy = panel_height + random() % range_y;
4777         else
4778                 dy = panel_height;
4779
4780         x = target_output->x + dx;
4781         y = target_output->y + dy;
4782
4783         weston_view_set_position(view, x, y);
4784 }
4785
4786 static void
4787 map(struct desktop_shell *shell, struct shell_surface *shsurf,
4788     int32_t sx, int32_t sy)
4789 {
4790         struct weston_compositor *compositor = shell->compositor;
4791         struct weston_seat *seat;
4792         int panel_height = 0;
4793         int32_t surf_x, surf_y;
4794
4795         /* initial positioning, see also configure() */
4796         switch (shsurf->type) {
4797         case SHELL_SURFACE_TOPLEVEL:
4798                 if (shsurf->state.fullscreen) {
4799                         center_on_output(shsurf->view, shsurf->fullscreen_output);
4800                         shell_map_fullscreen(shsurf);
4801                 } else if (shsurf->state.maximized) {
4802                         /* use surface configure to set the geometry */
4803                         panel_height = get_output_panel_height(shell, shsurf->output);
4804                         surface_subsurfaces_boundingbox(shsurf->surface,
4805                                                         &surf_x, &surf_y, NULL, NULL);
4806                         weston_view_set_position(shsurf->view,
4807                                                  shsurf->output->x - surf_x,
4808                                                  shsurf->output->y +
4809                                                  panel_height - surf_y);
4810                 } else if (!shsurf->state.relative) {
4811                         weston_view_set_initial_position(shsurf->view, shell);
4812                 }
4813                 break;
4814         case SHELL_SURFACE_POPUP:
4815                 shell_map_popup(shsurf);
4816                 break;
4817         case SHELL_SURFACE_NONE:
4818                 weston_view_set_position(shsurf->view,
4819                                          shsurf->view->geometry.x + sx,
4820                                          shsurf->view->geometry.y + sy);
4821                 break;
4822         case SHELL_SURFACE_XWAYLAND:
4823         default:
4824                 ;
4825         }
4826
4827         /* Surface stacking order, see also activate(). */
4828         shell_surface_update_layer(shsurf);
4829
4830         if (shsurf->type != SHELL_SURFACE_NONE) {
4831                 weston_view_update_transform(shsurf->view);
4832                 if (shsurf->state.maximized) {
4833                         shsurf->surface->output = shsurf->output;
4834                         shsurf->view->output = shsurf->output;
4835                 }
4836         }
4837
4838         switch (shsurf->type) {
4839         /* XXX: xwayland's using the same fields for transient type */
4840         case SHELL_SURFACE_XWAYLAND:
4841                 if (shsurf->transient.flags ==
4842                                 WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
4843                         break;
4844         case SHELL_SURFACE_TOPLEVEL:
4845                 if (shsurf->state.relative &&
4846                     shsurf->transient.flags == WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
4847                         break;
4848                 if (shell->locked)
4849                         break;
4850                 wl_list_for_each(seat, &compositor->seat_list, link)
4851                         activate(shell, shsurf->surface, seat);
4852                 break;
4853         case SHELL_SURFACE_POPUP:
4854         case SHELL_SURFACE_NONE:
4855         default:
4856                 break;
4857         }
4858
4859         if (shsurf->type == SHELL_SURFACE_TOPLEVEL &&
4860             !shsurf->state.maximized && !shsurf->state.fullscreen)
4861         {
4862                 switch (shell->win_animation_type) {
4863                 case ANIMATION_FADE:
4864                         weston_fade_run(shsurf->view, 0.0, 1.0, 300.0, NULL, NULL);
4865                         break;
4866                 case ANIMATION_ZOOM:
4867                         weston_zoom_run(shsurf->view, 0.5, 1.0, NULL, NULL);
4868                         break;
4869                 case ANIMATION_NONE:
4870                 default:
4871                         break;
4872                 }
4873         }
4874 }
4875
4876 static void
4877 configure(struct desktop_shell *shell, struct weston_surface *surface,
4878           float x, float y)
4879 {
4880         struct shell_surface *shsurf;
4881         struct weston_view *view;
4882         int32_t mx, my, surf_x, surf_y;
4883
4884         shsurf = get_shell_surface(surface);
4885
4886         assert(shsurf);
4887
4888         if (shsurf->state.fullscreen)
4889                 shell_configure_fullscreen(shsurf);
4890         else if (shsurf->state.maximized) {
4891                 /* setting x, y and using configure to change that geometry */
4892                 surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y,
4893                                                                  NULL, NULL);
4894                 mx = shsurf->output->x - surf_x;
4895                 my = shsurf->output->y +
4896                      get_output_panel_height(shell,shsurf->output) - surf_y;
4897                 weston_view_set_position(shsurf->view, mx, my);
4898         } else {
4899                 weston_view_set_position(shsurf->view, x, y);
4900         }
4901
4902         /* XXX: would a fullscreen surface need the same handling? */
4903         if (surface->output) {
4904                 wl_list_for_each(view, &surface->views, surface_link)
4905                         weston_view_update_transform(view);
4906
4907                 if (shsurf->state.maximized)
4908                         surface->output = shsurf->output;
4909         }
4910 }
4911
4912 static void
4913 shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
4914 {
4915         struct shell_surface *shsurf = get_shell_surface(es);
4916         struct desktop_shell *shell;
4917         int type_changed = 0;
4918
4919         assert(shsurf);
4920
4921         shell = shsurf->shell;
4922
4923         if (!weston_surface_is_mapped(es) &&
4924             !wl_list_empty(&shsurf->popup.grab_link)) {
4925                 remove_popup_grab(shsurf);
4926         }
4927
4928         if (es->width == 0)
4929                 return;
4930
4931         if (shsurf->state_changed) {
4932                 set_surface_type(shsurf);
4933                 type_changed = 1;
4934         }
4935
4936         if (!weston_surface_is_mapped(es)) {
4937                 map(shell, shsurf, sx, sy);
4938         } else if (type_changed || sx != 0 || sy != 0 ||
4939                    shsurf->last_width != es->width ||
4940                    shsurf->last_height != es->height) {
4941                 float from_x, from_y;
4942                 float to_x, to_y;
4943
4944                 if (shsurf->resize_edges) {
4945                         sx = 0;
4946                         sy = 0;
4947                 }
4948
4949                 if (shsurf->resize_edges & WL_SHELL_SURFACE_RESIZE_LEFT)
4950                         sx = shsurf->last_width - es->width;
4951                 if (shsurf->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP)
4952                         sy = shsurf->last_height - es->height;
4953
4954                 shsurf->last_width = es->width;
4955                 shsurf->last_height = es->height;
4956
4957                 weston_view_to_global_float(shsurf->view, 0, 0, &from_x, &from_y);
4958                 weston_view_to_global_float(shsurf->view, sx, sy, &to_x, &to_y);
4959                 configure(shell, es,
4960                           shsurf->view->geometry.x + to_x - from_x,
4961                           shsurf->view->geometry.y + to_y - from_y);
4962         }
4963 }
4964
4965 static void launch_desktop_shell_process(void *data);
4966
4967 static void
4968 desktop_shell_sigchld(struct weston_process *process, int status)
4969 {
4970         uint32_t time;
4971         struct desktop_shell *shell =
4972                 container_of(process, struct desktop_shell, child.process);
4973
4974         shell->child.process.pid = 0;
4975         shell->child.client = NULL; /* already destroyed by wayland */
4976
4977         /* if desktop-shell dies more than 5 times in 30 seconds, give up */
4978         time = weston_compositor_get_time();
4979         if (time - shell->child.deathstamp > 30000) {
4980                 shell->child.deathstamp = time;
4981                 shell->child.deathcount = 0;
4982         }
4983
4984         shell->child.deathcount++;
4985         if (shell->child.deathcount > 5) {
4986                 weston_log("%s died, giving up.\n", shell->client);
4987                 return;
4988         }
4989
4990         weston_log("%s died, respawning...\n", shell->client);
4991         launch_desktop_shell_process(shell);
4992         shell_fade_startup(shell);
4993 }
4994
4995 static void
4996 desktop_shell_client_destroy(struct wl_listener *listener, void *data)
4997 {
4998         struct desktop_shell *shell;
4999
5000         shell = container_of(listener, struct desktop_shell,
5001                              child.client_destroy_listener);
5002
5003         shell->child.client = NULL;
5004 }
5005
5006 static void
5007 launch_desktop_shell_process(void *data)
5008 {
5009         struct desktop_shell *shell = data;
5010
5011         shell->child.client = weston_client_launch(shell->compositor,
5012                                                  &shell->child.process,
5013                                                  shell->client,
5014                                                  desktop_shell_sigchld);
5015
5016         if (!shell->child.client)
5017                 weston_log("not able to start %s\n", shell->client);
5018
5019         shell->child.client_destroy_listener.notify =
5020                 desktop_shell_client_destroy;
5021         wl_client_add_destroy_listener(shell->child.client,
5022                                        &shell->child.client_destroy_listener);
5023 }
5024
5025 static void
5026 handle_shell_client_destroy(struct wl_listener *listener, void *data)
5027 {
5028         struct shell_client *sc =
5029                 container_of(listener, struct shell_client, destroy_listener);
5030
5031         if (sc->ping_timer)
5032                 wl_event_source_remove(sc->ping_timer);
5033         free(sc);
5034 }
5035
5036 static struct shell_client *
5037 shell_client_create(struct wl_client *client, struct desktop_shell *shell,
5038                     const struct wl_interface *interface, uint32_t id)
5039 {
5040         struct shell_client *sc;
5041
5042         sc = zalloc(sizeof *sc);
5043         if (sc == NULL) {
5044                 wl_client_post_no_memory(client);
5045                 return NULL;
5046         }
5047
5048         sc->resource = wl_resource_create(client, interface, 1, id);
5049         if (sc->resource == NULL) {
5050                 free(sc);
5051                 wl_client_post_no_memory(client);
5052                 return NULL;
5053         }
5054
5055         sc->client = client;
5056         sc->shell = shell;
5057         sc->destroy_listener.notify = handle_shell_client_destroy;
5058         wl_client_add_destroy_listener(client, &sc->destroy_listener);
5059
5060         return sc;
5061 }
5062
5063 static void
5064 bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
5065 {
5066         struct desktop_shell *shell = data;
5067         struct shell_client *sc;
5068
5069         sc = shell_client_create(client, shell, &wl_shell_interface, id);
5070         if (sc)
5071                 wl_resource_set_implementation(sc->resource,
5072                                                &shell_implementation,
5073                                                shell, NULL);
5074 }
5075
5076 static void
5077 bind_xdg_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
5078 {
5079         struct desktop_shell *shell = data;
5080         struct shell_client *sc;
5081
5082         sc = shell_client_create(client, shell, &xdg_shell_interface, id);
5083         if (sc)
5084                 wl_resource_set_dispatcher(sc->resource,
5085                                            xdg_shell_unversioned_dispatch,
5086                                            NULL, sc, NULL);
5087 }
5088
5089 static void
5090 unbind_desktop_shell(struct wl_resource *resource)
5091 {
5092         struct desktop_shell *shell = wl_resource_get_user_data(resource);
5093
5094         if (shell->locked)
5095                 resume_desktop(shell);
5096
5097         shell->child.desktop_shell = NULL;
5098         shell->prepare_event_sent = false;
5099 }
5100
5101 static void
5102 bind_desktop_shell(struct wl_client *client,
5103                    void *data, uint32_t version, uint32_t id)
5104 {
5105         struct desktop_shell *shell = data;
5106         struct wl_resource *resource;
5107
5108         resource = wl_resource_create(client, &desktop_shell_interface,
5109                                       MIN(version, 2), id);
5110
5111         if (client == shell->child.client) {
5112                 wl_resource_set_implementation(resource,
5113                                                &desktop_shell_implementation,
5114                                                shell, unbind_desktop_shell);
5115                 shell->child.desktop_shell = resource;
5116
5117                 if (version < 2)
5118                         shell_fade_startup(shell);
5119
5120                 return;
5121         }
5122
5123         wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
5124                                "permission to bind desktop_shell denied");
5125         wl_resource_destroy(resource);
5126 }
5127
5128 static void
5129 screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
5130 {
5131         struct desktop_shell *shell = surface->configure_private;
5132         struct weston_view *view;
5133
5134         if (surface->width == 0)
5135                 return;
5136
5137         /* XXX: starting weston-screensaver beforehand does not work */
5138         if (!shell->locked)
5139                 return;
5140
5141         view = container_of(surface->views.next, struct weston_view, surface_link);
5142         center_on_output(view, surface->output);
5143
5144         if (wl_list_empty(&view->layer_link)) {
5145                 wl_list_insert(shell->lock_layer.view_list.prev,
5146                                &view->layer_link);
5147                 weston_view_update_transform(view);
5148                 wl_event_source_timer_update(shell->screensaver.timer,
5149                                              shell->screensaver.duration);
5150                 shell_fade(shell, FADE_IN);
5151         }
5152 }
5153
5154 static void
5155 screensaver_set_surface(struct wl_client *client,
5156                         struct wl_resource *resource,
5157                         struct wl_resource *surface_resource,
5158                         struct wl_resource *output_resource)
5159 {
5160         struct desktop_shell *shell = wl_resource_get_user_data(resource);
5161         struct weston_surface *surface =
5162                 wl_resource_get_user_data(surface_resource);
5163         struct weston_output *output = wl_resource_get_user_data(output_resource);
5164         struct weston_view *view, *next;
5165
5166         /* Make sure we only have one view */
5167         wl_list_for_each_safe(view, next, &surface->views, surface_link)
5168                 weston_view_destroy(view);
5169         weston_view_create(surface);
5170
5171         surface->configure = screensaver_configure;
5172         surface->configure_private = shell;
5173         surface->output = output;
5174 }
5175
5176 static const struct screensaver_interface screensaver_implementation = {
5177         screensaver_set_surface
5178 };
5179
5180 static void
5181 unbind_screensaver(struct wl_resource *resource)
5182 {
5183         struct desktop_shell *shell = wl_resource_get_user_data(resource);
5184
5185         shell->screensaver.binding = NULL;
5186 }
5187
5188 static void
5189 bind_screensaver(struct wl_client *client,
5190                  void *data, uint32_t version, uint32_t id)
5191 {
5192         struct desktop_shell *shell = data;
5193         struct wl_resource *resource;
5194
5195         resource = wl_resource_create(client, &screensaver_interface, 1, id);
5196
5197         if (shell->screensaver.binding == NULL) {
5198                 wl_resource_set_implementation(resource,
5199                                                &screensaver_implementation,
5200                                                shell, unbind_screensaver);
5201                 shell->screensaver.binding = resource;
5202                 return;
5203         }
5204
5205         wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
5206                                "interface object already bound");
5207         wl_resource_destroy(resource);
5208 }
5209
5210 struct switcher {
5211         struct desktop_shell *shell;
5212         struct weston_surface *current;
5213         struct wl_listener listener;
5214         struct weston_keyboard_grab grab;
5215         struct wl_array minimized_array;
5216 };
5217
5218 static void
5219 switcher_next(struct switcher *switcher)
5220 {
5221         struct weston_view *view;
5222         struct weston_surface *first = NULL, *prev = NULL, *next = NULL;
5223         struct shell_surface *shsurf;
5224         struct workspace *ws = get_current_workspace(switcher->shell);
5225
5226          /* temporary re-display minimized surfaces */
5227         struct weston_view *tmp;
5228         struct weston_view **minimized;
5229         wl_list_for_each_safe(view, tmp, &switcher->shell->minimized_layer.view_list, layer_link) {
5230                 wl_list_remove(&view->layer_link);
5231                 wl_list_insert(&ws->layer.view_list, &view->layer_link);
5232                 minimized = wl_array_add(&switcher->minimized_array, sizeof *minimized);
5233                 *minimized = view;
5234         }
5235
5236         wl_list_for_each(view, &ws->layer.view_list, layer_link) {
5237                 shsurf = get_shell_surface(view->surface);
5238                 if (shsurf &&
5239                     shsurf->type == SHELL_SURFACE_TOPLEVEL &&
5240                     shsurf->parent == NULL) {
5241                         if (first == NULL)
5242                                 first = view->surface;
5243                         if (prev == switcher->current)
5244                                 next = view->surface;
5245                         prev = view->surface;
5246                         view->alpha = 0.25;
5247                         weston_view_geometry_dirty(view);
5248                         weston_surface_damage(view->surface);
5249                 }
5250
5251                 if (is_black_surface(view->surface, NULL)) {
5252                         view->alpha = 0.25;
5253                         weston_view_geometry_dirty(view);
5254                         weston_surface_damage(view->surface);
5255                 }
5256         }
5257
5258         if (next == NULL)
5259                 next = first;
5260
5261         if (next == NULL)
5262                 return;
5263
5264         wl_list_remove(&switcher->listener.link);
5265         wl_signal_add(&next->destroy_signal, &switcher->listener);
5266
5267         switcher->current = next;
5268         wl_list_for_each(view, &next->views, surface_link)
5269                 view->alpha = 1.0;
5270
5271         shsurf = get_shell_surface(switcher->current);
5272         if (shsurf && shsurf->state.fullscreen)
5273                 shsurf->fullscreen.black_view->alpha = 1.0;
5274 }
5275
5276 static void
5277 switcher_handle_surface_destroy(struct wl_listener *listener, void *data)
5278 {
5279         struct switcher *switcher =
5280                 container_of(listener, struct switcher, listener);
5281
5282         switcher_next(switcher);
5283 }
5284
5285 static void
5286 switcher_destroy(struct switcher *switcher)
5287 {
5288         struct weston_view *view;
5289         struct weston_keyboard *keyboard = switcher->grab.keyboard;
5290         struct workspace *ws = get_current_workspace(switcher->shell);
5291
5292         wl_list_for_each(view, &ws->layer.view_list, layer_link) {
5293                 if (is_focus_view(view))
5294                         continue;
5295
5296                 view->alpha = 1.0;
5297                 weston_surface_damage(view->surface);
5298         }
5299
5300         if (switcher->current)
5301                 activate(switcher->shell, switcher->current,
5302                          (struct weston_seat *) keyboard->seat);
5303         wl_list_remove(&switcher->listener.link);
5304         weston_keyboard_end_grab(keyboard);
5305         if (keyboard->input_method_resource)
5306                 keyboard->grab = &keyboard->input_method_grab;
5307
5308          /* re-hide surfaces that were temporary shown during the switch */
5309         struct weston_view **minimized;
5310         wl_array_for_each(minimized, &switcher->minimized_array) {
5311                 /* with the exception of the current selected */
5312                 if ((*minimized)->surface != switcher->current) {
5313                         wl_list_remove(&(*minimized)->layer_link);
5314                         wl_list_insert(&switcher->shell->minimized_layer.view_list, &(*minimized)->layer_link);
5315                         weston_view_damage_below(*minimized);
5316                 }
5317         }
5318         wl_array_release(&switcher->minimized_array);
5319
5320         free(switcher);
5321 }
5322
5323 static void
5324 switcher_key(struct weston_keyboard_grab *grab,
5325              uint32_t time, uint32_t key, uint32_t state_w)
5326 {
5327         struct switcher *switcher = container_of(grab, struct switcher, grab);
5328         enum wl_keyboard_key_state state = state_w;
5329
5330         if (key == KEY_TAB && state == WL_KEYBOARD_KEY_STATE_PRESSED)
5331                 switcher_next(switcher);
5332 }
5333
5334 static void
5335 switcher_modifier(struct weston_keyboard_grab *grab, uint32_t serial,
5336                   uint32_t mods_depressed, uint32_t mods_latched,
5337                   uint32_t mods_locked, uint32_t group)
5338 {
5339         struct switcher *switcher = container_of(grab, struct switcher, grab);
5340         struct weston_seat *seat = (struct weston_seat *) grab->keyboard->seat;
5341
5342         if ((seat->modifier_state & switcher->shell->binding_modifier) == 0)
5343                 switcher_destroy(switcher);
5344 }
5345
5346 static void
5347 switcher_cancel(struct weston_keyboard_grab *grab)
5348 {
5349         struct switcher *switcher = container_of(grab, struct switcher, grab);
5350
5351         switcher_destroy(switcher);
5352 }
5353
5354 static const struct weston_keyboard_grab_interface switcher_grab = {
5355         switcher_key,
5356         switcher_modifier,
5357         switcher_cancel,
5358 };
5359
5360 static void
5361 switcher_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
5362                  void *data)
5363 {
5364         struct desktop_shell *shell = data;
5365         struct switcher *switcher;
5366
5367         switcher = malloc(sizeof *switcher);
5368         switcher->shell = shell;
5369         switcher->current = NULL;
5370         switcher->listener.notify = switcher_handle_surface_destroy;
5371         wl_list_init(&switcher->listener.link);
5372         wl_array_init(&switcher->minimized_array);
5373
5374         restore_all_output_modes(shell->compositor);
5375         lower_fullscreen_layer(switcher->shell);
5376         switcher->grab.interface = &switcher_grab;
5377         weston_keyboard_start_grab(seat->keyboard, &switcher->grab);
5378         weston_keyboard_set_focus(seat->keyboard, NULL);
5379         switcher_next(switcher);
5380 }
5381
5382 static void
5383 backlight_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
5384                   void *data)
5385 {
5386         struct weston_compositor *compositor = data;
5387         struct weston_output *output;
5388         long backlight_new = 0;
5389
5390         /* TODO: we're limiting to simple use cases, where we assume just
5391          * control on the primary display. We'd have to extend later if we
5392          * ever get support for setting backlights on random desktop LCD
5393          * panels though */
5394         output = get_default_output(compositor);
5395         if (!output)
5396                 return;
5397
5398         if (!output->set_backlight)
5399                 return;
5400
5401         if (key == KEY_F9 || key == KEY_BRIGHTNESSDOWN)
5402                 backlight_new = output->backlight_current - 25;
5403         else if (key == KEY_F10 || key == KEY_BRIGHTNESSUP)
5404                 backlight_new = output->backlight_current + 25;
5405
5406         if (backlight_new < 5)
5407                 backlight_new = 5;
5408         if (backlight_new > 255)
5409                 backlight_new = 255;
5410
5411         output->backlight_current = backlight_new;
5412         output->set_backlight(output, output->backlight_current);
5413 }
5414
5415 struct debug_binding_grab {
5416         struct weston_keyboard_grab grab;
5417         struct weston_seat *seat;
5418         uint32_t key[2];
5419         int key_released[2];
5420 };
5421
5422 static void
5423 debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time,
5424                   uint32_t key, uint32_t state)
5425 {
5426         struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
5427         struct weston_compositor *ec = db->seat->compositor;
5428         struct wl_display *display = ec->wl_display;
5429         struct wl_resource *resource;
5430         uint32_t serial;
5431         int send = 0, terminate = 0;
5432         int check_binding = 1;
5433         int i;
5434         struct wl_list *resource_list;
5435
5436         if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
5437                 /* Do not run bindings on key releases */
5438                 check_binding = 0;
5439
5440                 for (i = 0; i < 2; i++)
5441                         if (key == db->key[i])
5442                                 db->key_released[i] = 1;
5443
5444                 if (db->key_released[0] && db->key_released[1]) {
5445                         /* All key releases been swalled so end the grab */
5446                         terminate = 1;
5447                 } else if (key != db->key[0] && key != db->key[1]) {
5448                         /* Should not swallow release of other keys */
5449                         send = 1;
5450                 }
5451         } else if (key == db->key[0] && !db->key_released[0]) {
5452                 /* Do not check bindings for the first press of the binding
5453                  * key. This allows it to be used as a debug shortcut.
5454                  * We still need to swallow this event. */
5455                 check_binding = 0;
5456         } else if (db->key[1]) {
5457                 /* If we already ran a binding don't process another one since
5458                  * we can't keep track of all the binding keys that were
5459                  * pressed in order to swallow the release events. */
5460                 send = 1;
5461                 check_binding = 0;
5462         }
5463
5464         if (check_binding) {
5465                 if (weston_compositor_run_debug_binding(ec, db->seat, time,
5466                                                         key, state)) {
5467                         /* We ran a binding so swallow the press and keep the
5468                          * grab to swallow the released too. */
5469                         send = 0;
5470                         terminate = 0;
5471                         db->key[1] = key;
5472                 } else {
5473                         /* Terminate the grab since the key pressed is not a
5474                          * debug binding key. */
5475                         send = 1;
5476                         terminate = 1;
5477                 }
5478         }
5479
5480         if (send) {
5481                 serial = wl_display_next_serial(display);
5482                 resource_list = &grab->keyboard->focus_resource_list;
5483                 wl_resource_for_each(resource, resource_list) {
5484                         wl_keyboard_send_key(resource, serial, time, key, state);
5485                 }
5486         }
5487
5488         if (terminate) {
5489                 weston_keyboard_end_grab(grab->keyboard);
5490                 if (grab->keyboard->input_method_resource)
5491                         grab->keyboard->grab = &grab->keyboard->input_method_grab;
5492                 free(db);
5493         }
5494 }
5495
5496 static void
5497 debug_binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
5498                         uint32_t mods_depressed, uint32_t mods_latched,
5499                         uint32_t mods_locked, uint32_t group)
5500 {
5501         struct wl_resource *resource;
5502         struct wl_list *resource_list;
5503
5504         resource_list = &grab->keyboard->focus_resource_list;
5505
5506         wl_resource_for_each(resource, resource_list) {
5507                 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
5508                                            mods_latched, mods_locked, group);
5509         }
5510 }
5511
5512 static void
5513 debug_binding_cancel(struct weston_keyboard_grab *grab)
5514 {
5515         struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
5516
5517         weston_keyboard_end_grab(grab->keyboard);
5518         free(db);
5519 }
5520
5521 struct weston_keyboard_grab_interface debug_binding_keyboard_grab = {
5522         debug_binding_key,
5523         debug_binding_modifiers,
5524         debug_binding_cancel,
5525 };
5526
5527 static void
5528 debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
5529 {
5530         struct debug_binding_grab *grab;
5531
5532         grab = calloc(1, sizeof *grab);
5533         if (!grab)
5534                 return;
5535
5536         grab->seat = (struct weston_seat *) seat;
5537         grab->key[0] = key;
5538         grab->grab.interface = &debug_binding_keyboard_grab;
5539         weston_keyboard_start_grab(seat->keyboard, &grab->grab);
5540 }
5541
5542 static void
5543 force_kill_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
5544                    void *data)
5545 {
5546         struct weston_surface *focus_surface;
5547         struct wl_client *client;
5548         struct desktop_shell *shell = data;
5549         struct weston_compositor *compositor = shell->compositor;
5550         pid_t pid;
5551
5552         focus_surface = seat->keyboard->focus;
5553         if (!focus_surface)
5554                 return;
5555
5556         wl_signal_emit(&compositor->kill_signal, focus_surface);
5557
5558         client = wl_resource_get_client(focus_surface->resource);
5559         wl_client_get_credentials(client, &pid, NULL, NULL);
5560
5561         /* Skip clients that we launched ourselves (the credentials of
5562          * the socketpair is ours) */
5563         if (pid == getpid())
5564                 return;
5565
5566         kill(pid, SIGKILL);
5567 }
5568
5569 static void
5570 workspace_up_binding(struct weston_seat *seat, uint32_t time,
5571                      uint32_t key, void *data)
5572 {
5573         struct desktop_shell *shell = data;
5574         unsigned int new_index = shell->workspaces.current;
5575
5576         if (shell->locked)
5577                 return;
5578         if (new_index != 0)
5579                 new_index--;
5580
5581         change_workspace(shell, new_index);
5582 }
5583
5584 static void
5585 workspace_down_binding(struct weston_seat *seat, uint32_t time,
5586                        uint32_t key, void *data)
5587 {
5588         struct desktop_shell *shell = data;
5589         unsigned int new_index = shell->workspaces.current;
5590
5591         if (shell->locked)
5592                 return;
5593         if (new_index < shell->workspaces.num - 1)
5594                 new_index++;
5595
5596         change_workspace(shell, new_index);
5597 }
5598
5599 static void
5600 workspace_f_binding(struct weston_seat *seat, uint32_t time,
5601                     uint32_t key, void *data)
5602 {
5603         struct desktop_shell *shell = data;
5604         unsigned int new_index;
5605
5606         if (shell->locked)
5607                 return;
5608         new_index = key - KEY_F1;
5609         if (new_index >= shell->workspaces.num)
5610                 new_index = shell->workspaces.num - 1;
5611
5612         change_workspace(shell, new_index);
5613 }
5614
5615 static void
5616 workspace_move_surface_up_binding(struct weston_seat *seat, uint32_t time,
5617                                   uint32_t key, void *data)
5618 {
5619         struct desktop_shell *shell = data;
5620         unsigned int new_index = shell->workspaces.current;
5621
5622         if (shell->locked)
5623                 return;
5624
5625         if (new_index != 0)
5626                 new_index--;
5627
5628         take_surface_to_workspace_by_seat(shell, seat, new_index);
5629 }
5630
5631 static void
5632 workspace_move_surface_down_binding(struct weston_seat *seat, uint32_t time,
5633                                     uint32_t key, void *data)
5634 {
5635         struct desktop_shell *shell = data;
5636         unsigned int new_index = shell->workspaces.current;
5637
5638         if (shell->locked)
5639                 return;
5640
5641         if (new_index < shell->workspaces.num - 1)
5642                 new_index++;
5643
5644         take_surface_to_workspace_by_seat(shell, seat, new_index);
5645 }
5646
5647 static void
5648 shell_reposition_view_on_output_destroy(struct weston_view *view)
5649 {
5650         struct weston_output *output, *first_output;
5651         struct weston_compositor *ec = view->surface->compositor;
5652         struct shell_surface *shsurf;
5653         float x, y;
5654         int visible;
5655
5656         x = view->geometry.x;
5657         y = view->geometry.y;
5658
5659         /* At this point the destroyed output is not in the list anymore.
5660          * If the view is still visible somewhere, we leave where it is,
5661          * otherwise, move it to the first output. */
5662         visible = 0;
5663         wl_list_for_each(output, &ec->output_list, link) {
5664                 if (pixman_region32_contains_point(&output->region,
5665                                                    x, y, NULL)) {
5666                         visible = 1;
5667                         break;
5668                 }
5669         }
5670
5671         if (!visible) {
5672                 first_output = container_of(ec->output_list.next,
5673                                             struct weston_output, link);
5674
5675                 x = first_output->x + first_output->width / 4;
5676                 y = first_output->y + first_output->height / 4;
5677         }
5678
5679         weston_view_set_position(view, x, y);
5680
5681         shsurf = get_shell_surface(view->surface);
5682
5683         if (shsurf) {
5684                 shsurf->saved_position_valid = false;
5685                 shsurf->next_state.maximized = false;
5686                 shsurf->next_state.fullscreen = false;
5687                 shsurf->state_changed = true;
5688         }
5689 }
5690
5691 static void
5692 shell_reposition_views_on_output_destroy(struct shell_output *shell_output)
5693 {
5694         struct desktop_shell *shell = shell_output->shell;
5695         struct weston_output *output = shell_output->output;
5696         struct weston_layer *layer;
5697         struct weston_view *view;
5698
5699         /* Move all views in the layers owned by the shell */
5700         wl_list_for_each(layer, shell->fullscreen_layer.link.prev, link) {
5701                 wl_list_for_each(view, &layer->view_list, layer_link) {
5702                         if (view->output != output)
5703                                 continue;
5704
5705                         shell_reposition_view_on_output_destroy(view);
5706                 }
5707
5708                 /* We don't start from the beggining of the layer list, so
5709                  * make sure we don't wrap around it. */
5710                 if (layer == &shell->background_layer)
5711                         break;
5712         }
5713 }
5714
5715 static void
5716 handle_output_destroy(struct wl_listener *listener, void *data)
5717 {
5718         struct shell_output *output_listener =
5719                 container_of(listener, struct shell_output, destroy_listener);
5720
5721         shell_reposition_views_on_output_destroy(output_listener);
5722
5723         wl_list_remove(&output_listener->destroy_listener.link);
5724         wl_list_remove(&output_listener->link);
5725         free(output_listener);
5726 }
5727
5728 static void
5729 create_shell_output(struct desktop_shell *shell,
5730                                         struct weston_output *output)
5731 {
5732         struct shell_output *shell_output;
5733
5734         shell_output = zalloc(sizeof *shell_output);
5735         if (shell_output == NULL)
5736                 return;
5737
5738         shell_output->output = output;
5739         shell_output->shell = shell;
5740         shell_output->destroy_listener.notify = handle_output_destroy;
5741         wl_signal_add(&output->destroy_signal,
5742                       &shell_output->destroy_listener);
5743         wl_list_insert(shell->output_list.prev, &shell_output->link);
5744 }
5745
5746 static void
5747 handle_output_create(struct wl_listener *listener, void *data)
5748 {
5749         struct desktop_shell *shell =
5750                 container_of(listener, struct desktop_shell, output_create_listener);
5751         struct weston_output *output = (struct weston_output *)data;
5752
5753         create_shell_output(shell, output);
5754 }
5755
5756 static void
5757 handle_output_move(struct wl_listener *listener, void *data)
5758 {
5759         struct desktop_shell *shell;
5760         struct weston_output *output;
5761         struct weston_layer *layer;
5762         struct weston_view *view;
5763         float x, y;
5764
5765         shell = container_of(listener, struct desktop_shell,
5766                              output_move_listener);
5767         output = data;
5768
5769         /* Move all views in the layers owned by the shell */
5770         wl_list_for_each(layer, shell->fullscreen_layer.link.prev, link) {
5771                 wl_list_for_each(view, &layer->view_list, layer_link) {
5772                         if (view->output != output)
5773                                 continue;
5774
5775                         x = view->geometry.x + output->move_x;
5776                         y = view->geometry.y + output->move_y;
5777                         weston_view_set_position(view, x, y);
5778                 }
5779
5780                 /* We don't start from the beggining of the layer list, so
5781                  * make sure we don't wrap around it. */
5782                 if (layer == &shell->background_layer)
5783                         break;
5784         }
5785 }
5786
5787 static void
5788 setup_output_destroy_handler(struct weston_compositor *ec,
5789                                                         struct desktop_shell *shell)
5790 {
5791         struct weston_output *output;
5792
5793         wl_list_init(&shell->output_list);
5794         wl_list_for_each(output, &ec->output_list, link)
5795                 create_shell_output(shell, output);
5796
5797         shell->output_create_listener.notify = handle_output_create;
5798         wl_signal_add(&ec->output_created_signal,
5799                                 &shell->output_create_listener);
5800
5801         shell->output_move_listener.notify = handle_output_move;
5802         wl_signal_add(&ec->output_moved_signal, &shell->output_move_listener);
5803 }
5804
5805 static void
5806 shell_destroy(struct wl_listener *listener, void *data)
5807 {
5808         struct desktop_shell *shell =
5809                 container_of(listener, struct desktop_shell, destroy_listener);
5810         struct workspace **ws;
5811         struct shell_output *shell_output, *tmp;
5812
5813         /* Force state to unlocked so we don't try to fade */
5814         shell->locked = false;
5815         if (shell->child.client)
5816                 wl_client_destroy(shell->child.client);
5817
5818         wl_list_remove(&shell->idle_listener.link);
5819         wl_list_remove(&shell->wake_listener.link);
5820
5821         input_panel_destroy(shell);
5822
5823         wl_list_for_each_safe(shell_output, tmp, &shell->output_list, link) {
5824                 wl_list_remove(&shell_output->destroy_listener.link);
5825                 wl_list_remove(&shell_output->link);
5826                 free(shell_output);
5827         }
5828
5829         wl_list_remove(&shell->output_create_listener.link);
5830
5831         wl_array_for_each(ws, &shell->workspaces.array)
5832                 workspace_destroy(*ws);
5833         wl_array_release(&shell->workspaces.array);
5834
5835         free(shell->screensaver.path);
5836         free(shell->client);
5837         free(shell);
5838 }
5839
5840 static void
5841 shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
5842 {
5843         uint32_t mod;
5844         int i, num_workspace_bindings;
5845
5846         /* fixed bindings */
5847         weston_compositor_add_key_binding(ec, KEY_BACKSPACE,
5848                                           MODIFIER_CTRL | MODIFIER_ALT,
5849                                           terminate_binding, ec);
5850         weston_compositor_add_button_binding(ec, BTN_LEFT, 0,
5851                                              click_to_activate_binding,
5852                                              shell);
5853         weston_compositor_add_touch_binding(ec, 0,
5854                                             touch_to_activate_binding,
5855                                             shell);
5856         weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL,
5857                                            MODIFIER_SUPER | MODIFIER_ALT,
5858                                            surface_opacity_binding, NULL);
5859         weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL,
5860                                            MODIFIER_SUPER, zoom_axis_binding,
5861                                            NULL);
5862
5863         /* configurable bindings */
5864         mod = shell->binding_modifier;
5865         weston_compositor_add_key_binding(ec, KEY_PAGEUP, mod,
5866                                           zoom_key_binding, NULL);
5867         weston_compositor_add_key_binding(ec, KEY_PAGEDOWN, mod,
5868                                           zoom_key_binding, NULL);
5869         weston_compositor_add_key_binding(ec, KEY_M, mod | MODIFIER_SHIFT,
5870                                           maximize_binding, NULL);
5871         weston_compositor_add_key_binding(ec, KEY_F, mod | MODIFIER_SHIFT,
5872                                           fullscreen_binding, NULL);
5873         weston_compositor_add_button_binding(ec, BTN_LEFT, mod, move_binding,
5874                                              shell);
5875         weston_compositor_add_touch_binding(ec, mod, touch_move_binding, shell);
5876         weston_compositor_add_button_binding(ec, BTN_MIDDLE, mod,
5877                                              resize_binding, shell);
5878         weston_compositor_add_button_binding(ec, BTN_LEFT,
5879                                              mod | MODIFIER_SHIFT,
5880                                              resize_binding, shell);
5881
5882         if (ec->capabilities & WESTON_CAP_ROTATION_ANY)
5883                 weston_compositor_add_button_binding(ec, BTN_RIGHT, mod,
5884                                                      rotate_binding, NULL);
5885
5886         weston_compositor_add_key_binding(ec, KEY_TAB, mod, switcher_binding,
5887                                           shell);
5888         weston_compositor_add_key_binding(ec, KEY_F9, mod, backlight_binding,
5889                                           ec);
5890         weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSDOWN, 0,
5891                                           backlight_binding, ec);
5892         weston_compositor_add_key_binding(ec, KEY_F10, mod, backlight_binding,
5893                                           ec);
5894         weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSUP, 0,
5895                                           backlight_binding, ec);
5896         weston_compositor_add_key_binding(ec, KEY_K, mod,
5897                                           force_kill_binding, shell);
5898         weston_compositor_add_key_binding(ec, KEY_UP, mod,
5899                                           workspace_up_binding, shell);
5900         weston_compositor_add_key_binding(ec, KEY_DOWN, mod,
5901                                           workspace_down_binding, shell);
5902         weston_compositor_add_key_binding(ec, KEY_UP, mod | MODIFIER_SHIFT,
5903                                           workspace_move_surface_up_binding,
5904                                           shell);
5905         weston_compositor_add_key_binding(ec, KEY_DOWN, mod | MODIFIER_SHIFT,
5906                                           workspace_move_surface_down_binding,
5907                                           shell);
5908
5909         if (shell->exposay_modifier)
5910                 weston_compositor_add_modifier_binding(ec, shell->exposay_modifier,
5911                                                        exposay_binding, shell);
5912
5913         /* Add bindings for mod+F[1-6] for workspace 1 to 6. */
5914         if (shell->workspaces.num > 1) {
5915                 num_workspace_bindings = shell->workspaces.num;
5916                 if (num_workspace_bindings > 6)
5917                         num_workspace_bindings = 6;
5918                 for (i = 0; i < num_workspace_bindings; i++)
5919                         weston_compositor_add_key_binding(ec, KEY_F1 + i, mod,
5920                                                           workspace_f_binding,
5921                                                           shell);
5922         }
5923
5924         /* Debug bindings */
5925         weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_SHIFT,
5926                                           debug_binding, shell);
5927 }
5928
5929 WL_EXPORT int
5930 module_init(struct weston_compositor *ec,
5931             int *argc, char *argv[])
5932 {
5933         struct weston_seat *seat;
5934         struct desktop_shell *shell;
5935         struct workspace **pws;
5936         unsigned int i;
5937         struct wl_event_loop *loop;
5938
5939         shell = zalloc(sizeof *shell);
5940         if (shell == NULL)
5941                 return -1;
5942
5943         shell->compositor = ec;
5944
5945         shell->destroy_listener.notify = shell_destroy;
5946         wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
5947         shell->idle_listener.notify = idle_handler;
5948         wl_signal_add(&ec->idle_signal, &shell->idle_listener);
5949         shell->wake_listener.notify = wake_handler;
5950         wl_signal_add(&ec->wake_signal, &shell->wake_listener);
5951
5952         ec->shell_interface.shell = shell;
5953         ec->shell_interface.create_shell_surface = create_shell_surface;
5954         ec->shell_interface.get_primary_view = get_primary_view;
5955         ec->shell_interface.set_toplevel = set_toplevel;
5956         ec->shell_interface.set_transient = set_transient;
5957         ec->shell_interface.set_fullscreen = set_fullscreen;
5958         ec->shell_interface.set_xwayland = set_xwayland;
5959         ec->shell_interface.move = surface_move;
5960         ec->shell_interface.resize = surface_resize;
5961         ec->shell_interface.set_title = set_title;
5962
5963         weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
5964         weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
5965         weston_layer_init(&shell->background_layer, &shell->panel_layer.link);
5966         weston_layer_init(&shell->lock_layer, NULL);
5967         weston_layer_init(&shell->input_panel_layer, NULL);
5968
5969         wl_array_init(&shell->workspaces.array);
5970         wl_list_init(&shell->workspaces.client_list);
5971
5972         if (input_panel_setup(shell) < 0)
5973                 return -1;
5974
5975         shell_configuration(shell);
5976
5977         shell->exposay.state_cur = EXPOSAY_LAYOUT_INACTIVE;
5978         shell->exposay.state_target = EXPOSAY_TARGET_CANCEL;
5979
5980         for (i = 0; i < shell->workspaces.num; i++) {
5981                 pws = wl_array_add(&shell->workspaces.array, sizeof *pws);
5982                 if (pws == NULL)
5983                         return -1;
5984
5985                 *pws = workspace_create();
5986                 if (*pws == NULL)
5987                         return -1;
5988         }
5989         activate_workspace(shell, 0);
5990
5991         weston_layer_init(&shell->minimized_layer, NULL);
5992
5993         wl_list_init(&shell->workspaces.anim_sticky_list);
5994         wl_list_init(&shell->workspaces.animation.link);
5995         shell->workspaces.animation.frame = animate_workspace_change_frame;
5996
5997         if (wl_global_create(ec->wl_display, &wl_shell_interface, 1,
5998                                   shell, bind_shell) == NULL)
5999                 return -1;
6000
6001         if (wl_global_create(ec->wl_display, &xdg_shell_interface, 1,
6002                                   shell, bind_xdg_shell) == NULL)
6003                 return -1;
6004
6005         if (wl_global_create(ec->wl_display,
6006                              &desktop_shell_interface, 2,
6007                              shell, bind_desktop_shell) == NULL)
6008                 return -1;
6009
6010         if (wl_global_create(ec->wl_display, &screensaver_interface, 1,
6011                              shell, bind_screensaver) == NULL)
6012                 return -1;
6013
6014         if (wl_global_create(ec->wl_display, &workspace_manager_interface, 1,
6015                              shell, bind_workspace_manager) == NULL)
6016                 return -1;
6017
6018         shell->child.deathstamp = weston_compositor_get_time();
6019
6020         setup_output_destroy_handler(ec, shell);
6021
6022         loop = wl_display_get_event_loop(ec->wl_display);
6023         wl_event_loop_add_idle(loop, launch_desktop_shell_process, shell);
6024
6025         shell->screensaver.timer =
6026                 wl_event_loop_add_timer(loop, screensaver_timeout, shell);
6027
6028         wl_list_for_each(seat, &ec->seat_list, link) {
6029                 create_pointer_focus_listener(seat);
6030                 create_keyboard_focus_listener(seat);
6031         }
6032
6033         shell_add_bindings(ec, shell);
6034
6035         shell_fade_init(shell);
6036
6037         return 0;
6038 }