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.
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.
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.
30 #include <linux/input.h>
34 #include <sys/types.h>
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"
43 #ifndef WESTON_SHELL_CLIENT
44 #define WESTON_SHELL_CLIENT "weston-desktop-shell"
46 #define DEFAULT_NUM_WORKSPACES 1
47 #define DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH 200
50 #define static_assert(cond, msg)
54 struct weston_seat *seat;
56 struct weston_surface *keyboard_focus;
58 struct wl_listener seat_destroy_listener;
59 struct wl_listener surface_destroy_listener;
63 struct desktop_shell *shell;
64 struct weston_output *output;
65 struct wl_listener destroy_listener;
69 #if 0 /* move to ico_ivi_shell_private.h */
70 enum shell_surface_type {
72 SHELL_SURFACE_TOPLEVEL,
74 SHELL_SURFACE_XWAYLAND
79 struct wl_event_source *source;
84 * Surface stacking and ordering.
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)
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
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.
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
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)
121 struct shell_surface {
122 struct wl_resource *resource;
123 struct wl_signal destroy_signal;
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;
134 enum shell_surface_type type;
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;
145 struct weston_transform transform;
146 struct weston_matrix rotation;
150 struct wl_list grab_link;
152 struct shell_seat *shseat;
162 enum wl_shell_surface_fullscreen_method type;
163 struct weston_transform transform; /* matrix from x, y */
165 struct weston_view *black_view;
168 struct ping_timer *ping_timer;
170 struct weston_transform workspace_transform;
172 struct weston_output *fullscreen_output;
173 struct weston_output *output;
174 struct weston_output *recommended_output;
177 const struct weston_shell_client *client;
183 } state, next_state; /* surface states */
188 struct weston_pointer_grab grab;
189 struct shell_surface *shsurf;
190 struct wl_listener shsurf_destroy_listener;
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;
200 struct weston_move_grab {
201 struct shell_grab base;
205 struct weston_touch_move_grab {
206 struct shell_touch_grab base;
212 struct shell_grab base;
213 struct weston_matrix rotation;
221 struct weston_seat *seat;
222 struct wl_listener seat_destroy_listener;
225 struct weston_pointer_grab grab;
226 struct wl_list surfaces_list;
227 struct wl_client *client;
233 set_alpha_if_fullscreen(struct shell_surface *shsurf)
235 if (shsurf && shsurf->state.fullscreen)
236 shsurf->fullscreen.black_view->alpha = 0.25;
239 static struct desktop_shell *
240 shell_surface_get_shell(struct shell_surface *shsurf);
243 surface_rotate(struct shell_surface *surface, struct weston_seat *seat);
246 shell_fade_startup(struct desktop_shell *shell);
248 static struct shell_seat *
249 get_shell_seat(struct weston_seat *seat);
252 shell_surface_update_child_surface_layers(struct shell_surface *shsurf);
255 shell_surface_is_wl_shell_surface(struct shell_surface *shsurf);
258 shell_surface_is_xdg_surface(struct shell_surface *shsurf);
261 shell_surface_is_xdg_popup(struct shell_surface *shsurf);
264 shell_surface_set_parent(struct shell_surface *shsurf,
265 struct weston_surface *parent);
267 /* shell management table */
268 static struct desktop_shell *_ico_ivi_shell = NULL;
270 /* shell program path for ico-ivi */
271 #define DEFAULT_DEBUG_LEVEL 4
272 int ico_debug_level = DEFAULT_DEBUG_LEVEL; /* Debug Level */
274 /* default display */
275 static struct weston_output *default_inputpanel = NULL;
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__);} }
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;
307 shell_surface_is_top_fullscreen(struct shell_surface *shsurf)
309 struct desktop_shell *shell;
310 struct weston_view *top_fs_ev;
312 if (shell_hook_fullscreen) {
313 return (*shell_hook_fullscreen)(SHELL_FULLSCREEN_ISTOP, shsurf->surface);
316 shell = shell_surface_get_shell(shsurf);
318 if (wl_list_empty(&shell->fullscreen_layer.view_list))
321 top_fs_ev = container_of(shell->fullscreen_layer.view_list.next,
324 return (shsurf == get_shell_surface(top_fs_ev->surface));
328 destroy_shell_grab_shsurf(struct wl_listener *listener, void *data)
330 struct shell_grab *grab;
332 grab = container_of(listener, struct shell_grab,
333 shsurf_destroy_listener);
339 get_default_view(struct weston_surface *surface)
341 struct shell_surface *shsurf;
342 struct weston_view *view;
344 if (!surface || wl_list_empty(&surface->views))
347 shsurf = get_shell_surface(surface);
351 wl_list_for_each(view, &surface->views, surface_link)
352 if (weston_view_is_mapped(view))
355 return container_of(surface->views.next, struct weston_view, surface_link);
359 popup_grab_end(struct weston_pointer *pointer);
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)
368 struct desktop_shell *shell = shsurf->shell;
370 /* if ico_window_mgr hook, not change grab */
371 if (shell_hook_select) {
375 popup_grab_end(pointer);
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);
384 weston_pointer_start_grab(pointer, &grab->grab);
385 if (shell->child.desktop_shell) {
386 desktop_shell_send_grab_cursor(shell->child.desktop_shell,
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));
396 shell_grab_end(struct shell_grab *grab)
399 wl_list_remove(&grab->shsurf_destroy_listener.link);
400 grab->shsurf->grabbed = 0;
403 weston_pointer_end_grab(grab->grab.pointer);
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)
412 struct desktop_shell *shell = shsurf->shell;
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);
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));
430 shell_touch_grab_end(struct shell_touch_grab *grab)
433 wl_list_remove(&grab->shsurf_destroy_listener.link);
434 grab->shsurf->grabbed = 0;
437 weston_touch_end_grab(grab->touch);
441 center_on_output(struct weston_view *view,
442 struct weston_output *output);
444 static enum weston_keyboard_modifier
445 get_modifier(char *modifier)
448 return MODIFIER_SUPER;
450 if (!strcmp("ctrl", modifier))
451 return MODIFIER_CTRL;
452 else if (!strcmp("alt", modifier))
454 else if (!strcmp("super", modifier))
455 return MODIFIER_SUPER;
457 return MODIFIER_SUPER;
460 static enum animation_type
461 get_animation_type(char *animation)
464 return ANIMATION_NONE;
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;
473 return ANIMATION_NONE;
477 shell_configuration(struct desktop_shell *shell)
479 struct weston_config_section *section;
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;
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);
495 weston_config_section_get_string(section,
496 "binding-modifier", &s, "super");
497 shell->binding_modifier = get_modifier(s);
500 weston_config_section_get_string(section,
501 "exposay-modifier", &s, "none");
502 if (strcmp(s, "none") == 0)
503 shell->exposay_modifier = 0;
505 shell->exposay_modifier = get_modifier(s);
508 weston_config_section_get_string(section, "animation", &s, "none");
509 shell->win_animation_type = get_animation_type(s);
511 weston_config_section_get_string(section,
512 "startup-animation", &s, "fade");
513 shell->startup_animation_type = get_animation_type(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);
520 weston_config_section_get_uint(section, "num-workspaces",
521 &shell->workspaces.num,
522 DEFAULT_NUM_WORKSPACES);
524 weston_log("workspaces=%d manager client=<%s>\n", shell->workspaces.num,
525 shell->client ? shell->client : "NULL");
527 /* get debug level for ivi debug */
528 section = weston_config_get_section(shell->compositor->config, "ivi-option", NULL, NULL);
530 weston_config_section_get_int(section, "log",
531 &ico_debug_level, DEFAULT_DEBUG_LEVEL);
532 ico_debug_level &= 0x0ffff;
536 struct weston_output *
537 get_default_output(struct weston_compositor *compositor)
539 /* support multi display, default fullscreen output display */
540 if (default_inputpanel) {
541 return default_inputpanel;
543 return container_of(compositor->output_list.next,
544 struct weston_output, link);
548 /* no-op func for checking focus surface */
550 focus_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
554 static struct focus_surface *
555 get_focus_surface(struct weston_surface *surface)
557 if (surface->configure == focus_surface_configure)
558 return surface->configure_private;
564 is_focus_surface (struct weston_surface *es)
566 return (es->configure == focus_surface_configure);
570 is_focus_view (struct weston_view *view)
572 return is_focus_surface (view->surface);
575 static struct focus_surface *
576 create_focus_surface(struct weston_compositor *ec,
577 struct weston_output *output)
579 struct focus_surface *fsurf = NULL;
580 struct weston_surface *surface = NULL;
582 fsurf = malloc(sizeof *fsurf);
586 fsurf->surface = weston_surface_create(ec);
587 surface = fsurf->surface;
588 if (surface == NULL) {
593 surface->configure = focus_surface_configure;
594 surface->output = output;
595 surface->configure_private = fsurf;
597 fsurf->view = weston_view_create(surface);
598 if (fsurf->view == NULL) {
599 weston_surface_destroy(surface);
603 fsurf->view->output = output;
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);
614 wl_list_init(&fsurf->workspace_transform.link);
620 focus_surface_destroy(struct focus_surface *fsurf)
622 weston_surface_destroy(fsurf->surface);
627 focus_animation_done(struct weston_view_animation *animation, void *data)
629 struct workspace *ws = data;
631 ws->focus_animation = NULL;
635 focus_state_destroy(struct focus_state *state)
637 wl_list_remove(&state->seat_destroy_listener.link);
638 wl_list_remove(&state->surface_destroy_listener.link);
643 focus_state_seat_destroy(struct wl_listener *listener, void *data)
645 struct focus_state *state = container_of(listener,
647 seat_destroy_listener);
649 wl_list_remove(&state->link);
650 focus_state_destroy(state);
654 focus_state_surface_destroy(struct wl_listener *listener, void *data)
656 struct focus_state *state = container_of(listener,
658 surface_destroy_listener);
659 struct desktop_shell *shell;
660 struct weston_surface *main_surface, *next;
661 struct weston_view *view;
663 main_surface = weston_surface_get_main_surface(state->keyboard_focus);
666 wl_list_for_each(view, &state->ws->layer.view_list, layer_link) {
667 if (view->surface == main_surface)
669 if (is_focus_view(view))
672 next = view->surface;
676 /* if the focus was a sub-surface, activate its main surface */
677 if (main_surface != state->keyboard_focus)
680 shell = state->seat->compositor->shell_interface.shell;
682 state->keyboard_focus = NULL;
683 activate(shell, next, state->seat);
685 if (shell->focus_animation_type == ANIMATION_DIM_LAYER) {
686 if (state->ws->focus_animation)
687 weston_view_animation_destroy(state->ws->focus_animation);
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);
695 wl_list_remove(&state->link);
696 focus_state_destroy(state);
700 static struct focus_state *
701 focus_state_create(struct weston_seat *seat, struct workspace *ws)
703 struct focus_state *state;
705 state = malloc(sizeof *state);
709 state->keyboard_focus = NULL;
712 wl_list_insert(&ws->focus_list, &state->link);
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);
723 static struct focus_state *
724 ensure_focus_state(struct desktop_shell *shell, struct weston_seat *seat)
726 struct workspace *ws = get_current_workspace(shell);
727 struct focus_state *state;
729 wl_list_for_each(state, &ws->focus_list, link)
730 if (state->seat == seat)
733 if (&state->link == &ws->focus_list)
734 state = focus_state_create(seat, ws);
740 focus_state_set_focus(struct focus_state *state,
741 struct weston_surface *surface)
743 if (state->keyboard_focus) {
744 wl_list_remove(&state->surface_destroy_listener.link);
745 wl_list_init(&state->surface_destroy_listener.link);
748 state->keyboard_focus = surface;
750 wl_signal_add(&surface->destroy_signal,
751 &state->surface_destroy_listener);
755 restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
757 struct focus_state *state, *next;
758 struct weston_surface *surface;
760 wl_list_for_each_safe(state, next, &ws->focus_list, link) {
761 if (state->seat->keyboard == NULL)
764 surface = state->keyboard_focus;
766 weston_keyboard_set_focus(state->seat->keyboard, surface);
771 replace_focus_state(struct desktop_shell *shell, struct workspace *ws,
772 struct weston_seat *seat)
774 struct focus_state *state;
776 wl_list_for_each(state, &ws->focus_list, link) {
777 if (state->seat == seat) {
778 focus_state_set_focus(state, seat->keyboard->focus);
785 drop_focus_state(struct desktop_shell *shell, struct workspace *ws,
786 struct weston_surface *surface)
788 struct focus_state *state;
790 wl_list_for_each(state, &ws->focus_list, link)
791 if (state->keyboard_focus == surface)
792 focus_state_set_focus(state, NULL);
796 animate_focus_change(struct desktop_shell *shell, struct workspace *ws,
797 struct weston_view *from, struct weston_view *to)
799 struct weston_output *output;
800 bool focus_surface_created = false;
802 /* FIXME: Only support dim animation using two layers */
803 if (from == to || shell->focus_animation_type != ANIMATION_DIM_LAYER)
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)
811 ws->fsurf_front->view->alpha = 0.0;
813 ws->fsurf_back = create_focus_surface(shell->compositor, output);
814 if (ws->fsurf_back == NULL) {
815 focus_surface_destroy(ws->fsurf_front);
818 ws->fsurf_back->view->alpha = 0.0;
820 focus_surface_created = true;
822 wl_list_remove(&ws->fsurf_front->view->layer_link);
823 wl_list_remove(&ws->fsurf_back->view->layer_link);
826 if (ws->focus_animation) {
827 weston_view_animation_destroy(ws->focus_animation);
828 ws->focus_animation = NULL;
832 wl_list_insert(&to->layer_link,
833 &ws->fsurf_front->view->layer_link);
835 wl_list_insert(&ws->layer.view_list,
836 &ws->fsurf_front->view->layer_link);
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);
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);
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);
861 workspace_destroy(struct workspace *ws)
863 struct focus_state *state, *next;
865 wl_list_for_each_safe(state, next, &ws->focus_list, link)
866 focus_state_destroy(state);
869 focus_surface_destroy(ws->fsurf_front);
871 focus_surface_destroy(ws->fsurf_back);
877 seat_destroyed(struct wl_listener *listener, void *data)
879 struct weston_seat *seat = data;
880 struct focus_state *state, *next;
881 struct workspace *ws = container_of(listener,
883 seat_destroyed_listener);
885 wl_list_for_each_safe(state, next, &ws->focus_list, link)
886 if (state->seat == seat)
887 wl_list_remove(&state->link);
890 static struct workspace *
891 workspace_create(void)
893 struct workspace *ws = malloc(sizeof *ws);
897 weston_layer_init(&ws->layer, NULL);
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;
910 workspace_is_empty(struct workspace *ws)
912 return wl_list_empty(&ws->layer.view_list);
915 static struct workspace *
916 get_workspace(struct desktop_shell *shell, unsigned int index)
918 struct workspace **pws = shell->workspaces.array.data;
919 assert(index < shell->workspaces.num);
925 get_current_workspace(struct desktop_shell *shell)
927 return get_workspace(shell, shell->workspaces.current);
931 activate_workspace(struct desktop_shell *shell, unsigned int index)
933 struct workspace *ws;
935 ws = get_workspace(shell, index);
936 wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
938 shell->workspaces.current = index;
942 get_output_height(struct weston_output *output)
944 return abs(output->region.extents.y1 - output->region.extents.y2);
948 view_translate(struct workspace *ws, struct weston_view *view, double d)
950 struct weston_transform *transform;
952 if (is_focus_view(view)) {
953 struct focus_surface *fsurf = get_focus_surface(view->surface);
954 transform = &fsurf->workspace_transform;
956 struct shell_surface *shsurf = get_shell_surface(view->surface);
957 transform = &shsurf->workspace_transform;
960 if (wl_list_empty(&transform->link))
961 wl_list_insert(view->geometry.transformation_list.prev,
964 weston_matrix_init(&transform->matrix);
965 weston_matrix_translate(&transform->matrix,
967 weston_view_geometry_dirty(view);
971 workspace_translate_out(struct workspace *ws, double fraction)
973 struct weston_view *view;
977 wl_list_for_each(view, &ws->layer.view_list, layer_link) {
978 height = get_output_height(view->surface->output);
979 d = height * fraction;
981 view_translate(ws, view, d);
986 workspace_translate_in(struct workspace *ws, double fraction)
988 struct weston_view *view;
992 wl_list_for_each(view, &ws->layer.view_list, layer_link) {
993 height = get_output_height(view->surface->output);
996 d = -(height - height * fraction);
998 d = height + height * fraction;
1000 view_translate(ws, view, d);
1005 broadcast_current_workspace_state(struct desktop_shell *shell)
1007 struct wl_resource *resource;
1009 wl_resource_for_each(resource, &shell->workspaces.client_list)
1010 workspace_manager_send_state(resource,
1011 shell->workspaces.current,
1012 shell->workspaces.num);
1016 reverse_workspace_change_animation(struct desktop_shell *shell,
1018 struct workspace *from,
1019 struct workspace *to)
1021 shell->workspaces.current = index;
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;
1028 weston_compositor_schedule_repaint(shell->compositor);
1032 workspace_deactivate_transforms(struct workspace *ws)
1034 struct weston_view *view;
1035 struct weston_transform *transform;
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;
1042 struct shell_surface *shsurf = get_shell_surface(view->surface);
1043 transform = &shsurf->workspace_transform;
1046 if (!wl_list_empty(&transform->link)) {
1047 wl_list_remove(&transform->link);
1048 wl_list_init(&transform->link);
1050 weston_view_geometry_dirty(view);
1055 finish_workspace_change_animation(struct desktop_shell *shell,
1056 struct workspace *from,
1057 struct workspace *to)
1059 weston_compositor_schedule_repaint(shell->compositor);
1061 wl_list_remove(&shell->workspaces.animation.link);
1062 workspace_deactivate_transforms(from);
1063 workspace_deactivate_transforms(to);
1064 shell->workspaces.anim_to = NULL;
1066 wl_list_remove(&shell->workspaces.anim_from->layer.link);
1070 animate_workspace_change_frame(struct weston_animation *animation,
1071 struct weston_output *output, uint32_t msecs)
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;
1081 if (workspace_is_empty(from) && workspace_is_empty(to)) {
1082 finish_workspace_change_animation(shell, from, to);
1086 if (shell->workspaces.anim_timestamp == 0) {
1087 if (shell->workspaces.anim_current == 0.0)
1088 shell->workspaces.anim_timestamp = msecs;
1090 shell->workspaces.anim_timestamp =
1092 /* Invers of movement function 'y' below. */
1093 (asin(1.0 - shell->workspaces.anim_current) *
1094 DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH *
1098 t = msecs - shell->workspaces.anim_timestamp;
1104 x = t * (1.0/DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH) * M_PI_2;
1107 if (t < DEFAULT_WORKSPACE_CHANGE_ANIMATION_LENGTH) {
1108 weston_compositor_schedule_repaint(shell->compositor);
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;
1114 weston_compositor_schedule_repaint(shell->compositor);
1117 finish_workspace_change_animation(shell, from, to);
1121 animate_workspace_change(struct desktop_shell *shell,
1123 struct workspace *from,
1124 struct workspace *to)
1126 struct weston_output *output;
1130 if (index > shell->workspaces.current)
1135 shell->workspaces.current = index;
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;
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);
1148 wl_list_insert(from->layer.link.prev, &to->layer.link);
1150 workspace_translate_in(to, 0);
1152 restore_focus_state(shell, to);
1154 weston_compositor_schedule_repaint(shell->compositor);
1158 update_workspace(struct desktop_shell *shell, unsigned int index,
1159 struct workspace *from, struct workspace *to)
1161 shell->workspaces.current = index;
1162 wl_list_insert(&from->layer.link, &to->layer.link);
1163 wl_list_remove(&from->layer.link);
1167 change_workspace(struct desktop_shell *shell, unsigned int index)
1169 struct workspace *from;
1170 struct workspace *to;
1171 struct focus_state *state;
1173 if (index == shell->workspaces.current)
1176 /* Don't change workspace when there is any fullscreen surfaces. */
1177 if (!wl_list_empty(&shell->fullscreen_layer.view_list))
1180 from = get_current_workspace(shell);
1181 to = get_workspace(shell, index);
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);
1191 if (shell->workspaces.anim_to != NULL)
1192 finish_workspace_change_animation(shell,
1193 shell->workspaces.anim_from,
1194 shell->workspaces.anim_to);
1196 restore_focus_state(shell, to);
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);
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));
1210 if (workspace_is_empty(to) && workspace_is_empty(from))
1211 update_workspace(shell, index, from, to);
1213 animate_workspace_change(shell, index, from, to);
1215 broadcast_current_workspace_state(shell);
1219 workspace_has_only(struct workspace *ws, struct weston_surface *surface)
1221 struct wl_list *list = &ws->layer.view_list;
1224 if (wl_list_empty(list))
1229 if (e->next != list)
1232 return container_of(e, struct weston_view, layer_link)->surface == surface;
1236 move_surface_to_workspace(struct desktop_shell *shell,
1237 struct shell_surface *shsurf,
1240 struct workspace *from;
1241 struct workspace *to;
1242 struct weston_seat *seat;
1243 struct weston_surface *focus;
1244 struct weston_view *view;
1246 if (workspace == shell->workspaces.current)
1249 view = get_default_view(shsurf->surface);
1253 assert(weston_surface_get_main_surface(view->surface) == view->surface);
1255 if (workspace >= shell->workspaces.num)
1256 workspace = shell->workspaces.num - 1;
1258 from = get_current_workspace(shell);
1259 to = get_workspace(shell, workspace);
1261 wl_list_remove(&view->layer_link);
1262 wl_list_insert(&to->layer.view_list, &view->layer_link);
1264 shell_surface_update_child_surface_layers(shsurf);
1266 drop_focus_state(shell, from, view->surface);
1267 wl_list_for_each(seat, &shell->compositor->seat_list, link) {
1268 if (!seat->keyboard)
1271 focus = weston_surface_get_main_surface(seat->keyboard->focus);
1272 if (focus == view->surface)
1273 weston_keyboard_set_focus(seat->keyboard, NULL);
1276 weston_view_damage_below(view);
1280 take_surface_to_workspace_by_seat(struct desktop_shell *shell,
1281 struct weston_seat *seat,
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;
1291 surface = weston_surface_get_main_surface(seat->keyboard->focus);
1292 view = get_default_view(surface);
1294 index == shell->workspaces.current ||
1295 is_focus_view(view))
1298 from = get_current_workspace(shell);
1299 to = get_workspace(shell, index);
1301 wl_list_remove(&view->layer_link);
1302 wl_list_insert(&to->layer.view_list, &view->layer_link);
1304 shsurf = get_shell_surface(surface);
1306 shell_surface_update_child_surface_layers(shsurf);
1308 replace_focus_state(shell, to, seat);
1309 drop_focus_state(shell, from, surface);
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);
1316 reverse_workspace_change_animation(shell, index, from, to);
1317 broadcast_current_workspace_state(shell);
1322 if (shell->workspaces.anim_to != NULL)
1323 finish_workspace_change_animation(shell,
1324 shell->workspaces.anim_from,
1325 shell->workspaces.anim_to);
1327 if (workspace_is_empty(from) &&
1328 workspace_has_only(to, surface))
1329 update_workspace(shell, index, from, to);
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);
1336 animate_workspace_change(shell, index, from, to);
1339 broadcast_current_workspace_state(shell);
1341 state = ensure_focus_state(shell, seat);
1343 focus_state_set_focus(state, surface);
1347 workspace_manager_move_surface(struct wl_client *client,
1348 struct wl_resource *resource,
1349 struct wl_resource *surface_resource,
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;
1358 main_surface = weston_surface_get_main_surface(surface);
1359 shell_surface = get_shell_surface(main_surface);
1360 if (shell_surface == NULL)
1363 move_surface_to_workspace(shell, shell_surface, workspace);
1366 static const struct workspace_manager_interface workspace_manager_implementation = {
1367 workspace_manager_move_surface,
1371 unbind_resource(struct wl_resource *resource)
1373 wl_list_remove(wl_resource_get_link(resource));
1377 bind_workspace_manager(struct wl_client *client,
1378 void *data, uint32_t version, uint32_t id)
1380 struct desktop_shell *shell = data;
1381 struct wl_resource *resource;
1383 resource = wl_resource_create(client,
1384 &workspace_manager_interface, 1, id);
1386 if (resource == NULL) {
1387 weston_log("couldn't add workspace manager object");
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));
1397 workspace_manager_send_state(resource,
1398 shell->workspaces.current,
1399 shell->workspaces.num);
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)
1409 touch_move_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id)
1411 struct weston_touch_move_grab *move =
1412 (struct weston_touch_move_grab *) container_of(
1413 grab, struct shell_touch_grab, grab);
1418 if (grab->touch->num_tp == 0) {
1419 shell_touch_grab_end(&move->base);
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)
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);
1434 if (!shsurf || !move->active)
1437 es = shsurf->surface;
1439 /* ico-ivi-shell hook move */
1440 if (shell_hook_move) {
1441 (*shell_hook_move)(es, &dx, &dy);
1444 weston_view_set_position(shsurf->view, dx, dy);
1446 weston_compositor_schedule_repaint(es->compositor);
1450 touch_move_grab_cancel(struct weston_touch_grab *grab)
1452 struct weston_touch_move_grab *move =
1453 (struct weston_touch_move_grab *) container_of(
1454 grab, struct shell_touch_grab, grab);
1456 shell_touch_grab_end(&move->base);
1460 static const struct weston_touch_grab_interface touch_move_grab_interface = {
1461 touch_move_grab_down,
1463 touch_move_grab_motion,
1464 touch_move_grab_cancel,
1468 surface_touch_move(struct shell_surface *shsurf, struct weston_seat *seat)
1470 struct weston_touch_move_grab *move;
1475 if (shsurf->state.fullscreen)
1477 if (shsurf->grabbed)
1480 move = malloc(sizeof *move);
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;
1490 shell_touch_grab_start(&move->base, &touch_move_grab_interface, shsurf,
1497 noop_grab_focus(struct weston_pointer_grab *grab)
1502 move_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
1503 wl_fixed_t x, wl_fixed_t y)
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;
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);
1517 weston_view_set_position(shsurf->view, dx, dy);
1519 weston_compositor_schedule_repaint(shsurf->surface->compositor);
1523 move_grab_button(struct weston_pointer_grab *grab,
1524 uint32_t time, uint32_t button, uint32_t state_w)
1526 struct shell_grab *shell_grab = container_of(grab, struct shell_grab,
1528 struct weston_pointer *pointer = grab->pointer;
1529 enum wl_pointer_button_state state = state_w;
1531 if (pointer->button_count == 0 &&
1532 state == WL_POINTER_BUTTON_STATE_RELEASED) {
1533 shell_grab_end(shell_grab);
1539 move_grab_cancel(struct weston_pointer_grab *grab)
1541 struct shell_grab *shell_grab =
1542 container_of(grab, struct shell_grab, grab);
1544 shell_grab_end(shell_grab);
1548 static const struct weston_pointer_grab_interface move_grab_interface = {
1556 surface_move(struct shell_surface *shsurf, struct weston_seat *seat)
1558 struct weston_move_grab *move;
1563 if (shsurf->grabbed)
1565 if (shsurf->state.fullscreen || shsurf->state.maximized)
1568 move = malloc(sizeof *move);
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;
1577 shell_grab_start(&move->base, &move_grab_interface, shsurf,
1578 seat->pointer, DESKTOP_SHELL_CURSOR_MOVE);
1584 common_surface_move(struct wl_resource *resource,
1585 struct wl_resource *seat_resource, uint32_t serial)
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;
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);
1610 shell_surface_move(struct wl_client *client, struct wl_resource *resource,
1611 struct wl_resource *seat_resource, uint32_t serial)
1613 common_surface_move(resource, seat_resource, serial);
1616 struct weston_resize_grab {
1617 struct shell_grab base;
1619 int32_t width, height;
1623 resize_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
1624 wl_fixed_t x, wl_fixed_t y)
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;
1633 weston_pointer_move(pointer, x, y);
1638 weston_view_from_global_fixed(shsurf->view,
1639 pointer->grab_x, pointer->grab_y,
1641 weston_view_from_global_fixed(shsurf->view,
1642 pointer->x, pointer->y, &to_x, &to_y);
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);
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);
1658 shsurf->client->send_configure(shsurf->surface,
1659 resize->edges, width, height);
1663 send_configure(struct weston_surface *surface,
1664 uint32_t edges, int32_t width, int32_t height)
1666 struct shell_surface *shsurf = get_shell_surface(surface);
1670 uifw_trace("send_configure: send %08x %x w/h=%d/%d",
1671 (int)shsurf->surface, edges, width, height);
1673 wl_shell_surface_send_configure(shsurf->resource,
1674 edges, width, height);
1677 static const struct weston_shell_client shell_client = {
1682 resize_grab_button(struct weston_pointer_grab *grab,
1683 uint32_t time, uint32_t button, uint32_t state_w)
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;
1689 if (pointer->button_count == 0 &&
1690 state == WL_POINTER_BUTTON_STATE_RELEASED) {
1691 shell_grab_end(&resize->base);
1697 resize_grab_cancel(struct weston_pointer_grab *grab)
1699 struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
1701 shell_grab_end(&resize->base);
1705 static const struct weston_pointer_grab_interface resize_grab_interface = {
1713 * Returns the bounding box of a surface and all its sub-surfaces,
1714 * in the surface coordinates system. */
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;
1722 pixman_region32_init_rect(®ion, 0, 0,
1726 wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
1727 pixman_region32_union_rect(®ion, ®ion,
1728 subsurface->position.x,
1729 subsurface->position.y,
1730 subsurface->surface->width,
1731 subsurface->surface->height);
1734 box = pixman_region32_extents(®ion);
1740 *w = box->x2 - box->x1;
1742 *h = box->y2 - box->y1;
1744 pixman_region32_fini(®ion);
1748 surface_resize(struct shell_surface *shsurf,
1749 struct weston_seat *seat, uint32_t edges)
1751 struct weston_resize_grab *resize;
1753 if (shsurf->state.fullscreen || shsurf->state.maximized)
1756 if (edges == 0 || edges > 15 ||
1757 (edges & 3) == 3 || (edges & 12) == 12)
1760 resize = malloc(sizeof *resize);
1764 resize->edges = edges;
1765 surface_subsurfaces_boundingbox(shsurf->surface, NULL, NULL,
1766 &resize->width, &resize->height);
1768 shell_grab_start(&resize->base, &resize_grab_interface, shsurf,
1769 seat->pointer, edges);
1775 common_surface_resize(struct wl_resource *resource,
1776 struct wl_resource *seat_resource, uint32_t serial,
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;
1783 if (shsurf->state.fullscreen)
1786 if (seat->pointer->button_count == 0 ||
1787 seat->pointer->grab_serial != serial ||
1788 seat->pointer->focus == NULL)
1791 surface = weston_surface_get_main_surface(seat->pointer->focus->surface);
1792 if (surface != shsurf->surface)
1795 if (surface_resize(shsurf, seat, edges) < 0)
1796 wl_resource_post_no_memory(resource);
1800 shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
1801 struct wl_resource *seat_resource, uint32_t serial,
1804 common_surface_resize(resource, seat_resource, serial, edges);
1808 end_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer);
1811 busy_cursor_grab_focus(struct weston_pointer_grab *base)
1813 struct shell_grab *grab = (struct shell_grab *) base;
1814 struct weston_pointer *pointer = base->pointer;
1815 struct weston_view *view;
1818 view = weston_compositor_pick_view(pointer->seat->compositor,
1819 pointer->x, pointer->y,
1822 if (!grab->shsurf || grab->shsurf->surface != view->surface)
1823 end_busy_cursor(grab->shsurf, pointer);
1827 busy_cursor_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
1828 wl_fixed_t x, wl_fixed_t y)
1830 weston_pointer_move(grab->pointer, x, y);
1834 busy_cursor_grab_button(struct weston_pointer_grab *base,
1835 uint32_t time, uint32_t button, uint32_t state)
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;
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);
1851 busy_cursor_grab_cancel(struct weston_pointer_grab *base)
1853 struct shell_grab *grab = (struct shell_grab *) base;
1855 shell_grab_end(grab);
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,
1867 set_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer)
1869 struct shell_grab *grab;
1871 grab = malloc(sizeof *grab);
1875 shell_grab_start(grab, &busy_cursor_grab_interface, shsurf, pointer,
1876 DESKTOP_SHELL_CURSOR_BUSY);
1880 end_busy_cursor(struct shell_surface *shsurf, struct weston_pointer *pointer)
1882 struct shell_grab *grab = (struct shell_grab *) pointer->grab;
1884 if (grab->grab.interface == &busy_cursor_grab_interface &&
1885 grab->shsurf == shsurf) {
1886 shell_grab_end(grab);
1892 ping_timer_destroy(struct shell_surface *shsurf)
1894 if (!shsurf || !shsurf->ping_timer)
1897 if (shsurf->ping_timer->source)
1898 wl_event_source_remove(shsurf->ping_timer->source);
1900 free(shsurf->ping_timer);
1901 shsurf->ping_timer = NULL;
1905 ping_timeout_handler(void *data)
1907 struct shell_surface *shsurf = data;
1908 struct weston_seat *seat;
1910 /* Client is not responding */
1911 shsurf->unresponsive = 1;
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);
1922 ping_handler(struct weston_surface *surface, uint32_t serial)
1924 struct shell_surface *shsurf = get_shell_surface(surface);
1925 struct wl_event_loop *loop;
1926 int ping_timeout = 200;
1930 if (!shsurf->resource)
1933 if (shsurf->surface == shsurf->shell->grab_surface)
1936 if (!shsurf->ping_timer) {
1937 shsurf->ping_timer = malloc(sizeof *shsurf->ping_timer);
1938 if (!shsurf->ping_timer)
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);
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);
1957 handle_pointer_focus(struct wl_listener *listener, void *data)
1959 struct weston_pointer *pointer = data;
1960 struct weston_view *view = pointer->focus;
1961 struct weston_compositor *compositor;
1962 struct shell_surface *shsurf;
1968 compositor = view->surface->compositor;
1969 shsurf = get_shell_surface(view->surface);
1971 if (shsurf && shsurf->unresponsive) {
1972 set_busy_cursor(shsurf, pointer);
1974 serial = wl_display_next_serial(compositor->wl_display);
1975 ping_handler(view->surface, serial);
1980 create_pointer_focus_listener(struct weston_seat *seat)
1982 struct wl_listener *listener;
1987 listener = malloc(sizeof *listener);
1988 listener->notify = handle_pointer_focus;
1989 wl_signal_add(&seat->pointer->focus_signal, listener);
1993 xdg_surface_set_transient_for(struct wl_client *client,
1994 struct wl_resource *resource,
1995 struct wl_resource *parent_resource)
1997 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
1998 struct weston_surface *parent;
2000 if (parent_resource)
2001 parent = wl_resource_get_user_data(parent_resource);
2005 shell_surface_set_parent(shsurf, parent);
2009 surface_pong(struct shell_surface *shsurf, uint32_t serial)
2011 struct weston_compositor *ec = shsurf->surface->compositor;
2012 struct weston_seat *seat;
2014 if (shsurf->ping_timer == NULL)
2015 /* Just ignore unsolicited pong. */
2018 if (shsurf->ping_timer->serial == serial) {
2019 shsurf->unresponsive = 0;
2020 wl_list_for_each(seat, &ec->seat_list, link) {
2022 end_busy_cursor(shsurf, seat->pointer);
2024 ping_timer_destroy(shsurf);
2029 shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
2032 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2034 surface_pong(shsurf, serial);
2039 set_title(struct shell_surface *shsurf, const char *title)
2043 /* if ico_window_mgr hook, call hook routine */
2044 if (shell_hook_title) {
2045 p = (*shell_hook_title)(shsurf->surface, title);
2047 free(shsurf->title);
2048 shsurf->title = strdup(p);
2052 free(shsurf->title);
2053 shsurf->title = strdup(title);
2058 shell_surface_set_title(struct wl_client *client,
2059 struct wl_resource *resource, const char *title)
2061 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2063 set_title(shsurf, title);
2067 shell_surface_set_class(struct wl_client *client,
2068 struct wl_resource *resource, const char *class)
2070 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2072 free(shsurf->class);
2073 shsurf->class = strdup(class);
2077 restore_output_mode(struct weston_output *output)
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);
2088 restore_all_output_modes(struct weston_compositor *compositor)
2090 struct weston_output *output;
2092 wl_list_for_each(output, &compositor->output_list, link)
2093 restore_output_mode(output);
2097 get_output_panel_height(struct desktop_shell *shell,
2098 struct weston_output *output)
2100 struct weston_view *view;
2101 int panel_height = 0;
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;
2113 return panel_height;
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)
2122 struct workspace *ws;
2123 struct weston_view *parent;
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. */
2136 /* TODO: Handle a parent with multiple views */
2137 parent = get_default_view(shsurf->parent);
2139 return parent->layer_link.prev;
2143 case SHELL_SURFACE_XWAYLAND:
2144 return &shsurf->shell->fullscreen_layer.view_list;
2146 case SHELL_SURFACE_NONE:
2148 /* Go to the fallback, below. */
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;
2160 shell_surface_update_child_surface_layers (struct shell_surface *shsurf)
2162 struct shell_surface *child;
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);
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);
2184 /* Update the surface’s layer. Mark both the old and new views as having dirty
2185 * geometry to ensure the changes are redrawn.
2187 * If any child surfaces exist and are mapped, ensure they’re in the same layer
2188 * as this surface. */
2190 shell_surface_update_layer(struct shell_surface *shsurf)
2192 struct wl_list *new_layer_link;
2194 new_layer_link = shell_surface_calculate_layer_link(shsurf);
2196 if (new_layer_link == &shsurf->view->layer_link)
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);
2205 shell_surface_update_child_surface_layers(shsurf);
2209 shell_surface_set_parent(struct shell_surface *shsurf,
2210 struct weston_surface *parent)
2212 shsurf->parent = parent;
2214 wl_list_remove(&shsurf->children_link);
2215 wl_list_init(&shsurf->children_link);
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);
2227 shell_surface_set_output(struct shell_surface *shsurf,
2228 struct weston_output *output)
2230 struct weston_surface *es = shsurf->surface;
2232 /* get the default output, if the client set it as NULL
2233 check whether the ouput is available */
2235 shsurf->output = output;
2236 else if (es->output)
2237 shsurf->output = es->output;
2239 shsurf->output = get_default_output(es->compositor);
2243 surface_clear_next_states(struct shell_surface *shsurf)
2245 shsurf->next_state.maximized = false;
2246 shsurf->next_state.fullscreen = false;
2248 if ((shsurf->next_state.maximized != shsurf->state.maximized) ||
2249 (shsurf->next_state.fullscreen != shsurf->state.fullscreen))
2250 shsurf->state_changed = true;
2254 set_toplevel(struct shell_surface *shsurf)
2256 shell_surface_set_parent(shsurf, NULL);
2257 surface_clear_next_states(shsurf);
2258 shsurf->type = SHELL_SURFACE_TOPLEVEL;
2260 /* The layer_link is updated in set_surface_type(),
2261 * called from configure. */
2265 shell_surface_set_toplevel(struct wl_client *client,
2266 struct wl_resource *resource)
2268 struct shell_surface *surface = wl_resource_get_user_data(resource);
2270 set_toplevel(surface);
2274 set_transient(struct shell_surface *shsurf,
2275 struct weston_surface *parent, int x, int y, uint32_t flags)
2277 assert(parent != NULL);
2279 shell_surface_set_parent(shsurf, parent);
2281 surface_clear_next_states(shsurf);
2283 shsurf->transient.x = x;
2284 shsurf->transient.y = y;
2285 shsurf->transient.flags = flags;
2287 shsurf->next_state.relative = true;
2288 shsurf->state_changed = true;
2289 shsurf->type = SHELL_SURFACE_TOPLEVEL;
2291 /* The layer_link is updated in set_surface_type(),
2292 * called from configure. */
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)
2301 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2302 struct weston_surface *parent =
2303 wl_resource_get_user_data(parent_resource);
2305 set_transient(shsurf, parent, x, y, flags);
2309 set_fullscreen(struct shell_surface *shsurf,
2312 struct weston_output *output)
2314 shell_surface_set_output(shsurf, output);
2316 shsurf->fullscreen_output = shsurf->output;
2317 shsurf->fullscreen.type = method;
2318 shsurf->fullscreen.framerate = framerate;
2320 shsurf->next_state.fullscreen = true;
2321 shsurf->state_changed = true;
2322 shsurf->type = SHELL_SURFACE_TOPLEVEL;
2324 if (shell_hook_fullscreen) {
2325 (*shell_hook_fullscreen)(SHELL_FULLSCREEN_SET, shsurf->surface);
2329 shsurf->client->send_configure(shsurf->surface, 0,
2330 shsurf->output->width,
2331 shsurf->output->height);
2333 /* The layer_link is updated in set_surface_type(),
2334 * called from configure. */
2338 weston_view_set_initial_position(struct weston_view *view,
2339 struct desktop_shell *shell);
2342 unset_fullscreen(struct shell_surface *shsurf)
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);
2349 shsurf->fullscreen_output = NULL;
2351 shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
2352 shsurf->fullscreen.framerate = 0;
2354 if (shell_hook_fullscreen) {
2355 (*shell_hook_fullscreen)(SHELL_FULLSCREEN_UNSET, shsurf->surface);
2358 wl_list_remove(&shsurf->fullscreen.transform.link);
2359 wl_list_init(&shsurf->fullscreen.transform.link);
2361 if (shsurf->fullscreen.black_view)
2362 weston_surface_destroy(shsurf->fullscreen.black_view->surface);
2363 shsurf->fullscreen.black_view = NULL;
2365 if (shsurf->saved_position_valid)
2366 weston_view_set_position(shsurf->view,
2367 shsurf->saved_x, shsurf->saved_y);
2369 weston_view_set_initial_position(shsurf->view, shsurf->shell);
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;
2377 /* Layer is updated in set_surface_type(). */
2381 shell_surface_set_fullscreen(struct wl_client *client,
2382 struct wl_resource *resource,
2385 struct wl_resource *output_resource)
2387 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2388 struct weston_output *output;
2390 if (output_resource)
2391 output = wl_resource_get_user_data(output_resource);
2395 shell_surface_set_parent(shsurf, NULL);
2397 surface_clear_next_states(shsurf);
2398 set_fullscreen(shsurf, method, framerate, output);
2402 set_popup(struct shell_surface *shsurf,
2403 struct weston_surface *parent,
2404 struct weston_seat *seat,
2409 assert(parent != NULL);
2411 shsurf->popup.shseat = get_shell_seat(seat);
2412 shsurf->popup.serial = serial;
2413 shsurf->popup.x = x;
2414 shsurf->popup.y = y;
2416 shsurf->type = SHELL_SURFACE_POPUP;
2420 shell_surface_set_popup(struct wl_client *client,
2421 struct wl_resource *resource,
2422 struct wl_resource *seat_resource,
2424 struct wl_resource *parent_resource,
2425 int32_t x, int32_t y, uint32_t flags)
2427 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2428 struct weston_surface *parent =
2429 wl_resource_get_user_data(parent_resource);
2431 shell_surface_set_parent(shsurf, parent);
2433 surface_clear_next_states(shsurf);
2436 wl_resource_get_user_data(seat_resource),
2441 set_maximized(struct shell_surface *shsurf,
2442 struct weston_output *output)
2444 struct desktop_shell *shell;
2445 uint32_t edges = 0, panel_height = 0;
2447 shell_surface_set_output(shsurf, output);
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;
2453 shsurf->client->send_configure(shsurf->surface, edges,
2454 shsurf->output->width,
2455 shsurf->output->height - panel_height);
2457 shsurf->next_state.maximized = true;
2458 shsurf->state_changed = true;
2459 shsurf->type = SHELL_SURFACE_TOPLEVEL;
2463 unset_maximized(struct shell_surface *shsurf)
2465 /* undo all maximized things here */
2466 shsurf->output = get_default_output(shsurf->surface->compositor);
2468 if (shsurf->saved_position_valid)
2469 weston_view_set_position(shsurf->view,
2470 shsurf->saved_x, shsurf->saved_y);
2472 weston_view_set_initial_position(shsurf->view, shsurf->shell);
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;
2480 /* Layer is updated in set_surface_type(). */
2484 shell_surface_set_maximized(struct wl_client *client,
2485 struct wl_resource *resource,
2486 struct wl_resource *output_resource)
2488 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
2489 struct weston_output *output;
2491 if (output_resource)
2492 output = wl_resource_get_user_data(output_resource);
2496 shell_surface_set_parent(shsurf, NULL);
2498 surface_clear_next_states(shsurf);
2499 set_maximized(shsurf, output);
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. */
2505 reset_surface_type(struct shell_surface *surface)
2507 if (surface->state.fullscreen)
2508 unset_fullscreen(surface);
2509 if (surface->state.maximized)
2510 unset_maximized(surface);
2516 set_full_output(struct shell_surface *shsurf)
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;
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;
2534 set_surface_type(struct shell_surface *shsurf)
2536 struct weston_surface *pes = shsurf->parent;
2537 struct weston_view *pev = get_default_view(pes);
2539 reset_surface_type(shsurf);
2541 shsurf->state = shsurf->next_state;
2542 shsurf->state_changed = false;
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);
2555 case SHELL_SURFACE_XWAYLAND:
2556 weston_view_set_position(shsurf->view, shsurf->transient.x,
2557 shsurf->transient.y);
2560 case SHELL_SURFACE_POPUP:
2561 case SHELL_SURFACE_NONE:
2566 /* Update the surface’s layer. */
2567 shell_surface_update_layer(shsurf);
2570 static struct desktop_shell *
2571 shell_surface_get_shell(struct shell_surface *shsurf)
2573 return shsurf->shell;
2577 black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy);
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)
2584 struct weston_surface *surface = NULL;
2585 struct weston_view *view;
2587 surface = weston_surface_create(ec);
2588 if (surface == NULL) {
2589 weston_log("no memory\n");
2592 view = weston_view_create(surface);
2593 if (surface == NULL) {
2594 weston_log("no memory\n");
2595 weston_surface_destroy(surface);
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);
2607 weston_surface_set_size(surface, w, h);
2608 weston_view_set_position(view, x, y);
2614 shell_ensure_fullscreen_black_view(struct shell_surface *shsurf)
2616 struct weston_output *output = shsurf->fullscreen_output;
2618 assert(shsurf->state.fullscreen);
2620 if (!shsurf->fullscreen.black_view)
2621 shsurf->fullscreen.black_view =
2622 create_black_surface(shsurf->surface->compositor,
2624 output->x, output->y,
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);
2636 /* Create black surface and append it to the associated fullscreen surface.
2637 * Handle size dismatch and positioning according to the method. */
2639 shell_configure_fullscreen(struct shell_surface *shsurf)
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;
2647 if (shell_hook_fullscreen) {
2648 (*shell_hook_fullscreen)(SHELL_FULLSCREEN_CONF, shsurf->surface);
2651 if (shsurf->fullscreen.type != WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER)
2652 restore_output_mode(output);
2654 shell_ensure_fullscreen_black_view(shsurf);
2656 surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y,
2657 &surf_width, &surf_height);
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);
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,
2670 output->y - surf_y);
2674 matrix = &shsurf->fullscreen.transform.matrix;
2675 weston_matrix_init(matrix);
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 /
2686 scale = (float) output->height /
2687 (float) surf_height;
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);
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};
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,
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,
2714 output->y - surf_y);
2717 restore_output_mode(output);
2718 center_on_output(shsurf->view, output);
2722 case WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL:
2723 center_on_output(shsurf->view, output);
2731 shell_map_fullscreen(struct shell_surface *shsurf)
2733 shell_configure_fullscreen(shsurf);
2737 set_xwayland(struct shell_surface *shsurf, int x, int y, uint32_t flags)
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;
2745 shell_surface_set_parent(shsurf, NULL);
2747 shsurf->type = SHELL_SURFACE_XWAYLAND;
2748 shsurf->state_changed = true;
2751 static const struct weston_pointer_grab_interface popup_grab_interface;
2754 destroy_shell_seat(struct wl_listener *listener, void *data)
2756 struct shell_seat *shseat =
2757 container_of(listener,
2758 struct shell_seat, seat_destroy_listener);
2759 struct shell_surface *shsurf, *prev = NULL;
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;
2765 wl_list_for_each(shsurf, &shseat->popup_grab.surfaces_list, popup.grab_link) {
2766 shsurf->popup.shseat = NULL;
2768 wl_list_init(&prev->popup.grab_link);
2772 wl_list_init(&prev->popup.grab_link);
2775 wl_list_remove(&shseat->seat_destroy_listener.link);
2779 static struct shell_seat *
2780 create_shell_seat(struct weston_seat *seat)
2782 struct shell_seat *shseat;
2784 shseat = calloc(1, sizeof *shseat);
2786 weston_log("no memory to allocate shell seat\n");
2790 shseat->seat = seat;
2791 wl_list_init(&shseat->popup_grab.surfaces_list);
2793 shseat->seat_destroy_listener.notify = destroy_shell_seat;
2794 wl_signal_add(&seat->destroy_signal,
2795 &shseat->seat_destroy_listener);
2800 static struct shell_seat *
2801 get_shell_seat(struct weston_seat *seat)
2803 struct wl_listener *listener;
2805 listener = wl_signal_get(&seat->destroy_signal, destroy_shell_seat);
2806 if (listener == NULL)
2807 return create_shell_seat(seat);
2809 return container_of(listener,
2810 struct shell_seat, seat_destroy_listener);
2814 popup_grab_focus(struct weston_pointer_grab *grab)
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;
2823 view = weston_compositor_pick_view(pointer->seat->compositor,
2824 pointer->x, pointer->y,
2827 if (view && view->surface->resource &&
2828 wl_resource_get_client(view->surface->resource) == client) {
2829 weston_pointer_set_focus(pointer, view, sx, sy);
2831 weston_pointer_set_focus(pointer, NULL,
2832 wl_fixed_from_int(0),
2833 wl_fixed_from_int(0));
2838 popup_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
2839 wl_fixed_t x, wl_fixed_t y)
2841 struct weston_pointer *pointer = grab->pointer;
2842 struct wl_resource *resource;
2845 weston_pointer_move(pointer, x, y);
2847 wl_resource_for_each(resource, &pointer->focus_resource_list) {
2848 weston_view_from_global_fixed(pointer->focus,
2849 pointer->x, pointer->y,
2851 wl_pointer_send_motion(resource, time, sx, sy);
2856 popup_grab_button(struct weston_pointer_grab *grab,
2857 uint32_t time, uint32_t button, uint32_t state_w)
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;
2865 struct wl_list *resource_list;
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);
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);
2880 if (state == WL_POINTER_BUTTON_STATE_RELEASED)
2881 shseat->popup_grab.initial_up = 1;
2885 popup_grab_cancel(struct weston_pointer_grab *grab)
2887 popup_grab_end(grab->pointer);
2890 static const struct weston_pointer_grab_interface popup_grab_interface = {
2898 shell_surface_send_popup_done(struct shell_surface *shsurf)
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);
2908 popup_grab_end(struct weston_pointer *pointer)
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;
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;
2926 wl_list_init(&prev->popup.grab_link);
2930 wl_list_init(&prev->popup.grab_link);
2931 wl_list_init(&shseat->popup_grab.surfaces_list);
2936 add_popup_grab(struct shell_surface *shsurf, struct shell_seat *shseat)
2938 struct weston_seat *seat = shseat->seat;
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;
2949 wl_list_insert(&shseat->popup_grab.surfaces_list, &shsurf->popup.grab_link);
2950 weston_pointer_start_grab(seat->pointer, &shseat->popup_grab.grab);
2952 wl_list_insert(&shseat->popup_grab.surfaces_list, &shsurf->popup.grab_link);
2957 remove_popup_grab(struct shell_surface *shsurf)
2959 struct shell_seat *shseat = shsurf->popup.shseat;
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;
2970 shell_map_popup(struct shell_surface *shsurf)
2972 struct shell_seat *shseat = shsurf->popup.shseat;
2973 struct weston_view *parent_view = get_default_view(shsurf->parent);
2975 shsurf->surface->output = parent_view->output;
2976 shsurf->view->output = parent_view->output;
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);
2982 if (shseat->seat->pointer->grab_serial == shsurf->popup.serial) {
2983 add_popup_grab(shsurf, shseat);
2985 shell_surface_send_popup_done(shsurf);
2986 shseat->popup_grab.client = NULL;
2990 static const struct wl_shell_surface_interface shell_surface_implementation = {
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
3004 destroy_shell_surface(struct shell_surface *shsurf)
3006 struct shell_surface *child, *next;
3008 /* if ico_window_mgr hook, call hook routine */
3009 if (shell_hook_destroy) {
3010 (*shell_hook_destroy)(shsurf->surface);
3013 wl_signal_emit(&shsurf->destroy_signal, shsurf);
3015 if (!wl_list_empty(&shsurf->popup.grab_link)) {
3016 remove_popup_grab(shsurf);
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);
3023 if (shsurf->fullscreen.black_view)
3024 weston_surface_destroy(shsurf->fullscreen.black_view->surface);
3026 /* As destroy_resource() use wl_list_for_each_safe(),
3027 * we can always remove the listener.
3029 wl_list_remove(&shsurf->surface_destroy_listener.link);
3030 shsurf->surface->configure = NULL;
3031 ping_timer_destroy(shsurf);
3032 free(shsurf->title);
3034 weston_view_destroy(shsurf->view);
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;
3042 wl_list_remove(&shsurf->link);
3047 shell_destroy_shell_surface(struct wl_resource *resource)
3049 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3051 destroy_shell_surface(shsurf);
3055 shell_handle_surface_destroy(struct wl_listener *listener, void *data)
3057 struct shell_surface *shsurf = container_of(listener,
3058 struct shell_surface,
3059 surface_destroy_listener);
3061 if (shsurf->resource)
3062 wl_resource_destroy(shsurf->resource);
3064 destroy_shell_surface(shsurf);
3068 shell_surface_configure(struct weston_surface *, int32_t, int32_t);
3070 shell_surface_output_destroyed(struct weston_surface *);
3072 struct shell_surface *
3073 get_shell_surface(struct weston_surface *surface)
3075 if (surface->configure == shell_surface_configure)
3076 return surface->configure_private;
3081 static struct shell_surface *
3082 create_common_surface(void *shell, struct weston_surface *surface,
3083 const struct weston_shell_client *client)
3085 struct shell_surface *shsurf;
3087 if (surface->configure) {
3088 weston_log("surface->configure already set\n");
3092 shsurf = calloc(1, sizeof *shsurf);
3094 weston_log("no memory to allocate shell surface\n");
3098 shsurf->view = weston_view_create(surface);
3099 if (!shsurf->view) {
3100 weston_log("no memory to allocate shell surface\n");
3105 surface->configure = shell_surface_configure;
3106 surface->configure_private = shsurf;
3107 surface->output_destroyed = shell_surface_output_destroyed;
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;
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);
3123 wl_list_init(&shsurf->fullscreen.transform.link);
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);
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);
3134 /* empty when not in use */
3135 wl_list_init(&shsurf->rotation.transform.link);
3136 weston_matrix_init(&shsurf->rotation.rotation);
3138 wl_list_init(&shsurf->workspace_transform.link);
3140 wl_list_init(&shsurf->children_link);
3141 wl_list_init(&shsurf->children_list);
3142 shsurf->parent = NULL;
3144 shsurf->type = SHELL_SURFACE_NONE;
3146 shsurf->client = client;
3151 static struct shell_surface *
3152 create_shell_surface(void *shell, struct weston_surface *surface,
3153 const struct weston_shell_client *client)
3155 return create_common_surface(shell, surface, client);
3158 static struct weston_view *
3159 get_primary_view(void *shell, struct shell_surface *shsurf)
3161 return shsurf->view;
3165 shell_get_shell_surface(struct wl_client *client,
3166 struct wl_resource *resource,
3168 struct wl_resource *surface_resource)
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;
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");
3182 shsurf = create_shell_surface(shell, surface, &shell_client);
3184 wl_resource_post_error(surface_resource,
3185 WL_DISPLAY_ERROR_INVALID_OBJECT,
3186 "surface->configure already set");
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);
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);
3205 shell_surface_is_wl_shell_surface(struct shell_surface *shsurf)
3207 return wl_resource_instance_of(shsurf->resource,
3208 &wl_shell_surface_interface,
3209 &shell_surface_implementation);
3212 static const struct wl_shell_interface shell_implementation = {
3213 shell_get_shell_surface
3216 /****************************
3217 * xdg-shell implementation */
3220 xdg_surface_destroy(struct wl_client *client,
3221 struct wl_resource *resource)
3223 wl_resource_destroy(resource);
3227 xdg_surface_pong(struct wl_client *client,
3228 struct wl_resource *resource,
3231 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3233 surface_pong(shsurf, serial);
3237 xdg_surface_set_app_id(struct wl_client *client,
3238 struct wl_resource *resource,
3241 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3243 free(shsurf->class);
3244 shsurf->class = strdup(app_id);
3248 xdg_surface_set_title(struct wl_client *client,
3249 struct wl_resource *resource, const char *title)
3251 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3253 set_title(shsurf, title);
3257 xdg_surface_move(struct wl_client *client, struct wl_resource *resource,
3258 struct wl_resource *seat_resource, uint32_t serial)
3260 common_surface_move(resource, seat_resource, serial);
3264 xdg_surface_resize(struct wl_client *client, struct wl_resource *resource,
3265 struct wl_resource *seat_resource, uint32_t serial,
3268 common_surface_resize(resource, seat_resource, serial, edges);
3272 xdg_surface_set_output(struct wl_client *client,
3273 struct wl_resource *resource,
3274 struct wl_resource *output_resource)
3276 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3277 struct weston_output *output;
3279 if (output_resource)
3280 output = wl_resource_get_user_data(output_resource);
3284 shsurf->recommended_output = output;
3288 xdg_surface_set_fullscreen(struct wl_client *client,
3289 struct wl_resource *resource)
3291 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3293 if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
3296 if (!shsurf->next_state.fullscreen)
3297 set_fullscreen(shsurf,
3298 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
3299 0, shsurf->recommended_output);
3303 xdg_surface_unset_fullscreen(struct wl_client *client,
3304 struct wl_resource *resource)
3306 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3307 int32_t width, height;
3309 if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
3312 if (!shsurf->next_state.fullscreen)
3315 shsurf->next_state.fullscreen = false;
3316 shsurf->state_changed = true;
3318 if (shsurf->saved_size_valid) {
3319 width = shsurf->saved_width;
3320 height = shsurf->saved_height;
3321 shsurf->saved_size_valid = false;
3323 width = shsurf->surface->width;
3324 height = shsurf->surface->height;
3327 if (shell_hook_fullscreen) {
3328 (*shell_hook_fullscreen)(SHELL_FULLSCREEN_UNSET, shsurf->surface);
3331 shsurf->client->send_configure(shsurf->surface, 0, width, height);
3335 xdg_surface_set_maximized(struct wl_client *client,
3336 struct wl_resource *resource)
3338 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3340 if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
3343 if (!shsurf->next_state.maximized)
3344 set_maximized(shsurf, NULL);
3348 xdg_surface_unset_maximized(struct wl_client *client,
3349 struct wl_resource *resource)
3351 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3352 int32_t width, height;
3354 if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
3357 if (!shsurf->next_state.maximized)
3360 shsurf->next_state.maximized = false;
3361 shsurf->state_changed = true;
3363 if (shsurf->saved_size_valid) {
3364 width = shsurf->saved_width;
3365 height = shsurf->saved_height;
3366 shsurf->saved_size_valid = false;
3368 width = shsurf->surface->width;
3369 height = shsurf->surface->height;
3372 shsurf->client->send_configure(shsurf->surface, 0, width, height);
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,
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 */
3392 xdg_send_configure(struct weston_surface *surface,
3393 uint32_t edges, int32_t width, int32_t height)
3395 struct shell_surface *shsurf = get_shell_surface(surface);
3399 xdg_surface_send_configure(shsurf->resource, edges, width, height);
3402 static const struct weston_shell_client xdg_client = {
3407 xdg_use_unstable_version(struct wl_client *client,
3408 struct wl_resource *resource,
3412 wl_resource_post_error(resource,
3414 "xdg-shell:: version not implemented yet.");
3419 static struct shell_surface *
3420 create_xdg_surface(void *shell, struct weston_surface *surface,
3421 const struct weston_shell_client *client)
3423 struct shell_surface *shsurf;
3425 shsurf = create_common_surface(shell, surface, client);
3426 shsurf->type = SHELL_SURFACE_TOPLEVEL;
3432 xdg_get_xdg_surface(struct wl_client *client,
3433 struct wl_resource *resource,
3435 struct wl_resource *surface_resource)
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;
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");
3449 shsurf = create_xdg_surface(shell, surface, &xdg_client);
3451 wl_resource_post_error(surface_resource,
3452 WL_DISPLAY_ERROR_INVALID_OBJECT,
3453 "surface->configure already set");
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);
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);
3472 shell_surface_is_xdg_surface(struct shell_surface *shsurf)
3474 return wl_resource_instance_of(shsurf->resource,
3475 &xdg_surface_interface,
3476 &xdg_surface_implementation);
3479 /* xdg-popup implementation */
3482 xdg_popup_destroy(struct wl_client *client,
3483 struct wl_resource *resource)
3485 wl_resource_destroy(resource);
3489 xdg_popup_pong(struct wl_client *client,
3490 struct wl_resource *resource,
3493 struct shell_surface *shsurf = wl_resource_get_user_data(resource);
3495 surface_pong(shsurf, serial);
3498 static const struct xdg_popup_interface xdg_popup_implementation = {
3504 xdg_popup_send_configure(struct weston_surface *surface,
3505 uint32_t edges, int32_t width, int32_t height)
3509 static const struct weston_shell_client xdg_popup_client = {
3510 xdg_popup_send_configure
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,
3519 int32_t x, int32_t y)
3521 struct shell_surface *shsurf;
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);
3535 xdg_get_xdg_popup(struct wl_client *client,
3536 struct wl_resource *resource,
3538 struct wl_resource *surface_resource,
3539 struct wl_resource *parent_resource,
3540 struct wl_resource *seat_resource,
3542 int32_t x, int32_t y, uint32_t flags)
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;
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");
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");
3564 parent = wl_resource_get_user_data(parent_resource);
3565 seat = get_shell_seat(wl_resource_get_user_data(seat_resource));;
3567 shsurf = create_xdg_popup(shell, surface, &xdg_popup_client,
3568 parent, seat, serial, x, y);
3570 wl_resource_post_error(surface_resource,
3571 WL_DISPLAY_ERROR_INVALID_OBJECT,
3572 "surface->configure already set");
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);
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);
3591 shell_surface_is_xdg_popup(struct shell_surface *shsurf)
3593 return wl_resource_instance_of(shsurf->resource,
3594 &xdg_popup_interface,
3595 &xdg_popup_implementation);
3598 static const struct xdg_shell_interface xdg_implementation = {
3599 xdg_use_unstable_version,
3600 xdg_get_xdg_surface,
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)
3610 struct wl_resource *resource = _target;
3611 struct desktop_shell *shell = wl_resource_get_user_data(resource);
3614 wl_resource_post_error(resource,
3615 WL_DISPLAY_ERROR_INVALID_OBJECT,
3616 "must call use_unstable_version first");
3620 #define XDG_SERVER_VERSION 1
3622 static_assert(XDG_SERVER_VERSION == XDG_SHELL_VERSION_CURRENT,
3623 "shell implementation doesn't match protocol version");
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 "
3630 XDG_SERVER_VERSION, args[0].i);
3634 wl_resource_set_implementation(resource, &xdg_implementation,
3640 /* end of xdg-shell implementation */
3641 /***********************************/
3644 shell_fade(struct desktop_shell *shell, enum fade_type type);
3647 screensaver_timeout(void *data)
3649 struct desktop_shell *shell = data;
3651 shell_fade(shell, FADE_OUT);
3657 handle_screensaver_sigchld(struct weston_process *proc, int status)
3659 struct desktop_shell *shell =
3660 container_of(proc, struct desktop_shell, screensaver.process);
3665 weston_compositor_sleep(shell->compositor);
3669 launch_screensaver(struct desktop_shell *shell)
3671 if (shell->screensaver.binding)
3674 if (!shell->screensaver.path) {
3675 weston_compositor_sleep(shell->compositor);
3679 if (shell->screensaver.process.pid != 0) {
3680 weston_log("old screensaver still running\n");
3684 weston_client_launch(shell->compositor,
3685 &shell->screensaver.process,
3686 shell->screensaver.path,
3687 handle_screensaver_sigchld);
3691 terminate_screensaver(struct desktop_shell *shell)
3693 if (shell->screensaver.process.pid == 0)
3696 kill(shell->screensaver.process.pid, SIGTERM);
3700 configure_static_view(struct weston_view *ev, struct weston_layer *layer)
3702 struct weston_view *v, *next;
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;
3711 weston_view_set_position(ev, ev->output->x, ev->output->y);
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);
3718 /* if ico_window_mgr hook, call hook routine */
3719 if (shell_hook_configure) {
3720 (*shell_hook_configure)(ev->surface);
3725 background_configure(struct weston_surface *es, int32_t sx, int32_t sy)
3727 struct desktop_shell *shell = es->configure_private;
3728 struct weston_view *view;
3730 view = container_of(es->views.next, struct weston_view, surface_link);
3732 configure_static_view(view, &shell->background_layer);
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)
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;
3746 if (surface->configure) {
3747 wl_resource_post_error(surface_resource,
3748 WL_DISPLAY_ERROR_INVALID_OBJECT,
3749 "surface role already assigned");
3753 wl_list_for_each_safe(view, next, &surface->views, surface_link)
3754 weston_view_destroy(view);
3755 view = weston_view_create(surface);
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,
3763 surface->output->width,
3764 surface->output->height);
3768 panel_configure(struct weston_surface *es, int32_t sx, int32_t sy)
3770 struct desktop_shell *shell = es->configure_private;
3771 struct weston_view *view;
3773 view = container_of(es->views.next, struct weston_view, surface_link);
3775 configure_static_view(view, &shell->panel_layer);
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)
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;
3789 if (surface->configure) {
3790 wl_resource_post_error(surface_resource,
3791 WL_DISPLAY_ERROR_INVALID_OBJECT,
3792 "surface role already assigned");
3796 wl_list_for_each_safe(view, next, &surface->views, surface_link)
3797 weston_view_destroy(view);
3798 view = weston_view_create(surface);
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,
3806 surface->output->width,
3807 surface->output->height);
3811 lock_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
3813 struct desktop_shell *shell = surface->configure_private;
3814 struct weston_view *view;
3816 view = container_of(surface->views.next, struct weston_view, surface_link);
3818 if (surface->width == 0)
3821 center_on_output(view, get_default_output(shell->compositor));
3823 if (!weston_surface_is_mapped(surface)) {
3824 wl_list_insert(&shell->lock_layer.view_list,
3826 weston_view_update_transform(view);
3827 shell_fade(shell, FADE_IN);
3832 handle_lock_surface_destroy(struct wl_listener *listener, void *data)
3834 struct desktop_shell *shell =
3835 container_of(listener, struct desktop_shell, lock_surface_listener);
3837 weston_log("lock surface gone\n");
3838 shell->lock_surface = NULL;
3842 desktop_shell_set_lock_surface(struct wl_client *client,
3843 struct wl_resource *resource,
3844 struct wl_resource *surface_resource)
3846 struct desktop_shell *shell = wl_resource_get_user_data(resource);
3847 struct weston_surface *surface =
3848 wl_resource_get_user_data(surface_resource);
3850 shell->prepare_event_sent = false;
3855 shell->lock_surface = surface;
3857 shell->lock_surface_listener.notify = handle_lock_surface_destroy;
3858 wl_signal_add(&surface->destroy_signal,
3859 &shell->lock_surface_listener);
3861 weston_view_create(surface);
3862 surface->configure = lock_surface_configure;
3863 surface->configure_private = shell;
3867 resume_desktop(struct desktop_shell *shell)
3869 struct workspace *ws = get_current_workspace(shell);
3871 terminate_screensaver(shell);
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,
3884 wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
3887 restore_focus_state(shell, get_current_workspace(shell));
3889 shell->locked = false;
3890 shell_fade(shell, FADE_IN);
3891 weston_compositor_damage_all(shell->compositor);
3895 desktop_shell_unlock(struct wl_client *client,
3896 struct wl_resource *resource)
3898 struct desktop_shell *shell = wl_resource_get_user_data(resource);
3900 shell->prepare_event_sent = false;
3903 resume_desktop(shell);
3907 desktop_shell_set_grab_surface(struct wl_client *client,
3908 struct wl_resource *resource,
3909 struct wl_resource *surface_resource)
3911 struct desktop_shell *shell = wl_resource_get_user_data(resource);
3913 shell->grab_surface = wl_resource_get_user_data(surface_resource);
3914 weston_view_create(shell->grab_surface);
3918 desktop_shell_desktop_ready(struct wl_client *client,
3919 struct wl_resource *resource)
3921 struct desktop_shell *shell = wl_resource_get_user_data(resource);
3923 shell_fade_startup(shell);
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
3935 static enum shell_surface_type
3936 get_shell_surface_type(struct weston_surface *surface)
3938 struct shell_surface *shsurf;
3940 shsurf = get_shell_surface(surface);
3942 return SHELL_SURFACE_NONE;
3943 return shsurf->type;
3947 move_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
3949 struct weston_surface *focus;
3950 struct weston_surface *surface;
3951 struct shell_surface *shsurf;
3953 if (seat->pointer->focus == NULL)
3956 focus = seat->pointer->focus->surface;
3958 surface = weston_surface_get_main_surface(focus);
3959 if (surface == NULL)
3962 shsurf = get_shell_surface(surface);
3963 if (shsurf == NULL || shsurf->state.fullscreen ||
3964 shsurf->state.maximized)
3967 surface_move(shsurf, (struct weston_seat *) seat);
3971 maximize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
3973 struct weston_surface *focus = seat->pointer->focus->surface;
3974 struct weston_surface *surface;
3975 struct shell_surface *shsurf;
3977 surface = weston_surface_get_main_surface(focus);
3978 if (surface == NULL)
3981 shsurf = get_shell_surface(surface);
3985 if (!shell_surface_is_xdg_surface(shsurf))
3988 if (shsurf->state.maximized)
3989 xdg_surface_send_request_unset_maximized(shsurf->resource);
3991 xdg_surface_send_request_set_maximized(shsurf->resource);
3995 fullscreen_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
3997 struct weston_surface *focus = seat->pointer->focus->surface;
3998 struct weston_surface *surface;
3999 struct shell_surface *shsurf;
4001 surface = weston_surface_get_main_surface(focus);
4002 if (surface == NULL)
4005 shsurf = get_shell_surface(surface);
4009 if (!shell_surface_is_xdg_surface(shsurf))
4012 if (shsurf->state.fullscreen)
4013 xdg_surface_send_request_unset_fullscreen(shsurf->resource);
4015 xdg_surface_send_request_set_fullscreen(shsurf->resource);
4019 touch_move_binding(struct weston_seat *seat, uint32_t time, void *data)
4021 struct weston_surface *focus = seat->touch->focus->surface;
4022 struct weston_surface *surface;
4023 struct shell_surface *shsurf;
4025 surface = weston_surface_get_main_surface(focus);
4026 if (surface == NULL)
4029 shsurf = get_shell_surface(surface);
4030 if (shsurf == NULL || shsurf->state.fullscreen ||
4031 shsurf->state.maximized)
4034 surface_touch_move(shsurf, (struct weston_seat *) seat);
4038 resize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void *data)
4040 struct weston_surface *focus;
4041 struct weston_surface *surface;
4044 struct shell_surface *shsurf;
4046 if (seat->pointer->focus == NULL)
4049 focus = seat->pointer->focus->surface;
4051 surface = weston_surface_get_main_surface(focus);
4052 if (surface == NULL)
4055 shsurf = get_shell_surface(surface);
4056 if (shsurf == NULL || shsurf->state.fullscreen ||
4057 shsurf->state.maximized)
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),
4065 if (x < shsurf->surface->width / 3)
4066 edges |= WL_SHELL_SURFACE_RESIZE_LEFT;
4067 else if (x < 2 * shsurf->surface->width / 3)
4070 edges |= WL_SHELL_SURFACE_RESIZE_RIGHT;
4072 if (y < shsurf->surface->height / 3)
4073 edges |= WL_SHELL_SURFACE_RESIZE_TOP;
4074 else if (y < 2 * shsurf->surface->height / 3)
4077 edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
4079 surface_resize(shsurf, (struct weston_seat *) seat, edges);
4083 surface_opacity_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
4084 wl_fixed_t value, void *data)
4087 struct shell_surface *shsurf;
4088 struct weston_surface *focus = seat->pointer->focus->surface;
4089 struct weston_surface *surface;
4091 /* XXX: broken for windows containing sub-surfaces */
4092 surface = weston_surface_get_main_surface(focus);
4093 if (surface == NULL)
4096 shsurf = get_shell_surface(surface);
4100 shsurf->view->alpha -= wl_fixed_to_double(value) * step;
4102 if (shsurf->view->alpha > 1.0)
4103 shsurf->view->alpha = 1.0;
4104 if (shsurf->view->alpha < step)
4105 shsurf->view->alpha = step;
4107 weston_view_geometry_dirty(shsurf->view);
4108 weston_surface_damage(surface);
4112 do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
4115 struct weston_seat *ws = (struct weston_seat *) seat;
4116 struct weston_compositor *compositor = ws->compositor;
4117 struct weston_output *output;
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),
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;
4136 output->zoom.level += increment;
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);
4146 output->zoom.spring_z.target = output->zoom.level;
4148 weston_output_update_zoom(output);
4154 zoom_axis_binding(struct weston_seat *seat, uint32_t time, uint32_t axis,
4155 wl_fixed_t value, void *data)
4157 do_zoom(seat, time, 0, axis, value);
4161 zoom_key_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
4164 do_zoom(seat, time, key, 0, 0);
4168 terminate_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
4171 struct weston_compositor *compositor = data;
4173 wl_display_terminate(compositor->wl_display);
4177 rotate_grab_motion(struct weston_pointer_grab *grab, uint32_t time,
4178 wl_fixed_t x, wl_fixed_t y)
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;
4186 weston_pointer_move(pointer, x, y);
4191 cx = 0.5f * shsurf->surface->width;
4192 cy = 0.5f * shsurf->surface->height;
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);
4198 wl_list_remove(&shsurf->rotation.transform.link);
4199 weston_view_geometry_dirty(shsurf->view);
4202 struct weston_matrix *matrix =
4203 &shsurf->rotation.transform.matrix;
4205 weston_matrix_init(&rotate->rotation);
4206 weston_matrix_rotate_xy(&rotate->rotation, dx / r, dy / r);
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);
4215 &shsurf->view->geometry.transformation_list,
4216 &shsurf->rotation.transform.link);
4218 wl_list_init(&shsurf->rotation.transform.link);
4219 weston_matrix_init(&shsurf->rotation.rotation);
4220 weston_matrix_init(&rotate->rotation);
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);
4235 /* Repaint implies weston_surface_update_transform(), which
4236 * lazily applies the damage due to rotation update.
4238 weston_compositor_schedule_repaint(shsurf->surface->compositor);
4242 rotate_grab_button(struct weston_pointer_grab *grab,
4243 uint32_t time, uint32_t button, uint32_t state_w)
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;
4251 if (pointer->button_count == 0 &&
4252 state == WL_POINTER_BUTTON_STATE_RELEASED) {
4254 weston_matrix_multiply(&shsurf->rotation.rotation,
4256 shell_grab_end(&rotate->base);
4262 rotate_grab_cancel(struct weston_pointer_grab *grab)
4264 struct rotate_grab *rotate =
4265 container_of(grab, struct rotate_grab, base.grab);
4267 shell_grab_end(&rotate->base);
4271 static const struct weston_pointer_grab_interface rotate_grab_interface = {
4279 surface_rotate(struct shell_surface *surface, struct weston_seat *seat)
4281 struct rotate_grab *rotate;
4285 rotate = malloc(sizeof *rotate);
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);
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);
4298 struct weston_matrix inverse;
4300 weston_matrix_init(&inverse);
4301 weston_matrix_rotate_xy(&inverse, dx / r, -dy / r);
4302 weston_matrix_multiply(&surface->rotation.rotation, &inverse);
4304 weston_matrix_init(&rotate->rotation);
4305 weston_matrix_rotate_xy(&rotate->rotation, dx / r, dy / r);
4307 weston_matrix_init(&surface->rotation.rotation);
4308 weston_matrix_init(&rotate->rotation);
4311 shell_grab_start(&rotate->base, &rotate_grab_interface, surface,
4312 seat->pointer, DESKTOP_SHELL_CURSOR_ARROW);
4316 rotate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
4319 struct weston_surface *focus;
4320 struct weston_surface *base_surface;
4321 struct shell_surface *surface;
4323 if (seat->pointer->focus == NULL)
4326 focus = seat->pointer->focus->surface;
4328 base_surface = weston_surface_get_main_surface(focus);
4329 if (base_surface == NULL)
4332 surface = get_shell_surface(base_surface);
4333 if (surface == NULL || surface->state.fullscreen ||
4334 surface->state.maximized)
4337 surface_rotate(surface, seat);
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. */
4344 lower_fullscreen_layer(struct desktop_shell *shell)
4346 struct workspace *ws;
4347 struct weston_view *view, *prev;
4349 if (shell_hook_fullscreen) {
4350 (*shell_hook_fullscreen)(SHELL_FULLSCREEN_HIDEALL, NULL);
4354 ws = get_current_workspace(shell);
4355 wl_list_for_each_reverse_safe(view, prev,
4356 &shell->fullscreen_layer.view_list,
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);
4366 activate(struct desktop_shell *shell, struct weston_surface *es,
4367 struct weston_seat *seat)
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;
4375 main_surface = weston_surface_get_main_surface(es);
4377 weston_surface_activate(es, seat);
4379 state = ensure_focus_state(shell, seat);
4383 old_es = state->keyboard_focus;
4384 focus_state_set_focus(state, es);
4386 shsurf = get_shell_surface(main_surface);
4389 /* if ico_window_mgr hook, not change surface stack */
4390 if (shell_hook_select) {
4394 if (shsurf->state.fullscreen)
4395 shell_configure_fullscreen(shsurf);
4397 restore_all_output_modes(shell->compositor);
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));
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);
4409 /* no-op func for checking black surface */
4411 black_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
4416 is_black_surface (struct weston_surface *es, struct weston_surface **fs_surface)
4418 if (es->configure == black_surface_configure) {
4420 *fs_surface = (struct weston_surface *)es->configure_private;
4427 activate_binding(struct weston_seat *seat,
4428 struct desktop_shell *shell,
4429 struct weston_surface *focus)
4431 struct weston_surface *main_surface;
4436 if (is_black_surface(focus, &main_surface))
4437 focus = main_surface;
4439 main_surface = weston_surface_get_main_surface(focus);
4440 if (get_shell_surface_type(main_surface) == SHELL_SURFACE_NONE)
4443 activate(shell, focus, seat);
4445 /* if ico_window_mgr hook, call hook routine */
4446 if (shell_hook_select) {
4447 (*shell_hook_select)(focus);
4452 click_to_activate_binding(struct weston_seat *seat, uint32_t time, uint32_t button,
4455 if (seat->pointer->grab != &seat->pointer->default_grab)
4457 if (seat->pointer->focus == NULL)
4460 activate_binding(seat, data, seat->pointer->focus->surface);
4464 touch_to_activate_binding(struct weston_seat *seat, uint32_t time, void *data)
4466 if (seat->touch->grab != &seat->touch->default_grab)
4468 if (seat->touch->focus == NULL)
4471 activate_binding(seat, data, seat->touch->focus->surface);
4475 lock(struct desktop_shell *shell)
4477 struct workspace *ws = get_current_workspace(shell);
4479 if (shell->locked) {
4480 weston_compositor_sleep(shell->compositor);
4484 shell->locked = true;
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. */
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);
4498 launch_screensaver(shell);
4500 /* TODO: disable bindings that should not work while locked. */
4502 /* All this must be undone in resume_desktop(). */
4506 unlock(struct desktop_shell *shell)
4508 if (!shell->locked || shell->lock_surface) {
4509 shell_fade(shell, FADE_IN);
4513 /* If desktop-shell client has gone away, unlock immediately. */
4514 if (!shell->child.desktop_shell) {
4515 resume_desktop(shell);
4519 if (shell->prepare_event_sent)
4522 desktop_shell_send_prepare_lock_surface(shell->child.desktop_shell);
4523 shell->prepare_event_sent = true;
4527 shell_fade_done(struct weston_view_animation *animation, void *data)
4529 struct desktop_shell *shell = data;
4531 shell->fade.animation = NULL;
4533 switch (shell->fade.type) {
4535 weston_surface_destroy(shell->fade.view->surface);
4536 shell->fade.view = NULL;
4546 static struct weston_view *
4547 shell_fade_create_surface(struct desktop_shell *shell)
4549 struct weston_compositor *compositor = shell->compositor;
4550 struct weston_surface *surface;
4551 struct weston_view *view;
4553 surface = weston_surface_create(compositor);
4557 view = weston_view_create(surface);
4559 weston_surface_destroy(surface);
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,
4568 pixman_region32_init(&surface->input);
4574 shell_fade(struct desktop_shell *shell, enum fade_type type)
4586 weston_log("shell: invalid fade type\n");
4590 shell->fade.type = type;
4592 if (shell->fade.view == NULL) {
4593 shell->fade.view = shell_fade_create_surface(shell);
4594 if (!shell->fade.view)
4597 shell->fade.view->alpha = 1.0 - tint;
4598 weston_view_update_transform(shell->fade.view);
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);
4612 shell->fade.animation =
4613 weston_fade_run(shell->fade.view,
4614 1.0 - tint, tint, 300.0,
4615 shell_fade_done, shell);
4620 do_shell_fade_startup(void *data)
4622 struct desktop_shell *shell = data;
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;
4633 shell_fade_startup(struct desktop_shell *shell)
4635 struct wl_event_loop *loop;
4637 if (!shell->fade.startup_timer)
4640 wl_event_source_remove(shell->fade.startup_timer);
4641 shell->fade.startup_timer = NULL;
4643 loop = wl_display_get_event_loop(shell->compositor->wl_display);
4644 wl_event_loop_add_idle(loop, do_shell_fade_startup, shell);
4648 fade_startup_timeout(void *data)
4650 struct desktop_shell *shell = data;
4652 shell_fade_startup(shell);
4657 shell_fade_init(struct desktop_shell *shell)
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.
4664 struct wl_event_loop *loop;
4666 if (shell->fade.view != NULL) {
4667 weston_log("%s: warning: fade surface already exists\n",
4672 shell->fade.view = shell_fade_create_surface(shell);
4673 if (!shell->fade.view)
4676 weston_view_update_transform(shell->fade.view);
4677 weston_surface_damage(shell->fade.view->surface);
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);
4686 idle_handler(struct wl_listener *listener, void *data)
4688 struct desktop_shell *shell =
4689 container_of(listener, struct desktop_shell, idle_listener);
4690 struct weston_seat *seat;
4692 wl_list_for_each(seat, &shell->compositor->seat_list, link)
4694 popup_grab_end(seat->pointer);
4696 shell_fade(shell, FADE_OUT);
4697 /* lock() is called from shell_fade_done() */
4701 wake_handler(struct wl_listener *listener, void *data)
4703 struct desktop_shell *shell =
4704 container_of(listener, struct desktop_shell, wake_listener);
4710 center_on_output(struct weston_view *view, struct weston_output *output)
4712 int32_t surf_x, surf_y, width, height;
4715 surface_subsurfaces_boundingbox(view->surface, &surf_x, &surf_y, &width, &height);
4717 x = output->x + (output->width - width) / 2 - surf_x / 2;
4718 y = output->y + (output->height - height) / 2 - surf_y / 2;
4720 weston_view_set_position(view, x, y);
4724 weston_view_set_initial_position(struct weston_view *view,
4725 struct desktop_shell *shell)
4727 struct weston_compositor *compositor = shell->compositor;
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;
4734 /* As a heuristic place the new window on the same output as the
4735 * pointer. Falling back to the output containing 0, 0.
4737 * TODO: Do something clever for touch too?
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);
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;
4754 if (!target_output) {
4755 weston_view_set_position(view, 10 + random() % 400,
4756 10 + random() % 400);
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
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;
4770 dx = random() % range_x;
4775 dy = panel_height + random() % range_y;
4779 x = target_output->x + dx;
4780 y = target_output->y + dy;
4782 weston_view_set_position(view, x, y);
4786 map(struct desktop_shell *shell, struct shell_surface *shsurf,
4787 int32_t sx, int32_t sy)
4789 struct weston_compositor *compositor = shell->compositor;
4790 struct weston_seat *seat;
4791 int panel_height = 0;
4792 int32_t surf_x, surf_y;
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,
4808 panel_height - surf_y);
4809 } else if (!shsurf->state.relative) {
4810 weston_view_set_initial_position(shsurf->view, shell);
4813 case SHELL_SURFACE_POPUP:
4814 shell_map_popup(shsurf);
4816 case SHELL_SURFACE_NONE:
4817 if (shsurf->layertype == LAYER_TYPE_INPUTPANEL) {
4818 weston_view_set_initial_position(shsurf->view, shell);
4821 weston_view_set_position(shsurf->view,
4822 shsurf->view->geometry.x + sx,
4823 shsurf->view->geometry.y + sy);
4826 case SHELL_SURFACE_XWAYLAND:
4831 /* Surface stacking order, see also activate(). */
4832 shell_surface_update_layer(shsurf);
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;
4842 if ((shsurf->type == SHELL_SURFACE_XWAYLAND || shsurf->state.relative) &&
4843 shsurf->transient.flags == WL_SHELL_SURFACE_TRANSIENT_INACTIVE) {
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)
4852 case SHELL_SURFACE_TOPLEVEL:
4853 if (shsurf->state.relative &&
4854 shsurf->transient.flags == WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
4858 wl_list_for_each(seat, &compositor->seat_list, link)
4859 activate(shell, shsurf->surface, seat);
4861 case SHELL_SURFACE_POPUP:
4862 case SHELL_SURFACE_NONE:
4867 if (shsurf->type == SHELL_SURFACE_TOPLEVEL &&
4868 !shsurf->state.maximized && !shsurf->state.fullscreen)
4870 switch (shell->win_animation_type) {
4871 case ANIMATION_FADE:
4872 weston_fade_run(shsurf->view, 0.0, 1.0, 300.0, NULL, NULL);
4874 case ANIMATION_ZOOM:
4875 weston_zoom_run(shsurf->view, 0.5, 1.0, NULL, NULL);
4877 case ANIMATION_NONE:
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);
4890 if (shell_hook_configure) {
4891 (*shell_hook_configure)(shsurf->surface); /* send event to manager */
4896 configure(struct desktop_shell *shell, struct weston_surface *surface,
4899 struct shell_surface *shsurf;
4900 struct weston_view *view;
4901 int32_t mx, my, surf_x, surf_y;
4903 shsurf = get_shell_surface(surface);
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,
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);
4918 weston_view_set_position(shsurf->view, x, y);
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);
4926 if (shsurf->state.maximized)
4927 surface->output = shsurf->output;
4930 /* if ico_window_mgr hook, call hook routine */
4931 if (shell_hook_configure) {
4932 (*shell_hook_configure)(surface);
4937 shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
4939 struct shell_surface *shsurf = get_shell_surface(es);
4940 struct desktop_shell *shell;
4941 int type_changed = 0;
4945 shell = shsurf->shell;
4947 if (!weston_surface_is_mapped(es) &&
4948 !wl_list_empty(&shsurf->popup.grab_link)) {
4949 remove_popup_grab(shsurf);
4955 if (shsurf->state_changed) {
4956 set_surface_type(shsurf);
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;
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);
4979 shell_surface_output_destroyed(struct weston_surface *es)
4981 struct shell_surface *shsurf = get_shell_surface(es);
4985 shsurf->saved_position_valid = false;
4986 shsurf->next_state.maximized = false;
4987 shsurf->next_state.fullscreen = false;
4988 shsurf->state_changed = true;
4991 static void launch_desktop_shell_process(void *data);
4994 desktop_shell_sigchld(struct weston_process *process, int status)
4997 struct desktop_shell *shell =
4998 container_of(process, struct desktop_shell, child.process);
5000 shell->child.process.pid = 0;
5001 shell->child.client = NULL; /* already destroyed by wayland */
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;
5010 shell->child.deathcount++;
5011 if (shell->child.deathcount > 5) {
5012 weston_log("%s died, giving up.\n", shell->client);
5016 weston_log("%s died, respawning...\n", shell->client);
5017 launch_desktop_shell_process(shell);
5018 shell_fade_startup(shell);
5022 desktop_shell_client_destroy(struct wl_listener *listener, void *data)
5024 struct desktop_shell *shell;
5026 shell = container_of(listener, struct desktop_shell,
5027 child.client_destroy_listener);
5029 shell->child.client = NULL;
5033 launch_desktop_shell_process(void *data)
5035 struct desktop_shell *shell = data;
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");
5042 uifw_trace("launch_desktop_shell_process: launch %s", shell->client);
5043 shell->child.client = weston_client_launch(shell->compositor,
5044 &shell->child.process,
5046 desktop_shell_sigchld);
5048 if (!shell->child.client)
5049 weston_log("not able to start %s\n", shell->client);
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);
5060 bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
5062 struct desktop_shell *shell = data;
5063 struct wl_resource *resource;
5065 resource = wl_resource_create(client, &wl_shell_interface, 1, id);
5067 wl_resource_set_implementation(resource, &shell_implementation,
5070 /* if ico_window_mgr hook, call hook routine */
5071 if (shell_hook_bind) {
5072 (*shell_hook_bind)(client, data);
5077 bind_xdg_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
5079 struct desktop_shell *shell = data;
5080 struct wl_resource *resource;
5082 resource = wl_resource_create(client, &xdg_shell_interface, 1, id);
5084 wl_resource_set_dispatcher(resource,
5085 xdg_shell_unversioned_dispatch,
5088 /* if ico_window_mgr hook, call hook routine */
5089 if (shell_hook_bind) {
5090 (*shell_hook_bind)(client, data);
5095 unbind_desktop_shell(struct wl_resource *resource)
5097 struct desktop_shell *shell = wl_resource_get_user_data(resource);
5099 /* if ico_window_mgr hook, call hook routine */
5100 if (shell_hook_unbind) {
5101 (*shell_hook_unbind)(wl_resource_get_client(resource));
5105 resume_desktop(shell);
5107 shell->child.desktop_shell = NULL;
5108 shell->prepare_event_sent = false;
5112 bind_desktop_shell(struct wl_client *client,
5113 void *data, uint32_t version, uint32_t id)
5115 struct desktop_shell *shell = data;
5116 struct wl_resource *resource;
5118 resource = wl_resource_create(client, &desktop_shell_interface,
5119 MIN(version, 2), id);
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;
5128 shell_fade_startup(shell);
5133 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
5134 "permission to bind desktop_shell denied");
5135 wl_resource_destroy(resource);
5139 screensaver_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
5141 struct desktop_shell *shell = surface->configure_private;
5142 struct weston_view *view;
5144 if (surface->width == 0)
5147 /* XXX: starting weston-screensaver beforehand does not work */
5151 view = container_of(surface->views.next, struct weston_view, surface_link);
5152 center_on_output(view, surface->output);
5154 if (wl_list_empty(&view->layer_link)) {
5155 wl_list_insert(shell->lock_layer.view_list.prev,
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);
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)
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;
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);
5181 surface->configure = screensaver_configure;
5182 surface->configure_private = shell;
5183 surface->output = output;
5186 static const struct screensaver_interface screensaver_implementation = {
5187 screensaver_set_surface
5191 unbind_screensaver(struct wl_resource *resource)
5193 struct desktop_shell *shell = wl_resource_get_user_data(resource);
5195 shell->screensaver.binding = NULL;
5199 bind_screensaver(struct wl_client *client,
5200 void *data, uint32_t version, uint32_t id)
5202 struct desktop_shell *shell = data;
5203 struct wl_resource *resource;
5205 resource = wl_resource_create(client, &screensaver_interface, 1, id);
5207 if (shell->screensaver.binding == NULL) {
5208 wl_resource_set_implementation(resource,
5209 &screensaver_implementation,
5210 shell, unbind_screensaver);
5211 shell->screensaver.binding = resource;
5215 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
5216 "interface object already bound");
5217 wl_resource_destroy(resource);
5221 struct desktop_shell *shell;
5222 struct weston_surface *current;
5223 struct wl_listener listener;
5224 struct weston_keyboard_grab grab;
5228 switcher_next(struct switcher *switcher)
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);
5235 wl_list_for_each(view, &ws->layer.view_list, layer_link) {
5236 shsurf = get_shell_surface(view->surface);
5238 shsurf->type == SHELL_SURFACE_TOPLEVEL &&
5239 shsurf->parent == NULL) {
5241 first = view->surface;
5242 if (prev == switcher->current)
5243 next = view->surface;
5244 prev = view->surface;
5246 weston_view_geometry_dirty(view);
5247 weston_surface_damage(view->surface);
5250 if (is_black_surface(view->surface, NULL)) {
5252 weston_view_geometry_dirty(view);
5253 weston_surface_damage(view->surface);
5263 wl_list_remove(&switcher->listener.link);
5264 wl_signal_add(&next->destroy_signal, &switcher->listener);
5266 switcher->current = next;
5267 wl_list_for_each(view, &next->views, surface_link)
5270 shsurf = get_shell_surface(switcher->current);
5271 if (shsurf && shsurf->state.fullscreen)
5272 shsurf->fullscreen.black_view->alpha = 1.0;
5276 switcher_handle_surface_destroy(struct wl_listener *listener, void *data)
5278 struct switcher *switcher =
5279 container_of(listener, struct switcher, listener);
5281 switcher_next(switcher);
5285 switcher_destroy(struct switcher *switcher)
5287 struct weston_view *view;
5288 struct weston_keyboard *keyboard = switcher->grab.keyboard;
5289 struct workspace *ws = get_current_workspace(switcher->shell);
5291 wl_list_for_each(view, &ws->layer.view_list, layer_link) {
5292 if (is_focus_view(view))
5296 weston_surface_damage(view->surface);
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;
5310 switcher_key(struct weston_keyboard_grab *grab,
5311 uint32_t time, uint32_t key, uint32_t state_w)
5313 struct switcher *switcher = container_of(grab, struct switcher, grab);
5314 enum wl_keyboard_key_state state = state_w;
5316 if (key == KEY_TAB && state == WL_KEYBOARD_KEY_STATE_PRESSED)
5317 switcher_next(switcher);
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)
5325 struct switcher *switcher = container_of(grab, struct switcher, grab);
5326 struct weston_seat *seat = (struct weston_seat *) grab->keyboard->seat;
5328 if ((seat->modifier_state & switcher->shell->binding_modifier) == 0)
5329 switcher_destroy(switcher);
5333 switcher_cancel(struct weston_keyboard_grab *grab)
5335 struct switcher *switcher = container_of(grab, struct switcher, grab);
5337 switcher_destroy(switcher);
5340 static const struct weston_keyboard_grab_interface switcher_grab = {
5347 switcher_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
5350 struct desktop_shell *shell = data;
5351 struct switcher *switcher;
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);
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);
5368 backlight_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
5371 struct weston_compositor *compositor = data;
5372 struct weston_output *output;
5373 long backlight_new = 0;
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
5379 output = get_default_output(compositor);
5383 if (!output->set_backlight)
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;
5391 if (backlight_new < 5)
5393 if (backlight_new > 255)
5394 backlight_new = 255;
5396 output->backlight_current = backlight_new;
5397 output->set_backlight(output, output->backlight_current);
5400 struct debug_binding_grab {
5401 struct weston_keyboard_grab grab;
5402 struct weston_seat *seat;
5404 int key_released[2];
5408 debug_binding_key(struct weston_keyboard_grab *grab, uint32_t time,
5409 uint32_t key, uint32_t state)
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;
5416 int send = 0, terminate = 0;
5417 int check_binding = 1;
5419 struct wl_list *resource_list;
5421 if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
5422 /* Do not run bindings on key releases */
5425 for (i = 0; i < 2; i++)
5426 if (key == db->key[i])
5427 db->key_released[i] = 1;
5429 if (db->key_released[0] && db->key_released[1]) {
5430 /* All key releases been swalled so end the grab */
5432 } else if (key != db->key[0] && key != db->key[1]) {
5433 /* Should not swallow release of other keys */
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. */
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. */
5449 if (check_binding) {
5450 if (weston_compositor_run_debug_binding(ec, db->seat, time,
5452 /* We ran a binding so swallow the press and keep the
5453 * grab to swallow the released too. */
5458 /* Terminate the grab since the key pressed is not a
5459 * debug binding key. */
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);
5474 weston_keyboard_end_grab(grab->keyboard);
5475 if (grab->keyboard->input_method_resource)
5476 grab->keyboard->grab = &grab->keyboard->input_method_grab;
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)
5486 struct wl_resource *resource;
5487 struct wl_list *resource_list;
5489 resource_list = &grab->keyboard->focus_resource_list;
5491 wl_resource_for_each(resource, resource_list) {
5492 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
5493 mods_latched, mods_locked, group);
5498 debug_binding_cancel(struct weston_keyboard_grab *grab)
5500 struct debug_binding_grab *db = (struct debug_binding_grab *) grab;
5502 weston_keyboard_end_grab(grab->keyboard);
5506 struct weston_keyboard_grab_interface debug_binding_keyboard_grab = {
5508 debug_binding_modifiers,
5509 debug_binding_cancel,
5513 debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
5515 struct debug_binding_grab *grab;
5517 grab = calloc(1, sizeof *grab);
5521 grab->seat = (struct weston_seat *) seat;
5523 grab->grab.interface = &debug_binding_keyboard_grab;
5524 weston_keyboard_start_grab(seat->keyboard, &grab->grab);
5528 force_kill_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
5531 struct weston_surface *focus_surface;
5532 struct wl_client *client;
5533 struct desktop_shell *shell = data;
5534 struct weston_compositor *compositor = shell->compositor;
5537 focus_surface = seat->keyboard->focus;
5541 wl_signal_emit(&compositor->kill_signal, focus_surface);
5543 client = wl_resource_get_client(focus_surface->resource);
5544 wl_client_get_credentials(client, &pid, NULL, NULL);
5546 /* Skip clients that we launched ourselves (the credentials of
5547 * the socketpair is ours) */
5548 if (pid == getpid())
5555 workspace_up_binding(struct weston_seat *seat, uint32_t time,
5556 uint32_t key, void *data)
5558 struct desktop_shell *shell = data;
5559 unsigned int new_index = shell->workspaces.current;
5566 change_workspace(shell, new_index);
5570 workspace_down_binding(struct weston_seat *seat, uint32_t time,
5571 uint32_t key, void *data)
5573 struct desktop_shell *shell = data;
5574 unsigned int new_index = shell->workspaces.current;
5578 if (new_index < shell->workspaces.num - 1)
5581 change_workspace(shell, new_index);
5585 workspace_f_binding(struct weston_seat *seat, uint32_t time,
5586 uint32_t key, void *data)
5588 struct desktop_shell *shell = data;
5589 unsigned int new_index;
5593 new_index = key - KEY_F1;
5594 if (new_index >= shell->workspaces.num)
5595 new_index = shell->workspaces.num - 1;
5597 change_workspace(shell, new_index);
5601 workspace_move_surface_up_binding(struct weston_seat *seat, uint32_t time,
5602 uint32_t key, void *data)
5604 struct desktop_shell *shell = data;
5605 unsigned int new_index = shell->workspaces.current;
5613 take_surface_to_workspace_by_seat(shell, seat, new_index);
5617 workspace_move_surface_down_binding(struct weston_seat *seat, uint32_t time,
5618 uint32_t key, void *data)
5620 struct desktop_shell *shell = data;
5621 unsigned int new_index = shell->workspaces.current;
5626 if (new_index < shell->workspaces.num - 1)
5629 take_surface_to_workspace_by_seat(shell, seat, new_index);
5633 handle_output_destroy(struct wl_listener *listener, void *data)
5635 struct shell_output *output_listener =
5636 container_of(listener, struct shell_output, destroy_listener);
5638 wl_list_remove(&output_listener->destroy_listener.link);
5639 wl_list_remove(&output_listener->link);
5640 free(output_listener);
5644 create_shell_output(struct desktop_shell *shell,
5645 struct weston_output *output)
5647 struct shell_output *shell_output;
5649 shell_output = zalloc(sizeof *shell_output);
5650 if (shell_output == NULL)
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);
5662 handle_output_create(struct wl_listener *listener, void *data)
5664 struct desktop_shell *shell =
5665 container_of(listener, struct desktop_shell, output_create_listener);
5666 struct weston_output *output = (struct weston_output *)data;
5668 create_shell_output(shell, output);
5672 setup_output_destroy_handler(struct weston_compositor *ec,
5673 struct desktop_shell *shell)
5675 struct weston_output *output;
5677 wl_list_init(&shell->output_list);
5678 wl_list_for_each(output, &ec->output_list, link)
5679 create_shell_output(shell, output);
5681 shell->output_create_listener.notify = handle_output_create;
5682 wl_signal_add(&ec->output_created_signal,
5683 &shell->output_create_listener);
5687 shell_destroy(struct wl_listener *listener, void *data)
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;
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);
5699 wl_list_remove(&shell->idle_listener.link);
5700 wl_list_remove(&shell->wake_listener.link);
5702 input_panel_destroy(shell);
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);
5710 wl_list_remove(&shell->output_create_listener.link);
5712 wl_array_for_each(ws, &shell->workspaces.array)
5713 workspace_destroy(*ws);
5714 wl_array_release(&shell->workspaces.array);
5716 free(shell->screensaver.path);
5717 free(shell->client);
5722 shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
5725 int i, num_workspace_bindings;
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,
5734 weston_compositor_add_touch_binding(ec, 0,
5735 touch_to_activate_binding,
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,
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,
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);
5763 if (ec->capabilities & WESTON_CAP_ROTATION_ANY)
5764 weston_compositor_add_button_binding(ec, BTN_RIGHT, mod,
5765 rotate_binding, NULL);
5767 weston_compositor_add_key_binding(ec, KEY_TAB, mod, switcher_binding,
5769 weston_compositor_add_key_binding(ec, KEY_F9, mod, backlight_binding,
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,
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,
5786 weston_compositor_add_key_binding(ec, KEY_DOWN, mod | MODIFIER_SHIFT,
5787 workspace_move_surface_down_binding,
5790 if (shell->exposay_modifier)
5791 weston_compositor_add_modifier_binding(ec, shell->exposay_modifier,
5792 exposay_binding, shell);
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,
5805 /* Debug bindings */
5806 weston_compositor_add_key_binding(ec, KEY_SPACE, mod | MODIFIER_SHIFT,
5807 debug_binding, shell);
5811 module_init(struct weston_compositor *ec,
5812 int *argc, char *argv[])
5814 struct weston_seat *seat;
5815 struct desktop_shell *shell;
5816 struct workspace **pws;
5818 struct wl_event_loop *loop;
5820 shell = zalloc(sizeof *shell);
5824 /* save shell management table for other plugin */
5825 _ico_ivi_shell = shell;
5827 shell->compositor = ec;
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);
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;
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);
5854 wl_array_init(&shell->workspaces.array);
5855 wl_list_init(&shell->workspaces.client_list);
5857 if (input_panel_setup(shell) < 0)
5860 shell_configuration(shell);
5862 shell->exposay.state_cur = EXPOSAY_LAYOUT_INACTIVE;
5863 shell->exposay.state_target = EXPOSAY_TARGET_CANCEL;
5865 for (i = 0; i < shell->workspaces.num; i++) {
5866 pws = wl_array_add(&shell->workspaces.array, sizeof *pws);
5870 *pws = workspace_create();
5874 activate_workspace(shell, 0);
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;
5880 if (wl_global_create(ec->wl_display, &wl_shell_interface, 1,
5881 shell, bind_shell) == NULL)
5884 if (wl_global_create(ec->wl_display, &xdg_shell_interface, 1,
5885 shell, bind_xdg_shell) == NULL)
5888 if (wl_global_create(ec->wl_display,
5889 &desktop_shell_interface, 2,
5890 shell, bind_desktop_shell) == NULL)
5893 if (wl_global_create(ec->wl_display, &screensaver_interface, 1,
5894 shell, bind_screensaver) == NULL)
5897 if (wl_global_create(ec->wl_display, &workspace_manager_interface, 1,
5898 shell, bind_workspace_manager) == NULL)
5901 shell->child.deathstamp = weston_compositor_get_time();
5903 setup_output_destroy_handler(ec, shell);
5905 loop = wl_display_get_event_loop(ec->wl_display);
5906 wl_event_loop_add_idle(loop, launch_desktop_shell_process, shell);
5908 shell->screensaver.timer =
5909 wl_event_loop_add_timer(loop, screensaver_timeout, shell);
5911 wl_list_for_each(seat, &ec->seat_list, link)
5912 create_pointer_focus_listener(seat);
5914 shell_add_bindings(ec, shell);
5916 shell_fade_init(shell);
5921 /*--------------------------------------------------------------------------*/
5923 * @brief ico_ivi_shell_weston_layer: get weston layer
5926 * @return current weston layer
5927 * @retval !=NULL success(current weston layer)
5928 * @retval ==NULL error(no layer)
5930 /*--------------------------------------------------------------------------*/
5931 /* API for other plugin */
5932 WL_EXPORT struct weston_layer *
5933 ico_ivi_shell_weston_layer(void)
5935 return(&_ico_ivi_shell->panel_layer);
5938 /*--------------------------------------------------------------------------*/
5940 * @brief ico_ivi_shell_set_toplevel: set surface to TopLevel
5942 * @param[in] shsurf shell surface
5945 /*--------------------------------------------------------------------------*/
5947 ico_ivi_shell_set_toplevel(struct shell_surface *shsurf)
5949 set_toplevel(shsurf);
5952 /*--------------------------------------------------------------------------*/
5954 * @brief ico_ivi_shell_get_surfacetype: get surface type
5956 * @param[in] shsurf shell surface
5957 * @return surface type
5959 /*--------------------------------------------------------------------------*/
5961 ico_ivi_shell_get_surfacetype(struct shell_surface *shsurf)
5963 return (shsurf ? (int)shsurf->type : -1);
5966 /*--------------------------------------------------------------------------*/
5968 * @brief ico_ivi_shell_set_surface_type: set surface type
5970 * @param[in] shsurf shell surface
5973 /*--------------------------------------------------------------------------*/
5975 ico_ivi_shell_set_surface_type(struct shell_surface *shsurf)
5977 set_surface_type(shsurf);
5980 /*--------------------------------------------------------------------------*/
5982 * @brief ico_ivi_shell_send_configure: send configure event to client application
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
5990 /*--------------------------------------------------------------------------*/
5992 ico_ivi_shell_send_configure(struct weston_surface *surface,
5993 const uint32_t edges, const int width, const int height)
5995 send_configure(surface, edges, width, height);
5998 /*--------------------------------------------------------------------------*/
6000 * @brief ico_ivi_shell_startup: start shell surface fade
6002 * @param[in] shell shell table address
6005 /*--------------------------------------------------------------------------*/
6007 ico_ivi_shell_startup(void *shell)
6009 shell_fade_startup((struct desktop_shell *)shell);
6012 /*--------------------------------------------------------------------------*/
6014 * @brief ico_ivi_shell_layertype: get layer type
6016 * @param[in] surface weston surface
6017 * @return layer type
6019 /*--------------------------------------------------------------------------*/
6021 ico_ivi_shell_layertype(struct weston_surface *surface)
6023 if (surface->configure == shell_surface_configure) {
6024 return ((struct shell_surface *)surface->configure_private)->layertype;
6026 return LAYER_TYPE_UNKNOWN;
6029 /*--------------------------------------------------------------------------*/
6031 * @brief ivi_shell_set_default_display: set default display
6033 * @param[in] inputpanel default display of input panel surface
6036 /*--------------------------------------------------------------------------*/
6038 ivi_shell_set_default_display(struct weston_output *inputpanel)
6040 default_inputpanel = inputpanel;
6043 /*--------------------------------------------------------------------------*/
6045 * @brief ico_ivi_shell_hook_bind: regist hook function for shell bind
6047 * @param[in] hook_bind hook function(if NULL, reset hook function)
6050 /*--------------------------------------------------------------------------*/
6052 ico_ivi_shell_hook_bind(void (*hook_bind)(struct wl_client *client, void *shell))
6054 shell_hook_bind = hook_bind;
6057 /*--------------------------------------------------------------------------*/
6059 * @brief ico_ivi_shell_hook_unbind: regist hook function for shell unbind
6061 * @param[in] hook_unbind hook function(if NULL, reset hook function)
6064 /*--------------------------------------------------------------------------*/
6066 ico_ivi_shell_hook_unbind(void (*hook_unbind)(struct wl_client *client))
6068 shell_hook_unbind = hook_unbind;
6071 /*--------------------------------------------------------------------------*/
6073 * @brief ico_ivi_shell_hook_create: regist hook function for create shell surface
6075 * @param[in] hook_create hook function(if NULL, reset hook function)
6078 /*--------------------------------------------------------------------------*/
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))
6085 shell_hook_create = hook_create;
6088 /*--------------------------------------------------------------------------*/
6090 * @brief ico_ivi_shell_hook_destroy: regist hook function for destroy shell surface
6092 * @param[in] hook_destroy hook function(if NULL, reset hook function)
6095 /*--------------------------------------------------------------------------*/
6097 ico_ivi_shell_hook_destroy(void (*hook_destroy)(struct weston_surface *surface))
6099 shell_hook_destroy = hook_destroy;
6102 /*--------------------------------------------------------------------------*/
6104 * @brief ico_ivi_shell_hook_map: regist hook function for map shell surface
6106 * @param[in] hook_map hook function(if NULL, reset hook function)
6109 /*--------------------------------------------------------------------------*/
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))
6115 shell_hook_map = hook_map;
6118 /*--------------------------------------------------------------------------*/
6120 * @brief ico_ivi_shell_hook_configure: regist hook function for configure shell surface
6122 * @param[in] hook_configure hook function(if NULL, reset hook function)
6125 /*--------------------------------------------------------------------------*/
6127 ico_ivi_shell_hook_configure(void (*hook_configure)(struct weston_surface *surface))
6129 shell_hook_configure = hook_configure;
6132 /*--------------------------------------------------------------------------*/
6134 * @brief ico_ivi_shell_hook_select: regist hook function for select(active) shell surface
6136 * @param[in] hook_select hook function(if NULL, reset hook function)
6139 /*--------------------------------------------------------------------------*/
6141 ico_ivi_shell_hook_select(void (*hook_select)(struct weston_surface *surface))
6143 shell_hook_select = hook_select;
6146 /*--------------------------------------------------------------------------*/
6148 * @brief ico_ivi_shell_hook_title: regist hook function for select(active) shell surface
6150 * @param[in] hook_title hook function(if NULL, reset hook function)
6153 /*--------------------------------------------------------------------------*/
6155 ico_ivi_shell_hook_title(char *(*hook_title)(struct weston_surface *surface,
6158 shell_hook_title = hook_title;
6161 /*--------------------------------------------------------------------------*/
6163 * @brief ico_ivi_shell_hook_move: regist hook function for move grab
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
6170 /*--------------------------------------------------------------------------*/
6172 ico_ivi_shell_hook_move(void (*hook_move)(struct weston_surface *surface, int *dx, int *dy))
6174 shell_hook_move = hook_move;
6177 /*--------------------------------------------------------------------------*/
6179 * @brief ico_ivi_shell_hook_show_layer: layer visible control
6181 * @param[in] hook_show hook function(if NULL, reset hook function)
6184 /*--------------------------------------------------------------------------*/
6186 ico_ivi_shell_hook_show_layer(void (*hook_show)(int layertype, int show, void *data))
6188 shell_hook_show_layer = hook_show;
6191 /*--------------------------------------------------------------------------*/
6193 * @brief ico_ivi_shell_hook_fullscreen: fullscreen surface control
6195 * @param[in] hook_fullscreen hook function(if NULL, reset hook function)
6198 /*--------------------------------------------------------------------------*/
6200 ico_ivi_shell_hook_fullscreen(int (*hook_fullscreen)
6201 (int event, struct weston_surface *surface))
6203 shell_hook_fullscreen = hook_fullscreen;