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