input: Fix minor issue while reporting disable cursor
[src/agl-compositor.git] / src / shell.c
1 /*
2  * Copyright © 2019 Collabora, Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial
14  * portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25
26 #include "ivi-compositor.h"
27 #include "policy.h"
28
29 #include <assert.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <signal.h>
33 #include <string.h>
34 #include <sys/socket.h>
35 #include <sys/types.h>
36 #include <unistd.h>
37 #include <libweston/libweston.h>
38 #include <libweston/config-parser.h>
39
40 #include "shared/os-compatibility.h"
41
42 #include "agl-shell-server-protocol.h"
43 #include "agl-shell-desktop-server-protocol.h"
44
45 #ifdef HAVE_WALTHAM
46 #include <waltham-transmitter/transmitter_api.h>
47 #endif
48
49 static void
50 create_black_surface_view(struct ivi_output *output);
51
52 void
53 agl_shell_desktop_advertise_application_id(struct ivi_compositor *ivi,
54                                            struct ivi_surface *surface)
55 {
56         struct desktop_client *dclient;
57         static bool display_adv = false;
58
59         if (surface->advertised_on_launch)
60                 return;
61
62         /* advertise to all desktop clients the new surface */
63         wl_list_for_each(dclient, &ivi->desktop_clients, link) {
64                 const char *app_id =
65                         weston_desktop_surface_get_app_id(surface->dsurface);
66                 if (app_id == NULL) {
67                         if (!display_adv) {
68                                 weston_log("WARNING app_is is null, unable to advertise\n");
69                                 display_adv = true;
70                         }
71                         return;
72                 }
73                 agl_shell_desktop_send_application(dclient->resource, app_id);
74                 surface->advertised_on_launch = true;
75         }
76 }
77
78 void
79 ivi_set_desktop_surface(struct ivi_surface *surface)
80 {
81         struct ivi_compositor *ivi = surface->ivi;
82         assert(surface->role == IVI_SURFACE_ROLE_NONE);
83
84         surface->role = IVI_SURFACE_ROLE_DESKTOP;
85         wl_list_insert(&surface->ivi->surfaces, &surface->link);
86
87         agl_shell_desktop_advertise_application_id(ivi, surface);
88 }
89
90 static void
91 ivi_set_background_surface(struct ivi_surface *surface)
92 {
93         struct ivi_compositor *ivi = surface->ivi;
94         assert(surface->role == IVI_SURFACE_ROLE_BACKGROUND);
95
96         wl_list_insert(&surface->ivi->surfaces, &surface->link);
97         agl_shell_desktop_advertise_application_id(ivi, surface);
98 }
99
100 static void
101 ivi_set_desktop_surface_popup(struct ivi_surface *surface)
102 {
103         struct ivi_compositor *ivi = surface->ivi;
104         assert(surface->role == IVI_SURFACE_ROLE_NONE);
105
106         surface->role = IVI_SURFACE_ROLE_POPUP;
107         wl_list_insert(&ivi->surfaces, &surface->link);
108
109         agl_shell_desktop_advertise_application_id(ivi, surface);
110 }
111
112 static void
113 ivi_set_desktop_surface_fullscreen(struct ivi_surface *surface)
114 {
115         struct ivi_compositor *ivi = surface->ivi;
116         assert(surface->role == IVI_SURFACE_ROLE_NONE);
117
118         surface->role = IVI_SURFACE_ROLE_FULLSCREEN;
119         wl_list_insert(&ivi->surfaces, &surface->link);
120
121         agl_shell_desktop_advertise_application_id(ivi, surface);
122 }
123
124 #ifdef HAVE_WALTHAM
125 void
126 ivi_destroy_waltham_destroy(struct ivi_surface *surface)
127 {
128         struct ivi_compositor *ivi = surface->ivi;
129         const struct weston_transmitter_api *api =
130                 ivi->waltham_transmitter_api;
131
132         if (!api)
133                 return;
134
135         if (surface->waltham_surface.transmitter_surface)
136                 api->surface_destroy(surface->waltham_surface.transmitter_surface);
137 }
138
139 static void
140 ivi_output_notify_waltham_plugin(struct ivi_surface *surface)
141 {
142         struct ivi_compositor *ivi = surface->ivi;
143         const struct weston_transmitter_api *api = ivi->waltham_transmitter_api;
144         struct weston_transmitter *transmitter;
145         struct weston_transmitter_remote *trans_remote;
146         struct weston_surface *weston_surface;
147         struct weston_output *woutput = surface->remote.output->output;
148         const char *app_id;
149
150         if (!api)
151                 return;
152
153         transmitter = api->transmitter_get(ivi->compositor);
154         if (!transmitter)
155                 return;
156
157         trans_remote = api->get_transmitter_remote(woutput->name, transmitter);
158         if (!trans_remote) {
159                 weston_log("Could not find a valie weston_transmitter_remote "
160                                 "that matches the output %s\n", woutput->name);
161                 return;
162         }
163
164         app_id = weston_desktop_surface_get_app_id(surface->dsurface);
165         weston_surface =
166                 weston_desktop_surface_get_surface(surface->dsurface);
167
168         weston_log("Forwarding app_id %s to remote %s\n", app_id, woutput->name);
169
170         /* this will have the effect of informing the remote side to create a
171          * surface with the name app_id. W/ xdg-shell the following happens:
172          *
173          * compositor (server):
174          * surface_push_to_remote():
175          *      waltham-transmitter plug-in
176          *              -> wthp_ivi_app_id_surface_create()
177          *
178          * client -- on the receiver side:
179          *      -> wthp_ivi_app_id_surface_create()
180          *              -> wth_receiver_weston_main()
181          *                      -> wl_compositor_create_surface()
182          *                      -> xdg_wm_base_get_xdg_surface
183          *                      -> xdg_toplevel_set_app_id()
184          *                      -> gst_init()
185          *                      -> gst_parse_launch()
186          *
187          * wth_receiver_weston_main() will be invoked from the handler of
188          * wthp_ivi_app_id_surface_create() and is responsible for setting-up
189          * the gstreamer pipeline as well.
190          */
191         surface->waltham_surface.transmitter_surface =
192             api->surface_push_to_remote(weston_surface, app_id, trans_remote, NULL);
193 }
194
195 #else
196 void
197 ivi_destroy_waltham_destroy(struct ivi_surface *surface)
198 {
199 }
200 static void
201 ivi_output_notify_waltham_plugin(struct ivi_surface *surface)
202 {
203 }
204 #endif
205
206 static void
207 ivi_set_desktop_surface_remote(struct ivi_surface *surface)
208 {
209         struct ivi_compositor *ivi = surface->ivi;
210         struct weston_view *view;
211         struct ivi_output *output = surface->remote.output;
212
213         assert(surface->role == IVI_SURFACE_ROLE_NONE);
214
215         /* remote type are the same as desktop just that client can tell
216          * the compositor to start on another output */
217         surface->role = IVI_SURFACE_ROLE_REMOTE;
218
219         /* if thew black surface view is mapped on the mean we need
220          * to remove it in order to start showing the 'remote' surface
221          * just being added */
222         view = output->fullscreen_view.fs->view;
223         if (view->is_mapped || view->surface->is_mapped)
224                 remove_black_surface(output);
225
226         if (output->type == OUTPUT_WALTHAM)
227                 ivi_output_notify_waltham_plugin(surface);
228
229         wl_list_insert(&ivi->surfaces, &surface->link);
230 }
231
232
233 static void
234 ivi_set_desktop_surface_split(struct ivi_surface *surface)
235 {
236         struct ivi_compositor *ivi = surface->ivi;
237         assert(surface->role == IVI_SURFACE_ROLE_NONE);
238
239         if (surface->split.orientation == AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL)
240                 surface->role = IVI_SURFACE_ROLE_SPLIT_V;
241         else
242                 surface->role = IVI_SURFACE_ROLE_SPLIT_H;
243
244         wl_list_insert(&ivi->surfaces, &surface->link);
245
246         agl_shell_desktop_advertise_application_id(ivi, surface);
247 }
248
249 static struct pending_popup *
250 ivi_ensure_popup(struct ivi_output *ioutput, int x, int y, int bx, int by,
251                  int width, int height, const char *app_id)
252 {
253         struct pending_popup *p_popup = zalloc(sizeof(*p_popup));
254         size_t len_app_id = strlen(app_id);
255
256         if (!p_popup)
257                 return NULL;
258         p_popup->app_id = zalloc(sizeof(char) * (len_app_id + 1));
259         if (!p_popup->app_id) {
260                 free(p_popup);
261                 return NULL;
262         }
263         memcpy(p_popup->app_id, app_id, len_app_id);
264         p_popup->ioutput = ioutput;
265         p_popup->x = x;
266         p_popup->y = y;
267
268         p_popup->bb.x = bx;
269         p_popup->bb.y = by;
270         p_popup->bb.width = width;
271         p_popup->bb.height = height;
272
273         return p_popup;
274 }
275
276 static void
277 ivi_update_popup(struct ivi_output *ioutput, int x, int y, int bx, int by,
278                  int width, int height, const char *app_id, struct pending_popup *p_popup)
279 {
280         size_t len_app_id = strlen(app_id);
281
282         wl_list_remove(&p_popup->link);
283         wl_list_init(&p_popup->link);
284
285         memset(p_popup->app_id, 0, strlen(app_id) + 1);
286         free(p_popup->app_id);
287
288         p_popup->app_id = zalloc(sizeof(char) * (len_app_id + 1));
289         if (!p_popup->app_id)
290                 return;
291         memcpy(p_popup->app_id, app_id, len_app_id);
292
293         p_popup->ioutput = ioutput;
294         p_popup->x = x;
295         p_popup->y = y;
296
297         p_popup->bb.x = bx;
298         p_popup->bb.y = by;
299         p_popup->bb.width = width;
300         p_popup->bb.height = height;
301 }
302
303 static struct pending_fullscreen *
304 ivi_ensure_fullscreen(struct ivi_output *ioutput, const char *app_id)
305 {
306         struct pending_fullscreen *p_fullscreen = zalloc(sizeof(*p_fullscreen));
307         size_t len_app_id = strlen(app_id);
308
309         if (!p_fullscreen)
310                 return NULL;
311         p_fullscreen->app_id = zalloc(sizeof(char) * (len_app_id + 1));
312         if (!p_fullscreen->app_id) {
313                 free(p_fullscreen);
314                 return NULL;
315         }
316         memcpy(p_fullscreen->app_id, app_id, len_app_id);
317
318         p_fullscreen->ioutput = ioutput;
319         return p_fullscreen;
320 }
321
322 static void
323 ivi_update_fullscreen(struct ivi_output *ioutput, const char *app_id,
324                       struct pending_fullscreen *p_fullscreen)
325 {
326         size_t len_app_id = strlen(app_id);
327
328         wl_list_remove(&p_fullscreen->link);
329         wl_list_init(&p_fullscreen->link);
330
331         memset(p_fullscreen->app_id, 0, strlen(app_id) + 1);
332         free(p_fullscreen->app_id);
333
334         p_fullscreen->app_id = zalloc(sizeof(char) * (len_app_id + 1));
335         if (!p_fullscreen->app_id)
336                 return;
337         memcpy(p_fullscreen->app_id, app_id, len_app_id);
338
339         p_fullscreen->ioutput = ioutput;
340 }
341
342 static struct pending_remote *
343 ivi_ensure_remote(struct ivi_output *ioutput, const char *app_id)
344 {
345         struct pending_remote *p_remote = zalloc(sizeof(*p_remote));
346         size_t len_app_id = strlen(app_id);
347
348         if (!p_remote)
349                 return NULL;
350         p_remote->app_id = zalloc(sizeof(char) * (len_app_id + 1));
351         if (!p_remote->app_id) {
352                 free(p_remote);
353                 return NULL;
354         }
355         memcpy(p_remote->app_id, app_id, len_app_id);
356
357         p_remote->ioutput = ioutput;
358         return p_remote;
359 }
360
361 static void
362 ivi_update_remote(struct ivi_output *ioutput, const char *app_id,
363                       struct pending_remote *p_remote)
364 {
365         size_t len_app_id = strlen(app_id);
366
367         wl_list_remove(&p_remote->link);
368         wl_list_init(&p_remote->link);
369
370         memset(p_remote->app_id, 0, strlen(app_id) + 1);
371         free(p_remote->app_id);
372
373         p_remote->app_id = zalloc(sizeof(char) * (len_app_id + 1));
374         if (!p_remote->app_id)
375                 return;
376         memcpy(p_remote->app_id, app_id, len_app_id);
377
378         p_remote->ioutput = ioutput;
379 }
380
381 static void
382 ivi_set_pending_desktop_surface_popup(struct ivi_output *ioutput, int x, int y, int bx,
383                                       int by, int width, int height, const char *app_id)
384 {
385         struct ivi_compositor *ivi = ioutput->ivi;
386         struct pending_popup *p_popup = NULL;
387         struct pending_popup *popup;
388
389         wl_list_for_each(popup, &ivi->popup_pending_apps, link)
390                 if (!strcmp(app_id, popup->app_id))
391                         p_popup = popup;
392
393         if (!p_popup)
394                 p_popup = ivi_ensure_popup(ioutput, x, y, bx, by, width, height, app_id);
395         else
396                 ivi_update_popup(ioutput, x, y, bx, by, width, height, app_id, p_popup);
397         if (!p_popup)
398                 return;
399
400         wl_list_insert(&ivi->popup_pending_apps, &p_popup->link);
401 }
402
403 static void
404 ivi_set_pending_desktop_surface_fullscreen(struct ivi_output *ioutput,
405                                            const char *app_id)
406 {
407         struct ivi_compositor *ivi = ioutput->ivi;
408         struct pending_fullscreen *p_fullscreen = NULL;
409         struct pending_fullscreen *fullscreen;
410
411         wl_list_for_each(fullscreen, &ivi->fullscreen_pending_apps, link)
412                 if (!strcmp(app_id, fullscreen->app_id))
413                         p_fullscreen = fullscreen;
414
415         if (!p_fullscreen)
416                 p_fullscreen = ivi_ensure_fullscreen(ioutput, app_id);
417         else
418                 ivi_update_fullscreen(ioutput, app_id, p_fullscreen);
419
420         if (!p_fullscreen)
421                 return;
422         wl_list_insert(&ivi->fullscreen_pending_apps, &p_fullscreen->link);
423 }
424
425 static void
426 ivi_set_pending_desktop_surface_split(struct ivi_output *ioutput,
427                                       const char *app_id, uint32_t orientation)
428 {
429         struct ivi_compositor *ivi = ioutput->ivi;
430         struct ivi_surface *surf;
431         size_t len_app_id = strlen(app_id);
432         struct pending_split *split;
433
434         if (orientation != AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL &&
435             orientation != AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_HORIZONTAL)
436                 return;
437
438         /* more than one is un-supported, do note we need to do
439          * conversion for surface roles instead of using the protocol ones */
440         wl_list_for_each(surf, &ivi->surfaces, link)
441                 if (surf->role == IVI_SURFACE_ROLE_SPLIT_V ||
442                     surf->role == IVI_SURFACE_ROLE_SPLIT_H)
443                         return;
444
445         split = zalloc(sizeof(*split));
446         if (!split)
447                 return;
448         split->app_id = zalloc(sizeof(char) * (len_app_id + 1));
449         if (!split->app_id) {
450                 free(split);
451                 return;
452         }
453         memcpy(split->app_id, app_id, len_app_id);
454
455         split->ioutput = ioutput;
456         split->orientation = orientation;
457
458         wl_list_insert(&ivi->split_pending_apps, &split->link);
459 }
460
461 void
462 ivi_set_pending_desktop_surface_remote(struct ivi_output *ioutput,
463                 const char *app_id)
464 {
465         struct ivi_compositor *ivi = ioutput->ivi;
466         struct pending_remote *remote;
467         struct pending_remote *p_remote = NULL;
468
469         wl_list_for_each(remote, &ivi->remote_pending_apps, link)
470                 if (!strcmp(app_id, remote->app_id))
471                         p_remote = remote;
472
473         if (!p_remote)
474                 p_remote = ivi_ensure_remote(ioutput, app_id);
475         else
476                 ivi_update_remote(ioutput, app_id, p_remote);
477         if (!p_remote)
478                 return;
479
480         wl_list_insert(&ivi->remote_pending_apps, &p_remote->link);
481 }
482
483
484 static void
485 ivi_remove_pending_desktop_surface_split(struct pending_split *split)
486 {
487         free(split->app_id);
488         wl_list_remove(&split->link);
489         free(split);
490 }
491
492 static void
493 ivi_remove_pending_desktop_surface_fullscreen(struct pending_fullscreen *fs)
494 {
495         free(fs->app_id);
496         wl_list_remove(&fs->link);
497         free(fs);
498 }
499
500 static void
501 ivi_remove_pending_desktop_surface_popup(struct pending_popup *p_popup)
502 {
503         free(p_popup->app_id);
504         wl_list_remove(&p_popup->link);
505         free(p_popup);
506 }
507
508 static void
509 ivi_remove_pending_desktop_surface_remote(struct pending_remote *remote)
510 {
511         free(remote->app_id);
512         wl_list_remove(&remote->link);
513         free(remote);
514 }
515
516 static bool
517 ivi_compositor_keep_pending_surfaces(struct ivi_surface *surface)
518 {
519         return surface->ivi->keep_pending_surfaces;
520 }
521
522 static bool
523 ivi_check_pending_desktop_surface_popup(struct ivi_surface *surface)
524 {
525         struct ivi_compositor *ivi = surface->ivi;
526         struct pending_popup *p_popup, *next_p_popup;
527         const char *_app_id =
528                         weston_desktop_surface_get_app_id(surface->dsurface);
529
530         if (wl_list_empty(&ivi->popup_pending_apps) || !_app_id)
531                 return false;
532
533         wl_list_for_each_safe(p_popup, next_p_popup,
534                               &ivi->popup_pending_apps, link) {
535                 if (!strcmp(_app_id, p_popup->app_id)) {
536                         surface->popup.output = p_popup->ioutput;
537                         surface->popup.x = p_popup->x;
538                         surface->popup.y = p_popup->y;
539
540                         surface->popup.bb.x = p_popup->bb.x;
541                         surface->popup.bb.y = p_popup->bb.y;
542                         surface->popup.bb.width = p_popup->bb.width;
543                         surface->popup.bb.height = p_popup->bb.height;
544
545                         if (!ivi_compositor_keep_pending_surfaces(surface))
546                                 ivi_remove_pending_desktop_surface_popup(p_popup);
547                         return true;
548                 }
549         }
550
551         return false;
552 }
553
554 static bool
555 ivi_check_pending_desktop_surface_split(struct ivi_surface *surface)
556 {
557         struct pending_split *split_surf, *next_split_surf;
558         struct ivi_compositor *ivi = surface->ivi;
559         const char *_app_id =
560                         weston_desktop_surface_get_app_id(surface->dsurface);
561
562         if (wl_list_empty(&ivi->split_pending_apps) || !_app_id)
563                 return false;
564
565         wl_list_for_each_safe(split_surf, next_split_surf,
566                               &ivi->split_pending_apps, link) {
567                 if (!strcmp(_app_id, split_surf->app_id)) {
568                         surface->split.output = split_surf->ioutput;
569                         surface->split.orientation = split_surf->orientation;
570                         if (!ivi_compositor_keep_pending_surfaces(surface))
571                                 ivi_remove_pending_desktop_surface_split(split_surf);
572                         return true;
573                 }
574         }
575
576         return false;
577 }
578
579 static bool
580 ivi_check_pending_desktop_surface_fullscreen(struct ivi_surface *surface)
581 {
582         struct pending_fullscreen *fs_surf, *next_fs_surf;
583         struct ivi_compositor *ivi = surface->ivi;
584         const char *_app_id =
585                         weston_desktop_surface_get_app_id(surface->dsurface);
586
587         if (wl_list_empty(&ivi->fullscreen_pending_apps) || !_app_id)
588                 return false;
589
590         wl_list_for_each_safe(fs_surf, next_fs_surf,
591                               &ivi->fullscreen_pending_apps, link) {
592                 if (!strcmp(_app_id, fs_surf->app_id)) {
593                         surface->fullscreen.output = fs_surf->ioutput;
594                         if (!ivi_compositor_keep_pending_surfaces(surface))
595                                 ivi_remove_pending_desktop_surface_fullscreen(fs_surf);
596                         return true;
597                 }
598         }
599
600         return false;
601 }
602
603 static bool
604 ivi_check_pending_desktop_surface_remote(struct ivi_surface *surface)
605 {
606         struct pending_remote *remote_surf, *next_remote_surf;
607         struct ivi_compositor *ivi = surface->ivi;
608         const char *_app_id =
609                 weston_desktop_surface_get_app_id(surface->dsurface);
610
611         if (wl_list_empty(&ivi->remote_pending_apps) || !_app_id)
612                 return false;
613
614         wl_list_for_each_safe(remote_surf, next_remote_surf,
615                               &ivi->remote_pending_apps, link) {
616                 if (!strcmp(_app_id, remote_surf->app_id)) {
617                         surface->remote.output = remote_surf->ioutput;
618                         if (!ivi_compositor_keep_pending_surfaces(surface))
619                                 ivi_remove_pending_desktop_surface_remote(remote_surf);
620                         return true;
621                 }
622         }
623
624         return false;
625 }
626 void
627 ivi_check_pending_surface_desktop(struct ivi_surface *surface,
628                                   enum ivi_surface_role *role)
629 {
630         struct ivi_compositor *ivi = surface->ivi;
631         struct wl_list *role_pending_list;
632         struct pending_popup *p_popup;
633         struct pending_split *p_split;
634         struct pending_fullscreen *p_fullscreen;
635         struct pending_remote *p_remote;
636         const char *app_id =
637                 weston_desktop_surface_get_app_id(surface->dsurface);
638
639         role_pending_list = &ivi->popup_pending_apps;
640         wl_list_for_each(p_popup, role_pending_list, link) {
641                 if (app_id && !strcmp(app_id, p_popup->app_id)) {
642                         *role = IVI_SURFACE_ROLE_POPUP;
643                         return;
644                 }
645         }
646
647         role_pending_list = &ivi->split_pending_apps;
648         wl_list_for_each(p_split, role_pending_list, link) {
649                 if (app_id && !strcmp(app_id, p_split->app_id)) {
650                         *role = IVI_SURFACE_ROLE_SPLIT_V;
651                         return;
652                 }
653         }
654
655         role_pending_list = &ivi->fullscreen_pending_apps;
656         wl_list_for_each(p_fullscreen, role_pending_list, link) {
657                 if (app_id && !strcmp(app_id, p_fullscreen->app_id)) {
658                         *role = IVI_SURFACE_ROLE_FULLSCREEN;
659                         return;
660                 }
661         }
662
663         role_pending_list = &ivi->remote_pending_apps;
664         wl_list_for_each(p_remote, role_pending_list, link) {
665                 if (app_id && !strcmp(app_id, p_remote->app_id)) {
666                         *role = IVI_SURFACE_ROLE_REMOTE;
667                         return;
668                 }
669         }
670
671         /* else, we are a regular desktop surface */
672         *role = IVI_SURFACE_ROLE_DESKTOP;
673 }
674
675
676 void
677 ivi_check_pending_desktop_surface(struct ivi_surface *surface)
678 {
679         bool ret = false;
680
681         ret = ivi_check_pending_desktop_surface_popup(surface);
682         if (ret) {
683                 ivi_set_desktop_surface_popup(surface);
684                 ivi_layout_popup_committed(surface);
685                 return;
686         }
687
688         ret = ivi_check_pending_desktop_surface_split(surface);
689         if (ret) {
690                 ivi_set_desktop_surface_split(surface);
691                 ivi_layout_split_committed(surface);
692                 return;
693         }
694
695         ret = ivi_check_pending_desktop_surface_fullscreen(surface);
696         if (ret) {
697                 ivi_set_desktop_surface_fullscreen(surface);
698                 ivi_layout_fullscreen_committed(surface);
699                 return;
700         }
701
702         ret = ivi_check_pending_desktop_surface_remote(surface);
703         if (ret) {
704                 ivi_set_desktop_surface_remote(surface);
705                 ivi_layout_desktop_committed(surface);
706                 return;
707         }
708
709         /* if we end up here means we have a regular desktop app and
710          * try to activate it */
711         ivi_set_desktop_surface(surface);
712         ivi_layout_desktop_committed(surface);
713 }
714
715 void
716 ivi_shell_init_black_fs(struct ivi_compositor *ivi)
717 {
718         struct ivi_output *out;
719
720         wl_list_for_each(out, &ivi->outputs, link) {
721                 create_black_surface_view(out);
722                 insert_black_surface(out);
723         }
724 }
725
726 int
727 ivi_shell_init(struct ivi_compositor *ivi)
728 {
729         weston_layer_init(&ivi->hidden, ivi->compositor);
730         weston_layer_init(&ivi->background, ivi->compositor);
731         weston_layer_init(&ivi->normal, ivi->compositor);
732         weston_layer_init(&ivi->panel, ivi->compositor);
733         weston_layer_init(&ivi->popup, ivi->compositor);
734         weston_layer_init(&ivi->fullscreen, ivi->compositor);
735
736         weston_layer_set_position(&ivi->hidden,
737                                   WESTON_LAYER_POSITION_HIDDEN);
738         weston_layer_set_position(&ivi->background,
739                                   WESTON_LAYER_POSITION_BACKGROUND);
740         weston_layer_set_position(&ivi->normal,
741                                   WESTON_LAYER_POSITION_NORMAL);
742         weston_layer_set_position(&ivi->panel,
743                                   WESTON_LAYER_POSITION_UI);
744         weston_layer_set_position(&ivi->popup,
745                                   WESTON_LAYER_POSITION_TOP_UI);
746         weston_layer_set_position(&ivi->fullscreen,
747                                   WESTON_LAYER_POSITION_FULLSCREEN);
748
749         return 0;
750 }
751
752
753 static void
754 ivi_surf_destroy(struct ivi_surface *surf)
755 {
756         struct weston_surface *wsurface = surf->view->surface;
757
758         if (weston_surface_is_mapped(wsurface)) {
759                 weston_desktop_surface_unlink_view(surf->view);
760                 weston_view_destroy(surf->view);
761         }
762
763         wl_list_remove(&surf->link);
764         free(surf);
765 }
766
767 static void
768 ivi_shell_destroy_views_on_layer(struct weston_layer *layer)
769 {
770         struct weston_view *view, *view_next;
771
772         wl_list_for_each_safe(view, view_next, &layer->view_list.link, layer_link.link) {
773                 struct ivi_surface *ivi_surf =
774                         get_ivi_shell_surface(view->surface);
775                 if (ivi_surf)
776                         ivi_surf_destroy(ivi_surf);
777         }
778 }
779
780 void
781 ivi_shell_finalize(struct ivi_compositor *ivi)
782 {
783         struct ivi_output *output;
784
785         ivi_shell_destroy_views_on_layer(&ivi->hidden);
786         weston_layer_fini(&ivi->hidden);
787
788         ivi_shell_destroy_views_on_layer(&ivi->background);
789         weston_layer_fini(&ivi->background);
790
791         ivi_shell_destroy_views_on_layer(&ivi->normal);
792         weston_layer_fini(&ivi->normal);
793
794         ivi_shell_destroy_views_on_layer(&ivi->panel);
795         weston_layer_fini(&ivi->panel);
796
797         ivi_shell_destroy_views_on_layer(&ivi->popup);
798         weston_layer_fini(&ivi->popup);
799
800         wl_list_for_each(output, &ivi->outputs, link) {
801                 if (output->fullscreen_view.fs->view) {
802                         weston_surface_destroy(output->fullscreen_view.fs->view->surface);
803                         output->fullscreen_view.fs->view = NULL;
804                 }
805         }
806         weston_layer_fini(&ivi->fullscreen);
807 }
808
809 static void
810 ivi_shell_advertise_xdg_surfaces(struct ivi_compositor *ivi, struct wl_resource *resource)
811 {
812         struct ivi_surface *surface;
813
814         wl_list_for_each(surface, &ivi->surfaces, link) {
815                 const char *app_id =
816                         weston_desktop_surface_get_app_id(surface->dsurface);
817                 if (app_id == NULL) {
818                         weston_log("WARNING app_is is null, unable to advertise\n");
819                         return;
820                 }
821                 agl_shell_desktop_send_application(resource, app_id);
822         }
823 }
824
825 static void
826 client_exec(const char *command, int fd)
827 {
828         sigset_t sig;
829         char s[32];
830
831         /* Don't give the child our signal mask */
832         sigfillset(&sig);
833         sigprocmask(SIG_UNBLOCK, &sig, NULL);
834
835         /* Launch clients as the user; don't give them the wrong euid */
836         if (seteuid(getuid()) == -1) {
837                 weston_log("seteuid failed: %s\n", strerror(errno));
838                 return;
839         }
840
841         /* Duplicate fd to unset the CLOEXEC flag. We don't need to worry about
842          * clobbering fd, as we'll exit/exec either way.
843          */
844         fd = dup(fd);
845         if (fd == -1) {
846                 weston_log("dup failed: %s\n", strerror(errno));
847                 return;
848         }
849
850         snprintf(s, sizeof s, "%d", fd);
851         setenv("WAYLAND_SOCKET", s, 1);
852
853         execl("/bin/sh", "/bin/sh", "-c", command, NULL);
854         weston_log("executing '%s' failed: %s", command, strerror(errno));
855 }
856
857 static struct wl_client *
858 launch_shell_client(struct ivi_compositor *ivi, const char *command)
859 {
860         struct wl_client *client;
861         int sock[2];
862         pid_t pid;
863
864         weston_log("launching' %s'\n", command);
865
866         if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sock) < 0) {
867                 weston_log("socketpair failed while launching '%s': %s\n",
868                            command, strerror(errno));
869                 return NULL;
870         }
871
872         pid = fork();
873         if (pid == -1) {
874                 close(sock[0]);
875                 close(sock[1]);
876                 weston_log("fork failed while launching '%s': %s\n",
877                            command, strerror(errno));
878                 return NULL;
879         }
880
881         if (pid == 0) {
882                 client_exec(command, sock[1]);
883                 _Exit(EXIT_FAILURE);
884         }
885         close(sock[1]);
886
887         client = wl_client_create(ivi->compositor->wl_display, sock[0]);
888         if (!client) {
889                 close(sock[0]);
890                 weston_log("Failed to create wayland client for '%s'",
891                            command);
892                 return NULL;
893         }
894
895         return client;
896 }
897
898 int
899 ivi_launch_shell_client(struct ivi_compositor *ivi)
900 {
901         struct weston_config_section *section;
902         char *command = NULL;
903
904         section = weston_config_get_section(ivi->config, "shell-client",
905                                             NULL, NULL);
906         if (section)
907                 weston_config_section_get_string(section, "command",
908                                                  &command, NULL);
909
910         if (!command)
911                 return -1;
912
913         ivi->shell_client.client = launch_shell_client(ivi, command);
914         if (!ivi->shell_client.client)
915                 return -1;
916
917         return 0;
918 }
919
920 static void
921 destroy_black_view(struct wl_listener *listener, void *data)
922 {
923         struct fullscreen_view *fs =
924                 wl_container_of(listener, fs, fs_destroy);
925
926
927         if (fs && fs->fs) {
928                 wl_list_remove(&fs->fs_destroy.link);
929                 free(fs->fs);
930         }
931 }
932
933
934 static void
935 create_black_surface_view(struct ivi_output *output)
936 {
937         struct weston_surface *surface = NULL;
938         struct weston_view *view;
939         struct ivi_compositor *ivi = output->ivi;
940         struct weston_compositor *wc= ivi->compositor;
941         struct weston_output *woutput = output->output;
942
943         if (!woutput)
944                 return;
945
946         surface = weston_surface_create(wc);
947         if (!surface)
948                 return;
949         view = weston_view_create(surface);
950         if (!view) {
951                 weston_surface_destroy(surface);
952                 return;
953         }
954
955         weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1);
956         weston_surface_set_size(surface, woutput->width, woutput->height);
957         weston_view_set_position(view, woutput->x, woutput->y);
958
959         output->fullscreen_view.fs = zalloc(sizeof(struct ivi_surface));
960         if (!output->fullscreen_view.fs) {
961                 weston_surface_destroy(surface);
962                 return;
963         }
964         output->fullscreen_view.fs->view = view;
965
966         output->fullscreen_view.fs_destroy.notify = destroy_black_view;
967         wl_signal_add(&woutput->destroy_signal,
968                       &output->fullscreen_view.fs_destroy);
969 }
970
971 void
972 remove_black_surface(struct ivi_output *output)
973 {
974         struct weston_view *view;
975
976         if (!output &&
977             !output->fullscreen_view.fs &&
978             !output->fullscreen_view.fs->view) {
979                 weston_log("Output %s doesn't have a surface installed!\n", output->name);
980                 return;
981         }
982
983         view = output->fullscreen_view.fs->view;
984         assert(view->is_mapped == true ||
985                view->surface->is_mapped == true);
986
987         view->is_mapped = false;
988         view->surface->is_mapped = false;
989
990         weston_layer_entry_remove(&view->layer_link);
991         weston_view_update_transform(view);
992
993         weston_view_damage_below(view);
994 }
995
996 void
997 insert_black_surface(struct ivi_output *output)
998 {
999         struct weston_view *view;
1000
1001         if ((!output &&
1002             !output->fullscreen_view.fs &&
1003             !output->fullscreen_view.fs->view) || !output->output) {
1004                 weston_log("Output %s doesn't have a surface installed!\n", output->name);
1005                 return;
1006         }
1007
1008         view = output->fullscreen_view.fs->view;
1009         if (view->is_mapped || view->surface->is_mapped)
1010                 return;
1011
1012         weston_layer_entry_remove(&view->layer_link);
1013         weston_layer_entry_insert(&output->ivi->fullscreen.view_list,
1014                                   &view->layer_link);
1015
1016         view->is_mapped = true;
1017         view->surface->is_mapped = true;
1018
1019         weston_view_update_transform(view);
1020         weston_view_damage_below(view);
1021 }
1022
1023 static void
1024 shell_ready(struct wl_client *client, struct wl_resource *shell_res)
1025 {
1026         struct ivi_compositor *ivi = wl_resource_get_user_data(shell_res);
1027         struct ivi_output *output;
1028         struct ivi_surface *surface, *tmp;
1029
1030         /* Init already finished. Do nothing */
1031         if (ivi->shell_client.ready)
1032                 return;
1033
1034         ivi->shell_client.ready = true;
1035
1036         wl_list_for_each(output, &ivi->outputs, link) {
1037                 if (output->background &&
1038                     output->background->role == IVI_SURFACE_ROLE_BACKGROUND) {
1039                         /* track the background surface role as a "regular"
1040                          * surface so we can activate it */
1041                         ivi_set_background_surface(output->background);
1042                         remove_black_surface(output);
1043                 }
1044
1045                 ivi_layout_init(ivi, output);
1046         }
1047
1048         wl_list_for_each_safe(surface, tmp, &ivi->pending_surfaces, link) {
1049                 wl_list_remove(&surface->link);
1050                 wl_list_init(&surface->link);
1051                 ivi_check_pending_desktop_surface(surface);
1052                 surface->checked_pending = true;
1053         }
1054 }
1055
1056 static void
1057 shell_set_background(struct wl_client *client,
1058                      struct wl_resource *shell_res,
1059                      struct wl_resource *surface_res,
1060                      struct wl_resource *output_res)
1061 {
1062         struct weston_head *head = weston_head_from_resource(output_res);
1063         struct weston_output *woutput = weston_head_get_output(head);
1064         struct ivi_output *output = to_ivi_output(woutput);
1065         struct weston_surface *wsurface = wl_resource_get_user_data(surface_res);
1066         struct weston_desktop_surface *dsurface;
1067         struct ivi_surface *surface;
1068
1069         dsurface = weston_surface_get_desktop_surface(wsurface);
1070         if (!dsurface) {
1071                 wl_resource_post_error(shell_res,
1072                                        AGL_SHELL_ERROR_INVALID_ARGUMENT,
1073                                        "surface must be a desktop surface");
1074                 return;
1075         }
1076
1077         surface = weston_desktop_surface_get_user_data(dsurface);
1078         if (surface->role != IVI_SURFACE_ROLE_NONE) {
1079                 wl_resource_post_error(shell_res,
1080                                        AGL_SHELL_ERROR_INVALID_ARGUMENT,
1081                                        "surface already has another ivi role");
1082                 return;
1083         }
1084
1085         if (output->background) {
1086                 wl_resource_post_error(shell_res,
1087                                        AGL_SHELL_ERROR_BACKGROUND_EXISTS,
1088                                        "output already has background");
1089                 return;
1090         }
1091
1092         surface->checked_pending = true;
1093         surface->role = IVI_SURFACE_ROLE_BACKGROUND;
1094         surface->bg.output = output;
1095         wl_list_remove(&surface->link);
1096         wl_list_init(&surface->link);
1097
1098         output->background = surface;
1099
1100         weston_desktop_surface_set_maximized(dsurface, true);
1101         weston_desktop_surface_set_size(dsurface,
1102                                         output->output->width,
1103                                         output->output->height);
1104 }
1105
1106 static void
1107 shell_set_panel(struct wl_client *client,
1108                 struct wl_resource *shell_res,
1109                 struct wl_resource *surface_res,
1110                 struct wl_resource *output_res,
1111                 uint32_t edge)
1112 {
1113         struct weston_head *head = weston_head_from_resource(output_res);
1114         struct weston_output *woutput = weston_head_get_output(head);
1115         struct ivi_output *output = to_ivi_output(woutput);
1116         struct weston_surface *wsurface = wl_resource_get_user_data(surface_res);
1117         struct weston_desktop_surface *dsurface;
1118         struct ivi_surface *surface;
1119         struct ivi_surface **member;
1120         int32_t width = 0, height = 0;
1121
1122         dsurface = weston_surface_get_desktop_surface(wsurface);
1123         if (!dsurface) {
1124                 wl_resource_post_error(shell_res,
1125                                        AGL_SHELL_ERROR_INVALID_ARGUMENT,
1126                                        "surface must be a desktop surface");
1127                 return;
1128         }
1129
1130         surface = weston_desktop_surface_get_user_data(dsurface);
1131         if (surface->role != IVI_SURFACE_ROLE_NONE) {
1132                 wl_resource_post_error(shell_res,
1133                                        AGL_SHELL_ERROR_INVALID_ARGUMENT,
1134                                        "surface already has another ivi role");
1135                 return;
1136         }
1137
1138         switch (edge) {
1139         case AGL_SHELL_EDGE_TOP:
1140                 member = &output->top;
1141                 break;
1142         case AGL_SHELL_EDGE_BOTTOM:
1143                 member = &output->bottom;
1144                 break;
1145         case AGL_SHELL_EDGE_LEFT:
1146                 member = &output->left;
1147                 break;
1148         case AGL_SHELL_EDGE_RIGHT:
1149                 member = &output->right;
1150                 break;
1151         default:
1152                 wl_resource_post_error(shell_res,
1153                                        AGL_SHELL_ERROR_INVALID_ARGUMENT,
1154                                        "invalid edge for panel");
1155                 return;
1156         }
1157
1158         if (*member) {
1159                 wl_resource_post_error(shell_res,
1160                                        AGL_SHELL_ERROR_BACKGROUND_EXISTS,
1161                                        "output already has panel on this edge");
1162                 return;
1163         }
1164
1165         surface->checked_pending = true;
1166         surface->role = IVI_SURFACE_ROLE_PANEL;
1167         surface->panel.output = output;
1168         surface->panel.edge = edge;
1169         wl_list_remove(&surface->link);
1170         wl_list_init(&surface->link);
1171
1172         *member = surface;
1173
1174         switch (surface->panel.edge) {
1175         case AGL_SHELL_EDGE_TOP:
1176         case AGL_SHELL_EDGE_BOTTOM:
1177                 width = woutput->width;
1178                 break;
1179         case AGL_SHELL_EDGE_LEFT:
1180         case AGL_SHELL_EDGE_RIGHT:
1181                 height = woutput->height;
1182                 break;
1183         }
1184
1185         weston_desktop_surface_set_size(dsurface, width, height);
1186 }
1187
1188 void
1189 shell_advertise_app_state(struct ivi_compositor *ivi, const char *app_id,
1190                           const char *data, uint32_t app_state)
1191 {
1192         struct desktop_client *dclient;
1193         uint32_t app_role;
1194         struct ivi_surface *surf = ivi_find_app(ivi, app_id);
1195         struct ivi_policy *policy = ivi->policy;
1196
1197         /* FIXME: should queue it here and see when binding agl-shell-desktop
1198          * if there are any to be sent */
1199         if (!surf)
1200                 return;
1201
1202         if (!app_id)
1203                 return;
1204
1205         if (policy && policy->api.surface_advertise_state_change &&
1206             !policy->api.surface_advertise_state_change(surf, surf->ivi)) {
1207                 return;
1208         }
1209
1210         app_role = surf->role;
1211         if (app_role == IVI_SURFACE_ROLE_POPUP)
1212                 app_role = AGL_SHELL_DESKTOP_APP_ROLE_POPUP;
1213
1214         wl_list_for_each(dclient, &ivi->desktop_clients, link)
1215                 agl_shell_desktop_send_state_app(dclient->resource, app_id,
1216                                                  data, app_state, app_role);
1217 }
1218
1219 static void
1220 shell_activate_app(struct wl_client *client,
1221                    struct wl_resource *shell_res,
1222                    const char *app_id,
1223                    struct wl_resource *output_res)
1224 {
1225         struct weston_head *head = weston_head_from_resource(output_res);
1226         struct weston_output *woutput = weston_head_get_output(head);
1227         struct ivi_output *output = to_ivi_output(woutput);
1228
1229         ivi_layout_activate(output, app_id);
1230 }
1231
1232 static void
1233 shell_desktop_activate_app(struct wl_client *client,
1234                            struct wl_resource *shell_res,
1235                            const char *app_id, const char *data,
1236                            struct wl_resource *output_res)
1237 {
1238         struct weston_head *head = weston_head_from_resource(output_res);
1239         struct weston_output *woutput = weston_head_get_output(head);
1240         struct ivi_output *output = to_ivi_output(woutput);
1241
1242         ivi_layout_activate(output, app_id);
1243         shell_advertise_app_state(output->ivi, app_id,
1244                                   data, AGL_SHELL_DESKTOP_APP_STATE_ACTIVATED);
1245 }
1246
1247 static void
1248 shell_deactivate_app(struct wl_client *client,
1249                    struct wl_resource *shell_res,
1250                    const char *app_id)
1251 {
1252         struct desktop_client *dclient = wl_resource_get_user_data(shell_res);
1253         struct ivi_compositor *ivi = dclient->ivi;
1254
1255         ivi_layout_deactivate(ivi, app_id);
1256         shell_advertise_app_state(ivi, app_id,
1257                                   NULL, AGL_SHELL_DESKTOP_APP_STATE_DEACTIVATED);
1258 }
1259
1260 static const struct agl_shell_interface agl_shell_implementation = {
1261         .ready = shell_ready,
1262         .set_background = shell_set_background,
1263         .set_panel = shell_set_panel,
1264         .activate_app = shell_activate_app,
1265 };
1266
1267 static void
1268 shell_desktop_set_app_property(struct wl_client *client,
1269                                struct wl_resource *shell_res,
1270                                const char *app_id, uint32_t role,
1271                                int x, int y, int bx, int by,
1272                                int width, int height,
1273                                struct wl_resource *output_res)
1274 {
1275         struct weston_head *head = weston_head_from_resource(output_res);
1276         struct weston_output *woutput = weston_head_get_output(head);
1277         struct ivi_output *output = to_ivi_output(woutput);
1278
1279         switch (role) {
1280         case AGL_SHELL_DESKTOP_APP_ROLE_POPUP:
1281                 ivi_set_pending_desktop_surface_popup(output, x, y, bx, by,
1282                                                       width, height, app_id);
1283                 break;
1284         case AGL_SHELL_DESKTOP_APP_ROLE_FULLSCREEN:
1285                 ivi_set_pending_desktop_surface_fullscreen(output, app_id);
1286                 break;
1287         case AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_VERTICAL:
1288         case AGL_SHELL_DESKTOP_APP_ROLE_SPLIT_HORIZONTAL:
1289                 ivi_set_pending_desktop_surface_split(output, app_id, role);
1290                 break;
1291         case AGL_SHELL_DESKTOP_APP_ROLE_REMOTE:
1292                 ivi_set_pending_desktop_surface_remote(output, app_id);
1293                 break;
1294         default:
1295                 break;
1296         }
1297 }
1298
1299 void
1300 ivi_compositor_destroy_pending_surfaces(struct ivi_compositor *ivi)
1301 {
1302         struct pending_popup *p_popup, *next_p_popup;
1303         struct pending_split *split_surf, *next_split_surf;
1304         struct pending_fullscreen *fs_surf, *next_fs_surf;
1305         struct pending_remote *remote_surf, *next_remote_surf;
1306
1307         wl_list_for_each_safe(p_popup, next_p_popup,
1308                               &ivi->popup_pending_apps, link)
1309                 ivi_remove_pending_desktop_surface_popup(p_popup);
1310
1311         wl_list_for_each_safe(split_surf, next_split_surf,
1312                               &ivi->split_pending_apps, link)
1313                 ivi_remove_pending_desktop_surface_split(split_surf);
1314
1315         wl_list_for_each_safe(fs_surf, next_fs_surf,
1316                               &ivi->fullscreen_pending_apps, link)
1317                 ivi_remove_pending_desktop_surface_fullscreen(fs_surf);
1318
1319         wl_list_for_each_safe(remote_surf, next_remote_surf,
1320                               &ivi->remote_pending_apps, link)
1321                 ivi_remove_pending_desktop_surface_remote(remote_surf);
1322 }
1323
1324 static void
1325 shell_desktop_set_app_property_mode(struct wl_client *client,
1326                                     struct wl_resource *shell_res, uint32_t perm)
1327 {
1328         struct desktop_client *dclient = wl_resource_get_user_data(shell_res);
1329         if (perm) {
1330                 dclient->ivi->keep_pending_surfaces = true;
1331         } else {
1332                 dclient->ivi->keep_pending_surfaces = false;
1333                 /* remove any previous pending surfaces */
1334                 ivi_compositor_destroy_pending_surfaces(dclient->ivi);
1335         }
1336 }
1337
1338 static const struct agl_shell_desktop_interface agl_shell_desktop_implementation = {
1339         .activate_app = shell_desktop_activate_app,
1340         .set_app_property = shell_desktop_set_app_property,
1341         .deactivate_app = shell_deactivate_app,
1342         .set_app_property_mode = shell_desktop_set_app_property_mode,
1343 };
1344
1345 static void
1346 unbind_agl_shell(struct wl_resource *resource)
1347 {
1348         struct ivi_compositor *ivi;
1349         struct ivi_output *output;
1350         struct ivi_surface *surf, *surf_tmp;
1351
1352         ivi = wl_resource_get_user_data(resource);
1353         wl_list_for_each(output, &ivi->outputs, link) {
1354                 /* reset the active surf if there's one present */
1355                 if (output->active) {
1356                         output->active->view->is_mapped = false;
1357                         output->active->view->surface->is_mapped = false;
1358
1359                         weston_layer_entry_remove(&output->active->view->layer_link);
1360                         output->active = NULL;
1361                 }
1362
1363                 insert_black_surface(output);
1364         }
1365
1366         wl_list_for_each_safe(surf, surf_tmp, &ivi->surfaces, link) {
1367                 wl_list_remove(&surf->link);
1368                 wl_list_init(&surf->link);
1369         }
1370
1371         wl_list_for_each_safe(surf, surf_tmp, &ivi->pending_surfaces, link) {
1372                 wl_list_remove(&surf->link);
1373                 wl_list_init(&surf->link);
1374         }
1375
1376         wl_list_init(&ivi->surfaces);
1377         wl_list_init(&ivi->pending_surfaces);
1378
1379         ivi->shell_client.ready = false;
1380         ivi->shell_client.resource = NULL;
1381         ivi->shell_client.client = NULL;
1382 }
1383
1384 static void
1385 bind_agl_shell(struct wl_client *client,
1386                void *data, uint32_t version, uint32_t id)
1387 {
1388         struct ivi_compositor *ivi = data;
1389         struct wl_resource *resource;
1390         struct ivi_policy *policy;
1391         void *interface;
1392
1393         policy = ivi->policy;
1394         interface = (void *) &agl_shell_interface;
1395         if (policy && policy->api.shell_bind_interface &&
1396             !policy->api.shell_bind_interface(client, interface)) {
1397                 wl_client_post_implementation_error(client,
1398                                        "client not authorized to use agl_shell");
1399                 return;
1400         }
1401
1402         resource = wl_resource_create(client, &agl_shell_interface,
1403                                       1, id);
1404         if (!resource) {
1405                 wl_client_post_no_memory(client);
1406                 return;
1407         }
1408
1409         if (ivi->shell_client.resource) {
1410                 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
1411                                        "agl_shell has already been bound");
1412                 return;
1413         }
1414
1415         wl_resource_set_implementation(resource, &agl_shell_implementation,
1416                                        ivi, unbind_agl_shell);
1417         ivi->shell_client.resource = resource;
1418 }
1419
1420 static void
1421 unbind_agl_shell_desktop(struct wl_resource *resource)
1422 {
1423         struct desktop_client *dclient = wl_resource_get_user_data(resource);
1424
1425         wl_list_remove(&dclient->link);
1426         free(dclient);
1427 }
1428
1429 static void
1430 bind_agl_shell_desktop(struct wl_client *client,
1431                        void *data, uint32_t version, uint32_t id)
1432 {
1433         struct ivi_compositor *ivi = data;
1434         struct wl_resource *resource;
1435         struct ivi_policy *policy;
1436         struct desktop_client *dclient;
1437         void *interface;
1438
1439         policy = ivi->policy;
1440         interface  = (void *) &agl_shell_desktop_interface;
1441         if (policy && policy->api.shell_bind_interface &&
1442             !policy->api.shell_bind_interface(client, interface)) {
1443                 wl_client_post_implementation_error(client,
1444                                 "client not authorized to use agl_shell_desktop");
1445                 return;
1446         }
1447
1448         dclient = zalloc(sizeof(*dclient));
1449         if (!dclient) {
1450                 wl_client_post_no_memory(client);
1451                 return;
1452         }
1453
1454         resource = wl_resource_create(client, &agl_shell_desktop_interface,
1455                                       version, id);
1456         dclient->ivi = ivi;
1457         if (!resource) {
1458                 wl_client_post_no_memory(client);
1459                 return;
1460         }
1461
1462         wl_resource_set_implementation(resource, &agl_shell_desktop_implementation,
1463                                        dclient, unbind_agl_shell_desktop);
1464
1465         dclient->resource = resource;
1466         wl_list_insert(&ivi->desktop_clients, &dclient->link);
1467
1468         /* advertise xdg surfaces */
1469         ivi_shell_advertise_xdg_surfaces(ivi, resource);
1470 }
1471
1472 int
1473 ivi_shell_create_global(struct ivi_compositor *ivi)
1474 {
1475         ivi->agl_shell = wl_global_create(ivi->compositor->wl_display,
1476                                           &agl_shell_interface, 1,
1477                                           ivi, bind_agl_shell);
1478         if (!ivi->agl_shell) {
1479                 weston_log("Failed to create wayland global.\n");
1480                 return -1;
1481         }
1482
1483         ivi->agl_shell_desktop = wl_global_create(ivi->compositor->wl_display,
1484                                                   &agl_shell_desktop_interface, 2,
1485                                                   ivi, bind_agl_shell_desktop);
1486         if (!ivi->agl_shell_desktop) {
1487                 weston_log("Failed to create wayland global (agl_shell_desktop).\n");
1488                 return -1;
1489         }
1490
1491         return 0;
1492 }