From b48661337ae274586df775a5fec63708505841bc Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 25 Jul 2022 13:41:21 +0900 Subject: [PATCH 01/16] shell: Split into multiple files This organizes the headless_shell implementation into separate files. No functional changes, just moving code around. Change-Id: Ibf793a2af4dc0860b8d067f2c5dc5b731535477c --- src/Makefile.am | 2 + src/headless_server.c | 1 + src/headless_server.h | 5 +- src/shell/shell.c | 1199 +--------------------------------------------- src/shell/shell.h | 65 +++ src/shell/tizen_policy.c | 492 +++++++++++++++++++ src/shell/xdg_shell_v6.c | 649 +++++++++++++++++++++++++ 7 files changed, 1216 insertions(+), 1197 deletions(-) create mode 100644 src/shell/shell.h create mode 100644 src/shell/tizen_policy.c create mode 100644 src/shell/xdg_shell_v6.c 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); +} -- 2.7.4 From 42d3512e11e84317695be72d52da92a9b4406870 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 25 Jul 2022 13:56:11 +0900 Subject: [PATCH 02/16] Rename variables to be more clear Change-Id: I1e7197cdc4481ab7f856f1f7ec28320ca8d42f64 --- src/debug/debug.c | 2 +- src/headless_server.c | 42 ++++++++++++++++++------------------ src/headless_server.h | 6 +++--- src/input/input.c | 60 ++++++++++++++++++++++++++------------------------- 4 files changed, 56 insertions(+), 54 deletions(-) diff --git a/src/debug/debug.c b/src/debug/debug.c index 2f97da7..b65b284 100644 --- a/src/debug/debug.c +++ b/src/debug/debug.c @@ -262,7 +262,7 @@ _headless_debug_topvwins(headless_debug_t *hdebug, void *data) cnt, view, wl_resource_get_id(resource), pid, view->width, view->height, view->x, view->y, view->mapped ? "O" : "X", - (view->mapped && hdebug->server->top_view == view) ? "O" : "X", + (view->mapped && hdebug->server->top_visible_view == view) ? "O" : "X", (hdebug->server->focus_view == view) ? "O" : "X"); } diff --git a/src/headless_server.c b/src/headless_server.c index 576df9a..0920b07 100644 --- a/src/headless_server.c +++ b/src/headless_server.c @@ -42,7 +42,7 @@ static void server_handle_new_shell_surface(struct wl_listener *listener, static void server_schedule_idle_task(headless_server_t *server); static void server_set_focus_view(headless_server_t *server, headless_view_t *view); -static void server_set_top_view(headless_server_t *server, +static void server_set_top_visible_view(headless_server_t *server, headless_view_t *view); static int @@ -126,8 +126,8 @@ main(int argc, char *argv[]) wl_list_init(&server.views); - wl_signal_init(&server.events.focus_change); - wl_signal_init(&server.events.top_change); + wl_signal_init(&server.events.focus_view_change); + wl_signal_init(&server.events.top_visible_view_change); server.compositor = ds_compositor_create(server.display); HS_CHECK(server.compositor, goto end, "Failed to create ds_compositor"); @@ -233,9 +233,9 @@ view_handle_shell_surface_destroy(struct wl_listener *listener, void *data) view = wl_container_of(listener, view, shell_surface_destroy); server = view->server; - if (server->top_view == view) { - server->top_view = NULL; - wl_signal_emit(&server->events.top_change, NULL); + if (server->top_visible_view == view) { + server->top_visible_view = NULL; + wl_signal_emit(&server->events.top_visible_view_change, NULL); } server_schedule_idle_task(server); @@ -391,19 +391,19 @@ server_set_focus_view(headless_server_t *server, headless_view_t *view) server->focus_view = view; - wl_signal_emit(&server->events.focus_change, view); + wl_signal_emit(&server->events.focus_view_change, view); } static void -server_set_top_view(headless_server_t *server, headless_view_t *view) +server_set_top_visible_view(headless_server_t *server, headless_view_t *view) { - if (server->top_view == view) + if (server->top_visible_view == view) return; // TODO handle input and debug - if (server->top_view) { - headless_shell_send_visibility(server->top_view->shell_surface, + if (server->top_visible_view) { + headless_shell_send_visibility(server->top_visible_view->shell_surface, TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED); } @@ -412,9 +412,9 @@ server_set_top_view(headless_server_t *server, headless_view_t *view) TIZEN_VISIBILITY_VISIBILITY_UNOBSCURED); } - server->top_view = view; + server->top_visible_view = view; - wl_signal_emit(&server->events.top_change, view); + wl_signal_emit(&server->events.top_visible_view_change, view); } static void @@ -428,9 +428,9 @@ server_repaint(headless_server_t *server) size_t stride; bool access = false; - if (server->top_view) { - surface = server->top_view->surface; - buffer = server->top_view->buffer; + if (server->top_visible_view) { + surface = server->top_visible_view->surface; + buffer = server->top_visible_view->buffer; } if (buffer) { @@ -455,7 +455,7 @@ static void idle_task(void *data) { headless_server_t *server = data; - headless_view_t *view, *focus_view = NULL, *top_view = NULL; + headless_view_t *view, *focus_view = NULL, *top_visible_view = NULL; server->idle_source = NULL; @@ -466,18 +466,18 @@ idle_task(void *data) if (!view->mapped) continue; - if (!top_view) - top_view = view; + if (!top_visible_view) + top_visible_view = view; if (!focus_view && !view->skip_focus) focus_view = view; - if (focus_view && top_view) + if (focus_view && top_visible_view) break; } server_set_focus_view(server, focus_view); - server_set_top_view(server, top_view); + server_set_top_visible_view(server, top_visible_view); server_repaint(server); } diff --git a/src/headless_server.h b/src/headless_server.h index ed3c5ab..9a933bc 100644 --- a/src/headless_server.h +++ b/src/headless_server.h @@ -82,7 +82,7 @@ struct headless_server headless_debug_t *debug; headless_view_t *focus_view; - headless_view_t *top_view; + headless_view_t *top_visible_view; struct wl_event_source *sigint_source; struct wl_event_source *idle_source; @@ -94,8 +94,8 @@ struct headless_server struct wl_list views; // headless_view::link struct { - struct wl_signal focus_change; - struct wl_signal top_change; + struct wl_signal focus_view_change; + struct wl_signal top_visible_view_change; } events; bool boot_animating; diff --git a/src/input/input.c b/src/input/input.c index b3a7ca0..638c5f7 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -52,7 +52,7 @@ struct headless_input { headless_server_t *server; headless_keyboard_t *keyboard; - headless_view_t *top_view; + headless_view_t *top_visible_view; struct ds_backend *backend; struct ds_seat *seat; @@ -60,9 +60,9 @@ struct headless_input struct ds_tizen_input_devicemgr *devicemgr; struct wl_listener new_input; - struct wl_listener focus_change; - struct wl_listener top_change; - struct wl_listener top_view_destroy; + struct wl_listener focus_view_change; + struct wl_listener top_visible_view_change; + struct wl_listener top_visible_view_destroy; }; struct headless_keyboard @@ -76,8 +76,8 @@ struct headless_keyboard }; static void handle_new_input(struct wl_listener *listener, void *data); -static void handle_focus_change(struct wl_listener *listener, void *data); -static void handle_top_change(struct wl_listener *listener, void *data); +static void handle_focus_view_change(struct wl_listener *listener, void *data); +static void handle_top_visible_view_change(struct wl_listener *listener, void *data); static void handle_top_view_destroy(struct wl_listener *listener, void *data); static headless_keyboard_t *create_keyboard(headless_input_t *input, struct ds_input_device *dev); @@ -127,11 +127,13 @@ headless_input_create(headless_server_t *server) input->new_input.notify = handle_new_input; ds_backend_add_new_input_listener(input->backend, &input->new_input); - input->focus_change.notify = handle_focus_change; - wl_signal_add(&server->events.focus_change, &input->focus_change); + input->focus_view_change.notify = handle_focus_view_change; + wl_signal_add(&server->events.focus_view_change, + &input->focus_view_change); - input->top_change.notify = handle_top_change; - wl_signal_add(&server->events.top_change, &input->top_change); + input->top_visible_view_change.notify = handle_top_visible_view_change; + wl_signal_add(&server->events.top_visible_view_change, + &input->top_visible_view_change); ds_backend_start(input->backend); @@ -155,11 +157,11 @@ headless_input_destroy(headless_input_t *input) if (input->keyboard) keyboard_destroy(input->keyboard); - if (input->top_view_destroy.notify) - wl_list_remove(&input->top_view_destroy.link); + if (input->top_visible_view_destroy.notify) + wl_list_remove(&input->top_visible_view_destroy.link); - wl_list_remove(&input->top_change.link); - wl_list_remove(&input->focus_change.link); + wl_list_remove(&input->top_visible_view_change.link); + wl_list_remove(&input->focus_view_change.link); wl_list_remove(&input->new_input.link); ds_backend_destroy(input->backend); @@ -167,12 +169,12 @@ headless_input_destroy(headless_input_t *input) } static void -handle_focus_change(struct wl_listener *listener, void *data) +handle_focus_view_change(struct wl_listener *listener, void *data) { headless_input_t *input; headless_view_t *view = data; - input = wl_container_of(listener, input, focus_change); + input = wl_container_of(listener, input, focus_view_change); if (view) { ds_seat_keyboard_notify_enter(input->seat, view->surface, @@ -184,24 +186,24 @@ handle_focus_change(struct wl_listener *listener, void *data) } static void -handle_top_change(struct wl_listener *listener, void *data) +handle_top_visible_view_change(struct wl_listener *listener, void *data) { headless_input_t *input; headless_view_t *view = data; - input = wl_container_of(listener, input, top_change); + input = wl_container_of(listener, input, top_visible_view_change); - if (input->top_view_destroy.notify) { - wl_list_remove(&input->top_view_destroy.link); - input->top_view_destroy.notify = NULL; + if (input->top_visible_view_destroy.notify) { + wl_list_remove(&input->top_visible_view_destroy.link); + input->top_visible_view_destroy.notify = NULL; } if (view) { - input->top_view_destroy.notify = handle_top_view_destroy; - wl_signal_add(&view->events.destroy, &input->top_view_destroy); + input->top_visible_view_destroy.notify = handle_top_view_destroy; + wl_signal_add(&view->events.destroy, &input->top_visible_view_destroy); } - input->top_view = view; + input->top_visible_view = view; } static void @@ -209,12 +211,12 @@ handle_top_view_destroy(struct wl_listener *listener, void *data) { headless_input_t *input; - input = wl_container_of(listener, input, top_view_destroy); + input = wl_container_of(listener, input, top_visible_view_destroy); - wl_list_remove(&input->top_view_destroy.link); + wl_list_remove(&input->top_visible_view_destroy.link); - input->top_view_destroy.notify = NULL; - input->top_view = NULL; + input->top_visible_view_destroy.notify = NULL; + input->top_visible_view = NULL; } static void @@ -325,7 +327,7 @@ keyboard_handle_key(struct wl_listener *listener, void *data) ev->time_msec, ev->update_state); ds_tizen_keyrouter_notify_key(input->keyrouter, input->seat, - input->top_view ? input->top_view->surface : NULL, + input->top_visible_view ? input->top_visible_view->surface : NULL, ev->time_msec, ev->keycode, ev->state); } -- 2.7.4 From 34f617d26a751225a6ce50b4e51c334a74c7ebf4 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 25 Jul 2022 15:41:46 +0900 Subject: [PATCH 03/16] shell: Send visibility events in shell This is to separate implementation of visibliity from headless_server.c. No functional changes. Change-Id: I5635e42a92af7855bdca55a38228adfc0046dba2 --- src/headless_server.c | 29 ++++++------------- src/headless_server.h | 4 +-- src/shell/shell.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++-- src/shell/shell.h | 9 +++++- src/shell/tizen_policy.c | 2 +- src/shell/xdg_shell_v6.c | 2 +- 6 files changed, 91 insertions(+), 29 deletions(-) diff --git a/src/headless_server.c b/src/headless_server.c index 0920b07..de35f86 100644 --- a/src/headless_server.c +++ b/src/headless_server.c @@ -31,7 +31,6 @@ #include #include -#include #include "headless_server.h" @@ -161,7 +160,7 @@ main(int argc, char *argv[]) } /* Init Shell */ - server.shell = headless_shell_create(server.display); + server.shell = headless_shell_create(&server); HS_CHECK(server.shell, goto end, "headless_shell_create() failed.\n"); server.new_shell_surface.notify = server_handle_new_shell_surface; @@ -209,8 +208,15 @@ end: static void destroy_view(headless_view_t *view) { + headless_server_t *server = view->server; + ds_inf("view(%p) destroyed", view); + if (server->top_visible_view == view) + server_set_top_visible_view(server, NULL); + + server_schedule_idle_task(server); + wl_signal_emit(&view->events.destroy, view); wl_list_remove(&view->commit.link); @@ -228,17 +234,8 @@ static void view_handle_shell_surface_destroy(struct wl_listener *listener, void *data) { headless_view_t *view; - headless_server_t *server; view = wl_container_of(listener, view, shell_surface_destroy); - server = view->server; - - if (server->top_visible_view == view) { - server->top_visible_view = NULL; - wl_signal_emit(&server->events.top_visible_view_change, NULL); - } - - server_schedule_idle_task(server); destroy_view(view); } @@ -402,16 +399,6 @@ server_set_top_visible_view(headless_server_t *server, headless_view_t *view) // TODO handle input and debug - if (server->top_visible_view) { - headless_shell_send_visibility(server->top_visible_view->shell_surface, - TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED); - } - - if (view) { - headless_shell_send_visibility(view->shell_surface, - TIZEN_VISIBILITY_VISIBILITY_UNOBSCURED); - } - server->top_visible_view = view; wl_signal_emit(&server->events.top_visible_view_change, view); diff --git a/src/headless_server.h b/src/headless_server.h index 9a933bc..761a932 100644 --- a/src/headless_server.h +++ b/src/headless_server.h @@ -137,7 +137,7 @@ void headless_output_stop_boot_ani(led_output_t *output); void headless_output_update_led(led_output_t *output, unsigned char *data); /* APIs for headless_shell */ -headless_shell_t *headless_shell_create(struct wl_display *display); +headless_shell_t *headless_shell_create(headless_server_t *server); void headless_shell_destroy(headless_shell_t *shell); void headless_shell_add_new_surface_listener(headless_shell_t *shell, struct wl_listener *listener); @@ -155,8 +155,6 @@ void headless_shell_surface_add_unset_skip_focus_listener( headless_shell_surface_t *hs_surface, struct wl_listener *listener); struct ds_surface * headless_shell_surface_get_surface(headless_shell_surface_t *shell_surface); -void headless_shell_send_visibility(headless_shell_surface_t *hs_surface, - uint8_t visibility); struct wl_resource * headless_shell_surface_get_resource(headless_shell_surface_t *hs_surface); diff --git a/src/shell/shell.c b/src/shell/shell.c index 69debca..b535440 100644 --- a/src/shell/shell.c +++ b/src/shell/shell.c @@ -25,26 +25,36 @@ #include "shell.h" +static void handle_top_visible_view_change(struct wl_listener *listener, + void *data); +static void handle_top_visible_view_destroy(struct wl_listener *listener, + void *data); +static void shell_set_top_visible_view(headless_shell_t *shell, + headless_view_t *top_visible_view); +static void shell_unset_top_visible_view(headless_shell_t *shell); + void headless_shell_destroy(headless_shell_t *shell) { if (!shell) return; + wl_list_remove(&shell->top_visible_view_change.link); + xdg_shell_v6_finish(shell); tizen_policy_finish(shell); free(shell); } headless_shell_t * -headless_shell_create(struct wl_display *display) +headless_shell_create(headless_server_t *server) { headless_shell_t *shell; shell = (headless_shell_t*)calloc(sizeof(headless_shell_t), 1); HS_CHECK(shell, goto error, "fail to alloc for shell\n"); - shell->display = display; + shell->server = server; wl_signal_init(&shell->events.new_surface); @@ -53,6 +63,11 @@ headless_shell_create(struct wl_display *display) HS_CHECK(tizen_policy_init(shell), goto error, "tizen_policy_init() failed\n"); + shell->top_visible_view_change.notify = + handle_top_visible_view_change; + wl_signal_add(&server->events.top_visible_view_change, + &shell->top_visible_view_change); + return shell; error: @@ -67,3 +82,58 @@ headless_shell_add_new_surface_listener(headless_shell_t *shell, { wl_signal_add(&shell->events.new_surface, listener); } + +static void +handle_top_visible_view_change(struct wl_listener *listener, void *data) +{ + headless_shell_t *shell; + headless_view_t *top_visible_view = data; + + shell = wl_container_of(listener, shell, top_visible_view_change); + + if (shell->top_visible_view == top_visible_view) + return; + + if (shell->top_visible_view) { + headless_shell_send_visibility(shell->top_visible_view->shell_surface, + TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED); + + shell_unset_top_visible_view(shell); + } + + if (top_visible_view) { + headless_shell_send_visibility(top_visible_view->shell_surface, + TIZEN_VISIBILITY_VISIBILITY_UNOBSCURED); + + shell_set_top_visible_view(shell, top_visible_view); + } +} + +static void +handle_top_visible_view_destroy(struct wl_listener *listener, + void *data) +{ + headless_shell_t *shell; + + shell = wl_container_of(listener, shell, top_visible_view_destroy); + + shell_unset_top_visible_view(shell); +} + +static void +shell_set_top_visible_view(headless_shell_t *shell, + headless_view_t *top_visible_view) +{ + shell->top_visible_view_destroy.notify = handle_top_visible_view_destroy; + wl_signal_add(&top_visible_view->events.destroy, + &shell->top_visible_view_destroy); + + shell->top_visible_view = top_visible_view; +} + +static void +shell_unset_top_visible_view(headless_shell_t *shell) +{ + wl_list_remove(&shell->top_visible_view_destroy.link); + shell->top_visible_view = NULL; +} diff --git a/src/shell/shell.h b/src/shell/shell.h index 14886c1..70868b1 100644 --- a/src/shell/shell.h +++ b/src/shell/shell.h @@ -18,11 +18,16 @@ typedef enum { } headless_surface_type_t; struct headless_shell { - struct wl_display *display; + headless_server_t *server; + headless_view_t *top_visible_view; + struct wl_global *zxdg_shell; struct wl_global *tizen_policy; struct wl_event_source *cb_idle; + struct wl_listener top_visible_view_destroy; + struct wl_listener top_visible_view_change; + struct { struct wl_signal new_surface; } events; @@ -61,5 +66,7 @@ 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); +void headless_shell_send_visibility(headless_shell_surface_t *hs_surface, + uint8_t visibility); #endif diff --git a/src/shell/tizen_policy.c b/src/shell/tizen_policy.c index 59f2b06..b16d4fc 100644 --- a/src/shell/tizen_policy.c +++ b/src/shell/tizen_policy.c @@ -6,7 +6,7 @@ static void tizen_policy_cb_bind(struct wl_client *client, void *data, bool tizen_policy_init(headless_shell_t *shell) { - shell->tizen_policy = wl_global_create(shell->display, + shell->tizen_policy = wl_global_create(shell->server->display, &tizen_policy_interface, 7, shell, tizen_policy_cb_bind); HS_CHECK(shell->tizen_policy, return false, "faile to create tizen_policy\n"); diff --git a/src/shell/xdg_shell_v6.c b/src/shell/xdg_shell_v6.c index a813ad4..cdca2f4 100644 --- a/src/shell/xdg_shell_v6.c +++ b/src/shell/xdg_shell_v6.c @@ -16,7 +16,7 @@ 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, + shell->zxdg_shell = wl_global_create(shell->server->display, &zxdg_shell_v6_interface, 1, shell, zxdg_shell_cb_bind); HS_CHECK(shell->zxdg_shell, return false, "fail to create zxdg_shell\n"); -- 2.7.4 From 98e95d6d32d898631abd1d10b48debb9bd0a6bde Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 1 Aug 2022 17:17:55 +0900 Subject: [PATCH 04/16] Add idle task after creating a view Change-Id: I91bab91394ce92581b9ea56d659cae99da5b03e9 --- src/headless_server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/headless_server.c b/src/headless_server.c index de35f86..83898e4 100644 --- a/src/headless_server.c +++ b/src/headless_server.c @@ -378,6 +378,8 @@ server_handle_new_shell_surface(struct wl_listener *listener, void *data) HS_CHECK(create_view(server, shell_surface), return, "Could not create headless_view"); + + server_schedule_idle_task(server); } static void -- 2.7.4 From 2533812e011a916536faee80aaa63ad5d2305a4b Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 1 Aug 2022 17:23:34 +0900 Subject: [PATCH 05/16] build: Fix parameters for AC_INIT Change-Id: I90f2588d37b7e598be3567221cb8e241c1888aa9 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 7e98ae9..5e1d629 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ m4_define([hsvr_micro], 0) m4_define([hsvr_version], [hsvr_major.hsvr_minor.hsvr_micro]) AC_PREREQ([2.64]) -AC_INIT([pepper], [pepper_version], [tkq.kim@samsung.com]) +AC_INIT([headless_server], [hsvr_version]) AC_SUBST([HSVR_VERSION_MAJOR], [hsvr_major_version]) AC_SUBST([HSVR_VERSION_MINOR], [hsvr_minor_version]) -- 2.7.4 From 441ceb3737b6346976ae06f0aec9da561cbe665a Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 1 Aug 2022 17:25:35 +0900 Subject: [PATCH 06/16] README: Replace pepper keyboard with libds Change-Id: Ic4c2aabc1aebd01a1e19959a1d0227c5a5660571 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1eea085..2c2125e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # headless-server -Pepper-based display server for headless (e.g. Tizen Speaker Profile) +libds-based display server for headless (e.g. Tizen Speaker Profile) -- 2.7.4 From 334c63722d990cee1d7015faecc8648bdf8bf349 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Tue, 2 Aug 2022 09:35:48 +0900 Subject: [PATCH 07/16] Remove unused variable WAYLAND_DISPLAY is not meant to be used to create wayland socket. Change-Id: I3eb9b9aab1cf4cd1daf0f188c36447547af405d3 --- src/headless_server.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/headless_server.c b/src/headless_server.c index 83898e4..1de6e38 100644 --- a/src/headless_server.c +++ b/src/headless_server.c @@ -93,7 +93,6 @@ int main(int argc, char *argv[]) { headless_server_t server = { 0, }; - const char *socket_name = NULL; bool ret; tbm_bufmgr bufmgr = NULL; @@ -106,11 +105,6 @@ main(int argc, char *argv[]) ds_log_init(DS_INF, handle_ds_log); } - socket_name = getenv("WAYLAND_DISPLAY"); - - if (!socket_name) - socket_name = "wayland-0"; - if (!getenv("XDG_RUNTIME_DIR")) setenv("XDG_RUNTIME_DIR", "/run", 1); -- 2.7.4 From 43e638b4d0b5df255f04fef7cde9b02ea2481a87 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Tue, 2 Aug 2022 09:40:06 +0900 Subject: [PATCH 08/16] Use a macro instead of string for dlog tag Change-Id: I56914f4d1c90f4a8cf76d40f87e440e8c40aa656 --- src/headless_server.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/headless_server.c b/src/headless_server.c index 1de6e38..6c059ef 100644 --- a/src/headless_server.c +++ b/src/headless_server.c @@ -34,6 +34,11 @@ #include "headless_server.h" +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "HEADLESS_SERVER" + int use_output = 1; static void server_handle_new_shell_surface(struct wl_listener *listener, @@ -85,8 +90,7 @@ dlog_level_from_ds_log_level(enum ds_log_level level) static void handle_ds_log(enum ds_log_level level, const char *fmt, va_list args) { - dlog_vprint(dlog_level_from_ds_log_level(level), "HEADLESS_SERVER", - fmt, args); + dlog_vprint(dlog_level_from_ds_log_level(level), LOG_TAG, fmt, args); } int -- 2.7.4 From 1a48833f27c2875f95e6f72d4c5604d8ad14ad59 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Tue, 2 Aug 2022 09:58:20 +0900 Subject: [PATCH 09/16] boot_ani: Change function signature properly No functional changes Change-Id: I17146f399618950420d8b25f32131fd821586953 --- src/output/boot_anim.c | 43 ++++++++++++++++++------------------------- src/output/output_internal.h | 8 +++++--- src/output/output_led.c | 9 ++++++--- 3 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/output/boot_anim.c b/src/output/boot_anim.c index f58a2a8..47019e5 100644 --- a/src/output/boot_anim.c +++ b/src/output/boot_anim.c @@ -31,13 +31,13 @@ #include "HL_UI_LED.h" #include "output_internal.h" -typedef struct { +struct boot_ani { HL_UI_LED *led; struct wl_event_source *source; uint32_t serial; int index; -} boot_ani_t; +}; #define ANI_INTERVAL 40 //20ms @@ -68,7 +68,8 @@ boot_ani_timer_cb(void *data) return 1; } -void boot_ani_start(led_output_t *output) +boot_ani_t * +boot_ani_start(struct wl_display *display, HL_UI_LED *ui_led) { struct wl_event_loop *loop; boot_ani_t *ani; @@ -76,11 +77,11 @@ void boot_ani_start(led_output_t *output) HS_TRACE("[OUTPUT] start boot-animation\n"); - loop = wl_display_get_event_loop(output->display); - HS_CHECK(loop, return, "failed to wl_display_get_event_loop()\n"); + loop = wl_display_get_event_loop(display); + HS_CHECK(loop, return NULL, "failed to wl_display_get_event_loop()\n"); ani = (boot_ani_t *)calloc(sizeof(boot_ani_t), 1); - HS_CHECK(ani, return, "failed to alloc\n"); + HS_CHECK(ani, return NULL, "failed to alloc\n"); ani->source = wl_event_loop_add_timer(loop, boot_ani_timer_cb, ani); HS_CHECK(ani->source, goto err, "failed to wl_event_loop_add_timer()\n"); @@ -88,32 +89,24 @@ void boot_ani_start(led_output_t *output) ret = wl_event_source_timer_update(ani->source, ANI_INTERVAL); HS_CHECK(!ret, goto err, "failed to wl_event_source_timer_update\n"); - ani->led = output->ui_led; - output->boot_ani = ani; - return; -err: - if (ani) { - if (ani->source) - wl_event_source_remove(ani->source); + ani->led = ui_led; - free(ani); - } - return; -} + return ani; -void boot_ani_stop(led_output_t *output) -{ - boot_ani_t *ani; +err: + if (ani->source) + wl_event_source_remove(ani->source); - if (!output->boot_ani) return; + free(ani); - ani = (boot_ani_t *)output->boot_ani; + return NULL; +} +void +boot_ani_stop(boot_ani_t *ani) +{ HL_UI_LED_Clear_All(ani->led); wl_event_source_remove(ani->source); free(ani); - - output->boot_ani = NULL; - return; } diff --git a/src/output/output_internal.h b/src/output/output_internal.h index 78a1da8..1404c2e 100644 --- a/src/output/output_internal.h +++ b/src/output/output_internal.h @@ -32,6 +32,8 @@ typedef struct led_output led_output_t; +typedef struct boot_ani boot_ani_t; + struct led_output { struct wl_display *display; struct ds_tbm_server *tbm_server; @@ -42,8 +44,8 @@ struct led_output { struct wl_event_source *frame_done; //For booting animation - void *boot_ani; + boot_ani_t *boot_ani; }; -void boot_ani_start(led_output_t *output); -void boot_ani_stop(led_output_t *output); +boot_ani_t *boot_ani_start(struct wl_display *display, HL_UI_LED *ui_led); +void boot_ani_stop(boot_ani_t *ani); diff --git a/src/output/output_led.c b/src/output/output_led.c index 4b314fa..dd99103 100644 --- a/src/output/output_led.c +++ b/src/output/output_led.c @@ -63,7 +63,7 @@ headless_output_destroy(led_output_t *output) HS_TRACE("Output Destroy %p", output); if (output->boot_ani) { - boot_ani_stop(output); + boot_ani_stop(output->boot_ani); } if (output->ui_led) { @@ -103,7 +103,9 @@ headless_output_start_boot_ani(led_output_t *output) if (output->boot_ani) return; - boot_ani_start(output); + output->boot_ani = boot_ani_start(output->display, output->ui_led); + if (!output->boot_ani) + HS_ERROR("Failed to start boot animation"); } void @@ -112,5 +114,6 @@ headless_output_stop_boot_ani(led_output_t *output) if (!output->boot_ani) return; - boot_ani_stop(output); + boot_ani_stop(output->boot_ani); + output->boot_ani = NULL; } -- 2.7.4 From 2947fbfc269dad47a68dd30d9ace288bc836c530 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Tue, 2 Aug 2022 10:13:51 +0900 Subject: [PATCH 10/16] output: Cleanup code No functional changes Change-Id: I0c5c75b27ba99315f63b6ec5431564ffbbc95946 --- src/output/output_internal.h | 3 --- src/output/output_led.c | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/output/output_internal.h b/src/output/output_internal.h index 1404c2e..c4973fb 100644 --- a/src/output/output_internal.h +++ b/src/output/output_internal.h @@ -28,8 +28,6 @@ #include "HL_UI_LED.h" -#define NUM_LED 12 - typedef struct led_output led_output_t; typedef struct boot_ani boot_ani_t; @@ -38,7 +36,6 @@ struct led_output { struct wl_display *display; struct ds_tbm_server *tbm_server; - int num_led; HL_UI_LED *ui_led; struct wl_event_source *frame_done; diff --git a/src/output/output_led.c b/src/output/output_led.c index dd99103..455ea18 100644 --- a/src/output/output_led.c +++ b/src/output/output_led.c @@ -28,31 +28,31 @@ #include #include "headless_server.h" -#include "HL_UI_LED.h" #include "output_internal.h" +#define NUM_LED 12 +#define LED_BRIGHTNESS 0x1 + led_output_t * headless_output_create(struct wl_display *display) { - led_output_t *output = (led_output_t*)calloc(sizeof(led_output_t), 1); + led_output_t *output; HS_TRACE("Output Init\n"); + output = calloc(1, sizeof(led_output_t)); if (!output) { - HS_ERROR("Failed to allocate memory in %s\n", __FUNCTION__); + HS_ERROR("Failed to allocate memory\n"); return false; } output->display = display; - // FIXME Should we create wl_global for wl_output? - - output->num_led = NUM_LED; - output->ui_led = HL_UI_LED_Init(output->num_led); - if (output->ui_led) HL_UI_LED_Change_Brightness(output->ui_led, 0x1); - - if (!output->ui_led) - HS_ERROR("HL_UI_LED_Init() failed.\n"); + output->ui_led = HL_UI_LED_Init(NUM_LED); + if (output->ui_led) + HL_UI_LED_Change_Brightness(output->ui_led, LED_BRIGHTNESS); + else + HS_ERROR("HL_UI_LED_Init() failed."); return output; } @@ -82,13 +82,13 @@ headless_output_update_led(led_output_t *output, unsigned char *data) int i; uint8_t *ptr = (uint8_t *)data; - if (data == NULL) { + if (!ptr) { HS_TRACE("[OUTPUT] update LED to empty\n"); HL_UI_LED_Clear_All(output->ui_led); return; } - for(i=0; inum_led; i++) { + for (i = 0; i < NUM_LED; i++) { HL_UI_LED_Set_Pixel_RGB(output->ui_led, i, ptr[R_OFF_SET], ptr[G_OFF_SET], ptr[B_OFF_SET]); ptr += 4; -- 2.7.4 From 848ae2d84733d66d928d248f2dd67ae3436b746b Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Tue, 2 Aug 2022 10:14:25 +0900 Subject: [PATCH 11/16] output: Fix wrong return value Change-Id: Idfdedc1f829b2403e78085e5fb99b7ee1b0565f4 --- src/output/output_led.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/output/output_led.c b/src/output/output_led.c index 455ea18..31d246f 100644 --- a/src/output/output_led.c +++ b/src/output/output_led.c @@ -43,7 +43,7 @@ headless_output_create(struct wl_display *display) output = calloc(1, sizeof(led_output_t)); if (!output) { HS_ERROR("Failed to allocate memory\n"); - return false; + return NULL; } output->display = display; -- 2.7.4 From 30937bb8eb72e0f9dcf34041f5f83a5ba549b992 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 1 Sep 2022 17:20:17 +0900 Subject: [PATCH 12/16] packaging: Add xkeyboard-config dependency The xkeyboard-config is necessary to feed a keymap dataset to xkbcommon. Otherwise, xkb_contexnt_new() will be failed. Change-Id: I101cece10129a749ea2b78353445bebf27d0e1b7 --- packaging/headless-server.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packaging/headless-server.spec b/packaging/headless-server.spec index 9f6716e..8b934c8 100644 --- a/packaging/headless-server.spec +++ b/packaging/headless-server.spec @@ -28,6 +28,9 @@ BuildRequires: pkgconfig(libds-tizen-input-devicemgr) Requires: libtbm Requires: capi-system-peripheral-io +# To feed a keymap dataset to xkbcommon +Requires: xkeyboard-config + %description Headless server is a display server for headless profile. -- 2.7.4 From 1cd614e49e0f223eec367b226cf69624d52ede67 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Fri, 2 Sep 2022 16:46:52 +0900 Subject: [PATCH 13/16] input: clean up devicemgr related code Change-Id: Ia8f04b19f3d41a7dc476201b1525a2377767f032 --- src/input/input.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/input/input.c b/src/input/input.c index 638c5f7..bdc8a3f 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -349,16 +349,14 @@ devicemgr_add_keymap_data(struct wl_list *list, const char *name, int keycode) } static void -devicemgr_remove_keymap_data(struct wl_list *list, int keycode) +devicemgr_cleanup_keymap_list(struct wl_list *list) { struct ds_tizen_input_devicemgr_keymap_data *data, *tmp; wl_list_for_each_safe(data, tmp, list, link) { - if (data->keycode == keycode) { - wl_list_remove(&data->link); - free(data->name); - free(data); - } + wl_list_remove(&data->link); + free(data->name); + free(data); } } @@ -383,8 +381,5 @@ devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr) if (!res) ds_inf("Failed to set keymap"); - devicemgr_remove_keymap_data(&keymap_list, KEYCODE_XF86_VOLUME_RAISE); - devicemgr_remove_keymap_data(&keymap_list, KEYCODE_XF86_VOLUME_LOWER); - devicemgr_remove_keymap_data(&keymap_list, KEYCODE_XF86_LIGHT_ON); - devicemgr_remove_keymap_data(&keymap_list, KEYCODE_XF86_LIGHT_OFF); + devicemgr_cleanup_keymap_list(&keymap_list); } -- 2.7.4 From 80d49fe92a6087381faa0cd155a85dce6505c176 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 5 Sep 2022 11:06:46 +0900 Subject: [PATCH 14/16] input: Add null checks This adds null checks for xkb_context and xkb_keymap, also makes a function for setting keymap for ds_keyboard. Change-Id: If20e115c20491cf27e1a21a7fa77f15b97176a55 --- src/input/input.c | 51 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/input/input.c b/src/input/input.c index bdc8a3f..43f3652 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -82,6 +82,7 @@ static void handle_top_view_destroy(struct wl_listener *listener, void *data); static headless_keyboard_t *create_keyboard(headless_input_t *input, struct ds_input_device *dev); static void keyboard_destroy(headless_keyboard_t *keyboard); +static bool keyboard_set_keymap(headless_keyboard_t *keyboard); static void keyboard_handle_destroy(struct wl_listener *listener, void *data); static void keyboard_handle_key(struct wl_listener *listener, void *data); static void devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr); @@ -256,9 +257,6 @@ static headless_keyboard_t * create_keyboard(headless_input_t *input, struct ds_input_device *dev) { headless_keyboard_t *keyboard; - struct ds_keyboard *ds_keyboard; - struct xkb_context *context; - struct xkb_keymap *keymap; keyboard = calloc(1, sizeof *keyboard); if (!keyboard) { @@ -269,21 +267,18 @@ create_keyboard(headless_input_t *input, struct ds_input_device *dev) keyboard->input = input; keyboard->dev = dev; + if (!keyboard_set_keymap(keyboard)) { + ds_err("Could not set keymap for ds_keyboard"); + free(keyboard); + return NULL; + } + keyboard->device_destroy.notify = keyboard_handle_destroy; ds_input_device_add_destroy_listener(dev, &keyboard->device_destroy); - ds_keyboard = ds_input_device_get_keyboard(dev); - keyboard->key.notify = keyboard_handle_key; - ds_keyboard_add_key_listener(ds_keyboard, &keyboard->key); - - context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - keymap = xkb_keymap_new_from_names(context, NULL, - XKB_KEYMAP_COMPILE_NO_FLAGS); - - ds_keyboard_set_keymap(ds_keyboard, keymap); - xkb_keymap_unref(keymap); - xkb_context_unref(context); + ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), + &keyboard->key); ds_inf("Input(%p): New keyboard(%p)", input, keyboard); @@ -300,6 +295,34 @@ keyboard_destroy(headless_keyboard_t *keyboard) free(keyboard); } +static bool +keyboard_set_keymap(headless_keyboard_t *keyboard) +{ + struct xkb_context *context; + struct xkb_keymap *keymap; + + context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (!context) { + ds_err("Could not create xkb_context"); + return false; + } + + keymap = xkb_keymap_new_from_names(context, NULL, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!keymap) { + ds_err("Could not create xkb_keymap"); + xkb_context_unref(context); + return false; + } + ds_keyboard_set_keymap(ds_input_device_get_keyboard(keyboard->dev), + keymap); + + xkb_keymap_unref(keymap); + xkb_context_unref(context); + + return true; +} + static void keyboard_handle_destroy(struct wl_listener *listener, void *data) { -- 2.7.4 From ccb815c82c3bcd6851ad7320123fa62ddea6097e Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 5 Sep 2022 11:09:40 +0900 Subject: [PATCH 15/16] input: Fix wrong return value Change-Id: I92039fef769e4484cb826b2b345e4453711ce1da --- src/input/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/input.c b/src/input/input.c index 43f3652..7b95a74 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -261,7 +261,7 @@ create_keyboard(headless_input_t *input, struct ds_input_device *dev) keyboard = calloc(1, sizeof *keyboard); if (!keyboard) { ds_err("Could not allocate memory"); - return false; + return NULL; } keyboard->input = input; -- 2.7.4 From 05caabad4064fe66eae2a8a6f0fc87b6b547411c Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 5 Jan 2023 16:13:39 +0900 Subject: [PATCH 16/16] Apply renamed event name of libds Change-Id: I2d6b50810689ddf34cdff077f2f83cbb9d4ad67f --- src/input/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/input.c b/src/input/input.c index 7b95a74..381a22e 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -340,7 +340,7 @@ keyboard_handle_key(struct wl_listener *listener, void *data) { headless_input_t *input; headless_keyboard_t *keyboard; - struct ds_event_keyboard_key *ev = data; + struct ds_keyboard_event_key *ev = data; keyboard = wl_container_of(listener, keyboard, key); input = keyboard->input; -- 2.7.4