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