2 * Copyright © 2019 Samsung Electronics co., Ltd. All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
30 #include <pepper-output-backend.h>
31 #include <xdg-shell-unstable-v6-server-protocol.h>
32 #include <tizen-extension-server-protocol.h>
34 #include "headless_server.h"
36 #define UPDATE_SURFACE_TYPE 0 //update the surface_type(map. unmap)
37 #define SET_UPDATE(x, type) (x |= ((uint32_t)(1<<type)))
38 #define IS_UPDATE(x, type) (!!(x & ((uint32_t)(1<<type))))
41 HEADLESS_SURFACE_NONE,
42 HEADLESS_SURFACE_TOPLEVEL,
43 HEADLESS_SURFACE_POPUP
44 } headless_surface_type_t;
46 typedef struct HEADLESS_SHELL headless_shell_t;
47 typedef struct HEADLESS_SHELL_SURFACE headless_shell_surface_t;
49 struct HEADLESS_SHELL{
50 pepper_compositor_t *compositor;
51 struct wl_global *zxdg_shell;
52 struct wl_global *tizen_policy;
53 struct wl_event_source *cb_idle;
56 pepper_view_t *top_mapped;
57 pepper_view_t *top_visible;
59 pepper_event_listener_t *surface_add_listener;
60 pepper_event_listener_t *surface_remove_listener;
61 pepper_event_listener_t *view_remove_listener;
64 struct HEADLESS_SHELL_SURFACE{
65 headless_shell_t *hs_shell;
66 pepper_surface_t *surface;
71 headless_surface_type_t surface_type;
72 struct wl_resource *zxdg_shell_surface;
73 struct wl_resource *zxdg_surface; /*resource of toplevel, popup and etc*/
74 struct wl_resource *tizen_visibility;
75 uint32_t last_ack_configure;
77 pepper_bool_t skip_focus;
79 pepper_event_listener_t *cb_commit;
83 headless_shell_cb_surface_commit(pepper_event_listener_t *listener,
84 pepper_object_t *object,
85 uint32_t id, void *info, void *data);
87 headless_shell_add_idle(headless_shell_t *shell);
91 headless_shell_send_visiblity(pepper_view_t *view, uint8_t visibility);
93 const static int KEY_SHELL = 0;
96 zxdg_toplevel_cb_resource_destroy(struct wl_resource *resource)
98 headless_shell_surface_t *hs_surface = (headless_shell_surface_t *)wl_resource_get_user_data(resource);
100 PEPPER_CHECK(hs_surface, return, "fail to get headless_surface.\n");
101 PEPPER_CHECK((hs_surface->surface_type == HEADLESS_SURFACE_TOPLEVEL), return, "Invalid surface type.\n");
102 PEPPER_CHECK((hs_surface->zxdg_surface == resource), return, "Invalid surface.");
104 PEPPER_TRACE("[SHELL] zxdg_toplevel_cb_resource_destroy: view:%p, hs_surface:%p\n", hs_surface->view, hs_surface);
106 if (hs_surface->view) {
107 pepper_view_unmap(hs_surface->view);
108 headless_shell_add_idle(hs_surface->hs_shell);
111 hs_surface->surface_type = HEADLESS_SURFACE_NONE;
112 hs_surface->zxdg_surface = NULL;
113 SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE);
117 zxdg_toplevel_cb_destroy(struct wl_client *client, struct wl_resource *resource)
119 wl_resource_destroy(resource);
123 zxdg_toplevel_cb_parent_set(struct wl_client *client,
124 struct wl_resource *resource,
125 struct wl_resource *res_parent)
130 zxdg_toplevel_cb_title_set(struct wl_client *client,
131 struct wl_resource *resource,
137 zxdg_toplevel_cb_app_id_set(struct wl_client *client,
138 struct wl_resource *resource,
144 zxdg_toplevel_cb_win_menu_show(struct wl_client *client,
145 struct wl_resource *resource,
146 struct wl_resource *res_seat,
154 zxdg_toplevel_cb_move(struct wl_client *client,
155 struct wl_resource *resource,
156 struct wl_resource *res_seat,
162 zxdg_toplevel_cb_resize(struct wl_client *client,
163 struct wl_resource *resource,
164 struct wl_resource *res_seat,
171 zxdg_toplevel_cb_max_size_set(struct wl_client *client,
172 struct wl_resource *resource,
179 zxdg_toplevel_cb_min_size_set(struct wl_client *client,
180 struct wl_resource *resource,
187 zxdg_toplevel_cb_maximized_set(struct wl_client *client, struct wl_resource *resource)
192 zxdg_toplevel_cb_maximized_unset(struct wl_client *client, struct wl_resource *resource)
197 zxdg_toplevel_cb_fullscreen_set(struct wl_client *client,
198 struct wl_resource *resource,
199 struct wl_resource *res_output)
204 zxdg_toplevel_cb_fullscreen_unset(struct wl_client *client, struct wl_resource *resource)
209 zxdg_toplevel_cb_minimized_set(struct wl_client *client, struct wl_resource *resource)
213 static const struct zxdg_toplevel_v6_interface zxdg_toplevel_interface =
215 zxdg_toplevel_cb_destroy,
216 zxdg_toplevel_cb_parent_set,
217 zxdg_toplevel_cb_title_set,
218 zxdg_toplevel_cb_app_id_set,
219 zxdg_toplevel_cb_win_menu_show,
220 zxdg_toplevel_cb_move,
221 zxdg_toplevel_cb_resize,
222 zxdg_toplevel_cb_max_size_set,
223 zxdg_toplevel_cb_min_size_set,
224 zxdg_toplevel_cb_maximized_set,
225 zxdg_toplevel_cb_maximized_unset,
226 zxdg_toplevel_cb_fullscreen_set,
227 zxdg_toplevel_cb_fullscreen_unset,
228 zxdg_toplevel_cb_minimized_set
232 zxdg_popup_cb_resource_destroy(struct wl_resource *resource)
234 headless_shell_surface_t *hs_surface = (headless_shell_surface_t *)wl_resource_get_user_data(resource);
236 PEPPER_CHECK(hs_surface, return, "fail to get headless_surface.\n");
237 PEPPER_CHECK((hs_surface->surface_type == HEADLESS_SURFACE_POPUP), return, "Invalid surface type.\n");
238 PEPPER_CHECK((hs_surface->zxdg_surface == resource), return, "Invalid surface.");
240 hs_surface->surface_type = HEADLESS_SURFACE_NONE;
241 hs_surface->zxdg_surface = NULL;
242 SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE);
246 zxdg_popup_cb_destroy(struct wl_client *client, struct wl_resource *resource)
248 wl_resource_destroy(resource);
252 zxdg_popup_cb_grab(struct wl_client *client,
253 struct wl_resource *resource,
254 struct wl_resource *res_seat,
259 static const struct zxdg_popup_v6_interface zxdg_popup_interface =
261 zxdg_popup_cb_destroy,
266 zxdg_surface_cb_resource_destroy(struct wl_resource *resource)
268 headless_shell_surface_t *hs_surface;
270 hs_surface = wl_resource_get_user_data(resource);
271 PEPPER_CHECK(hs_surface, return, "fail to get hs_surface\n");
273 PEPPER_TRACE("[SHELL] zxdg_surface_cb_resource_destroy: hs_surface:%p view:%p\n", hs_surface, hs_surface->view);
275 if (hs_surface->view) {
276 pepper_view_destroy(hs_surface->view);
277 hs_surface->view = NULL;
280 if (hs_surface->cb_commit) {
281 pepper_event_listener_remove(hs_surface->cb_commit);
282 hs_surface->cb_commit = NULL;
285 hs_surface->zxdg_shell_surface = NULL;
286 hs_surface->skip_focus = PEPPER_FALSE;
287 hs_surface->visibility = TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED;
289 SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE);
290 headless_shell_add_idle(hs_surface->hs_shell);
294 zxdg_surface_cb_destroy(struct wl_client *client, struct wl_resource *resource)
296 wl_resource_destroy(resource);
300 zxdg_surface_cb_toplevel_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
302 headless_shell_surface_t *hs_surface = (headless_shell_surface_t *)wl_resource_get_user_data(resource);
303 struct wl_resource *new_res;
305 PEPPER_CHECK(hs_surface, return, "fail to get headless_surface\n");
306 PEPPER_CHECK((hs_surface->zxdg_surface == NULL), return, "alwreay assign zdg_surface:%p role:%d\n", hs_surface->zxdg_surface, hs_surface->surface_type);
308 new_res = wl_resource_create(client, &zxdg_toplevel_v6_interface, 1, id);
310 PEPPER_ERROR("fail to create zxdg_toplevel");
311 wl_resource_post_no_memory(resource);
315 wl_resource_set_implementation(new_res,
316 &zxdg_toplevel_interface,
318 zxdg_toplevel_cb_resource_destroy);
320 hs_surface->surface_type = HEADLESS_SURFACE_TOPLEVEL;
321 hs_surface->zxdg_surface = new_res;
323 SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE);
327 zxdg_surface_cb_popup_get(struct wl_client *client,
328 struct wl_resource *resource,
330 struct wl_resource *res_parent,
331 struct wl_resource *res_pos)
333 headless_shell_surface_t *hs_surface = (headless_shell_surface_t *)wl_resource_get_user_data(resource);
334 struct wl_resource *new_res;
336 PEPPER_CHECK(hs_surface, return, "fail to get headless_surface\n");
337 PEPPER_CHECK((hs_surface->zxdg_surface == NULL), return, "alwreay assign zdg_surface:%p role:%d\n", hs_surface->zxdg_surface, hs_surface->surface_type);
339 new_res = wl_resource_create(client, &zxdg_popup_v6_interface, 1, id);
341 PEPPER_ERROR("fail to create popup");
342 wl_resource_post_no_memory(resource);
346 wl_resource_set_implementation(new_res,
347 &zxdg_popup_interface,
349 zxdg_popup_cb_resource_destroy);
351 hs_surface->surface_type = HEADLESS_SURFACE_POPUP;
352 hs_surface->zxdg_surface = new_res;
354 SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE);
358 zxdg_surface_cb_win_geometry_set(struct wl_client *client,
359 struct wl_resource *resource,
368 zxdg_surface_cb_configure_ack(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
370 headless_shell_surface_t *hs_surface;
372 hs_surface = wl_resource_get_user_data(resource);
373 PEPPER_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
375 hs_surface->last_ack_configure = serial;
378 static const struct zxdg_surface_v6_interface zxdg_surface_interface =
380 zxdg_surface_cb_destroy,
381 zxdg_surface_cb_toplevel_get,
382 zxdg_surface_cb_popup_get,
383 zxdg_surface_cb_win_geometry_set,
384 zxdg_surface_cb_configure_ack
388 zxdg_positioner_cb_destroy(struct wl_client *client, struct wl_resource *resource)
390 wl_resource_destroy(resource);
394 zxdg_positioner_cb_size_set(struct wl_client *client,
395 struct wl_resource *resource,
396 int32_t w, int32_t h)
401 zxdg_positioner_cb_anchor_rect_set(struct wl_client *client,
402 struct wl_resource *resource,
403 int32_t x, int32_t y, int32_t w, int32_t h)
408 zxdg_positioner_cb_anchor_set(struct wl_client *client,
409 struct wl_resource *resource,
410 enum zxdg_positioner_v6_anchor anchor)
415 zxdg_positioner_cb_gravity_set(struct wl_client *client,
416 struct wl_resource *resource,
417 enum zxdg_positioner_v6_gravity gravity)
422 zxdg_positioner_cb_constraint_adjustment_set(struct wl_client *client,
423 struct wl_resource *resource,
424 enum zxdg_positioner_v6_constraint_adjustment constraint_adjustment)
429 zxdg_positioner_cb_offset_set(struct wl_client *client,
430 struct wl_resource *resource,
431 int32_t x, int32_t y)
435 static const struct zxdg_positioner_v6_interface zxdg_positioner_interface =
437 zxdg_positioner_cb_destroy,
438 zxdg_positioner_cb_size_set,
439 zxdg_positioner_cb_anchor_rect_set,
440 zxdg_positioner_cb_anchor_set,
441 zxdg_positioner_cb_gravity_set,
442 zxdg_positioner_cb_constraint_adjustment_set,
443 zxdg_positioner_cb_offset_set,
447 zxdg_shell_cb_destroy(struct wl_client *client, struct wl_resource *resource)
449 PEPPER_TRACE("Destroy zxdg_shell\n");
451 wl_resource_destroy(resource);
455 zxdg_shell_cb_positioner_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
457 struct wl_resource *new_res;
459 PEPPER_TRACE("Create zxdg_positoiner\n");
461 new_res = wl_resource_create(client, &zxdg_positioner_v6_interface, 1, id);
464 PEPPER_ERROR("fail to create zxdg_positioner\n");
465 wl_resource_post_no_memory(resource);
469 wl_resource_set_implementation(new_res, &zxdg_positioner_interface, NULL, NULL);
473 zxdg_shell_cb_surface_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *wsurface)
475 headless_shell_t *hs;
476 headless_shell_surface_t *hs_surface = NULL;
477 pepper_surface_t *psurface;
480 hs = wl_resource_get_user_data(resource);
482 PEPPER_ERROR("fail to get headless_shell\n");
483 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
484 "failed to get headless shell");
488 psurface = wl_resource_get_user_data(wsurface);
489 PEPPER_CHECK(psurface, goto error, "faile to get pepper_surface\n");
491 hs_surface = (headless_shell_surface_t *)pepper_object_get_user_data((pepper_object_t *)psurface, wsurface);
493 PEPPER_ERROR("fail to get headless_shell_surface_t: %p key:%p\n", psurface, wsurface);
494 wl_resource_post_no_memory(resource);
498 hs_surface->zxdg_shell_surface = wl_resource_create(client, &zxdg_surface_v6_interface, 1, id);
499 if (!hs_surface->zxdg_shell_surface) {
500 PEPPER_ERROR("fail to create the zxdg_surface\n");
501 wl_resource_post_no_memory(resource);
505 wl_resource_set_implementation(hs_surface->zxdg_shell_surface,
506 &zxdg_surface_interface,
508 zxdg_surface_cb_resource_destroy);
510 hs_surface->view = pepper_compositor_add_view(hs->compositor);
511 if (!hs_surface->view) {
512 PEPPER_ERROR("fail to create the pepper_view\n");
513 wl_resource_post_no_memory(resource);
517 if (!pepper_view_set_surface(hs_surface->view, psurface)) {
518 PEPPER_ERROR("fail to set surface\n");
519 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
520 "Assign set psurface to pview");
524 hs_surface->cb_commit = pepper_object_add_event_listener((pepper_object_t *)psurface,
525 PEPPER_EVENT_SURFACE_COMMIT, 0, headless_shell_cb_surface_commit, hs_surface);
527 role = pepper_surface_get_role(psurface);
529 if (!pepper_surface_set_role(psurface, "xdg_surface")) {
530 PEPPER_ERROR("fail to set role\n");
531 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
532 "Assign \"xdg_surface\" to wl_surface failed\n");
536 PEPPER_CHECK(!strcmp(role, "xdg_surface"), goto error, "surface has alweady role %s\n", role);
539 PEPPER_TRACE("[SHELL] create zxdg_surface:%p, pview:%p, psurface:%p\n",
540 hs_surface->zxdg_shell_surface,
547 if (hs_surface->view) {
548 pepper_view_destroy(hs_surface->view);
549 hs_surface->view = NULL;
552 if (hs_surface->zxdg_shell_surface) {
553 wl_resource_destroy(hs_surface->zxdg_shell_surface);
554 hs_surface->zxdg_shell_surface = NULL;
560 zxdg_shell_cb_pong(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
565 static const struct zxdg_shell_v6_interface zxdg_shell_interface =
567 zxdg_shell_cb_destroy,
568 zxdg_shell_cb_positioner_create,
569 zxdg_shell_cb_surface_get,
574 zxdg_shell_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
576 struct wl_resource *resource;
577 headless_shell_t *hs = (headless_shell_t *)data;
579 PEPPER_TRACE("Bind zxdg_shell\n");
581 /* Create resource for zxdg_shell_v6 */
582 resource = wl_resource_create(client,
583 &zxdg_shell_v6_interface,
586 PEPPER_CHECK(resource, goto err_shell, "fail to create the zxdg_shell_v6\n");
588 wl_resource_set_implementation(resource, &zxdg_shell_interface, hs, NULL);
592 wl_client_post_no_memory(client);
596 zxdg_init(headless_shell_t *shell)
598 struct wl_display *display;
600 display = pepper_compositor_get_display(shell->compositor);
602 shell->zxdg_shell = wl_global_create(display, &zxdg_shell_v6_interface, 1, shell, zxdg_shell_cb_bind);
603 PEPPER_CHECK(shell->zxdg_shell, return PEPPER_FALSE, "fail to create zxdg_shell\n");
609 zxdg_deinit(headless_shell_t *shell)
611 if (shell->zxdg_shell)
612 wl_global_destroy(shell->zxdg_shell);
616 tizen_visibility_cb_destroy(struct wl_client *client, struct wl_resource *res_tzvis)
618 wl_resource_destroy(res_tzvis);
621 static const struct tizen_visibility_interface tizen_visibility =
623 tizen_visibility_cb_destroy
627 tizen_visibility_cb_vis_destroy(struct wl_resource *res_tzvis)
629 headless_shell_surface_t *hs_surface = (headless_shell_surface_t *)wl_resource_get_user_data(res_tzvis);
631 PEPPER_CHECK(hs_surface, return, "[SHELL] cannot get headless_shell_surface_t\n");
632 hs_surface->tizen_visibility = NULL;
636 tizen_position_cb_destroy(struct wl_client *client, struct wl_resource *res_tzpos)
638 wl_resource_destroy(res_tzpos);
642 tizen_position_cb_set(struct wl_client *client, struct wl_resource *res_tzpos, int32_t x, int32_t y)
646 static const struct tizen_position_interface tizen_position =
648 tizen_position_cb_destroy,
649 tizen_position_cb_set,
653 tizen_position_cb_pos_destroy(struct wl_resource *res_tzpos)
658 tizen_policy_cb_vis_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surf)
660 pepper_surface_t *psurface;
661 headless_shell_surface_t *hs_surface;
662 struct wl_resource *new_res;
664 psurface = wl_resource_get_user_data(surf);
665 PEPPER_CHECK(psurface, return, "fail to get pepper_surface_t\n");
667 hs_surface = pepper_object_get_user_data((pepper_object_t *)psurface, surf);
668 PEPPER_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
670 new_res = wl_resource_create(client, &tizen_visibility_interface, 5, id);
672 PEPPER_ERROR("fail to create tizen_visibility");
673 wl_resource_post_no_memory(resource);
677 wl_resource_set_implementation(new_res,
680 tizen_visibility_cb_vis_destroy);
682 hs_surface->tizen_visibility = new_res;
684 if (hs_surface->visibility != TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED)
685 tizen_visibility_send_notify(hs_surface->tizen_visibility, hs_surface->visibility);
689 tizen_policy_cb_pos_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surf)
691 struct wl_resource *new_res;
693 new_res = wl_resource_create(client, &tizen_position_interface, 1, id);
695 PEPPER_ERROR("fail to create tizen_visibility");
696 wl_resource_post_no_memory(resource);
700 wl_resource_set_implementation(new_res,
703 tizen_position_cb_pos_destroy);
707 tizen_policy_cb_activate(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
709 pepper_surface_t *psurface;
710 headless_shell_surface_t *hs_surface;
712 psurface = wl_resource_get_user_data(surf);
713 PEPPER_CHECK(psurface, return, "fail to get pepper_surface_t\n");
715 hs_surface = pepper_object_get_user_data((pepper_object_t *)psurface, surf);
716 PEPPER_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
717 PEPPER_CHECK(hs_surface->view, return, "invalid view from headless_shell_surface\n");
719 pepper_view_stack_top(hs_surface->view, PEPPER_TRUE);
721 headless_shell_add_idle(hs_surface->hs_shell);
725 tizen_policy_cb_activate_below_by_res_id(struct wl_client *client, struct wl_resource *resource, uint32_t res_id, uint32_t below_res_id)
730 tizen_policy_cb_raise(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
735 tizen_policy_cb_lower(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
740 tizen_policy_cb_lower_by_res_id(struct wl_client *client, struct wl_resource *resource, uint32_t res_id)
745 tizen_policy_cb_focus_skip_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
747 pepper_surface_t *psurface;
748 headless_shell_surface_t *hs_surface;
750 psurface = wl_resource_get_user_data(surf);
751 PEPPER_CHECK(psurface, return, "fail to get pepper_surface_t\n");
753 hs_surface = pepper_object_get_user_data((pepper_object_t *)psurface, surf);
754 PEPPER_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
756 hs_surface->skip_focus = PEPPER_TRUE;
760 tizen_policy_cb_focus_skip_unset(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
762 pepper_surface_t *psurface;
763 headless_shell_surface_t *hs_surface;
765 psurface = wl_resource_get_user_data(surf);
766 PEPPER_CHECK(psurface, return, "fail to get pepper_surface_t\n");
768 hs_surface = pepper_object_get_user_data((pepper_object_t *)psurface, surf);
769 PEPPER_CHECK(hs_surface, return, "fail to get headless_shell_surface\n");
771 hs_surface->skip_focus = PEPPER_FALSE;
775 tizen_policy_cb_role_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf, const char *role)
780 tizen_policy_cb_type_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf, uint32_t type)
785 tizen_policy_cb_conformant_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
790 tizen_policy_cb_conformant_unset(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
795 tizen_policy_cb_conformant_get(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
797 tizen_policy_send_conformant(resource, surf, 0);
801 tizen_policy_cb_notilv_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf, int32_t lv)
806 tizen_policy_cb_transient_for_set(struct wl_client *client, struct wl_resource *resource, uint32_t child_id, uint32_t parent_id)
811 tizen_policy_cb_transient_for_unset(struct wl_client *client, struct wl_resource *resource, uint32_t child_id)
813 tizen_policy_send_transient_for_done(resource, child_id);
817 tizen_policy_cb_win_scrmode_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf, uint32_t mode)
819 tizen_policy_send_window_screen_mode_done
820 (resource, surf, mode, TIZEN_POLICY_ERROR_STATE_NONE);
824 tizen_policy_cb_subsurf_place_below_parent(struct wl_client *client, struct wl_resource *resource, struct wl_resource *subsurf)
829 tizen_policy_cb_subsurf_stand_alone_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *subsurf)
834 tizen_policy_cb_subsurface_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface, uint32_t parent_id)
836 wl_client_post_implementation_error(client, "Headless server not support tizen_subsurface\n");
840 tizen_policy_cb_opaque_state_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, int32_t state)
845 tizen_policy_cb_iconify(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
850 tizen_policy_cb_uniconify(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
855 tizen_policy_cb_aux_hint_add(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf, int32_t id, const char *name, const char *value)
860 tizen_policy_cb_aux_hint_change(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf, int32_t id, const char *value)
865 tizen_policy_cb_aux_hint_del(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf, int32_t id)
870 tizen_policy_cb_supported_aux_hints_get(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
875 tizen_policy_cb_background_state_set(struct wl_client *client, struct wl_resource *resource, uint32_t pid)
880 tizen_policy_cb_background_state_unset(struct wl_client *client, struct wl_resource *resource, uint32_t pid)
885 tizen_policy_cb_floating_mode_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
890 tizen_policy_cb_floating_mode_unset(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf)
895 tizen_policy_cb_stack_mode_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surf, uint32_t mode)
900 tizen_policy_cb_activate_above_by_res_id(struct wl_client *client, struct wl_resource *resource, uint32_t res_id, uint32_t above_res_id)
905 tizen_policy_cb_subsurf_watcher_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface)
907 wl_client_post_implementation_error(client, "Headless server not support tizen_subsurface\n");
911 tizen_policy_cb_parent_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *child, struct wl_resource *parent)
916 tizen_policy_cb_ack_conformant_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t serial)
921 tizen_policy_cb_destroy(struct wl_client *client, struct wl_resource *resource)
923 wl_resource_destroy(resource);
927 tizen_policy_cb_has_video(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t has)
931 static const struct tizen_policy_interface tizen_policy_iface =
933 tizen_policy_cb_vis_get,
934 tizen_policy_cb_pos_get,
935 tizen_policy_cb_activate,
936 tizen_policy_cb_activate_below_by_res_id,
937 tizen_policy_cb_raise,
938 tizen_policy_cb_lower,
939 tizen_policy_cb_lower_by_res_id,
940 tizen_policy_cb_focus_skip_set,
941 tizen_policy_cb_focus_skip_unset,
942 tizen_policy_cb_role_set,
943 tizen_policy_cb_type_set,
944 tizen_policy_cb_conformant_set,
945 tizen_policy_cb_conformant_unset,
946 tizen_policy_cb_conformant_get,
947 tizen_policy_cb_notilv_set,
948 tizen_policy_cb_transient_for_set,
949 tizen_policy_cb_transient_for_unset,
950 tizen_policy_cb_win_scrmode_set,
951 tizen_policy_cb_subsurf_place_below_parent,
952 tizen_policy_cb_subsurf_stand_alone_set,
953 tizen_policy_cb_subsurface_get,
954 tizen_policy_cb_opaque_state_set,
955 tizen_policy_cb_iconify,
956 tizen_policy_cb_uniconify,
957 tizen_policy_cb_aux_hint_add,
958 tizen_policy_cb_aux_hint_change,
959 tizen_policy_cb_aux_hint_del,
960 tizen_policy_cb_supported_aux_hints_get,
961 tizen_policy_cb_background_state_set,
962 tizen_policy_cb_background_state_unset,
963 tizen_policy_cb_floating_mode_set,
964 tizen_policy_cb_floating_mode_unset,
965 tizen_policy_cb_stack_mode_set,
966 tizen_policy_cb_activate_above_by_res_id,
967 tizen_policy_cb_subsurf_watcher_get,
968 tizen_policy_cb_parent_set,
969 tizen_policy_cb_ack_conformant_region,
970 tizen_policy_cb_destroy,
971 tizen_policy_cb_has_video,
975 tizen_policy_cb_unbind(struct wl_resource *resource)
977 headless_shell_t *shell = (headless_shell_t *)wl_resource_get_user_data(resource);
980 shell->tizen_policy = NULL;
984 tizen_policy_cb_bind(struct wl_client *client, void *data, uint32_t ver, uint32_t id)
986 headless_shell_t *shell = (headless_shell_t *)data;
987 struct wl_resource *resource;
989 PEPPER_CHECK(shell, goto err, "data is NULL\n");
991 resource = wl_resource_create(client,
992 &tizen_policy_interface,
995 PEPPER_CHECK(resource, goto err, "fail to create tizen_policy\n");
997 wl_resource_set_implementation(resource,
1000 tizen_policy_cb_unbind);
1004 wl_client_post_no_memory(client);
1007 static pepper_bool_t
1008 tizen_policy_init(headless_shell_t *shell)
1010 struct wl_display *display;
1012 display = pepper_compositor_get_display(shell->compositor);
1014 shell->tizen_policy = wl_global_create(display, &tizen_policy_interface, 7, shell, tizen_policy_cb_bind);
1015 PEPPER_CHECK(shell->tizen_policy, return PEPPER_FALSE, "faile to create tizen_policy\n");
1021 tizen_policy_deinit(headless_shell_t *shell)
1023 if (shell->tizen_policy)
1024 wl_global_destroy(shell->tizen_policy);
1028 headless_shell_send_visiblity(pepper_view_t *view, uint8_t visibility)
1030 pepper_surface_t *surface;
1031 headless_shell_surface_t *hs_surface;
1033 if (view == NULL) return;
1035 surface = pepper_view_get_surface(view);
1036 PEPPER_CHECK(surface, return, "[SHELL] Invalid object surface:%p\n", surface);
1038 hs_surface = pepper_object_get_user_data((pepper_object_t *)surface, pepper_surface_get_resource(surface));
1039 PEPPER_CHECK(hs_surface, return, "[SHELL] Invalid object headless_surface:%p\n", hs_surface);
1041 if (hs_surface->visibility == visibility) {
1042 PEPPER_TRACE("[SHELL] Same Visibility hs_surface:%p, visibility:%d\n", hs_surface, visibility);
1046 if (hs_surface->tizen_visibility)
1047 tizen_visibility_send_notify(hs_surface->tizen_visibility, visibility);
1049 hs_surface->visibility = visibility;
1050 PEPPER_TRACE("[SHELL] Set Visibility hs_surface:%p, visibility:%d\n", hs_surface, visibility);
1054 headless_shell_cb_idle(void *data)
1056 headless_shell_t *hs_shell = (headless_shell_t *)data;
1057 const pepper_list_t *list;
1058 pepper_list_t *l = NULL;
1059 pepper_view_t *view;
1060 pepper_surface_t *surface;
1061 headless_shell_surface_t *hs_surface;
1063 pepper_view_t *focus = NULL, *top = NULL, *top_visible = NULL;
1065 PEPPER_TRACE("[SHELL] Enter Idle\n");
1066 list = pepper_compositor_get_view_list(hs_shell->compositor);
1068 pepper_list_for_each_list(l, list) {
1071 view = (pepper_view_t *)l->item;
1072 PEPPER_CHECK(view, continue, "[SHELL] idle_cb, Invalid object view:%p\n", view);
1074 surface = pepper_view_get_surface(view);
1075 PEPPER_CHECK(surface, continue, "[SHELL] idle_cb, Invalid object surface:%p\n", surface);
1077 hs_surface = pepper_object_get_user_data((pepper_object_t *)surface, pepper_surface_get_resource(surface));
1078 PEPPER_CHECK(hs_surface, continue, "[SHELL] idle_cb, Invalid object headless_surface:%p\n", hs_surface);
1080 if (!pepper_view_is_mapped(view)) {
1081 headless_shell_send_visiblity(view, TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED);
1088 if (!focus && !hs_surface->skip_focus)
1091 if (!top_visible && pepper_surface_get_buffer(surface))
1094 if (top && focus && top_visible)
1098 if (top != hs_shell->top_mapped) {
1099 const pepper_list_t *l;
1102 PEPPER_TRACE("[SHELL] IDLE : top-view change: %p to %p\n", hs_shell->top_mapped , top);
1103 hs_shell->top_mapped = top;
1104 headless_input_set_top_view(hs_shell->compositor, hs_shell->top_mapped);
1105 headless_debug_set_top_view(hs_shell->compositor, hs_shell->top_mapped);
1107 /*Force update the output*/
1108 l = pepper_compositor_get_output_list(hs_shell->compositor);
1109 pepper_list_for_each_list(ll, l) {
1110 pepper_output_add_damage_region((pepper_output_t *)ll->item, NULL);
1114 if (focus != hs_shell->focus) {
1115 PEPPER_TRACE("[SHELL] IDLE : focus-view change: %p to %p\n", hs_shell->focus , focus);
1116 hs_shell->focus = focus;
1117 headless_input_set_focus_view(hs_shell->compositor, hs_shell->focus);
1118 headless_debug_set_focus_view(hs_shell->compositor, hs_shell->focus);
1121 if (top_visible != hs_shell->top_visible) {
1122 PEPPER_TRACE("[SHELL] IDLE : visible-view change: %p to %p\n", hs_shell->top_visible, top_visible);
1123 headless_shell_send_visiblity(hs_shell->top_visible, TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED);
1124 headless_shell_send_visiblity(top_visible, TIZEN_VISIBILITY_VISIBILITY_UNOBSCURED);
1125 hs_shell->top_visible = top_visible;
1128 hs_shell->cb_idle = NULL;
1132 headless_shell_cb_surface_commit(pepper_event_listener_t *listener,
1133 pepper_object_t *object,
1134 uint32_t id, void *info, void *data)
1136 headless_shell_surface_t * hs_surface = (headless_shell_surface_t *)data;
1138 PEPPER_CHECK(((pepper_object_t *)hs_surface->surface == object), return, "Invalid object\n");
1141 1. Check the changes(buffer, map status...)
1143 if (IS_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE)) {
1144 if (hs_surface->surface_type != HEADLESS_SURFACE_NONE)
1145 pepper_view_map(hs_surface->view);
1147 pepper_view_unmap(hs_surface->view);
1149 PEPPER_TRACE("Surface type change. view:%p, type:%d, res:%p\n", hs_surface->view, hs_surface->surface_type, hs_surface->zxdg_surface);
1152 hs_surface->updates = 0;
1154 headless_shell_add_idle(hs_surface->hs_shell);
1158 headless_shell_cb_surface_free(void *data)
1160 headless_shell_surface_t *surface = (headless_shell_surface_t *)data;
1162 PEPPER_TRACE("[SHELL] hs_surface free surface:%p, view:%p, zxdg_shell_surface:%p, zxdg_surface:%p\n",
1163 surface->surface, surface->view,
1164 surface->zxdg_shell_surface, surface->zxdg_surface);
1170 headless_shell_cb_surface_add(pepper_event_listener_t *listener,
1171 pepper_object_t *object,
1172 uint32_t id, void *info, void *data)
1174 headless_shell_surface_t *hs_surface;
1175 pepper_surface_t *surface = (pepper_surface_t *)info;
1177 hs_surface = (headless_shell_surface_t*)calloc(sizeof(headless_shell_surface_t), 1);
1178 PEPPER_CHECK(hs_surface, return, "fail to alloc for headless_shell_surface\n");
1180 hs_surface->hs_shell = (headless_shell_t *)data;
1181 hs_surface->surface = (pepper_surface_t *)surface;
1182 hs_surface->visibility = TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED;
1184 pepper_object_set_user_data((pepper_object_t *)surface,
1185 pepper_surface_get_resource(surface),
1187 headless_shell_cb_surface_free);
1188 PEPPER_TRACE("[SHELL] surface_Add: pepper_surface:%, headless_shell:%p to p\n", surface, hs_surface);
1192 headless_shell_cb_surface_remove(pepper_event_listener_t *listener,
1193 pepper_object_t *object,
1194 uint32_t id, void *info, void *data)
1196 headless_shell_surface_t *hs_surface;
1197 pepper_surface_t *surface = (pepper_surface_t *)info;
1199 hs_surface = pepper_object_get_user_data((pepper_object_t *)surface, pepper_surface_get_resource(surface));
1200 PEPPER_CHECK(hs_surface, return, "[SHELL] cb_surface_remove, Invalid object headless_surface:%p\n", hs_surface);
1201 PEPPER_TRACE("[SHELL] surface_remove: pepper_surface:%p, headless_shell:%p\n", object, hs_surface);
1203 if (hs_surface->zxdg_surface) {
1204 wl_resource_set_user_data(hs_surface->zxdg_surface, NULL);
1205 hs_surface->zxdg_surface = NULL;
1208 if (hs_surface->zxdg_shell_surface) {
1209 wl_resource_set_user_data(hs_surface->zxdg_shell_surface, NULL);
1210 hs_surface->zxdg_shell_surface = NULL;
1213 if (hs_surface->view) {
1214 pepper_view_destroy(hs_surface->view);
1215 hs_surface->view = NULL;
1218 SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE);
1219 headless_shell_add_idle(hs_surface->hs_shell);
1223 headless_shell_cb_view_remove(pepper_event_listener_t *listener,
1224 pepper_object_t *object,
1225 uint32_t id, void *info, void *data)
1227 pepper_view_t *view = (pepper_view_t *)info;
1228 headless_shell_t *shell = (headless_shell_t *)data;
1230 if (view == shell->top_mapped)
1231 shell->top_mapped = NULL;
1233 if (view == shell->top_visible)
1234 shell->top_visible = NULL;
1236 if (view == shell->focus)
1237 shell->focus = NULL;
1239 headless_shell_add_idle(shell);
1243 headless_shell_add_idle(headless_shell_t *shell)
1245 struct wl_event_loop *loop;
1247 if (!shell || shell->cb_idle)
1250 loop = wl_display_get_event_loop(pepper_compositor_get_display(shell->compositor));
1251 PEPPER_CHECK(loop, return, "fail to get event loop\n");
1253 shell->cb_idle = wl_event_loop_add_idle(loop, headless_shell_cb_idle, shell);
1254 PEPPER_CHECK(shell->cb_idle, return, "fail to add idle\n");
1258 headless_shell_init_listeners(headless_shell_t *shell)
1260 shell->surface_add_listener = pepper_object_add_event_listener((pepper_object_t *)shell->compositor,
1261 PEPPER_EVENT_COMPOSITOR_SURFACE_ADD,
1262 0, headless_shell_cb_surface_add, shell);
1264 shell->surface_remove_listener = pepper_object_add_event_listener((pepper_object_t *)shell->compositor,
1265 PEPPER_EVENT_COMPOSITOR_SURFACE_REMOVE,
1266 0, headless_shell_cb_surface_remove, shell);
1268 shell->view_remove_listener = pepper_object_add_event_listener((pepper_object_t *)shell->compositor,
1269 PEPPER_EVENT_COMPOSITOR_VIEW_REMOVE,
1270 0, headless_shell_cb_view_remove, shell);
1274 headless_shell_deinit_listeners(headless_shell_t *shell)
1276 pepper_event_listener_remove(shell->surface_add_listener);
1277 pepper_event_listener_remove(shell->surface_remove_listener);
1278 pepper_event_listener_remove(shell->view_remove_listener);
1282 headless_shell_destroy(headless_shell_t *shell)
1288 wl_event_source_remove(shell->cb_idle);
1290 headless_shell_deinit_listeners(shell);
1292 tizen_policy_deinit(shell);
1296 headless_shell_deinit(pepper_compositor_t *compositor)
1298 headless_shell_t *shell;
1300 PEPPER_CHECK(compositor, return, "compositor is NULL\n");
1302 shell = (headless_shell_t *)pepper_object_get_user_data((pepper_object_t *)compositor, &KEY_SHELL);
1303 PEPPER_CHECK(shell, return, "shell is NULL\n");
1305 headless_shell_destroy(shell);
1307 pepper_object_set_user_data((pepper_object_t *)shell->compositor, &KEY_SHELL, NULL, NULL);
1312 headless_shell_init(pepper_compositor_t *compositor)
1314 headless_shell_t *shell;
1316 shell = (headless_shell_t*)calloc(sizeof(headless_shell_t), 1);
1317 PEPPER_CHECK(shell, goto error, "fail to alloc for shell\n");
1318 shell->compositor = compositor;
1320 headless_shell_init_listeners(shell);
1321 PEPPER_CHECK(zxdg_init(shell), goto error, "zxdg_init() failed\n");
1322 PEPPER_CHECK(tizen_policy_init(shell), goto error, "tizen_policy_init() failed\n");
1324 pepper_object_set_user_data((pepper_object_t *)compositor, &KEY_SHELL, shell, NULL);
1330 headless_shell_destroy(shell);
1333 return PEPPER_FALSE;