e23c09b542f5b8b6648831b2a6c7eecb09eae5e3
[platform/upstream/weston.git] / src / shell.c
1 /*
2  * Copyright © 2010-2012 Intel Corporation
3  * Copyright © 2011-2012 Collabora, Ltd.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of the copyright holders not be used in
10  * advertising or publicity pertaining to distribution of the software
11  * without specific, written prior permission.  The copyright holders make
12  * no representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  */
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <stdbool.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <linux/input.h>
30 #include <assert.h>
31 #include <signal.h>
32 #include <math.h>
33 #include <sys/types.h>
34
35 #include <wayland-server.h>
36 #include "compositor.h"
37 #include "desktop-shell-server-protocol.h"
38 #include "input-method-server-protocol.h"
39 #include "workspaces-server-protocol.h"
40 #include "../shared/config-parser.h"
41
42 #define DEFAULT_NUM_WORKSPACES 1
43 #define DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH 200
44
45 enum animation_type {
46         ANIMATION_NONE,
47
48         ANIMATION_ZOOM,
49         ANIMATION_FADE
50 };
51
52 enum fade_type {
53         FADE_IN,
54         FADE_OUT
55 };
56
57 struct focus_state {
58         struct weston_seat *seat;
59         struct workspace *ws;
60         struct weston_surface *keyboard_focus;
61         struct wl_list link;
62         struct wl_listener seat_destroy_listener;
63         struct wl_listener surface_destroy_listener;
64 };
65
66 struct workspace {
67         struct weston_layer layer;
68
69         struct wl_list focus_list;
70         struct wl_listener seat_destroyed_listener;
71 };
72
73 struct input_panel_surface {
74         struct wl_resource resource;
75
76         struct desktop_shell *shell;
77
78         struct wl_list link;
79         struct weston_surface *surface;
80         struct wl_listener surface_destroy_listener;
81
82         struct weston_output *output;
83         uint32_t panel;
84 };
85
86 struct desktop_shell {
87         struct weston_compositor *compositor;
88
89         struct wl_listener idle_listener;
90         struct wl_listener wake_listener;
91         struct wl_listener destroy_listener;
92         struct wl_listener show_input_panel_listener;
93         struct wl_listener hide_input_panel_listener;
94         struct wl_listener update_input_panel_listener;
95
96         struct weston_layer fullscreen_layer;
97         struct weston_layer panel_layer;
98         struct weston_layer background_layer;
99         struct weston_layer lock_layer;
100         struct weston_layer input_panel_layer;
101
102         struct wl_listener pointer_focus_listener;
103         struct weston_surface *grab_surface;
104
105         struct {
106                 struct weston_process process;
107                 struct wl_client *client;
108                 struct wl_resource *desktop_shell;
109
110                 unsigned deathcount;
111                 uint32_t deathstamp;
112         } child;
113
114         bool locked;
115         bool showing_input_panels;
116         bool prepare_event_sent;
117
118         struct {
119                 struct weston_surface *surface;
120                 pixman_box32_t cursor_rectangle;
121         } text_input;
122
123         struct weston_surface *lock_surface;
124         struct wl_listener lock_surface_listener;
125
126         struct {
127                 struct wl_array array;
128                 unsigned int current;
129                 unsigned int num;
130
131                 struct wl_list client_list;
132
133                 struct weston_animation animation;
134                 struct wl_list anim_sticky_list;
135                 int anim_dir;
136                 uint32_t anim_timestamp;
137                 double anim_current;
138                 struct workspace *anim_from;
139                 struct workspace *anim_to;
140         } workspaces;
141
142         struct {
143                 char *path;
144                 int duration;
145                 struct wl_resource *binding;
146                 struct weston_process process;
147                 struct wl_event_source *timer;
148         } screensaver;
149
150         struct {
151                 struct wl_resource *binding;
152                 struct wl_list surfaces;
153         } input_panel;
154
155         struct {
156                 struct weston_surface *surface;
157                 struct weston_surface_animation *animation;
158                 enum fade_type type;
159         } fade;
160
161         uint32_t binding_modifier;
162         enum animation_type win_animation_type;
163 };
164
165 enum shell_surface_type {
166         SHELL_SURFACE_NONE,
167         SHELL_SURFACE_TOPLEVEL,
168         SHELL_SURFACE_TRANSIENT,
169         SHELL_SURFACE_FULLSCREEN,
170         SHELL_SURFACE_MAXIMIZED,
171         SHELL_SURFACE_POPUP
172 };
173
174 struct ping_timer {
175         struct wl_event_source *source;
176         uint32_t serial;
177 };
178
179 struct shell_surface {
180         struct wl_resource resource;
181
182         struct weston_surface *surface;
183         struct wl_listener surface_destroy_listener;
184         struct weston_surface *parent;
185         struct desktop_shell *shell;
186
187         enum shell_surface_type type, next_type;
188         char *title, *class;
189         int32_t saved_x, saved_y;
190         bool saved_position_valid;
191         bool saved_rotation_valid;
192         int unresponsive;
193
194         struct {
195                 struct weston_transform transform;
196                 struct weston_matrix rotation;
197         } rotation;
198
199         struct {
200                 struct wl_list grab_link;
201                 int32_t x, y;
202                 struct shell_seat *shseat;
203                 uint32_t serial;
204         } popup;
205
206         struct {
207                 int32_t x, y;
208                 uint32_t flags;
209         } transient;
210
211         struct {
212                 enum wl_shell_surface_fullscreen_method type;
213                 struct weston_transform transform; /* matrix from x, y */
214                 uint32_t framerate;
215                 struct weston_surface *black_surface;
216         } fullscreen;
217
218         struct ping_timer *ping_timer;
219
220         struct weston_transform workspace_transform;
221
222         struct weston_output *fullscreen_output;
223         struct weston_output *output;
224         struct wl_list link;
225
226         const struct weston_shell_client *client;
227 };
228
229 struct shell_grab {
230         struct weston_pointer_grab grab;
231         struct shell_surface *shsurf;
232         struct wl_listener shsurf_destroy_listener;
233         struct weston_pointer *pointer;
234 };
235
236 struct weston_move_grab {
237         struct shell_grab base;
238         wl_fixed_t dx, dy;
239 };
240
241 struct rotate_grab {
242         struct shell_grab base;
243         struct weston_matrix rotation;
244         struct {
245                 float x;
246                 float y;
247         } center;
248 };
249
250 struct shell_seat {
251         struct weston_seat *seat;
252         struct wl_listener seat_destroy_listener;
253
254         struct {
255                 struct weston_pointer_grab grab;
256                 struct wl_list surfaces_list;
257                 struct wl_client *client;
258                 int32_t initial_up;
259         } popup_grab;
260 };
261
262 static void
263 activate(struct desktop_shell *shell, struct weston_surface *es,
264          struct weston_seat *seat);
265
266 static struct workspace *
267 get_current_workspace(struct desktop_shell *shell);
268
269 static struct shell_surface *
270 get_shell_surface(struct weston_surface *surface);
271
272 static struct desktop_shell *
273 shell_surface_get_shell(struct shell_surface *shsurf);
274
275 static void
276 surface_rotate(struct shell_surface *surface, struct weston_seat *seat);
277
278 static bool
279 shell_surface_is_top_fullscreen(struct shell_surface *shsurf)
280 {
281         struct desktop_shell *shell;
282         struct weston_surface *top_fs_es;
283
284         shell = shell_surface_get_shell(shsurf);
285
286         if (wl_list_empty(&shell->fullscreen_layer.surface_list))
287                 return false;
288
289         top_fs_es = container_of(shell->fullscreen_layer.surface_list.next,
290                                  struct weston_surface,
291                                  layer_link);
292         return (shsurf == get_shell_surface(top_fs_es));
293 }
294
295 static void
296 destroy_shell_grab_shsurf(struct wl_listener *listener, void *data)
297 {
298         struct shell_grab *grab;
299
300         grab = container_of(listener, struct shell_grab,
301                             shsurf_destroy_listener);
302
303         grab->shsurf = NULL;
304 }
305
306 static void
307 popup_grab_end(struct weston_pointer *pointer);
308
309 static void
310 shell_grab_start(struct shell_grab *grab,
311                  const struct weston_pointer_grab_interface *interface,
312                  struct shell_surface *shsurf,
313                  struct weston_pointer *pointer,
314                  enum desktop_shell_cursor cursor)
315 {
316         struct desktop_shell *shell = shsurf->shell;
317
318         popup_grab_end(pointer);
319
320         grab->grab.interface = interface;
321         grab->shsurf = shsurf;
322         grab->shsurf_destroy_listener.notify = destroy_shell_grab_shsurf;
323         wl_signal_add(&shsurf->resource.destroy_signal,
324                       &grab->shsurf_destroy_listener);
325
326         grab->pointer = pointer;
327
328         weston_pointer_start_grab(pointer, &grab->grab);
329         desktop_shell_send_grab_cursor(shell->child.desktop_shell, cursor);
330         weston_pointer_set_focus(pointer, shell->grab_surface,
331                                  wl_fixed_from_int(0), wl_fixed_from_int(0));
332 }
333
334 static void
335 shell_grab_end(struct shell_grab *grab)
336 {
337         if (grab->shsurf)
338                 wl_list_remove(&grab->shsurf_destroy_listener.link);
339
340         weston_pointer_end_grab(grab->pointer);
341 }
342
343 static void
344 center_on_output(struct weston_surface *surface,
345                  struct weston_output *output);
346
347 static enum weston_keyboard_modifier
348 get_modifier(char *modifier)
349 {
350         if (!modifier)
351                 return MODIFIER_SUPER;
352
353         if (!strcmp("ctrl", modifier))
354                 return MODIFIER_CTRL;
355         else if (!strcmp("alt", modifier))
356                 return MODIFIER_ALT;
357         else if (!strcmp("super", modifier))
358                 return MODIFIER_SUPER;
359         else
360                 return MODIFIER_SUPER;
361 }
362
363 static enum animation_type
364 get_animation_type(char *animation)
365 {
366         if (!animation)
367                 return ANIMATION_NONE;
368
369         if (!strcmp("zoom", animation))
370                 return ANIMATION_ZOOM;
371         else if (!strcmp("fade", animation))
372                 return ANIMATION_FADE;
373         else
374                 return ANIMATION_NONE;
375 }
376
377 static void
378 shell_configuration(struct desktop_shell *shell, int config_fd)
379 {
380         char *path = NULL;
381         int duration = 60;
382         unsigned int num_workspaces = DEFAULT_NUM_WORKSPACES;
383         char *modifier = NULL;
384         char *win_animation = NULL;
385
386         struct config_key shell_keys[] = {
387                 { "binding-modifier",   CONFIG_KEY_STRING, &modifier },
388                 { "animation",          CONFIG_KEY_STRING, &win_animation},
389                 { "num-workspaces",
390                         CONFIG_KEY_UNSIGNED_INTEGER, &num_workspaces },
391         };
392
393         struct config_key saver_keys[] = {
394                 { "path",       CONFIG_KEY_STRING,  &path },
395                 { "duration",   CONFIG_KEY_INTEGER, &duration },
396         };
397
398         struct config_section cs[] = {
399                 { "shell", shell_keys, ARRAY_LENGTH(shell_keys), NULL },
400                 { "screensaver", saver_keys, ARRAY_LENGTH(saver_keys), NULL },
401         };
402
403         parse_config_file(config_fd, cs, ARRAY_LENGTH(cs), shell);
404
405         shell->screensaver.path = path;
406         shell->screensaver.duration = duration * 1000;
407         shell->binding_modifier = get_modifier(modifier);
408         shell->win_animation_type = get_animation_type(win_animation);
409         shell->workspaces.num = num_workspaces > 0 ? num_workspaces : 1;
410 }
411
412 static void
413 focus_state_destroy(struct focus_state *state)
414 {
415         wl_list_remove(&state->seat_destroy_listener.link);
416         wl_list_remove(&state->surface_destroy_listener.link);
417         free(state);
418 }
419
420 static void
421 focus_state_seat_destroy(struct wl_listener *listener, void *data)
422 {
423         struct focus_state *state = container_of(listener,
424                                                  struct focus_state,
425                                                  seat_destroy_listener);
426
427         wl_list_remove(&state->link);
428         focus_state_destroy(state);
429 }
430
431 static void
432 focus_state_surface_destroy(struct wl_listener *listener, void *data)
433 {
434         struct focus_state *state = container_of(listener,
435                                                  struct focus_state,
436                                                  surface_destroy_listener);
437         struct desktop_shell *shell;
438         struct weston_surface *main_surface;
439         struct weston_surface *surface, *next;
440
441         main_surface = weston_surface_get_main_surface(state->keyboard_focus);
442
443         next = NULL;
444         wl_list_for_each(surface, &state->ws->layer.surface_list, layer_link) {
445                 if (surface == main_surface)
446                         continue;
447
448                 next = surface;
449                 break;
450         }
451
452         /* if the focus was a sub-surface, activate its main surface */
453         if (main_surface != state->keyboard_focus)
454                 next = main_surface;
455
456         if (next) {
457                 shell = state->seat->compositor->shell_interface.shell;
458                 activate(shell, next, state->seat);
459         } else {
460                 wl_list_remove(&state->link);
461                 focus_state_destroy(state);
462         }
463 }
464
465 static struct focus_state *
466 focus_state_create(struct weston_seat *seat, struct workspace *ws)
467 {
468         struct focus_state *state;
469
470         state = malloc(sizeof *state);
471         if (state == NULL)
472                 return NULL;
473
474         state->ws = ws;
475         state->seat = seat;
476         wl_list_insert(&ws->focus_list, &state->link);
477
478         state->seat_destroy_listener.notify = focus_state_seat_destroy;
479         state->surface_destroy_listener.notify = focus_state_surface_destroy;
480         wl_signal_add(&seat->destroy_signal,
481                       &state->seat_destroy_listener);
482         wl_list_init(&state->surface_destroy_listener.link);
483
484         return state;
485 }
486
487 static struct focus_state *
488 ensure_focus_state(struct desktop_shell *shell, struct weston_seat *seat)
489 {
490         struct workspace *ws = get_current_workspace(shell);
491         struct focus_state *state;
492
493         wl_list_for_each(state, &ws->focus_list, link)
494                 if (state->seat == seat)
495                         break;
496
497         if (&state->link == &ws->focus_list)
498                 state = focus_state_create(seat, ws);
499
500         return state;
501 }
502
503 static void
504 restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
505 {
506         struct focus_state *state, *next;
507         struct weston_surface *surface;
508
509         wl_list_for_each_safe(state, next, &ws->focus_list, link) {
510                 surface = state->keyboard_focus;
511
512                 weston_keyboard_set_focus(state->seat->keyboard, surface);
513         }
514 }
515
516 static void
517 replace_focus_state(struct desktop_shell *shell, struct workspace *ws,
518                     struct weston_seat *seat)
519 {
520         struct focus_state *state;
521         struct weston_surface *surface;
522
523         wl_list_for_each(state, &ws->focus_list, link) {
524                 if (state->seat == seat) {
525                         surface = seat->keyboard->focus;
526                         state->keyboard_focus =
527                                 (struct weston_surface *) surface;
528                         return;
529                 }
530         }
531 }
532
533 static void
534 drop_focus_state(struct desktop_shell *shell, struct workspace *ws,
535                  struct weston_surface *surface)
536 {
537         struct focus_state *state;
538
539         wl_list_for_each(state, &ws->focus_list, link)
540                 if (state->keyboard_focus == surface)
541                         state->keyboard_focus = NULL;
542 }
543
544 static void
545 workspace_destroy(struct workspace *ws)
546 {
547         struct focus_state *state, *next;
548
549         wl_list_for_each_safe(state, next, &ws->focus_list, link)
550                 focus_state_destroy(state);
551
552         free(ws);
553 }
554
555 static void
556 seat_destroyed(struct wl_listener *listener, void *data)
557 {
558         struct weston_seat *seat = data;
559         struct focus_state *state, *next;
560         struct workspace *ws = container_of(listener,
561                                             struct workspace,
562                                             seat_destroyed_listener);
563
564         wl_list_for_each_safe(state, next, &ws->focus_list, link)
565                 if (state->seat == seat)
566                         wl_list_remove(&state->link);
567 }
568
569 static struct workspace *
570 workspace_create(void)
571 {
572         struct workspace *ws = malloc(sizeof *ws);
573         if (ws == NULL)
574                 return NULL;
575
576         weston_layer_init(&ws->layer, NULL);
577
578         wl_list_init(&ws->focus_list);
579         wl_list_init(&ws->seat_destroyed_listener.link);
580         ws->seat_destroyed_listener.notify = seat_destroyed;
581
582         return ws;
583 }
584
585 static int
586 workspace_is_empty(struct workspace *ws)
587 {
588         return wl_list_empty(&ws->layer.surface_list);
589 }
590
591 static struct workspace *
592 get_workspace(struct desktop_shell *shell, unsigned int index)
593 {
594         struct workspace **pws = shell->workspaces.array.data;
595         assert(index < shell->workspaces.num);
596         pws += index;
597         return *pws;
598 }
599
600 static struct workspace *
601 get_current_workspace(struct desktop_shell *shell)
602 {
603         return get_workspace(shell, shell->workspaces.current);
604 }
605
606 static void
607 activate_workspace(struct desktop_shell *shell, unsigned int index)
608 {
609         struct workspace *ws;
610
611         ws = get_workspace(shell, index);
612         wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
613
614         shell->workspaces.current = index;
615 }
616
617 static unsigned int
618 get_output_height(struct weston_output *output)
619 {
620         return abs(output->region.extents.y1 - output->region.extents.y2);
621 }
622
623 static void
624 surface_translate(struct weston_surface *surface, double d)
625 {
626         struct shell_surface *shsurf = get_shell_surface(surface);
627         struct weston_transform *transform;
628
629         transform = &shsurf->workspace_transform;
630         if (wl_list_empty(&transform->link))
631                 wl_list_insert(surface->geometry.transformation_list.prev,
632                                &shsurf->workspace_transform.link);
633
634         weston_matrix_init(&shsurf->workspace_transform.matrix);
635         weston_matrix_translate(&shsurf->workspace_transform.matrix,
636                                 0.0, d, 0.0);
637         weston_surface_geometry_dirty(surface);
638 }
639
640 static void
641 workspace_translate_out(struct workspace *ws, double fraction)
642 {
643         struct weston_surface *surface;
644         unsigned int height;
645         double d;
646
647         wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
648                 height = get_output_height(surface->output);
649                 d = height * fraction;
650
651                 surface_translate(surface, d);
652         }
653 }
654
655 static void
656 workspace_translate_in(struct workspace *ws, double fraction)
657 {
658         struct weston_surface *surface;
659         unsigned int height;
660         double d;
661
662         wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
663                 height = get_output_height(surface->output);
664
665                 if (fraction > 0)
666                         d = -(height - height * fraction);
667                 else
668                         d = height + height * fraction;
669
670                 surface_translate(surface, d);
671         }
672 }
673
674 static void
675 broadcast_current_workspace_state(struct desktop_shell *shell)
676 {
677         struct wl_resource *resource;
678
679         wl_list_for_each(resource, &shell->workspaces.client_list, link)
680                 workspace_manager_send_state(resource,
681                                              shell->workspaces.current,
682                                              shell->workspaces.num);
683 }
684
685 static void
686 reverse_workspace_change_animation(struct desktop_shell *shell,
687                                    unsigned int index,
688                                    struct workspace *from,
689                                    struct workspace *to)
690 {
691         shell->workspaces.current = index;
692
693         shell->workspaces.anim_to = to;
694         shell->workspaces.anim_from = from;
695         shell->workspaces.anim_dir = -1 * shell->workspaces.anim_dir;
696         shell->workspaces.anim_timestamp = 0;
697
698         weston_compositor_schedule_repaint(shell->compositor);
699 }
700
701 static void
702 workspace_deactivate_transforms(struct workspace *ws)
703 {
704         struct weston_surface *surface;
705         struct shell_surface *shsurf;
706
707         wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
708                 shsurf = get_shell_surface(surface);
709                 if (!wl_list_empty(&shsurf->workspace_transform.link)) {
710                         wl_list_remove(&shsurf->workspace_transform.link);
711                         wl_list_init(&shsurf->workspace_transform.link);
712                 }
713                 weston_surface_geometry_dirty(surface);
714         }
715 }
716
717 static void
718 finish_workspace_change_animation(struct desktop_shell *shell,
719                                   struct workspace *from,
720                                   struct workspace *to)
721 {
722         weston_compositor_schedule_repaint(shell->compositor);
723
724         wl_list_remove(&shell->workspaces.animation.link);
725         workspace_deactivate_transforms(from);
726         workspace_deactivate_transforms(to);
727         shell->workspaces.anim_to = NULL;
728
729         wl_list_remove(&shell->workspaces.anim_from->layer.link);
730 }
731
732 static void
733 animate_workspace_change_frame(struct weston_animation *animation,
734                                struct weston_output *output, uint32_t msecs)
735 {
736         struct desktop_shell *shell =
737                 container_of(animation, struct desktop_shell,
738                              workspaces.animation);
739         struct workspace *from = shell->workspaces.anim_from;
740         struct workspace *to = shell->workspaces.anim_to;
741         uint32_t t;
742         double x, y;
743
744         if (workspace_is_empty(from) && workspace_is_empty(to)) {
745                 finish_workspace_change_animation(shell, from, to);
746                 return;
747         }
748
749         if (shell->workspaces.anim_timestamp == 0) {
750                 if (shell->workspaces.anim_current == 0.0)
751                         shell->workspaces.anim_timestamp = msecs;
752                 else
753                         shell->workspaces.anim_timestamp =
754                                 msecs -
755                                 /* Invers of movement function 'y' below. */
756                                 (asin(1.0 - shell->workspaces.anim_current) *
757                                  DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH *
758                                  M_2_PI);
759         }
760
761         t = msecs - shell->workspaces.anim_timestamp;
762
763         /*
764          * x = [0, π/2]
765          * y(x) = sin(x)
766          */
767         x = t * (1.0/DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH) * M_PI_2;
768         y = sin(x);
769
770         if (t < DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH) {
771                 weston_compositor_schedule_repaint(shell->compositor);
772
773                 workspace_translate_out(from, shell->workspaces.anim_dir * y);
774                 workspace_translate_in(to, shell->workspaces.anim_dir * y);
775                 shell->workspaces.anim_current = y;
776
777                 weston_compositor_schedule_repaint(shell->compositor);
778         }
779         else
780                 finish_workspace_change_animation(shell, from, to);
781 }
782
783 static void
784 animate_workspace_change(struct desktop_shell *shell,
785                          unsigned int index,
786                          struct workspace *from,
787                          struct workspace *to)
788 {
789         struct weston_output *output;
790
791         int dir;
792
793         if (index > shell->workspaces.current)
794                 dir = -1;
795         else
796                 dir = 1;
797
798         shell->workspaces.current = index;
799
800         shell->workspaces.anim_dir = dir;
801         shell->workspaces.anim_from = from;
802         shell->workspaces.anim_to = to;
803         shell->workspaces.anim_current = 0.0;
804         shell->workspaces.anim_timestamp = 0;
805
806         output = container_of(shell->compositor->output_list.next,
807                               struct weston_output, link);
808         wl_list_insert(&output->animation_list,
809                        &shell->workspaces.animation.link);
810
811         wl_list_insert(from->layer.link.prev, &to->layer.link);
812
813         workspace_translate_in(to, 0);
814
815         restore_focus_state(shell, to);
816
817         weston_compositor_schedule_repaint(shell->compositor);
818 }
819
820 static void
821 update_workspace(struct desktop_shell *shell, unsigned int index,
822                  struct workspace *from, struct workspace *to)
823 {
824         shell->workspaces.current = index;
825         wl_list_insert(&from->layer.link, &to->layer.link);
826         wl_list_remove(&from->layer.link);
827 }
828
829 static void
830 change_workspace(struct desktop_shell *shell, unsigned int index)
831 {
832         struct workspace *from;
833         struct workspace *to;
834
835         if (index == shell->workspaces.current)
836                 return;
837
838         /* Don't change workspace when there is any fullscreen surfaces. */
839         if (!wl_list_empty(&shell->fullscreen_layer.surface_list))
840                 return;
841
842         from = get_current_workspace(shell);
843         to = get_workspace(shell, index);
844
845         if (shell->workspaces.anim_from == to &&
846             shell->workspaces.anim_to == from) {
847                 restore_focus_state(shell, to);
848                 reverse_workspace_change_animation(shell, index, from, to);
849                 broadcast_current_workspace_state(shell);
850                 return;
851         }
852
853         if (shell->workspaces.anim_to != NULL)
854                 finish_workspace_change_animation(shell,
855                                                   shell->workspaces.anim_from,
856                                                   shell->workspaces.anim_to);
857
858         restore_focus_state(shell, to);
859
860         if (workspace_is_empty(to) && workspace_is_empty(from))
861                 update_workspace(shell, index, from, to);
862         else
863                 animate_workspace_change(shell, index, from, to);
864
865         broadcast_current_workspace_state(shell);
866 }
867
868 static bool
869 workspace_has_only(struct workspace *ws, struct weston_surface *surface)
870 {
871         struct wl_list *list = &ws->layer.surface_list;
872         struct wl_list *e;
873
874         if (wl_list_empty(list))
875                 return false;
876
877         e = list->next;
878
879         if (e->next != list)
880                 return false;
881
882         return container_of(e, struct weston_surface, layer_link) == surface;
883 }
884
885 static void
886 move_surface_to_workspace(struct desktop_shell *shell,
887                           struct weston_surface *surface,
888                           uint32_t workspace)
889 {
890         struct workspace *from;
891         struct workspace *to;
892         struct weston_seat *seat;
893         struct weston_surface *focus;
894
895         assert(weston_surface_get_main_surface(surface) == surface);
896
897         if (workspace == shell->workspaces.current)
898                 return;
899
900         if (workspace >= shell->workspaces.num)
901                 workspace = shell->workspaces.num - 1;
902
903         from = get_current_workspace(shell);
904         to = get_workspace(shell, workspace);
905
906         wl_list_remove(&surface->layer_link);
907         wl_list_insert(&to->layer.surface_list, &surface->layer_link);
908
909         drop_focus_state(shell, from, surface);
910         wl_list_for_each(seat, &shell->compositor->seat_list, link) {
911                 if (!seat->keyboard)
912                         continue;
913
914                 focus = weston_surface_get_main_surface(seat->keyboard->focus);
915                 if (focus == surface)
916                         weston_keyboard_set_focus(seat->keyboard, NULL);
917         }
918
919         weston_surface_damage_below(surface);
920 }
921
922 static void
923 take_surface_to_workspace_by_seat(struct desktop_shell *shell,
924                                   struct weston_seat *seat,
925                                   unsigned int index)
926 {
927         struct weston_surface *surface;
928         struct shell_surface *shsurf;
929         struct workspace *from;
930         struct workspace *to;
931         struct focus_state *state;
932
933         surface = weston_surface_get_main_surface(seat->keyboard->focus);
934         if (surface == NULL ||
935             index == shell->workspaces.current)
936                 return;
937
938         from = get_current_workspace(shell);
939         to = get_workspace(shell, index);
940
941         wl_list_remove(&surface->layer_link);
942         wl_list_insert(&to->layer.surface_list, &surface->layer_link);
943
944         replace_focus_state(shell, to, seat);
945         drop_focus_state(shell, from, surface);
946
947         if (shell->workspaces.anim_from == to &&
948             shell->workspaces.anim_to == from) {
949                 wl_list_remove(&to->layer.link);
950                 wl_list_insert(from->layer.link.prev, &to->layer.link);
951
952                 reverse_workspace_change_animation(shell, index, from, to);
953                 broadcast_current_workspace_state(shell);
954
955                 return;
956         }
957
958         if (shell->workspaces.anim_to != NULL)
959                 finish_workspace_change_animation(shell,
960                                                   shell->workspaces.anim_from,
961                                                   shell->workspaces.anim_to);
962
963         if (workspace_is_empty(from) &&
964             workspace_has_only(to, surface))
965                 update_workspace(shell, index, from, to);
966         else {
967                 shsurf = get_shell_surface(surface);
968                 if (wl_list_empty(&shsurf->workspace_transform.link))
969                         wl_list_insert(&shell->workspaces.anim_sticky_list,
970                                        &shsurf->workspace_transform.link);
971
972                 animate_workspace_change(shell, index, from, to);
973         }
974
975         broadcast_current_workspace_state(shell);
976
977         state = ensure_focus_state(shell, seat);
978         if (state != NULL)
979                 state->keyboard_focus = surface;
980 }
981
982 static void
983 workspace_manager_move_surface(struct wl_client *client,
984                                struct wl_resource *resource,
985                                struct wl_resource *surface_resource,
986                                uint32_t workspace)
987 {
988         struct desktop_shell *shell = resource->data;
989         struct weston_surface *surface =
990                 (struct weston_surface *) surface_resource;
991         struct weston_surface *main_surface;
992
993         main_surface = weston_surface_get_main_surface(surface);
994         move_surface_to_workspace(shell, main_surface, workspace);
995 }
996
997 static const struct workspace_manager_interface workspace_manager_implementation = {
998         workspace_manager_move_surface,
999 };
1000
1001 static void
1002 unbind_resource(struct wl_resource *resource)
1003 {
1004         wl_list_remove(&resource->link);
1005         free(resource);
1006 }
1007
1008 static void
1009 bind_workspace_manager(struct wl_client *client,
1010                        void *data, uint32_t version, uint32_t id)
1011 {
1012         struct desktop_shell *shell = data;
1013         struct wl_resource *resource;
1014
1015         resource = wl_client_add_object(client, &workspace_manager_interface,
1016                                         &workspace_manager_implementation,
1017                                         id, shell);
1018
1019         if (resource == NULL) {
1020                 weston_log("couldn't add workspace manager object");
1021                 return;
1022         }
1023
1024         resource->destroy = unbind_resource;
1025         wl_list_insert(&shell->workspaces.client_list, &resource->link);
1026
1027         workspace_manager_send_state(resource,
1028                                      shell->workspaces.current,
1029                                      shell->workspaces.num);
1030 }
1031
1032 static void
1033 noop_grab_focus(struct weston_pointer_grab *grab)
1034 {
1035 }
1036
1037 static void
1038 move_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
1039 {
1040         struct weston_move_grab *move = (struct weston_move_grab *) grab;
1041         struct weston_pointer *pointer = grab->pointer;
1042         struct shell_surface *shsurf = move->base.shsurf;
1043         struct weston_surface *es;
1044         int dx = wl_fixed_to_int(pointer->x + move->dx);
1045         int dy = wl_fixed_to_int(pointer->y + move->dy);
1046
1047         if (!shsurf)
1048                 return;
1049
1050         es = shsurf->surface;
1051
1052         weston_surface_configure(es, dx, dy,
1053                                  es->geometry.width, es->geometry.height);
1054
1055         weston_compositor_schedule_repaint(es->compositor);
1056 }
1057
1058 static void
1059 move_grab_button(struct weston_pointer_grab *grab,
1060                  uint32_t time, uint32_t button, uint32_t state_w)
1061 {
1062         struct shell_grab *shell_grab = container_of(grab, struct shell_grab,
1063                                                     grab);
1064         struct weston_pointer *pointer = grab->pointer;
1065         enum wl_pointer_button_state state = state_w;
1066
1067         if (pointer->button_count == 0 &&
1068             state == WL_POINTER_BUTTON_STATE_RELEASED) {
1069                 shell_grab_end(shell_grab);
1070                 free(grab);
1071         }
1072 }
1073
1074 static const struct weston_pointer_grab_interface move_grab_interface = {
1075         noop_grab_focus,
1076         move_grab_motion,
1077         move_grab_button,
1078 };
1079
1080 static int
1081 surface_move(struct shell_surface *shsurf, struct weston_seat *seat)
1082 {
1083         struct weston_move_grab *move;
1084
1085         if (!shsurf)
1086                 return -1;
1087
1088         if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
1089                 return 0;
1090
1091         move = malloc(sizeof *move);
1092         if (!move)
1093                 return -1;
1094
1095         move->dx = wl_fixed_from_double(shsurf->surface->geometry.x) -
1096                         seat->pointer->grab_x;
1097         move->dy = wl_fixed_from_double(shsurf->surface->geometry.y) -
1098                         seat->pointer->grab_y;
1099
1100         shell_grab_start(&move->base, &move_grab_interface, shsurf,
1101                          seat->pointer, DESKTOP_SHELL_CURSOR_MOVE);
1102
1103         return 0;
1104 }
1105
1106 static void
1107 shell_surface_move(struct wl_client *client, struct wl_resource *resource,
1108                    struct wl_resource *seat_resource, uint32_t serial)
1109 {
1110         struct weston_seat *seat = seat_resource->data;
1111         struct shell_surface *shsurf = resource->data;
1112         struct weston_surface *surface;
1113
1114         surface = weston_surface_get_main_surface(seat->pointer->focus);
1115         if (seat->pointer->button_count == 0 ||
1116             seat->pointer->grab_serial != serial ||
1117             surface != shsurf->surface)
1118                 return;
1119
1120         if (surface_move(shsurf, seat) < 0)
1121                 wl_resource_post_no_memory(resource);
1122 }
1123
1124 struct weston_resize_grab {
1125         struct shell_grab base;
1126         uint32_t edges;
1127         int32_t width, height;
1128 };
1129
1130 static void
1131 resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
1132 {
1133         struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
1134         struct weston_pointer *pointer = grab->pointer;
1135         struct shell_surface *shsurf = resize->base.shsurf;
1136         int32_t width, height;
1137         wl_fixed_t from_x, from_y;
1138         wl_fixed_t to_x, to_y;
1139
1140         if (!shsurf)
1141                 return;
1142
1143         weston_surface_from_global_fixed(shsurf->surface,
1144                                          pointer->grab_x, pointer->grab_y,
1145                                          &from_x, &from_y);
1146         weston_surface_from_global_fixed(shsurf->surface,
1147                                          pointer->x, pointer->y, &to_x, &to_y);
1148
1149         width = resize->width;
1150         if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
1151                 width += wl_fixed_to_int(from_x - to_x);
1152         } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) {
1153                 width += wl_fixed_to_int(to_x - from_x);
1154         }
1155
1156         height = resize->height;
1157         if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) {
1158                 height += wl_fixed_to_int(from_y - to_y);
1159         } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) {
1160                 height += wl_fixed_to_int(to_y - from_y);
1161         }
1162
1163         shsurf->client->send_configure(shsurf->surface,
1164                                        resize->edges, width, height);
1165 }
1166
1167 static void
1168 send_configure(struct weston_surface *surface,
1169                uint32_t edges, int32_t width, int32_t height)
1170 {
1171         struct shell_surface *shsurf = get_shell_surface(surface);
1172
1173         wl_shell_surface_send_configure(&shsurf->resource,
1174                                         edges, width, height);
1175 }
1176
1177 static const struct weston_shell_client shell_client = {
1178         send_configure
1179 };
1180
1181 static void
1182 resize_grab_button(struct weston_pointer_grab *grab,
1183                    uint32_t time, uint32_t button, uint32_t state_w)
1184 {
1185         struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
1186         struct weston_pointer *pointer = grab->pointer;
1187         enum wl_pointer_button_state state = state_w;
1188
1189         if (pointer->button_count == 0 &&
1190             state == WL_POINTER_BUTTON_STATE_RELEASED) {
1191                 shell_grab_end(&resize->base);
1192                 free(grab);
1193         }
1194 }
1195
1196 static const struct weston_pointer_grab_interface resize_grab_interface = {
1197         noop_grab_focus,
1198         resize_grab_motion,
1199         resize_grab_button,
1200 };
1201
1202 /*
1203  * Returns the bounding box of a surface and all its sub-surfaces,
1204  * in the surface coordinates system. */
1205 static void
1206 surface_subsurfaces_boundingbox(struct weston_surface *surface, int32_t *x,
1207                                 int32_t *y, int32_t *w, int32_t *h) {
1208         pixman_region32_t region;
1209         pixman_box32_t *box;
1210         struct weston_subsurface *subsurface;
1211
1212         pixman_region32_init_rect(&region, 0, 0,
1213                                   surface->geometry.width,
1214                                   surface->geometry.height);
1215
1216         wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
1217                 pixman_region32_union_rect(&region, &region,
1218                                            subsurface->position.x,
1219                                            subsurface->position.y,
1220                                            subsurface->surface->geometry.width,
1221                                            subsurface->surface->geometry.height);
1222         }
1223
1224         box = pixman_region32_extents(&region);
1225         if (x)
1226                 *x = box->x1;
1227         if (y)
1228                 *y = box->y1;
1229         if (w)
1230                 *w = box->x2 - box->x1;
1231         if (h)
1232                 *h = box->y2 - box->y1;
1233
1234         pixman_region32_fini(&region);
1235 }
1236
1237 static int
1238 surface_resize(struct shell_surface *shsurf,
1239                struct weston_seat *seat, uint32_t edges)
1240 {
1241         struct weston_resize_grab *resize;
1242
1243         if (shsurf->type == SHELL_SURFACE_FULLSCREEN ||
1244             shsurf->type == SHELL_SURFACE_MAXIMIZED)
1245                 return 0;
1246
1247         if (edges == 0 || edges > 15 ||
1248             (edges & 3) == 3 || (edges & 12) == 12)
1249                 return 0;
1250
1251         resize = malloc(sizeof *resize);
1252         if (!resize)
1253                 return -1;
1254
1255         resize->edges = edges;
1256         surface_subsurfaces_boundingbox(shsurf->surface, NULL, NULL,
1257                                         &resize->width, &resize->height);
1258
1259         shell_grab_start(&resize->base, &resize_grab_interface, shsurf,
1260                          seat->pointer, edges);
1261
1262         return 0;
1263 }
1264
1265 static void
1266 shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
1267                      struct wl_resource *seat_resource, uint32_t serial,
1268                      uint32_t edges)
1269 {
1270         struct weston_seat *seat = seat_resource->data;
1271         struct shell_surface *shsurf = resource->data;
1272         struct weston_surface *surface;
1273
1274         if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
1275                 return;
1276
1277         surface = weston_surface_get_main_surface(seat->pointer->focus);
1278         if (seat->pointer->button_count == 0 ||
1279             seat->pointer->grab_serial != serial ||
1280             surface != shsurf->surface)
1281                 return;
1282
1283         if (surface_resize(shsurf, seat, edges) < 0)
1284                 wl_resource_post_no_memory(resource);
1285 }
1286
1287 static void
1288 busy_cursor_grab_focus(struct weston_pointer_grab *base)
1289 {
1290         struct shell_grab *grab = (struct shell_grab *) base;
1291         struct weston_pointer *pointer = base->pointer;
1292         struct weston_surface *surface;
1293         wl_fixed_t sx, sy;
1294
1295         surface = weston_compositor_pick_surface(pointer->seat->compositor,
1296                                                  pointer->x, pointer->y,
1297                                                  &sx, &sy);
1298
1299         if (!grab->shsurf || grab->shsurf->surface != surface) {
1300                 shell_grab_end(grab);
1301                 free(grab);
1302         }
1303 }
1304
1305 static void
1306 busy_cursor_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
1307 {
1308 }
1309
1310 static void
1311 busy_cursor_grab_button(struct weston_pointer_grab *base,
1312                         uint32_t time, uint32_t button, uint32_t state)
1313 {
1314         struct shell_grab *grab = (struct shell_grab *) base;
1315         struct shell_surface *shsurf = grab->shsurf;
1316         struct weston_seat *seat = grab->grab.pointer->seat;
1317
1318         if (shsurf && button == BTN_LEFT && state) {
1319                 activate(shsurf->shell, shsurf->surface, seat);
1320                 surface_move(shsurf, seat);
1321         } else if (shsurf && button == BTN_RIGHT && state) {
1322                 activate(shsurf->shell, shsurf->surface, seat);
1323                 surface_rotate(shsurf, seat);
1324         }
1325 }
1326
1327 static const struct weston_pointer_grab_interface busy_cursor_grab_interface = {
1328         busy_cursor_grab_focus,
1329         busy_cursor_grab_motion,
1330         busy_cursor_grab_button,
1331 };
1332
1333 static void
1334 set_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer)
1335 {
1336         struct shell_grab *grab;
1337
1338         grab = malloc(sizeof *grab);
1339         if (!grab)
1340                 return;
1341
1342         shell_grab_start(grab, &busy_cursor_grab_interface, shsurf, pointer,
1343                          DESKTOP_SHELL_CURSOR_BUSY);
1344 }
1345
1346 static void
1347 end_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer)
1348 {
1349         struct shell_grab *grab = (struct shell_grab *) pointer->grab;
1350
1351         if (grab->grab.interface == &busy_cursor_grab_interface &&
1352             grab->shsurf == shsurf) {
1353                 shell_grab_end(grab);
1354                 free(grab);
1355         }
1356 }
1357
1358 static void
1359 ping_timer_destroy(struct shell_surface *shsurf)
1360 {
1361         if (!shsurf || !shsurf->ping_timer)
1362                 return;
1363
1364         if (shsurf->ping_timer->source)
1365                 wl_event_source_remove(shsurf->ping_timer->source);
1366
1367         free(shsurf->ping_timer);
1368         shsurf->ping_timer = NULL;
1369 }
1370
1371 static int
1372 ping_timeout_handler(void *data)
1373 {
1374         struct shell_surface *shsurf = data;
1375         struct weston_seat *seat;
1376
1377         /* Client is not responding */
1378         shsurf->unresponsive = 1;
1379
1380         wl_list_for_each(seat, &shsurf->surface->compositor->seat_list, link)
1381                 if (seat->pointer->focus == shsurf->surface)
1382                         set_busy_cursor(shsurf, seat->pointer);
1383
1384         return 1;
1385 }
1386
1387 static void
1388 ping_handler(struct weston_surface *surface, uint32_t serial)
1389 {
1390         struct shell_surface *shsurf = get_shell_surface(surface);
1391         struct wl_event_loop *loop;
1392         int ping_timeout = 200;
1393
1394         if (!shsurf)
1395                 return;
1396         if (!shsurf->resource.client)
1397                 return;
1398
1399         if (shsurf->surface == shsurf->shell->grab_surface)
1400                 return;
1401
1402         if (!shsurf->ping_timer) {
1403                 shsurf->ping_timer = malloc(sizeof *shsurf->ping_timer);
1404                 if (!shsurf->ping_timer)
1405                         return;
1406
1407                 shsurf->ping_timer->serial = serial;
1408                 loop = wl_display_get_event_loop(surface->compositor->wl_display);
1409                 shsurf->ping_timer->source =
1410                         wl_event_loop_add_timer(loop, ping_timeout_handler, shsurf);
1411                 wl_event_source_timer_update(shsurf->ping_timer->source, ping_timeout);
1412
1413                 wl_shell_surface_send_ping(&shsurf->resource, serial);
1414         }
1415 }
1416
1417 static void
1418 handle_pointer_focus(struct wl_listener *listener, void *data)
1419 {
1420         struct weston_pointer *pointer = data;
1421         struct weston_surface *surface =
1422                 (struct weston_surface *) pointer->focus;
1423         struct weston_compositor *compositor;
1424         struct shell_surface *shsurf;
1425         uint32_t serial;
1426
1427         if (!surface)
1428                 return;
1429
1430         compositor = surface->compositor;
1431         shsurf = get_shell_surface(surface);
1432
1433         if (shsurf && shsurf->unresponsive) {
1434                 set_busy_cursor(shsurf, pointer);
1435         } else {
1436                 serial = wl_display_next_serial(compositor->wl_display);
1437                 ping_handler(surface, serial);
1438         }
1439 }
1440
1441 static void
1442 create_pointer_focus_listener(struct weston_seat *seat)
1443 {
1444         struct wl_listener *listener;
1445
1446         if (!seat->pointer)
1447                 return;
1448
1449         listener = malloc(sizeof *listener);
1450         listener->notify = handle_pointer_focus;
1451         wl_signal_add(&seat->pointer->focus_signal, listener);
1452 }
1453
1454 static void
1455 shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
1456                                                         uint32_t serial)
1457 {
1458         struct shell_surface *shsurf = resource->data;
1459         struct weston_seat *seat;
1460         struct weston_compositor *ec = shsurf->surface->compositor;
1461
1462         if (shsurf->ping_timer == NULL)
1463                 /* Just ignore unsolicited pong. */
1464                 return;
1465
1466         if (shsurf->ping_timer->serial == serial) {
1467                 shsurf->unresponsive = 0;
1468                 wl_list_for_each(seat, &ec->seat_list, link) {
1469                         if(seat->pointer)
1470                                 end_busy_cursor(shsurf, seat->pointer);
1471                 }
1472                 ping_timer_destroy(shsurf);
1473         }
1474 }
1475
1476 static void
1477 shell_surface_set_title(struct wl_client *client,
1478                         struct wl_resource *resource, const char *title)
1479 {
1480         struct shell_surface *shsurf = resource->data;
1481
1482         free(shsurf->title);
1483         shsurf->title = strdup(title);
1484 }
1485
1486 static void
1487 shell_surface_set_class(struct wl_client *client,
1488                         struct wl_resource *resource, const char *class)
1489 {
1490         struct shell_surface *shsurf = resource->data;
1491
1492         free(shsurf->class);
1493         shsurf->class = strdup(class);
1494 }
1495
1496 static struct weston_output *
1497 get_default_output(struct weston_compositor *compositor)
1498 {
1499         return container_of(compositor->output_list.next,
1500                             struct weston_output, link);
1501 }
1502
1503 static void
1504 shell_unset_fullscreen(struct shell_surface *shsurf)
1505 {
1506         struct workspace *ws;
1507         /* undo all fullscreen things here */
1508         if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER &&
1509             shell_surface_is_top_fullscreen(shsurf)) {
1510                 weston_output_switch_mode(shsurf->fullscreen_output,
1511                                           shsurf->fullscreen_output->origin);
1512         }
1513         shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
1514         shsurf->fullscreen.framerate = 0;
1515         wl_list_remove(&shsurf->fullscreen.transform.link);
1516         wl_list_init(&shsurf->fullscreen.transform.link);
1517         if (shsurf->fullscreen.black_surface)
1518                 weston_surface_destroy(shsurf->fullscreen.black_surface);
1519         shsurf->fullscreen.black_surface = NULL;
1520         shsurf->fullscreen_output = NULL;
1521         weston_surface_set_position(shsurf->surface,
1522                                     shsurf->saved_x, shsurf->saved_y);
1523         if (shsurf->saved_rotation_valid) {
1524                 wl_list_insert(&shsurf->surface->geometry.transformation_list,
1525                                &shsurf->rotation.transform.link);
1526                 shsurf->saved_rotation_valid = false;
1527         }
1528
1529         ws = get_current_workspace(shsurf->shell);
1530         wl_list_remove(&shsurf->surface->layer_link);
1531         wl_list_insert(&ws->layer.surface_list, &shsurf->surface->layer_link);
1532 }
1533
1534 static void
1535 shell_unset_maximized(struct shell_surface *shsurf)
1536 {
1537         struct workspace *ws;
1538         /* undo all maximized things here */
1539         shsurf->output = get_default_output(shsurf->surface->compositor);
1540         weston_surface_set_position(shsurf->surface,
1541                                     shsurf->saved_x,
1542                                     shsurf->saved_y);
1543
1544         if (shsurf->saved_rotation_valid) {
1545                 wl_list_insert(&shsurf->surface->geometry.transformation_list,
1546                                                    &shsurf->rotation.transform.link);
1547                 shsurf->saved_rotation_valid = false;
1548         }
1549
1550         ws = get_current_workspace(shsurf->shell);
1551         wl_list_remove(&shsurf->surface->layer_link);
1552         wl_list_insert(&ws->layer.surface_list, &shsurf->surface->layer_link);
1553 }
1554
1555 static int
1556 reset_shell_surface_type(struct shell_surface *surface)
1557 {
1558         switch (surface->type) {
1559         case SHELL_SURFACE_FULLSCREEN:
1560                 shell_unset_fullscreen(surface);
1561                 break;
1562         case SHELL_SURFACE_MAXIMIZED:
1563                 shell_unset_maximized(surface);
1564                 break;
1565         case SHELL_SURFACE_NONE:
1566         case SHELL_SURFACE_TOPLEVEL:
1567         case SHELL_SURFACE_TRANSIENT:
1568         case SHELL_SURFACE_POPUP:
1569                 break;
1570         }
1571
1572         surface->type = SHELL_SURFACE_NONE;
1573         return 0;
1574 }
1575
1576 static void
1577 set_surface_type(struct shell_surface *shsurf)
1578 {
1579         struct weston_surface *surface = shsurf->surface;
1580         struct weston_surface *pes = shsurf->parent;
1581
1582         reset_shell_surface_type(shsurf);
1583
1584         shsurf->type = shsurf->next_type;
1585         shsurf->next_type = SHELL_SURFACE_NONE;
1586
1587         switch (shsurf->type) {
1588         case SHELL_SURFACE_TOPLEVEL:
1589                 break;
1590         case SHELL_SURFACE_TRANSIENT:
1591                 weston_surface_set_position(surface,
1592                                 pes->geometry.x + shsurf->transient.x,
1593                                 pes->geometry.y + shsurf->transient.y);
1594                 break;
1595
1596         case SHELL_SURFACE_MAXIMIZED:
1597         case SHELL_SURFACE_FULLSCREEN:
1598                 shsurf->saved_x = surface->geometry.x;
1599                 shsurf->saved_y = surface->geometry.y;
1600                 shsurf->saved_position_valid = true;
1601
1602                 if (!wl_list_empty(&shsurf->rotation.transform.link)) {
1603                         wl_list_remove(&shsurf->rotation.transform.link);
1604                         wl_list_init(&shsurf->rotation.transform.link);
1605                         weston_surface_geometry_dirty(shsurf->surface);
1606                         shsurf->saved_rotation_valid = true;
1607                 }
1608                 break;
1609
1610         default:
1611                 break;
1612         }
1613 }
1614
1615 static void
1616 set_toplevel(struct shell_surface *shsurf)
1617 {
1618        shsurf->next_type = SHELL_SURFACE_TOPLEVEL;
1619 }
1620
1621 static void
1622 shell_surface_set_toplevel(struct wl_client *client,
1623                            struct wl_resource *resource)
1624 {
1625         struct shell_surface *surface = resource->data;
1626
1627         set_toplevel(surface);
1628 }
1629
1630 static void
1631 set_transient(struct shell_surface *shsurf,
1632               struct weston_surface *parent, int x, int y, uint32_t flags)
1633 {
1634         /* assign to parents output */
1635         shsurf->parent = parent;
1636         shsurf->transient.x = x;
1637         shsurf->transient.y = y;
1638         shsurf->transient.flags = flags;
1639         shsurf->next_type = SHELL_SURFACE_TRANSIENT;
1640 }
1641
1642 static void
1643 shell_surface_set_transient(struct wl_client *client,
1644                             struct wl_resource *resource,
1645                             struct wl_resource *parent_resource,
1646                             int x, int y, uint32_t flags)
1647 {
1648         struct shell_surface *shsurf = resource->data;
1649         struct weston_surface *parent = parent_resource->data;
1650
1651         set_transient(shsurf, parent, x, y, flags);
1652 }
1653
1654 static struct desktop_shell *
1655 shell_surface_get_shell(struct shell_surface *shsurf)
1656 {
1657         return shsurf->shell;
1658 }
1659
1660 static int
1661 get_output_panel_height(struct desktop_shell *shell,
1662                         struct weston_output *output)
1663 {
1664         struct weston_surface *surface;
1665         int panel_height = 0;
1666
1667         if (!output)
1668                 return 0;
1669
1670         wl_list_for_each(surface, &shell->panel_layer.surface_list, layer_link) {
1671                 if (surface->output == output) {
1672                         panel_height = surface->geometry.height;
1673                         break;
1674                 }
1675         }
1676
1677         return panel_height;
1678 }
1679
1680 static void
1681 shell_surface_set_maximized(struct wl_client *client,
1682                             struct wl_resource *resource,
1683                             struct wl_resource *output_resource )
1684 {
1685         struct shell_surface *shsurf = resource->data;
1686         struct weston_surface *es = shsurf->surface;
1687         struct desktop_shell *shell = NULL;
1688         uint32_t edges = 0, panel_height = 0;
1689
1690         /* get the default output, if the client set it as NULL
1691            check whether the ouput is available */
1692         if (output_resource)
1693                 shsurf->output = output_resource->data;
1694         else if (es->output)
1695                 shsurf->output = es->output;
1696         else
1697                 shsurf->output = get_default_output(es->compositor);
1698
1699         shell = shell_surface_get_shell(shsurf);
1700         panel_height = get_output_panel_height(shell, shsurf->output);
1701         edges = WL_SHELL_SURFACE_RESIZE_TOP|WL_SHELL_SURFACE_RESIZE_LEFT;
1702
1703         shsurf->client->send_configure(shsurf->surface, edges,
1704                                        shsurf->output->width,
1705                                        shsurf->output->height - panel_height);
1706
1707         shsurf->next_type = SHELL_SURFACE_MAXIMIZED;
1708 }
1709
1710 static void
1711 black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height);
1712
1713 static struct weston_surface *
1714 create_black_surface(struct weston_compositor *ec,
1715                      struct weston_surface *fs_surface,
1716                      float x, float y, int w, int h)
1717 {
1718         struct weston_surface *surface = NULL;
1719
1720         surface = weston_surface_create(ec);
1721         if (surface == NULL) {
1722                 weston_log("no memory\n");
1723                 return NULL;
1724         }
1725
1726         surface->configure = black_surface_configure;
1727         surface->configure_private = fs_surface;
1728         weston_surface_configure(surface, x, y, w, h);
1729         weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1);
1730         pixman_region32_fini(&surface->opaque);
1731         pixman_region32_init_rect(&surface->opaque, 0, 0, w, h);
1732         pixman_region32_fini(&surface->input);
1733         pixman_region32_init_rect(&surface->input, 0, 0, w, h);
1734
1735         return surface;
1736 }
1737
1738 /* Create black surface and append it to the associated fullscreen surface.
1739  * Handle size dismatch and positioning according to the method. */
1740 static void
1741 shell_configure_fullscreen(struct shell_surface *shsurf)
1742 {
1743         struct weston_output *output = shsurf->fullscreen_output;
1744         struct weston_surface *surface = shsurf->surface;
1745         struct weston_matrix *matrix;
1746         float scale, output_aspect, surface_aspect, x, y;
1747         int32_t surf_x, surf_y, surf_width, surf_height;
1748
1749         if (!shsurf->fullscreen.black_surface)
1750                 shsurf->fullscreen.black_surface =
1751                         create_black_surface(surface->compositor,
1752                                              surface,
1753                                              output->x, output->y,
1754                                              output->width,
1755                                              output->height);
1756
1757         wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
1758         wl_list_insert(&surface->layer_link,
1759                        &shsurf->fullscreen.black_surface->layer_link);
1760         shsurf->fullscreen.black_surface->output = output;
1761
1762         surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y,
1763                                         &surf_width, &surf_height);
1764
1765         switch (shsurf->fullscreen.type) {
1766         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT:
1767                 if (surface->buffer_ref.buffer)
1768                         center_on_output(surface, shsurf->fullscreen_output);
1769                 break;
1770         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE:
1771                 /* 1:1 mapping between surface and output dimensions */
1772                 if (output->width == surf_width &&
1773                         output->height == surf_height) {
1774                         weston_surface_set_position(surface, output->x - surf_x,
1775                                                              output->y - surf_y);
1776                         break;
1777                 }
1778
1779                 matrix = &shsurf->fullscreen.transform.matrix;
1780                 weston_matrix_init(matrix);
1781
1782                 output_aspect = (float) output->width /
1783                         (float) output->height;
1784                 surface_aspect = (float) surface->geometry.width /
1785                         (float) surface->geometry.height;
1786                 if (output_aspect < surface_aspect)
1787                         scale = (float) output->width /
1788                                 (float) surf_width;
1789                 else
1790                         scale = (float) output->height /
1791                                 (float) surf_height;
1792
1793                 weston_matrix_scale(matrix, scale, scale, 1);
1794                 wl_list_remove(&shsurf->fullscreen.transform.link);
1795                 wl_list_insert(&surface->geometry.transformation_list,
1796                                &shsurf->fullscreen.transform.link);
1797                 x = output->x + (output->width - surf_width * scale) / 2 - surf_x;
1798                 y = output->y + (output->height - surf_height * scale) / 2 - surf_y;
1799                 weston_surface_set_position(surface, x, y);
1800
1801                 break;
1802         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER:
1803                 if (shell_surface_is_top_fullscreen(shsurf)) {
1804                         struct weston_mode mode = {0,
1805                                 surf_width,
1806                                 surf_height,
1807                                 shsurf->fullscreen.framerate};
1808
1809                         if (weston_output_switch_mode(output, &mode) == 0) {
1810                                 weston_surface_configure(shsurf->fullscreen.black_surface,
1811                                                          output->x - surf_x,
1812                                                          output->y - surf_y,
1813                                                          output->width,
1814                                                          output->height);
1815                                 break;
1816                         }
1817                 }
1818                 break;
1819         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL:
1820                 break;
1821         default:
1822                 break;
1823         }
1824 }
1825
1826 /* make the fullscreen and black surface at the top */
1827 static void
1828 shell_stack_fullscreen(struct shell_surface *shsurf)
1829 {
1830         struct weston_output *output = shsurf->fullscreen_output;
1831         struct weston_surface *surface = shsurf->surface;
1832         struct desktop_shell *shell = shell_surface_get_shell(shsurf);
1833
1834         wl_list_remove(&surface->layer_link);
1835         wl_list_insert(&shell->fullscreen_layer.surface_list,
1836                        &surface->layer_link);
1837         weston_surface_damage(surface);
1838
1839         if (!shsurf->fullscreen.black_surface)
1840                 shsurf->fullscreen.black_surface =
1841                         create_black_surface(surface->compositor,
1842                                              surface,
1843                                              output->x, output->y,
1844                                              output->width,
1845                                              output->height);
1846
1847         wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
1848         wl_list_insert(&surface->layer_link,
1849                        &shsurf->fullscreen.black_surface->layer_link);
1850         weston_surface_damage(shsurf->fullscreen.black_surface);
1851 }
1852
1853 static void
1854 shell_map_fullscreen(struct shell_surface *shsurf)
1855 {
1856         shell_stack_fullscreen(shsurf);
1857         shell_configure_fullscreen(shsurf);
1858 }
1859
1860 static void
1861 set_fullscreen(struct shell_surface *shsurf,
1862                uint32_t method,
1863                uint32_t framerate,
1864                struct weston_output *output)
1865 {
1866         struct weston_surface *es = shsurf->surface;
1867
1868         if (output)
1869                 shsurf->output = output;
1870         else if (es->output)
1871                 shsurf->output = es->output;
1872         else
1873                 shsurf->output = get_default_output(es->compositor);
1874
1875         shsurf->fullscreen_output = shsurf->output;
1876         shsurf->fullscreen.type = method;
1877         shsurf->fullscreen.framerate = framerate;
1878         shsurf->next_type = SHELL_SURFACE_FULLSCREEN;
1879
1880         shsurf->client->send_configure(shsurf->surface, 0,
1881                                        shsurf->output->width,
1882                                        shsurf->output->height);
1883 }
1884
1885 static void
1886 shell_surface_set_fullscreen(struct wl_client *client,
1887                              struct wl_resource *resource,
1888                              uint32_t method,
1889                              uint32_t framerate,
1890                              struct wl_resource *output_resource)
1891 {
1892         struct shell_surface *shsurf = resource->data;
1893         struct weston_output *output;
1894
1895         if (output_resource)
1896                 output = output_resource->data;
1897         else
1898                 output = NULL;
1899
1900         set_fullscreen(shsurf, method, framerate, output);
1901 }
1902
1903 static const struct weston_pointer_grab_interface popup_grab_interface;
1904
1905 static void
1906 destroy_shell_seat(struct wl_listener *listener, void *data)
1907 {
1908         struct shell_seat *shseat =
1909                 container_of(listener,
1910                              struct shell_seat, seat_destroy_listener);
1911         struct shell_surface *shsurf, *prev = NULL;
1912
1913         if (shseat->popup_grab.grab.interface == &popup_grab_interface) {
1914                 weston_pointer_end_grab(shseat->popup_grab.grab.pointer);
1915                 shseat->popup_grab.client = NULL;
1916
1917                 wl_list_for_each(shsurf, &shseat->popup_grab.surfaces_list, popup.grab_link) {
1918                         shsurf->popup.shseat = NULL;
1919                         if (prev) {
1920                                 wl_list_init(&prev->popup.grab_link);
1921                         }
1922                         prev = shsurf;
1923                 }
1924                 wl_list_init(&prev->popup.grab_link);
1925         }
1926
1927         wl_list_remove(&shseat->seat_destroy_listener.link);
1928         free(shseat);
1929 }
1930
1931 static struct shell_seat *
1932 create_shell_seat(struct weston_seat *seat)
1933 {
1934         struct shell_seat *shseat;
1935
1936         shseat = calloc(1, sizeof *shseat);
1937         if (!shseat) {
1938                 weston_log("no memory to allocate shell seat\n");
1939                 return NULL;
1940         }
1941
1942         shseat->seat = seat;
1943         wl_list_init(&shseat->popup_grab.surfaces_list);
1944
1945         shseat->seat_destroy_listener.notify = destroy_shell_seat;
1946         wl_signal_add(&seat->destroy_signal,
1947                       &shseat->seat_destroy_listener);
1948
1949         return shseat;
1950 }
1951
1952 static struct shell_seat *
1953 get_shell_seat(struct weston_seat *seat)
1954 {
1955         struct wl_listener *listener;
1956
1957         listener = wl_signal_get(&seat->destroy_signal, destroy_shell_seat);
1958         if (listener == NULL)
1959                 return create_shell_seat(seat);
1960
1961         return container_of(listener,
1962                             struct shell_seat, seat_destroy_listener);
1963 }
1964
1965 static void
1966 popup_grab_focus(struct weston_pointer_grab *grab)
1967 {
1968         struct weston_pointer *pointer = grab->pointer;
1969         struct weston_surface *surface;
1970         struct shell_seat *shseat =
1971             container_of(grab, struct shell_seat, popup_grab.grab);
1972         struct wl_client *client = shseat->popup_grab.client;
1973         wl_fixed_t sx, sy;
1974
1975         surface = weston_compositor_pick_surface(pointer->seat->compositor,
1976                                                  pointer->x, pointer->y,
1977                                                  &sx, &sy);
1978
1979         if (surface && surface->resource.client == client) {
1980                 weston_pointer_set_focus(pointer, surface, sx, sy);
1981         } else {
1982                 weston_pointer_set_focus(pointer, NULL,
1983                                          wl_fixed_from_int(0),
1984                                          wl_fixed_from_int(0));
1985         }
1986 }
1987
1988 static void
1989 popup_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
1990 {
1991         struct weston_pointer *pointer = grab->pointer;
1992         wl_fixed_t sx, sy;
1993
1994         if (pointer->focus_resource) {
1995                 weston_surface_from_global_fixed(pointer->focus,
1996                                                  pointer->x, pointer->y,
1997                                                  &sx, &sy);
1998                 wl_pointer_send_motion(pointer->focus_resource, time, sx, sy);
1999         }
2000 }
2001
2002 static void
2003 popup_grab_button(struct weston_pointer_grab *grab,
2004                   uint32_t time, uint32_t button, uint32_t state_w)
2005 {
2006         struct wl_resource *resource;
2007         struct shell_seat *shseat =
2008             container_of(grab, struct shell_seat, popup_grab.grab);
2009         struct wl_display *display;
2010         enum wl_pointer_button_state state = state_w;
2011         uint32_t serial;
2012
2013         resource = grab->pointer->focus_resource;
2014         if (resource) {
2015                 display = wl_client_get_display(resource->client);
2016                 serial = wl_display_get_serial(display);
2017                 wl_pointer_send_button(resource, serial, time, button, state);
2018         } else if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
2019                    (shseat->popup_grab.initial_up ||
2020                     time - shseat->seat->pointer->grab_time > 500)) {
2021                 popup_grab_end(grab->pointer);
2022         }
2023
2024         if (state == WL_POINTER_BUTTON_STATE_RELEASED)
2025                 shseat->popup_grab.initial_up = 1;
2026 }
2027
2028 static const struct weston_pointer_grab_interface popup_grab_interface = {
2029         popup_grab_focus,
2030         popup_grab_motion,
2031         popup_grab_button,
2032 };
2033
2034 static void
2035 popup_grab_end(struct weston_pointer *pointer)
2036 {
2037         struct weston_pointer_grab *grab = pointer->grab;
2038         struct shell_seat *shseat =
2039             container_of(grab, struct shell_seat, popup_grab.grab);
2040         struct shell_surface *shsurf;
2041         struct shell_surface *prev = NULL;
2042
2043         if (pointer->grab->interface == &popup_grab_interface) {
2044                 weston_pointer_end_grab(grab->pointer);
2045                 shseat->popup_grab.client = NULL;
2046                 shseat->popup_grab.grab.interface = NULL;
2047                 assert(!wl_list_empty(&shseat->popup_grab.surfaces_list));
2048                 /* Send the popup_done event to all the popups open */
2049                 wl_list_for_each(shsurf, &shseat->popup_grab.surfaces_list, popup.grab_link) {
2050                         wl_shell_surface_send_popup_done(&shsurf->resource);
2051                         shsurf->popup.shseat = NULL;
2052                         if (prev) {
2053                                 wl_list_init(&prev->popup.grab_link);
2054                         }
2055                         prev = shsurf;
2056                 }
2057                 wl_list_init(&prev->popup.grab_link);
2058                 wl_list_init(&shseat->popup_grab.surfaces_list);
2059         }
2060 }
2061
2062 static void
2063 add_popup_grab(struct shell_surface *shsurf, struct shell_seat *shseat)
2064 {
2065         struct weston_seat *seat = shseat->seat;
2066
2067         if (wl_list_empty(&shseat->popup_grab.surfaces_list)) {
2068                 shseat->popup_grab.client = shsurf->resource.client;
2069                 shseat->popup_grab.grab.interface = &popup_grab_interface;
2070                 /* We must make sure here that this popup was opened after
2071                  * a mouse press, and not just by moving around with other
2072                  * popups already open. */
2073                 if (shseat->seat->pointer->button_count > 0)
2074                         shseat->popup_grab.initial_up = 0;
2075
2076                 weston_pointer_start_grab(seat->pointer, &shseat->popup_grab.grab);
2077         }
2078         wl_list_insert(&shseat->popup_grab.surfaces_list, &shsurf->popup.grab_link);
2079 }
2080
2081 static void
2082 remove_popup_grab(struct shell_surface *shsurf)
2083 {
2084         struct shell_seat *shseat = shsurf->popup.shseat;
2085
2086         wl_list_remove(&shsurf->popup.grab_link);
2087         wl_list_init(&shsurf->popup.grab_link);
2088         if (wl_list_empty(&shseat->popup_grab.surfaces_list)) {
2089                 weston_pointer_end_grab(shseat->popup_grab.grab.pointer);
2090                 shseat->popup_grab.grab.interface = NULL;
2091         }
2092 }
2093
2094 static void
2095 shell_map_popup(struct shell_surface *shsurf)
2096 {
2097         struct shell_seat *shseat = shsurf->popup.shseat;
2098         struct weston_surface *es = shsurf->surface;
2099         struct weston_surface *parent = shsurf->parent;
2100
2101         es->output = parent->output;
2102
2103         weston_surface_set_transform_parent(es, parent);
2104         weston_surface_set_position(es, shsurf->popup.x, shsurf->popup.y);
2105         weston_surface_update_transform(es);
2106
2107         if (shseat->seat->pointer->grab_serial == shsurf->popup.serial) {
2108                 add_popup_grab(shsurf, shseat);
2109         } else {
2110                 wl_shell_surface_send_popup_done(&shsurf->resource);
2111                 shseat->popup_grab.client = NULL;
2112         }
2113 }
2114
2115 static void
2116 shell_surface_set_popup(struct wl_client *client,
2117                         struct wl_resource *resource,
2118                         struct wl_resource *seat_resource,
2119                         uint32_t serial,
2120                         struct wl_resource *parent_resource,
2121                         int32_t x, int32_t y, uint32_t flags)
2122 {
2123         struct shell_surface *shsurf = resource->data;
2124
2125         shsurf->type = SHELL_SURFACE_POPUP;
2126         shsurf->parent = parent_resource->data;
2127         shsurf->popup.shseat = get_shell_seat(seat_resource->data);
2128         shsurf->popup.serial = serial;
2129         shsurf->popup.x = x;
2130         shsurf->popup.y = y;
2131 }
2132
2133 static const struct wl_shell_surface_interface shell_surface_implementation = {
2134         shell_surface_pong,
2135         shell_surface_move,
2136         shell_surface_resize,
2137         shell_surface_set_toplevel,
2138         shell_surface_set_transient,
2139         shell_surface_set_fullscreen,
2140         shell_surface_set_popup,
2141         shell_surface_set_maximized,
2142         shell_surface_set_title,
2143         shell_surface_set_class
2144 };
2145
2146 static void
2147 destroy_shell_surface(struct shell_surface *shsurf)
2148 {
2149         if (!wl_list_empty(&shsurf->popup.grab_link)) {
2150                 remove_popup_grab(shsurf);
2151         }
2152
2153         if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER &&
2154             shell_surface_is_top_fullscreen(shsurf)) {
2155                 weston_output_switch_mode(shsurf->fullscreen_output,
2156                                           shsurf->fullscreen_output->origin);
2157         }
2158
2159         if (shsurf->fullscreen.black_surface)
2160                 weston_surface_destroy(shsurf->fullscreen.black_surface);
2161
2162         /* As destroy_resource() use wl_list_for_each_safe(),
2163          * we can always remove the listener.
2164          */
2165         wl_list_remove(&shsurf->surface_destroy_listener.link);
2166         shsurf->surface->configure = NULL;
2167         ping_timer_destroy(shsurf);
2168         free(shsurf->title);
2169
2170         wl_list_remove(&shsurf->link);
2171         free(shsurf);
2172 }
2173
2174 static void
2175 shell_destroy_shell_surface(struct wl_resource *resource)
2176 {
2177         struct shell_surface *shsurf = resource->data;
2178
2179         destroy_shell_surface(shsurf);
2180 }
2181
2182 static void
2183 shell_handle_surface_destroy(struct wl_listener *listener, void *data)
2184 {
2185         struct shell_surface *shsurf = container_of(listener,
2186                                                     struct shell_surface,
2187                                                     surface_destroy_listener);
2188
2189         if (shsurf->resource.client) {
2190                 wl_resource_destroy(&shsurf->resource);
2191         } else {
2192                 wl_signal_emit(&shsurf->resource.destroy_signal,
2193                                &shsurf->resource);
2194                 destroy_shell_surface(shsurf);
2195         }
2196 }
2197
2198 static void
2199 shell_surface_configure(struct weston_surface *, int32_t, int32_t, int32_t, int32_t);
2200
2201 static struct shell_surface *
2202 get_shell_surface(struct weston_surface *surface)
2203 {
2204         if (surface->configure == shell_surface_configure)
2205                 return surface->configure_private;
2206         else
2207                 return NULL;
2208 }
2209
2210 static  struct shell_surface *
2211 create_shell_surface(void *shell, struct weston_surface *surface,
2212                      const struct weston_shell_client *client)
2213 {
2214         struct shell_surface *shsurf;
2215
2216         if (surface->configure) {
2217                 weston_log("surface->configure already set\n");
2218                 return NULL;
2219         }
2220
2221         shsurf = calloc(1, sizeof *shsurf);
2222         if (!shsurf) {
2223                 weston_log("no memory to allocate shell surface\n");
2224                 return NULL;
2225         }
2226
2227         surface->configure = shell_surface_configure;
2228         surface->configure_private = shsurf;
2229
2230         shsurf->shell = (struct desktop_shell *) shell;
2231         shsurf->unresponsive = 0;
2232         shsurf->saved_position_valid = false;
2233         shsurf->saved_rotation_valid = false;
2234         shsurf->surface = surface;
2235         shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
2236         shsurf->fullscreen.framerate = 0;
2237         shsurf->fullscreen.black_surface = NULL;
2238         shsurf->ping_timer = NULL;
2239         wl_list_init(&shsurf->fullscreen.transform.link);
2240
2241         wl_signal_init(&shsurf->resource.destroy_signal);
2242         shsurf->surface_destroy_listener.notify = shell_handle_surface_destroy;
2243         wl_signal_add(&surface->resource.destroy_signal,
2244                       &shsurf->surface_destroy_listener);
2245
2246         /* init link so its safe to always remove it in destroy_shell_surface */
2247         wl_list_init(&shsurf->link);
2248         wl_list_init(&shsurf->popup.grab_link);
2249
2250         /* empty when not in use */
2251         wl_list_init(&shsurf->rotation.transform.link);
2252         weston_matrix_init(&shsurf->rotation.rotation);
2253
2254         wl_list_init(&shsurf->workspace_transform.link);
2255
2256         shsurf->type = SHELL_SURFACE_NONE;
2257         shsurf->next_type = SHELL_SURFACE_NONE;
2258
2259         shsurf->client = client;
2260
2261         return shsurf;
2262 }
2263
2264 static void
2265 shell_get_shell_surface(struct wl_client *client,
2266                         struct wl_resource *resource,
2267                         uint32_t id,
2268                         struct wl_resource *surface_resource)
2269 {
2270         struct weston_surface *surface = surface_resource->data;
2271         struct desktop_shell *shell = resource->data;
2272         struct shell_surface *shsurf;
2273
2274         if (get_shell_surface(surface)) {
2275                 wl_resource_post_error(surface_resource,
2276                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
2277                                        "desktop_shell::get_shell_surface already requested");
2278                 return;
2279         }
2280
2281         shsurf = create_shell_surface(shell, surface, &shell_client);
2282         if (!shsurf) {
2283                 wl_resource_post_error(surface_resource,
2284                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
2285                                        "surface->configure already set");
2286                 return;
2287         }
2288
2289         shsurf->resource.destroy = shell_destroy_shell_surface;
2290         shsurf->resource.object.id = id;
2291         shsurf->resource.object.interface = &wl_shell_surface_interface;
2292         shsurf->resource.object.implementation =
2293                 (void (**)(void)) &shell_surface_implementation;
2294         shsurf->resource.data = shsurf;
2295
2296         wl_client_add_resource(client, &shsurf->resource);
2297 }
2298
2299 static const struct wl_shell_interface shell_implementation = {
2300         shell_get_shell_surface
2301 };
2302
2303 static void
2304 shell_fade(struct desktop_shell *shell, enum fade_type type);
2305
2306 static int
2307 screensaver_timeout(void *data)
2308 {
2309         struct desktop_shell *shell = data;
2310
2311         shell_fade(shell, FADE_OUT);
2312
2313         return 1;
2314 }
2315
2316 static void
2317 handle_screensaver_sigchld(struct weston_process *proc, int status)
2318 {
2319         struct desktop_shell *shell =
2320                 container_of(proc, struct desktop_shell, screensaver.process);
2321
2322         proc->pid = 0;
2323
2324         if (shell->locked)
2325                 weston_compositor_sleep(shell->compositor);
2326 }
2327
2328 static void
2329 launch_screensaver(struct desktop_shell *shell)
2330 {
2331         if (shell->screensaver.binding)
2332                 return;
2333
2334         if (!shell->screensaver.path) {
2335                 weston_compositor_sleep(shell->compositor);
2336                 return;
2337         }
2338
2339         if (shell->screensaver.process.pid != 0) {
2340                 weston_log("old screensaver still running\n");
2341                 return;
2342         }
2343
2344         weston_client_launch(shell->compositor,
2345                            &shell->screensaver.process,
2346                            shell->screensaver.path,
2347                            handle_screensaver_sigchld);
2348 }
2349
2350 static void
2351 terminate_screensaver(struct desktop_shell *shell)
2352 {
2353         if (shell->screensaver.process.pid == 0)
2354                 return;
2355
2356         kill(shell->screensaver.process.pid, SIGTERM);
2357 }
2358
2359 static void
2360 configure_static_surface(struct weston_surface *es, struct weston_layer *layer, int32_t width, int32_t height)
2361 {
2362         struct weston_surface *s, *next;
2363
2364         if (width == 0)
2365                 return;
2366
2367         wl_list_for_each_safe(s, next, &layer->surface_list, layer_link) {
2368                 if (s->output == es->output && s != es) {
2369                         weston_surface_unmap(s);
2370                         s->configure = NULL;
2371                 }
2372         }
2373
2374         weston_surface_configure(es, es->output->x, es->output->y, width, height);
2375
2376         if (wl_list_empty(&es->layer_link)) {
2377                 wl_list_insert(&layer->surface_list, &es->layer_link);
2378                 weston_compositor_schedule_repaint(es->compositor);
2379         }
2380 }
2381
2382 static void
2383 background_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
2384 {
2385         struct desktop_shell *shell = es->configure_private;
2386
2387         configure_static_surface(es, &shell->background_layer, width, height);
2388 }
2389
2390 static void
2391 desktop_shell_set_background(struct wl_client *client,
2392                              struct wl_resource *resource,
2393                              struct wl_resource *output_resource,
2394                              struct wl_resource *surface_resource)
2395 {
2396         struct desktop_shell *shell = resource->data;
2397         struct weston_surface *surface = surface_resource->data;
2398
2399         if (surface->configure) {
2400                 wl_resource_post_error(surface_resource,
2401                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
2402                                        "surface role already assigned");
2403                 return;
2404         }
2405
2406         surface->configure = background_configure;
2407         surface->configure_private = shell;
2408         surface->output = output_resource->data;
2409         desktop_shell_send_configure(resource, 0,
2410                                      surface_resource,
2411                                      surface->output->width,
2412                                      surface->output->height);
2413 }
2414
2415 static void
2416 panel_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
2417 {
2418         struct desktop_shell *shell = es->configure_private;
2419
2420         configure_static_surface(es, &shell->panel_layer, width, height);
2421 }
2422
2423 static void
2424 desktop_shell_set_panel(struct wl_client *client,
2425                         struct wl_resource *resource,
2426                         struct wl_resource *output_resource,
2427                         struct wl_resource *surface_resource)
2428 {
2429         struct desktop_shell *shell = resource->data;
2430         struct weston_surface *surface = surface_resource->data;
2431
2432         if (surface->configure) {
2433                 wl_resource_post_error(surface_resource,
2434                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
2435                                        "surface role already assigned");
2436                 return;
2437         }
2438
2439         surface->configure = panel_configure;
2440         surface->configure_private = shell;
2441         surface->output = output_resource->data;
2442         desktop_shell_send_configure(resource, 0,
2443                                      surface_resource,
2444                                      surface->output->width,
2445                                      surface->output->height);
2446 }
2447
2448 static void
2449 lock_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
2450 {
2451         struct desktop_shell *shell = surface->configure_private;
2452
2453         if (width == 0)
2454                 return;
2455
2456         surface->geometry.width = width;
2457         surface->geometry.height = height;
2458         center_on_output(surface, get_default_output(shell->compositor));
2459
2460         if (!weston_surface_is_mapped(surface)) {
2461                 wl_list_insert(&shell->lock_layer.surface_list,
2462                                &surface->layer_link);
2463                 weston_surface_update_transform(surface);
2464                 shell_fade(shell, FADE_IN);
2465         }
2466 }
2467
2468 static void
2469 handle_lock_surface_destroy(struct wl_listener *listener, void *data)
2470 {
2471         struct desktop_shell *shell =
2472             container_of(listener, struct desktop_shell, lock_surface_listener);
2473
2474         weston_log("lock surface gone\n");
2475         shell->lock_surface = NULL;
2476 }
2477
2478 static void
2479 desktop_shell_set_lock_surface(struct wl_client *client,
2480                                struct wl_resource *resource,
2481                                struct wl_resource *surface_resource)
2482 {
2483         struct desktop_shell *shell = resource->data;
2484         struct weston_surface *surface = surface_resource->data;
2485
2486         shell->prepare_event_sent = false;
2487
2488         if (!shell->locked)
2489                 return;
2490
2491         shell->lock_surface = surface;
2492
2493         shell->lock_surface_listener.notify = handle_lock_surface_destroy;
2494         wl_signal_add(&surface_resource->destroy_signal,
2495                       &shell->lock_surface_listener);
2496
2497         surface->configure = lock_surface_configure;
2498         surface->configure_private = shell;
2499 }
2500
2501 static void
2502 resume_desktop(struct desktop_shell *shell)
2503 {
2504         struct workspace *ws = get_current_workspace(shell);
2505
2506         terminate_screensaver(shell);
2507
2508         wl_list_remove(&shell->lock_layer.link);
2509         wl_list_insert(&shell->compositor->cursor_layer.link,
2510                        &shell->fullscreen_layer.link);
2511         wl_list_insert(&shell->fullscreen_layer.link,
2512                        &shell->panel_layer.link);
2513         if (shell->showing_input_panels) {
2514                 wl_list_insert(&shell->panel_layer.link,
2515                                &shell->input_panel_layer.link);
2516                 wl_list_insert(&shell->input_panel_layer.link,
2517                                &ws->layer.link);
2518         } else {
2519                 wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
2520         }
2521
2522         restore_focus_state(shell, get_current_workspace(shell));
2523
2524         shell->locked = false;
2525         shell_fade(shell, FADE_IN);
2526         weston_compositor_damage_all(shell->compositor);
2527 }
2528
2529 static void
2530 desktop_shell_unlock(struct wl_client *client,
2531                      struct wl_resource *resource)
2532 {
2533         struct desktop_shell *shell = resource->data;
2534
2535         shell->prepare_event_sent = false;
2536
2537         if (shell->locked)
2538                 resume_desktop(shell);
2539 }
2540
2541 static void
2542 desktop_shell_set_grab_surface(struct wl_client *client,
2543                                struct wl_resource *resource,
2544                                struct wl_resource *surface_resource)
2545 {
2546         struct desktop_shell *shell = resource->data;
2547
2548         shell->grab_surface = surface_resource->data;
2549 }
2550
2551 static const struct desktop_shell_interface desktop_shell_implementation = {
2552         desktop_shell_set_background,
2553         desktop_shell_set_panel,
2554         desktop_shell_set_lock_surface,
2555         desktop_shell_unlock,
2556         desktop_shell_set_grab_surface
2557 };
2558
2559 static enum shell_surface_type
2560 get_shell_surface_type(struct weston_surface *surface)
2561 {
2562         struct shell_surface *shsurf;
2563
2564         shsurf = get_shell_surface(surface);
2565         if (!shsurf)
2566                 return SHELL_SURFACE_NONE;
2567         return shsurf->type;
2568 }
2569
2570 static void
2571 move_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
2572 {
2573         struct weston_surface *focus =
2574                 (struct weston_surface *) seat->pointer->focus;
2575         struct weston_surface *surface;
2576         struct shell_surface *shsurf;
2577
2578         surface = weston_surface_get_main_surface(focus);
2579         if (surface == NULL)
2580                 return;
2581
2582         shsurf = get_shell_surface(surface);
2583         if (shsurf == NULL || shsurf->type == SHELL_SURFACE_FULLSCREEN ||
2584             shsurf->type == SHELL_SURFACE_MAXIMIZED)
2585                 return;
2586
2587         surface_move(shsurf, (struct weston_seat *) seat);
2588 }
2589
2590 static void
2591 resize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
2592 {
2593         struct weston_surface *focus =
2594                 (struct weston_surface *) seat->pointer->focus;
2595         struct weston_surface *surface;
2596         uint32_t edges = 0;
2597         int32_t x, y;
2598         struct shell_surface *shsurf;
2599
2600         surface = weston_surface_get_main_surface(focus);
2601         if (surface == NULL)
2602                 return;
2603
2604         shsurf = get_shell_surface(surface);
2605         if (!shsurf || shsurf->type == SHELL_SURFACE_FULLSCREEN ||
2606             shsurf->type == SHELL_SURFACE_MAXIMIZED)
2607                 return;
2608
2609         weston_surface_from_global(surface,
2610                                    wl_fixed_to_int(seat->pointer->grab_x),
2611                                    wl_fixed_to_int(seat->pointer->grab_y),
2612                                    &x, &y);
2613
2614         if (x < surface->geometry.width / 3)
2615                 edges |= WL_SHELL_SURFACE_RESIZE_LEFT;
2616         else if (x < 2 * surface->geometry.width / 3)
2617                 edges |= 0;
2618         else
2619                 edges |= WL_SHELL_SURFACE_RESIZE_RIGHT;
2620
2621         if (y < surface->geometry.height / 3)
2622                 edges |= WL_SHELL_SURFACE_RESIZE_TOP;
2623         else if (y < 2 * surface->geometry.height / 3)
2624                 edges |= 0;
2625         else
2626                 edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
2627
2628         surface_resize(shsurf, (struct weston_seat *) seat, edges);
2629 }
2630
2631 static void
2632 surface_opacity_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
2633                         wl_fixed_t value, void *data)
2634 {
2635         float step = 0.005;
2636         struct shell_surface *shsurf;
2637         struct weston_surface *focus =
2638                 (struct weston_surface *) seat->pointer->focus;
2639         struct weston_surface *surface;
2640
2641         /* XXX: broken for windows containing sub-surfaces */
2642         surface = weston_surface_get_main_surface(focus);
2643         if (surface == NULL)
2644                 return;
2645
2646         shsurf = get_shell_surface(surface);
2647         if (!shsurf)
2648                 return;
2649
2650         surface->alpha -= wl_fixed_to_double(value) * step;
2651
2652         if (surface->alpha > 1.0)
2653                 surface->alpha = 1.0;
2654         if (surface->alpha < step)
2655                 surface->alpha = step;
2656
2657         weston_surface_geometry_dirty(surface);
2658         weston_surface_damage(surface);
2659 }
2660
2661 static void
2662 do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
2663         wl_fixed_t value)
2664 {
2665         struct weston_seat *ws = (struct weston_seat *) seat;
2666         struct weston_compositor *compositor = ws->compositor;
2667         struct weston_output *output;
2668         float increment;
2669
2670         wl_list_for_each(output, &compositor->output_list, link) {
2671                 if (pixman_region32_contains_point(&output->region,
2672                                                    wl_fixed_to_double(seat->pointer->x),
2673                                                    wl_fixed_to_double(seat->pointer->y),
2674                                                    NULL)) {
2675                         if (key == KEY_PAGEUP)
2676                                 increment = output->zoom.increment;
2677                         else if (key == KEY_PAGEDOWN)
2678                                 increment = -output->zoom.increment;
2679                         else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
2680                                 /* For every pixel zoom 20th of a step */
2681                                 increment = output->zoom.increment *
2682                                             -wl_fixed_to_double(value) / 20.0;
2683                         else
2684                                 increment = 0;
2685
2686                         output->zoom.level += increment;
2687
2688                         if (output->zoom.level < 0.0)
2689                                 output->zoom.level = 0.0;
2690                         else if (output->zoom.level > output->zoom.max_level)
2691                                 output->zoom.level = output->zoom.max_level;
2692                         else if (!output->zoom.active) {
2693                                 output->zoom.active = 1;
2694                                 output->disable_planes++;
2695                         }
2696
2697                         output->zoom.spring_z.target = output->zoom.level;
2698
2699                         weston_output_update_zoom(output, output->zoom.type);
2700                 }
2701         }
2702 }
2703
2704 static void
2705 zoom_axis_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
2706                   wl_fixed_t value, void *data)
2707 {
2708         do_zoom(seat, time, 0, axis, value);
2709 }
2710
2711 static void
2712 zoom_key_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2713                  void *data)
2714 {
2715         do_zoom(seat, time, key, 0, 0);
2716 }
2717
2718 static void
2719 terminate_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2720                   void *data)
2721 {
2722         struct weston_compositor *compositor = data;
2723
2724         wl_display_terminate(compositor->wl_display);
2725 }
2726
2727 static void
2728 rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
2729 {
2730         struct rotate_grab *rotate =
2731                 container_of(grab, struct rotate_grab, base.grab);
2732         struct weston_pointer *pointer = grab->pointer;
2733         struct shell_surface *shsurf = rotate->base.shsurf;
2734         struct weston_surface *surface;
2735         float cx, cy, dx, dy, cposx, cposy, dposx, dposy, r;
2736
2737         if (!shsurf)
2738                 return;
2739
2740         surface = shsurf->surface;
2741
2742         cx = 0.5f * surface->geometry.width;
2743         cy = 0.5f * surface->geometry.height;
2744
2745         dx = wl_fixed_to_double(pointer->x) - rotate->center.x;
2746         dy = wl_fixed_to_double(pointer->y) - rotate->center.y;
2747         r = sqrtf(dx * dx + dy * dy);
2748
2749         wl_list_remove(&shsurf->rotation.transform.link);
2750         weston_surface_geometry_dirty(shsurf->surface);
2751
2752         if (r > 20.0f) {
2753                 struct weston_matrix *matrix =
2754                         &shsurf->rotation.transform.matrix;
2755
2756                 weston_matrix_init(&rotate->rotation);
2757                 weston_matrix_rotate_xy(&rotate->rotation, dx / r, dy / r);
2758
2759                 weston_matrix_init(matrix);
2760                 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
2761                 weston_matrix_multiply(matrix, &shsurf->rotation.rotation);
2762                 weston_matrix_multiply(matrix, &rotate->rotation);
2763                 weston_matrix_translate(matrix, cx, cy, 0.0f);
2764
2765                 wl_list_insert(
2766                         &shsurf->surface->geometry.transformation_list,
2767                         &shsurf->rotation.transform.link);
2768         } else {
2769                 wl_list_init(&shsurf->rotation.transform.link);
2770                 weston_matrix_init(&shsurf->rotation.rotation);
2771                 weston_matrix_init(&rotate->rotation);
2772         }
2773
2774         /* We need to adjust the position of the surface
2775          * in case it was resized in a rotated state before */
2776         cposx = surface->geometry.x + cx;
2777         cposy = surface->geometry.y + cy;
2778         dposx = rotate->center.x - cposx;
2779         dposy = rotate->center.y - cposy;
2780         if (dposx != 0.0f || dposy != 0.0f) {
2781                 weston_surface_set_position(surface,
2782                                             surface->geometry.x + dposx,
2783                                             surface->geometry.y + dposy);
2784         }
2785
2786         /* Repaint implies weston_surface_update_transform(), which
2787          * lazily applies the damage due to rotation update.
2788          */
2789         weston_compositor_schedule_repaint(shsurf->surface->compositor);
2790 }
2791
2792 static void
2793 rotate_grab_button(struct weston_pointer_grab *grab,
2794                    uint32_t time, uint32_t button, uint32_t state_w)
2795 {
2796         struct rotate_grab *rotate =
2797                 container_of(grab, struct rotate_grab, base.grab);
2798         struct weston_pointer *pointer = grab->pointer;
2799         struct shell_surface *shsurf = rotate->base.shsurf;
2800         enum wl_pointer_button_state state = state_w;
2801
2802         if (pointer->button_count == 0 &&
2803             state == WL_POINTER_BUTTON_STATE_RELEASED) {
2804                 if (shsurf)
2805                         weston_matrix_multiply(&shsurf->rotation.rotation,
2806                                                &rotate->rotation);
2807                 shell_grab_end(&rotate->base);
2808                 free(rotate);
2809         }
2810 }
2811
2812 static const struct weston_pointer_grab_interface rotate_grab_interface = {
2813         noop_grab_focus,
2814         rotate_grab_motion,
2815         rotate_grab_button,
2816 };
2817
2818 static void
2819 surface_rotate(struct shell_surface *surface, struct weston_seat *seat)
2820 {
2821         struct rotate_grab *rotate;
2822         float dx, dy;
2823         float r;
2824
2825         rotate = malloc(sizeof *rotate);
2826         if (!rotate)
2827                 return;
2828
2829         weston_surface_to_global_float(surface->surface,
2830                                        surface->surface->geometry.width / 2,
2831                                        surface->surface->geometry.height / 2,
2832                                        &rotate->center.x, &rotate->center.y);
2833
2834         dx = wl_fixed_to_double(seat->pointer->x) - rotate->center.x;
2835         dy = wl_fixed_to_double(seat->pointer->y) - rotate->center.y;
2836         r = sqrtf(dx * dx + dy * dy);
2837         if (r > 20.0f) {
2838                 struct weston_matrix inverse;
2839
2840                 weston_matrix_init(&inverse);
2841                 weston_matrix_rotate_xy(&inverse, dx / r, -dy / r);
2842                 weston_matrix_multiply(&surface->rotation.rotation, &inverse);
2843
2844                 weston_matrix_init(&rotate->rotation);
2845                 weston_matrix_rotate_xy(&rotate->rotation, dx / r, dy / r);
2846         } else {
2847                 weston_matrix_init(&surface->rotation.rotation);
2848                 weston_matrix_init(&rotate->rotation);
2849         }
2850
2851         shell_grab_start(&rotate->base, &rotate_grab_interface, surface,
2852                          seat->pointer, DESKTOP_SHELL_CURSOR_ARROW);
2853 }
2854
2855 static void
2856 rotate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
2857                void *data)
2858 {
2859         struct weston_surface *focus =
2860                 (struct weston_surface *) seat->pointer->focus;
2861         struct weston_surface *base_surface;
2862         struct shell_surface *surface;
2863
2864         base_surface = weston_surface_get_main_surface(focus);
2865         if (base_surface == NULL)
2866                 return;
2867
2868         surface = get_shell_surface(base_surface);
2869         if (!surface || surface->type == SHELL_SURFACE_FULLSCREEN ||
2870             surface->type == SHELL_SURFACE_MAXIMIZED)
2871                 return;
2872
2873         surface_rotate(surface, seat);
2874 }
2875
2876 static void
2877 lower_fullscreen_layer(struct desktop_shell *shell)
2878 {
2879         struct workspace *ws;
2880         struct weston_surface *surface, *prev;
2881
2882         ws = get_current_workspace(shell);
2883         wl_list_for_each_reverse_safe(surface, prev,
2884                                       &shell->fullscreen_layer.surface_list,
2885                                       layer_link)
2886                 weston_surface_restack(surface, &ws->layer.surface_list);
2887 }
2888
2889 static void
2890 activate(struct desktop_shell *shell, struct weston_surface *es,
2891          struct weston_seat *seat)
2892 {
2893         struct weston_surface *main_surface;
2894         struct focus_state *state;
2895         struct workspace *ws;
2896
2897         main_surface = weston_surface_get_main_surface(es);
2898
2899         weston_surface_activate(es, seat);
2900
2901         state = ensure_focus_state(shell, seat);
2902         if (state == NULL)
2903                 return;
2904
2905         state->keyboard_focus = es;
2906         wl_list_remove(&state->surface_destroy_listener.link);
2907         wl_signal_add(&es->resource.destroy_signal,
2908                       &state->surface_destroy_listener);
2909
2910         switch (get_shell_surface_type(main_surface)) {
2911         case SHELL_SURFACE_FULLSCREEN:
2912                 /* should on top of panels */
2913                 shell_stack_fullscreen(get_shell_surface(main_surface));
2914                 shell_configure_fullscreen(get_shell_surface(main_surface));
2915                 break;
2916         default:
2917                 ws = get_current_workspace(shell);
2918                 weston_surface_restack(main_surface, &ws->layer.surface_list);
2919                 break;
2920         }
2921 }
2922
2923 /* no-op func for checking black surface */
2924 static void
2925 black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
2926 {
2927 }
2928
2929 static bool
2930 is_black_surface (struct weston_surface *es, struct weston_surface **fs_surface)
2931 {
2932         if (es->configure == black_surface_configure) {
2933                 if (fs_surface)
2934                         *fs_surface = (struct weston_surface *)es->configure_private;
2935                 return true;
2936         }
2937         return false;
2938 }
2939
2940 static void
2941 click_to_activate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
2942                           void *data)
2943 {
2944         struct weston_seat *ws = (struct weston_seat *) seat;
2945         struct desktop_shell *shell = data;
2946         struct weston_surface *focus;
2947         struct weston_surface *main_surface;
2948
2949         focus = (struct weston_surface *) seat->pointer->focus;
2950         if (!focus)
2951                 return;
2952
2953         if (is_black_surface(focus, &main_surface))
2954                 focus = main_surface;
2955
2956         main_surface = weston_surface_get_main_surface(focus);
2957         if (get_shell_surface_type(main_surface) == SHELL_SURFACE_NONE)
2958                 return;
2959
2960         if (seat->pointer->grab == &seat->pointer->default_grab)
2961                 activate(shell, focus, ws);
2962 }
2963
2964 static void
2965 lock(struct desktop_shell *shell)
2966 {
2967         struct workspace *ws = get_current_workspace(shell);
2968
2969         if (shell->locked) {
2970                 weston_compositor_sleep(shell->compositor);
2971                 return;
2972         }
2973
2974         shell->locked = true;
2975
2976         /* Hide all surfaces by removing the fullscreen, panel and
2977          * toplevel layers.  This way nothing else can show or receive
2978          * input events while we are locked. */
2979
2980         wl_list_remove(&shell->panel_layer.link);
2981         wl_list_remove(&shell->fullscreen_layer.link);
2982         if (shell->showing_input_panels)
2983                 wl_list_remove(&shell->input_panel_layer.link);
2984         wl_list_remove(&ws->layer.link);
2985         wl_list_insert(&shell->compositor->cursor_layer.link,
2986                        &shell->lock_layer.link);
2987
2988         launch_screensaver(shell);
2989
2990         /* TODO: disable bindings that should not work while locked. */
2991
2992         /* All this must be undone in resume_desktop(). */
2993 }
2994
2995 static void
2996 unlock(struct desktop_shell *shell)
2997 {
2998         if (!shell->locked || shell->lock_surface) {
2999                 shell_fade(shell, FADE_IN);
3000                 return;
3001         }
3002
3003         /* If desktop-shell client has gone away, unlock immediately. */
3004         if (!shell->child.desktop_shell) {
3005                 resume_desktop(shell);
3006                 return;
3007         }
3008
3009         if (shell->prepare_event_sent)
3010                 return;
3011
3012         desktop_shell_send_prepare_lock_surface(shell->child.desktop_shell);
3013         shell->prepare_event_sent = true;
3014 }
3015
3016 static void
3017 shell_fade_done(struct weston_surface_animation *animation, void *data)
3018 {
3019         struct desktop_shell *shell = data;
3020
3021         shell->fade.animation = NULL;
3022
3023         switch (shell->fade.type) {
3024         case FADE_IN:
3025                 weston_surface_destroy(shell->fade.surface);
3026                 shell->fade.surface = NULL;
3027                 break;
3028         case FADE_OUT:
3029                 lock(shell);
3030                 break;
3031         }
3032 }
3033
3034 static void
3035 shell_fade(struct desktop_shell *shell, enum fade_type type)
3036 {
3037         struct weston_compositor *compositor = shell->compositor;
3038         struct weston_surface *surface;
3039         float tint;
3040
3041         switch (type) {
3042         case FADE_IN:
3043                 tint = 0.0;
3044                 break;
3045         case FADE_OUT:
3046                 tint = 1.0;
3047                 break;
3048         default:
3049                 weston_log("shell: invalid fade type\n");
3050                 return;
3051         }
3052
3053         shell->fade.type = type;
3054
3055         if (shell->fade.surface == NULL) {
3056                 surface = weston_surface_create(compositor);
3057                 if (!surface)
3058                         return;
3059
3060                 weston_surface_configure(surface, 0, 0, 8192, 8192);
3061                 weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
3062                 surface->alpha = 1.0 - tint;
3063                 wl_list_insert(&compositor->fade_layer.surface_list,
3064                                &surface->layer_link);
3065                 weston_surface_update_transform(surface);
3066                 shell->fade.surface = surface;
3067                 pixman_region32_init(&surface->input);
3068         }
3069
3070         if (shell->fade.animation)
3071                 weston_fade_update(shell->fade.animation,
3072                                    shell->fade.surface->alpha, tint, 30.0);
3073         else
3074                 shell->fade.animation =
3075                         weston_fade_run(shell->fade.surface,
3076                                         1.0 - tint, tint, 30.0,
3077                                         shell_fade_done, shell);
3078 }
3079
3080 static void
3081 idle_handler(struct wl_listener *listener, void *data)
3082 {
3083         struct desktop_shell *shell =
3084                 container_of(listener, struct desktop_shell, idle_listener);
3085
3086         shell_fade(shell, FADE_OUT);
3087         /* lock() is called from shell_fade_done() */
3088 }
3089
3090 static void
3091 wake_handler(struct wl_listener *listener, void *data)
3092 {
3093         struct desktop_shell *shell =
3094                 container_of(listener, struct desktop_shell, wake_listener);
3095
3096         unlock(shell);
3097 }
3098
3099 static void
3100 show_input_panels(struct wl_listener *listener, void *data)
3101 {
3102         struct desktop_shell *shell =
3103                 container_of(listener, struct desktop_shell,
3104                              show_input_panel_listener);
3105         struct input_panel_surface *surface, *next;
3106         struct weston_surface *ws;
3107
3108         shell->text_input.surface = (struct weston_surface*)data;
3109
3110         if (shell->showing_input_panels)
3111                 return;
3112
3113         shell->showing_input_panels = true;
3114
3115         if (!shell->locked)
3116                 wl_list_insert(&shell->panel_layer.link,
3117                                &shell->input_panel_layer.link);
3118
3119         wl_list_for_each_safe(surface, next,
3120                               &shell->input_panel.surfaces, link) {
3121                 ws = surface->surface;
3122                 if (!ws->buffer_ref.buffer)
3123                         continue;
3124                 wl_list_insert(&shell->input_panel_layer.surface_list,
3125                                &ws->layer_link);
3126                 weston_surface_geometry_dirty(ws);
3127                 weston_surface_update_transform(ws);
3128                 weston_surface_damage(ws);
3129                 weston_slide_run(ws, ws->geometry.height, 0, NULL, NULL);
3130         }
3131 }
3132
3133 static void
3134 hide_input_panels(struct wl_listener *listener, void *data)
3135 {
3136         struct desktop_shell *shell =
3137                 container_of(listener, struct desktop_shell,
3138                              hide_input_panel_listener);
3139         struct weston_surface *surface, *next;
3140
3141         if (!shell->showing_input_panels)
3142                 return;
3143
3144         shell->showing_input_panels = false;
3145
3146         if (!shell->locked)
3147                 wl_list_remove(&shell->input_panel_layer.link);
3148
3149         wl_list_for_each_safe(surface, next,
3150                               &shell->input_panel_layer.surface_list, layer_link)
3151                 weston_surface_unmap(surface);
3152 }
3153
3154 static void
3155 update_input_panels(struct wl_listener *listener, void *data)
3156 {
3157         struct desktop_shell *shell =
3158                 container_of(listener, struct desktop_shell,
3159                              update_input_panel_listener);
3160
3161         memcpy(&shell->text_input.cursor_rectangle, data, sizeof(pixman_box32_t));
3162 }
3163
3164 static void
3165 center_on_output(struct weston_surface *surface, struct weston_output *output)
3166 {
3167         int32_t surf_x, surf_y, width, height;
3168         float x, y;
3169
3170         surface_subsurfaces_boundingbox(surface, &surf_x, &surf_y, &width, &height);
3171
3172         x = output->x + (output->width - width) / 2 - surf_x / 2;
3173         y = output->y + (output->height - height) / 2 - surf_y / 2;
3174
3175         weston_surface_configure(surface, x, y, width, height);
3176 }
3177
3178 static void
3179 weston_surface_set_initial_position (struct weston_surface *surface,
3180                                      struct desktop_shell *shell)
3181 {
3182         struct weston_compositor *compositor = shell->compositor;
3183         int ix = 0, iy = 0;
3184         int range_x, range_y;
3185         int dx, dy, x, y, panel_height;
3186         struct weston_output *output, *target_output = NULL;
3187         struct weston_seat *seat;
3188
3189         /* As a heuristic place the new window on the same output as the
3190          * pointer. Falling back to the output containing 0, 0.
3191          *
3192          * TODO: Do something clever for touch too?
3193          */
3194         wl_list_for_each(seat, &compositor->seat_list, link) {
3195                 if (seat->pointer) {
3196                         ix = wl_fixed_to_int(seat->pointer->x);
3197                         iy = wl_fixed_to_int(seat->pointer->y);
3198                         break;
3199                 }
3200         }
3201
3202         wl_list_for_each(output, &compositor->output_list, link) {
3203                 if (pixman_region32_contains_point(&output->region, ix, iy, NULL)) {
3204                         target_output = output;
3205                         break;
3206                 }
3207         }
3208
3209         if (!target_output) {
3210                 weston_surface_set_position(surface, 10 + random() % 400,
3211                                            10 + random() % 400);
3212                 return;
3213         }
3214
3215         /* Valid range within output where the surface will still be onscreen.
3216          * If this is negative it means that the surface is bigger than
3217          * output.
3218          */
3219         panel_height = get_output_panel_height(shell, target_output);
3220         range_x = target_output->width - surface->geometry.width;
3221         range_y = (target_output->height - panel_height) -
3222                   surface->geometry.height;
3223
3224         if (range_x > 0)
3225                 dx = random() % range_x;
3226         else
3227                 dx = 0;
3228
3229         if (range_y > 0)
3230                 dy = panel_height + random() % range_y;
3231         else
3232                 dy = panel_height;
3233
3234         x = target_output->x + dx;
3235         y = target_output->y + dy;
3236
3237         weston_surface_set_position (surface, x, y);
3238 }
3239
3240 static void
3241 map(struct desktop_shell *shell, struct weston_surface *surface,
3242     int32_t width, int32_t height, int32_t sx, int32_t sy)
3243 {
3244         struct weston_compositor *compositor = shell->compositor;
3245         struct shell_surface *shsurf = get_shell_surface(surface);
3246         enum shell_surface_type surface_type = shsurf->type;
3247         struct weston_surface *parent;
3248         struct weston_seat *seat;
3249         struct workspace *ws;
3250         int panel_height = 0;
3251         int32_t surf_x, surf_y;
3252
3253         surface->geometry.width = width;
3254         surface->geometry.height = height;
3255         weston_surface_geometry_dirty(surface);
3256
3257         /* initial positioning, see also configure() */
3258         switch (surface_type) {
3259         case SHELL_SURFACE_TOPLEVEL:
3260                 weston_surface_set_initial_position(surface, shell);
3261                 break;
3262         case SHELL_SURFACE_FULLSCREEN:
3263                 center_on_output(surface, shsurf->fullscreen_output);
3264                 shell_map_fullscreen(shsurf);
3265                 break;
3266         case SHELL_SURFACE_MAXIMIZED:
3267                 /* use surface configure to set the geometry */
3268                 panel_height = get_output_panel_height(shell,surface->output);
3269                 surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y,
3270                                                                  NULL, NULL);
3271                 weston_surface_set_position(surface, shsurf->output->x - surf_x,
3272                                             shsurf->output->y + panel_height - surf_y);
3273                 break;
3274         case SHELL_SURFACE_POPUP:
3275                 shell_map_popup(shsurf);
3276                 break;
3277         case SHELL_SURFACE_NONE:
3278                 weston_surface_set_position(surface,
3279                                             surface->geometry.x + sx,
3280                                             surface->geometry.y + sy);
3281                 break;
3282         default:
3283                 ;
3284         }
3285
3286         /* surface stacking order, see also activate() */
3287         switch (surface_type) {
3288         case SHELL_SURFACE_POPUP:
3289         case SHELL_SURFACE_TRANSIENT:
3290                 parent = shsurf->parent;
3291                 wl_list_insert(parent->layer_link.prev, &surface->layer_link);
3292                 break;
3293         case SHELL_SURFACE_FULLSCREEN:
3294         case SHELL_SURFACE_NONE:
3295                 break;
3296         default:
3297                 ws = get_current_workspace(shell);
3298                 wl_list_insert(&ws->layer.surface_list, &surface->layer_link);
3299                 break;
3300         }
3301
3302         if (surface_type != SHELL_SURFACE_NONE) {
3303                 weston_surface_update_transform(surface);
3304                 if (surface_type == SHELL_SURFACE_MAXIMIZED)
3305                         surface->output = shsurf->output;
3306         }
3307
3308         switch (surface_type) {
3309         case SHELL_SURFACE_TRANSIENT:
3310                 if (shsurf->transient.flags ==
3311                                 WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
3312                         break;
3313         case SHELL_SURFACE_TOPLEVEL:
3314         case SHELL_SURFACE_FULLSCREEN:
3315         case SHELL_SURFACE_MAXIMIZED:
3316                 if (!shell->locked) {
3317                         wl_list_for_each(seat, &compositor->seat_list, link)
3318                                 activate(shell, surface, seat);
3319                 }
3320                 break;
3321         default:
3322                 break;
3323         }
3324
3325         if (surface_type == SHELL_SURFACE_TOPLEVEL)
3326         {
3327                 switch (shell->win_animation_type) {
3328                 case ANIMATION_FADE:
3329                         weston_fade_run(surface, 0.0, 1.0, 200.0, NULL, NULL);
3330                         break;
3331                 case ANIMATION_ZOOM:
3332                         weston_zoom_run(surface, 0.8, 1.0, NULL, NULL);
3333                         break;
3334                 default:
3335                         break;
3336                 }
3337         }
3338 }
3339
3340 static void
3341 configure(struct desktop_shell *shell, struct weston_surface *surface,
3342           float x, float y, int32_t width, int32_t height)
3343 {
3344         enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
3345         struct shell_surface *shsurf;
3346         int32_t surf_x, surf_y;
3347
3348         shsurf = get_shell_surface(surface);
3349         if (shsurf)
3350                 surface_type = shsurf->type;
3351
3352         weston_surface_configure(surface, x, y, width, height);
3353
3354         switch (surface_type) {
3355         case SHELL_SURFACE_FULLSCREEN:
3356                 shell_stack_fullscreen(shsurf);
3357                 shell_configure_fullscreen(shsurf);
3358                 break;
3359         case SHELL_SURFACE_MAXIMIZED:
3360                 /* setting x, y and using configure to change that geometry */
3361                 surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y,
3362                                                                  NULL, NULL);
3363                 surface->geometry.x = surface->output->x - surf_x;
3364                 surface->geometry.y = surface->output->y +
3365                 get_output_panel_height(shell,surface->output) - surf_y;
3366                 break;
3367         case SHELL_SURFACE_TOPLEVEL:
3368                 break;
3369         default:
3370                 break;
3371         }
3372
3373         /* XXX: would a fullscreen surface need the same handling? */
3374         if (surface->output) {
3375                 weston_surface_update_transform(surface);
3376
3377                 if (surface_type == SHELL_SURFACE_MAXIMIZED)
3378                         surface->output = shsurf->output;
3379         }
3380 }
3381
3382 static void
3383 shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_t width, int32_t height)
3384 {
3385         struct shell_surface *shsurf = get_shell_surface(es);
3386         struct desktop_shell *shell = shsurf->shell;
3387
3388         int type_changed = 0;
3389
3390         if (!weston_surface_is_mapped(es) && !wl_list_empty(&shsurf->popup.grab_link)) {
3391                 remove_popup_grab(shsurf);
3392         }
3393
3394         if (width == 0)
3395                 return;
3396
3397         if (shsurf->next_type != SHELL_SURFACE_NONE &&
3398             shsurf->type != shsurf->next_type) {
3399                 set_surface_type(shsurf);
3400                 type_changed = 1;
3401         }
3402
3403         if (!weston_surface_is_mapped(es)) {
3404                 map(shell, es, width, height, sx, sy);
3405         } else if (type_changed || sx != 0 || sy != 0 ||
3406                    es->geometry.width != width ||
3407                    es->geometry.height != height) {
3408                 float from_x, from_y;
3409                 float to_x, to_y;
3410
3411                 weston_surface_to_global_float(es, 0, 0, &from_x, &from_y);
3412                 weston_surface_to_global_float(es, sx, sy, &to_x, &to_y);
3413                 configure(shell, es,
3414                           es->geometry.x + to_x - from_x,
3415                           es->geometry.y + to_y - from_y,
3416                           width, height);
3417         }
3418 }
3419
3420 static void launch_desktop_shell_process(void *data);
3421
3422 static void
3423 desktop_shell_sigchld(struct weston_process *process, int status)
3424 {
3425         uint32_t time;
3426         struct desktop_shell *shell =
3427                 container_of(process, struct desktop_shell, child.process);
3428
3429         shell->child.process.pid = 0;
3430         shell->child.client = NULL; /* already destroyed by wayland */
3431
3432         /* if desktop-shell dies more than 5 times in 30 seconds, give up */
3433         time = weston_compositor_get_time();
3434         if (time - shell->child.deathstamp > 30000) {
3435                 shell->child.deathstamp = time;
3436                 shell->child.deathcount = 0;
3437         }
3438
3439         shell->child.deathcount++;
3440         if (shell->child.deathcount > 5) {
3441                 weston_log("weston-desktop-shell died, giving up.\n");
3442                 return;
3443         }
3444
3445         weston_log("weston-desktop-shell died, respawning...\n");
3446         launch_desktop_shell_process(shell);
3447 }
3448
3449 static void
3450 launch_desktop_shell_process(void *data)
3451 {
3452         struct desktop_shell *shell = data;
3453         const char *shell_exe = LIBEXECDIR "/weston-desktop-shell";
3454
3455         shell->child.client = weston_client_launch(shell->compositor,
3456                                                  &shell->child.process,
3457                                                  shell_exe,
3458                                                  desktop_shell_sigchld);
3459
3460         if (!shell->child.client)
3461                 weston_log("not able to start %s\n", shell_exe);
3462 }
3463
3464 static void
3465 bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
3466 {
3467         struct desktop_shell *shell = data;
3468
3469         wl_client_add_object(client, &wl_shell_interface,
3470                              &shell_implementation, id, shell);
3471 }
3472
3473 static void
3474 unbind_desktop_shell(struct wl_resource *resource)
3475 {
3476         struct desktop_shell *shell = resource->data;
3477
3478         if (shell->locked)
3479                 resume_desktop(shell);
3480
3481         shell->child.desktop_shell = NULL;
3482         shell->prepare_event_sent = false;
3483         free(resource);
3484 }
3485
3486 static void
3487 bind_desktop_shell(struct wl_client *client,
3488                    void *data, uint32_t version, uint32_t id)
3489 {
3490         struct desktop_shell *shell = data;
3491         struct wl_resource *resource;
3492
3493         resource = wl_client_add_object(client, &desktop_shell_interface,
3494                                         &desktop_shell_implementation,
3495                                         id, shell);
3496
3497         if (client == shell->child.client) {
3498                 resource->destroy = unbind_desktop_shell;
3499                 shell->child.desktop_shell = resource;
3500                 return;
3501         }
3502
3503         wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
3504                                "permission to bind desktop_shell denied");
3505         wl_resource_destroy(resource);
3506 }
3507
3508 static void
3509 screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
3510 {
3511         struct desktop_shell *shell = surface->configure_private;
3512
3513         if (width == 0)
3514                 return;
3515
3516         /* XXX: starting weston-screensaver beforehand does not work */
3517         if (!shell->locked)
3518                 return;
3519
3520         center_on_output(surface, surface->output);
3521
3522         if (wl_list_empty(&surface->layer_link)) {
3523                 wl_list_insert(shell->lock_layer.surface_list.prev,
3524                                &surface->layer_link);
3525                 weston_surface_update_transform(surface);
3526                 wl_event_source_timer_update(shell->screensaver.timer,
3527                                              shell->screensaver.duration);
3528                 shell_fade(shell, FADE_IN);
3529         }
3530 }
3531
3532 static void
3533 screensaver_set_surface(struct wl_client *client,
3534                         struct wl_resource *resource,
3535                         struct wl_resource *surface_resource,
3536                         struct wl_resource *output_resource)
3537 {
3538         struct desktop_shell *shell = resource->data;
3539         struct weston_surface *surface = surface_resource->data;
3540         struct weston_output *output = output_resource->data;
3541
3542         surface->configure = screensaver_configure;
3543         surface->configure_private = shell;
3544         surface->output = output;
3545 }
3546
3547 static const struct screensaver_interface screensaver_implementation = {
3548         screensaver_set_surface
3549 };
3550
3551 static void
3552 unbind_screensaver(struct wl_resource *resource)
3553 {
3554         struct desktop_shell *shell = resource->data;
3555
3556         shell->screensaver.binding = NULL;
3557         free(resource);
3558 }
3559
3560 static void
3561 bind_screensaver(struct wl_client *client,
3562                  void *data, uint32_t version, uint32_t id)
3563 {
3564         struct desktop_shell *shell = data;
3565         struct wl_resource *resource;
3566
3567         resource = wl_client_add_object(client, &screensaver_interface,
3568                                         &screensaver_implementation,
3569                                         id, shell);
3570
3571         if (shell->screensaver.binding == NULL) {
3572                 resource->destroy = unbind_screensaver;
3573                 shell->screensaver.binding = resource;
3574                 return;
3575         }
3576
3577         wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
3578                                "interface object already bound");
3579         wl_resource_destroy(resource);
3580 }
3581
3582 static void
3583 input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
3584 {
3585         struct input_panel_surface *ip_surface = surface->configure_private;
3586         struct desktop_shell *shell = ip_surface->shell;
3587         struct weston_mode *mode;
3588         float x, y;
3589         uint32_t show_surface = 0;
3590
3591         if (width == 0)
3592                 return;
3593
3594         if (!weston_surface_is_mapped(surface)) {
3595                 if (!shell->showing_input_panels)
3596                         return;
3597
3598                 show_surface = 1;
3599         }
3600
3601         fprintf(stderr, "%s panel: %d, output: %p\n", __FUNCTION__, ip_surface->panel, ip_surface->output);
3602
3603         if (ip_surface->panel) {
3604                 x = shell->text_input.surface->geometry.x + shell->text_input.cursor_rectangle.x2;
3605                 y = shell->text_input.surface->geometry.y + shell->text_input.cursor_rectangle.y2;
3606         } else {
3607                 mode = ip_surface->output->current;
3608
3609                 x = ip_surface->output->x + (mode->width - width) / 2;
3610                 y = ip_surface->output->y + mode->height - height;
3611         }
3612
3613         weston_surface_configure(surface,
3614                                  x, y,
3615                                  width, height);
3616
3617         if (show_surface) {
3618                 wl_list_insert(&shell->input_panel_layer.surface_list,
3619                                &surface->layer_link);
3620                 weston_surface_update_transform(surface);
3621                 weston_surface_damage(surface);
3622                 weston_slide_run(surface, surface->geometry.height, 0, NULL, NULL);
3623         }
3624 }
3625
3626 static void
3627 destroy_input_panel_surface(struct input_panel_surface *input_panel_surface)
3628 {
3629         wl_list_remove(&input_panel_surface->surface_destroy_listener.link);
3630         wl_list_remove(&input_panel_surface->link);
3631
3632         input_panel_surface->surface->configure = NULL;
3633
3634         free(input_panel_surface);
3635 }
3636
3637 static struct input_panel_surface *
3638 get_input_panel_surface(struct weston_surface *surface)
3639 {
3640         if (surface->configure == input_panel_configure) {
3641                 return surface->configure_private;
3642         } else {
3643                 return NULL;
3644         }
3645 }
3646
3647 static void
3648 input_panel_handle_surface_destroy(struct wl_listener *listener, void *data)
3649 {
3650         struct input_panel_surface *ipsurface = container_of(listener,
3651                                                              struct input_panel_surface,
3652                                                              surface_destroy_listener);
3653
3654         if (ipsurface->resource.client) {
3655                 wl_resource_destroy(&ipsurface->resource);
3656         } else {
3657                 wl_signal_emit(&ipsurface->resource.destroy_signal,
3658                                &ipsurface->resource);
3659                 destroy_input_panel_surface(ipsurface);
3660         }
3661 }
3662 static struct input_panel_surface *
3663 create_input_panel_surface(struct desktop_shell *shell,
3664                            struct weston_surface *surface)
3665 {
3666         struct input_panel_surface *input_panel_surface;
3667
3668         input_panel_surface = calloc(1, sizeof *input_panel_surface);
3669         if (!input_panel_surface)
3670                 return NULL;
3671
3672         surface->configure = input_panel_configure;
3673         surface->configure_private = input_panel_surface;
3674
3675         input_panel_surface->shell = shell;
3676
3677         input_panel_surface->surface = surface;
3678
3679         wl_signal_init(&input_panel_surface->resource.destroy_signal);
3680         input_panel_surface->surface_destroy_listener.notify = input_panel_handle_surface_destroy;
3681         wl_signal_add(&surface->resource.destroy_signal,
3682                       &input_panel_surface->surface_destroy_listener);
3683
3684         wl_list_init(&input_panel_surface->link);
3685
3686         return input_panel_surface;
3687 }
3688
3689 static void
3690 input_panel_surface_set_toplevel(struct wl_client *client,
3691                                  struct wl_resource *resource,
3692                                  struct wl_resource *output_resource,
3693                                  uint32_t position)
3694 {
3695         struct input_panel_surface *input_panel_surface = resource->data;
3696         struct desktop_shell *shell = input_panel_surface->shell;
3697
3698         wl_list_insert(&shell->input_panel.surfaces,
3699                        &input_panel_surface->link);
3700
3701         input_panel_surface->output = output_resource->data;
3702         input_panel_surface->panel = 0;
3703
3704         fprintf(stderr, "%s panel: %d, output: %p\n", __FUNCTION__,
3705                 input_panel_surface->panel,
3706                 input_panel_surface->output);
3707 }
3708
3709 static void
3710 input_panel_surface_set_overlay_panel(struct wl_client *client,
3711                                       struct wl_resource *resource)
3712 {
3713         struct input_panel_surface *input_panel_surface = resource->data;
3714         struct desktop_shell *shell = input_panel_surface->shell;
3715
3716         wl_list_insert(&shell->input_panel.surfaces,
3717                        &input_panel_surface->link);
3718
3719         input_panel_surface->panel = 1;
3720 }
3721
3722 static const struct wl_input_panel_surface_interface input_panel_surface_implementation = {
3723         input_panel_surface_set_toplevel,
3724         input_panel_surface_set_overlay_panel
3725 };
3726
3727 static void
3728 destroy_input_panel_surface_resource(struct wl_resource *resource)
3729 {
3730         struct input_panel_surface *ipsurf = resource->data;
3731
3732         destroy_input_panel_surface(ipsurf);
3733 }
3734
3735 static void
3736 input_panel_get_input_panel_surface(struct wl_client *client,
3737                                     struct wl_resource *resource,
3738                                     uint32_t id,
3739                                     struct wl_resource *surface_resource)
3740 {
3741         struct weston_surface *surface = surface_resource->data;
3742         struct desktop_shell *shell = resource->data;
3743         struct input_panel_surface *ipsurf;
3744
3745         if (get_input_panel_surface(surface)) {
3746                 wl_resource_post_error(surface_resource,
3747                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3748                                        "wl_input_panel::get_input_panel_surface already requested");
3749                 return;
3750         }
3751
3752         ipsurf = create_input_panel_surface(shell, surface);
3753         if (!ipsurf) {
3754                 wl_resource_post_error(surface_resource,
3755                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
3756                                        "surface->configure already set");
3757                 return;
3758         }
3759
3760         ipsurf->resource.destroy = destroy_input_panel_surface_resource;
3761         ipsurf->resource.object.id = id;
3762         ipsurf->resource.object.interface = &wl_input_panel_surface_interface;
3763         ipsurf->resource.object.implementation =
3764                 (void (**)(void)) &input_panel_surface_implementation;
3765         ipsurf->resource.data = ipsurf;
3766
3767         wl_client_add_resource(client, &ipsurf->resource);
3768 }
3769
3770 static const struct wl_input_panel_interface input_panel_implementation = {
3771         input_panel_get_input_panel_surface
3772 };
3773
3774 static void
3775 unbind_input_panel(struct wl_resource *resource)
3776 {
3777         struct desktop_shell *shell = resource->data;
3778
3779         shell->input_panel.binding = NULL;
3780         free(resource);
3781 }
3782
3783 static void
3784 bind_input_panel(struct wl_client *client,
3785               void *data, uint32_t version, uint32_t id)
3786 {
3787         struct desktop_shell *shell = data;
3788         struct wl_resource *resource;
3789
3790         resource = wl_client_add_object(client, &wl_input_panel_interface,
3791                                         &input_panel_implementation,
3792                                         id, shell);
3793
3794         if (shell->input_panel.binding == NULL) {
3795                 resource->destroy = unbind_input_panel;
3796                 shell->input_panel.binding = resource;
3797                 return;
3798         }
3799
3800         wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
3801                                "interface object already bound");
3802         wl_resource_destroy(resource);
3803 }
3804
3805 struct switcher {
3806         struct desktop_shell *shell;
3807         struct weston_surface *current;
3808         struct wl_listener listener;
3809         struct weston_keyboard_grab grab;
3810 };
3811
3812 static void
3813 switcher_next(struct switcher *switcher)
3814 {
3815         struct weston_surface *surface;
3816         struct weston_surface *first = NULL, *prev = NULL, *next = NULL;
3817         struct shell_surface *shsurf;
3818         struct workspace *ws = get_current_workspace(switcher->shell);
3819
3820         wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
3821                 switch (get_shell_surface_type(surface)) {
3822                 case SHELL_SURFACE_TOPLEVEL:
3823                 case SHELL_SURFACE_FULLSCREEN:
3824                 case SHELL_SURFACE_MAXIMIZED:
3825                         if (first == NULL)
3826                                 first = surface;
3827                         if (prev == switcher->current)
3828                                 next = surface;
3829                         prev = surface;
3830                         surface->alpha = 0.25;
3831                         weston_surface_geometry_dirty(surface);
3832                         weston_surface_damage(surface);
3833                         break;
3834                 default:
3835                         break;
3836                 }
3837
3838                 if (is_black_surface(surface, NULL)) {
3839                         surface->alpha = 0.25;
3840                         weston_surface_geometry_dirty(surface);
3841                         weston_surface_damage(surface);
3842                 }
3843         }
3844
3845         if (next == NULL)
3846                 next = first;
3847
3848         if (next == NULL)
3849                 return;
3850
3851         wl_list_remove(&switcher->listener.link);
3852         wl_signal_add(&next->resource.destroy_signal, &switcher->listener);
3853
3854         switcher->current = next;
3855         next->alpha = 1.0;
3856
3857         shsurf = get_shell_surface(switcher->current);
3858         if (shsurf && shsurf->type ==SHELL_SURFACE_FULLSCREEN)
3859                 shsurf->fullscreen.black_surface->alpha = 1.0;
3860 }
3861
3862 static void
3863 switcher_handle_surface_destroy(struct wl_listener *listener, void *data)
3864 {
3865         struct switcher *switcher =
3866                 container_of(listener, struct switcher, listener);
3867
3868         switcher_next(switcher);
3869 }
3870
3871 static void
3872 switcher_destroy(struct switcher *switcher)
3873 {
3874         struct weston_surface *surface;
3875         struct weston_keyboard *keyboard = switcher->grab.keyboard;
3876         struct workspace *ws = get_current_workspace(switcher->shell);
3877
3878         wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
3879                 surface->alpha = 1.0;
3880                 weston_surface_damage(surface);
3881         }
3882
3883         if (switcher->current)
3884                 activate(switcher->shell, switcher->current,
3885                          (struct weston_seat *) keyboard->seat);
3886         wl_list_remove(&switcher->listener.link);
3887         weston_keyboard_end_grab(keyboard);
3888         if (keyboard->input_method_resource)
3889                 keyboard->grab = &keyboard->input_method_grab;
3890         free(switcher);
3891 }
3892
3893 static void
3894 switcher_key(struct weston_keyboard_grab *grab,
3895              uint32_t time, uint32_t key, uint32_t state_w)
3896 {
3897         struct switcher *switcher = container_of(grab, struct switcher, grab);
3898         enum wl_keyboard_key_state state = state_w;
3899
3900         if (key == KEY_TAB && state == WL_KEYBOARD_KEY_STATE_PRESSED)
3901                 switcher_next(switcher);
3902 }
3903
3904 static void
3905 switcher_modifier(struct weston_keyboard_grab *grab, uint32_t serial,
3906                   uint32_t mods_depressed, uint32_t mods_latched,
3907                   uint32_t mods_locked, uint32_t group)
3908 {
3909         struct switcher *switcher = container_of(grab, struct switcher, grab);
3910         struct weston_seat *seat = (struct weston_seat *) grab->keyboard->seat;
3911
3912         if ((seat->modifier_state & switcher->shell->binding_modifier) == 0)
3913                 switcher_destroy(switcher);
3914 }
3915
3916 static const struct weston_keyboard_grab_interface switcher_grab = {
3917         switcher_key,
3918         switcher_modifier,
3919 };
3920
3921 static void
3922 switcher_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
3923                  void *data)
3924 {
3925         struct desktop_shell *shell = data;
3926         struct switcher *switcher;
3927
3928         switcher = malloc(sizeof *switcher);
3929         switcher->shell = shell;
3930         switcher->current = NULL;
3931         switcher->listener.notify = switcher_handle_surface_destroy;
3932         wl_list_init(&switcher->listener.link);
3933
3934         lower_fullscreen_layer(switcher->shell);
3935         switcher->grab.interface = &switcher_grab;
3936         weston_keyboard_start_grab(seat->keyboard, &switcher->grab);
3937         weston_keyboard_set_focus(seat->keyboard, NULL);
3938         switcher_next(switcher);
3939 }
3940
3941 static void
3942 backlight_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
3943                   void *data)
3944 {
3945         struct weston_compositor *compositor = data;
3946         struct weston_output *output;
3947         long backlight_new = 0;
3948
3949         /* TODO: we're limiting to simple use cases, where we assume just
3950          * control on the primary display. We'd have to extend later if we
3951          * ever get support for setting backlights on random desktop LCD
3952          * panels though */
3953         output = get_default_output(compositor);
3954         if (!output)
3955                 return;
3956
3957         if (!output->set_backlight)
3958                 return;
3959
3960         if (key == KEY_F9 || key == KEY_BRIGHTNESSDOWN)
3961                 backlight_new = output->backlight_current - 25;
3962         else if (key == KEY_F10 || key == KEY_BRIGHTNESSUP)
3963                 backlight_new = output->backlight_current + 25;
3964
3965         if (backlight_new < 5)
3966                 backlight_new = 5;
3967         if (backlight_new > 255)
3968                 backlight_new = 255;
3969
3970         output->backlight_current = backlight_new;
3971         output->set_backlight(output, output->backlight_current);
3972 }
3973
3974 struct debug_binding_grab {
3975         struct weston_keyboard_grab grab;
3976         struct weston_seat *seat;
3977         uint32_t key[2];
3978         int key_released[2];
3979 };
3980
3981 static void
3982 debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time,
3983                   uint32_t key, uint32_t state)
3984 {
3985         struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
3986         struct wl_resource *resource;
3987         struct wl_display *display;
3988         uint32_t serial;
3989         int send = 0, terminate = 0;
3990         int check_binding = 1;
3991         int i;
3992
3993         if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
3994                 /* Do not run bindings on key releases */
3995                 check_binding = 0;
3996
3997                 for (i = 0; i < 2; i++)
3998                         if (key == db->key[i])
3999                                 db->key_released[i] = 1;
4000
4001                 if (db->key_released[0] && db->key_released[1]) {
4002                         /* All key releases been swalled so end the grab */
4003                         terminate = 1;
4004                 } else if (key != db->key[0] && key != db->key[1]) {
4005                         /* Should not swallow release of other keys */
4006                         send = 1;
4007                 }
4008         } else if (key == db->key[0] && !db->key_released[0]) {
4009                 /* Do not check bindings for the first press of the binding
4010                  * key. This allows it to be used as a debug shortcut.
4011                  * We still need to swallow this event. */
4012                 check_binding = 0;
4013         } else if (db->key[1]) {
4014                 /* If we already ran a binding don't process another one since
4015                  * we can't keep track of all the binding keys that were
4016                  * pressed in order to swallow the release events. */
4017                 send = 1;
4018                 check_binding = 0;
4019         }
4020
4021         if (check_binding) {
4022                 struct weston_compositor *ec = db->seat->compositor;
4023
4024                 if (weston_compositor_run_debug_binding(ec, db->seat, time,
4025                                                         key, state)) {
4026                         /* We ran a binding so swallow the press and keep the
4027                          * grab to swallow the released too. */
4028                         send = 0;
4029                         terminate = 0;
4030                         db->key[1] = key;
4031                 } else {
4032                         /* Terminate the grab since the key pressed is not a
4033                          * debug binding key. */
4034                         send = 1;
4035                         terminate = 1;
4036                 }
4037         }
4038
4039         if (send) {
4040                 resource = grab->keyboard->focus_resource;
4041
4042                 if (resource) {
4043                         display = wl_client_get_display(resource->client);
4044                         serial = wl_display_next_serial(display);
4045                         wl_keyboard_send_key(resource, serial, time, key, state);
4046                 }
4047         }
4048
4049         if (terminate) {
4050                 weston_keyboard_end_grab(grab->keyboard);
4051                 if (grab->keyboard->input_method_resource)
4052                         grab->keyboard->grab = &grab->keyboard->input_method_grab;
4053                 free(db);
4054         }
4055 }
4056
4057 static void
4058 debug_binding_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
4059                         uint32_t mods_depressed, uint32_t mods_latched,
4060                         uint32_t mods_locked, uint32_t group)
4061 {
4062         struct wl_resource *resource;
4063
4064         resource = grab->keyboard->focus_resource;
4065         if (!resource)
4066                 return;
4067
4068         wl_keyboard_send_modifiers(resource, serial, mods_depressed,
4069                                    mods_latched, mods_locked, group);
4070 }
4071
4072 struct weston_keyboard_grab_interface debug_binding_keyboard_grab = {
4073         debug_binding_key,
4074         debug_binding_modifiers
4075 };
4076
4077 static void
4078 debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
4079 {
4080         struct debug_binding_grab *grab;
4081
4082         grab = calloc(1, sizeof *grab);
4083         if (!grab)
4084                 return;
4085
4086         grab->seat = (struct weston_seat *) seat;
4087         grab->key[0] = key;
4088         grab->grab.interface = &debug_binding_keyboard_grab;
4089         weston_keyboard_start_grab(seat->keyboard, &grab->grab);
4090 }
4091
4092 static void
4093 force_kill_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
4094                    void *data)
4095 {
4096         struct weston_surface *focus_surface;
4097         struct wl_client *client;
4098         struct desktop_shell *shell = data;
4099         struct weston_compositor *compositor = shell->compositor;
4100         pid_t pid;
4101
4102         focus_surface = seat->keyboard->focus;
4103         if (!focus_surface)
4104                 return;
4105
4106         wl_signal_emit(&compositor->kill_signal, focus_surface);
4107
4108         client = focus_surface->resource.client;
4109         wl_client_get_credentials(client, &pid, NULL, NULL);
4110
4111         /* Skip clients that we launched ourselves (the credentials of
4112          * the socketpair is ours) */
4113         if (pid == getpid())
4114                 return;
4115
4116         kill(pid, SIGKILL);
4117 }
4118
4119 static void
4120 workspace_up_binding(struct weston_seat *seat, uint32_t time,
4121                      uint32_t key, void *data)
4122 {
4123         struct desktop_shell *shell = data;
4124         unsigned int new_index = shell->workspaces.current;
4125
4126         if (shell->locked)
4127                 return;
4128         if (new_index != 0)
4129                 new_index--;
4130
4131         change_workspace(shell, new_index);
4132 }
4133
4134 static void
4135 workspace_down_binding(struct weston_seat *seat, uint32_t time,
4136                        uint32_t key, void *data)
4137 {
4138         struct desktop_shell *shell = data;
4139         unsigned int new_index = shell->workspaces.current;
4140
4141         if (shell->locked)
4142                 return;
4143         if (new_index < shell->workspaces.num - 1)
4144                 new_index++;
4145
4146         change_workspace(shell, new_index);
4147 }
4148
4149 static void
4150 workspace_f_binding(struct weston_seat *seat, uint32_t time,
4151                     uint32_t key, void *data)
4152 {
4153         struct desktop_shell *shell = data;
4154         unsigned int new_index;
4155
4156         if (shell->locked)
4157                 return;
4158         new_index = key - KEY_F1;
4159         if (new_index >= shell->workspaces.num)
4160                 new_index = shell->workspaces.num - 1;
4161
4162         change_workspace(shell, new_index);
4163 }
4164
4165 static void
4166 workspace_move_surface_up_binding(struct weston_seat *seat, uint32_t time,
4167                                   uint32_t key, void *data)
4168 {
4169         struct desktop_shell *shell = data;
4170         unsigned int new_index = shell->workspaces.current;
4171
4172         if (shell->locked)
4173                 return;
4174
4175         if (new_index != 0)
4176                 new_index--;
4177
4178         take_surface_to_workspace_by_seat(shell, seat, new_index);
4179 }
4180
4181 static void
4182 workspace_move_surface_down_binding(struct weston_seat *seat, uint32_t time,
4183                                     uint32_t key, void *data)
4184 {
4185         struct desktop_shell *shell = data;
4186         unsigned int new_index = shell->workspaces.current;
4187
4188         if (shell->locked)
4189                 return;
4190
4191         if (new_index < shell->workspaces.num - 1)
4192                 new_index++;
4193
4194         take_surface_to_workspace_by_seat(shell, seat, new_index);
4195 }
4196
4197 static void
4198 shell_destroy(struct wl_listener *listener, void *data)
4199 {
4200         struct desktop_shell *shell =
4201                 container_of(listener, struct desktop_shell, destroy_listener);
4202         struct workspace **ws;
4203
4204         if (shell->child.client)
4205                 wl_client_destroy(shell->child.client);
4206
4207         wl_list_remove(&shell->idle_listener.link);
4208         wl_list_remove(&shell->wake_listener.link);
4209         wl_list_remove(&shell->show_input_panel_listener.link);
4210         wl_list_remove(&shell->hide_input_panel_listener.link);
4211
4212         wl_array_for_each(ws, &shell->workspaces.array)
4213                 workspace_destroy(*ws);
4214         wl_array_release(&shell->workspaces.array);
4215
4216         free(shell->screensaver.path);
4217         free(shell);
4218 }
4219
4220 static void
4221 shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
4222 {
4223         uint32_t mod;
4224         int i, num_workspace_bindings;
4225
4226         /* fixed bindings */
4227         weston_compositor_add_key_binding(ec, KEY_BACKSPACE,
4228                                           MODIFIER_CTRL | MODIFIER_ALT,
4229                                           terminate_binding, ec);
4230         weston_compositor_add_button_binding(ec, BTN_LEFT, 0,
4231                                              click_to_activate_binding,
4232                                              shell);
4233         weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL,
4234                                            MODIFIER_SUPER | MODIFIER_ALT,
4235                                            surface_opacity_binding, NULL);
4236         weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL,
4237                                            MODIFIER_SUPER, zoom_axis_binding,
4238                                            NULL);
4239
4240         /* configurable bindings */
4241         mod = shell->binding_modifier;
4242         weston_compositor_add_key_binding(ec, KEY_PAGEUP, mod,
4243                                           zoom_key_binding, NULL);
4244         weston_compositor_add_key_binding(ec, KEY_PAGEDOWN, mod,
4245                                           zoom_key_binding, NULL);
4246         weston_compositor_add_button_binding(ec, BTN_LEFT, mod, move_binding,
4247                                              shell);
4248         weston_compositor_add_button_binding(ec, BTN_MIDDLE, mod,
4249                                              resize_binding, shell);
4250
4251         if (ec->capabilities & WESTON_CAP_ROTATION_ANY)
4252                 weston_compositor_add_button_binding(ec, BTN_RIGHT, mod,
4253                                                      rotate_binding, NULL);
4254
4255         weston_compositor_add_key_binding(ec, KEY_TAB, mod, switcher_binding,
4256                                           shell);
4257         weston_compositor_add_key_binding(ec, KEY_F9, mod, backlight_binding,
4258                                           ec);
4259         weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSDOWN, 0,
4260                                           backlight_binding, ec);
4261         weston_compositor_add_key_binding(ec, KEY_F10, mod, backlight_binding,
4262                                           ec);
4263         weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSUP, 0,
4264                                           backlight_binding, ec);
4265         weston_compositor_add_key_binding(ec, KEY_K, mod,
4266                                           force_kill_binding, shell);
4267         weston_compositor_add_key_binding(ec, KEY_UP, mod,
4268                                           workspace_up_binding, shell);
4269         weston_compositor_add_key_binding(ec, KEY_DOWN, mod,
4270                                           workspace_down_binding, shell);
4271         weston_compositor_add_key_binding(ec, KEY_UP, mod | MODIFIER_SHIFT,
4272                                           workspace_move_surface_up_binding,
4273                                           shell);
4274         weston_compositor_add_key_binding(ec, KEY_DOWN, mod | MODIFIER_SHIFT,
4275                                           workspace_move_surface_down_binding,
4276                                           shell);
4277
4278         /* Add bindings for mod+F[1-6] for workspace 1 to 6. */
4279         if (shell->workspaces.num > 1) {
4280                 num_workspace_bindings = shell->workspaces.num;
4281                 if (num_workspace_bindings > 6)
4282                         num_workspace_bindings = 6;
4283                 for (i = 0; i < num_workspace_bindings; i++)
4284                         weston_compositor_add_key_binding(ec, KEY_F1 + i, mod,
4285                                                           workspace_f_binding,
4286                                                           shell);
4287         }
4288
4289         /* Debug bindings */
4290         weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_SHIFT,
4291                                           debug_binding, shell);
4292 }
4293
4294 WL_EXPORT int
4295 module_init(struct weston_compositor *ec,
4296             int *argc, char *argv[])
4297 {
4298         struct weston_seat *seat;
4299         struct desktop_shell *shell;
4300         struct workspace **pws;
4301         unsigned int i;
4302         struct wl_event_loop *loop;
4303
4304         shell = malloc(sizeof *shell);
4305         if (shell == NULL)
4306                 return -1;
4307
4308         memset(shell, 0, sizeof *shell);
4309         shell->compositor = ec;
4310
4311         shell->destroy_listener.notify = shell_destroy;
4312         wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
4313         shell->idle_listener.notify = idle_handler;
4314         wl_signal_add(&ec->idle_signal, &shell->idle_listener);
4315         shell->wake_listener.notify = wake_handler;
4316         wl_signal_add(&ec->wake_signal, &shell->wake_listener);
4317         shell->show_input_panel_listener.notify = show_input_panels;
4318         wl_signal_add(&ec->show_input_panel_signal, &shell->show_input_panel_listener);
4319         shell->hide_input_panel_listener.notify = hide_input_panels;
4320         wl_signal_add(&ec->hide_input_panel_signal, &shell->hide_input_panel_listener);
4321         shell->update_input_panel_listener.notify = update_input_panels;
4322         wl_signal_add(&ec->update_input_panel_signal, &shell->update_input_panel_listener);
4323         ec->ping_handler = ping_handler;
4324         ec->shell_interface.shell = shell;
4325         ec->shell_interface.create_shell_surface = create_shell_surface;
4326         ec->shell_interface.set_toplevel = set_toplevel;
4327         ec->shell_interface.set_transient = set_transient;
4328         ec->shell_interface.set_fullscreen = set_fullscreen;
4329         ec->shell_interface.move = surface_move;
4330         ec->shell_interface.resize = surface_resize;
4331
4332         wl_list_init(&shell->input_panel.surfaces);
4333
4334         weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
4335         weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
4336         weston_layer_init(&shell->background_layer, &shell->panel_layer.link);
4337         weston_layer_init(&shell->lock_layer, NULL);
4338         weston_layer_init(&shell->input_panel_layer, NULL);
4339
4340         wl_array_init(&shell->workspaces.array);
4341         wl_list_init(&shell->workspaces.client_list);
4342
4343         shell_configuration(shell, ec->config_fd);
4344
4345         for (i = 0; i < shell->workspaces.num; i++) {
4346                 pws = wl_array_add(&shell->workspaces.array, sizeof *pws);
4347                 if (pws == NULL)
4348                         return -1;
4349
4350                 *pws = workspace_create();
4351                 if (*pws == NULL)
4352                         return -1;
4353         }
4354         activate_workspace(shell, 0);
4355
4356         wl_list_init(&shell->workspaces.anim_sticky_list);
4357         wl_list_init(&shell->workspaces.animation.link);
4358         shell->workspaces.animation.frame = animate_workspace_change_frame;
4359
4360         if (wl_display_add_global(ec->wl_display, &wl_shell_interface,
4361                                   shell, bind_shell) == NULL)
4362                 return -1;
4363
4364         if (wl_display_add_global(ec->wl_display,
4365                                   &desktop_shell_interface,
4366                                   shell, bind_desktop_shell) == NULL)
4367                 return -1;
4368
4369         if (wl_display_add_global(ec->wl_display, &screensaver_interface,
4370                                   shell, bind_screensaver) == NULL)
4371                 return -1;
4372
4373         if (wl_display_add_global(ec->wl_display, &wl_input_panel_interface,
4374                                   shell, bind_input_panel) == NULL)
4375                 return -1;
4376
4377         if (wl_display_add_global(ec->wl_display, &workspace_manager_interface,
4378                                   shell, bind_workspace_manager) == NULL)
4379                 return -1;
4380
4381         shell->child.deathstamp = weston_compositor_get_time();
4382
4383         loop = wl_display_get_event_loop(ec->wl_display);
4384         wl_event_loop_add_idle(loop, launch_desktop_shell_process, shell);
4385
4386         shell->screensaver.timer =
4387                 wl_event_loop_add_timer(loop, screensaver_timeout, shell);
4388
4389         wl_list_for_each(seat, &ec->seat_list, link)
4390                 create_pointer_focus_listener(seat);
4391
4392         shell_add_bindings(ec, shell);
4393
4394         shell_fade(shell, FADE_IN);
4395
4396         return 0;
4397 }