Replace fprintf() by weston_log()
[profile/ivi/weston.git] / src / shell.c
1 /*
2  * Copyright © 2010-2012 Intel Corporation
3  * Copyright © 2011-2012 Collabora, Ltd.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of the copyright holders not be used in
10  * advertising or publicity pertaining to distribution of the software
11  * without specific, written prior permission.  The copyright holders make
12  * no representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  */
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <stdbool.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <linux/input.h>
30 #include <assert.h>
31 #include <signal.h>
32 #include <math.h>
33 #include <sys/types.h>
34
35 #include <wayland-server.h>
36 #include "compositor.h"
37 #include "desktop-shell-server-protocol.h"
38 #include "../shared/config-parser.h"
39 #include "log.h"
40
41 enum animation_type {
42         ANIMATION_NONE,
43
44         ANIMATION_ZOOM,
45         ANIMATION_FADE
46 };
47
48 struct desktop_shell {
49         struct weston_compositor *compositor;
50
51         struct wl_listener lock_listener;
52         struct wl_listener unlock_listener;
53         struct wl_listener destroy_listener;
54
55         struct weston_layer fullscreen_layer;
56         struct weston_layer panel_layer;
57         struct weston_layer toplevel_layer;
58         struct weston_layer background_layer;
59         struct weston_layer lock_layer;
60
61         struct wl_listener pointer_focus_listener;
62         struct weston_surface *busy_surface;
63
64         struct {
65                 struct weston_process process;
66                 struct wl_client *client;
67                 struct wl_resource *desktop_shell;
68
69                 unsigned deathcount;
70                 uint32_t deathstamp;
71         } child;
72
73         bool locked;
74         bool prepare_event_sent;
75
76         struct shell_surface *lock_surface;
77         struct wl_listener lock_surface_listener;
78
79         struct wl_list backgrounds;
80         struct wl_list panels;
81
82         struct {
83                 char *path;
84                 int duration;
85                 struct wl_resource *binding;
86                 struct wl_list surfaces;
87                 struct weston_process process;
88         } screensaver;
89
90         uint32_t binding_modifier;
91         enum animation_type win_animation_type;
92         struct weston_surface *debug_repaint_surface;
93 };
94
95 enum shell_surface_type {
96         SHELL_SURFACE_NONE,
97
98         SHELL_SURFACE_PANEL,
99         SHELL_SURFACE_BACKGROUND,
100         SHELL_SURFACE_LOCK,
101         SHELL_SURFACE_SCREENSAVER,
102
103         SHELL_SURFACE_TOPLEVEL,
104         SHELL_SURFACE_TRANSIENT,
105         SHELL_SURFACE_FULLSCREEN,
106         SHELL_SURFACE_MAXIMIZED,
107         SHELL_SURFACE_POPUP
108 };
109
110 struct ping_timer {
111         struct wl_event_source *source;
112         uint32_t serial;
113 };
114
115 struct shell_surface {
116         struct wl_resource resource;
117
118         struct weston_surface *surface;
119         struct wl_listener surface_destroy_listener;
120         struct shell_surface *parent;
121         struct desktop_shell *shell;
122
123         enum shell_surface_type type, next_type;
124         char *title, *class;
125         int32_t saved_x, saved_y;
126         bool saved_position_valid;
127         bool saved_rotation_valid;
128         int unresponsive;
129
130         struct {
131                 struct weston_transform transform;
132                 struct weston_matrix rotation;
133         } rotation;
134
135         struct {
136                 struct wl_pointer_grab grab;
137                 int32_t x, y;
138                 struct weston_transform parent_transform;
139                 int32_t initial_up;
140                 struct wl_seat *seat;
141                 uint32_t serial;
142         } popup;
143
144         struct {
145                 int32_t x, y;
146                 uint32_t flags;
147         } transient;
148
149         struct {
150                 enum wl_shell_surface_fullscreen_method type;
151                 struct weston_transform transform; /* matrix from x, y */
152                 uint32_t framerate;
153                 struct weston_surface *black_surface;
154         } fullscreen;
155
156         struct ping_timer *ping_timer;
157
158         struct weston_output *fullscreen_output;
159         struct weston_output *output;
160         struct wl_list link;
161
162         const struct weston_shell_client *client;
163 };
164
165 struct shell_grab {
166         struct wl_pointer_grab grab;
167         struct shell_surface *shsurf;
168         struct wl_listener shsurf_destroy_listener;
169 };
170
171 struct weston_move_grab {
172         struct shell_grab base;
173         wl_fixed_t dx, dy;
174 };
175
176 struct rotate_grab {
177         struct shell_grab base;
178         struct weston_matrix rotation;
179         struct {
180                 GLfloat x;
181                 GLfloat y;
182         } center;
183 };
184
185 static struct shell_surface *
186 get_shell_surface(struct weston_surface *surface);
187
188 static struct desktop_shell *
189 shell_surface_get_shell(struct shell_surface *shsurf);
190
191 static bool
192 shell_surface_is_top_fullscreen(struct shell_surface *shsurf)
193 {
194         struct desktop_shell *shell;
195         struct weston_surface *top_fs_es;
196
197         shell = shell_surface_get_shell(shsurf);
198         
199         if (wl_list_empty(&shell->fullscreen_layer.surface_list))
200                 return false;
201
202         top_fs_es = container_of(shell->fullscreen_layer.surface_list.next,
203                                  struct weston_surface, 
204                                  layer_link);
205         return (shsurf == get_shell_surface(top_fs_es));
206 }
207
208 static void
209 destroy_shell_grab_shsurf(struct wl_listener *listener, void *data)
210 {
211         struct shell_grab *grab;
212
213         grab = container_of(listener, struct shell_grab,
214                             shsurf_destroy_listener);
215
216         grab->shsurf = NULL;
217 }
218
219 static void
220 shell_grab_init(struct shell_grab *grab,
221                 const struct wl_pointer_grab_interface *interface,
222                 struct shell_surface *shsurf)
223 {
224         grab->grab.interface = interface;
225         grab->shsurf = shsurf;
226         grab->shsurf_destroy_listener.notify = destroy_shell_grab_shsurf;
227         wl_signal_add(&shsurf->resource.destroy_signal,
228                       &grab->shsurf_destroy_listener);
229
230 }
231
232 static void
233 shell_grab_finish(struct shell_grab *grab)
234 {
235         if (grab->shsurf)
236                 wl_list_remove(&grab->shsurf_destroy_listener.link);
237 }
238
239 static void
240 center_on_output(struct weston_surface *surface,
241                  struct weston_output *output);
242
243 static enum weston_keyboard_modifier
244 get_modifier(char *modifier)
245 {
246         if (!modifier)
247                 return MODIFIER_SUPER;
248
249         if (!strcmp("ctrl", modifier))
250                 return MODIFIER_CTRL;
251         else if (!strcmp("alt", modifier))
252                 return MODIFIER_ALT;
253         else if (!strcmp("super", modifier))
254                 return MODIFIER_SUPER;
255         else
256                 return MODIFIER_SUPER;
257 }
258
259 static enum animation_type
260 get_animation_type(char *animation)
261 {
262         if (!animation)
263                 return ANIMATION_NONE;
264
265         if (!strcmp("zoom", animation))
266                 return ANIMATION_ZOOM;
267         else if (!strcmp("fade", animation))
268                 return ANIMATION_FADE;
269         else
270                 return ANIMATION_NONE;
271 }
272
273 static void
274 shell_configuration(struct desktop_shell *shell)
275 {
276         char *config_file;
277         char *path = NULL;
278         int duration = 60;
279         char *modifier = NULL;
280         char *win_animation = NULL;
281
282         struct config_key shell_keys[] = {
283                 { "binding-modifier",   CONFIG_KEY_STRING, &modifier },
284                 { "animation",          CONFIG_KEY_STRING, &win_animation},
285         };
286
287         struct config_key saver_keys[] = {
288                 { "path",       CONFIG_KEY_STRING,  &path },
289                 { "duration",   CONFIG_KEY_INTEGER, &duration },
290         };
291
292         struct config_section cs[] = {
293                 { "shell", shell_keys, ARRAY_LENGTH(shell_keys), NULL },
294                 { "screensaver", saver_keys, ARRAY_LENGTH(saver_keys), NULL },
295         };
296
297         config_file = config_file_path("weston.ini");
298         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), shell);
299         free(config_file);
300
301         shell->screensaver.path = path;
302         shell->screensaver.duration = duration;
303         shell->binding_modifier = get_modifier(modifier);
304         shell->win_animation_type = get_animation_type(win_animation);
305 }
306
307 static void
308 noop_grab_focus(struct wl_pointer_grab *grab,
309                 struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y)
310 {
311         grab->focus = NULL;
312 }
313
314 static void
315 move_grab_motion(struct wl_pointer_grab *grab,
316                  uint32_t time, wl_fixed_t x, wl_fixed_t y)
317 {
318         struct weston_move_grab *move = (struct weston_move_grab *) grab;
319         struct wl_pointer *pointer = grab->pointer;
320         struct shell_surface *shsurf = move->base.shsurf;
321         struct weston_surface *es;
322         int dx = wl_fixed_to_int(pointer->x + move->dx);
323         int dy = wl_fixed_to_int(pointer->y + move->dy);
324
325         if (!shsurf)
326                 return;
327
328         es = shsurf->surface;
329
330         weston_surface_configure(es, dx, dy,
331                                  es->geometry.width, es->geometry.height);
332 }
333
334 static void
335 move_grab_button(struct wl_pointer_grab *grab,
336                  uint32_t time, uint32_t button, uint32_t state_w)
337 {
338         struct shell_grab *shell_grab = container_of(grab, struct shell_grab,
339                                                     grab);
340         struct wl_pointer *pointer = grab->pointer;
341         enum wl_pointer_button_state state = state_w;
342
343         if (pointer->button_count == 0 &&
344             state == WL_POINTER_BUTTON_STATE_RELEASED) {
345                 shell_grab_finish(shell_grab);
346                 wl_pointer_end_grab(pointer);
347                 free(grab);
348         }
349 }
350
351 static const struct wl_pointer_grab_interface move_grab_interface = {
352         noop_grab_focus,
353         move_grab_motion,
354         move_grab_button,
355 };
356
357 static void
358 busy_cursor_grab_focus(struct wl_pointer_grab *base,
359                        struct wl_surface *surface, int32_t x, int32_t y)
360 {
361         struct shell_grab *grab = (struct shell_grab *) base;
362         struct wl_pointer *pointer = base->pointer;
363
364         if (grab->grab.focus != surface) {
365                 shell_grab_finish(grab);
366                 wl_pointer_end_grab(pointer);
367                 free(grab);
368         }
369 }
370
371 static void
372 busy_cursor_grab_motion(struct wl_pointer_grab *grab,
373                         uint32_t time, int32_t x, int32_t y)
374 {
375 }
376
377 static void
378 busy_cursor_grab_button(struct wl_pointer_grab *grab,
379                         uint32_t time, uint32_t button, uint32_t state)
380 {
381 }
382
383 static const struct wl_pointer_grab_interface busy_cursor_grab_interface = {
384         busy_cursor_grab_focus,
385         busy_cursor_grab_motion,
386         busy_cursor_grab_button,
387 };
388
389 static void
390 set_busy_cursor(struct shell_surface *shsurf, struct wl_pointer *pointer)
391 {
392         struct shell_grab *grab;
393         struct desktop_shell *shell = shsurf->shell;
394         struct weston_seat *seat = (struct weston_seat *) pointer->seat;
395         struct weston_surface *sprite;
396
397         grab = malloc(sizeof *grab);
398         if (!grab)
399                 return;
400
401         shell_grab_init(grab, &busy_cursor_grab_interface, shsurf);
402         grab->grab.focus = &shsurf->surface->surface;
403         wl_pointer_start_grab(pointer, &grab->grab);
404         wl_pointer_set_focus(pointer, &shell->busy_surface->surface, 0, 0);
405
406         sprite = (struct weston_surface *) seat->sprite;
407         shell->busy_surface->output = sprite->output;
408 }
409
410 static void
411 end_busy_cursor(struct shell_surface *shsurf, struct wl_pointer *pointer)
412 {
413         struct shell_grab *grab = (struct shell_grab *) pointer->grab;
414
415         if (grab->grab.interface == &busy_cursor_grab_interface) {
416                 shell_grab_finish(grab);
417                 wl_pointer_end_grab(pointer);
418                 free(grab);
419         }
420 }
421
422 static void
423 ping_timer_destroy(struct shell_surface *shsurf)
424 {
425         if (!shsurf || !shsurf->ping_timer)
426                 return;
427
428         if (shsurf->ping_timer->source)
429                 wl_event_source_remove(shsurf->ping_timer->source);
430
431         free(shsurf->ping_timer);
432         shsurf->ping_timer = NULL;
433 }
434
435 static int
436 ping_timeout_handler(void *data)
437 {
438         struct shell_surface *shsurf = data;
439         struct weston_seat *seat;
440
441         /* Client is not responding */
442         shsurf->unresponsive = 1;
443
444         wl_list_for_each(seat, &shsurf->surface->compositor->seat_list, link)
445                 if (seat->seat.pointer->focus == &shsurf->surface->surface)
446                         set_busy_cursor(shsurf, seat->seat.pointer);
447
448         return 1;
449 }
450
451 static void
452 ping_handler(struct weston_surface *surface, uint32_t serial)
453 {
454         struct shell_surface *shsurf = get_shell_surface(surface);
455         struct wl_event_loop *loop;
456         int ping_timeout = 200;
457
458         if (!shsurf)
459                 return;
460         if (!shsurf->resource.client)
461                 return;
462
463         if (!shsurf->ping_timer) {
464                 shsurf->ping_timer = malloc(sizeof *shsurf->ping_timer);
465                 if (!shsurf->ping_timer)
466                         return;
467
468                 shsurf->ping_timer->serial = serial;
469                 loop = wl_display_get_event_loop(surface->compositor->wl_display);
470                 shsurf->ping_timer->source =
471                         wl_event_loop_add_timer(loop, ping_timeout_handler, shsurf);
472                 wl_event_source_timer_update(shsurf->ping_timer->source, ping_timeout);
473
474                 wl_shell_surface_send_ping(&shsurf->resource, serial);
475         }
476 }
477
478 static void
479 handle_pointer_focus(struct wl_listener *listener, void *data)
480 {
481         struct wl_pointer *pointer = data;
482         struct weston_surface *surface =
483                 (struct weston_surface *) pointer->focus;
484         struct weston_compositor *compositor;
485         struct shell_surface *shsurf;
486         uint32_t serial;
487
488         if (!surface)
489                 return;
490
491         compositor = surface->compositor;
492         shsurf = get_shell_surface(surface);
493
494         if (shsurf && shsurf->unresponsive) {
495                 set_busy_cursor(shsurf, pointer);
496         } else {
497                 serial = wl_display_next_serial(compositor->wl_display);
498                 ping_handler(surface, serial);
499         }
500 }
501
502 static void
503 shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
504                                                         uint32_t serial)
505 {
506         struct shell_surface *shsurf = resource->data;
507         struct desktop_shell *shell = shsurf->shell;
508         struct weston_seat *seat;
509         struct weston_compositor *ec = shsurf->surface->compositor;
510         struct wl_pointer *pointer;
511         int was_unresponsive;
512
513         if (shsurf->ping_timer->serial == serial) {
514                 was_unresponsive = shsurf->unresponsive;
515                 shsurf->unresponsive = 0;
516                 if (was_unresponsive) {
517                         /* Received pong from previously unresponsive client */
518                         wl_list_for_each(seat, &ec->seat_list, link) {
519                                 pointer = seat->seat.pointer;
520                                 if (pointer->focus ==
521                                     &shell->busy_surface->surface &&
522                                     pointer->current ==
523                                     &shsurf->surface->surface)
524                                         end_busy_cursor(shsurf, pointer);
525                         }
526                 }
527                 ping_timer_destroy(shsurf);
528         }
529 }
530
531 static void
532 shell_surface_set_title(struct wl_client *client,
533                         struct wl_resource *resource, const char *title)
534 {
535         struct shell_surface *shsurf = resource->data;
536
537         free(shsurf->title);
538         shsurf->title = strdup(title);
539 }
540
541 static void
542 shell_surface_set_class(struct wl_client *client,
543                         struct wl_resource *resource, const char *class)
544 {
545         struct shell_surface *shsurf = resource->data;
546
547         free(shsurf->class);
548         shsurf->class = strdup(class);
549 }
550
551 static int
552 surface_move(struct shell_surface *shsurf, struct weston_seat *ws)
553 {
554         struct weston_move_grab *move;
555
556         if (!shsurf)
557                 return -1;
558
559         move = malloc(sizeof *move);
560         if (!move)
561                 return -1;
562
563         shell_grab_init(&move->base, &move_grab_interface, shsurf);
564
565         move->dx = wl_fixed_from_double(shsurf->surface->geometry.x) -
566                         ws->seat.pointer->grab_x;
567         move->dy = wl_fixed_from_double(shsurf->surface->geometry.y) -
568                         ws->seat.pointer->grab_y;
569
570         wl_pointer_start_grab(ws->seat.pointer, &move->base.grab);
571
572         wl_pointer_set_focus(ws->seat.pointer, NULL,
573                              wl_fixed_from_int(0),
574                              wl_fixed_from_int(0));
575
576         return 0;
577 }
578
579 static void
580 shell_surface_move(struct wl_client *client, struct wl_resource *resource,
581                    struct wl_resource *seat_resource, uint32_t serial)
582 {
583         struct weston_seat *ws = seat_resource->data;
584         struct shell_surface *shsurf = resource->data;
585
586         if (ws->seat.pointer->button_count == 0 ||
587             ws->seat.pointer->grab_serial != serial ||
588             ws->seat.pointer->focus != &shsurf->surface->surface)
589                 return;
590
591         if (surface_move(shsurf, ws) < 0)
592                 wl_resource_post_no_memory(resource);
593 }
594
595 struct weston_resize_grab {
596         struct shell_grab base;
597         uint32_t edges;
598         int32_t width, height;
599 };
600
601 static void
602 resize_grab_motion(struct wl_pointer_grab *grab,
603                    uint32_t time, wl_fixed_t x, wl_fixed_t y)
604 {
605         struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
606         struct wl_pointer *pointer = grab->pointer;
607         struct shell_surface *shsurf = resize->base.shsurf;
608         int32_t width, height;
609         wl_fixed_t from_x, from_y;
610         wl_fixed_t to_x, to_y;
611
612         if (!shsurf)
613                 return;
614
615         weston_surface_from_global_fixed(shsurf->surface,
616                                          pointer->grab_x, pointer->grab_y,
617                                          &from_x, &from_y);
618         weston_surface_from_global_fixed(shsurf->surface,
619                                          pointer->x, pointer->y, &to_x, &to_y);
620
621         width = resize->width;
622         if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
623                 width += wl_fixed_to_int(from_x - to_x);
624         } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) {
625                 width += wl_fixed_to_int(to_x - from_x);
626         }
627
628         height = resize->height;
629         if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) {
630                 height += wl_fixed_to_int(from_y - to_y);
631         } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) {
632                 height += wl_fixed_to_int(to_y - from_y);
633         }
634
635         shsurf->client->send_configure(shsurf->surface,
636                                        resize->edges, width, height);
637 }
638
639 static void
640 send_configure(struct weston_surface *surface,
641                uint32_t edges, int32_t width, int32_t height)
642 {
643         struct shell_surface *shsurf = get_shell_surface(surface);
644
645         wl_shell_surface_send_configure(&shsurf->resource,
646                                         edges, width, height);
647 }
648
649 static const struct weston_shell_client shell_client = {
650         send_configure
651 };
652
653 static void
654 resize_grab_button(struct wl_pointer_grab *grab,
655                    uint32_t time, uint32_t button, uint32_t state_w)
656 {
657         struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
658         struct wl_pointer *pointer = grab->pointer;
659         enum wl_pointer_button_state state = state_w;
660
661         if (pointer->button_count == 0 &&
662             state == WL_POINTER_BUTTON_STATE_RELEASED) {
663                 shell_grab_finish(&resize->base);
664                 wl_pointer_end_grab(pointer);
665                 free(grab);
666         }
667 }
668
669 static const struct wl_pointer_grab_interface resize_grab_interface = {
670         noop_grab_focus,
671         resize_grab_motion,
672         resize_grab_button,
673 };
674
675 static int
676 surface_resize(struct shell_surface *shsurf,
677                struct weston_seat *ws, uint32_t edges)
678 {
679         struct weston_resize_grab *resize;
680
681         if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
682                 return 0;
683
684         if (edges == 0 || edges > 15 ||
685             (edges & 3) == 3 || (edges & 12) == 12)
686                 return 0;
687
688         resize = malloc(sizeof *resize);
689         if (!resize)
690                 return -1;
691
692         shell_grab_init(&resize->base, &resize_grab_interface, shsurf);
693
694         resize->edges = edges;
695         resize->width = shsurf->surface->geometry.width;
696         resize->height = shsurf->surface->geometry.height;
697
698         wl_pointer_start_grab(ws->seat.pointer, &resize->base.grab);
699
700         wl_pointer_set_focus(ws->seat.pointer, NULL,
701                              wl_fixed_from_int(0),
702                              wl_fixed_from_int(0));
703
704         return 0;
705 }
706
707 static void
708 shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
709                      struct wl_resource *seat_resource, uint32_t serial,
710                      uint32_t edges)
711 {
712         struct weston_seat *ws = seat_resource->data;
713         struct shell_surface *shsurf = resource->data;
714
715         if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
716                 return;
717
718         if (ws->seat.pointer->button_count == 0 ||
719             ws->seat.pointer->grab_serial != serial ||
720             ws->seat.pointer->focus != &shsurf->surface->surface)
721                 return;
722
723         if (surface_resize(shsurf, ws, edges) < 0)
724                 wl_resource_post_no_memory(resource);
725 }
726
727 static struct weston_output *
728 get_default_output(struct weston_compositor *compositor)
729 {
730         return container_of(compositor->output_list.next,
731                             struct weston_output, link);
732 }
733
734 static void
735 shell_unset_fullscreen(struct shell_surface *shsurf)
736 {
737         /* undo all fullscreen things here */
738         if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER &&
739             shell_surface_is_top_fullscreen(shsurf)) {
740                 weston_output_switch_mode(shsurf->fullscreen_output,
741                                           shsurf->fullscreen_output->origin);
742         }
743         shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
744         shsurf->fullscreen.framerate = 0;
745         wl_list_remove(&shsurf->fullscreen.transform.link);
746         wl_list_init(&shsurf->fullscreen.transform.link);
747         if (shsurf->fullscreen.black_surface)
748                 weston_surface_destroy(shsurf->fullscreen.black_surface);
749         shsurf->fullscreen.black_surface = NULL;
750         shsurf->fullscreen_output = NULL;
751         weston_surface_set_position(shsurf->surface,
752                                     shsurf->saved_x, shsurf->saved_y);
753         if (shsurf->saved_rotation_valid) {
754                 wl_list_insert(&shsurf->surface->geometry.transformation_list,
755                                &shsurf->rotation.transform.link);
756                 shsurf->saved_rotation_valid = false;
757         }
758 }
759
760 static int
761 reset_shell_surface_type(struct shell_surface *surface)
762 {
763         switch (surface->type) {
764         case SHELL_SURFACE_FULLSCREEN:
765                 shell_unset_fullscreen(surface);
766                 break;
767         case SHELL_SURFACE_MAXIMIZED:
768                 surface->output = get_default_output(surface->surface->compositor);
769                 weston_surface_set_position(surface->surface,
770                                             surface->saved_x,
771                                             surface->saved_y);
772                 break;
773         case SHELL_SURFACE_PANEL:
774         case SHELL_SURFACE_BACKGROUND:
775                 wl_list_remove(&surface->link);
776                 wl_list_init(&surface->link);
777                 break;
778         case SHELL_SURFACE_SCREENSAVER:
779         case SHELL_SURFACE_LOCK:
780                 wl_resource_post_error(&surface->resource,
781                                        WL_DISPLAY_ERROR_INVALID_METHOD,
782                                        "cannot reassign surface type");
783                 return -1;
784         case SHELL_SURFACE_NONE:
785         case SHELL_SURFACE_TOPLEVEL:
786         case SHELL_SURFACE_TRANSIENT:
787         case SHELL_SURFACE_POPUP:
788                 break;
789         }
790
791         surface->type = SHELL_SURFACE_NONE;
792         return 0;
793 }
794
795 static void
796 set_surface_type(struct shell_surface *shsurf)
797 {
798         struct weston_surface *surface = shsurf->surface;
799         struct shell_surface *pshsurf = shsurf->parent;
800         struct weston_surface *pes;
801         struct shell_surface *priv;
802         struct desktop_shell *shell = shsurf->shell;
803
804         reset_shell_surface_type(shsurf);
805
806         shsurf->type = shsurf->next_type;
807         shsurf->next_type = SHELL_SURFACE_NONE;
808
809         switch (shsurf->type) {
810         case SHELL_SURFACE_TOPLEVEL:
811                 break;
812         case SHELL_SURFACE_TRANSIENT:
813                 pes = pshsurf->surface;
814                 weston_surface_set_position(surface,
815                                 pes->geometry.x + shsurf->transient.x,
816                                 pes->geometry.y + shsurf->transient.y);
817                 break;
818
819         case SHELL_SURFACE_MAXIMIZED:
820                 shsurf->saved_x = surface->geometry.x;
821                 shsurf->saved_y = surface->geometry.y;
822                 shsurf->saved_position_valid = true;
823                 break;
824
825         case SHELL_SURFACE_FULLSCREEN:
826                 shsurf->saved_x = surface->geometry.x;
827                 shsurf->saved_y = surface->geometry.y;
828                 shsurf->saved_position_valid = true;
829
830                 if (!wl_list_empty(&shsurf->rotation.transform.link)) {
831                         wl_list_remove(&shsurf->rotation.transform.link);
832                         wl_list_init(&shsurf->rotation.transform.link);
833                         shsurf->surface->geometry.dirty = 1;
834                         shsurf->saved_rotation_valid = true;
835                 }
836                 break;
837
838         case SHELL_SURFACE_BACKGROUND:
839                 wl_list_for_each(priv, &shell->backgrounds, link) {
840                         if (priv->output == shsurf->output) {
841                                 priv->surface->output = NULL;
842                                 wl_list_remove(&priv->surface->layer_link);
843                                 wl_list_remove(&priv->link);
844                                 break;
845                         }
846                 }
847
848                 wl_list_insert(&shell->backgrounds, &shsurf->link);
849
850                 weston_surface_set_position(surface, shsurf->output->x,
851                                             shsurf->output->y);
852                 break;
853
854         case SHELL_SURFACE_PANEL:
855                 wl_list_for_each(priv, &shell->panels, link) {
856                         if (priv->output == shsurf->output) {
857                                 priv->surface->output = NULL;
858                                 wl_list_remove(&priv->surface->layer_link);
859                                 wl_list_remove(&priv->link);
860                                 break;
861                         }
862                 }
863
864                 wl_list_insert(&shell->panels, &shsurf->link);
865
866                 weston_surface_set_position(surface, shsurf->output->x,
867                                             shsurf->output->y);
868                 break;
869
870         default:
871                 break;
872         }
873 }
874
875 static void
876 set_toplevel(struct shell_surface *shsurf)
877 {
878        shsurf->next_type = SHELL_SURFACE_TOPLEVEL;
879 }
880
881 static void
882 shell_surface_set_toplevel(struct wl_client *client,
883                            struct wl_resource *resource)
884 {
885         struct shell_surface *surface = resource->data;
886
887         set_toplevel(surface);
888 }
889
890 static void
891 set_transient(struct shell_surface *shsurf,
892               struct shell_surface *pshsurf, int x, int y, uint32_t flags)
893 {
894         /* assign to parents output */
895         shsurf->parent = pshsurf;
896         shsurf->transient.x = x;
897         shsurf->transient.y = y;
898         shsurf->transient.flags = flags;
899         shsurf->next_type = SHELL_SURFACE_TRANSIENT;
900 }
901
902 static void
903 shell_surface_set_transient(struct wl_client *client,
904                             struct wl_resource *resource,
905                             struct wl_resource *parent_resource,
906                             int x, int y, uint32_t flags)
907 {
908         struct shell_surface *shsurf = resource->data;
909         struct shell_surface *pshsurf = parent_resource->data;
910
911         set_transient(shsurf, pshsurf, x, y, flags);
912 }
913
914 static struct desktop_shell *
915 shell_surface_get_shell(struct shell_surface *shsurf)
916 {
917         return shsurf->shell;
918 }
919
920 static int
921 get_output_panel_height(struct desktop_shell *shell,
922                         struct weston_output *output)
923 {
924         struct shell_surface *priv;
925         int panel_height = 0;
926
927         if (!output)
928                 return 0;
929
930         wl_list_for_each(priv, &shell->panels, link) {
931                 if (priv->output == output) {
932                         panel_height = priv->surface->geometry.height;
933                         break;
934                 }
935         }
936         return panel_height;
937 }
938
939 static void
940 shell_surface_set_maximized(struct wl_client *client,
941                             struct wl_resource *resource,
942                             struct wl_resource *output_resource )
943 {
944         struct shell_surface *shsurf = resource->data;
945         struct weston_surface *es = shsurf->surface;
946         struct desktop_shell *shell = NULL;
947         uint32_t edges = 0, panel_height = 0;
948
949         /* get the default output, if the client set it as NULL
950            check whether the ouput is available */
951         if (output_resource)
952                 shsurf->output = output_resource->data;
953         else
954                 shsurf->output = get_default_output(es->compositor);
955
956         shell = shell_surface_get_shell(shsurf);
957         panel_height = get_output_panel_height(shell, es->output);
958         edges = WL_SHELL_SURFACE_RESIZE_TOP|WL_SHELL_SURFACE_RESIZE_LEFT;
959
960         shsurf->client->send_configure(shsurf->surface, edges,
961                                        es->output->current->width,
962                                        es->output->current->height - panel_height);
963
964         shsurf->next_type = SHELL_SURFACE_MAXIMIZED;
965 }
966
967 static void
968 black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy);
969
970 static struct weston_surface *
971 create_black_surface(struct weston_compositor *ec,
972                      struct weston_surface *fs_surface,
973                      GLfloat x, GLfloat y, int w, int h)
974 {
975         struct weston_surface *surface = NULL;
976
977         surface = weston_surface_create(ec);
978         if (surface == NULL) {
979                 weston_log("no memory\n");
980                 return NULL;
981         }
982
983         surface->configure = black_surface_configure;
984         surface->private = fs_surface;
985         weston_surface_configure(surface, x, y, w, h);
986         weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1);
987         return surface;
988 }
989
990 /* Create black surface and append it to the associated fullscreen surface.
991  * Handle size dismatch and positioning according to the method. */
992 static void
993 shell_configure_fullscreen(struct shell_surface *shsurf)
994 {
995         struct weston_output *output = shsurf->fullscreen_output;
996         struct weston_surface *surface = shsurf->surface;
997         struct weston_matrix *matrix;
998         float scale;
999
1000         center_on_output(surface, output);
1001
1002         if (!shsurf->fullscreen.black_surface)
1003                 shsurf->fullscreen.black_surface =
1004                         create_black_surface(surface->compositor,
1005                                              surface,
1006                                              output->x, output->y,
1007                                              output->current->width,
1008                                              output->current->height);
1009
1010         wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
1011         wl_list_insert(&surface->layer_link,
1012                        &shsurf->fullscreen.black_surface->layer_link);
1013         shsurf->fullscreen.black_surface->output = output;
1014
1015         switch (shsurf->fullscreen.type) {
1016         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT:
1017                 break;
1018         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE:
1019                 matrix = &shsurf->fullscreen.transform.matrix;
1020                 weston_matrix_init(matrix);
1021                 scale = (float)output->current->width/(float)surface->geometry.width;
1022                 weston_matrix_scale(matrix, scale, scale, 1);
1023                 wl_list_remove(&shsurf->fullscreen.transform.link);
1024                 wl_list_insert(surface->geometry.transformation_list.prev,
1025                                &shsurf->fullscreen.transform.link);
1026                 weston_surface_set_position(surface, output->x, output->y);
1027                 break;
1028         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER:
1029                 if (shell_surface_is_top_fullscreen(shsurf)) {
1030                         struct weston_mode mode = {0, 
1031                                 surface->geometry.width,
1032                                 surface->geometry.height,
1033                                 shsurf->fullscreen.framerate};
1034
1035                         if (weston_output_switch_mode(output, &mode) == 0) {
1036                                 weston_surface_configure(shsurf->fullscreen.black_surface, 
1037                                                          output->x, output->y,
1038                                                          output->current->width,
1039                                                          output->current->height);
1040                                 weston_surface_set_position(surface, output->x, output->y);
1041                                 break;
1042                         }
1043                 }
1044                 break;
1045         case WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL:
1046                 break;
1047         default:
1048                 break;
1049         }
1050 }
1051
1052 /* make the fullscreen and black surface at the top */
1053 static void
1054 shell_stack_fullscreen(struct shell_surface *shsurf)
1055 {
1056         struct weston_output *output = shsurf->fullscreen_output;
1057         struct weston_surface *surface = shsurf->surface;
1058         struct desktop_shell *shell = shell_surface_get_shell(shsurf);
1059
1060         wl_list_remove(&surface->layer_link);
1061         wl_list_insert(&shell->fullscreen_layer.surface_list,
1062                        &surface->layer_link);
1063         weston_surface_damage(surface);
1064
1065         if (!shsurf->fullscreen.black_surface)
1066                 shsurf->fullscreen.black_surface =
1067                         create_black_surface(surface->compositor,
1068                                              surface,
1069                                              output->x, output->y,
1070                                              output->current->width,
1071                                              output->current->height);
1072
1073         wl_list_remove(&shsurf->fullscreen.black_surface->layer_link);
1074         wl_list_insert(&surface->layer_link,
1075                        &shsurf->fullscreen.black_surface->layer_link);
1076         weston_surface_damage(shsurf->fullscreen.black_surface);
1077 }
1078
1079 static void
1080 shell_map_fullscreen(struct shell_surface *shsurf)
1081 {
1082         shell_stack_fullscreen(shsurf);
1083         shell_configure_fullscreen(shsurf);
1084 }
1085
1086 static void
1087 shell_surface_set_fullscreen(struct wl_client *client,
1088                              struct wl_resource *resource,
1089                              uint32_t method,
1090                              uint32_t framerate,
1091                              struct wl_resource *output_resource)
1092 {
1093         struct shell_surface *shsurf = resource->data;
1094         struct weston_surface *es = shsurf->surface;
1095
1096         if (output_resource)
1097                 shsurf->output = output_resource->data;
1098         else
1099                 shsurf->output = get_default_output(es->compositor);
1100
1101         shsurf->fullscreen_output = shsurf->output;
1102         shsurf->fullscreen.type = method;
1103         shsurf->fullscreen.framerate = framerate;
1104         shsurf->next_type = SHELL_SURFACE_FULLSCREEN;
1105
1106         shsurf->client->send_configure(shsurf->surface, 0,
1107                                        shsurf->output->current->width,
1108                                        shsurf->output->current->height);
1109 }
1110
1111 static void
1112 popup_grab_focus(struct wl_pointer_grab *grab,
1113                  struct wl_surface *surface,
1114                  wl_fixed_t x,
1115                  wl_fixed_t y)
1116 {
1117         struct wl_pointer *pointer = grab->pointer;
1118         struct shell_surface *priv =
1119                 container_of(grab, struct shell_surface, popup.grab);
1120         struct wl_client *client = priv->surface->surface.resource.client;
1121
1122         if (surface && surface->resource.client == client) {
1123                 wl_pointer_set_focus(pointer, surface, x, y);
1124                 grab->focus = surface;
1125         } else {
1126                 wl_pointer_set_focus(pointer, NULL,
1127                                      wl_fixed_from_int(0),
1128                                      wl_fixed_from_int(0));
1129                 grab->focus = NULL;
1130         }
1131 }
1132
1133 static void
1134 popup_grab_motion(struct wl_pointer_grab *grab,
1135                   uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
1136 {
1137         struct wl_resource *resource;
1138
1139         resource = grab->pointer->focus_resource;
1140         if (resource)
1141                 wl_pointer_send_motion(resource, time, sx, sy);
1142 }
1143
1144 static void
1145 popup_grab_button(struct wl_pointer_grab *grab,
1146                   uint32_t time, uint32_t button, uint32_t state_w)
1147 {
1148         struct wl_resource *resource;
1149         struct shell_surface *shsurf =
1150                 container_of(grab, struct shell_surface, popup.grab);
1151         struct wl_display *display;
1152         enum wl_pointer_button_state state = state_w;
1153         uint32_t serial;
1154
1155         resource = grab->pointer->focus_resource;
1156         if (resource) {
1157                 display = wl_client_get_display(resource->client);
1158                 serial = wl_display_get_serial(display);
1159                 wl_pointer_send_button(resource, serial, time, button, state);
1160         } else if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
1161                    (shsurf->popup.initial_up ||
1162                     time - shsurf->popup.seat->pointer->grab_time > 500)) {
1163                 wl_shell_surface_send_popup_done(&shsurf->resource);
1164                 wl_pointer_end_grab(grab->pointer);
1165                 shsurf->popup.grab.pointer = NULL;
1166         }
1167
1168         if (state == WL_POINTER_BUTTON_STATE_RELEASED)
1169                 shsurf->popup.initial_up = 1;
1170 }
1171
1172 static const struct wl_pointer_grab_interface popup_grab_interface = {
1173         popup_grab_focus,
1174         popup_grab_motion,
1175         popup_grab_button,
1176 };
1177
1178 static void
1179 shell_map_popup(struct shell_surface *shsurf)
1180 {
1181         struct wl_seat *seat = shsurf->popup.seat;
1182         struct weston_surface *es = shsurf->surface;
1183         struct weston_surface *parent = shsurf->parent->surface;
1184
1185         es->output = parent->output;
1186         shsurf->popup.grab.interface = &popup_grab_interface;
1187
1188         weston_surface_update_transform(parent);
1189         if (parent->transform.enabled) {
1190                 shsurf->popup.parent_transform.matrix =
1191                         parent->transform.matrix;
1192         } else {
1193                 /* construct x, y translation matrix */
1194                 weston_matrix_init(&shsurf->popup.parent_transform.matrix);
1195                 shsurf->popup.parent_transform.matrix.d[12] =
1196                         parent->geometry.x;
1197                 shsurf->popup.parent_transform.matrix.d[13] =
1198                         parent->geometry.y;
1199         }
1200         wl_list_insert(es->geometry.transformation_list.prev,
1201                        &shsurf->popup.parent_transform.link);
1202         weston_surface_set_position(es, shsurf->popup.x, shsurf->popup.y);
1203
1204         shsurf->popup.initial_up = 0;
1205
1206         /* We don't require the grab to still be active, but if another
1207          * grab has started in the meantime, we end the popup now. */
1208         if (seat->pointer->grab_serial == shsurf->popup.serial) {
1209                 wl_pointer_start_grab(seat->pointer, &shsurf->popup.grab);
1210         } else {
1211                 wl_shell_surface_send_popup_done(&shsurf->resource);
1212         }
1213 }
1214
1215 static void
1216 shell_surface_set_popup(struct wl_client *client,
1217                         struct wl_resource *resource,
1218                         struct wl_resource *seat_resource,
1219                         uint32_t serial,
1220                         struct wl_resource *parent_resource,
1221                         int32_t x, int32_t y, uint32_t flags)
1222 {
1223         struct shell_surface *shsurf = resource->data;
1224
1225         shsurf->type = SHELL_SURFACE_POPUP;
1226         shsurf->parent = parent_resource->data;
1227         shsurf->popup.seat = seat_resource->data;
1228         shsurf->popup.serial = serial;
1229         shsurf->popup.x = x;
1230         shsurf->popup.y = y;
1231 }
1232
1233 static const struct wl_shell_surface_interface shell_surface_implementation = {
1234         shell_surface_pong,
1235         shell_surface_move,
1236         shell_surface_resize,
1237         shell_surface_set_toplevel,
1238         shell_surface_set_transient,
1239         shell_surface_set_fullscreen,
1240         shell_surface_set_popup,
1241         shell_surface_set_maximized,
1242         shell_surface_set_title,
1243         shell_surface_set_class
1244 };
1245
1246 static void
1247 destroy_shell_surface(struct shell_surface *shsurf)
1248 {
1249         if (shsurf->popup.grab.pointer)
1250                 wl_pointer_end_grab(shsurf->popup.grab.pointer);
1251
1252         if (shsurf->fullscreen.type == WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER &&
1253             shell_surface_is_top_fullscreen(shsurf)) {
1254                 weston_output_switch_mode(shsurf->fullscreen_output,
1255                                           shsurf->fullscreen_output->origin);
1256         }
1257
1258         if (shsurf->fullscreen.black_surface)
1259                 weston_surface_destroy(shsurf->fullscreen.black_surface);
1260
1261         /* As destroy_resource() use wl_list_for_each_safe(),
1262          * we can always remove the listener.
1263          */
1264         wl_list_remove(&shsurf->surface_destroy_listener.link);
1265         shsurf->surface->configure = NULL;
1266         ping_timer_destroy(shsurf);
1267
1268         wl_list_remove(&shsurf->link);
1269         free(shsurf);
1270 }
1271
1272 static void
1273 shell_destroy_shell_surface(struct wl_resource *resource)
1274 {
1275         struct shell_surface *shsurf = resource->data;
1276
1277         destroy_shell_surface(shsurf);
1278 }
1279
1280 static void
1281 shell_handle_surface_destroy(struct wl_listener *listener, void *data)
1282 {
1283         struct shell_surface *shsurf = container_of(listener,
1284                                                     struct shell_surface,
1285                                                     surface_destroy_listener);
1286
1287         if (shsurf->resource.client) {
1288                 wl_resource_destroy(&shsurf->resource);
1289         } else {
1290                 wl_signal_emit(&shsurf->resource.destroy_signal,
1291                                &shsurf->resource);
1292                 destroy_shell_surface(shsurf);
1293         }
1294 }
1295
1296 static struct shell_surface *
1297 get_shell_surface(struct weston_surface *surface)
1298 {
1299         struct wl_listener *listener;
1300
1301         listener = wl_signal_get(&surface->surface.resource.destroy_signal,
1302                                  shell_handle_surface_destroy);
1303         if (listener)
1304                 return container_of(listener, struct shell_surface,
1305                                     surface_destroy_listener);
1306
1307         return NULL;
1308 }
1309
1310 static void
1311 shell_surface_configure(struct weston_surface *, int32_t, int32_t);
1312
1313 static  struct shell_surface *
1314 create_shell_surface(void *shell, struct weston_surface *surface,
1315                      const struct weston_shell_client *client)
1316 {
1317         struct shell_surface *shsurf;
1318
1319         if (surface->configure) {
1320                 weston_log("surface->configure already set\n");
1321                 return NULL;
1322         }
1323
1324         shsurf = calloc(1, sizeof *shsurf);
1325         if (!shsurf) {
1326                 weston_log("no memory to allocate shell surface\n");
1327                 return NULL;
1328         }
1329
1330         surface->configure = shell_surface_configure;
1331         surface->compositor->shell_interface.shell = shell;
1332
1333         shsurf->shell = (struct desktop_shell *) shell;
1334         shsurf->unresponsive = 0;
1335         shsurf->saved_position_valid = false;
1336         shsurf->saved_rotation_valid = false;
1337         shsurf->surface = surface;
1338         shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
1339         shsurf->fullscreen.framerate = 0;
1340         shsurf->fullscreen.black_surface = NULL;
1341         shsurf->ping_timer = NULL;
1342         wl_list_init(&shsurf->fullscreen.transform.link);
1343
1344         wl_signal_init(&shsurf->resource.destroy_signal);
1345         shsurf->surface_destroy_listener.notify = shell_handle_surface_destroy;
1346         wl_signal_add(&surface->surface.resource.destroy_signal,
1347                       &shsurf->surface_destroy_listener);
1348
1349         /* init link so its safe to always remove it in destroy_shell_surface */
1350         wl_list_init(&shsurf->link);
1351
1352         /* empty when not in use */
1353         wl_list_init(&shsurf->rotation.transform.link);
1354         weston_matrix_init(&shsurf->rotation.rotation);
1355
1356         shsurf->type = SHELL_SURFACE_NONE;
1357         shsurf->next_type = SHELL_SURFACE_NONE;
1358
1359         shsurf->client = client;
1360
1361         return shsurf;
1362 }
1363
1364 static void
1365 shell_get_shell_surface(struct wl_client *client,
1366                         struct wl_resource *resource,
1367                         uint32_t id,
1368                         struct wl_resource *surface_resource)
1369 {
1370         struct weston_surface *surface = surface_resource->data;
1371         struct desktop_shell *shell = resource->data;
1372         struct shell_surface *shsurf;
1373
1374         if (get_shell_surface(surface)) {
1375                 wl_resource_post_error(surface_resource,
1376                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
1377                                        "desktop_shell::get_shell_surface already requested");
1378                 return;
1379         }
1380
1381         shsurf = create_shell_surface(shell, surface, &shell_client);
1382         if (!shsurf) {
1383                 wl_resource_post_error(surface_resource,
1384                                        WL_DISPLAY_ERROR_INVALID_OBJECT,
1385                                        "surface->configure already set");
1386                 return;
1387         }
1388
1389         shsurf->resource.destroy = shell_destroy_shell_surface;
1390         shsurf->resource.object.id = id;
1391         shsurf->resource.object.interface = &wl_shell_surface_interface;
1392         shsurf->resource.object.implementation =
1393                 (void (**)(void)) &shell_surface_implementation;
1394         shsurf->resource.data = shsurf;
1395
1396         wl_client_add_resource(client, &shsurf->resource);
1397 }
1398
1399 static const struct wl_shell_interface shell_implementation = {
1400         shell_get_shell_surface
1401 };
1402
1403 static void
1404 handle_screensaver_sigchld(struct weston_process *proc, int status)
1405 {
1406         proc->pid = 0;
1407 }
1408
1409 static void
1410 launch_screensaver(struct desktop_shell *shell)
1411 {
1412         if (shell->screensaver.binding)
1413                 return;
1414
1415         if (!shell->screensaver.path)
1416                 return;
1417
1418         if (shell->screensaver.process.pid != 0) {
1419                 weston_log("old screensaver still running\n");
1420                 return;
1421         }
1422
1423         weston_client_launch(shell->compositor,
1424                            &shell->screensaver.process,
1425                            shell->screensaver.path,
1426                            handle_screensaver_sigchld);
1427 }
1428
1429 static void
1430 terminate_screensaver(struct desktop_shell *shell)
1431 {
1432         if (shell->screensaver.process.pid == 0)
1433                 return;
1434
1435         kill(shell->screensaver.process.pid, SIGTERM);
1436 }
1437
1438 static void
1439 show_screensaver(struct desktop_shell *shell, struct shell_surface *surface)
1440 {
1441         struct wl_list *list;
1442
1443         if (shell->lock_surface)
1444                 list = &shell->lock_surface->surface->layer_link;
1445         else
1446                 list = &shell->lock_layer.surface_list;
1447
1448         wl_list_remove(&surface->surface->layer_link);
1449         wl_list_insert(list, &surface->surface->layer_link);
1450         surface->surface->output = surface->output;
1451         weston_surface_damage(surface->surface);
1452 }
1453
1454 static void
1455 hide_screensaver(struct desktop_shell *shell, struct shell_surface *surface)
1456 {
1457         wl_list_remove(&surface->surface->layer_link);
1458         wl_list_init(&surface->surface->layer_link);
1459         surface->surface->output = NULL;
1460 }
1461
1462 static void
1463 desktop_shell_set_background(struct wl_client *client,
1464                              struct wl_resource *resource,
1465                              struct wl_resource *output_resource,
1466                              struct wl_resource *surface_resource)
1467 {
1468         struct shell_surface *shsurf = surface_resource->data;
1469
1470         shsurf->next_type = SHELL_SURFACE_BACKGROUND;
1471         shsurf->output = output_resource->data;
1472
1473         desktop_shell_send_configure(resource, 0,
1474                                      surface_resource,
1475                                      shsurf->output->current->width,
1476                                      shsurf->output->current->height);
1477 }
1478
1479 static void
1480 desktop_shell_set_panel(struct wl_client *client,
1481                         struct wl_resource *resource,
1482                         struct wl_resource *output_resource,
1483                         struct wl_resource *surface_resource)
1484 {
1485         struct shell_surface *shsurf = surface_resource->data;
1486
1487         shsurf->next_type = SHELL_SURFACE_PANEL;
1488         shsurf->output = output_resource->data;
1489
1490         desktop_shell_send_configure(resource, 0,
1491                                      surface_resource,
1492                                      shsurf->output->current->width,
1493                                      shsurf->output->current->height);
1494 }
1495
1496 static void
1497 handle_lock_surface_destroy(struct wl_listener *listener, void *data)
1498 {
1499         struct desktop_shell *shell =
1500             container_of(listener, struct desktop_shell, lock_surface_listener);
1501
1502         weston_log("lock surface gone\n");
1503         shell->lock_surface = NULL;
1504 }
1505
1506 static void
1507 desktop_shell_set_lock_surface(struct wl_client *client,
1508                                struct wl_resource *resource,
1509                                struct wl_resource *surface_resource)
1510 {
1511         struct desktop_shell *shell = resource->data;
1512         struct shell_surface *surface = surface_resource->data;
1513
1514         shell->prepare_event_sent = false;
1515
1516         if (!shell->locked)
1517                 return;
1518
1519         shell->lock_surface = surface;
1520
1521         shell->lock_surface_listener.notify = handle_lock_surface_destroy;
1522         wl_signal_add(&surface_resource->destroy_signal,
1523                       &shell->lock_surface_listener);
1524
1525         shell->lock_surface->next_type = SHELL_SURFACE_LOCK;
1526 }
1527
1528 static void
1529 resume_desktop(struct desktop_shell *shell)
1530 {
1531         struct shell_surface *tmp;
1532
1533         wl_list_for_each(tmp, &shell->screensaver.surfaces, link)
1534                 hide_screensaver(shell, tmp);
1535
1536         terminate_screensaver(shell);
1537
1538         wl_list_remove(&shell->lock_layer.link);
1539         wl_list_insert(&shell->compositor->cursor_layer.link,
1540                        &shell->fullscreen_layer.link);
1541         wl_list_insert(&shell->fullscreen_layer.link,
1542                        &shell->panel_layer.link);
1543         wl_list_insert(&shell->panel_layer.link, &shell->toplevel_layer.link);
1544
1545         shell->locked = false;
1546         shell->compositor->idle_time = shell->compositor->option_idle_time;
1547         weston_compositor_wake(shell->compositor);
1548         weston_compositor_damage_all(shell->compositor);
1549 }
1550
1551 static void
1552 desktop_shell_unlock(struct wl_client *client,
1553                      struct wl_resource *resource)
1554 {
1555         struct desktop_shell *shell = resource->data;
1556
1557         shell->prepare_event_sent = false;
1558
1559         if (shell->locked)
1560                 resume_desktop(shell);
1561 }
1562
1563 static void
1564 desktop_shell_set_busy_surface(struct wl_client *client,
1565                                struct wl_resource *resource,
1566                                struct wl_resource *surface_resource)
1567 {
1568         struct desktop_shell *shell = resource->data;
1569
1570         shell->busy_surface = surface_resource->data;
1571 }
1572
1573 static const struct desktop_shell_interface desktop_shell_implementation = {
1574         desktop_shell_set_background,
1575         desktop_shell_set_panel,
1576         desktop_shell_set_lock_surface,
1577         desktop_shell_unlock,
1578         desktop_shell_set_busy_surface
1579 };
1580
1581 static enum shell_surface_type
1582 get_shell_surface_type(struct weston_surface *surface)
1583 {
1584         struct shell_surface *shsurf;
1585
1586         shsurf = get_shell_surface(surface);
1587         if (!shsurf)
1588                 return SHELL_SURFACE_NONE;
1589         return shsurf->type;
1590 }
1591
1592 static void
1593 move_binding(struct wl_seat *seat, uint32_t time, uint32_t button, void *data)
1594 {
1595         struct weston_surface *surface =
1596                 (struct weston_surface *) seat->pointer->focus;
1597         struct shell_surface *shsurf;
1598
1599         if (surface == NULL)
1600                 return;
1601
1602         shsurf = get_shell_surface(surface);
1603         if (shsurf == NULL)
1604                 return;
1605
1606         switch (shsurf->type) {
1607                 case SHELL_SURFACE_PANEL:
1608                 case SHELL_SURFACE_BACKGROUND:
1609                 case SHELL_SURFACE_FULLSCREEN:
1610                 case SHELL_SURFACE_SCREENSAVER:
1611                         return;
1612                 default:
1613                         break;
1614         }
1615
1616         surface_move(shsurf, (struct weston_seat *) seat);
1617 }
1618
1619 static void
1620 resize_binding(struct wl_seat *seat, uint32_t time, uint32_t button, void *data)
1621 {
1622         struct weston_surface *surface =
1623                 (struct weston_surface *) seat->pointer->focus;
1624         uint32_t edges = 0;
1625         int32_t x, y;
1626         struct shell_surface *shsurf;
1627
1628         if (surface == NULL)
1629                 return;
1630
1631         shsurf = get_shell_surface(surface);
1632         if (!shsurf)
1633                 return;
1634
1635         switch (shsurf->type) {
1636                 case SHELL_SURFACE_PANEL:
1637                 case SHELL_SURFACE_BACKGROUND:
1638                 case SHELL_SURFACE_FULLSCREEN:
1639                 case SHELL_SURFACE_SCREENSAVER:
1640                         return;
1641                 default:
1642                         break;
1643         }
1644
1645         weston_surface_from_global(surface,
1646                                    wl_fixed_to_int(seat->pointer->grab_x),
1647                                    wl_fixed_to_int(seat->pointer->grab_y),
1648                                    &x, &y);
1649
1650         if (x < surface->geometry.width / 3)
1651                 edges |= WL_SHELL_SURFACE_RESIZE_LEFT;
1652         else if (x < 2 * surface->geometry.width / 3)
1653                 edges |= 0;
1654         else
1655                 edges |= WL_SHELL_SURFACE_RESIZE_RIGHT;
1656
1657         if (y < surface->geometry.height / 3)
1658                 edges |= WL_SHELL_SURFACE_RESIZE_TOP;
1659         else if (y < 2 * surface->geometry.height / 3)
1660                 edges |= 0;
1661         else
1662                 edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
1663
1664         surface_resize(shsurf, (struct weston_seat *) seat, edges);
1665 }
1666
1667 static void
1668 surface_opacity_binding(struct wl_seat *seat, uint32_t time, uint32_t axis,
1669                         wl_fixed_t value, void *data)
1670 {
1671         float step = 0.05;
1672         struct shell_surface *shsurf;
1673         struct weston_surface *surface =
1674                 (struct weston_surface *) seat->pointer->focus;
1675
1676         if (surface == NULL)
1677                 return;
1678
1679         shsurf = get_shell_surface(surface);
1680         if (!shsurf)
1681                 return;
1682
1683         switch (shsurf->type) {
1684                 case SHELL_SURFACE_BACKGROUND:
1685                 case SHELL_SURFACE_SCREENSAVER:
1686                         return;
1687                 default:
1688                         break;
1689         }
1690
1691         surface->alpha += wl_fixed_to_double(value) * step;
1692
1693         if (surface->alpha > 1.0)
1694                 surface->alpha = 1.0;
1695         if (surface->alpha < step)
1696                 surface->alpha = step;
1697
1698         surface->geometry.dirty = 1;
1699         weston_surface_damage(surface);
1700 }
1701
1702 static void
1703 do_zoom(struct wl_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
1704         wl_fixed_t value)
1705 {
1706         struct weston_seat *ws = (struct weston_seat *) seat;
1707         struct weston_compositor *compositor = ws->compositor;
1708         struct weston_output *output;
1709         float maximum_level, increment;
1710
1711         wl_list_for_each(output, &compositor->output_list, link) {
1712                 if (pixman_region32_contains_point(&output->region,
1713                                                    wl_fixed_to_double(seat->pointer->x),
1714                                                    wl_fixed_to_double(seat->pointer->y),
1715                                                    NULL)) {
1716                         if (key == KEY_PAGEUP)
1717                                 increment = output->zoom.increment;
1718                         else if (key == KEY_PAGEDOWN)
1719                                 increment = -output->zoom.increment;
1720                         else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
1721                                 increment = output->zoom.increment *
1722                                             wl_fixed_to_double(value);
1723                         else
1724                                 increment = 0;
1725
1726                         output->zoom.active = 1;
1727                         output->zoom.level += increment;
1728
1729                         if (output->zoom.level <= 0.0) {
1730                                 output->zoom.active = 0;
1731                                 output->zoom.level = 0.0;
1732                         }
1733
1734                         maximum_level = 1 - output->zoom.increment;
1735
1736                         if (output->zoom.level > maximum_level)
1737                                 output->zoom.level = maximum_level;
1738
1739                         weston_output_update_zoom(output,
1740                                                   seat->pointer->x,
1741                                                   seat->pointer->y,
1742                                                   ZOOM_POINTER);
1743                 }
1744         }
1745 }
1746
1747 static void
1748 zoom_axis_binding(struct wl_seat *seat, uint32_t time, uint32_t axis,
1749                   wl_fixed_t value, void *data)
1750 {
1751         do_zoom(seat, time, 0, axis, value);
1752 }
1753
1754 static void
1755 zoom_key_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
1756                  void *data)
1757 {
1758         do_zoom(seat, time, key, 0, 0);
1759 }
1760
1761 static void
1762 terminate_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
1763                   void *data)
1764 {
1765         struct weston_compositor *compositor = data;
1766
1767         wl_display_terminate(compositor->wl_display);
1768 }
1769
1770 static void
1771 rotate_grab_motion(struct wl_pointer_grab *grab,
1772                    uint32_t time, wl_fixed_t x, wl_fixed_t y)
1773 {
1774         struct rotate_grab *rotate =
1775                 container_of(grab, struct rotate_grab, base.grab);
1776         struct wl_pointer *pointer = grab->pointer;
1777         struct shell_surface *shsurf = rotate->base.shsurf;
1778         struct weston_surface *surface;
1779         GLfloat cx, cy, dx, dy, cposx, cposy, dposx, dposy, r;
1780
1781         if (!shsurf)
1782                 return;
1783
1784         surface = shsurf->surface;
1785
1786         cx = 0.5f * surface->geometry.width;
1787         cy = 0.5f * surface->geometry.height;
1788
1789         dx = wl_fixed_to_double(pointer->x) - rotate->center.x;
1790         dy = wl_fixed_to_double(pointer->y) - rotate->center.y;
1791         r = sqrtf(dx * dx + dy * dy);
1792
1793         wl_list_remove(&shsurf->rotation.transform.link);
1794         shsurf->surface->geometry.dirty = 1;
1795
1796         if (r > 20.0f) {
1797                 struct weston_matrix *matrix =
1798                         &shsurf->rotation.transform.matrix;
1799
1800                 weston_matrix_init(&rotate->rotation);
1801                 rotate->rotation.d[0] = dx / r;
1802                 rotate->rotation.d[4] = -dy / r;
1803                 rotate->rotation.d[1] = -rotate->rotation.d[4];
1804                 rotate->rotation.d[5] = rotate->rotation.d[0];
1805
1806                 weston_matrix_init(matrix);
1807                 weston_matrix_translate(matrix, -cx, -cy, 0.0f);
1808                 weston_matrix_multiply(matrix, &shsurf->rotation.rotation);
1809                 weston_matrix_multiply(matrix, &rotate->rotation);
1810                 weston_matrix_translate(matrix, cx, cy, 0.0f);
1811
1812                 wl_list_insert(
1813                         &shsurf->surface->geometry.transformation_list,
1814                         &shsurf->rotation.transform.link);
1815         } else {
1816                 wl_list_init(&shsurf->rotation.transform.link);
1817                 weston_matrix_init(&shsurf->rotation.rotation);
1818                 weston_matrix_init(&rotate->rotation);
1819         }
1820
1821         /* We need to adjust the position of the surface
1822          * in case it was resized in a rotated state before */
1823         cposx = surface->geometry.x + cx;
1824         cposy = surface->geometry.y + cy;
1825         dposx = rotate->center.x - cposx;
1826         dposy = rotate->center.y - cposy;
1827         if (dposx != 0.0f || dposy != 0.0f) {
1828                 weston_surface_set_position(surface,
1829                                             surface->geometry.x + dposx,
1830                                             surface->geometry.y + dposy);
1831         }
1832
1833         /* Repaint implies weston_surface_update_transform(), which
1834          * lazily applies the damage due to rotation update.
1835          */
1836         weston_compositor_schedule_repaint(shsurf->surface->compositor);
1837 }
1838
1839 static void
1840 rotate_grab_button(struct wl_pointer_grab *grab,
1841                  uint32_t time, uint32_t button, uint32_t state_w)
1842 {
1843         struct rotate_grab *rotate =
1844                 container_of(grab, struct rotate_grab, base.grab);
1845         struct wl_pointer *pointer = grab->pointer;
1846         struct shell_surface *shsurf = rotate->base.shsurf;
1847         enum wl_pointer_button_state state = state_w;
1848
1849         if (pointer->button_count == 0 &&
1850             state == WL_POINTER_BUTTON_STATE_RELEASED) {
1851                 if (shsurf)
1852                         weston_matrix_multiply(&shsurf->rotation.rotation,
1853                                                &rotate->rotation);
1854                 shell_grab_finish(&rotate->base);
1855                 wl_pointer_end_grab(pointer);
1856                 free(rotate);
1857         }
1858 }
1859
1860 static const struct wl_pointer_grab_interface rotate_grab_interface = {
1861         noop_grab_focus,
1862         rotate_grab_motion,
1863         rotate_grab_button,
1864 };
1865
1866 static void
1867 rotate_binding(struct wl_seat *seat, uint32_t time, uint32_t button,
1868                void *data)
1869 {
1870         struct weston_surface *base_surface =
1871                 (struct weston_surface *) seat->pointer->focus;
1872         struct shell_surface *surface;
1873         struct rotate_grab *rotate;
1874         GLfloat dx, dy;
1875         GLfloat r;
1876
1877         if (base_surface == NULL)
1878                 return;
1879
1880         surface = get_shell_surface(base_surface);
1881         if (!surface)
1882                 return;
1883
1884         switch (surface->type) {
1885                 case SHELL_SURFACE_PANEL:
1886                 case SHELL_SURFACE_BACKGROUND:
1887                 case SHELL_SURFACE_FULLSCREEN:
1888                 case SHELL_SURFACE_SCREENSAVER:
1889                         return;
1890                 default:
1891                         break;
1892         }
1893
1894         rotate = malloc(sizeof *rotate);
1895         if (!rotate)
1896                 return;
1897
1898         shell_grab_init(&rotate->base, &rotate_grab_interface, surface);
1899
1900         weston_surface_to_global_float(surface->surface,
1901                                        surface->surface->geometry.width / 2,
1902                                        surface->surface->geometry.height / 2,
1903                                        &rotate->center.x, &rotate->center.y);
1904
1905         wl_pointer_start_grab(seat->pointer, &rotate->base.grab);
1906
1907         dx = wl_fixed_to_double(seat->pointer->x) - rotate->center.x;
1908         dy = wl_fixed_to_double(seat->pointer->y) - rotate->center.y;
1909         r = sqrtf(dx * dx + dy * dy);
1910         if (r > 20.0f) {
1911                 struct weston_matrix inverse;
1912
1913                 weston_matrix_init(&inverse);
1914                 inverse.d[0] = dx / r;
1915                 inverse.d[4] = dy / r;
1916                 inverse.d[1] = -inverse.d[4];
1917                 inverse.d[5] = inverse.d[0];
1918                 weston_matrix_multiply(&surface->rotation.rotation, &inverse);
1919
1920                 weston_matrix_init(&rotate->rotation);
1921                 rotate->rotation.d[0] = dx / r;
1922                 rotate->rotation.d[4] = -dy / r;
1923                 rotate->rotation.d[1] = -rotate->rotation.d[4];
1924                 rotate->rotation.d[5] = rotate->rotation.d[0];
1925         } else {
1926                 weston_matrix_init(&surface->rotation.rotation);
1927                 weston_matrix_init(&rotate->rotation);
1928         }
1929
1930         wl_pointer_set_focus(seat->pointer, NULL,
1931                              wl_fixed_from_int(0),
1932                              wl_fixed_from_int(0));
1933 }
1934
1935 static void
1936 activate(struct desktop_shell *shell, struct weston_surface *es,
1937          struct weston_seat *seat)
1938 {
1939         struct weston_surface *surf, *prev;
1940
1941         weston_surface_activate(es, seat);
1942
1943         switch (get_shell_surface_type(es)) {
1944         case SHELL_SURFACE_BACKGROUND:
1945         case SHELL_SURFACE_PANEL:
1946         case SHELL_SURFACE_LOCK:
1947                 break;
1948
1949         case SHELL_SURFACE_SCREENSAVER:
1950                 /* always below lock surface */
1951                 if (shell->lock_surface)
1952                         weston_surface_restack(es,
1953                                                &shell->lock_surface->surface->layer_link);
1954                 break;
1955         case SHELL_SURFACE_FULLSCREEN:
1956                 /* should on top of panels */
1957                 shell_stack_fullscreen(get_shell_surface(es));
1958                 shell_configure_fullscreen(get_shell_surface(es));
1959                 break;
1960         default:
1961                 /* move the fullscreen surfaces down into the toplevel layer */
1962                 if (!wl_list_empty(&shell->fullscreen_layer.surface_list)) {
1963                         wl_list_for_each_reverse_safe(surf,
1964                                                       prev, 
1965                                                       &shell->fullscreen_layer.surface_list, 
1966                                                       layer_link)
1967                                 weston_surface_restack(surf,
1968                                                        &shell->toplevel_layer.surface_list); 
1969                 }
1970
1971                 weston_surface_restack(es,
1972                                        &shell->toplevel_layer.surface_list);
1973                 break;
1974         }
1975 }
1976
1977 /* no-op func for checking black surface */
1978 static void
1979 black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
1980 {
1981 }
1982
1983 static bool 
1984 is_black_surface (struct weston_surface *es, struct weston_surface **fs_surface)
1985 {
1986         if (es->configure == black_surface_configure) {
1987                 if (fs_surface)
1988                         *fs_surface = (struct weston_surface *)es->private;
1989                 return true;
1990         }
1991         return false;
1992 }
1993
1994 static void
1995 click_to_activate_binding(struct wl_seat *seat, uint32_t time, uint32_t button,
1996                           void *data)
1997 {
1998         struct weston_seat *ws = (struct weston_seat *) seat;
1999         struct desktop_shell *shell = data;
2000         struct weston_surface *focus;
2001         struct weston_surface *upper;
2002
2003         focus = (struct weston_surface *) seat->pointer->focus;
2004         if (!focus)
2005                 return;
2006
2007         if (is_black_surface(focus, &upper))
2008                 focus = upper;
2009
2010         if (seat->pointer->grab == &seat->pointer->default_grab)
2011                 activate(shell, focus, ws);
2012 }
2013
2014 static void
2015 lock(struct wl_listener *listener, void *data)
2016 {
2017         struct desktop_shell *shell =
2018                 container_of(listener, struct desktop_shell, lock_listener);
2019         struct weston_seat *seat;
2020         struct shell_surface *shsurf;
2021         struct weston_output *output;
2022
2023         if (shell->locked) {
2024                 wl_list_for_each(output, &shell->compositor->output_list, link)
2025                         /* TODO: find a way to jump to other DPMS levels */
2026                         if (output->set_dpms)
2027                                 output->set_dpms(output, WESTON_DPMS_STANDBY);
2028                 return;
2029         }
2030
2031         shell->locked = true;
2032
2033         /* Hide all surfaces by removing the fullscreen, panel and
2034          * toplevel layers.  This way nothing else can show or receive
2035          * input events while we are locked. */
2036
2037         wl_list_remove(&shell->panel_layer.link);
2038         wl_list_remove(&shell->toplevel_layer.link);
2039         wl_list_remove(&shell->fullscreen_layer.link);
2040         wl_list_insert(&shell->compositor->cursor_layer.link,
2041                        &shell->lock_layer.link);
2042
2043         launch_screensaver(shell);
2044
2045         wl_list_for_each(shsurf, &shell->screensaver.surfaces, link)
2046                 show_screensaver(shell, shsurf);
2047
2048         if (!wl_list_empty(&shell->screensaver.surfaces)) {
2049                 shell->compositor->idle_time = shell->screensaver.duration;
2050                 weston_compositor_wake(shell->compositor);
2051                 shell->compositor->state = WESTON_COMPOSITOR_IDLE;
2052         }
2053
2054         /* reset pointer foci */
2055         weston_compositor_schedule_repaint(shell->compositor);
2056
2057         /* reset keyboard foci */
2058         wl_list_for_each(seat, &shell->compositor->seat_list, link) {
2059                 wl_keyboard_set_focus(seat->seat.keyboard, NULL);
2060         }
2061
2062         /* TODO: disable bindings that should not work while locked. */
2063
2064         /* All this must be undone in resume_desktop(). */
2065 }
2066
2067 static void
2068 unlock(struct wl_listener *listener, void *data)
2069 {
2070         struct desktop_shell *shell =
2071                 container_of(listener, struct desktop_shell, unlock_listener);
2072
2073         if (!shell->locked || shell->lock_surface) {
2074                 weston_compositor_wake(shell->compositor);
2075                 return;
2076         }
2077
2078         /* If desktop-shell client has gone away, unlock immediately. */
2079         if (!shell->child.desktop_shell) {
2080                 resume_desktop(shell);
2081                 return;
2082         }
2083
2084         if (shell->prepare_event_sent)
2085                 return;
2086
2087         desktop_shell_send_prepare_lock_surface(shell->child.desktop_shell);
2088         shell->prepare_event_sent = true;
2089 }
2090
2091 static void
2092 center_on_output(struct weston_surface *surface, struct weston_output *output)
2093 {
2094         struct weston_mode *mode = output->current;
2095         GLfloat x = (mode->width - surface->geometry.width) / 2;
2096         GLfloat y = (mode->height - surface->geometry.height) / 2;
2097
2098         weston_surface_set_position(surface, output->x + x, output->y + y);
2099 }
2100
2101 static void
2102 map(struct desktop_shell *shell, struct weston_surface *surface,
2103     int32_t width, int32_t height, int32_t sx, int32_t sy)
2104 {
2105         struct weston_compositor *compositor = shell->compositor;
2106         struct shell_surface *shsurf;
2107         enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
2108         struct weston_surface *parent;
2109         struct weston_seat *seat;
2110         int panel_height = 0;
2111
2112         shsurf = get_shell_surface(surface);
2113         if (shsurf)
2114                 surface_type = shsurf->type;
2115
2116         surface->geometry.width = width;
2117         surface->geometry.height = height;
2118         surface->geometry.dirty = 1;
2119
2120         /* initial positioning, see also configure() */
2121         switch (surface_type) {
2122         case SHELL_SURFACE_TOPLEVEL:
2123                 weston_surface_set_position(surface, 10 + random() % 400,
2124                                             10 + random() % 400);
2125                 break;
2126         case SHELL_SURFACE_SCREENSAVER:
2127                 center_on_output(surface, shsurf->fullscreen_output);
2128                 break;
2129         case SHELL_SURFACE_FULLSCREEN:
2130                 shell_map_fullscreen(shsurf);
2131                 break;
2132         case SHELL_SURFACE_MAXIMIZED:
2133                 /* use surface configure to set the geometry */
2134                 panel_height = get_output_panel_height(shell,surface->output);
2135                 weston_surface_set_position(surface, surface->output->x,
2136                                             surface->output->y + panel_height);
2137                 break;
2138         case SHELL_SURFACE_LOCK:
2139                 center_on_output(surface, get_default_output(compositor));
2140                 break;
2141         case SHELL_SURFACE_POPUP:
2142                 shell_map_popup(shsurf);
2143         case SHELL_SURFACE_NONE:
2144                 weston_surface_set_position(surface,
2145                                             surface->geometry.x + sx,
2146                                             surface->geometry.y + sy);
2147                 break;
2148         default:
2149                 ;
2150         }
2151
2152         /* surface stacking order, see also activate() */
2153         switch (surface_type) {
2154         case SHELL_SURFACE_BACKGROUND:
2155                 /* background always visible, at the bottom */
2156                 wl_list_insert(&shell->background_layer.surface_list,
2157                                &surface->layer_link);
2158                 break;
2159         case SHELL_SURFACE_PANEL:
2160                 /* panel always on top, hidden while locked */
2161                 wl_list_insert(&shell->panel_layer.surface_list,
2162                                &surface->layer_link);
2163                 break;
2164         case SHELL_SURFACE_LOCK:
2165                 /* lock surface always visible, on top */
2166                 wl_list_insert(&shell->lock_layer.surface_list,
2167                                &surface->layer_link);
2168                 weston_compositor_wake(compositor);
2169                 break;
2170         case SHELL_SURFACE_SCREENSAVER:
2171                 /* If locked, show it. */
2172                 if (shell->locked) {
2173                         show_screensaver(shell, shsurf);
2174                         compositor->idle_time = shell->screensaver.duration;
2175                         weston_compositor_wake(compositor);
2176                         if (!shell->lock_surface)
2177                                 compositor->state = WESTON_COMPOSITOR_IDLE;
2178                 }
2179                 break;
2180         case SHELL_SURFACE_POPUP:
2181         case SHELL_SURFACE_TRANSIENT:
2182                 parent = shsurf->parent->surface;
2183                 wl_list_insert(parent->layer_link.prev, &surface->layer_link);
2184                 break;
2185         case SHELL_SURFACE_FULLSCREEN:
2186         case SHELL_SURFACE_NONE:
2187                 break;
2188         default:
2189                 wl_list_insert(&shell->toplevel_layer.surface_list,
2190                                &surface->layer_link); 
2191                 break;
2192         }
2193
2194         if (surface_type != SHELL_SURFACE_NONE) {
2195                 weston_surface_assign_output(surface);
2196                 if (surface_type == SHELL_SURFACE_MAXIMIZED)
2197                         surface->output = shsurf->output;
2198         }
2199
2200         switch (surface_type) {
2201         case SHELL_SURFACE_TRANSIENT:
2202                 if (shsurf->transient.flags ==
2203                                 WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
2204                         break;
2205         case SHELL_SURFACE_TOPLEVEL:
2206         case SHELL_SURFACE_FULLSCREEN:
2207         case SHELL_SURFACE_MAXIMIZED:
2208                 if (!shell->locked) {
2209                         wl_list_for_each(seat, &compositor->seat_list, link)
2210                                 activate(shell, surface, seat);
2211                 }
2212                 break;
2213         default:
2214                 break;
2215         }
2216
2217         if (surface_type == SHELL_SURFACE_TOPLEVEL)
2218         {
2219                 switch (shell->win_animation_type) {
2220                 case ANIMATION_FADE:
2221                         weston_fade_run(surface, NULL, NULL);
2222                         break;
2223                 case ANIMATION_ZOOM:
2224                         weston_zoom_run(surface, 0.8, 1.0, NULL, NULL);
2225                         break;
2226                 default:
2227                         break;
2228                 }
2229         }
2230 }
2231
2232 static void
2233 configure(struct desktop_shell *shell, struct weston_surface *surface,
2234           GLfloat x, GLfloat y, int32_t width, int32_t height)
2235 {
2236         enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
2237         struct shell_surface *shsurf;
2238
2239         shsurf = get_shell_surface(surface);
2240         if (shsurf)
2241                 surface_type = shsurf->type;
2242
2243         surface->geometry.x = x;
2244         surface->geometry.y = y;
2245         surface->geometry.width = width;
2246         surface->geometry.height = height;
2247         surface->geometry.dirty = 1;
2248
2249         switch (surface_type) {
2250         case SHELL_SURFACE_SCREENSAVER:
2251                 center_on_output(surface, shsurf->fullscreen_output);
2252                 break;
2253         case SHELL_SURFACE_FULLSCREEN:
2254                 shell_stack_fullscreen(shsurf);
2255                 shell_configure_fullscreen(shsurf);
2256                 break;
2257         case SHELL_SURFACE_MAXIMIZED:
2258                 /* setting x, y and using configure to change that geometry */
2259                 surface->geometry.x = surface->output->x;
2260                 surface->geometry.y = surface->output->y +
2261                         get_output_panel_height(shell,surface->output);
2262                 break;
2263         case SHELL_SURFACE_TOPLEVEL:
2264                 break;
2265         default:
2266                 break;
2267         }
2268
2269         /* XXX: would a fullscreen surface need the same handling? */
2270         if (surface->output) {
2271                 weston_surface_assign_output(surface);
2272
2273                 if (surface_type == SHELL_SURFACE_SCREENSAVER)
2274                         surface->output = shsurf->output;
2275                 else if (surface_type == SHELL_SURFACE_MAXIMIZED)
2276                         surface->output = shsurf->output;
2277         }
2278 }
2279
2280 static void
2281 shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
2282 {
2283         struct shell_surface *shsurf = get_shell_surface(es);
2284         struct desktop_shell *shell = shsurf->shell;
2285         int type_changed = 0;
2286
2287         if (shsurf->next_type != SHELL_SURFACE_NONE &&
2288             shsurf->type != shsurf->next_type) {
2289                 set_surface_type(shsurf);
2290                 type_changed = 1;
2291         }
2292
2293         if (!weston_surface_is_mapped(es)) {
2294                 map(shell, es, es->buffer->width, es->buffer->height, sx, sy);
2295         } else if (type_changed || sx != 0 || sy != 0 ||
2296                    es->geometry.width != es->buffer->width ||
2297                    es->geometry.height != es->buffer->height) {
2298                 GLfloat from_x, from_y;
2299                 GLfloat to_x, to_y;
2300
2301                 weston_surface_to_global_float(es, 0, 0, &from_x, &from_y);
2302                 weston_surface_to_global_float(es, sx, sy, &to_x, &to_y);
2303                 configure(shell, es,
2304                           es->geometry.x + to_x - from_x,
2305                           es->geometry.y + to_y - from_y,
2306                           es->buffer->width, es->buffer->height);
2307         }
2308 }
2309
2310 static int launch_desktop_shell_process(struct desktop_shell *shell);
2311
2312 static void
2313 desktop_shell_sigchld(struct weston_process *process, int status)
2314 {
2315         uint32_t time;
2316         struct desktop_shell *shell =
2317                 container_of(process, struct desktop_shell, child.process);
2318
2319         shell->child.process.pid = 0;
2320         shell->child.client = NULL; /* already destroyed by wayland */
2321
2322         /* if desktop-shell dies more than 5 times in 30 seconds, give up */
2323         time = weston_compositor_get_time();
2324         if (time - shell->child.deathstamp > 30000) {
2325                 shell->child.deathstamp = time;
2326                 shell->child.deathcount = 0;
2327         }
2328
2329         shell->child.deathcount++;
2330         if (shell->child.deathcount > 5) {
2331                 weston_log("weston-desktop-shell died, giving up.\n");
2332                 return;
2333         }
2334
2335         weston_log("weston-desktop-shell died, respawning...\n");
2336         launch_desktop_shell_process(shell);
2337 }
2338
2339 static int
2340 launch_desktop_shell_process(struct desktop_shell *shell)
2341 {
2342         const char *shell_exe = LIBEXECDIR "/weston-desktop-shell";
2343
2344         shell->child.client = weston_client_launch(shell->compositor,
2345                                                  &shell->child.process,
2346                                                  shell_exe,
2347                                                  desktop_shell_sigchld);
2348
2349         if (!shell->child.client)
2350                 return -1;
2351         return 0;
2352 }
2353
2354 static void
2355 bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2356 {
2357         struct desktop_shell *shell = data;
2358
2359         wl_client_add_object(client, &wl_shell_interface,
2360                              &shell_implementation, id, shell);
2361 }
2362
2363 static void
2364 unbind_desktop_shell(struct wl_resource *resource)
2365 {
2366         struct desktop_shell *shell = resource->data;
2367
2368         if (shell->locked)
2369                 resume_desktop(shell);
2370
2371         shell->child.desktop_shell = NULL;
2372         shell->prepare_event_sent = false;
2373         free(resource);
2374 }
2375
2376 static void
2377 bind_desktop_shell(struct wl_client *client,
2378                    void *data, uint32_t version, uint32_t id)
2379 {
2380         struct desktop_shell *shell = data;
2381         struct wl_resource *resource;
2382
2383         resource = wl_client_add_object(client, &desktop_shell_interface,
2384                                         &desktop_shell_implementation,
2385                                         id, shell);
2386
2387         if (client == shell->child.client) {
2388                 resource->destroy = unbind_desktop_shell;
2389                 shell->child.desktop_shell = resource;
2390                 return;
2391         }
2392
2393         wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
2394                                "permission to bind desktop_shell denied");
2395         wl_resource_destroy(resource);
2396 }
2397
2398 static void
2399 screensaver_set_surface(struct wl_client *client,
2400                         struct wl_resource *resource,
2401                         struct wl_resource *shell_surface_resource,
2402                         struct wl_resource *output_resource)
2403 {
2404         struct desktop_shell *shell = resource->data;
2405         struct shell_surface *surface = shell_surface_resource->data;
2406         struct weston_output *output = output_resource->data;
2407
2408         surface->next_type = SHELL_SURFACE_SCREENSAVER;
2409
2410         surface->fullscreen_output = output;
2411         surface->output = output;
2412         wl_list_insert(shell->screensaver.surfaces.prev, &surface->link);
2413 }
2414
2415 static const struct screensaver_interface screensaver_implementation = {
2416         screensaver_set_surface
2417 };
2418
2419 static void
2420 unbind_screensaver(struct wl_resource *resource)
2421 {
2422         struct desktop_shell *shell = resource->data;
2423
2424         shell->screensaver.binding = NULL;
2425         free(resource);
2426 }
2427
2428 static void
2429 bind_screensaver(struct wl_client *client,
2430                  void *data, uint32_t version, uint32_t id)
2431 {
2432         struct desktop_shell *shell = data;
2433         struct wl_resource *resource;
2434
2435         resource = wl_client_add_object(client, &screensaver_interface,
2436                                         &screensaver_implementation,
2437                                         id, shell);
2438
2439         if (shell->screensaver.binding == NULL) {
2440                 resource->destroy = unbind_screensaver;
2441                 shell->screensaver.binding = resource;
2442                 return;
2443         }
2444
2445         wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
2446                                "interface object already bound");
2447         wl_resource_destroy(resource);
2448 }
2449
2450 struct switcher {
2451         struct desktop_shell *shell;
2452         struct weston_surface *current;
2453         struct wl_listener listener;
2454         struct wl_keyboard_grab grab;
2455 };
2456
2457 static void
2458 switcher_next(struct switcher *switcher)
2459 {
2460         struct weston_compositor *compositor = switcher->shell->compositor;
2461         struct weston_surface *surface;
2462         struct weston_surface *first = NULL, *prev = NULL, *next = NULL;
2463         struct shell_surface *shsurf;
2464
2465         wl_list_for_each(surface, &compositor->surface_list, link) {
2466                 switch (get_shell_surface_type(surface)) {
2467                 case SHELL_SURFACE_TOPLEVEL:
2468                 case SHELL_SURFACE_FULLSCREEN:
2469                 case SHELL_SURFACE_MAXIMIZED:
2470                         if (first == NULL)
2471                                 first = surface;
2472                         if (prev == switcher->current)
2473                                 next = surface;
2474                         prev = surface;
2475                         surface->alpha = 0.25;
2476                         surface->geometry.dirty = 1;
2477                         weston_surface_damage(surface);
2478                         break;
2479                 default:
2480                         break;
2481                 }
2482
2483                 if (is_black_surface(surface, NULL)) {
2484                         surface->alpha = 0.25;
2485                         surface->geometry.dirty = 1;
2486                         weston_surface_damage(surface);
2487                 }
2488         }
2489
2490         if (next == NULL)
2491                 next = first;
2492
2493         if (next == NULL)
2494                 return;
2495
2496         wl_list_remove(&switcher->listener.link);
2497         wl_signal_add(&next->surface.resource.destroy_signal,
2498                       &switcher->listener);
2499
2500         switcher->current = next;
2501         next->alpha = 1.0;
2502
2503         shsurf = get_shell_surface(switcher->current);
2504         if (shsurf && shsurf->type ==SHELL_SURFACE_FULLSCREEN)
2505                 shsurf->fullscreen.black_surface->alpha = 1.0;
2506 }
2507
2508 static void
2509 switcher_handle_surface_destroy(struct wl_listener *listener, void *data)
2510 {
2511         struct switcher *switcher =
2512                 container_of(listener, struct switcher, listener);
2513
2514         switcher_next(switcher);
2515 }
2516
2517 static void
2518 switcher_destroy(struct switcher *switcher)
2519 {
2520         struct weston_compositor *compositor = switcher->shell->compositor;
2521         struct weston_surface *surface;
2522         struct wl_keyboard *keyboard = switcher->grab.keyboard;
2523
2524         wl_list_for_each(surface, &compositor->surface_list, link) {
2525                 surface->alpha = 1.0;
2526                 weston_surface_damage(surface);
2527         }
2528
2529         if (switcher->current)
2530                 activate(switcher->shell, switcher->current,
2531                          (struct weston_seat *) keyboard->seat);
2532         wl_list_remove(&switcher->listener.link);
2533         wl_keyboard_end_grab(keyboard);
2534         free(switcher);
2535 }
2536
2537 static void
2538 switcher_key(struct wl_keyboard_grab *grab,
2539              uint32_t time, uint32_t key, uint32_t state_w)
2540 {
2541         struct switcher *switcher = container_of(grab, struct switcher, grab);
2542         enum wl_keyboard_key_state state = state_w;
2543
2544         if (key == KEY_TAB && state == WL_KEYBOARD_KEY_STATE_PRESSED)
2545                 switcher_next(switcher);
2546 }
2547
2548 static void
2549 switcher_modifier(struct wl_keyboard_grab *grab, uint32_t serial,
2550                   uint32_t mods_depressed, uint32_t mods_latched,
2551                   uint32_t mods_locked, uint32_t group)
2552 {
2553         struct switcher *switcher = container_of(grab, struct switcher, grab);
2554         struct weston_seat *seat = (struct weston_seat *) grab->keyboard->seat;
2555
2556         if ((seat->modifier_state & switcher->shell->binding_modifier) == 0)
2557                 switcher_destroy(switcher);
2558 }
2559
2560 static const struct wl_keyboard_grab_interface switcher_grab = {
2561         switcher_key,
2562         switcher_modifier,
2563 };
2564
2565 static void
2566 switcher_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
2567                  void *data)
2568 {
2569         struct desktop_shell *shell = data;
2570         struct switcher *switcher;
2571
2572         switcher = malloc(sizeof *switcher);
2573         switcher->shell = shell;
2574         switcher->current = NULL;
2575         switcher->listener.notify = switcher_handle_surface_destroy;
2576         wl_list_init(&switcher->listener.link);
2577
2578         switcher->grab.interface = &switcher_grab;
2579         wl_keyboard_start_grab(seat->keyboard, &switcher->grab);
2580         wl_keyboard_set_focus(seat->keyboard, NULL);
2581         switcher_next(switcher);
2582 }
2583
2584 static void
2585 backlight_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
2586                   void *data)
2587 {
2588         struct weston_compositor *compositor = data;
2589         struct weston_output *output;
2590         long backlight_new = 0;
2591
2592         /* TODO: we're limiting to simple use cases, where we assume just
2593          * control on the primary display. We'd have to extend later if we
2594          * ever get support for setting backlights on random desktop LCD
2595          * panels though */
2596         output = get_default_output(compositor);
2597         if (!output)
2598                 return;
2599
2600         if (!output->set_backlight)
2601                 return;
2602
2603         if (key == KEY_F9 || key == KEY_BRIGHTNESSDOWN)
2604                 backlight_new = output->backlight_current - 25;
2605         else if (key == KEY_F10 || key == KEY_BRIGHTNESSUP)
2606                 backlight_new = output->backlight_current + 25;
2607
2608         if (backlight_new < 5)
2609                 backlight_new = 5;
2610         if (backlight_new > 255)
2611                 backlight_new = 255;
2612
2613         output->backlight_current = backlight_new;
2614         output->set_backlight(output, output->backlight_current);
2615 }
2616
2617 static void
2618 debug_repaint_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
2619                       void *data)
2620 {
2621         struct desktop_shell *shell = data;
2622         struct weston_compositor *compositor = shell->compositor;
2623         struct weston_surface *surface;
2624
2625         if (shell->debug_repaint_surface) {
2626                 weston_surface_destroy(shell->debug_repaint_surface);
2627                 shell->debug_repaint_surface = NULL;
2628         } else {
2629                 surface = weston_surface_create(compositor);
2630                 weston_surface_set_color(surface, 1.0, 0.0, 0.0, 0.2);
2631                 weston_surface_configure(surface, 0, 0, 8192, 8192);
2632                 wl_list_insert(&compositor->fade_layer.surface_list,
2633                                &surface->layer_link);
2634                 weston_surface_assign_output(surface);
2635                 pixman_region32_init(&surface->input);
2636
2637                 /* Here's the dirty little trick that makes the
2638                  * repaint debugging work: we force an
2639                  * update_transform first to update dependent state
2640                  * and clear the geometry.dirty bit.  Then we clear
2641                  * the surface damage so it only gets repainted
2642                  * piecewise as we repaint other things.  */
2643
2644                 weston_surface_update_transform(surface);
2645                 pixman_region32_fini(&surface->damage);
2646                 pixman_region32_init(&surface->damage);
2647                 shell->debug_repaint_surface = surface;
2648         }
2649 }
2650
2651 static void
2652 force_kill_binding(struct wl_seat *seat, uint32_t time, uint32_t key,
2653                    void *data)
2654 {
2655         struct wl_client *client;
2656         pid_t pid;
2657         uid_t uid;
2658         gid_t gid;
2659
2660         client = seat->keyboard->focus->resource.client;
2661         wl_client_get_credentials(client, &pid, &uid, &gid);
2662
2663         kill(pid, SIGKILL);
2664 }
2665
2666 static void
2667 shell_destroy(struct wl_listener *listener, void *data)
2668 {
2669         struct desktop_shell *shell =
2670                 container_of(listener, struct desktop_shell, destroy_listener);
2671
2672         if (shell->child.client)
2673                 wl_client_destroy(shell->child.client);
2674
2675         wl_list_remove(&shell->lock_listener.link);
2676         wl_list_remove(&shell->unlock_listener.link);
2677
2678         free(shell->screensaver.path);
2679         free(shell);
2680 }
2681
2682 static void
2683 shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
2684 {
2685         uint32_t mod;
2686
2687         /* fixed bindings */
2688         weston_compositor_add_key_binding(ec, KEY_BACKSPACE,
2689                                           MODIFIER_CTRL | MODIFIER_ALT,
2690                                           terminate_binding, ec);
2691         weston_compositor_add_button_binding(ec, BTN_LEFT, 0,
2692                                              click_to_activate_binding,
2693                                              shell);
2694         weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL,
2695                                            MODIFIER_SUPER | MODIFIER_ALT,
2696                                            surface_opacity_binding, NULL);
2697         weston_compositor_add_axis_binding(ec, WL_POINTER_AXIS_VERTICAL_SCROLL,
2698                                            MODIFIER_SUPER, zoom_axis_binding,
2699                                            NULL);
2700
2701         /* configurable bindings */
2702         mod = shell->binding_modifier;
2703         weston_compositor_add_key_binding(ec, KEY_PAGEUP, mod,
2704                                           zoom_key_binding, NULL);
2705         weston_compositor_add_key_binding(ec, KEY_PAGEDOWN, mod,
2706                                           zoom_key_binding, NULL);
2707         weston_compositor_add_button_binding(ec, BTN_LEFT, mod, move_binding,
2708                                              shell);
2709         weston_compositor_add_button_binding(ec, BTN_MIDDLE, mod,
2710                                              resize_binding, shell);
2711         weston_compositor_add_button_binding(ec, BTN_RIGHT, mod,
2712                                              rotate_binding, NULL);
2713         weston_compositor_add_key_binding(ec, KEY_TAB, mod, switcher_binding,
2714                                           shell);
2715         weston_compositor_add_key_binding(ec, KEY_F9, mod, backlight_binding,
2716                                           ec);
2717         weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSDOWN, 0,
2718                                           backlight_binding, ec);
2719         weston_compositor_add_key_binding(ec, KEY_F10, mod, backlight_binding,
2720                                           ec);
2721         weston_compositor_add_key_binding(ec, KEY_BRIGHTNESSUP, 0,
2722                                           backlight_binding, ec);
2723         weston_compositor_add_key_binding(ec, KEY_SPACE, mod,
2724                                           debug_repaint_binding, shell);
2725         weston_compositor_add_key_binding(ec, KEY_K, mod,
2726                                           force_kill_binding, shell);
2727 }
2728
2729 int
2730 shell_init(struct weston_compositor *ec);
2731
2732 WL_EXPORT int
2733 shell_init(struct weston_compositor *ec)
2734 {
2735         struct desktop_shell *shell;
2736
2737         shell = malloc(sizeof *shell);
2738         if (shell == NULL)
2739                 return -1;
2740
2741         memset(shell, 0, sizeof *shell);
2742         shell->compositor = ec;
2743
2744         shell->destroy_listener.notify = shell_destroy;
2745         wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
2746         shell->lock_listener.notify = lock;
2747         wl_signal_add(&ec->lock_signal, &shell->lock_listener);
2748         shell->unlock_listener.notify = unlock;
2749         wl_signal_add(&ec->unlock_signal, &shell->unlock_listener);
2750         ec->ping_handler = ping_handler;
2751         ec->shell_interface.create_shell_surface = create_shell_surface;
2752         ec->shell_interface.set_toplevel = set_toplevel;
2753         ec->shell_interface.set_transient = set_transient;
2754         ec->shell_interface.move = surface_move;
2755         ec->shell_interface.resize = surface_resize;
2756
2757         wl_list_init(&shell->backgrounds);
2758         wl_list_init(&shell->panels);
2759         wl_list_init(&shell->screensaver.surfaces);
2760
2761         weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
2762         weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
2763         weston_layer_init(&shell->toplevel_layer, &shell->panel_layer.link);
2764         weston_layer_init(&shell->background_layer,
2765                           &shell->toplevel_layer.link);
2766         wl_list_init(&shell->lock_layer.surface_list);
2767
2768         shell_configuration(shell);
2769
2770         if (wl_display_add_global(ec->wl_display, &wl_shell_interface,
2771                                   shell, bind_shell) == NULL)
2772                 return -1;
2773
2774         if (wl_display_add_global(ec->wl_display,
2775                                   &desktop_shell_interface,
2776                                   shell, bind_desktop_shell) == NULL)
2777                 return -1;
2778
2779         if (wl_display_add_global(ec->wl_display, &screensaver_interface,
2780                                   shell, bind_screensaver) == NULL)
2781                 return -1;
2782
2783         shell->child.deathstamp = weston_compositor_get_time();
2784         if (launch_desktop_shell_process(shell) != 0)
2785                 return -1;
2786
2787         shell->pointer_focus_listener.notify = handle_pointer_focus;
2788         if (ec->seat->seat.pointer)
2789                 wl_signal_add(&ec->seat->seat.pointer->focus_signal,
2790                               &shell->pointer_focus_listener);
2791
2792         shell_add_bindings(ec, shell);
2793
2794         return 0;
2795 }