From: Seunghun Lee Date: Mon, 25 Jul 2022 04:41:21 +0000 (+0900) Subject: shell: Split into multiple files X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a4bb61d90c7587f74becfbc5643ce12006bedd0c;p=platform%2Fcore%2Fuifw%2Fheadless-server.git shell: Split into multiple files This organizes the headless_shell implementation into separate files. No functional changes, just moving code around. Change-Id: Ibf793a2af4dc0860b8d067f2c5dc5b731535477c --- diff --git a/src/Makefile.am b/src/Makefile.am index 13fb3ed..7ed8588 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,5 +10,7 @@ headless_server_SOURCES = headless_server.c \ output/HL_UI_LED_APA102.c \ output/boot_anim.c \ shell/shell.c \ + shell/xdg_shell_v6.c \ + shell/tizen_policy.c \ debug/debug.c \ input/input.c diff --git a/src/headless_server.c b/src/headless_server.c index 3a4c6d8..576df9a 100644 --- a/src/headless_server.c +++ b/src/headless_server.c @@ -31,6 +31,7 @@ #include #include +#include #include "headless_server.h" diff --git a/src/headless_server.h b/src/headless_server.h index 4697281..ed3c5ab 100644 --- a/src/headless_server.h +++ b/src/headless_server.h @@ -31,7 +31,6 @@ extern "C" { #include #include -#include #include #include #include @@ -63,9 +62,9 @@ typedef struct headless_view headless_view_t; typedef struct led_output led_output_t; -typedef struct HEADLESS_SHELL headless_shell_t; +typedef struct headless_shell headless_shell_t; -typedef struct HEADLESS_SHELL_SURFACE headless_shell_surface_t; +typedef struct headless_shell_surface headless_shell_surface_t; typedef struct headless_debug headless_debug_t; diff --git a/src/shell/shell.c b/src/shell/shell.c index c74a264..69debca 100644 --- a/src/shell/shell.c +++ b/src/shell/shell.c @@ -21,1127 +21,9 @@ * DEALINGS IN THE SOFTWARE. */ -#include -#include #include -#include -#include -#include -#include - -#include "headless_server.h" - -#define UPDATE_SURFACE_TYPE 0 //update the surface_type(map. unmap) -#define SET_UPDATE(x, type) (x |= ((uint32_t)(1<surface_type == HEADLESS_SURFACE_POPUP), return, - "Invalid surface type.\n"); - HS_CHECK((hs_surface->zxdg_surface == resource), return, - "Invalid surface."); - - hs_surface->surface_type = HEADLESS_SURFACE_NONE; - hs_surface->zxdg_surface = NULL; - SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE); -} - -static void -zxdg_popup_cb_destroy(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -zxdg_popup_cb_grab(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *res_seat, - uint32_t serial) -{ -} - -static const struct zxdg_popup_v6_interface zxdg_popup_interface = { - zxdg_popup_cb_destroy, - zxdg_popup_cb_grab -}; - -static void -zxdg_surface_cb_resource_destroy(struct wl_resource *resource) -{ - headless_shell_surface_t *hs_surface; - - hs_surface = wl_resource_get_user_data(resource); - if (!hs_surface) - return; - - HS_TRACE("[SHELL] zxdg_surface_cb_resource_destroy: hs_surface:%p", - hs_surface); - - destroy_headless_shell_surface(hs_surface); -} - -static void -zxdg_surface_cb_destroy(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -headless_toplevel_handle_surface_commit(struct ds_surface *ds_surface) -{ - headless_shell_surface_t *hs_surface; - - hs_surface = ds_surface_get_role_data(ds_surface); - if (!hs_surface) - return; - - if (!hs_surface->added) { - hs_surface->added = true; - wl_signal_emit(&hs_surface->hs_shell->events.new_surface, hs_surface); - } - - if (ds_surface_get_buffer(hs_surface->ds_surface) && - !hs_surface->mapped) { - map_headless_shell_surface(hs_surface); - } - else if (!ds_surface_get_buffer(hs_surface->ds_surface) && - hs_surface->mapped) { - unmap_headless_shell_surface(hs_surface); - } -} - -static const struct ds_surface_role xdg_toplevel_role = { - .name = "headless_shell_surface", - .commit = headless_toplevel_handle_surface_commit, -}; - -static void -zxdg_surface_cb_toplevel_get(struct wl_client *client, - struct wl_resource *resource, uint32_t id) -{ - headless_shell_surface_t *hs_surface; - struct wl_resource *new_res; - - hs_surface = wl_resource_get_user_data(resource); - HS_CHECK(hs_surface, return, "fail to get headless_surface\n"); - - if (!ds_surface_set_role(hs_surface->ds_surface, &xdg_toplevel_role, - hs_surface, resource, ZXDG_SHELL_V6_ERROR_ROLE)) - return; - - if (hs_surface->surface_type != HEADLESS_SURFACE_NONE) { - wl_resource_post_error(hs_surface->zxdg_shell_surface, - ZXDG_SURFACE_V6_ERROR_ALREADY_CONSTRUCTED, - "xdg-surface has already been constructed"); - return; - } - - new_res = wl_resource_create(client, &zxdg_toplevel_v6_interface, 1, id); - if (!new_res) { - HS_ERROR("fail to create zxdg_toplevel"); - wl_resource_post_no_memory(resource); - return; - } - - wl_resource_set_implementation(new_res, - &zxdg_toplevel_interface, - hs_surface, - zxdg_toplevel_cb_resource_destroy); - - hs_surface->surface_type = HEADLESS_SURFACE_TOPLEVEL; - hs_surface->zxdg_surface = new_res; -} - -static void -zxdg_surface_cb_popup_get(struct wl_client *client, - struct wl_resource *resource, - uint32_t id, - struct wl_resource *res_parent, - struct wl_resource *res_pos) -{ - headless_shell_surface_t *hs_surface; - struct wl_resource *new_res; - - hs_surface = wl_resource_get_user_data(resource); - HS_CHECK(hs_surface, return, "fail to get headless_surface\n"); - HS_CHECK((hs_surface->zxdg_surface == NULL), return, - "alwreay assign zdg_surface:%p role:%d\n", - hs_surface->zxdg_surface, hs_surface->surface_type); - - new_res = wl_resource_create(client, &zxdg_popup_v6_interface, 1, id); - if (!new_res) { - HS_ERROR("fail to create popup"); - wl_resource_post_no_memory(resource); - return; - } - - wl_resource_set_implementation(new_res, - &zxdg_popup_interface, - hs_surface, - zxdg_popup_cb_resource_destroy); - - hs_surface->surface_type = HEADLESS_SURFACE_POPUP; - hs_surface->zxdg_surface = new_res; - - SET_UPDATE(hs_surface->updates, UPDATE_SURFACE_TYPE); -} - -static void -zxdg_surface_cb_win_geometry_set(struct wl_client *client, - struct wl_resource *resource, - int32_t x, int32_t y, int32_t w, int32_t h) -{ -} - -static void -zxdg_surface_cb_configure_ack(struct wl_client *client, - struct wl_resource *resource, uint32_t serial) -{ - headless_shell_surface_t *hs_surface; - - hs_surface = wl_resource_get_user_data(resource); - HS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n"); - - hs_surface->last_ack_configure = serial; -} - -static const struct zxdg_surface_v6_interface zxdg_surface_interface = { - zxdg_surface_cb_destroy, - zxdg_surface_cb_toplevel_get, - zxdg_surface_cb_popup_get, - zxdg_surface_cb_win_geometry_set, - zxdg_surface_cb_configure_ack -}; - -static void -zxdg_positioner_cb_destroy(struct wl_client *client, - struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -zxdg_positioner_cb_size_set(struct wl_client *client, - struct wl_resource *resource, int32_t w, int32_t h) -{ -} - -static void -zxdg_positioner_cb_anchor_rect_set(struct wl_client *client, - struct wl_resource *resource, - int32_t x, int32_t y, int32_t w, int32_t h) -{ -} - -static void -zxdg_positioner_cb_anchor_set(struct wl_client *client, - struct wl_resource *resource, enum zxdg_positioner_v6_anchor anchor) -{ -} - -static void -zxdg_positioner_cb_gravity_set(struct wl_client *client, - struct wl_resource *resource, enum zxdg_positioner_v6_gravity gravity) -{ -} - -static void -zxdg_positioner_cb_constraint_adjustment_set(struct wl_client *client, - struct wl_resource *resource, - enum zxdg_positioner_v6_constraint_adjustment constraint_adjustment) -{ -} - -static void -zxdg_positioner_cb_offset_set(struct wl_client *client, - struct wl_resource *resource, int32_t x, int32_t y) -{ -} - -static const struct zxdg_positioner_v6_interface zxdg_positioner_interface = { - zxdg_positioner_cb_destroy, - zxdg_positioner_cb_size_set, - zxdg_positioner_cb_anchor_rect_set, - zxdg_positioner_cb_anchor_set, - zxdg_positioner_cb_gravity_set, - zxdg_positioner_cb_constraint_adjustment_set, - zxdg_positioner_cb_offset_set, -}; - -static void -zxdg_shell_cb_destroy(struct wl_client *client, struct wl_resource *resource) -{ - HS_TRACE("Destroy zxdg_shell\n"); - - wl_resource_destroy(resource); -} - -static void -zxdg_shell_cb_positioner_create(struct wl_client *client, - struct wl_resource *resource, uint32_t id) -{ - struct wl_resource *new_res; - - HS_TRACE("Create zxdg_positoiner\n"); - - new_res = wl_resource_create(client, &zxdg_positioner_v6_interface, 1, id); - if (!new_res) { - HS_ERROR("fail to create zxdg_positioner\n"); - wl_resource_post_no_memory(resource); - return; - } - - wl_resource_set_implementation(new_res, &zxdg_positioner_interface, - NULL, NULL); -} - -static void -map_headless_shell_surface(headless_shell_surface_t *hs_surface) -{ - if (hs_surface->mapped) - return; - - hs_surface->mapped = true; - wl_signal_emit(&hs_surface->events.map, hs_surface); -} - -static void -unmap_headless_shell_surface(headless_shell_surface_t *hs_surface) -{ - if (!hs_surface->mapped) - return; - - hs_surface->mapped = false; - wl_signal_emit(&hs_surface->events.unmap, hs_surface); -} - -static void -reset_headless_shell_surface(headless_shell_surface_t *hs_surface) -{ - if (hs_surface->surface_type != HEADLESS_SURFACE_NONE) - unmap_headless_shell_surface(hs_surface); - - if (hs_surface->added) { - wl_signal_emit(&hs_surface->events.destroy, hs_surface); - hs_surface->added = false; - } - - if (hs_surface->zxdg_surface) { - wl_resource_set_user_data(hs_surface->zxdg_surface, NULL); - hs_surface->zxdg_surface = NULL; - } - - hs_surface->surface_type = HEADLESS_SURFACE_NONE; -} - -static void -destroy_headless_shell_surface(headless_shell_surface_t *hs_surface) -{ - HS_TRACE("[SHELL] hs_surface free ds_surface:%p, " - "zxdg_shell_surface:%p, zxdg_surface:%p", - hs_surface->ds_surface, hs_surface->zxdg_shell_surface, - hs_surface->zxdg_surface); - - reset_headless_shell_surface(hs_surface); - - wl_resource_set_user_data(hs_surface->zxdg_shell_surface, NULL); - - if (hs_surface->tizen_visibility) - wl_resource_set_user_data(hs_surface->tizen_visibility, NULL); - - ds_surface_reset_role_data(hs_surface->ds_surface); - - wl_list_remove(&hs_surface->surface_destroy.link); - - free(hs_surface); -} - -static void -headless_shell_surface_cb_surface_destroy(struct wl_listener *listener, - void *data) -{ - headless_shell_surface_t *hs_surface; - - hs_surface = wl_container_of(listener, hs_surface, surface_destroy); - destroy_headless_shell_surface(hs_surface); -} - -static void -zxdg_shell_cb_surface_get(struct wl_client *client, - struct wl_resource *resource, uint32_t id, - struct wl_resource *wsurface) -{ - headless_shell_t *hs; - headless_shell_surface_t *hs_surface = NULL; - struct ds_surface *ds_surface; - - hs = wl_resource_get_user_data(resource); - if (!hs) { - HS_ERROR("fail to get headless_shell\n"); - wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "failed to get headless shell"); - return; - } - - ds_surface = ds_surface_from_resource(wsurface); - HS_CHECK(ds_surface, goto error, "faile to get ds_surface\n"); - - hs_surface = calloc(1, sizeof *hs_surface); - if (!hs_surface) { - wl_resource_post_no_memory(resource); - return; - } - - hs_surface->hs_shell = hs; - hs_surface->ds_surface = ds_surface; - hs_surface->visibility = TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED; - - wl_signal_init(&hs_surface->events.destroy); - wl_signal_init(&hs_surface->events.map); - wl_signal_init(&hs_surface->events.unmap); - wl_signal_init(&hs_surface->events.request_activate); - wl_signal_init(&hs_surface->events.set_skip_focus); - wl_signal_init(&hs_surface->events.unset_skip_focus); - - hs_surface->zxdg_shell_surface = wl_resource_create(client, - &zxdg_surface_v6_interface, 1, id); - if (!hs_surface->zxdg_shell_surface) { - HS_ERROR("fail to create the zxdg_surface\n"); - wl_resource_post_no_memory(resource); - goto error; - } - - wl_resource_set_implementation(hs_surface->zxdg_shell_surface, - &zxdg_surface_interface, - hs_surface, - zxdg_surface_cb_resource_destroy); - - hs_surface->surface_destroy.notify = - headless_shell_surface_cb_surface_destroy; - ds_surface_add_destroy_listener(ds_surface, &hs_surface->surface_destroy); - - HS_TRACE("[SHELL] create zxdg_surface:%p, ds_surface:%p\n", - hs_surface->zxdg_shell_surface, - hs_surface->ds_surface); - - return; -error: - if (hs_surface) { - if (hs_surface->zxdg_shell_surface) { - wl_resource_destroy(hs_surface->zxdg_shell_surface); - hs_surface->zxdg_shell_surface = NULL; - } - - free(hs_surface); - } -} - -static void -zxdg_shell_cb_pong(struct wl_client *client, struct wl_resource *resource, - uint32_t serial) -{ - -} - -static const struct zxdg_shell_v6_interface zxdg_shell_interface = { - zxdg_shell_cb_destroy, - zxdg_shell_cb_positioner_create, - zxdg_shell_cb_surface_get, - zxdg_shell_cb_pong -}; - -static void -zxdg_shell_cb_bind(struct wl_client *client, void *data, uint32_t version, - uint32_t id) -{ - struct wl_resource *resource; - headless_shell_t *hs = (headless_shell_t *)data; - - HS_TRACE("Bind zxdg_shell\n"); - - /* Create resource for zxdg_shell_v6 */ - resource = wl_resource_create(client, &zxdg_shell_v6_interface, - version, id); - HS_CHECK(resource, goto err_shell, "fail to create the zxdg_shell_v6\n"); - - wl_resource_set_implementation(resource, &zxdg_shell_interface, hs, NULL); - - return; -err_shell: - wl_client_post_no_memory(client); -} - -static bool -zxdg_init(headless_shell_t *shell) -{ - shell->zxdg_shell = wl_global_create(shell->display, - &zxdg_shell_v6_interface, 1, shell, zxdg_shell_cb_bind); - HS_CHECK(shell->zxdg_shell, return false, "fail to create zxdg_shell\n"); - - return true; -} - -void -zxdg_deinit(headless_shell_t *shell) -{ - if (shell->zxdg_shell) - wl_global_destroy(shell->zxdg_shell); -} - -static void -tizen_visibility_cb_destroy(struct wl_client *client, - struct wl_resource *res_tzvis) -{ - wl_resource_destroy(res_tzvis); -} - -static const struct tizen_visibility_interface tizen_visibility = -{ - tizen_visibility_cb_destroy -}; - -static void -tizen_visibility_cb_vis_destroy(struct wl_resource *res_tzvis) -{ - headless_shell_surface_t *hs_surface; - - hs_surface = wl_resource_get_user_data(res_tzvis); - if (!hs_surface) - return; - - hs_surface->tizen_visibility = NULL; -} - -static void -tizen_position_cb_destroy(struct wl_client *client, - struct wl_resource *res_tzpos) -{ - wl_resource_destroy(res_tzpos); -} - -static void -tizen_position_cb_set(struct wl_client *client, struct wl_resource *res_tzpos, - int32_t x, int32_t y) -{ -} - -static const struct tizen_position_interface tizen_position = { - tizen_position_cb_destroy, - tizen_position_cb_set, -}; - -static void -tizen_position_cb_pos_destroy(struct wl_resource *res_tzpos) -{ -} - -static headless_shell_surface_t * -headless_shell_surface_from_ds_surface(struct ds_surface *ds_surface) -{ - if (ds_surface_get_role(ds_surface) != &xdg_toplevel_role) - return NULL; - return ds_surface_get_role_data(ds_surface); -} - -static void -tizen_policy_cb_vis_get(struct wl_client *client, struct wl_resource *resource, - uint32_t id, struct wl_resource *surf) -{ - struct ds_surface *ds_surface; - headless_shell_surface_t *hs_surface; - struct wl_resource *new_res; - - ds_surface = ds_surface_from_resource(surf); - HS_CHECK(ds_surface, return, "fail to get ds_surface_t\n"); - - hs_surface = headless_shell_surface_from_ds_surface(ds_surface); - HS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n"); - - new_res = wl_resource_create(client, &tizen_visibility_interface, 5, id); - if (!new_res) { - HS_ERROR("fail to create tizen_visibility"); - wl_resource_post_no_memory(resource); - return; - } - - wl_resource_set_implementation(new_res, - &tizen_visibility, - hs_surface, - tizen_visibility_cb_vis_destroy); - - hs_surface->tizen_visibility = new_res; - - if (hs_surface->visibility != TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED) { - tizen_visibility_send_notify(hs_surface->tizen_visibility, - hs_surface->visibility); - } -} - -static void -tizen_policy_cb_pos_get(struct wl_client *client, struct wl_resource *resource, - uint32_t id, struct wl_resource *surf) -{ - struct wl_resource *new_res; - - new_res = wl_resource_create(client, &tizen_position_interface, 1, id); - if (!new_res) { - HS_ERROR("fail to create tizen_visibility"); - wl_resource_post_no_memory(resource); - return; - } - - wl_resource_set_implementation(new_res, &tizen_position, NULL, - tizen_position_cb_pos_destroy); -} - -static void -tizen_policy_cb_activate(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf) -{ - struct ds_surface *ds_surface; - headless_shell_surface_t *hs_surface; - - ds_surface = ds_surface_from_resource(surf); - HS_CHECK(ds_surface, return, "fail to get ds_surface\n"); - - hs_surface = headless_shell_surface_from_ds_surface(ds_surface); - HS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n"); - - wl_signal_emit(&hs_surface->events.request_activate, hs_surface); -} - -static void -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) -{ -} - -static void -tizen_policy_cb_raise(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *surf) -{ -} - -static void -tizen_policy_cb_lower(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *surf) -{ -} - -static void -tizen_policy_cb_lower_by_res_id(struct wl_client *client, - struct wl_resource *resource, uint32_t res_id) -{ -} - -static void -tizen_policy_cb_focus_skip_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf) -{ - struct ds_surface *ds_surface; - headless_shell_surface_t *hs_surface; - - ds_surface = ds_surface_from_resource(surf); - HS_CHECK(ds_surface, return, "fail to get ds_surface\n"); - - hs_surface = headless_shell_surface_from_ds_surface(ds_surface); - HS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n"); - - wl_signal_emit(&hs_surface->events.set_skip_focus, hs_surface); -} - -static void -tizen_policy_cb_focus_skip_unset(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf) -{ - struct ds_surface *ds_surface; - headless_shell_surface_t *hs_surface; - - ds_surface = ds_surface_from_resource(surf); - HS_CHECK(ds_surface, return, "fail to get ds_surface\n"); - - hs_surface = headless_shell_surface_from_ds_surface(ds_surface); - HS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n"); - - wl_signal_emit(&hs_surface->events.unset_skip_focus, hs_surface); -} - -static void -tizen_policy_cb_role_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf, - const char *role) -{ -} - -static void -tizen_policy_cb_type_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf, uint32_t type) -{ -} - -static void -tizen_policy_cb_conformant_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf) -{ -} - -static void -tizen_policy_cb_conformant_unset(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf) -{ -} - -static void -tizen_policy_cb_conformant_get(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf) -{ - tizen_policy_send_conformant(resource, surf, 0); -} - -static void -tizen_policy_cb_notilv_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf, int32_t lv) -{ -} - -static void -tizen_policy_cb_transient_for_set(struct wl_client *client, - struct wl_resource *resource, uint32_t child_id, uint32_t parent_id) -{ -} - -static void -tizen_policy_cb_transient_for_unset(struct wl_client *client, - struct wl_resource *resource, uint32_t child_id) -{ - tizen_policy_send_transient_for_done(resource, child_id); -} - -static void -tizen_policy_cb_win_scrmode_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf, uint32_t mode) -{ - tizen_policy_send_window_screen_mode_done - (resource, surf, mode, TIZEN_POLICY_ERROR_STATE_NONE); -} - -static void -tizen_policy_cb_subsurf_place_below_parent(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *subsurf) -{ -} - -static void -tizen_policy_cb_subsurf_stand_alone_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *subsurf) -{ -} - -static void -tizen_policy_cb_subsurface_get(struct wl_client *client, - struct wl_resource *resource, uint32_t id, struct wl_resource *surface, - uint32_t parent_id) -{ - wl_client_post_implementation_error(client, - "Headless server not support tizen_subsurface\n"); -} - -static void -tizen_policy_cb_opaque_state_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface, - int32_t state) -{ -} - -static void -tizen_policy_cb_iconify(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *surf) -{ -} - -static void -tizen_policy_cb_uniconify(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf) -{ -} - -static void -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) -{ -} - -static void -tizen_policy_cb_aux_hint_change(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf, int32_t id, - const char *value) -{ -} - -static void -tizen_policy_cb_aux_hint_del(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf, int32_t id) -{ -} - -static void -tizen_policy_cb_supported_aux_hints_get(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf) -{ -} - -static void -tizen_policy_cb_background_state_set(struct wl_client *client, - struct wl_resource *resource, uint32_t pid) -{ -} - -static void -tizen_policy_cb_background_state_unset(struct wl_client *client, - struct wl_resource *resource, uint32_t pid) -{ -} - -static void -tizen_policy_cb_floating_mode_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf) -{ -} - -static void -tizen_policy_cb_floating_mode_unset(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf) -{ -} - -static void -tizen_policy_cb_stack_mode_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surf, uint32_t mode) -{ -} - -static void -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) -{ -} - -static void -tizen_policy_cb_subsurf_watcher_get(struct wl_client *client, - struct wl_resource *resource, uint32_t id, struct wl_resource *surface) -{ - wl_client_post_implementation_error(client, - "Headless server not support tizen_subsurface\n"); -} - -static void -tizen_policy_cb_parent_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *child, - struct wl_resource *parent) -{ -} - -static void -tizen_policy_cb_ack_conformant_region(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface, - uint32_t serial) -{ -} - -static void -tizen_policy_cb_destroy(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -tizen_policy_cb_has_video(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface, - uint32_t has) -{ -} - -static const struct tizen_policy_interface tizen_policy_iface = { - tizen_policy_cb_vis_get, - tizen_policy_cb_pos_get, - tizen_policy_cb_activate, - tizen_policy_cb_activate_below_by_res_id, - tizen_policy_cb_raise, - tizen_policy_cb_lower, - tizen_policy_cb_lower_by_res_id, - tizen_policy_cb_focus_skip_set, - tizen_policy_cb_focus_skip_unset, - tizen_policy_cb_role_set, - tizen_policy_cb_type_set, - tizen_policy_cb_conformant_set, - tizen_policy_cb_conformant_unset, - tizen_policy_cb_conformant_get, - tizen_policy_cb_notilv_set, - tizen_policy_cb_transient_for_set, - tizen_policy_cb_transient_for_unset, - tizen_policy_cb_win_scrmode_set, - tizen_policy_cb_subsurf_place_below_parent, - tizen_policy_cb_subsurf_stand_alone_set, - tizen_policy_cb_subsurface_get, - tizen_policy_cb_opaque_state_set, - tizen_policy_cb_iconify, - tizen_policy_cb_uniconify, - tizen_policy_cb_aux_hint_add, - tizen_policy_cb_aux_hint_change, - tizen_policy_cb_aux_hint_del, - tizen_policy_cb_supported_aux_hints_get, - tizen_policy_cb_background_state_set, - tizen_policy_cb_background_state_unset, - tizen_policy_cb_floating_mode_set, - tizen_policy_cb_floating_mode_unset, - tizen_policy_cb_stack_mode_set, - tizen_policy_cb_activate_above_by_res_id, - tizen_policy_cb_subsurf_watcher_get, - tizen_policy_cb_parent_set, - tizen_policy_cb_ack_conformant_region, - tizen_policy_cb_destroy, - tizen_policy_cb_has_video, -}; - -static void -tizen_policy_cb_unbind(struct wl_resource *resource) -{ - headless_shell_t *shell; - - shell = wl_resource_get_user_data(resource); - if (shell) - shell->tizen_policy = NULL; -} - -static void -tizen_policy_cb_bind(struct wl_client *client, void *data, uint32_t ver, - uint32_t id) -{ - headless_shell_t *shell = (headless_shell_t *)data; - struct wl_resource *resource; - - HS_CHECK(shell, goto err, "data is NULL\n"); - - resource = wl_resource_create(client, &tizen_policy_interface, ver, id); - HS_CHECK(resource, goto err, "fail to create tizen_policy\n"); - - wl_resource_set_implementation(resource, &tizen_policy_iface, shell, - tizen_policy_cb_unbind); - return; - -err: - wl_client_post_no_memory(client); -} - -static bool -tizen_policy_init(headless_shell_t *shell) -{ - shell->tizen_policy = wl_global_create(shell->display, - &tizen_policy_interface, 7, shell, tizen_policy_cb_bind); - HS_CHECK(shell->tizen_policy, return false, - "faile to create tizen_policy\n"); - - return true; -} - -void -tizen_policy_deinit(headless_shell_t *shell) -{ - if (shell->tizen_policy) - wl_global_destroy(shell->tizen_policy); -} +#include "shell.h" void headless_shell_destroy(headless_shell_t *shell) @@ -1149,8 +31,8 @@ headless_shell_destroy(headless_shell_t *shell) if (!shell) return; - zxdg_deinit(shell); - tizen_policy_deinit(shell); + xdg_shell_v6_finish(shell); + tizen_policy_finish(shell); free(shell); } @@ -1166,7 +48,8 @@ headless_shell_create(struct wl_display *display) wl_signal_init(&shell->events.new_surface); - HS_CHECK(zxdg_init(shell), goto error, "zxdg_init() failed\n"); + HS_CHECK(xdg_shell_v6_init(shell), goto error, + "xdg_shell_v6_init() failed\n"); HS_CHECK(tizen_policy_init(shell), goto error, "tizen_policy_init() failed\n"); @@ -1184,75 +67,3 @@ headless_shell_add_new_surface_listener(headless_shell_t *shell, { wl_signal_add(&shell->events.new_surface, listener); } - -void -headless_shell_surface_add_destroy_listener( - headless_shell_surface_t *hs_surface, struct wl_listener *listener) -{ - wl_signal_add(&hs_surface->events.destroy, listener); -} - -void -headless_shell_surface_add_map_listener( - headless_shell_surface_t *hs_surface, struct wl_listener *listener) -{ - wl_signal_add(&hs_surface->events.map, listener); -} - -void -headless_shell_surface_add_unmap_listener( - headless_shell_surface_t *hs_surface, struct wl_listener *listener) -{ - wl_signal_add(&hs_surface->events.unmap, listener); -} - -void -headless_shell_surface_add_request_activate_listener( - headless_shell_surface_t *hs_surface, struct wl_listener *listener) -{ - wl_signal_add(&hs_surface->events.request_activate, listener); -} - -void -headless_shell_surface_add_set_skip_focus_listener( - headless_shell_surface_t *hs_surface, struct wl_listener *listener) -{ - wl_signal_add(&hs_surface->events.set_skip_focus, listener); -} - -void -headless_shell_surface_add_unset_skip_focus_listener( - headless_shell_surface_t *hs_surface, struct wl_listener *listener) -{ - wl_signal_add(&hs_surface->events.unset_skip_focus, listener); -} - -struct ds_surface * -headless_shell_surface_get_surface(headless_shell_surface_t *hs_surface) -{ - return hs_surface->ds_surface; -} - -void -headless_shell_send_visibility(headless_shell_surface_t *hs_surface, - uint8_t visibility) -{ - if (hs_surface->visibility == visibility) { - HS_TRACE("[SHELL] Same Visibility hs_surface:%p, visibility:%d\n", - hs_surface, visibility); - return; - } - - if (hs_surface->tizen_visibility) - tizen_visibility_send_notify(hs_surface->tizen_visibility, visibility); - - hs_surface->visibility = visibility; - HS_TRACE("[SHELL] Set Visibility hs_surface:%p, visibility:%d\n", - hs_surface, visibility); -} - -struct wl_resource * -headless_shell_surface_get_resource(headless_shell_surface_t *hs_surface) -{ - return hs_surface->zxdg_shell_surface; -} diff --git a/src/shell/shell.h b/src/shell/shell.h new file mode 100644 index 0000000..14886c1 --- /dev/null +++ b/src/shell/shell.h @@ -0,0 +1,65 @@ +#ifndef HEADLESS_SHELL_H +#define HEADLESS_SHELL_H + +#include +#include +#include +#include + +#include "headless_server.h" + +typedef struct headless_shell headless_shell_t; +typedef struct headless_shell_surface headless_shell_surface_t; + +typedef enum { + HEADLESS_SURFACE_NONE, + HEADLESS_SURFACE_TOPLEVEL, + HEADLESS_SURFACE_POPUP +} headless_surface_type_t; + +struct headless_shell { + struct wl_display *display; + struct wl_global *zxdg_shell; + struct wl_global *tizen_policy; + struct wl_event_source *cb_idle; + + struct { + struct wl_signal new_surface; + } events; +}; + +struct headless_shell_surface { + headless_shell_t *hs_shell; + struct ds_surface *ds_surface; + uint8_t visibility; + + headless_surface_type_t surface_type; + struct wl_resource *zxdg_shell_surface; + struct wl_resource *zxdg_surface; /*resource of toplevel, popup and etc*/ + struct wl_resource *tizen_visibility; + uint32_t last_ack_configure; + + struct wl_listener surface_destroy; + + struct { + struct wl_signal destroy; + struct wl_signal map; + struct wl_signal unmap; + struct wl_signal request_activate; + struct wl_signal set_skip_focus; + struct wl_signal unset_skip_focus; + } events; + + bool added; + bool mapped; +}; + +bool xdg_shell_v6_init(headless_shell_t *shell); +void xdg_shell_v6_finish(headless_shell_t *shell); +headless_shell_surface_t * +headless_shell_surface_from_ds_surface(struct ds_surface *ds_surface); + +bool tizen_policy_init(headless_shell_t *shell); +void tizen_policy_finish(headless_shell_t *shell); + +#endif diff --git a/src/shell/tizen_policy.c b/src/shell/tizen_policy.c new file mode 100644 index 0000000..59f2b06 --- /dev/null +++ b/src/shell/tizen_policy.c @@ -0,0 +1,492 @@ +#include "shell.h" + +static void tizen_policy_cb_bind(struct wl_client *client, void *data, + uint32_t ver, uint32_t id); + +bool +tizen_policy_init(headless_shell_t *shell) +{ + shell->tizen_policy = wl_global_create(shell->display, + &tizen_policy_interface, 7, shell, tizen_policy_cb_bind); + HS_CHECK(shell->tizen_policy, return false, + "faile to create tizen_policy\n"); + + return true; +} + +void +tizen_policy_finish(headless_shell_t *shell) +{ + if (shell->tizen_policy) + wl_global_destroy(shell->tizen_policy); +} + +void +headless_shell_surface_add_set_skip_focus_listener( + headless_shell_surface_t *hs_surface, struct wl_listener *listener) +{ + wl_signal_add(&hs_surface->events.set_skip_focus, listener); +} + +void +headless_shell_surface_add_unset_skip_focus_listener( + headless_shell_surface_t *hs_surface, struct wl_listener *listener) +{ + wl_signal_add(&hs_surface->events.unset_skip_focus, listener); +} + +void +headless_shell_send_visibility(headless_shell_surface_t *hs_surface, + uint8_t visibility) +{ + if (hs_surface->visibility == visibility) { + HS_TRACE("[SHELL] Same Visibility hs_surface:%p, visibility:%d\n", + hs_surface, visibility); + return; + } + + if (hs_surface->tizen_visibility) + tizen_visibility_send_notify(hs_surface->tizen_visibility, visibility); + + hs_surface->visibility = visibility; + HS_TRACE("[SHELL] Set Visibility hs_surface:%p, visibility:%d\n", + hs_surface, visibility); +} + +static void +tizen_visibility_cb_destroy(struct wl_client *client, + struct wl_resource *res_tzvis) +{ + wl_resource_destroy(res_tzvis); +} + +static const struct tizen_visibility_interface tizen_visibility = +{ + tizen_visibility_cb_destroy +}; + +static void +tizen_visibility_cb_vis_destroy(struct wl_resource *res_tzvis) +{ + headless_shell_surface_t *hs_surface; + + hs_surface = wl_resource_get_user_data(res_tzvis); + if (!hs_surface) + return; + + hs_surface->tizen_visibility = NULL; +} + +static void +tizen_position_cb_destroy(struct wl_client *client, + struct wl_resource *res_tzpos) +{ + wl_resource_destroy(res_tzpos); +} + +static void +tizen_position_cb_set(struct wl_client *client, struct wl_resource *res_tzpos, + int32_t x, int32_t y) +{ +} + +static const struct tizen_position_interface tizen_position = { + tizen_position_cb_destroy, + tizen_position_cb_set, +}; + +static void +tizen_position_cb_pos_destroy(struct wl_resource *res_tzpos) +{ +} + +static void +tizen_policy_cb_vis_get(struct wl_client *client, struct wl_resource *resource, + uint32_t id, struct wl_resource *surf) +{ + struct ds_surface *ds_surface; + headless_shell_surface_t *hs_surface; + struct wl_resource *new_res; + + ds_surface = ds_surface_from_resource(surf); + HS_CHECK(ds_surface, return, "fail to get ds_surface_t\n"); + + hs_surface = headless_shell_surface_from_ds_surface(ds_surface); + HS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n"); + + new_res = wl_resource_create(client, &tizen_visibility_interface, 5, id); + if (!new_res) { + HS_ERROR("fail to create tizen_visibility"); + wl_resource_post_no_memory(resource); + return; + } + + wl_resource_set_implementation(new_res, + &tizen_visibility, + hs_surface, + tizen_visibility_cb_vis_destroy); + + hs_surface->tizen_visibility = new_res; + + if (hs_surface->visibility != TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED) { + tizen_visibility_send_notify(hs_surface->tizen_visibility, + hs_surface->visibility); + } +} + +static void +tizen_policy_cb_pos_get(struct wl_client *client, struct wl_resource *resource, + uint32_t id, struct wl_resource *surf) +{ + struct wl_resource *new_res; + + new_res = wl_resource_create(client, &tizen_position_interface, 1, id); + if (!new_res) { + HS_ERROR("fail to create tizen_visibility"); + wl_resource_post_no_memory(resource); + return; + } + + wl_resource_set_implementation(new_res, &tizen_position, NULL, + tizen_position_cb_pos_destroy); +} + +static void +tizen_policy_cb_activate(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf) +{ + struct ds_surface *ds_surface; + headless_shell_surface_t *hs_surface; + + ds_surface = ds_surface_from_resource(surf); + HS_CHECK(ds_surface, return, "fail to get ds_surface\n"); + + hs_surface = headless_shell_surface_from_ds_surface(ds_surface); + HS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n"); + + wl_signal_emit(&hs_surface->events.request_activate, hs_surface); +} + +static void +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) +{ +} + +static void +tizen_policy_cb_raise(struct wl_client *client, struct wl_resource *resource, + struct wl_resource *surf) +{ +} + +static void +tizen_policy_cb_lower(struct wl_client *client, struct wl_resource *resource, + struct wl_resource *surf) +{ +} + +static void +tizen_policy_cb_lower_by_res_id(struct wl_client *client, + struct wl_resource *resource, uint32_t res_id) +{ +} + +static void +tizen_policy_cb_focus_skip_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf) +{ + struct ds_surface *ds_surface; + headless_shell_surface_t *hs_surface; + + ds_surface = ds_surface_from_resource(surf); + HS_CHECK(ds_surface, return, "fail to get ds_surface\n"); + + hs_surface = headless_shell_surface_from_ds_surface(ds_surface); + HS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n"); + + wl_signal_emit(&hs_surface->events.set_skip_focus, hs_surface); +} + +static void +tizen_policy_cb_focus_skip_unset(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf) +{ + struct ds_surface *ds_surface; + headless_shell_surface_t *hs_surface; + + ds_surface = ds_surface_from_resource(surf); + HS_CHECK(ds_surface, return, "fail to get ds_surface\n"); + + hs_surface = headless_shell_surface_from_ds_surface(ds_surface); + HS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n"); + + wl_signal_emit(&hs_surface->events.unset_skip_focus, hs_surface); +} + +static void +tizen_policy_cb_role_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf, + const char *role) +{ +} + +static void +tizen_policy_cb_type_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf, uint32_t type) +{ +} + +static void +tizen_policy_cb_conformant_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf) +{ +} + +static void +tizen_policy_cb_conformant_unset(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf) +{ +} + +static void +tizen_policy_cb_conformant_get(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf) +{ + tizen_policy_send_conformant(resource, surf, 0); +} + +static void +tizen_policy_cb_notilv_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf, int32_t lv) +{ +} + +static void +tizen_policy_cb_transient_for_set(struct wl_client *client, + struct wl_resource *resource, uint32_t child_id, uint32_t parent_id) +{ +} + +static void +tizen_policy_cb_transient_for_unset(struct wl_client *client, + struct wl_resource *resource, uint32_t child_id) +{ + tizen_policy_send_transient_for_done(resource, child_id); +} + +static void +tizen_policy_cb_win_scrmode_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf, uint32_t mode) +{ + tizen_policy_send_window_screen_mode_done + (resource, surf, mode, TIZEN_POLICY_ERROR_STATE_NONE); +} + +static void +tizen_policy_cb_subsurf_place_below_parent(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *subsurf) +{ +} + +static void +tizen_policy_cb_subsurf_stand_alone_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *subsurf) +{ +} + +static void +tizen_policy_cb_subsurface_get(struct wl_client *client, + struct wl_resource *resource, uint32_t id, struct wl_resource *surface, + uint32_t parent_id) +{ + wl_client_post_implementation_error(client, + "Headless server not support tizen_subsurface\n"); +} + +static void +tizen_policy_cb_opaque_state_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surface, + int32_t state) +{ +} + +static void +tizen_policy_cb_iconify(struct wl_client *client, struct wl_resource *resource, + struct wl_resource *surf) +{ +} + +static void +tizen_policy_cb_uniconify(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf) +{ +} + +static void +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) +{ +} + +static void +tizen_policy_cb_aux_hint_change(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf, int32_t id, + const char *value) +{ +} + +static void +tizen_policy_cb_aux_hint_del(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf, int32_t id) +{ +} + +static void +tizen_policy_cb_supported_aux_hints_get(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf) +{ +} + +static void +tizen_policy_cb_background_state_set(struct wl_client *client, + struct wl_resource *resource, uint32_t pid) +{ +} + +static void +tizen_policy_cb_background_state_unset(struct wl_client *client, + struct wl_resource *resource, uint32_t pid) +{ +} + +static void +tizen_policy_cb_floating_mode_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf) +{ +} + +static void +tizen_policy_cb_floating_mode_unset(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf) +{ +} + +static void +tizen_policy_cb_stack_mode_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surf, uint32_t mode) +{ +} + +static void +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) +{ +} + +static void +tizen_policy_cb_subsurf_watcher_get(struct wl_client *client, + struct wl_resource *resource, uint32_t id, struct wl_resource *surface) +{ + wl_client_post_implementation_error(client, + "Headless server not support tizen_subsurface\n"); +} + +static void +tizen_policy_cb_parent_set(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *child, + struct wl_resource *parent) +{ +} + +static void +tizen_policy_cb_ack_conformant_region(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surface, + uint32_t serial) +{ +} + +static void +tizen_policy_cb_destroy(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +tizen_policy_cb_has_video(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surface, + uint32_t has) +{ +} + +static const struct tizen_policy_interface tizen_policy_iface = { + tizen_policy_cb_vis_get, + tizen_policy_cb_pos_get, + tizen_policy_cb_activate, + tizen_policy_cb_activate_below_by_res_id, + tizen_policy_cb_raise, + tizen_policy_cb_lower, + tizen_policy_cb_lower_by_res_id, + tizen_policy_cb_focus_skip_set, + tizen_policy_cb_focus_skip_unset, + tizen_policy_cb_role_set, + tizen_policy_cb_type_set, + tizen_policy_cb_conformant_set, + tizen_policy_cb_conformant_unset, + tizen_policy_cb_conformant_get, + tizen_policy_cb_notilv_set, + tizen_policy_cb_transient_for_set, + tizen_policy_cb_transient_for_unset, + tizen_policy_cb_win_scrmode_set, + tizen_policy_cb_subsurf_place_below_parent, + tizen_policy_cb_subsurf_stand_alone_set, + tizen_policy_cb_subsurface_get, + tizen_policy_cb_opaque_state_set, + tizen_policy_cb_iconify, + tizen_policy_cb_uniconify, + tizen_policy_cb_aux_hint_add, + tizen_policy_cb_aux_hint_change, + tizen_policy_cb_aux_hint_del, + tizen_policy_cb_supported_aux_hints_get, + tizen_policy_cb_background_state_set, + tizen_policy_cb_background_state_unset, + tizen_policy_cb_floating_mode_set, + tizen_policy_cb_floating_mode_unset, + tizen_policy_cb_stack_mode_set, + tizen_policy_cb_activate_above_by_res_id, + tizen_policy_cb_subsurf_watcher_get, + tizen_policy_cb_parent_set, + tizen_policy_cb_ack_conformant_region, + tizen_policy_cb_destroy, + tizen_policy_cb_has_video, +}; + +static void +tizen_policy_cb_unbind(struct wl_resource *resource) +{ + headless_shell_t *shell; + + shell = wl_resource_get_user_data(resource); + if (shell) + shell->tizen_policy = NULL; +} + +static void +tizen_policy_cb_bind(struct wl_client *client, void *data, uint32_t ver, + uint32_t id) +{ + headless_shell_t *shell = (headless_shell_t *)data; + struct wl_resource *resource; + + HS_CHECK(shell, goto err, "data is NULL\n"); + + resource = wl_resource_create(client, &tizen_policy_interface, ver, id); + HS_CHECK(resource, goto err, "fail to create tizen_policy\n"); + + wl_resource_set_implementation(resource, &tizen_policy_iface, shell, + tizen_policy_cb_unbind); + return; + +err: + wl_client_post_no_memory(client); +} diff --git a/src/shell/xdg_shell_v6.c b/src/shell/xdg_shell_v6.c new file mode 100644 index 0000000..a813ad4 --- /dev/null +++ b/src/shell/xdg_shell_v6.c @@ -0,0 +1,649 @@ +#include +#include + +#include "shell.h" + +static const struct ds_surface_role xdg_toplevel_role; + +static void zxdg_shell_cb_bind(struct wl_client *client, void *data, + uint32_t version, uint32_t id); +static void reset_headless_shell_surface(headless_shell_surface_t *hs_surface); +static void +destroy_headless_shell_surface(headless_shell_surface_t *hs_surface); +static void map_headless_shell_surface(headless_shell_surface_t *hs_surface); +static void unmap_headless_shell_surface(headless_shell_surface_t *hs_surface); + +bool +xdg_shell_v6_init(headless_shell_t *shell) +{ + shell->zxdg_shell = wl_global_create(shell->display, + &zxdg_shell_v6_interface, 1, shell, zxdg_shell_cb_bind); + HS_CHECK(shell->zxdg_shell, return false, "fail to create zxdg_shell\n"); + + return true; +} + +void +xdg_shell_v6_finish(headless_shell_t *shell) +{ + if (shell->zxdg_shell) + wl_global_destroy(shell->zxdg_shell); +} + +void +headless_shell_surface_add_destroy_listener( + headless_shell_surface_t *hs_surface, struct wl_listener *listener) +{ + wl_signal_add(&hs_surface->events.destroy, listener); +} + +void +headless_shell_surface_add_map_listener( + headless_shell_surface_t *hs_surface, struct wl_listener *listener) +{ + wl_signal_add(&hs_surface->events.map, listener); +} + +void +headless_shell_surface_add_unmap_listener( + headless_shell_surface_t *hs_surface, struct wl_listener *listener) +{ + wl_signal_add(&hs_surface->events.unmap, listener); +} + +void +headless_shell_surface_add_request_activate_listener( + headless_shell_surface_t *hs_surface, struct wl_listener *listener) +{ + wl_signal_add(&hs_surface->events.request_activate, listener); +} + +headless_shell_surface_t * +headless_shell_surface_from_ds_surface(struct ds_surface *ds_surface) +{ + if (ds_surface_get_role(ds_surface) != &xdg_toplevel_role) + return NULL; + return ds_surface_get_role_data(ds_surface); +} + +struct ds_surface * +headless_shell_surface_get_surface(headless_shell_surface_t *hs_surface) +{ + return hs_surface->ds_surface; +} + +struct wl_resource * +headless_shell_surface_get_resource(headless_shell_surface_t *hs_surface) +{ + return hs_surface->zxdg_shell_surface; +} + +static void +zxdg_toplevel_cb_resource_destroy(struct wl_resource *resource) +{ + headless_shell_surface_t *hs_surface; + + hs_surface = wl_resource_get_user_data(resource); + if (!hs_surface) + return; + + reset_headless_shell_surface(hs_surface); +} + +static void +zxdg_toplevel_cb_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +zxdg_toplevel_cb_parent_set(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *res_parent) +{ +} + +static void +zxdg_toplevel_cb_title_set(struct wl_client *client, + struct wl_resource *resource, + const char *title) +{ +} + +static void +zxdg_toplevel_cb_app_id_set(struct wl_client *client, + struct wl_resource *resource, + const char *app_id) +{ +} + +static void +zxdg_toplevel_cb_win_menu_show(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *res_seat, + uint32_t serial, + int32_t x, + int32_t y) +{ +} + +static void +zxdg_toplevel_cb_move(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *res_seat, + uint32_t serial) +{ +} + +static void +zxdg_toplevel_cb_resize(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *res_seat, + uint32_t serial, + uint32_t edges) +{ +} + +static void +zxdg_toplevel_cb_max_size_set(struct wl_client *client, + struct wl_resource *resource, + int32_t w, + int32_t h) +{ +} + +static void +zxdg_toplevel_cb_min_size_set(struct wl_client *client, + struct wl_resource *resource, + int32_t w, + int32_t h) +{ +} + +static void +zxdg_toplevel_cb_maximized_set(struct wl_client *client, + struct wl_resource *resource) +{ +} + +static void +zxdg_toplevel_cb_maximized_unset(struct wl_client *client, + struct wl_resource *resource) +{ +} + +static void +zxdg_toplevel_cb_fullscreen_set(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *res_output) +{ +} + +static void +zxdg_toplevel_cb_fullscreen_unset(struct wl_client *client, + struct wl_resource *resource) +{ +} + +static void +zxdg_toplevel_cb_minimized_set(struct wl_client *client, + struct wl_resource *resource) +{ +} + +static const struct zxdg_toplevel_v6_interface zxdg_toplevel_interface = { + zxdg_toplevel_cb_destroy, + zxdg_toplevel_cb_parent_set, + zxdg_toplevel_cb_title_set, + zxdg_toplevel_cb_app_id_set, + zxdg_toplevel_cb_win_menu_show, + zxdg_toplevel_cb_move, + zxdg_toplevel_cb_resize, + zxdg_toplevel_cb_max_size_set, + zxdg_toplevel_cb_min_size_set, + zxdg_toplevel_cb_maximized_set, + zxdg_toplevel_cb_maximized_unset, + zxdg_toplevel_cb_fullscreen_set, + zxdg_toplevel_cb_fullscreen_unset, + zxdg_toplevel_cb_minimized_set +}; + +static void +zxdg_popup_cb_resource_destroy(struct wl_resource *resource) +{ + headless_shell_surface_t *hs_surface; + + hs_surface = wl_resource_get_user_data(resource); + HS_CHECK(hs_surface, return, "fail to get headless_surface.\n"); + HS_CHECK((hs_surface->surface_type == HEADLESS_SURFACE_POPUP), return, + "Invalid surface type.\n"); + HS_CHECK((hs_surface->zxdg_surface == resource), return, + "Invalid surface."); + + hs_surface->surface_type = HEADLESS_SURFACE_NONE; + hs_surface->zxdg_surface = NULL; +} + +static void +zxdg_popup_cb_destroy(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +zxdg_popup_cb_grab(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *res_seat, + uint32_t serial) +{ +} + +static const struct zxdg_popup_v6_interface zxdg_popup_interface = { + zxdg_popup_cb_destroy, + zxdg_popup_cb_grab +}; + +static void +zxdg_surface_cb_resource_destroy(struct wl_resource *resource) +{ + headless_shell_surface_t *hs_surface; + + hs_surface = wl_resource_get_user_data(resource); + if (!hs_surface) + return; + + HS_TRACE("[SHELL] zxdg_surface_cb_resource_destroy: hs_surface:%p", + hs_surface); + + destroy_headless_shell_surface(hs_surface); +} + +static void +zxdg_surface_cb_destroy(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +headless_toplevel_handle_surface_commit(struct ds_surface *ds_surface) +{ + headless_shell_surface_t *hs_surface; + + hs_surface = ds_surface_get_role_data(ds_surface); + if (!hs_surface) + return; + + if (!hs_surface->added) { + hs_surface->added = true; + wl_signal_emit(&hs_surface->hs_shell->events.new_surface, hs_surface); + } + + if (ds_surface_get_buffer(hs_surface->ds_surface) && + !hs_surface->mapped) { + map_headless_shell_surface(hs_surface); + } + else if (!ds_surface_get_buffer(hs_surface->ds_surface) && + hs_surface->mapped) { + unmap_headless_shell_surface(hs_surface); + } +} + +static const struct ds_surface_role xdg_toplevel_role = { + .name = "headless_shell_surface", + .commit = headless_toplevel_handle_surface_commit, +}; + +static void +zxdg_surface_cb_toplevel_get(struct wl_client *client, + struct wl_resource *resource, uint32_t id) +{ + headless_shell_surface_t *hs_surface; + struct wl_resource *new_res; + + hs_surface = wl_resource_get_user_data(resource); + HS_CHECK(hs_surface, return, "fail to get headless_surface\n"); + + if (!ds_surface_set_role(hs_surface->ds_surface, &xdg_toplevel_role, + hs_surface, resource, ZXDG_SHELL_V6_ERROR_ROLE)) + return; + + if (hs_surface->surface_type != HEADLESS_SURFACE_NONE) { + wl_resource_post_error(hs_surface->zxdg_shell_surface, + ZXDG_SURFACE_V6_ERROR_ALREADY_CONSTRUCTED, + "xdg-surface has already been constructed"); + return; + } + + new_res = wl_resource_create(client, &zxdg_toplevel_v6_interface, 1, id); + if (!new_res) { + HS_ERROR("fail to create zxdg_toplevel"); + wl_resource_post_no_memory(resource); + return; + } + + wl_resource_set_implementation(new_res, + &zxdg_toplevel_interface, + hs_surface, + zxdg_toplevel_cb_resource_destroy); + + hs_surface->surface_type = HEADLESS_SURFACE_TOPLEVEL; + hs_surface->zxdg_surface = new_res; +} + +static void +zxdg_surface_cb_popup_get(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *res_parent, + struct wl_resource *res_pos) +{ + headless_shell_surface_t *hs_surface; + struct wl_resource *new_res; + + hs_surface = wl_resource_get_user_data(resource); + HS_CHECK(hs_surface, return, "fail to get headless_surface\n"); + HS_CHECK((hs_surface->zxdg_surface == NULL), return, + "alwreay assign zdg_surface:%p role:%d\n", + hs_surface->zxdg_surface, hs_surface->surface_type); + + new_res = wl_resource_create(client, &zxdg_popup_v6_interface, 1, id); + if (!new_res) { + HS_ERROR("fail to create popup"); + wl_resource_post_no_memory(resource); + return; + } + + wl_resource_set_implementation(new_res, + &zxdg_popup_interface, + hs_surface, + zxdg_popup_cb_resource_destroy); + + hs_surface->surface_type = HEADLESS_SURFACE_POPUP; + hs_surface->zxdg_surface = new_res; +} + +static void +zxdg_surface_cb_win_geometry_set(struct wl_client *client, + struct wl_resource *resource, + int32_t x, int32_t y, int32_t w, int32_t h) +{ +} + +static void +zxdg_surface_cb_configure_ack(struct wl_client *client, + struct wl_resource *resource, uint32_t serial) +{ + headless_shell_surface_t *hs_surface; + + hs_surface = wl_resource_get_user_data(resource); + HS_CHECK(hs_surface, return, "fail to get headless_shell_surface\n"); + + hs_surface->last_ack_configure = serial; +} + +static const struct zxdg_surface_v6_interface zxdg_surface_interface = { + zxdg_surface_cb_destroy, + zxdg_surface_cb_toplevel_get, + zxdg_surface_cb_popup_get, + zxdg_surface_cb_win_geometry_set, + zxdg_surface_cb_configure_ack +}; + +static void +zxdg_positioner_cb_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +zxdg_positioner_cb_size_set(struct wl_client *client, + struct wl_resource *resource, int32_t w, int32_t h) +{ +} + +static void +zxdg_positioner_cb_anchor_rect_set(struct wl_client *client, + struct wl_resource *resource, + int32_t x, int32_t y, int32_t w, int32_t h) +{ +} + +static void +zxdg_positioner_cb_anchor_set(struct wl_client *client, + struct wl_resource *resource, enum zxdg_positioner_v6_anchor anchor) +{ +} + +static void +zxdg_positioner_cb_gravity_set(struct wl_client *client, + struct wl_resource *resource, enum zxdg_positioner_v6_gravity gravity) +{ +} + +static void +zxdg_positioner_cb_constraint_adjustment_set(struct wl_client *client, + struct wl_resource *resource, + enum zxdg_positioner_v6_constraint_adjustment constraint_adjustment) +{ +} + +static void +zxdg_positioner_cb_offset_set(struct wl_client *client, + struct wl_resource *resource, int32_t x, int32_t y) +{ +} + +static const struct zxdg_positioner_v6_interface zxdg_positioner_interface = { + zxdg_positioner_cb_destroy, + zxdg_positioner_cb_size_set, + zxdg_positioner_cb_anchor_rect_set, + zxdg_positioner_cb_anchor_set, + zxdg_positioner_cb_gravity_set, + zxdg_positioner_cb_constraint_adjustment_set, + zxdg_positioner_cb_offset_set, +}; + +static void +zxdg_shell_cb_destroy(struct wl_client *client, struct wl_resource *resource) +{ + HS_TRACE("Destroy zxdg_shell\n"); + + wl_resource_destroy(resource); +} + +static void +zxdg_shell_cb_positioner_create(struct wl_client *client, + struct wl_resource *resource, uint32_t id) +{ + struct wl_resource *new_res; + + HS_TRACE("Create zxdg_positoiner\n"); + + new_res = wl_resource_create(client, &zxdg_positioner_v6_interface, 1, id); + if (!new_res) { + HS_ERROR("fail to create zxdg_positioner\n"); + wl_resource_post_no_memory(resource); + return; + } + + wl_resource_set_implementation(new_res, &zxdg_positioner_interface, + NULL, NULL); +} + +static void +map_headless_shell_surface(headless_shell_surface_t *hs_surface) +{ + if (hs_surface->mapped) + return; + + hs_surface->mapped = true; + wl_signal_emit(&hs_surface->events.map, hs_surface); +} + +static void +unmap_headless_shell_surface(headless_shell_surface_t *hs_surface) +{ + if (!hs_surface->mapped) + return; + + hs_surface->mapped = false; + wl_signal_emit(&hs_surface->events.unmap, hs_surface); +} + +static void +reset_headless_shell_surface(headless_shell_surface_t *hs_surface) +{ + if (hs_surface->surface_type != HEADLESS_SURFACE_NONE) + unmap_headless_shell_surface(hs_surface); + + if (hs_surface->added) { + wl_signal_emit(&hs_surface->events.destroy, hs_surface); + hs_surface->added = false; + } + + if (hs_surface->zxdg_surface) { + wl_resource_set_user_data(hs_surface->zxdg_surface, NULL); + hs_surface->zxdg_surface = NULL; + } + + hs_surface->surface_type = HEADLESS_SURFACE_NONE; +} + +static void +destroy_headless_shell_surface(headless_shell_surface_t *hs_surface) +{ + HS_TRACE("[SHELL] hs_surface free ds_surface:%p, " + "zxdg_shell_surface:%p, zxdg_surface:%p", + hs_surface->ds_surface, hs_surface->zxdg_shell_surface, + hs_surface->zxdg_surface); + + reset_headless_shell_surface(hs_surface); + + wl_resource_set_user_data(hs_surface->zxdg_shell_surface, NULL); + + if (hs_surface->tizen_visibility) + wl_resource_set_user_data(hs_surface->tizen_visibility, NULL); + + ds_surface_reset_role_data(hs_surface->ds_surface); + + wl_list_remove(&hs_surface->surface_destroy.link); + + free(hs_surface); +} + +static void +headless_shell_surface_cb_surface_destroy(struct wl_listener *listener, + void *data) +{ + headless_shell_surface_t *hs_surface; + + hs_surface = wl_container_of(listener, hs_surface, surface_destroy); + destroy_headless_shell_surface(hs_surface); +} + +static void +zxdg_shell_cb_surface_get(struct wl_client *client, + struct wl_resource *resource, uint32_t id, + struct wl_resource *wsurface) +{ + headless_shell_t *hs; + headless_shell_surface_t *hs_surface = NULL; + struct ds_surface *ds_surface; + + hs = wl_resource_get_user_data(resource); + if (!hs) { + HS_ERROR("fail to get headless_shell\n"); + wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "failed to get headless shell"); + return; + } + + ds_surface = ds_surface_from_resource(wsurface); + HS_CHECK(ds_surface, goto error, "faile to get ds_surface\n"); + + hs_surface = calloc(1, sizeof *hs_surface); + if (!hs_surface) { + wl_resource_post_no_memory(resource); + return; + } + + hs_surface->hs_shell = hs; + hs_surface->ds_surface = ds_surface; + hs_surface->visibility = TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED; + + wl_signal_init(&hs_surface->events.destroy); + wl_signal_init(&hs_surface->events.map); + wl_signal_init(&hs_surface->events.unmap); + wl_signal_init(&hs_surface->events.request_activate); + wl_signal_init(&hs_surface->events.set_skip_focus); + wl_signal_init(&hs_surface->events.unset_skip_focus); + + hs_surface->zxdg_shell_surface = wl_resource_create(client, + &zxdg_surface_v6_interface, 1, id); + if (!hs_surface->zxdg_shell_surface) { + HS_ERROR("fail to create the zxdg_surface\n"); + wl_resource_post_no_memory(resource); + goto error; + } + + wl_resource_set_implementation(hs_surface->zxdg_shell_surface, + &zxdg_surface_interface, + hs_surface, + zxdg_surface_cb_resource_destroy); + + hs_surface->surface_destroy.notify = + headless_shell_surface_cb_surface_destroy; + ds_surface_add_destroy_listener(ds_surface, &hs_surface->surface_destroy); + + HS_TRACE("[SHELL] create zxdg_surface:%p, ds_surface:%p\n", + hs_surface->zxdg_shell_surface, + hs_surface->ds_surface); + + return; +error: + if (hs_surface) { + if (hs_surface->zxdg_shell_surface) { + wl_resource_destroy(hs_surface->zxdg_shell_surface); + hs_surface->zxdg_shell_surface = NULL; + } + + free(hs_surface); + } +} + +static void +zxdg_shell_cb_pong(struct wl_client *client, struct wl_resource *resource, + uint32_t serial) +{ + +} + +static const struct zxdg_shell_v6_interface zxdg_shell_interface = { + zxdg_shell_cb_destroy, + zxdg_shell_cb_positioner_create, + zxdg_shell_cb_surface_get, + zxdg_shell_cb_pong +}; + +static void +zxdg_shell_cb_bind(struct wl_client *client, void *data, uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + headless_shell_t *hs = (headless_shell_t *)data; + + HS_TRACE("Bind zxdg_shell\n"); + + /* Create resource for zxdg_shell_v6 */ + resource = wl_resource_create(client, &zxdg_shell_v6_interface, + version, id); + HS_CHECK(resource, goto err_shell, "fail to create the zxdg_shell_v6\n"); + + wl_resource_set_implementation(resource, &zxdg_shell_interface, hs, NULL); + + return; +err_shell: + wl_client_post_no_memory(client); +}