From 1bd5d3b200f9c1dc7d7f02c863a0cd21bf206fac Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Wed, 7 Sep 2022 15:44:23 +0900 Subject: [PATCH 01/16] clients: merge text-entry code to simple-tbm Change-Id: I9c74e6155cb570d74cdb24c6b05e0515cc8362bf --- clients/meson.build | 22 +- clients/simple-tbm.c | 605 ++++++++++++++++++++- clients/text-entry.c | 1261 -------------------------------------------- packaging/libds-tizen.spec | 1 - 4 files changed, 596 insertions(+), 1293 deletions(-) delete mode 100644 clients/text-entry.c diff --git a/clients/meson.build b/clients/meson.build index c825bce..aa89a3c 100644 --- a/clients/meson.build +++ b/clients/meson.build @@ -14,13 +14,6 @@ simple_tbm_deps = [ tizen_extension_client, ] -text_entry_files = ['text-entry.c'] -text_entry_deps = [ - dependency('wayland-client', required: true), - wayland_tbm_client, - libtbm, -] - protocols = { 'xdg-shell': wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', } @@ -35,7 +28,6 @@ foreach name, path : protocols command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'], ) simple_tbm_files += code - text_entry_files += code client_header = custom_target( name.underscorify() + '_client_h', @@ -45,12 +37,13 @@ foreach name, path : protocols build_by_default: false, ) simple_tbm_files += client_header - text_entry_files += client_header endforeach executable('ds-simple-tbm', simple_tbm_files, - dependencies: simple_tbm_deps, + dependencies: [simple_tbm_deps, + deps_libds_tizen_text_input, + ], install_dir: libds_tizen_bindir, install: true, ) @@ -65,15 +58,6 @@ executable('ds-simple-dpms', install: true, ) -executable('text-entry', - text_entry_files, - dependencies: [text_entry_deps, - deps_libds_tizen_text_input, - ], - install_dir: libds_tizen_bindir, - install: true, -) - input_generator_files = ['input-generator.c'] input_generator_deps = [ dependency('wayland-client', required: true), diff --git a/clients/simple-tbm.c b/clients/simple-tbm.c index f68fedb..46d48dd 100644 --- a/clients/simple-tbm.c +++ b/clients/simple-tbm.c @@ -39,9 +39,12 @@ #include #include "xdg-shell-client-protocol.h" #include +#include +#include static uint64_t buffer_info_key; #define BUFFER_INFO_KEY (unsigned long)(&buffer_info_key) +struct text_entry; struct display { struct wl_display *display; @@ -57,6 +60,9 @@ struct display { int notified; bool blocked; struct wl_surface *entered_surface; + + struct wl_text_input_manager *text_input_mgr; + struct text_entry *entry; }; struct window { @@ -75,10 +81,54 @@ struct buffer_info { struct wl_buffer *wl_buffer; }; +struct text_entry { + char *text; + int active; + bool panel_visible; + uint32_t cursor; + uint32_t anchor; + struct { + char *text; + int32_t cursor; + char *commit; + } preedit; + struct { + int32_t cursor; + } preedit_info; + struct { + int32_t cursor; + int32_t anchor; + uint32_t delete_index; + uint32_t delete_length; + bool invalid_delete; + } pending_commit; + struct wl_text_input *text_input; + struct { + xkb_mod_mask_t shift_mask; + } keysym; + uint32_t serial; + uint32_t reset_serial; + uint32_t content_purpose; + bool click_to_show; + char *preferred_language; + bool button_pressed; +}; + +struct rectangle { + int32_t x; + int32_t y; + int32_t width; + int32_t height; +}; + static int running = 1; static void redraw(void *data, struct wl_callback *callback, uint32_t time); +static void +text_entry_activate(struct display *d); +static void +text_entry_deactivate(struct display *d); static void handle_xdg_surface_configure(void *data, struct xdg_surface *surface, @@ -343,20 +393,27 @@ static void pointer_handle_button(void *data, struct wl_pointer *pointer, static int warp_x = 0, warp_y = 0; if (state == WL_POINTER_BUTTON_STATE_PRESSED) { - fprintf(stderr, "pointer_handle_button: PRESSED\n"); - - warp_x += 10; - warp_y += 10; - tizen_input_device_manager_pointer_warp(d->devicemgr, - d->entered_surface, - wl_fixed_from_int(warp_x), - wl_fixed_from_int(warp_y)); - fprintf(stderr, "requesting pointer_warp: surface:%p sx: %d sy: %d\n", - d->entered_surface, - warp_x, warp_y); + fprintf(stderr, "pointer_handle_button: button(%d) PRESSED\n", button); + if (button == 1) { //left button + text_entry_activate(d); + } + else if (button == 3) {//right button + warp_x += 10; + warp_y += 10; + tizen_input_device_manager_pointer_warp(d->devicemgr, + d->entered_surface, + wl_fixed_from_int(warp_x), + wl_fixed_from_int(warp_y)); + fprintf(stderr, "requesting pointer_warp: surface:%p sx: %d sy: %d\n", + d->entered_surface, + warp_x, warp_y); + } } else { - fprintf(stderr, "pointer_handle_button: RELEASED\n"); + fprintf(stderr, "pointer_handle_button: button(%d) RELEASED\n", button); + if (button == 1) { + text_entry_deactivate(d); + } } } @@ -571,6 +628,519 @@ static const struct tizen_input_device_manager_listener _input_device_manager_li .block_expired = input_device_manager_handle_block_expired, }; + +static void +text_entry_get_cursor_rectangle(struct text_entry *entry, struct rectangle *rectangle) +{ + if (entry->preedit.text && entry->preedit.cursor < 0) { + rectangle->x = 0; + rectangle->y = 0; + rectangle->width = 0; + rectangle->height = 0; + return; + } + + rectangle->x = 10; + rectangle->y = 20; + rectangle->width = 50; + rectangle->height = 50; +} + +static void +text_entry_update(struct text_entry *entry) +{ + struct rectangle cursor_rectangle; + + fprintf(stderr, "text_entry_update()\n"); + + wl_text_input_set_content_type(entry->text_input, + WL_TEXT_INPUT_CONTENT_HINT_NONE, + entry->content_purpose); + + if (entry->preferred_language) + wl_text_input_set_preferred_language(entry->text_input, + entry->preferred_language); + + text_entry_get_cursor_rectangle(entry, &cursor_rectangle); + wl_text_input_set_cursor_rectangle(entry->text_input, + cursor_rectangle.x, + cursor_rectangle.y, + cursor_rectangle.width, + cursor_rectangle.height); + + wl_text_input_commit_state(entry->text_input, ++entry->serial); +} + +static void +text_entry_reset_preedit(struct text_entry *entry) +{ + fprintf(stderr, "text_entry_reset_preedit()\n"); + entry->preedit.cursor = 0; + + free(entry->preedit.text); + entry->preedit.text = NULL; + + free(entry->preedit.commit); + entry->preedit.commit = NULL; +} + +static void +text_entry_insert_at_cursor(struct text_entry *entry, const char *text, + int32_t cursor, int32_t anchor) +{ + fprintf(stderr, "text_entry_insert_at_cursor()\n"); + char *new_text; + int len_entry_text, len_text; + + len_entry_text = strlen(entry->text); + len_text = strlen(text); + new_text = malloc(len_entry_text + len_text + 1); + if (new_text == NULL) { + fprintf(stderr, "alloc fail"); + return; + } + + memcpy(new_text, entry->text, entry->cursor); + memcpy(new_text + entry->cursor, text, len_text); + memcpy(new_text + entry->cursor + len_text, + entry->text + entry->cursor, len_entry_text - entry->cursor); + new_text[len_entry_text + len_text] = '\0'; + + free(entry->text); + entry->text = new_text; + if (anchor >= 0) + entry->anchor = entry->cursor + strlen(text) + anchor; + else + entry->anchor = entry->cursor + 1 + anchor; + + if (cursor >= 0) + entry->cursor += strlen(text) + cursor; + else + entry->cursor += 1 + cursor; + + text_entry_update(entry); +} + +static void +text_entry_commit_and_reset(struct text_entry *entry) +{ + char *commit = NULL; + + fprintf(stderr, "text_entry_commit_and_reset()\n"); + + if (entry->preedit.commit) + commit = strdup(entry->preedit.commit); + + text_entry_reset_preedit(entry); + if (commit) { + text_entry_insert_at_cursor(entry, commit, 0, 0); + free(commit); + } + + wl_text_input_reset(entry->text_input); + text_entry_update(entry); + entry->reset_serial = entry->serial; +} + +static void +text_input_enter(void *data, struct wl_text_input *text_input, + struct wl_surface *surface) +{ + fprintf(stderr, "text_input_enter()\n"); + + struct display *d = data; + struct text_entry *entry = d->entry; + + entry->active++; + + text_entry_update(entry); + entry->reset_serial = entry->serial; +} + +static void +text_input_leave(void *data, struct wl_text_input *text_input) +{ + fprintf(stderr, "text_input_leave()\n"); + + struct display *d = data; + struct text_entry *entry = d->entry; + + text_entry_commit_and_reset(entry); + d->entry->active--; + + if (!entry->active) { + wl_text_input_hide_input_panel(text_input); + entry->panel_visible = false; + } +} + +static void +text_input_modifiers_map(void *data, struct wl_text_input *text_input, + struct wl_array *map) +{ + fprintf(stderr, "text_input_modifiers_map()\n"); +} + +static void +text_input_input_panel_state(void *data, struct wl_text_input *text_input, + uint32_t state) +{ + fprintf(stderr, "text_input_input_panel_state() state:%u\n", state); +} + +static void +clear_pending_preedit(struct text_entry *entry) +{ + fprintf(stderr, "clear_pending_preedit()\n"); + + memset(&entry->pending_commit, 0, sizeof entry->pending_commit); + + entry->preedit_info.cursor = 0; + + memset(&entry->preedit_info, 0, sizeof entry->preedit_info); +} + +static void +text_entry_delete_text(struct text_entry *entry, + uint32_t index, uint32_t length) +{ + uint32_t l; + + fprintf(stderr, "text_entry_delete_text()\n"); + + assert(index <= strlen(entry->text)); + assert(index + length <= strlen(entry->text)); + assert(index + length >= length); + + l = strlen(entry->text + index + length); + memmove(entry->text + index, + entry->text + index + length, + l + 1); + + if (entry->cursor > (index + length)) + entry->cursor -= length; + else if (entry->cursor > index) + entry->cursor = index; + + entry->anchor = entry->cursor; + + text_entry_update(entry); +} + +static void +text_entry_delete_selected_text(struct text_entry *entry) +{ + uint32_t start_index = entry->anchor < entry->cursor ? entry->anchor : entry->cursor; + uint32_t end_index = entry->anchor < entry->cursor ? entry->cursor : entry->anchor; + + fprintf(stderr, "text_entry_delete_selected_text()\n"); + + if (entry->anchor == entry->cursor) + return; + + text_entry_delete_text(entry, start_index, end_index - start_index); + + entry->anchor = entry->cursor; +} + +static void +text_entry_set_preedit(struct text_entry *entry, + const char *preedit_text, + int preedit_cursor) +{ + fprintf(stderr, "text_entry_set_preedit()\n"); + + text_entry_reset_preedit(entry); + + if (!preedit_text) + return; + + entry->preedit.text = strdup(preedit_text); + entry->preedit.cursor = preedit_cursor; +} + +static void +text_input_preedit_string(void *data, struct wl_text_input *text_input, + uint32_t serial, const char *text, const char *commit) +{ + struct display *d = data; + struct text_entry *entry = d->entry; + + fprintf(stderr, "text_input_preedit_string() serial(%u), text(%s), commit(%s)\n", serial, text, commit); + + if ((entry->serial - serial) > (entry->serial - entry->reset_serial)) { + fprintf(stderr, "Ignore preedit_string. Serial: %u, Current: %u, Reset: %u\n", + serial, entry->serial, entry->reset_serial); + clear_pending_preedit(entry); + return; + } + + if (entry->pending_commit.invalid_delete) { + fprintf(stderr, "Ignore preedit_string. Invalid previous delete_surrounding event.\n"); + clear_pending_preedit(entry); + return; + } + + if (entry->pending_commit.delete_length) { + text_entry_delete_text(entry, + entry->pending_commit.delete_index, + entry->pending_commit.delete_length); + } else { + text_entry_delete_selected_text(entry); + } + + text_entry_set_preedit(entry, text, entry->preedit_info.cursor); + entry->preedit.commit = strdup(commit); + + clear_pending_preedit(entry); + + text_entry_update(entry); +} + +static void +text_input_preedit_styling(void *data, struct wl_text_input *text_input, + uint32_t index, uint32_t length, uint32_t style) +{ + fprintf(stderr, "text_input_preedit_styling() index(%u), length(%u), style(%u)\n", index, length, style); + + switch (style) { + case WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT: + fprintf(stderr, "text_input_preedit_styling() style:DEFAULT"); + break; + case WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE: + fprintf(stderr, "text_input_preedit_styling() style:UNDERLINE"); + break; + case WL_TEXT_INPUT_PREEDIT_STYLE_INCORRECT: + fprintf(stderr, "text_input_preedit_styling() style:INCORRECT"); + break; + case WL_TEXT_INPUT_PREEDIT_STYLE_SELECTION: + fprintf(stderr, "text_input_preedit_styling() style:SELECTION"); + break; + case WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT: + fprintf(stderr, "text_input_preedit_styling() style:HIGHLIGHT"); + break; + case WL_TEXT_INPUT_PREEDIT_STYLE_ACTIVE: + fprintf(stderr, "text_input_preedit_styling() style:ACTIVE"); + break; + case WL_TEXT_INPUT_PREEDIT_STYLE_INACTIVE: + fprintf(stderr, "text_input_preedit_styling() style:INACTIVE"); + break; + default: + fprintf(stderr, "text_input_preedit_styling() no style enum found"); + break; + } +} + +static void +text_input_preedit_cursor(void *data, struct wl_text_input *text_input, + int32_t index) +{ + struct display *d = data; + struct text_entry *entry = d->entry; + + fprintf(stderr, "text_input_preedit_cursor() index(%u)\n", index); + + entry->preedit_info.cursor = index; +} + +static void +text_input_commit_string(void *data, struct wl_text_input *text_input, + uint32_t serial, const char *text) +{ + struct display *d = data; + struct text_entry *entry = d->entry; + + fprintf(stderr, "text_input_commit_string() serial(%u), text(%s)\n", serial, text); + + if ((entry->serial - serial) > (entry->serial - entry->reset_serial)) { + fprintf(stderr, "Ignore commit. Serial: %u, Current: %u, Reset: %u\n", + serial, entry->serial, entry->reset_serial); + return; + } + + if (entry->pending_commit.invalid_delete) { + fprintf(stderr, "Ignore commit. Invalid previous delete_surrounding event.\n"); + memset(&entry->pending_commit, 0, sizeof entry->pending_commit); + return; + } + + text_entry_reset_preedit(entry); + + if (entry->pending_commit.delete_length) { + text_entry_delete_text(entry, + entry->pending_commit.delete_index, + entry->pending_commit.delete_length); + } else { + text_entry_delete_selected_text(entry); + } + + text_entry_insert_at_cursor(entry, text, + entry->pending_commit.cursor, + entry->pending_commit.anchor); + + memset(&entry->pending_commit, 0, sizeof entry->pending_commit); +} + +static void +text_input_cursor_position(void *data, struct wl_text_input *text_input, + int32_t index, int32_t anchor) +{ + fprintf(stderr, "text_input_cursor_position() index(%d), anchor(%d)\n", index, anchor); +} + +static void +text_input_delete_surrounding_text(void *data, + struct wl_text_input *text_input, int32_t index, uint32_t length) +{ + struct text_entry *entry = data; + uint32_t text_length; + + fprintf(stderr, "text_input_delete_surrounding_text() index(%d), length(%u)\n", index, length); + + entry->pending_commit.delete_index = entry->cursor + index; + entry->pending_commit.delete_length = length; + entry->pending_commit.invalid_delete = false; + + text_length = strlen(entry->text); + + if (entry->pending_commit.delete_index > text_length || + length > text_length || + entry->pending_commit.delete_index + length > text_length) { + fprintf(stderr, "delete_surrounding_text: Invalid index: %d," \ + "length %u'; cursor: %u text length: %u\n", index, length, entry->cursor, text_length); + entry->pending_commit.invalid_delete = true; + return; + } +} + +static void +text_input_keysym(void *data, struct wl_text_input *text_input, + uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, + uint32_t modifiers) +{ + fprintf(stderr, "text_input_keysym() serial(%u), time(%u), sym(%u), state(%u), modifiers(%u)\n", + serial, time, sym, state, modifiers); +} + +static void +text_input_language(void *data, struct wl_text_input *text_input, + uint32_t serial, const char *language) +{ + fprintf(stderr, "text_input_language() serial(%u), language(%s)\n", serial, language); +} + +static void +text_input_text_direction(void *data, struct wl_text_input *text_input, + uint32_t serial, uint32_t direction) +{ + fprintf(stderr, "text_input_text_direction() serial(%d), direction(%d)\n", serial, direction); +} + +static const struct wl_text_input_listener text_input_listener = { + .enter = text_input_enter, + .leave = text_input_leave, + .modifiers_map = text_input_modifiers_map, + .input_panel_state = text_input_input_panel_state, + .preedit_string = text_input_preedit_string, + .preedit_styling = text_input_preedit_styling, + .preedit_cursor = text_input_preedit_cursor, + .commit_string = text_input_commit_string, + .cursor_position = text_input_cursor_position, + .delete_surrounding_text = text_input_delete_surrounding_text, + .keysym = text_input_keysym, + .language = text_input_language, + .text_direction = text_input_text_direction, + // TIZEN_ONLY + .selection_region = NULL, + .private_command = NULL, + .input_panel_geometry = NULL, + .input_panel_data = NULL, + .get_selection_text = NULL, + .get_surrounding_text = NULL, + .filter_key_event_done = NULL, + .hide_permission = NULL, + .recapture_string = NULL, + .input_panel_event = NULL, + .commit_content = NULL, + // +}; + +static void +text_entry_activate(struct display *d) +{ + struct wl_surface *surface = d->entered_surface; + struct text_entry *entry = d->entry; + + fprintf(stderr, "text_entry_activate\n"); + if (entry->click_to_show && entry->active) { + entry->panel_visible = !entry->panel_visible; + + if (entry->panel_visible) + wl_text_input_show_input_panel(entry->text_input); + else + wl_text_input_hide_input_panel(entry->text_input); + + return; + } + + if (!entry->click_to_show) + wl_text_input_show_input_panel(entry->text_input); + + wl_text_input_activate(entry->text_input, + d->seat, + surface); +} + +static void +text_entry_deactivate(struct display *d) +{ + struct text_entry *entry = d->entry; + + fprintf(stderr, "text_entry_deactivate\n"); + wl_text_input_deactivate(entry->text_input, + d->seat); +} + +static void +text_entry_destroy(struct display *d) +{ + struct text_entry *entry; + + entry = d->entry; + d->entry = NULL; + + wl_text_input_destroy(entry->text_input); + free(entry->text); + free(entry->preferred_language); + free(entry); +} + +static struct text_entry* +text_entry_create(struct display *d, const char *text) +{ + struct text_entry *entry; + + entry = calloc(1, sizeof *entry); + if (!entry) + return NULL; + + entry->text = strdup(text); + entry->active = 0; + entry->panel_visible = false; + entry->cursor = strlen(text); + entry->anchor = entry->cursor; + entry->click_to_show = true; + entry->text_input = + wl_text_input_manager_create_text_input(d->text_input_mgr); + wl_text_input_add_listener(entry->text_input, + &text_input_listener, d); + + d->entry = entry; + fprintf(stderr, "text_entry_create() entry(%p) created.\n", entry); + + return entry; +} + static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) @@ -600,6 +1170,12 @@ registry_handle_global(void *data, struct wl_registry *registry, tizen_input_device_manager_add_listener(d->devicemgr, &_input_device_manager_listener, d); fprintf(stderr, "tizen input device manager bound!\n"); + } else if (strcmp(interface, "wl_text_input_manager") == 0) { + d->text_input_mgr = wl_registry_bind(registry, + id, &wl_text_input_manager_interface, version); + fprintf(stderr, "wl_text_input_manager bound!\n"); + + text_entry_create(d, "Entry"); } } @@ -698,6 +1274,11 @@ create_display(void) static void destroy_display(struct display *display) { + text_entry_destroy(display); + + if (display->text_input_mgr) + wl_text_input_manager_destroy(display->text_input_mgr); + if (display->seat) wl_seat_destroy(display->seat); diff --git a/clients/text-entry.c b/clients/text-entry.c deleted file mode 100644 index 0561e56..0000000 --- a/clients/text-entry.c +++ /dev/null @@ -1,1261 +0,0 @@ -/* - * Copyright © 2011 Benjamin Franzke - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "xdg-shell-client-protocol.h" -#include -#include - -static uint64_t buffer_info_key; -#define BUFFER_INFO_KEY (unsigned long)(&buffer_info_key) - -struct display { - struct wl_display *display; - struct wl_registry *registry; - struct wl_compositor *compositor; - struct xdg_wm_base *wm_base; - struct wl_shm *shm; - struct wl_seat *seat; - struct wayland_tbm_client *wl_tbm; - bool has_xrgb; - - struct wl_text_input_manager *text_input_mgr; - int notified; - bool blocked; - struct wl_surface *entered_surface; - - struct text_entry *entry; -}; - -struct window { - struct display *display; - int width, height; - struct wl_surface *surface; - struct xdg_surface *xdg_surface; - struct xdg_toplevel *xdg_toplevel; - struct wl_callback *callback; - tbm_surface_queue_h surface_queue; - bool wait_for_configure; -}; - -struct buffer_info { - struct window *window; - struct wl_buffer *wl_buffer; -}; - -struct text_entry { - char *text; - int active; - bool panel_visible; - uint32_t cursor; - uint32_t anchor; - struct { - char *text; - int32_t cursor; - char *commit; - } preedit; - struct { - int32_t cursor; - } preedit_info; - struct { - int32_t cursor; - int32_t anchor; - uint32_t delete_index; - uint32_t delete_length; - bool invalid_delete; - } pending_commit; - struct wl_text_input *text_input; - struct { - xkb_mod_mask_t shift_mask; - } keysym; - uint32_t serial; - uint32_t reset_serial; - uint32_t content_purpose; - bool click_to_show; - char *preferred_language; - bool button_pressed; -}; - -struct rectangle { - int32_t x; - int32_t y; - int32_t width; - int32_t height; -}; - -static int running = 1; - -static void -redraw(void *data, struct wl_callback *callback, uint32_t time); -static void -text_entry_activate(struct display *d); -static void -text_entry_deactivate(struct display *d); - -static void -handle_xdg_surface_configure(void *data, struct xdg_surface *surface, - uint32_t serial) -{ - struct window *window = data; - - xdg_surface_ack_configure(surface, serial); - - if (window->wait_for_configure) { - redraw(window, NULL, 0); - window->wait_for_configure = false; - } -} - -static const struct xdg_surface_listener xdg_surface_listener = { - handle_xdg_surface_configure, -}; - -static void -handle_xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, - int32_t width, int32_t height, - struct wl_array *state) -{ -} - -static void -handle_xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) -{ - running = 0; -} - -static const struct xdg_toplevel_listener xdg_toplevel_listener = { - handle_xdg_toplevel_configure, - handle_xdg_toplevel_close, -}; - -static struct window * -create_window(struct display *display, int width, int height) -{ - struct window *window; - - window = calloc(1, sizeof *window); - if (!window) - return NULL; - - window->callback = NULL; - window->display = display; - window->width = width; - window->height = height; - window->surface = wl_compositor_create_surface(display->compositor); - - if (display->wm_base) { - window->xdg_surface = - xdg_wm_base_get_xdg_surface(display->wm_base, - window->surface); - assert(window->xdg_surface); - xdg_surface_add_listener(window->xdg_surface, - &xdg_surface_listener, window); - - window->xdg_toplevel = - xdg_surface_get_toplevel(window->xdg_surface); - assert(window->xdg_toplevel); - xdg_toplevel_add_listener(window->xdg_toplevel, - &xdg_toplevel_listener, window); - - xdg_toplevel_set_title(window->xdg_toplevel, "simple-tbm"); - wl_surface_commit(window->surface); - window->wait_for_configure = true; - } else { - assert(0); - } - - window->surface_queue = - wayland_tbm_client_create_surface_queue(display->wl_tbm, - window->surface, - 3, - width, - height, - TBM_FORMAT_XRGB8888); - assert(window->surface_queue); - - return window; -} - -static void -destroy_window(struct window *window) -{ - tbm_surface_queue_destroy(window->surface_queue); - - if (window->callback) - wl_callback_destroy(window->callback); - - if (window->xdg_toplevel) - xdg_toplevel_destroy(window->xdg_toplevel); - if (window->xdg_surface) - xdg_surface_destroy(window->xdg_surface); - wl_surface_destroy(window->surface); - free(window); -} - -static void -paint_pixels(void *image, int padding, int width, int height, uint32_t time) -{ - const int halfh = padding + (height - padding * 2) / 2; - const int halfw = padding + (width - padding * 2) / 2; - int ir, or; - uint32_t *pixel = image; - int y; - - /* squared radii thresholds */ - or = (halfw < halfh ? halfw : halfh) - 8; - ir = or - 32; - or *= or; - ir *= ir; - - pixel += padding * width; - for (y = padding; y < height - padding; y++) { - int x; - int y2 = (y - halfh) * (y - halfh); - - pixel += padding; - for (x = padding; x < width - padding; x++) { - uint32_t v; - - /* squared distance from center */ - int r2 = (x - halfw) * (x - halfw) + y2; - - if (r2 < ir) - v = (r2 / 32 + time / 64) * 0x0080401; - else if (r2 < or) - v = (y + time / 32) * 0x0080401; - else - v = (x + time / 16) * 0x0080401; - v &= 0x00ffffff; - - /* cross if compositor uses X from XRGB as alpha */ - if (abs(x - y) > 6 && abs(x + y - height) > 6) - v |= 0xff000000; - - *pixel++ = v; - } - - pixel += padding; - } -} - -static void -buffer_info_free_cb(void *data) -{ - struct buffer_info *buffer_info = data; - - if (!buffer_info) - return; - - wayland_tbm_client_destroy_buffer(buffer_info->window->display->wl_tbm, - buffer_info->wl_buffer); - free(buffer_info); -} - -static void -buffer_handle_release(void *data, struct wl_buffer *wl_buffer) -{ - tbm_surface_h surface = data; - struct buffer_info *buffer_info; - - tbm_surface_internal_get_user_data(surface, BUFFER_INFO_KEY, - (void **)&buffer_info); - if (buffer_info) - tbm_surface_queue_release(buffer_info->window->surface_queue, surface); -} - -static const struct wl_buffer_listener buffer_listener = { - .release = buffer_handle_release, -}; - -static const struct wl_callback_listener frame_listener; - -static void -redraw(void *data, struct wl_callback *callback, uint32_t time) -{ - struct window *window = data; - struct buffer_info *buffer_info = NULL; - tbm_surface_h surface = NULL; - tbm_surface_info_s surface_info; - - if (!tbm_surface_queue_can_dequeue(window->surface_queue, 0)) - return; - - tbm_surface_queue_dequeue(window->surface_queue, &surface); - assert(surface); - - tbm_surface_internal_get_user_data(surface, BUFFER_INFO_KEY, - (void **)&buffer_info); - if (!buffer_info) { - buffer_info = calloc(1, sizeof *buffer_info); - assert(buffer_info); - - tbm_surface_internal_add_user_data(surface, BUFFER_INFO_KEY, buffer_info_free_cb); - tbm_surface_internal_set_user_data(surface, BUFFER_INFO_KEY, buffer_info); - - buffer_info->wl_buffer = - wayland_tbm_client_create_buffer(window->display->wl_tbm, surface); - assert(buffer_info->wl_buffer); - - wl_buffer_add_listener(buffer_info->wl_buffer, &buffer_listener, - surface); - - buffer_info->window = window; - } - - tbm_surface_map(surface, TBM_SURF_OPTION_WRITE, &surface_info); - - paint_pixels(surface_info.planes[0].ptr, 20, - (surface_info.planes[0].stride/4), surface_info.height, time); - - tbm_surface_unmap(surface); - - wl_surface_attach(window->surface, buffer_info->wl_buffer, 0, 0); - wl_surface_damage(window->surface, - 20, 20, window->width - 40, window->height - 40); - - if (callback) - wl_callback_destroy(callback); - - window->callback = wl_surface_frame(window->surface); - wl_callback_add_listener(window->callback, &frame_listener, window); - wl_surface_commit(window->surface); -} - -static const struct wl_callback_listener frame_listener = { - redraw -}; - -static void -shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) -{ - struct display *d = data; - - if (format == WL_SHM_FORMAT_XRGB8888) - d->has_xrgb = true; -} - -struct wl_shm_listener shm_listener = { - shm_format -}; - -static void -xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial) -{ - xdg_wm_base_pong(shell, serial); -} - -static const struct xdg_wm_base_listener xdg_wm_base_listener = { - xdg_wm_base_ping, -}; - -static void pointer_handle_button(void *data, struct wl_pointer *pointer, - uint32_t serial, uint32_t time, uint32_t button, uint32_t state) -{ - struct display *d = data; - - if (state == WL_POINTER_BUTTON_STATE_PRESSED) { - fprintf(stderr, "pointer_handle_button: PRESSED\n"); - - text_entry_activate(d); - } - else { - fprintf(stderr, "pointer_handle_button: RELEASED\n"); - - text_entry_deactivate(d); - } -} - -static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface, - wl_fixed_t surface_x, wl_fixed_t surface_y) -{ - struct display *d = data; - - fprintf(stderr, "pointer_handle_enter surface_x:%d, surface_y:%d\n", - wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y)); - d->entered_surface = surface; -} - -static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface) -{ - fprintf(stderr, "pointer_handle_leave\n"); -} - -static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) -{ - fprintf(stderr, "pointer_handle_motion surface_x:%d, surface_y:%d\n", - wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y)); -} - -static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) -{ - fprintf(stderr, "pointer_handle_frame\n"); -} - -static struct wl_pointer_listener pointer_listener = { - .enter = pointer_handle_enter, - .leave = pointer_handle_leave, - .motion = pointer_handle_motion, - .button = pointer_handle_button, - .axis = NULL, - .frame = pointer_handle_frame, - .axis_source = NULL, - .axis_stop = NULL, - .axis_discrete = NULL, -}; - -static void touch_handle_down(void *data, struct wl_touch *wl_touch, - uint32_t serial, uint32_t time, struct wl_surface *surface, - int32_t id, wl_fixed_t x, wl_fixed_t y) -{ - fprintf(stderr, "touch_handle_down id:%d, x:%d, y:%d\n", - id, wl_fixed_to_int(x), wl_fixed_to_int(y)); -} - -static void touch_handle_up(void *data, struct wl_touch *wl_touch, - uint32_t serial, uint32_t time, int32_t id) -{ - fprintf(stderr, "touch_handle_up id:%d\n", id); -} - -static void touch_handle_motion(void *data, struct wl_touch *wl_touch, - uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) -{ - fprintf(stderr, "touch_handle_motion id:%d, x:%d, y:%d\n", - id, wl_fixed_to_int(x), wl_fixed_to_int(y)); -} - -static void touch_handle_frame(void *data, struct wl_touch *wl_touch) -{ - fprintf(stderr, "touch_handle_frame\n"); -} - -static struct wl_touch_listener touch_listener = { - .down = touch_handle_down, - .up = touch_handle_up, - .motion = touch_handle_motion, - .frame = touch_handle_frame, - .cancel = NULL, - .shape = NULL, - .orientation = NULL, -}; - -static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard, - uint32_t format, int32_t fd, uint32_t size) -{ - fprintf(stderr, "keyboard_handle_keymap\n"); -} -static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface, struct wl_array *keys) -{ - fprintf(stderr, "keyboard_handle_enter\n"); -} -static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface) -{ - fprintf(stderr, "keyboard_handle_leave\n"); -} -static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) -{ - fprintf(stderr, "keyboard_handle_modifiers\n"); -} -static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, - int32_t rate, int32_t delay) -{ - fprintf(stderr, "keyboard_handle_repeat_info\n"); -} - -static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, uint32_t time, uint32_t key, uint32_t state) -{ - if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { - fprintf(stderr, "keyboard_handle_key: key:%d, PRESSED\n", key); - } else { - fprintf(stderr, "keyboard_handle_key: key:%d, RELEASED\n", key); - } -} - -static struct wl_keyboard_listener keyboard_listener = { - .keymap = keyboard_handle_keymap, - .enter = keyboard_handle_enter, - .leave = keyboard_handle_leave, - .key = keyboard_handle_key, - .modifiers = keyboard_handle_modifiers, - .repeat_info = keyboard_handle_repeat_info, -}; - -static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, - enum wl_seat_capability caps) -{ - struct display *d = data; - if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { - struct wl_keyboard *keyboard = wl_seat_get_keyboard(wl_seat); - wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL); - fprintf(stderr, "seat_handle_capabilities: keyboard\n"); - } - if ((caps & WL_SEAT_CAPABILITY_POINTER)) { - struct wl_pointer *pointer = wl_seat_get_pointer(wl_seat); - wl_pointer_add_listener(pointer, &pointer_listener, d); - fprintf(stderr, "seat_handle_capabilities: pointer\n"); - } - if ((caps & WL_SEAT_CAPABILITY_TOUCH)) { - struct wl_touch *touch = wl_seat_get_touch(wl_seat); - wl_touch_add_listener(touch, &touch_listener, d); - fprintf(stderr, "seat_handle_capabilities: touch\n"); - } -} - -static void seat_handle_name(void *data, struct wl_seat *wl_seat, - const char *name) -{ - fprintf(stderr, "seat_handle_name name:%s\n", name); -} - -const struct wl_seat_listener seat_listener = { - .capabilities = seat_handle_capabilities, - .name = seat_handle_name, -}; - -static void -text_entry_get_cursor_rectangle(struct text_entry *entry, struct rectangle *rectangle) -{ - if (entry->preedit.text && entry->preedit.cursor < 0) { - rectangle->x = 0; - rectangle->y = 0; - rectangle->width = 0; - rectangle->height = 0; - return; - } - - rectangle->x = 10; - rectangle->y = 20; - rectangle->width = 50; - rectangle->height = 50; -} - -static void -text_entry_update(struct text_entry *entry) -{ - struct rectangle cursor_rectangle; - - fprintf(stderr, "text_entry_update()\n"); - - wl_text_input_set_content_type(entry->text_input, - WL_TEXT_INPUT_CONTENT_HINT_NONE, - entry->content_purpose); - - if (entry->preferred_language) - wl_text_input_set_preferred_language(entry->text_input, - entry->preferred_language); - - text_entry_get_cursor_rectangle(entry, &cursor_rectangle); - wl_text_input_set_cursor_rectangle(entry->text_input, - cursor_rectangle.x, - cursor_rectangle.y, - cursor_rectangle.width, - cursor_rectangle.height); - - wl_text_input_commit_state(entry->text_input, ++entry->serial); -} - -static void -text_entry_reset_preedit(struct text_entry *entry) -{ - fprintf(stderr, "text_entry_reset_preedit()\n"); - entry->preedit.cursor = 0; - - free(entry->preedit.text); - entry->preedit.text = NULL; - - free(entry->preedit.commit); - entry->preedit.commit = NULL; -} - -static void -text_entry_insert_at_cursor(struct text_entry *entry, const char *text, - int32_t cursor, int32_t anchor) -{ - fprintf(stderr, "text_entry_insert_at_cursor()\n"); - char *new_text; - int len_entry_text, len_text; - - len_entry_text = strlen(entry->text); - len_text = strlen(text); - new_text = malloc(len_entry_text + len_text + 1); - if (new_text == NULL) { - fprintf(stderr, "alloc fail"); - return; - } - - memcpy(new_text, entry->text, entry->cursor); - memcpy(new_text + entry->cursor, text, len_text); - memcpy(new_text + entry->cursor + len_text, - entry->text + entry->cursor, len_entry_text - entry->cursor); - new_text[len_entry_text + len_text] = '\0'; - - free(entry->text); - entry->text = new_text; - if (anchor >= 0) - entry->anchor = entry->cursor + strlen(text) + anchor; - else - entry->anchor = entry->cursor + 1 + anchor; - - if (cursor >= 0) - entry->cursor += strlen(text) + cursor; - else - entry->cursor += 1 + cursor; - - text_entry_update(entry); -} - -static void -text_entry_commit_and_reset(struct text_entry *entry) -{ - char *commit = NULL; - - fprintf(stderr, "text_entry_commit_and_reset()\n"); - - if (entry->preedit.commit) - commit = strdup(entry->preedit.commit); - - text_entry_reset_preedit(entry); - if (commit) { - text_entry_insert_at_cursor(entry, commit, 0, 0); - free(commit); - } - - wl_text_input_reset(entry->text_input); - text_entry_update(entry); - entry->reset_serial = entry->serial; -} - -static void -text_input_enter(void *data, struct wl_text_input *text_input, - struct wl_surface *surface) -{ - fprintf(stderr, "text_input_enter()\n"); - - struct display *d = data; - struct text_entry *entry = d->entry; - - entry->active++; - - text_entry_update(entry); - entry->reset_serial = entry->serial; -} - -static void -text_input_leave(void *data, struct wl_text_input *text_input) -{ - fprintf(stderr, "text_input_leave()\n"); - - struct display *d = data; - struct text_entry *entry = d->entry; - - text_entry_commit_and_reset(entry); - d->entry->active--; - - if (!entry->active) { - wl_text_input_hide_input_panel(text_input); - entry->panel_visible = false; - } -} - -static void -text_input_modifiers_map(void *data, struct wl_text_input *text_input, - struct wl_array *map) -{ - fprintf(stderr, "text_input_modifiers_map()\n"); -} - -static void -text_input_input_panel_state(void *data, struct wl_text_input *text_input, - uint32_t state) -{ - fprintf(stderr, "text_input_input_panel_state() state:%u\n", state); -} - -static void -clear_pending_preedit(struct text_entry *entry) -{ - fprintf(stderr, "clear_pending_preedit()\n"); - - memset(&entry->pending_commit, 0, sizeof entry->pending_commit); - - entry->preedit_info.cursor = 0; - - memset(&entry->preedit_info, 0, sizeof entry->preedit_info); -} - -static void -text_entry_delete_text(struct text_entry *entry, - uint32_t index, uint32_t length) -{ - uint32_t l; - - fprintf(stderr, "text_entry_delete_text()\n"); - - assert(index <= strlen(entry->text)); - assert(index + length <= strlen(entry->text)); - assert(index + length >= length); - - l = strlen(entry->text + index + length); - memmove(entry->text + index, - entry->text + index + length, - l + 1); - - if (entry->cursor > (index + length)) - entry->cursor -= length; - else if (entry->cursor > index) - entry->cursor = index; - - entry->anchor = entry->cursor; - - text_entry_update(entry); -} - -static void -text_entry_delete_selected_text(struct text_entry *entry) -{ - uint32_t start_index = entry->anchor < entry->cursor ? entry->anchor : entry->cursor; - uint32_t end_index = entry->anchor < entry->cursor ? entry->cursor : entry->anchor; - - fprintf(stderr, "text_entry_delete_selected_text()\n"); - - if (entry->anchor == entry->cursor) - return; - - text_entry_delete_text(entry, start_index, end_index - start_index); - - entry->anchor = entry->cursor; -} - -static void -text_entry_set_preedit(struct text_entry *entry, - const char *preedit_text, - int preedit_cursor) -{ - fprintf(stderr, "text_entry_set_preedit()\n"); - - text_entry_reset_preedit(entry); - - if (!preedit_text) - return; - - entry->preedit.text = strdup(preedit_text); - entry->preedit.cursor = preedit_cursor; -} - -static void -text_input_preedit_string(void *data, struct wl_text_input *text_input, - uint32_t serial, const char *text, const char *commit) -{ - struct display *d = data; - struct text_entry *entry = d->entry; - - fprintf(stderr, "text_input_preedit_string() serial(%u), text(%s), commit(%s)\n", serial, text, commit); - - if ((entry->serial - serial) > (entry->serial - entry->reset_serial)) { - fprintf(stderr, "Ignore preedit_string. Serial: %u, Current: %u, Reset: %u\n", - serial, entry->serial, entry->reset_serial); - clear_pending_preedit(entry); - return; - } - - if (entry->pending_commit.invalid_delete) { - fprintf(stderr, "Ignore preedit_string. Invalid previous delete_surrounding event.\n"); - clear_pending_preedit(entry); - return; - } - - if (entry->pending_commit.delete_length) { - text_entry_delete_text(entry, - entry->pending_commit.delete_index, - entry->pending_commit.delete_length); - } else { - text_entry_delete_selected_text(entry); - } - - text_entry_set_preedit(entry, text, entry->preedit_info.cursor); - entry->preedit.commit = strdup(commit); - - clear_pending_preedit(entry); - - text_entry_update(entry); -} - -static void -text_input_preedit_styling(void *data, struct wl_text_input *text_input, - uint32_t index, uint32_t length, uint32_t style) -{ - fprintf(stderr, "text_input_preedit_styling() index(%u), length(%u), style(%u)\n", index, length, style); - - switch (style) { - case WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT: - fprintf(stderr, "text_input_preedit_styling() style:DEFAULT"); - break; - case WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE: - fprintf(stderr, "text_input_preedit_styling() style:UNDERLINE"); - break; - case WL_TEXT_INPUT_PREEDIT_STYLE_INCORRECT: - fprintf(stderr, "text_input_preedit_styling() style:INCORRECT"); - break; - case WL_TEXT_INPUT_PREEDIT_STYLE_SELECTION: - fprintf(stderr, "text_input_preedit_styling() style:SELECTION"); - break; - case WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT: - fprintf(stderr, "text_input_preedit_styling() style:HIGHLIGHT"); - break; - case WL_TEXT_INPUT_PREEDIT_STYLE_ACTIVE: - fprintf(stderr, "text_input_preedit_styling() style:ACTIVE"); - break; - case WL_TEXT_INPUT_PREEDIT_STYLE_INACTIVE: - fprintf(stderr, "text_input_preedit_styling() style:INACTIVE"); - break; - default: - fprintf(stderr, "text_input_preedit_styling() no style enum found"); - break; - } -} - -static void -text_input_preedit_cursor(void *data, struct wl_text_input *text_input, - int32_t index) -{ - struct display *d = data; - struct text_entry *entry = d->entry; - - fprintf(stderr, "text_input_preedit_cursor() index(%u)\n", index); - - entry->preedit_info.cursor = index; -} - -static void -text_input_commit_string(void *data, struct wl_text_input *text_input, - uint32_t serial, const char *text) -{ - struct display *d = data; - struct text_entry *entry = d->entry; - - fprintf(stderr, "text_input_commit_string() serial(%u), text(%s)\n", serial, text); - - if ((entry->serial - serial) > (entry->serial - entry->reset_serial)) { - fprintf(stderr, "Ignore commit. Serial: %u, Current: %u, Reset: %u\n", - serial, entry->serial, entry->reset_serial); - return; - } - - if (entry->pending_commit.invalid_delete) { - fprintf(stderr, "Ignore commit. Invalid previous delete_surrounding event.\n"); - memset(&entry->pending_commit, 0, sizeof entry->pending_commit); - return; - } - - text_entry_reset_preedit(entry); - - if (entry->pending_commit.delete_length) { - text_entry_delete_text(entry, - entry->pending_commit.delete_index, - entry->pending_commit.delete_length); - } else { - text_entry_delete_selected_text(entry); - } - - text_entry_insert_at_cursor(entry, text, - entry->pending_commit.cursor, - entry->pending_commit.anchor); - - memset(&entry->pending_commit, 0, sizeof entry->pending_commit); -} - -static void -text_input_cursor_position(void *data, struct wl_text_input *text_input, - int32_t index, int32_t anchor) -{ - fprintf(stderr, "text_input_cursor_position() index(%d), anchor(%d)\n", index, anchor); -} - -static void -text_input_delete_surrounding_text(void *data, - struct wl_text_input *text_input, int32_t index, uint32_t length) -{ - struct text_entry *entry = data; - uint32_t text_length; - - fprintf(stderr, "text_input_delete_surrounding_text() index(%d), length(%u)\n", index, length); - - entry->pending_commit.delete_index = entry->cursor + index; - entry->pending_commit.delete_length = length; - entry->pending_commit.invalid_delete = false; - - text_length = strlen(entry->text); - - if (entry->pending_commit.delete_index > text_length || - length > text_length || - entry->pending_commit.delete_index + length > text_length) { - fprintf(stderr, "delete_surrounding_text: Invalid index: %d," \ - "length %u'; cursor: %u text length: %u\n", index, length, entry->cursor, text_length); - entry->pending_commit.invalid_delete = true; - return; - } -} - -static void -text_input_keysym(void *data, struct wl_text_input *text_input, - uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, - uint32_t modifiers) -{ - fprintf(stderr, "text_input_keysym() serial(%u), time(%u), sym(%u), state(%u), modifiers(%u)\n", - serial, time, sym, state, modifiers); -} - -static void -text_input_language(void *data, struct wl_text_input *text_input, - uint32_t serial, const char *language) -{ - fprintf(stderr, "text_input_language() serial(%u), language(%s)\n", serial, language); -} - -static void -text_input_text_direction(void *data, struct wl_text_input *text_input, - uint32_t serial, uint32_t direction) -{ - fprintf(stderr, "text_input_text_direction() serial(%d), direction(%d)\n", serial, direction); -} - -static const struct wl_text_input_listener text_input_listener = { - .enter = text_input_enter, - .leave = text_input_leave, - .modifiers_map = text_input_modifiers_map, - .input_panel_state = text_input_input_panel_state, - .preedit_string = text_input_preedit_string, - .preedit_styling = text_input_preedit_styling, - .preedit_cursor = text_input_preedit_cursor, - .commit_string = text_input_commit_string, - .cursor_position = text_input_cursor_position, - .delete_surrounding_text = text_input_delete_surrounding_text, - .keysym = text_input_keysym, - .language = text_input_language, - .text_direction = text_input_text_direction, - // TIZEN_ONLY - .selection_region = NULL, - .private_command = NULL, - .input_panel_geometry = NULL, - .input_panel_data = NULL, - .get_selection_text = NULL, - .get_surrounding_text = NULL, - .filter_key_event_done = NULL, - .hide_permission = NULL, - .recapture_string = NULL, - .input_panel_event = NULL, - .commit_content = NULL, - // -}; - -static void -text_entry_activate(struct display *d) -{ - struct wl_surface *surface = d->entered_surface; - struct text_entry *entry = d->entry; - - fprintf(stderr, "text_entry_activate\n"); - if (entry->click_to_show && entry->active) { - entry->panel_visible = !entry->panel_visible; - - if (entry->panel_visible) - wl_text_input_show_input_panel(entry->text_input); - else - wl_text_input_hide_input_panel(entry->text_input); - - return; - } - - if (!entry->click_to_show) - wl_text_input_show_input_panel(entry->text_input); - - wl_text_input_activate(entry->text_input, - d->seat, - surface); -} - -static void -text_entry_deactivate(struct display *d) -{ - struct text_entry *entry = d->entry; - - fprintf(stderr, "text_entry_deactivate\n"); - wl_text_input_deactivate(entry->text_input, - d->seat); -} - -static void -text_entry_destroy(struct display *d) -{ - struct text_entry *entry; - - entry = d->entry; - d->entry = NULL; - - wl_text_input_destroy(entry->text_input); - free(entry->text); - free(entry->preferred_language); - free(entry); -} - -static struct text_entry* -text_entry_create(struct display *d, const char *text) -{ - struct text_entry *entry; - - entry = calloc(1, sizeof *entry); - if (!entry) - return NULL; - - entry->text = strdup(text); - entry->active = 0; - entry->panel_visible = false; - entry->cursor = strlen(text); - entry->anchor = entry->cursor; - entry->click_to_show = true; - entry->text_input = - wl_text_input_manager_create_text_input(d->text_input_mgr); - wl_text_input_add_listener(entry->text_input, - &text_input_listener, d); - - d->entry = entry; - fprintf(stderr, "text_entry_create() entry(%p) created.\n", entry); - - return entry; -} - -static void -registry_handle_global(void *data, struct wl_registry *registry, - uint32_t id, const char *interface, uint32_t version) -{ - struct display *d = data; - - if (strcmp(interface, "wl_compositor") == 0) { - d->compositor = - wl_registry_bind(registry, - id, &wl_compositor_interface, 1); - } else if (strcmp(interface, "xdg_wm_base") == 0) { - d->wm_base = wl_registry_bind(registry, - id, &xdg_wm_base_interface, 1); - xdg_wm_base_add_listener(d->wm_base, &xdg_wm_base_listener, d); - } else if (strcmp(interface, "wl_shm") == 0) { - d->shm = wl_registry_bind(registry, - id, &wl_shm_interface, 1); - wl_shm_add_listener(d->shm, &shm_listener, d); - } else if (strcmp(interface, "wl_seat") == 0) { - d->seat = wl_registry_bind(registry, - id, &wl_seat_interface, 7); - wl_seat_add_listener(d->seat, &seat_listener, d); - fprintf(stderr, "wl_seat bound!\n"); - } else if (strcmp(interface, "wl_text_input_manager") == 0) { - d->text_input_mgr = wl_registry_bind(registry, - id, &wl_text_input_manager_interface, version); - fprintf(stderr, "wl_text_input_manager bound!\n"); - - text_entry_create(d, "Entry"); - } -} - -static void -registry_handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) -{ -} - -static const struct wl_registry_listener registry_listener = { - registry_handle_global, - registry_handle_global_remove -}; - -static struct display * -create_display(void) -{ - struct display *display; - - display = calloc(1, sizeof *display); - if (display == NULL) { - fprintf(stderr, "out of memory\n"); - exit(1); - } - display->display = wl_display_connect(NULL); - assert(display->display); - - display->has_xrgb = false; - display->registry = wl_display_get_registry(display->display); - wl_registry_add_listener(display->registry, - ®istry_listener, display); - wl_display_roundtrip(display->display); - if (display->shm == NULL) { - fprintf(stderr, "No wl_shm global\n"); - exit(1); - } - - wl_display_roundtrip(display->display); - - /* - * Why do we need two roundtrips here? - * - * wl_display_get_registry() sends a request to the server, to which - * the server replies by emitting the wl_registry.global events. - * The first wl_display_roundtrip() sends wl_display.sync. The server - * first processes the wl_display.get_registry which includes sending - * the global events, and then processes the sync. Therefore when the - * sync (roundtrip) returns, we are guaranteed to have received and - * processed all the global events. - * - * While we are inside the first wl_display_roundtrip(), incoming - * events are dispatched, which causes registry_handle_global() to - * be called for each global. One of these globals is wl_shm. - * registry_handle_global() sends wl_registry.bind request for the - * wl_shm global. However, wl_registry.bind request is sent after - * the first wl_display.sync, so the reply to the sync comes before - * the initial events of the wl_shm object. - * - * The initial events that get sent as a reply to binding to wl_shm - * include wl_shm.format. These tell us which pixel formats are - * supported, and we need them before we can create buffers. They - * don't change at runtime, so we receive them as part of init. - * - * When the reply to the first sync comes, the server may or may not - * have sent the initial wl_shm events. Therefore we need the second - * wl_display_roundtrip() call here. - * - * The server processes the wl_registry.bind for wl_shm first, and - * the second wl_display.sync next. During our second call to - * wl_display_roundtrip() the initial wl_shm events are received and - * processed. Finally, when the reply to the second wl_display.sync - * arrives, it guarantees we have processed all wl_shm initial events. - * - * This sequence contains two examples on how wl_display_roundtrip() - * can be used to guarantee, that all reply events to a request - * have been received and processed. This is a general Wayland - * technique. - */ - - if (!display->has_xrgb) { - fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n"); - exit(1); - } - - display->wl_tbm = wayland_tbm_client_init(display->display); - if (!display->wl_tbm) { - fprintf(stderr, "failed wayland_tbm_client_init()\n"); - exit(1); - } - - display->notified = -1; - - return display; -} - -static void -destroy_display(struct display *display) -{ - text_entry_destroy(display); - - if (display->text_input_mgr) - wl_text_input_manager_destroy(display->text_input_mgr); - - if (display->seat) - wl_seat_destroy(display->seat); - - if (display->shm) - wl_shm_destroy(display->shm); - - if (display->wm_base) - xdg_wm_base_destroy(display->wm_base); - - if (display->compositor) - wl_compositor_destroy(display->compositor); - - wayland_tbm_client_deinit(display->wl_tbm); - wl_registry_destroy(display->registry); - wl_display_flush(display->display); - wl_display_disconnect(display->display); - free(display); -} - -static void -signal_int(int signum) -{ - running = 0; -} - -int -main(int argc, char **argv) -{ - struct sigaction sigint; - struct display *display; - struct window *window; - int ret = 0; - - display = create_display(); - window = create_window(display, 250, 250); - if (!window) - return 1; - - sigint.sa_handler = signal_int; - sigemptyset(&sigint.sa_mask); - sigint.sa_flags = SA_RESETHAND; - sigaction(SIGINT, &sigint, NULL); - - /* Initialise damage to full surface, so the padding gets painted */ - wl_surface_damage(window->surface, 0, 0, - window->width, window->height); - - if (!window->wait_for_configure) - redraw(window, NULL, 0); - - while (running && ret != -1) - ret = wl_display_dispatch(display->display); - - fprintf(stderr, "simple-shm exiting\n"); - - destroy_window(window); - destroy_display(display); - - return 0; -} diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 37f9559..82a0fec 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -570,7 +570,6 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-text-input.pc %{_libdir}/libds-tizen-text-input.so %{_bindir}/libds-tizen-text-input-tests -%{_bindir}/text-entry %files input-method %manifest %{name}.manifest -- 2.7.4 From 1b5eb509806e3b880a2a2b66959b14950cd6052e Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Sun, 28 Aug 2022 15:14:09 +0900 Subject: [PATCH 02/16] add .vscode to .gitignore Change-Id: I5ed9158db630465b6766fdf3454dc30d90a7ab68 --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 7ca031c..9aa0a36 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,6 @@ dkms.conf # Vim swapfiles .*.sw? .sw? + +# VS code +.vscode -- 2.7.4 From e8f683006d4fe45cc7a7d5093c3d7c4ead658cbd Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 12 Aug 2022 17:07:33 +0900 Subject: [PATCH 03/16] implement tizen_policy Change-Id: I1be6f809cba50e8864e3d7ee6059dcefbdf8840a --- include/libds-tizen/policy.h | 686 +++++++++++++ packaging/libds-tizen.spec | 29 + src/meson.build | 1 + src/policy/meson.build | 31 + src/policy/policy.c | 2313 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 3060 insertions(+) create mode 100644 include/libds-tizen/policy.h create mode 100644 src/policy/meson.build create mode 100644 src/policy/policy.c diff --git a/include/libds-tizen/policy.h b/include/libds-tizen/policy.h new file mode 100644 index 0000000..f95e7cf --- /dev/null +++ b/include/libds-tizen/policy.h @@ -0,0 +1,686 @@ +#ifndef LIBDS_TIZEN_POLICY_H +#define LIBDS_TIZEN_POLICY_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tizen_policy; +struct ds_tizen_policy_surface; +struct ds_tizen_policy_visibility; +struct ds_tizen_policy_position; +struct ds_tizen_policy_subsurface_watcher; + +enum ds_tizen_policy_window_type +{ + DS_TIZEN_POLICY_WINDOW_TYPE_NONE, + DS_TIZEN_POLICY_WINDOW_TYPE_TOPLEVEL, + DS_TIZEN_POLICY_WINDOW_TYPE_FULLLSCREEN, + DS_TIZEN_POLICY_WINDOW_TYPE_MAXIMIZED, + DS_TIZEN_POLICY_WINDOW_TYPE_TRANSIENT, + DS_TIZEN_POLICY_WINDOW_TYPE_MENU, + DS_TIZEN_POLICY_WINDOW_TYPE_DND, + DS_TIZEN_POLICY_WINDOW_TYPE_CUSTOM, + DS_TIZEN_POLICY_WINDOW_TYPE_NOTIFICATION, + DS_TIZEN_POLICY_WINDOW_TYPE_UTILITY, + DS_TIZEN_POLICY_WINDOW_TYPE_DIALOG, + DS_TIZEN_POLICY_WINDOW_TYPE_DOCK, + DS_TIZEN_POLICY_WINDOW_TYPE_SPLASH, + DS_TIZEN_POLICY_WINDOW_TYPE_DESKTOP, +}; + +enum ds_tizen_policy_conformant_part +{ + DS_TIZEN_POLICY_CONFORMANT_PART_UNKNOWN, + DS_TIZEN_POLICY_CONFORMANT_PART_INDICATOR, + DS_TIZEN_POLICY_CONFORMANT_PART_KEYBOARD, + DS_TIZEN_POLICY_CONFORMANT_PART_CLIPBOARD, +}; + +enum ds_tizen_policy_error_state +{ + DS_TIZEN_POLICY_ERROR_STATE_NONE, + DS_TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED, +}; + +enum ds_tizen_policy_notification_level +{ + DS_TIZEN_POLICY_NOTIFICATION_LEVEL_1, + DS_TIZEN_POLICY_NOTIFICATION_LEVEL_2, + DS_TIZEN_POLICY_NOTIFICATION_LEVEL_3, + DS_TIZEN_POLICY_NOTIFICATION_LEVEL_NONE, + DS_TIZEN_POLICY_NOTIFICATION_LEVEL_DEFAULT, + DS_TIZEN_POLICY_NOTIFICATION_LEVEL_MEDIUM, + DS_TIZEN_POLICY_NOTIFICATION_LEVEL_HIGH, + DS_TIZEN_POLICY_NOTIFICATION_LEVEL_TOP, +}; + +enum ds_tizen_policy_window_screen_mode +{ + DS_TIZEN_POLICY_WINDOW_SCREEN_MODE_DEFAULT, + DS_TIZEN_POLICY_WINDOW_SCREEN_MODE_ALWAYS_ON, +}; + +enum ds_tizen_policy_stack_mode +{ + DS_TIZEN_POLICY_STACK_MODE_NONE, + DS_TIZEN_POLICY_STACK_MODE_ABOVE, + DS_TIZEN_POLICY_STACK_MODE_BELOW, +}; + +enum ds_tizen_policy_visibility_type +{ + DS_TIZEN_POLICY_VISIBILITY_TYPE_UNKNOWN, + DS_TIZEN_POLICY_VISIBILITY_TYPE_UNOBSCURED, + DS_TIZEN_POLICY_VISIBILITY_TYPE_PARTIALLY_OBSCURED, + DS_TIZEN_POLICY_VISIBILITY_TYPE_FULLY_OBSCURED, + DS_TIZEN_POLICY_VISIBILITY_TYPE_PRE_UNOBSCURED, +}; + +// policy event structures +struct ds_tizen_event_policy_get_surface +{ + struct ds_tizen_policy *policy; + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_activate_below_by_univeral_id +{ + struct ds_tizen_policy *policy; + uint32_t universal_id; + uint32_t below_universal_id; +}; + +struct ds_tizen_event_policy_lower_by_universal_id +{ + struct ds_tizen_policy *policy; + uint32_t universal_id; +}; + +struct ds_tizen_event_policy_set_transient_for +{ + struct ds_tizen_policy *policy; + uint32_t child_universal_id; + uint32_t parent_universal_id; +}; + +struct ds_tizen_event_policy_unset_transient_for +{ + struct ds_tizen_policy *policy; + uint32_t child_universal_id; +}; + +struct ds_tizen_event_policy_place_subsurface_below_parent +{ + struct ds_tizen_policy *policy; + struct ds_subsurface *subsurface; +}; + +struct ds_tizen_event_policy_set_subsurface_stand_alone +{ + struct ds_tizen_policy *policy; + struct ds_subsurface *subsurface; +}; + +struct ds_tizen_event_policy_set_background_state +{ + struct ds_tizen_policy *policy; + int32_t pid; +}; + +struct ds_tizen_event_policy_unset_background_state +{ + struct ds_tizen_policy *policy; + int32_t pid; +}; + +struct ds_tizen_event_policy_activate_above_by_universal_id +{ + struct ds_tizen_policy *policy; + uint32_t universal_id; + uint32_t above_universal_id; +}; + +struct ds_tizen_event_policy_set_appid +{ + struct ds_tizen_policy *policy; + int32_t pid; + const char *appid; +}; + +struct ds_tizen_event_policy_set_transient_for_below +{ + struct ds_tizen_policy *policy; + uint32_t universal_id; + uint32_t parent_universal_id; +}; + +// policy policy_surface event structures +struct ds_tizen_event_policy_surface_get_visibility +{ + struct ds_tizen_policy_surface *policy_surface; + struct ds_tizen_policy_visibility *visibility; +}; + +struct ds_tizen_event_policy_surface_get_position +{ + struct ds_tizen_policy_surface *policy_surface; + struct ds_tizen_policy_position *position; +}; + +struct ds_tizen_event_policy_surface_activate +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_raise +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_lower +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_set_focus_skip +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_unset_focus_skip +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_set_role +{ + struct ds_tizen_policy_surface *policy_surface; + const char *role; +}; + +struct ds_tizen_event_policy_surface_set_window_type +{ + struct ds_tizen_policy_surface *policy_surface; + enum ds_tizen_policy_window_type win_type; +}; + +struct ds_tizen_event_policy_surface_set_conformant +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_unset_conformant +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_get_conformant +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_set_notification_level +{ + struct ds_tizen_policy_surface *policy_surface; + enum ds_tizen_policy_notification_level level; +}; + +struct ds_tizen_event_policy_surface_set_window_screen_mode +{ + struct ds_tizen_policy_surface *policy_surface; + enum ds_tizen_policy_window_screen_mode mode; +}; + +struct ds_tizen_event_policy_surface_get_subsurface +{ + struct ds_tizen_policy_surface *policy_surface; + uint32_t parent_universal_id; +}; + +struct ds_tizen_event_policy_surface_iconify +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_uniconify +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_add_aux_hint +{ + struct ds_tizen_policy_surface *policy_surface; + int32_t id; + const char *name; + const char *value; +}; + +struct ds_tizen_event_policy_surface_change_aux_hint +{ + struct ds_tizen_policy_surface *policy_surface; + int32_t id; + const char *value; +}; + +struct ds_tizen_event_policy_surface_delete_aux_hint +{ + struct ds_tizen_policy_surface *policy_surface; + int32_t id; +}; + +struct ds_tizen_event_policy_surface_get_supported_aux_hints +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_set_floating_mode +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_unset_floating_mode +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_set_stack_mode +{ + struct ds_tizen_policy_surface *policy_surface; + enum ds_tizen_policy_stack_mode mode; +}; + +struct ds_tizen_event_policy_surface_get_subsurface_watcher +{ + struct ds_tizen_policy_surface *policy_surface; + struct ds_tizen_policy_subsurface_watcher *subsurface_watcher; +}; + +struct ds_tizen_event_policy_surface_set_parent +{ + struct ds_tizen_policy_surface *policy_surface; + struct ds_surface *parent_surface; +}; + +struct ds_tizen_event_policy_surface_ack_conformant_region +{ + struct ds_tizen_policy_surface *policy_surface; + uint32_t serial; +}; + +struct ds_tizen_event_policy_surface_set_video +{ + struct ds_tizen_policy_surface *policy_surface; + bool video; +}; + +struct ds_tizen_event_policy_surface_show +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_hide +{ + struct ds_tizen_policy_surface *policy_surface; +}; + +struct ds_tizen_event_policy_surface_set_parent_with_below +{ + struct ds_tizen_policy_surface *policy_surface; + struct ds_surface *parent_surface; +}; + +// policy policy_surface event structures +struct ds_tizen_event_policy_position_set +{ + struct ds_tizen_policy_position *position; + int32_t x; + int32_t y; +}; + +struct ds_tizen_policy * +ds_tizen_policy_create(struct wl_display *display); + +// add listeners for ds_tizen_policy +void +ds_tizen_policy_add_destroy_listener(struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_get_surface_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_activate_below_by_univeral_id_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_lower_by_universal_id_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_set_transient_for_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_unset_transient_for_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_place_subsurface_below_parent_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_set_subsurface_stand_alone_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_set_background_state_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_unset_background_state_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_activate_above_by_universal_id_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_set_appid_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +void +ds_tizen_policy_add_set_transient_for_below_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener); + +// add listeners for ds_tizen_policy_surface +void +ds_tizen_policy_surface_add_destroy_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_get_visibility_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_get_position_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_activate_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_raise_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_lower_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_focus_skip_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_unset_focus_skip_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_role_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_window_type_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_conformant_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_unset_conformant_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_get_conformant_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_notification_level_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_window_screen_mode_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_get_subsurface_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_iconify_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_uniconify_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_add_aux_hint_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_change_aux_hint_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_delete_aux_hint_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_get_supported_aux_hints_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_floating_mode_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_unset_floating_mode_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_stack_mode_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_get_subsurface_watcher_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_parent_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_ack_conformant_region_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_video_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_show_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_hide_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +void +ds_tizen_policy_surface_add_set_parent_with_below_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener); + +// add listeners for ds_tizen_policy_visibility +void +ds_tizen_policy_visibility_add_destroy_listener( + struct ds_tizen_policy_visibility *visibility, + struct wl_listener *listener); + +// add listeners for ds_tizen_policy_position +void +ds_tizen_policy_position_add_destroy_listener( + struct ds_tizen_policy_position *position, + struct wl_listener *listener); + +void +ds_tizen_policy_position_add_set_listener( + struct ds_tizen_policy_position *position, + struct wl_listener *listener); + +// add listeners for ds_tizen_policy_subsurface_watcher +void +ds_tizen_policy_subsurface_watcher_add_destroy_listener( + struct ds_tizen_policy_subsurface_watcher *subsurface_watcher, + struct wl_listener *listener); + +// policy_surface senders to client +void +ds_tizen_policy_surface_send_conformant(struct ds_tizen_policy_surface *policy_surface, + bool active); + +void +ds_tizen_policy_surface_send_conformant_area(struct ds_tizen_policy_surface *policy_surface, + enum ds_tizen_policy_conformant_part part, bool visible, + int32_t x, int32_t y, int32_t w, int32_t h); + +void +ds_tizen_policy_surface_send_notification_done(struct ds_tizen_policy_surface *policy_surface, + enum ds_tizen_policy_notification_level level, + enum ds_tizen_policy_error_state state); + +void +ds_tizen_policy_surface_send_window_screen_mode_done(struct ds_tizen_policy_surface *policy_surface, + enum ds_tizen_policy_window_screen_mode mode, + enum ds_tizen_policy_error_state state); + +void +ds_tizen_policy_surface_send_iconify_state_changed(struct ds_tizen_policy_surface *policy_surface, + bool iconified, bool force); + +void +ds_tizen_policy_surface_send_supported_aux_hints(struct ds_tizen_policy_surface *policy_surface, + struct wl_array *hints, uint32_t force); + +void +ds_tizen_policy_surface_send_allowed_aux_hint(struct ds_tizen_policy_surface *policy_surface, + int32_t hint_id); + +void +ds_tizen_policy_surface_send_aux_message(struct ds_tizen_policy_surface *policy_surface, + const char *key, const char *value, struct wl_array *options); + +void +ds_tizen_policy_surface_send_conformant_region(struct ds_tizen_policy_surface *policy_surface, + enum ds_tizen_policy_conformant_part part, bool visible, + int32_t x, int32_t y, int32_t w, int32_t h, uint32_t serial); + +void +ds_tizen_policy_surface_send_interactive_move_done(struct ds_tizen_policy_surface *policy_surface, + int32_t x, int32_t y, uint32_t w, uint32_t h); + +void +ds_tizen_policy_surface_send_interactive_resize_done(struct ds_tizen_policy_surface *policy_surface, + int32_t x, int32_t y, uint32_t w, uint32_t h); + +// visibility senders to client +void +ds_tizen_policy_visibility_send_notify( + struct ds_tizen_policy_visibility *visibility, + enum ds_tizen_policy_visibility_type type); + +void +ds_tizen_policy_visibility_send_changed( + struct ds_tizen_policy_visibility *visibility, + enum ds_tizen_policy_visibility_type type, uint32_t option); + +// position senders to client +void +ds_tizen_policy_position_send_changed( + struct ds_tizen_policy_position *position, int32_t x, int32_t y); + +// getters for ds_tizen_policy_surface +struct ds_surface * +ds_tizen_policy_surface_get_surface(struct ds_tizen_policy_surface *policy_surface); + +bool +ds_tizen_policy_surface_get_conformant(struct ds_tizen_policy_surface *policy_surface); + +int32_t +ds_tizen_policy_surface_get_opaque_state(struct ds_tizen_policy_surface *policy_surface); + +bool +ds_tizen_policy_surface_get_iconified(struct ds_tizen_policy_surface *policy_surface); + +bool +ds_tizen_policy_surface_get_floating_mode(struct ds_tizen_policy_surface *policy_surface); + +enum ds_tizen_policy_stack_mode +ds_tizen_policy_surface_get_stack_mode(struct ds_tizen_policy_surface *policy_surface); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 82a0fec..1ef64cc 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -312,6 +312,21 @@ Group: Development/Libraries %description hwc-devel Development package for tizen hwc +## libds-tizen-policy +%package policy +Summary: Library for tizen policy +Group: Development/Libraries + +%description policy +Library for tizen policy + +%package policy-devel +Summary: Development package for tizen policy +Group: Development/Libraries + +%description policy-devel +Development package for tizen policy + %prep %setup -q cp %{SOURCE1001} . @@ -601,3 +616,17 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-hwc.pc %{_libdir}/libds-tizen-hwc.so* %{_bindir}/libds-tizen-hwc-tests + +%files policy +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-policy.so.* + +%files policy-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/policy.h +%{_libdir}/pkgconfig/libds-tizen-policy.pc +%{_libdir}/libds-tizen-policy.so diff --git a/src/meson.build b/src/meson.build index 8d254fa..227b7a9 100644 --- a/src/meson.build +++ b/src/meson.build @@ -45,3 +45,4 @@ subdir('embedded_compositor') subdir('input_method') subdir('text_input') subdir('hwc') +subdir('policy') diff --git a/src/policy/meson.build b/src/policy/meson.build new file mode 100644 index 0000000..3f4881f --- /dev/null +++ b/src/policy/meson.build @@ -0,0 +1,31 @@ +libds_tizen_policy_files = [ + tizen_security_files, + 'policy.c', +] + +libds_tizen_policy_deps = [ + deps_libds_tizen, + deps_tizen_security, + dependency('tizen-extension-server', required: true), +] + +lib_libds_tizen_policy = shared_library('ds-tizen-policy', libds_tizen_policy_files, + dependencies: libds_tizen_policy_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +deps_libds_tizen_policy = declare_dependency( + link_with: lib_libds_tizen_policy, + dependencies: libds_tizen_policy_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_policy, + version: meson.project_version(), + filebase: 'libds-tizen-policy', + name: 'libds-tizen-policy', + description: 'tizen policy extension of libds-tizen for tizen platform', +) diff --git a/src/policy/policy.c b/src/policy/policy.c new file mode 100644 index 0000000..b349d8b --- /dev/null +++ b/src/policy/policy.c @@ -0,0 +1,2313 @@ +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "security.h" +#include "libds-tizen/policy.h" + +#define TIZEN_POLICY_VERSION 11 +#define TIZEN_POLICY_PRIVILEGE_SET_NOTIFICATION_LEVEL \ + "http://tizen.org/privilege/window.priority.set" +#define TIZEN_POLICY_PRIVILEGE_SET_SCREEN_MODE \ + "http://tizen.org/privilege/display" + +struct ds_tizen_policy +{ + struct wl_global *global; + + struct wl_list clients; + + struct wl_listener destroy; + + bool use_security; + + struct { + struct wl_signal destroy; + struct wl_signal get_surface; + struct wl_signal activate_below_by_univeral_id; + struct wl_signal lower_by_universal_id; + struct wl_signal set_transient_for; + struct wl_signal unset_transient_for; + struct wl_signal place_subsurface_below_parent; + struct wl_signal set_subsurface_stand_alone; + struct wl_signal set_background_state; + struct wl_signal unset_background_state; + struct wl_signal activate_above_by_universal_id; + struct wl_signal set_appid; + struct wl_signal set_transient_for_below; + } events; +}; + +struct ds_tizen_policy_client +{ + struct ds_tizen_policy *policy; + + struct wl_resource *resource; + struct wl_client *wl_client; + pid_t pid; + uid_t uid; + + struct wl_list policy_surfaces; + + struct wl_list link; // ds_tizen_policy::clients +}; + +struct ds_tizen_policy_surface +{ + struct ds_tizen_policy_client *client; + + struct ds_surface *surface; + pid_t pid; + uid_t uid; + + struct wl_list visibilities; + struct wl_list positions; + struct wl_list subsurface_watchers; + + bool conformant; + int32_t opaque_state; + bool iconified; + bool floating_mode; + enum ds_tizen_policy_stack_mode stack_mode; + bool video; + + struct { + struct wl_signal destroy; + struct wl_signal get_visibility; + struct wl_signal get_position; + struct wl_signal activate; + struct wl_signal raise; + struct wl_signal lower; + struct wl_signal set_focus_skip; + struct wl_signal unset_focus_skip; + struct wl_signal set_role; + struct wl_signal set_window_type; + struct wl_signal set_conformant; + struct wl_signal unset_conformant; + struct wl_signal get_conformant; + struct wl_signal set_notification_level; + struct wl_signal set_window_screen_mode; + struct wl_signal get_subsurface; + struct wl_signal iconify; + struct wl_signal uniconify; + struct wl_signal add_aux_hint; + struct wl_signal change_aux_hint; + struct wl_signal delete_aux_hint; + struct wl_signal get_supported_aux_hints; + struct wl_signal set_floating_mode; + struct wl_signal unset_floating_mode; + struct wl_signal set_stack_mode; + struct wl_signal get_subsurface_watcher; + struct wl_signal set_parent; + struct wl_signal ack_conformant_region; + struct wl_signal set_video; + struct wl_signal show; + struct wl_signal hide; + struct wl_signal set_parent_with_below; + } events; + + struct wl_list link; // ds_tizen_policy_client::policy_surfaces +}; + +struct ds_tizen_policy_visibility +{ + struct ds_tizen_policy_surface *policy_surface; + + struct wl_resource *resource; + + struct { + struct wl_signal destroy; + } events; + + struct wl_list link; // ds_tizen_policy_surface::visibilities +}; + +struct ds_tizen_policy_position +{ + struct ds_tizen_policy_surface *policy_surface; + + struct wl_resource *resource; + + struct { + struct wl_signal destroy; + struct wl_signal set; + } events; + + struct wl_list link; // ds_tizen_policy_surface::positions +}; + +struct ds_tizen_policy_subsurface_watcher +{ + struct ds_tizen_policy_surface *policy_surface; + + struct wl_resource *resource; + + struct { + struct wl_signal destroy; + } events; + + struct wl_list link; // ds_tizen_policy_surface::subsurface_watchers +}; + +static void policy_handle_display_destroy(struct wl_listener *listener, + void *data); + +static void policy_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id); + +static struct ds_tizen_policy_surface *tizen_policy_client_find_policy_surface( + struct ds_tizen_policy_client *client, + struct ds_surface *surface); + +static struct ds_tizen_policy_surface *tizen_policy_client_get_surface( + struct wl_resource *resource, + struct wl_resource *surface_resource); + +WL_EXPORT struct ds_tizen_policy * +ds_tizen_policy_create(struct wl_display *display) +{ + struct ds_tizen_policy *policy; + + policy = calloc(1, sizeof *policy); + if (!policy) { + ds_err("calloc() failed."); + return NULL; + } + + policy->global = wl_global_create(display, &tizen_policy_interface, + TIZEN_POLICY_VERSION, policy, policy_bind); + if (!policy->global) { + ds_err("wl_global_create() failed. tizen_policy_interface"); + free(policy); + return NULL; + } + + wl_list_init(&policy->clients); + + policy->destroy.notify = policy_handle_display_destroy; + wl_display_add_destroy_listener(display, &policy->destroy); + + policy->use_security = tizen_security_init(); + if (!policy->use_security) { + ds_inf("tizen_security_init() is not successful. " + "policy works without security."); + } + + wl_signal_init(&policy->events.destroy); + wl_signal_init(&policy->events.get_surface); + wl_signal_init(&policy->events.activate_below_by_univeral_id); + wl_signal_init(&policy->events.lower_by_universal_id); + wl_signal_init(&policy->events.set_transient_for); + wl_signal_init(&policy->events.unset_transient_for); + wl_signal_init(&policy->events.place_subsurface_below_parent); + wl_signal_init(&policy->events.set_subsurface_stand_alone); + wl_signal_init(&policy->events.set_background_state); + wl_signal_init(&policy->events.unset_background_state); + wl_signal_init(&policy->events.activate_above_by_universal_id); + wl_signal_init(&policy->events.set_appid); + wl_signal_init(&policy->events.set_transient_for_below); + + ds_inf("Global created: tizen_policy(%p)", policy); + + return policy; +} + +WL_EXPORT void +ds_tizen_policy_add_destroy_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_get_surface_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.get_surface, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_activate_below_by_univeral_id_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.activate_below_by_univeral_id, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_lower_by_universal_id_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.lower_by_universal_id, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_set_transient_for_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.set_transient_for, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_unset_transient_for_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.unset_transient_for, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_place_subsurface_below_parent_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.place_subsurface_below_parent, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_set_subsurface_stand_alone_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.set_subsurface_stand_alone, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_set_background_state_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.set_background_state, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_unset_background_state_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.unset_background_state, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_activate_above_by_universal_id_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.activate_above_by_universal_id, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_set_appid_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.set_appid, listener); +} + +WL_EXPORT void +ds_tizen_policy_add_set_transient_for_below_listener( + struct ds_tizen_policy *policy, + struct wl_listener *listener) +{ + wl_signal_add(&policy->events.set_transient_for_below, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_destroy_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_get_visibility_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.get_visibility, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_get_position_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.get_position, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_activate_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.activate, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_raise_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.raise, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_lower_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.lower, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_focus_skip_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_focus_skip, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_unset_focus_skip_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.unset_focus_skip, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_role_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_role, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_window_type_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_window_type, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_conformant_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_conformant, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_unset_conformant_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.unset_conformant, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_get_conformant_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.get_conformant, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_notification_level_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_notification_level, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_window_screen_mode_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_window_screen_mode, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_get_subsurface_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.get_subsurface, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_iconify_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.iconify, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_uniconify_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.uniconify, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_add_aux_hint_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.add_aux_hint, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_change_aux_hint_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.change_aux_hint, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_delete_aux_hint_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.delete_aux_hint, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_get_supported_aux_hints_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.get_supported_aux_hints, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_floating_mode_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_floating_mode, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_unset_floating_mode_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.unset_floating_mode, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_stack_mode_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_stack_mode, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_get_subsurface_watcher_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.get_subsurface_watcher, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_parent_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_parent, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_ack_conformant_region_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.ack_conformant_region, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_video_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_video, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_show_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.show, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_hide_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.hide, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_add_set_parent_with_below_listener( + struct ds_tizen_policy_surface *policy_surface, + struct wl_listener *listener) +{ + wl_signal_add(&policy_surface->events.set_parent_with_below, listener); +} + +WL_EXPORT void +ds_tizen_policy_visibility_add_destroy_listener( + struct ds_tizen_policy_visibility *visibility, + struct wl_listener *listener) +{ + wl_signal_add(&visibility->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_policy_position_add_destroy_listener( + struct ds_tizen_policy_position *position, + struct wl_listener *listener) +{ + wl_signal_add(&position->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_policy_position_add_set_listener( + struct ds_tizen_policy_position *position, + struct wl_listener *listener) +{ + wl_signal_add(&position->events.set, listener); +} + +void +ds_tizen_policy_subsurface_watcher_add_destroy_listener( + struct ds_tizen_policy_subsurface_watcher *subsurface_watcher, + struct wl_listener *listener) +{ + wl_signal_add(&subsurface_watcher->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_policy_surface_send_conformant(struct ds_tizen_policy_surface *policy_surface, + bool active) +{ + tizen_policy_send_conformant(policy_surface->client->resource, + ds_surface_get_wl_resource(policy_surface->surface), active); +} + +WL_EXPORT void +ds_tizen_policy_surface_send_conformant_area(struct ds_tizen_policy_surface *policy_surface, + enum ds_tizen_policy_conformant_part part, bool visible, + int32_t x, int32_t y, int32_t w, int32_t h) +{ + uint32_t conformant_part; + + switch (part) { + case DS_TIZEN_POLICY_CONFORMANT_PART_INDICATOR: + conformant_part = TIZEN_POLICY_CONFORMANT_PART_INDICATOR; + break; + case DS_TIZEN_POLICY_CONFORMANT_PART_KEYBOARD: + conformant_part = TIZEN_POLICY_CONFORMANT_PART_KEYBOARD; + break; + case DS_TIZEN_POLICY_CONFORMANT_PART_CLIPBOARD: + conformant_part = TIZEN_POLICY_CONFORMANT_PART_CLIPBOARD; + break; + default: + ds_err("Not supported conformant_part(%d)", part); + return; + } + + tizen_policy_send_conformant_area(policy_surface->client->resource, + ds_surface_get_wl_resource(policy_surface->surface), conformant_part, visible, + x, y, w, h); +} + +WL_EXPORT void +ds_tizen_policy_surface_send_notification_done(struct ds_tizen_policy_surface *policy_surface, + enum ds_tizen_policy_notification_level level, + enum ds_tizen_policy_error_state state) +{ + uint32_t notification_level; + uint32_t error_state; + + switch (level) { + case DS_TIZEN_POLICY_NOTIFICATION_LEVEL_1: + notification_level = TIZEN_POLICY_LEVEL_1; + break; + case DS_TIZEN_POLICY_NOTIFICATION_LEVEL_2: + notification_level = TIZEN_POLICY_LEVEL_2; + break; + case DS_TIZEN_POLICY_NOTIFICATION_LEVEL_3: + notification_level = TIZEN_POLICY_LEVEL_3; + break; + case DS_TIZEN_POLICY_NOTIFICATION_LEVEL_NONE: + notification_level = TIZEN_POLICY_LEVEL_NONE; + break; + case DS_TIZEN_POLICY_NOTIFICATION_LEVEL_DEFAULT: + notification_level = TIZEN_POLICY_LEVEL_DEFAULT; + break; + case DS_TIZEN_POLICY_NOTIFICATION_LEVEL_MEDIUM: + notification_level = TIZEN_POLICY_LEVEL_MEDIUM; + break; + case DS_TIZEN_POLICY_NOTIFICATION_LEVEL_HIGH: + notification_level = TIZEN_POLICY_LEVEL_HIGH; + break; + case DS_TIZEN_POLICY_NOTIFICATION_LEVEL_TOP: + notification_level = TIZEN_POLICY_LEVEL_TOP; + break; + default: + ds_err("Not supported notification_level(%d)", level); + return; + } + + switch (state) { + case DS_TIZEN_POLICY_ERROR_STATE_NONE: + error_state = TIZEN_POLICY_ERROR_STATE_NONE; + break; + case DS_TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED: + error_state = TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED; + break; + default: + ds_err("Not supported error_state(%d)", state); + return; + } + + tizen_policy_send_notification_done(policy_surface->client->resource, + ds_surface_get_wl_resource(policy_surface->surface), + notification_level, error_state); +} + +WL_EXPORT void +ds_tizen_policy_surface_send_window_screen_mode_done(struct ds_tizen_policy_surface *policy_surface, + enum ds_tizen_policy_window_screen_mode mode, + enum ds_tizen_policy_error_state state) +{ + uint32_t window_screen_mode; + uint32_t error_state; + + switch (mode) { + case DS_TIZEN_POLICY_WINDOW_SCREEN_MODE_DEFAULT: + window_screen_mode = TIZEN_POLICY_MODE_DEFAULT; + break; + case DS_TIZEN_POLICY_WINDOW_SCREEN_MODE_ALWAYS_ON: + window_screen_mode = TIZEN_POLICY_MODE_ALWAYS_ON; + break; + default: + ds_err("Not supported window_screen_mode(%d)", mode); + return; + } + + switch (state) { + case DS_TIZEN_POLICY_ERROR_STATE_NONE: + error_state = TIZEN_POLICY_ERROR_STATE_NONE; + break; + case DS_TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED: + error_state = TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED; + break; + default: + ds_err("Not supported error_state(%d)", state); + return; + } + + tizen_policy_send_window_screen_mode_done(policy_surface->client->resource, + ds_surface_get_wl_resource(policy_surface->surface), + window_screen_mode, error_state); +} + +WL_EXPORT void +ds_tizen_policy_surface_send_iconify_state_changed(struct ds_tizen_policy_surface *policy_surface, + bool iconified, bool force) +{ + tizen_policy_send_iconify_state_changed(policy_surface->client->resource, + ds_surface_get_wl_resource(policy_surface->surface), iconified, force); +} + +WL_EXPORT void +ds_tizen_policy_surface_send_supported_aux_hints(struct ds_tizen_policy_surface *policy_surface, + struct wl_array *hints, uint32_t force) +{ + // TODO: +} + +WL_EXPORT void +ds_tizen_policy_surface_send_allowed_aux_hint(struct ds_tizen_policy_surface *policy_surface, + int32_t hint_id) +{ + // TODO: +} + +WL_EXPORT void +ds_tizen_policy_surface_send_aux_message(struct ds_tizen_policy_surface *policy_surface, + const char *key, const char *value, struct wl_array *options) +{ + // TODO: +} + +WL_EXPORT void +ds_tizen_policy_surface_send_conformant_region(struct ds_tizen_policy_surface *policy_surface, + enum ds_tizen_policy_conformant_part part, bool visible, + int32_t x, int32_t y, int32_t w, int32_t h, uint32_t serial) +{ + uint32_t conformant_part; + + switch (part) { + case DS_TIZEN_POLICY_CONFORMANT_PART_INDICATOR: + conformant_part = TIZEN_POLICY_CONFORMANT_PART_INDICATOR; + break; + case DS_TIZEN_POLICY_CONFORMANT_PART_KEYBOARD: + conformant_part = TIZEN_POLICY_CONFORMANT_PART_KEYBOARD; + break; + case DS_TIZEN_POLICY_CONFORMANT_PART_CLIPBOARD: + conformant_part = TIZEN_POLICY_CONFORMANT_PART_CLIPBOARD; + break; + default: + ds_err("Not supported conformant_part(%d)", part); + return; + } + + tizen_policy_send_conformant_region(policy_surface->client->resource, + ds_surface_get_wl_resource(policy_surface->surface), conformant_part, visible, + x, y, w, h, serial); +} + +WL_EXPORT void +ds_tizen_policy_surface_send_interactive_move_done(struct ds_tizen_policy_surface *policy_surface, + int32_t x, int32_t y, uint32_t w, uint32_t h) +{ + // TODO: +} + +WL_EXPORT void +ds_tizen_policy_surface_send_interactive_resize_done(struct ds_tizen_policy_surface *policy_surface, + int32_t x, int32_t y, uint32_t w, uint32_t h) +{ + // TODO: +} + +static int32_t +tizen_policy_visibility_get_type(enum ds_tizen_policy_visibility_type type) +{ + uint32_t vis_type; + + switch (type) { + case DS_TIZEN_POLICY_VISIBILITY_TYPE_UNOBSCURED: + vis_type = TIZEN_VISIBILITY_VISIBILITY_UNOBSCURED; + break; + case DS_TIZEN_POLICY_VISIBILITY_TYPE_PARTIALLY_OBSCURED: + vis_type = TIZEN_VISIBILITY_VISIBILITY_PARTIALLY_OBSCURED; + break; + case DS_TIZEN_POLICY_VISIBILITY_TYPE_FULLY_OBSCURED: + vis_type = TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED; + break; + case DS_TIZEN_POLICY_VISIBILITY_TYPE_PRE_UNOBSCURED: + vis_type = TIZEN_VISIBILITY_VISIBILITY_PRE_UNOBSCURED; + break; + default: + ds_err("Not supported visible type (%d)", type); + vis_type = DS_TIZEN_POLICY_VISIBILITY_TYPE_UNKNOWN; + break; + } + + return vis_type; +} + +WL_EXPORT void +ds_tizen_policy_visibility_send_notify( + struct ds_tizen_policy_visibility *visibility, + enum ds_tizen_policy_visibility_type type) +{ + uint32_t vis_type; + + vis_type = tizen_policy_visibility_get_type(type); + if (vis_type == DS_TIZEN_POLICY_VISIBILITY_TYPE_UNKNOWN) + return; + + tizen_visibility_send_notify(visibility->resource, vis_type); +} + +WL_EXPORT void +ds_tizen_policy_visibility_send_changed( + struct ds_tizen_policy_visibility *visibility, + enum ds_tizen_policy_visibility_type type, uint32_t option) +{ + uint32_t vis_type; + + vis_type = tizen_policy_visibility_get_type(type); + if (vis_type == DS_TIZEN_POLICY_VISIBILITY_TYPE_UNKNOWN) + return; + + tizen_visibility_send_changed(visibility->resource, vis_type, option); +} + +WL_EXPORT void +ds_tizen_policy_position_send_changed( + struct ds_tizen_policy_position *position, int32_t x, int32_t y) +{ + tizen_position_send_changed(position->resource, x, y); +} + +WL_EXPORT struct ds_surface * +ds_tizen_policy_surface_get_surface(struct ds_tizen_policy_surface *policy_surface) +{ + return policy_surface->surface; +} + +WL_EXPORT bool +ds_tizen_policy_surface_get_conformant(struct ds_tizen_policy_surface *policy_surface) +{ + return policy_surface->conformant; +} + +WL_EXPORT int32_t +ds_tizen_policy_surface_get_opaque_state(struct ds_tizen_policy_surface *policy_surface) +{ + return policy_surface->opaque_state; +} + +WL_EXPORT bool +ds_tizen_policy_surface_get_iconified(struct ds_tizen_policy_surface *policy_surface) +{ + return policy_surface->iconified; +} + +WL_EXPORT bool +ds_tizen_policy_surface_get_floating_mode(struct ds_tizen_policy_surface *policy_surface) +{ + return policy_surface->floating_mode; +} + +WL_EXPORT enum ds_tizen_policy_stack_mode +ds_tizen_policy_surface_get_stack_mode(struct ds_tizen_policy_surface *policy_surface) +{ + return policy_surface->stack_mode; +} + +static struct ds_tizen_policy_surface * +tizen_policy_client_find_policy_surface(struct ds_tizen_policy_client *client, + struct ds_surface *surface) +{ + struct ds_tizen_policy_surface *policy_surface; + + wl_list_for_each(policy_surface, &client->policy_surfaces, link) { + if (surface == policy_surface->surface) + return policy_surface; + } + + return NULL; +} + +static struct ds_tizen_policy_surface * +tizen_policy_client_get_surface(struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_client *client; + struct ds_tizen_policy_surface *policy_surface; + struct ds_surface *surface; + + client = wl_resource_get_user_data(resource); + surface = ds_surface_from_resource(surface_resource); + + policy_surface = tizen_policy_client_find_policy_surface(client, surface); + if (policy_surface) + return policy_surface; + + policy_surface = calloc(1, sizeof *policy_surface); + if (policy_surface == NULL) { + ds_err("calloc() failed. tizen_policy"); + return NULL; + } + + policy_surface->client = client; + policy_surface->surface = surface; + wl_client_get_credentials(client->wl_client, &policy_surface->pid, &policy_surface->uid, NULL); + + wl_list_init(&policy_surface->visibilities); + wl_list_init(&policy_surface->positions); + wl_list_init(&policy_surface->subsurface_watchers); + + wl_signal_init(&policy_surface->events.destroy); + wl_signal_init(&policy_surface->events.get_visibility); + wl_signal_init(&policy_surface->events.get_position); + wl_signal_init(&policy_surface->events.activate); + wl_signal_init(&policy_surface->events.raise); + wl_signal_init(&policy_surface->events.lower); + wl_signal_init(&policy_surface->events.set_focus_skip); + wl_signal_init(&policy_surface->events.unset_focus_skip); + wl_signal_init(&policy_surface->events.set_role); + wl_signal_init(&policy_surface->events.set_window_type); + wl_signal_init(&policy_surface->events.set_conformant); + wl_signal_init(&policy_surface->events.unset_conformant); + wl_signal_init(&policy_surface->events.get_conformant); + wl_signal_init(&policy_surface->events.set_notification_level); + wl_signal_init(&policy_surface->events.set_window_screen_mode); + wl_signal_init(&policy_surface->events.get_subsurface); + wl_signal_init(&policy_surface->events.iconify); + wl_signal_init(&policy_surface->events.uniconify); + wl_signal_init(&policy_surface->events.add_aux_hint); + wl_signal_init(&policy_surface->events.change_aux_hint); + wl_signal_init(&policy_surface->events.delete_aux_hint); + wl_signal_init(&policy_surface->events.get_supported_aux_hints); + wl_signal_init(&policy_surface->events.set_floating_mode); + wl_signal_init(&policy_surface->events.unset_floating_mode); + wl_signal_init(&policy_surface->events.set_stack_mode); + wl_signal_init(&policy_surface->events.get_subsurface_watcher); + wl_signal_init(&policy_surface->events.set_parent); + wl_signal_init(&policy_surface->events.ack_conformant_region); + wl_signal_init(&policy_surface->events.set_video); + wl_signal_init(&policy_surface->events.show); + wl_signal_init(&policy_surface->events.hide); + wl_signal_init(&policy_surface->events.set_parent_with_below); + + wl_list_insert(&client->policy_surfaces, &policy_surface->link); + + struct ds_tizen_event_policy_get_surface event = { + .policy = client->policy, + .policy_surface = policy_surface, + }; + wl_signal_emit(&client->policy->events.get_surface, &event); + + return policy_surface; +} + +static void +policy_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_policy *policy; + + policy = wl_container_of(listener, policy, destroy); + + ds_inf("Global destroy: policy(%p)", policy); + + wl_signal_emit(&policy->events.destroy, policy); + + if (policy->use_security) + tizen_security_finish(); + + wl_list_remove(&policy->destroy.link); + wl_global_destroy(policy->global); + free(policy); +} + +static void +visibility_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct tizen_visibility_interface visibility_impl = +{ + visibility_handle_destroy, +}; + +static void +_tizen_policy_visibility_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_policy_visibility *visibility; + + visibility = wl_resource_get_user_data(resource); + + ds_inf("_tizen_policy_visibility_handle_destroy (visibility:%p)", + visibility); + + wl_signal_emit(&visibility->events.destroy, visibility); + wl_list_remove(&visibility->link); + free(visibility); +} + +static void +policy_handle_get_visibility(struct wl_client *wl_client, struct wl_resource *resource, + uint32_t id, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + struct ds_tizen_policy_visibility *visibility; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + visibility = calloc(1, sizeof *visibility); + if (visibility == NULL) { + ds_err("calloc() failed. tizen_policy"); + return; + } + + visibility->policy_surface = policy_surface; + wl_signal_init(&visibility->events.destroy); + + wl_list_insert(&policy_surface->visibilities, &visibility->link); + + visibility->resource = wl_resource_create(wl_client, + &tizen_visibility_interface, wl_resource_get_version(resource), + id); + if (visibility->resource == NULL) { + ds_err("tizen_policy : wl_resource_create() failed."); + wl_list_remove(&visibility->link); + free(visibility); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(visibility->resource, + &visibility_impl, visibility, + _tizen_policy_visibility_handle_destroy); + + struct ds_tizen_event_policy_surface_get_visibility event = { + .policy_surface = policy_surface, + .visibility = visibility, + }; + wl_signal_emit(&policy_surface->events.get_visibility, &event); +} + +static void +position_handle_destroy(struct wl_client *wl_client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +position_handle_set(struct wl_client *wl_client, struct wl_resource *resource, + int32_t x, int32_t y) +{ + struct ds_tizen_policy_position *position; + + position = wl_resource_get_user_data(resource); + + struct ds_tizen_event_policy_position_set event = { + .position = position, + .x = x, + .y = y, + }; + wl_signal_emit(&position->events.set, &event); +} + +static const struct tizen_position_interface position_impl = +{ + position_handle_destroy, + position_handle_set, +}; + +static void +_tizen_policy_position_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_policy_position *position; + + position = wl_resource_get_user_data(resource); + + ds_inf("_tizen_policy_position_handle_destroy (position:%p)", + position); + + wl_signal_emit(&position->events.destroy, position); + wl_list_remove(&position->link); + free(position); +} + +static void +policy_handle_get_position(struct wl_client *wl_client, struct wl_resource *resource, + uint32_t id, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + struct ds_tizen_policy_position *position; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + position = calloc(1, sizeof *position); + if (position == NULL) { + ds_err("calloc() failed. tizen_policy"); + return; + } + + position->policy_surface = policy_surface; + wl_signal_init(&position->events.destroy); + wl_signal_init(&position->events.set); + + wl_list_insert(&policy_surface->positions, &position->link); + + position->resource = wl_resource_create(wl_client, + &tizen_position_interface, wl_resource_get_version(resource), + id); + if (position->resource == NULL) { + ds_err("tizen_policy : wl_resource_create() failed."); + wl_list_remove(&position->link); + free(position); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(position->resource, + &position_impl, position, + _tizen_policy_position_handle_destroy); + + struct ds_tizen_event_policy_surface_get_position event = { + .policy_surface = policy_surface, + .position = position, + }; + wl_signal_emit(&policy_surface->events.get_position, &event); +} + +static void +policy_handle_activate(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_activate event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.activate, &event); +} + +static void +policy_handle_activate_below_by_res_id(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t universal_id, + uint32_t below_universal_id) +{ + struct ds_tizen_policy_client *client; + + client = wl_resource_get_user_data(resource); + + struct ds_tizen_event_policy_activate_below_by_univeral_id event = { + .policy = client->policy, + .universal_id = universal_id, + .below_universal_id = below_universal_id, + }; + wl_signal_emit(&client->policy->events.activate_below_by_univeral_id, &event); +} + +static void +policy_handle_raise(struct wl_client *wl_client, struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_raise event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.raise, &event); +} + +static void +policy_handle_lower(struct wl_client *wl_client, struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_lower event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.lower, &event); +} + +static void +policy_handle_lower_by_res_id(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t universal_id) +{ + struct ds_tizen_policy_client *client; + + client = wl_resource_get_user_data(resource); + + struct ds_tizen_event_policy_lower_by_universal_id event = { + .policy = client->policy, + .universal_id = universal_id, + }; + wl_signal_emit(&client->policy->events.lower_by_universal_id, &event); +} + +static void +policy_handle_set_focus_skip(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_set_focus_skip event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.set_focus_skip, &event); +} + +static void +policy_handle_unset_focus_skip(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_unset_focus_skip event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.unset_focus_skip, &event); +} + +static void +policy_handle_set_role(struct wl_client *wl_client, struct wl_resource *resource, + struct wl_resource *surface_resource, const char *role) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_set_role event = { + .policy_surface = policy_surface, + .role = role, + }; + wl_signal_emit(&policy_surface->events.set_role, &event); +} + +static void +policy_handle_set_type(struct wl_client *wl_client, struct wl_resource *resource, + struct wl_resource *surface_resource, uint32_t type) +{ + struct ds_tizen_policy_surface *policy_surface; + enum ds_tizen_policy_window_type win_type; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + switch (type) { + case TIZEN_POLICY_WIN_TYPE_NONE: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_NONE; + break; + case TIZEN_POLICY_WIN_TYPE_TOPLEVEL: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_TOPLEVEL; + break; + case TIZEN_POLICY_WIN_TYPE_FULLSCREEN: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_FULLLSCREEN; + break; + case TIZEN_POLICY_WIN_TYPE_MAXIMIZED: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_MAXIMIZED; + break; + case TIZEN_POLICY_WIN_TYPE_TRANSIENT: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_TRANSIENT; + break; + case TIZEN_POLICY_WIN_TYPE_MENU: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_MENU; + break; + case TIZEN_POLICY_WIN_TYPE_DND: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_DND; + break; + case TIZEN_POLICY_WIN_TYPE_CUSTOM: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_CUSTOM; + break; + case TIZEN_POLICY_WIN_TYPE_NOTIFICATION: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_NOTIFICATION; + break; + case TIZEN_POLICY_WIN_TYPE_UTILITY: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_UTILITY; + break; + case TIZEN_POLICY_WIN_TYPE_DIALOG: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_DIALOG; + break; + case TIZEN_POLICY_WIN_TYPE_DOCK: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_DOCK; + break; + case TIZEN_POLICY_WIN_TYPE_SPLASH: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_SPLASH; + break; + case TIZEN_POLICY_WIN_TYPE_DESKTOP: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_DESKTOP; + break; + default: + win_type = DS_TIZEN_POLICY_WINDOW_TYPE_NONE; + break; + } + + struct ds_tizen_event_policy_surface_set_window_type event = { + .policy_surface = policy_surface, + .win_type = win_type, + }; + wl_signal_emit(&policy_surface->events.set_window_type, &event); +} + +static void +policy_handle_set_conformant(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + if (!policy_surface->conformant) + policy_surface->conformant = true; + + struct ds_tizen_event_policy_surface_set_conformant event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.set_conformant, &event); +} + +static void +policy_handle_unset_conformant(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + if (policy_surface->conformant) + policy_surface->conformant = false; + + struct ds_tizen_event_policy_surface_unset_conformant event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.unset_conformant, &event); +} + +static void +policy_handle_get_conformant(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_get_conformant event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.get_conformant, &event); +} + +static void +policy_handle_set_notification_level(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + int32_t level) +{ + struct ds_tizen_policy_surface *policy_surface; + enum ds_tizen_policy_notification_level noti_level; + bool ret; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + ret = tizen_security_check_privilege(policy_surface->pid, policy_surface->uid, + TIZEN_POLICY_PRIVILEGE_SET_NOTIFICATION_LEVEL); + if (ret == false) { + ds_err("tizen_security_check_privilege() failed. " + "Privilege Denied on set_notification_level."); + + tizen_policy_send_notification_done(resource, surface_resource, + -1, TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED); + + return; + } + + switch (level) { + case TIZEN_POLICY_LEVEL_1: + noti_level = DS_TIZEN_POLICY_NOTIFICATION_LEVEL_1; + break; + case TIZEN_POLICY_LEVEL_2: + noti_level = DS_TIZEN_POLICY_NOTIFICATION_LEVEL_2; + break; + case TIZEN_POLICY_LEVEL_3: + noti_level = DS_TIZEN_POLICY_NOTIFICATION_LEVEL_3; + break; + case TIZEN_POLICY_LEVEL_NONE: + noti_level = DS_TIZEN_POLICY_NOTIFICATION_LEVEL_NONE; + break; + case TIZEN_POLICY_LEVEL_DEFAULT: + noti_level = DS_TIZEN_POLICY_NOTIFICATION_LEVEL_DEFAULT; + break; + case TIZEN_POLICY_LEVEL_MEDIUM: + noti_level = DS_TIZEN_POLICY_NOTIFICATION_LEVEL_MEDIUM; + break; + case TIZEN_POLICY_LEVEL_HIGH: + noti_level = DS_TIZEN_POLICY_NOTIFICATION_LEVEL_HIGH; + break; + case TIZEN_POLICY_LEVEL_TOP: + noti_level = DS_TIZEN_POLICY_NOTIFICATION_LEVEL_TOP; + break; + default: + noti_level = DS_TIZEN_POLICY_NOTIFICATION_LEVEL_NONE; + break; + } + + struct ds_tizen_event_policy_surface_set_notification_level event = { + .policy_surface = policy_surface, + .level = noti_level, + }; + wl_signal_emit(&policy_surface->events.set_notification_level, &event); +} + +static void +policy_handle_set_transient_for(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t child_id, uint32_t parent_id) +{ + struct ds_tizen_policy_client *client; + + client = wl_resource_get_user_data(resource); + + struct ds_tizen_event_policy_set_transient_for event = { + .policy = client->policy, + .child_universal_id = child_id, + .parent_universal_id = parent_id, + }; + wl_signal_emit(&client->policy->events.set_transient_for, &event); + + tizen_policy_send_transient_for_done(resource, child_id); +} + +static void +policy_handle_unset_transient_for(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t child_id) +{ + struct ds_tizen_policy_client *client; + + client = wl_resource_get_user_data(resource); + + struct ds_tizen_event_policy_unset_transient_for event = { + .policy = client->policy, + .child_universal_id = child_id, + }; + wl_signal_emit(&client->policy->events.unset_transient_for, &event); +} + +static void +policy_handle_set_window_screen_mode(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + uint32_t mode) +{ + struct ds_tizen_policy_surface *policy_surface; + enum ds_tizen_policy_window_screen_mode screen_mode; + bool ret; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + ret = tizen_security_check_privilege(policy_surface->pid, policy_surface->uid, + TIZEN_POLICY_PRIVILEGE_SET_SCREEN_MODE); + if (ret == false) { + ds_err("tizen_security_check_privilege() failed. " + "Privilege Denied on set_window_screen_mode."); + + tizen_policy_send_notification_done(resource, surface_resource, + -1, TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED); + + return; + } + + switch (mode) { + case TIZEN_POLICY_MODE_DEFAULT: + screen_mode = DS_TIZEN_POLICY_WINDOW_SCREEN_MODE_DEFAULT; + break; + case TIZEN_POLICY_MODE_ALWAYS_ON: + screen_mode = DS_TIZEN_POLICY_WINDOW_SCREEN_MODE_ALWAYS_ON; + break; + default: + screen_mode = DS_TIZEN_POLICY_WINDOW_SCREEN_MODE_DEFAULT; + break; + } + + struct ds_tizen_event_policy_surface_set_window_screen_mode event = { + .policy_surface = policy_surface, + .mode = screen_mode, + }; + wl_signal_emit(&policy_surface->events.set_window_screen_mode, &event); +} + +static void +policy_handle_place_subsurface_below_parent(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *subsurface_resource) +{ + struct ds_tizen_policy_client *client; + struct ds_subsurface *subsurface; + + client = wl_resource_get_user_data(resource); + subsurface = ds_subsurface_from_resource(subsurface_resource); + + struct ds_tizen_event_policy_place_subsurface_below_parent event = { + .policy = client->policy, + .subsurface = subsurface, + }; + wl_signal_emit( + &client->policy->events.place_subsurface_below_parent, + &event); +} + +static void +policy_handle_set_subsurface_stand_alone(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *subsurface_resource) +{ + struct ds_tizen_policy_client *client; + struct ds_subsurface *subsurface; + + client = wl_resource_get_user_data(resource); + subsurface = ds_subsurface_from_resource(subsurface_resource); + + struct ds_tizen_event_policy_set_subsurface_stand_alone event = { + .policy = client->policy, + .subsurface = subsurface, + }; + wl_signal_emit( + &client->policy->events.set_subsurface_stand_alone, + &event); +} + +static void +policy_handle_get_subsurface(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t id, + struct wl_resource *surface_resource, uint32_t parent_id) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + // TODO: How to create the ds_subsurface with a parent_universal_id. + + struct ds_tizen_event_policy_surface_get_subsurface event = { + .policy_surface = policy_surface, + .parent_universal_id = parent_id, + }; + wl_signal_emit(&policy_surface->events.get_subsurface, &event); +} + +static void +policy_handle_set_opaque_state(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + int32_t state) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + if (policy_surface->opaque_state != state) + policy_surface->opaque_state = state; +} + +static void +policy_handle_iconify(struct wl_client *wl_client, struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + if (!policy_surface->iconified) + policy_surface->iconified = true; + + struct ds_tizen_event_policy_surface_iconify event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.iconify, &event); +} + +static void +policy_handle_uniconify(struct wl_client *wl_client, struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + if (policy_surface->iconified) + policy_surface->iconified = false; + + struct ds_tizen_event_policy_surface_uniconify event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.uniconify, &event); +} + +static void +policy_handle_add_aux_hint(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + int32_t id, const char *name, const char *value) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_add_aux_hint event = { + .policy_surface = policy_surface, + .id = id, + .name = name, + .value = value, + }; + wl_signal_emit(&policy_surface->events.add_aux_hint, &event); +} + +static void +policy_handle_change_aux_hint(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + int32_t id, const char *value) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_change_aux_hint event = { + .policy_surface = policy_surface, + .id = id, + .value = value, + }; + wl_signal_emit(&policy_surface->events.change_aux_hint, &event); +} + +static void +policy_handle_delete_aux_hint(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + int32_t id) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_delete_aux_hint event = { + .policy_surface = policy_surface, + .id = id, + }; + wl_signal_emit(&policy_surface->events.delete_aux_hint, &event); +} + +static void +policy_handle_get_supported_aux_hints(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_get_supported_aux_hints event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.get_supported_aux_hints, &event); +} + +static void +policy_handle_set_background_state(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t pid) +{ + struct ds_tizen_policy_client *client; + struct ds_tizen_policy *policy; + + client = wl_resource_get_user_data(resource); + policy = client->policy; + + wl_list_for_each(client, &policy->clients, link) { + if (pid == client->pid) { + struct ds_tizen_event_policy_set_background_state event = { + .policy = client->policy, + .pid = pid, + }; + wl_signal_emit(&client->policy->events.set_background_state, &event); + } + } +} + +static void +policy_handle_unset_background_state(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t pid) +{ + struct ds_tizen_policy_client *client; + struct ds_tizen_policy *policy; + + client = wl_resource_get_user_data(resource); + policy = client->policy; + + wl_list_for_each(client, &policy->clients, link) { + if (pid == client->pid) { + struct ds_tizen_event_policy_unset_background_state event = { + .policy = client->policy, + .pid = pid, + }; + wl_signal_emit(&client->policy->events.unset_background_state, &event); + } + } +} + +static void +policy_handle_set_floating_mode(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + if (policy_surface->floating_mode == false) + return; + + policy_surface->floating_mode = false; + + struct ds_tizen_event_policy_surface_set_floating_mode event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.set_floating_mode, &event); +} + +static void +policy_handle_unset_floating_mode(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + if (policy_surface->floating_mode == false) + return; + + policy_surface->floating_mode = false; + + struct ds_tizen_event_policy_surface_unset_floating_mode event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.unset_floating_mode, &event); +} + +static void +policy_handle_set_stack_mode(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + uint32_t mode) +{ + struct ds_tizen_policy_surface *policy_surface; + enum ds_tizen_policy_stack_mode stack_mode; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + switch (mode) { + case TIZEN_POLICY_STACK_MODE_ABOVE: + stack_mode = DS_TIZEN_POLICY_STACK_MODE_ABOVE; + break; + case TIZEN_POLICY_STACK_MODE_BELOW: + stack_mode = DS_TIZEN_POLICY_STACK_MODE_BELOW; + break; + default: + stack_mode = DS_TIZEN_POLICY_STACK_MODE_NONE; + break; + } + + if (policy_surface->stack_mode == stack_mode) + return; + + policy_surface->stack_mode = stack_mode; + + struct ds_tizen_event_policy_surface_set_stack_mode event = { + .policy_surface = policy_surface, + .mode = stack_mode, + }; + wl_signal_emit(&policy_surface->events.set_stack_mode, &event); +} + +static void +policy_handle_activate_above_by_res_id(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t universal_id, + uint32_t above_universal_id) +{ + struct ds_tizen_policy_client *client; + + client = wl_resource_get_user_data(resource); + + struct ds_tizen_event_policy_activate_above_by_universal_id event = { + .policy = client->policy, + .universal_id = universal_id, + .above_universal_id = above_universal_id, + }; + wl_signal_emit(&client->policy->events.activate_above_by_universal_id, &event); +} + +static void +subsurface_watcher_handle_destroy(struct wl_client *wl_client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct tizen_subsurface_watcher_interface subsurface_watcher_impl = +{ + subsurface_watcher_handle_destroy, +}; + +static void +_tizen_policy_subsurface_watcher_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_policy_subsurface_watcher *subsurface_watcher; + + subsurface_watcher = wl_resource_get_user_data(resource); + + ds_inf("_tizen_policy_subsurface_watcher_handle_destroy (subsurface_watcher:%p)", + subsurface_watcher); + + wl_signal_emit(&subsurface_watcher->events.destroy, subsurface_watcher); + free(subsurface_watcher); +} + +static void +policy_handle_get_subsurface_watcher(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t id, + struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + struct ds_tizen_policy_subsurface_watcher *subsurface_watcher; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + subsurface_watcher = calloc(1, sizeof *subsurface_watcher); + if (!subsurface_watcher) { + ds_err("calloc() failed. tizen_policy"); + return; + } + + subsurface_watcher->policy_surface = policy_surface; + wl_signal_init(&subsurface_watcher->events.destroy); + + wl_list_insert(&policy_surface->subsurface_watchers, &subsurface_watcher->link); + + subsurface_watcher->resource = wl_resource_create(wl_client, + &tizen_subsurface_watcher_interface, wl_resource_get_version(resource), + id); + if (subsurface_watcher->resource == NULL) { + ds_err("tizen_policy : wl_resource_create() failed."); + free(subsurface_watcher); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(subsurface_watcher->resource, + &subsurface_watcher_impl, subsurface_watcher, + _tizen_policy_subsurface_watcher_handle_destroy); + + struct ds_tizen_event_policy_surface_get_subsurface_watcher event = { + .policy_surface = policy_surface, + .subsurface_watcher = subsurface_watcher, + }; + wl_signal_emit(&policy_surface->events.get_subsurface_watcher, &event); +} + +static void +policy_handle_set_parent(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + struct wl_resource *parent_surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + struct ds_surface *parent_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + parent_surface = ds_surface_from_resource(parent_surface_resource); + + struct ds_tizen_event_policy_surface_set_parent event = { + .policy_surface = policy_surface, + .parent_surface = parent_surface, + }; + wl_signal_emit(&policy_surface->events.set_parent, &event); +} + +static void +policy_handle_ack_conformant_region(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + uint32_t serial) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_ack_conformant_region event = { + .policy_surface = policy_surface, + .serial = serial, + }; + wl_signal_emit(&policy_surface->events.ack_conformant_region, &event); +} + +static void +policy_handle_destroy(struct wl_client *wl_client, struct wl_resource *resource) +{ + struct ds_tizen_policy_client *client; + + client = wl_resource_get_user_data(resource); + + if (!wl_list_empty(&client->policy_surfaces)) { + ds_err("tizen_policy was destroyed before children"); + return; + } + + wl_resource_destroy(resource); +} + +static void +policy_handle_has_video(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + uint32_t has) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + if (policy_surface->video == has) + return; + + policy_surface->video = has; + + struct ds_tizen_event_policy_surface_set_video event = { + .policy_surface = policy_surface, + .video = has, + }; + wl_signal_emit(&policy_surface->events.set_video, &event); +} + +static void +policy_handle_set_appid(struct wl_client *wl_client, + struct wl_resource *resource, int32_t pid, const char *appid) +{ + struct ds_tizen_policy_client *client; + + client = wl_resource_get_user_data(resource); + + struct ds_tizen_event_policy_set_appid event = { + .policy = client->policy, + .pid = pid, + .appid = appid, + }; + wl_signal_emit(&client->policy->events.set_appid, &event); +} + +static void +policy_handle_show(struct wl_client *wl_client, struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_show event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.show, &event); +} + +static void +policy_handle_hide(struct wl_client *wl_client, struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + struct ds_tizen_event_policy_surface_hide event = { + .policy_surface = policy_surface, + }; + wl_signal_emit(&policy_surface->events.hide, &event); +} + +static void +policy_handle_set_transient_for_below(struct wl_client *wl_client, + struct wl_resource *resource, uint32_t universal_id, + uint32_t parent_universal_id) +{ + struct ds_tizen_policy_client *client; + + client = wl_resource_get_user_data(resource); + + struct ds_tizen_event_policy_set_transient_for_below event = { + .policy = client->policy, + .universal_id = universal_id, + .parent_universal_id = parent_universal_id, + }; + wl_signal_emit(&client->policy->events.set_transient_for_below, &event); +} + +static void +policy_handle_set_parent_with_below(struct wl_client *wl_client, + struct wl_resource *resource, struct wl_resource *surface_resource, + struct wl_resource *parent_surface_resource) +{ + struct ds_tizen_policy_surface *policy_surface; + struct ds_surface *parent_surface; + + policy_surface = tizen_policy_client_get_surface(resource, surface_resource); + if (policy_surface == NULL) { + ds_err("tizen_policy_client_get_surface() failed."); + wl_client_post_no_memory(wl_client); + return; + } + + parent_surface = ds_surface_from_resource(parent_surface_resource); + + struct ds_tizen_event_policy_surface_set_parent_with_below event = { + .policy_surface = policy_surface, + .parent_surface = parent_surface, + }; + wl_signal_emit(&policy_surface->events.set_parent_with_below, &event); +} + +static const struct tizen_policy_interface policy_impl = +{ + policy_handle_get_visibility, + policy_handle_get_position, + policy_handle_activate, + policy_handle_activate_below_by_res_id, + policy_handle_raise, + policy_handle_lower, + policy_handle_lower_by_res_id, + policy_handle_set_focus_skip, + policy_handle_unset_focus_skip, + policy_handle_set_role, + policy_handle_set_type, + policy_handle_set_conformant, + policy_handle_unset_conformant, + policy_handle_get_conformant, + policy_handle_set_notification_level, + policy_handle_set_transient_for, + policy_handle_unset_transient_for, + policy_handle_set_window_screen_mode, + policy_handle_place_subsurface_below_parent, + policy_handle_set_subsurface_stand_alone, + policy_handle_get_subsurface, + policy_handle_set_opaque_state, + policy_handle_iconify, + policy_handle_uniconify, + policy_handle_add_aux_hint, + policy_handle_change_aux_hint, + policy_handle_delete_aux_hint, + policy_handle_get_supported_aux_hints, + policy_handle_set_background_state, + policy_handle_unset_background_state, + policy_handle_set_floating_mode, + policy_handle_unset_floating_mode, + policy_handle_set_stack_mode, + policy_handle_activate_above_by_res_id, + policy_handle_get_subsurface_watcher, + policy_handle_set_parent, + policy_handle_ack_conformant_region, + policy_handle_destroy, + policy_handle_has_video, + policy_handle_set_appid, + policy_handle_show, + policy_handle_hide, + policy_handle_set_transient_for_below, + policy_handle_set_parent_with_below, +}; + +static void +_tizen_policy_client_handle_destroy(struct wl_resource *resource) +{ + struct ds_tizen_policy_client *client; + struct ds_tizen_policy_surface *policy_surface, *tmp; + + client = wl_resource_get_user_data(resource); + + ds_inf("_tizen_policy_client_handle_destroy (client:%p)", client); + + wl_list_for_each_safe(policy_surface, tmp, &client->policy_surfaces, link) { + wl_signal_emit(&policy_surface->events.destroy, policy_surface); + wl_list_remove(&policy_surface->link); + free(policy_surface); + } + + wl_list_remove(&client->link); + free(client); +} + +static void +policy_bind(struct wl_client *wl_client, void *data, uint32_t version, + uint32_t id) +{ + struct ds_tizen_policy *policy = data; + struct ds_tizen_policy_client *client; + + client = calloc(1, sizeof *client); + if (client == NULL) { + ds_err("calloc() failed. tizen_policy"); + wl_client_post_no_memory(wl_client); + return; + } + + ds_inf("tizen_policy_client binds. (client:%p)", client); + + client->policy = policy; + client->wl_client = wl_client; + wl_client_get_credentials(client->wl_client, &client->pid, &client->uid, NULL); + + wl_list_init(&client->policy_surfaces); + + client->resource = wl_resource_create(wl_client, &tizen_policy_interface, + MIN(version, TIZEN_POLICY_VERSION), id); + + if (client->resource == NULL) { + ds_err("tizen_policy : wl_resource_create() failed."); + free(client); + wl_client_post_no_memory(wl_client); + return; + } + + wl_resource_set_implementation(client->resource, &policy_impl, client, + _tizen_policy_client_handle_destroy); + + wl_list_insert(&policy->clients, &client->link); +} -- 2.7.4 From a19d23162d919defba77e0be189803d68de51fb3 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Sun, 28 Aug 2022 13:05:36 +0900 Subject: [PATCH 04/16] add testcases for ds_tizen_policy Change-Id: Ia93e8f7caf52713beaf6dd175f2443337252266e --- packaging/libds-tizen.spec | 1 + tests/meson.build | 20 + tests/tc_policy.cpp | 2989 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 3010 insertions(+) create mode 100644 tests/tc_policy.cpp diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 1ef64cc..e1d4c25 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -630,3 +630,4 @@ ninja -C builddir install %{_includedir}/libds-tizen/policy.h %{_libdir}/pkgconfig/libds-tizen-policy.pc %{_libdir}/libds-tizen-policy.so +%{_bindir}/libds-tizen-policy-tests diff --git a/tests/meson.build b/tests/meson.build index 1b78a64..030c3b0 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -304,3 +304,23 @@ executable('libds-tizen-hwc-tests', install_dir: libds_tizen_bindir, install : true ) + +## policy tests +tc_policy_files = [ + 'tc_main.cpp', + 'tc_policy.cpp', +] + +executable('libds-tizen-policy-tests', + [ + tc_mock_files, + tc_policy_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_policy, + dependency('tizen-extension-client', required: true), + ], + install_dir: libds_tizen_bindir, + install : true +) diff --git a/tests/tc_policy.cpp b/tests/tc_policy.cpp new file mode 100644 index 0000000..e099014 --- /dev/null +++ b/tests/tc_policy.cpp @@ -0,0 +1,2989 @@ +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" +#include +#include + +#define TIZEN_POLICY_VERSION 11 + +class MockPolicyVisibility +{ +public: + MockPolicyVisibility() + : mVisibility(nullptr) + {} + MockPolicyVisibility(struct ds_tizen_policy_visibility *visibility) + : mVisibility(visibility) + { + ds_inf("%s", __func__); + + // policy_surface destroy listener + mDestroyListener.notify = MockPolicyVisibility::DestroyCallback; + mDestroyListener.parent = this; + ds_tizen_policy_visibility_add_destroy_listener(visibility, &mDestroyListener); + } + ~MockPolicyVisibility() + { + ds_inf("%s", __func__); + + if (mDestroyListener.notify) { + wl_list_remove(&mDestroyListener.link); + mDestroyListener.notify = nullptr; + } + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + MockPolicyVisibility *policyVisibility = + reinterpret_cast(listener)->parent; + struct ds_tizen_policy_visibility *visibility = + static_cast(data); + + ds_inf("%s: policyVisibility(%p), visibility(%p)", __func__, + policyVisibility, visibility); + + wl_list_remove(&policyVisibility->mDestroyListener.link); + policyVisibility->mDestroyListener.notify = nullptr; + + policyVisibility->bDestroyed = true; + } + + void SendNotify(enum ds_tizen_policy_visibility_type type) + { + ds_tizen_policy_visibility_send_notify(mVisibility, type); + } + + void SendChanged(enum ds_tizen_policy_visibility_type type, uint32_t option) + { + ds_tizen_policy_visibility_send_changed(mVisibility, type, option); + } + +public: + bool bDestroyed; + +private: + struct ds_tizen_policy_visibility *mVisibility; + + struct DestroyListener : ::wl_listener { + MockPolicyVisibility *parent; + }; + DestroyListener mDestroyListener; +}; + +class MockPolicyPosition +{ +public: + MockPolicyPosition() + : mX(-1), + mY(-1), + mPosition(nullptr) + {} + MockPolicyPosition(struct ds_tizen_policy_position *position) + : mX(-1), + mY(-1), + mPosition(position) + { + ds_inf("%s", __func__); + + // policy_surface destroy listener + mDestroyListener.notify = MockPolicyPosition::DestroyCallback; + mDestroyListener.parent = this; + ds_tizen_policy_position_add_destroy_listener(position, &mDestroyListener); + + // position listener + mSetListener.notify = MockPolicyPosition::SetCallback; + mSetListener.parent = this; + ds_tizen_policy_position_add_set_listener(position, &mSetListener); + } + ~MockPolicyPosition() + { + ds_inf("%s", __func__); + + if (mSetListener.notify) { + wl_list_remove(&mSetListener.link); + mSetListener.notify = nullptr; + } + + if (mDestroyListener.notify) { + wl_list_remove(&mDestroyListener.link); + mDestroyListener.notify = nullptr; + } + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + MockPolicyPosition *policyPosition = + reinterpret_cast(listener)->parent; + struct ds_tizen_policy_position *position = + static_cast(data); + + ds_inf("%s: policyPosition(%p), position(%p)", __func__, + policyPosition, position); + + wl_list_remove(&policyPosition->mSetListener.link); + policyPosition->mSetListener.notify = nullptr; + + wl_list_remove(&policyPosition->mDestroyListener.link); + policyPosition->mDestroyListener.notify = nullptr; + + policyPosition->bDestroyed = true; + } + + static void SetCallback(struct wl_listener *listener, void *data) + { + MockPolicyPosition *mockPosition = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_position_set *event = + static_cast(data); + + EXPECT_TRUE(mockPosition->mPosition == event->position); + mockPosition->mX = event->x; + mockPosition->mY = event->y; + } + + void SendChanged(int32_t x, int32_t y) + { + ds_tizen_policy_position_send_changed(mPosition, x, y); + mX = x; + mY = y; + } + +public: + bool bDestroyed; + + int32_t mX; + int32_t mY; + +private: + struct ds_tizen_policy_position *mPosition; + + struct DestroyListener : ::wl_listener { + MockPolicyPosition *parent; + }; + DestroyListener mDestroyListener; + + struct SetListener : ::wl_listener { + MockPolicyPosition *parent; + }; + SetListener mSetListener; +}; + +class MockPolicySubsurfaceWatcher +{ +public: + MockPolicySubsurfaceWatcher() + : mSubsurfaceWatcher(nullptr) + {} + MockPolicySubsurfaceWatcher(struct ds_tizen_policy_subsurface_watcher *subsurface_watcher) + : mSubsurfaceWatcher(subsurface_watcher) + { + ds_inf("%s", __func__); + + // policy_surface destroy listener + mDestroyListener.notify = MockPolicySubsurfaceWatcher::DestroyCallback; + mDestroyListener.parent = this; + ds_tizen_policy_subsurface_watcher_add_destroy_listener(subsurface_watcher, &mDestroyListener); + } + ~MockPolicySubsurfaceWatcher() + { + ds_inf("%s", __func__); + + if (mDestroyListener.notify) { + wl_list_remove(&mDestroyListener.link); + mDestroyListener.notify = nullptr; + } + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + MockPolicySubsurfaceWatcher *policySubsurfaceWatcher = + reinterpret_cast(listener)->parent; + struct ds_tizen_policy_subsurface_watcher *subsurface_watcher = + static_cast(data); + + ds_inf("%s: policySubsurfaceWatcher(%p), subsurface_watcher(%p)", __func__, + policySubsurfaceWatcher, subsurface_watcher); + + wl_list_remove(&policySubsurfaceWatcher->mDestroyListener.link); + policySubsurfaceWatcher->mDestroyListener.notify = nullptr; + + policySubsurfaceWatcher->bDestroyed = true; + } + +#if 0 // TODO: + void SendMessage(enum ds_tizen_policy_subsurface_watcher_message message) + { + ds_tizen_policy_subsurface_watcher_send_message(mSubsurfaceWatcher, message); + } +#endif + +public: + bool bDestroyed; + +private: + struct ds_tizen_policy_subsurface_watcher *mSubsurfaceWatcher; + + struct DestroyListener : ::wl_listener { + MockPolicySubsurfaceWatcher *parent; + }; + DestroyListener mDestroyListener; +}; + +class MockPolicySurface +{ +public: + MockPolicySurface(struct ds_tizen_policy_surface *policy_surface) + : mPolicySurface(policy_surface), + mPolicyVisibility(nullptr), + mPolicyPosition(nullptr), + mPolicySubsurfaceWatcher(nullptr) + { + ds_inf("%s", __func__); + + // policy_surface destroy listener + mDestroyListener.notify = MockPolicySurface::DestroyCallback; + mDestroyListener.parent = this; + ds_tizen_policy_surface_add_destroy_listener(policy_surface, &mDestroyListener); + + // policy_surface listeners + mGetVisibilityListener.notify = MockPolicySurface::GetVisibilityCallback; + mGetVisibilityListener.parent = this; + ds_tizen_policy_surface_add_get_visibility_listener(policy_surface, + &mGetVisibilityListener); + + mGetPositionListener.notify = MockPolicySurface::GetPositionCallback; + mGetPositionListener.parent = this; + ds_tizen_policy_surface_add_get_position_listener(policy_surface, + &mGetPositionListener); + + mActivateListener.notify = MockPolicySurface::ActivateCallback; + mActivateListener.parent = this; + ds_tizen_policy_surface_add_activate_listener(policy_surface, + &mActivateListener); + + mRaiseListener.notify = MockPolicySurface::RaiseCallback; + mRaiseListener.parent = this; + ds_tizen_policy_surface_add_raise_listener(policy_surface, + &mRaiseListener); + + mLowerListener.notify = MockPolicySurface::LowerCallback; + mLowerListener.parent = this; + ds_tizen_policy_surface_add_lower_listener(policy_surface, + &mLowerListener); + + mSetFocusSkipListener.notify = MockPolicySurface::SetFocusSkipCallback; + mSetFocusSkipListener.parent = this; + ds_tizen_policy_surface_add_set_focus_skip_listener(policy_surface, + &mSetFocusSkipListener); + + mUnsetFocusSkipListener.notify = MockPolicySurface::UnsetFocusSkipCallback; + mUnsetFocusSkipListener.parent = this; + ds_tizen_policy_surface_add_unset_focus_skip_listener(policy_surface, + &mUnsetFocusSkipListener); + + mSetRoleListener.notify = MockPolicySurface::SetRoleCallback; + mSetRoleListener.parent = this; + ds_tizen_policy_surface_add_set_role_listener(policy_surface, + &mSetRoleListener); + + mWindowTypeListener.notify = MockPolicySurface::WindowTypeCallback; + mWindowTypeListener.parent = this; + ds_tizen_policy_surface_add_set_window_type_listener(policy_surface, + &mWindowTypeListener); + + mSetConformantListener.notify = MockPolicySurface::SetConformantCallback; + mSetConformantListener.parent = this; + ds_tizen_policy_surface_add_set_conformant_listener(policy_surface, + &mSetConformantListener); + + mUnsetConformantListener.notify = MockPolicySurface::UnsetConformantCallback; + mUnsetConformantListener.parent = this; + ds_tizen_policy_surface_add_unset_conformant_listener(policy_surface, + &mUnsetConformantListener); + + mGetConformantListener.notify = MockPolicySurface::GetConformantCallback; + mGetConformantListener.parent = this; + ds_tizen_policy_surface_add_get_conformant_listener(policy_surface, + &mGetConformantListener); + + mSetNotificationLevelListener.notify = MockPolicySurface::SetNotificationLevelCallback; + mSetNotificationLevelListener.parent = this; + ds_tizen_policy_surface_add_set_notification_level_listener(policy_surface, + &mSetNotificationLevelListener); + + mSetWindowScreenModeListener.notify = MockPolicySurface::SetWindowScreenModeCallback; + mSetWindowScreenModeListener.parent = this; + ds_tizen_policy_surface_add_set_window_screen_mode_listener(policy_surface, + &mSetWindowScreenModeListener); + + mGetSubsurfaceListener.notify = MockPolicySurface::GetSubsurfaceCallback; + mGetSubsurfaceListener.parent = this; + ds_tizen_policy_surface_add_get_subsurface_listener(policy_surface, + &mGetSubsurfaceListener); + + mIconifyListener.notify = MockPolicySurface::IconifyCallback; + mIconifyListener.parent = this; + ds_tizen_policy_surface_add_iconify_listener(policy_surface, + &mIconifyListener); + + mUniconifyListener.notify = MockPolicySurface::UniconifyCallback; + mUniconifyListener.parent = this; + ds_tizen_policy_surface_add_uniconify_listener(policy_surface, + &mUniconifyListener); + + mAddAuxHintListener.notify = MockPolicySurface::AddAuxHintCallback; + mAddAuxHintListener.parent = this; + ds_tizen_policy_surface_add_add_aux_hint_listener(policy_surface, + &mAddAuxHintListener); + + mChangeAuxHintListener.notify = MockPolicySurface::ChangeAuxHintCallback; + mChangeAuxHintListener.parent = this; + ds_tizen_policy_surface_add_change_aux_hint_listener(policy_surface, + &mChangeAuxHintListener); + + mDeleteAuxHintListener.notify = MockPolicySurface::DeleteAuxHintCallback; + mDeleteAuxHintListener.parent = this; + ds_tizen_policy_surface_add_delete_aux_hint_listener(policy_surface, + &mDeleteAuxHintListener); + + mGetSupportAuxHintsListener.notify = MockPolicySurface::GetSupportAuxHintsCallback; + mGetSupportAuxHintsListener.parent = this; + ds_tizen_policy_surface_add_get_supported_aux_hints_listener(policy_surface, + &mGetSupportAuxHintsListener); + + mSetFloatingModeListener.notify = MockPolicySurface::SetFloatingModeCallback; + mSetFloatingModeListener.parent = this; + ds_tizen_policy_surface_add_set_floating_mode_listener(policy_surface, + &mSetFloatingModeListener); + + mUnsetFloatingModeListener.notify = MockPolicySurface::UnsetFloatingModeCallback; + mUnsetFloatingModeListener.parent = this; + ds_tizen_policy_surface_add_unset_floating_mode_listener(policy_surface, + &mUnsetFloatingModeListener); + + mSetStackModeListener.notify = MockPolicySurface::SetStackModeCallback; + mSetStackModeListener.parent = this; + ds_tizen_policy_surface_add_set_stack_mode_listener(policy_surface, + &mSetStackModeListener); + + mGetSubsurfaceWatcherListener.notify = MockPolicySurface::GetSubsurfaceWatcherCallback; + mGetSubsurfaceWatcherListener.parent = this; + ds_tizen_policy_surface_add_get_subsurface_watcher_listener(policy_surface, + &mGetSubsurfaceWatcherListener); + + mSetParentListener.notify = MockPolicySurface::SetParentCallback; + mSetParentListener.parent = this; + ds_tizen_policy_surface_add_set_parent_listener(policy_surface, + &mSetParentListener); + + mAckConformantRegionListener.notify = MockPolicySurface::AckConformantRegionCallback; + mAckConformantRegionListener.parent = this; + ds_tizen_policy_surface_add_ack_conformant_region_listener(policy_surface, + &mAckConformantRegionListener); + + mSetVideoListener.notify = MockPolicySurface::SetVideoCallback; + mSetVideoListener.parent = this; + ds_tizen_policy_surface_add_set_video_listener(policy_surface, + &mSetVideoListener); + + mShowListener.notify = MockPolicySurface::ShowCallback; + mShowListener.parent = this; + ds_tizen_policy_surface_add_show_listener(policy_surface, + &mShowListener); + + mHideListener.notify = MockPolicySurface::HideCallback; + mHideListener.parent = this; + ds_tizen_policy_surface_add_hide_listener(policy_surface, + &mHideListener); + + mSetParentWithBelowListener.notify = MockPolicySurface::SetParentWithBelowCallback; + mSetParentWithBelowListener.parent = this; + ds_tizen_policy_surface_add_set_parent_with_below_listener(policy_surface, + &mSetParentWithBelowListener); + } + ~MockPolicySurface() + { + ds_inf("%s", __func__); + + if (mGetVisibilityListener.notify) { + wl_list_remove(&mGetVisibilityListener.link); + mGetVisibilityListener.notify = nullptr; + } + + if (mDestroyListener.notify) { + wl_list_remove(&mDestroyListener.link); + mDestroyListener.notify = nullptr; + } + + if (mPolicySubsurfaceWatcher) + delete mPolicySubsurfaceWatcher; + + if (mPolicyPosition) + delete mPolicyPosition; + + if (mPolicyVisibility) + delete mPolicyVisibility; + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_policy_surface *policy_surface = + static_cast(data); + + ds_inf("%s: policySurface(%p), policy_surface(%p)", __func__, policySurface, policy_surface); + + wl_list_remove(&policySurface->mDestroyListener.link); + policySurface->mDestroyListener.notify = nullptr; + + policySurface->bDestroyed = true; + } + + static void GetVisibilityCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_get_visibility *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + EXPECT_TRUE(event->visibility != NULL); + + policySurface->bGetVisibility = true; + + MockPolicyVisibility *policyVisibility = + new MockPolicyVisibility(event->visibility); + + policySurface->mPolicyVisibility = policyVisibility; + } + + static void GetPositionCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_get_position *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + EXPECT_TRUE(event->position != NULL); + + policySurface->bGetPosition = true; + + MockPolicyPosition *policyPosition = + new MockPolicyPosition(event->position); + + policySurface->mPolicyPosition = policyPosition; + } + + static void ActivateCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_activate *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bActivate = true; + } + + static void RaiseCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_raise *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bRaise = true; + } + + static void LowerCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_lower *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bLower = true; + } + + static void SetFocusSkipCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_focus_skip *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bSetFocusSkip = true; + } + + static void UnsetFocusSkipCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_unset_focus_skip *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bSetFocusSkip = false; + } + + static void SetRoleCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_role *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + policySurface->mRole = event->role; // char -> string + } + + static void WindowTypeCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_window_type *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mWinType = event->win_type; + } + + static void SetConformantCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_conformant *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bSetConformant = true; + } + + static void UnsetConformantCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_unset_conformant *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bSetConformant = false; + } + + static void GetConformantCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_get_conformant *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bGetConformant = true; + } + + static void SetNotificationLevelCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_notification_level *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mNotificationLevel = event->level; + } + + static void SetWindowScreenModeCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_window_screen_mode *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mWindowScreenMode = event->mode; + } + + static void GetSubsurfaceCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_get_subsurface *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mParentUniversalId = event->parent_universal_id; + } + + static void IconifyCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_iconify *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bIconify = true; + } + + static void UniconifyCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_uniconify *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bIconify = false; + } + + static void AddAuxHintCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_add_aux_hint *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mAuxHintId = event->id; + policySurface->mAuxHintName = event->name; + policySurface->mAuxHintValue = event->value; + } + + static void ChangeAuxHintCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_change_aux_hint *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mAuxHintId = event->id; + policySurface->mAuxHintValue = event->value; + } + + static void DeleteAuxHintCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_delete_aux_hint *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mAuxHintId = event->id; + } + + static void GetSupportAuxHintsCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_get_supported_aux_hints *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bGetSupportedAuxHints = true; + } + + static void SetFloatingModeCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_floating_mode *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bSetFloatingMode = true; + } + + static void UnsetFloatingModeCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_unset_floating_mode *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bSetFloatingMode = false; + } + + static void SetStackModeCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_stack_mode *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mStackMode = event->mode; + } + + static void GetSubsurfaceWatcherCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_get_subsurface_watcher *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + EXPECT_TRUE(event->subsurface_watcher != NULL); + + policySurface->bGetSubsurfaceWatcher = true; + + MockPolicySubsurfaceWatcher *policySubsurfaceWatcher = + new MockPolicySubsurfaceWatcher(event->subsurface_watcher); + + policySurface->mPolicySubsurfaceWatcher = policySubsurfaceWatcher; + } + + static void SetParentCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_parent *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mParentSurface = event->parent_surface; + } + + static void AckConformantRegionCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_ack_conformant_region *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mSerial = event->serial; + } + + static void SetVideoCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_video *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bVideo = event->video; + } + + static void ShowCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_show *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bShow = true; + } + + static void HideCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_hide *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->bHide = true; + } + + static void SetParentWithBelowCallback(struct wl_listener *listener, void *data) + { + MockPolicySurface *policySurface = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_set_parent_with_below *event = + static_cast(data); + + EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); + + policySurface->mParentSurface = event->parent_surface; + } + + uint32_t GetSurfaceResId() + { + struct ds_surface *surface = ds_tizen_policy_surface_get_surface(mPolicySurface); + struct wl_resource *surface_res = ds_surface_get_wl_resource(surface); + + return wl_resource_get_id(surface_res); + } + + MockPolicyVisibility *GetVisibility() + { + return mPolicyVisibility; + } + + MockPolicyPosition *GetPosition() + { + return mPolicyPosition; + } + + MockPolicySubsurfaceWatcher*GetSubsurfaceWatcher() + { + return mPolicySubsurfaceWatcher; + } + + void SendConformant(bool active) + { + ds_inf("%s", __func__); + + ds_tizen_policy_surface_send_conformant(mPolicySurface, active); + } + + void SendConformantArea(enum ds_tizen_policy_conformant_part part, + bool visible, int32_t x, int32_t y, int32_t w, int32_t h) + { + ds_inf("%s", __func__); + + ds_tizen_policy_surface_send_conformant_area(mPolicySurface, part, visible, + x, y, w, h); + } + + void SendNotificationDone( + enum ds_tizen_policy_notification_level notification_level, + enum ds_tizen_policy_error_state error_state) + { + ds_inf("%s", __func__); + + ds_tizen_policy_surface_send_notification_done(mPolicySurface, notification_level, + error_state); + } + + void SendWindowScreenModeDone( + enum ds_tizen_policy_window_screen_mode window_screen_mode, + enum ds_tizen_policy_error_state error_state) + { + ds_inf("%s", __func__); + + ds_tizen_policy_surface_send_window_screen_mode_done(mPolicySurface, window_screen_mode, + error_state); + } + + void SendIconifyStateChanged(bool iconified, bool force) + { + ds_inf("%s", __func__); + + ds_tizen_policy_surface_send_iconify_state_changed(mPolicySurface, iconified, force); + } + +public: + bool bDestroyed; + + bool bGetVisibility; + bool bGetPosition; + bool bActivate; + bool bRaise; + bool bLower; + bool bSetFocusSkip; + std::string mRole; + enum ds_tizen_policy_window_type mWinType; + bool bSetConformant; + bool bGetConformant; + enum ds_tizen_policy_notification_level mNotificationLevel; + enum ds_tizen_policy_window_screen_mode mWindowScreenMode; + uint32_t mUniversalId; + uint32_t mParentUniversalId; + bool bIconify; + int32_t mAuxHintId; + std::string mAuxHintName; + std::string mAuxHintValue; + bool bGetSupportedAuxHints; + bool bSetFloatingMode; + enum ds_tizen_policy_stack_mode mStackMode; + bool bGetSubsurfaceWatcher; + struct ds_surface *mParentSurface; + uint32_t mSerial; + bool bVideo; + bool bShow; + bool bHide; + +private: + struct ds_tizen_policy_surface *mPolicySurface; + MockPolicyVisibility *mPolicyVisibility; + MockPolicyPosition *mPolicyPosition; + MockPolicySubsurfaceWatcher *mPolicySubsurfaceWatcher; + + struct DestroyListener : ::wl_listener { + MockPolicySurface *parent; + }; + DestroyListener mDestroyListener; + + // policy policy_surface listener structure + struct GetVisibilityListener : ::wl_listener { + MockPolicySurface *parent; + }; + GetVisibilityListener mGetVisibilityListener; + + struct GetPositionListener : ::wl_listener { + MockPolicySurface *parent; + }; + GetPositionListener mGetPositionListener; + + struct ActivateListener : ::wl_listener { + MockPolicySurface *parent; + }; + ActivateListener mActivateListener; + + struct RaiseListener : ::wl_listener { + MockPolicySurface *parent; + }; + RaiseListener mRaiseListener; + + struct LowerListener : ::wl_listener { + MockPolicySurface *parent; + }; + LowerListener mLowerListener; + + struct SetFocusSkipListener : ::wl_listener { + MockPolicySurface *parent; + }; + SetFocusSkipListener mSetFocusSkipListener; + + struct UnsetFocusSkipListener : ::wl_listener { + MockPolicySurface *parent; + }; + UnsetFocusSkipListener mUnsetFocusSkipListener; + + struct SetRoleListener : ::wl_listener { + MockPolicySurface *parent; + }; + SetRoleListener mSetRoleListener; + + struct WindowTypeListener : ::wl_listener { + MockPolicySurface *parent; + }; + WindowTypeListener mWindowTypeListener; + + struct SetConformantListener : ::wl_listener { + MockPolicySurface *parent; + }; + SetConformantListener mSetConformantListener; + + struct UnsetConformantListener : ::wl_listener { + MockPolicySurface *parent; + }; + UnsetConformantListener mUnsetConformantListener; + + struct GetConformantListener : ::wl_listener { + MockPolicySurface *parent; + }; + GetConformantListener mGetConformantListener; + + struct SetNotificationLevelListener : ::wl_listener { + MockPolicySurface *parent; + }; + SetNotificationLevelListener mSetNotificationLevelListener; + + struct SetWindowScreenModeListener : ::wl_listener { + MockPolicySurface *parent; + }; + SetWindowScreenModeListener mSetWindowScreenModeListener; + + struct GetSubsurfaceListener : ::wl_listener { + MockPolicySurface *parent; + }; + GetSubsurfaceListener mGetSubsurfaceListener; + + struct IconifyListener : ::wl_listener { + MockPolicySurface *parent; + }; + IconifyListener mIconifyListener; + + struct UniconifyListener : ::wl_listener { + MockPolicySurface *parent; + }; + UniconifyListener mUniconifyListener; + + struct AddAuxHintListener : ::wl_listener { + MockPolicySurface *parent; + }; + AddAuxHintListener mAddAuxHintListener; + + struct ChangeAuxHintListener : ::wl_listener { + MockPolicySurface *parent; + }; + ChangeAuxHintListener mChangeAuxHintListener; + + struct DeleteAuxHintListener : ::wl_listener { + MockPolicySurface *parent; + }; + DeleteAuxHintListener mDeleteAuxHintListener; + + struct GetSupportAuxHintsListener : ::wl_listener { + MockPolicySurface *parent; + }; + GetSupportAuxHintsListener mGetSupportAuxHintsListener; + + struct SetFloatingModeListener : ::wl_listener { + MockPolicySurface *parent; + }; + SetFloatingModeListener mSetFloatingModeListener; + + struct UnsetFloatingModeListener : ::wl_listener { + MockPolicySurface *parent; + }; + UnsetFloatingModeListener mUnsetFloatingModeListener; + + struct SetStackModeListener : ::wl_listener { + MockPolicySurface *parent; + }; + SetStackModeListener mSetStackModeListener; + + struct GetSubsurfaceWatcherListener : ::wl_listener { + MockPolicySurface *parent; + }; + GetSubsurfaceWatcherListener mGetSubsurfaceWatcherListener; + + struct SetParentListener : ::wl_listener { + MockPolicySurface *parent; + }; + SetParentListener mSetParentListener; + + struct AckConformantRegionListener : ::wl_listener { + MockPolicySurface *parent; + }; + AckConformantRegionListener mAckConformantRegionListener; + + struct SetVideoListener : ::wl_listener { + MockPolicySurface *parent; + }; + SetVideoListener mSetVideoListener; + + struct ShowListener : ::wl_listener { + MockPolicySurface *parent; + }; + ShowListener mShowListener; + + struct HideListener : ::wl_listener { + MockPolicySurface *parent; + }; + HideListener mHideListener; + + struct SetParentWithBelowListener : ::wl_listener { + MockPolicySurface *parent; + }; + SetParentWithBelowListener mSetParentWithBelowListener; +}; + +class MockSurface +{ +public: + MockSurface(struct ds_surface *surface) + : mSurface(surface) + { + ds_inf("%s", __func__); + + // del surface listener + mDestroyListener.notify = MockSurface::DestroyCallback; + mDestroyListener.parent = this; + ds_surface_add_destroy_listener(surface, &mDestroyListener); + } + ~MockSurface() + { + ds_inf("%s", __func__); + + if (mDestroyListener.notify) { + wl_list_remove(&mDestroyListener.link); + mDestroyListener.notify = nullptr; + } + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + MockSurface *mockSurface = + reinterpret_cast(listener)->parent; + struct ds_surface *surface = static_cast(data); + + ds_inf("%s: mockSurface(%p), surface(%p)", __func__, mockSurface, surface); + + wl_list_remove(&mockSurface->mDestroyListener.link); + mockSurface->mDestroyListener.notify = nullptr; + } + +private: + struct ds_surface *mSurface; + + struct DestroyListener : ::wl_listener { + MockSurface *parent; + }; + DestroyListener mDestroyListener; +}; + +class MockPolicyCompositor : public MockCompositor +{ +public: + MockPolicyCompositor() + : MockCompositor(&MockPolicyCompositor::TestSetup, this) + { + ds_inf("%s : this(%p)", __func__, this); + + // initialize the flags to check + bDestroyed = false; + bGetPolicySurface = false; + } + + ~MockPolicyCompositor() + { + ds_inf("%s : this(%p)", __func__, this); + + auto removeSurfaces = [&](MockSurface* s)->void {delete s;}; + for_each(mMockSurfaces.begin(), mMockSurfaces.end(), removeSurfaces); + mMockSurfaces.clear(); + + auto removePolicySurfaces = [&](MockPolicySurface* i)->void {delete i;}; + for_each(mPolicySurfaces.begin(), mPolicySurfaces.end(), removePolicySurfaces); + mPolicySurfaces.clear(); + + wl_list_remove(&mNewSurfaceListener.link); + } + + static void TestSetup(void *data) + { + MockPolicyCompositor *mockComp = + static_cast(data); + Compositor *comp = mockComp->compositor; + + ds_inf("%s: mockComp(%p)", __func__, mockComp); + + // new surface listener + mockComp->mNewSurfaceListener.notify = + MockPolicyCompositor::NewSurfaceCallback; + mockComp->mNewSurfaceListener.parent = mockComp; + ds_compositor_add_new_surface_listener(comp->compositor, + &mockComp->mNewSurfaceListener); + + mockComp->mPolicy = + ds_tizen_policy_create(comp->display); + + // policy destroy listener + mockComp->mDestroyListener.notify = + MockPolicyCompositor::DestroyCallback; + mockComp->mDestroyListener.parent = mockComp; + ds_tizen_policy_add_destroy_listener(mockComp->mPolicy, + &mockComp->mDestroyListener); + + // policy listeners + mockComp->mGetPolicySurfaceListener.notify = + MockPolicyCompositor::GetPolicySurfaceCallback; + mockComp->mGetPolicySurfaceListener.parent = mockComp; + ds_tizen_policy_add_get_surface_listener( + mockComp->mPolicy, + &mockComp->mGetPolicySurfaceListener); + + mockComp->mActivateBelowByUniversalIdListener.notify = + MockPolicyCompositor::ActivateBelowByUniversalIdCallback; + mockComp->mActivateBelowByUniversalIdListener.parent = mockComp; + ds_tizen_policy_add_activate_below_by_univeral_id_listener( + mockComp->mPolicy, + &mockComp->mActivateBelowByUniversalIdListener); + + mockComp->mLowerByUniversalIdListener.notify = + MockPolicyCompositor::LowerByUniversalIdCallback; + mockComp->mLowerByUniversalIdListener.parent = mockComp; + ds_tizen_policy_add_lower_by_universal_id_listener( + mockComp->mPolicy, + &mockComp->mLowerByUniversalIdListener); + + mockComp->mSetTransientForListener.notify = + MockPolicyCompositor::SetTransientForCallback; + mockComp->mSetTransientForListener.parent = mockComp; + ds_tizen_policy_add_set_transient_for_listener( + mockComp->mPolicy, + &mockComp->mSetTransientForListener); + + mockComp->mUnsetTransientForListener.notify = + MockPolicyCompositor::UnsetTransientForCallback; + mockComp->mUnsetTransientForListener.parent = mockComp; + ds_tizen_policy_add_unset_transient_for_listener( + mockComp->mPolicy, + &mockComp->mUnsetTransientForListener); + + mockComp->mPlaceSubsurfaceBelowParentListener.notify = + MockPolicyCompositor::PlaceSubsurfaceBelowParentCallback; + mockComp->mPlaceSubsurfaceBelowParentListener.parent = mockComp; + ds_tizen_policy_add_place_subsurface_below_parent_listener( + mockComp->mPolicy, + &mockComp->mPlaceSubsurfaceBelowParentListener); + + mockComp->mSetSubsurfaceStandAloneListener.notify = + MockPolicyCompositor::SetSubsurfaceStandAloneCallback; + mockComp->mSetSubsurfaceStandAloneListener.parent = mockComp; + ds_tizen_policy_add_set_subsurface_stand_alone_listener( + mockComp->mPolicy, + &mockComp->mSetSubsurfaceStandAloneListener); + + mockComp->mSetBackgroundStateListener.notify = + MockPolicyCompositor::SetBackgroundStateCallback; + mockComp->mSetBackgroundStateListener.parent = mockComp; + ds_tizen_policy_add_set_background_state_listener( + mockComp->mPolicy, + &mockComp->mSetBackgroundStateListener); + + mockComp->mUnsetBackgroundStateListener.notify = + MockPolicyCompositor::UnsetBackgroundStateCallback; + mockComp->mUnsetBackgroundStateListener.parent = mockComp; + ds_tizen_policy_add_unset_background_state_listener( + mockComp->mPolicy, + &mockComp->mUnsetBackgroundStateListener); + + mockComp->mActivateAboveByUniversalIdListener.notify = + MockPolicyCompositor::ActivateAboveByUniversalIdCallback; + mockComp->mActivateAboveByUniversalIdListener.parent = mockComp; + ds_tizen_policy_add_activate_above_by_universal_id_listener( + mockComp->mPolicy, + &mockComp->mActivateAboveByUniversalIdListener); + + mockComp->mSetAppIdListener.notify = + MockPolicyCompositor::SetAppIdCallback; + mockComp->mSetAppIdListener.parent = mockComp; + ds_tizen_policy_add_set_appid_listener( + mockComp->mPolicy, + &mockComp->mSetAppIdListener); + + mockComp->mSetTransientForBelowListener.notify = + MockPolicyCompositor::SetTransientForBelowCallback; + mockComp->mSetTransientForBelowListener.parent = mockComp; + ds_tizen_policy_add_set_transient_for_below_listener( + mockComp->mPolicy, + &mockComp->mSetTransientForBelowListener); + } + + static void NewSurfaceCallback(struct wl_listener *listener, void *data) + { + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_surface *surface = static_cast(data); + MockSurface *mockSurf = new MockSurface(surface); + + ds_inf("%s: mockComp(%p), surface(%p)", __func__, mockComp, surface); + + mockComp->mMockSurfaces.push_back(mockSurf); + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bDestroyed = true; + } + + static void GetPolicySurfaceCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_get_surface *event = + static_cast(data); + + struct ds_tizen_policy_surface *policy_surface = event->policy_surface; + + ds_inf("%s: mockComp(%p), policy_surface(%p)", __func__, mockComp, policy_surface); + + mockComp->bGetPolicySurface = true; + + MockPolicySurface *policySurface = new MockPolicySurface(event->policy_surface); + mockComp->mPolicySurfaces.push_back(policySurface); + } + + static void ActivateBelowByUniversalIdCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_activate_below_by_univeral_id *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->mUniversalId = event->universal_id; + mockComp->mBelowUniversalId = event->below_universal_id; + } + + static void LowerByUniversalIdCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_lower_by_universal_id *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->mUniversalId = event->universal_id; + } + + static void SetTransientForCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_set_transient_for *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->mChildUniversalId = event->child_universal_id; + mockComp->mParentUniversalId = event->parent_universal_id; + } + + static void UnsetTransientForCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_unset_transient_for *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->mChildUniversalId = event->child_universal_id; + } + + static void PlaceSubsurfaceBelowParentCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_place_subsurface_below_parent *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->bPlaceSubsurfaceBelowParent = true; + } + + static void SetSubsurfaceStandAloneCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_set_subsurface_stand_alone *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->bSetSubsurfaceStandAlone = true; + } + + static void SetBackgroundStateCallback(struct wl_listener *listener, void *data) + { + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_set_background_state *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->mPid = event->pid; + } + + static void UnsetBackgroundStateCallback(struct wl_listener *listener, void *data) + { + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_unset_background_state *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->mPid = event->pid; + } + + static void ActivateAboveByUniversalIdCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_activate_above_by_universal_id *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->mUniversalId = event->universal_id; + mockComp->mAboveUniversalId = event->above_universal_id; + } + + static void SetAppIdCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_set_appid *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->mPid = event->pid; + mockComp->mAppId = event->appid; // char -> string + } + + static void SetTransientForBelowCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockPolicyCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_set_transient_for_below *event = + static_cast(data); + + EXPECT_TRUE(mockComp->mPolicy == event->policy); + mockComp->mUniversalId = event->universal_id; + mockComp->mParentUniversalId = event->parent_universal_id; + } + + MockPolicySurface* FindPolicySurfaceWidthResId(uint32_t res_id) + { + auto is_matched = [&](MockPolicySurface* i)->bool { + return (i->GetSurfaceResId() == res_id); + }; + auto result = std::find_if(begin(mPolicySurfaces), end(mPolicySurfaces), + is_matched); + if (result != std::end(mPolicySurfaces)) + return *result; + + return nullptr; + } + +public: + bool bDestroyed; + bool bGetPolicySurface; + int32_t mPid; + std::string mAppId; + uint32_t mUniversalId; + uint32_t mAboveUniversalId; + uint32_t mBelowUniversalId; + uint32_t mParentUniversalId; + uint32_t mChildUniversalId; + bool bPlaceSubsurfaceBelowParent; + bool bSetSubsurfaceStandAlone; + +private: + struct ds_tizen_policy *mPolicy; + + std::vector mMockSurfaces; + std::vector mPolicySurfaces; + + struct NewSurfaceListener : ::wl_listener { + MockPolicyCompositor *parent; + }; + NewSurfaceListener mNewSurfaceListener; + + struct DestroyListener : ::wl_listener { + MockPolicyCompositor *parent; + }; + DestroyListener mDestroyListener; + + // policy listener structure + struct GetPolicySurfaceListener : ::wl_listener { + MockPolicyCompositor *parent; + }; + GetPolicySurfaceListener mGetPolicySurfaceListener; + + struct ActivateBelowByUniversalIdListener: ::wl_listener { + MockPolicyCompositor *parent; + }; + ActivateBelowByUniversalIdListener mActivateBelowByUniversalIdListener; + + struct LowerByUniversalIdListener: ::wl_listener { + MockPolicyCompositor *parent; + }; + LowerByUniversalIdListener mLowerByUniversalIdListener; + + struct SetTransientForListener: ::wl_listener { + MockPolicyCompositor *parent; + }; + SetTransientForListener mSetTransientForListener; + + struct UnsetTransientForListener: ::wl_listener { + MockPolicyCompositor *parent; + }; + UnsetTransientForListener mUnsetTransientForListener; + + struct PlaceSubsurfaceBelowParentListener: ::wl_listener { + MockPolicyCompositor *parent; + }; + PlaceSubsurfaceBelowParentListener mPlaceSubsurfaceBelowParentListener; + + struct SetSubsurfaceStandAloneListener: ::wl_listener { + MockPolicyCompositor *parent; + }; + SetSubsurfaceStandAloneListener mSetSubsurfaceStandAloneListener; + + struct SetBackgroundStateListener : ::wl_listener { + MockPolicyCompositor *parent; + }; + SetBackgroundStateListener mSetBackgroundStateListener; + + struct UnsetBackgroundStateListener : ::wl_listener { + MockPolicyCompositor *parent; + }; + UnsetBackgroundStateListener mUnsetBackgroundStateListener; + + struct ActivateAboveByUniversalIdListener: ::wl_listener { + MockPolicyCompositor *parent; + }; + ActivateAboveByUniversalIdListener mActivateAboveByUniversalIdListener; + + struct SetAppIdListener: ::wl_listener { + MockPolicyCompositor *parent; + }; + SetAppIdListener mSetAppIdListener; + + struct SetTransientForBelowListener: ::wl_listener { + MockPolicyCompositor *parent; + }; + SetTransientForBelowListener mSetTransientForBelowListener; + + // policy_surface listener structure + struct PolicySurfaceDestroyListener : ::wl_listener { + MockPolicyCompositor *parent; + }; + PolicySurfaceDestroyListener mPolicySurfaceDestroyListener; +}; + +class MockPolicyClient : public MockClient +{ +public: + MockPolicyClient() + : mSurfaceRes(nullptr), + mIsConformant(0), + mLevel(-1), + mErrorState(0), + mChildId(0), + mWindowScreenMode(0), + mIconified(0), + mForce(0), + mHints(nullptr), + mNumHints(0), + mHintId(-1), + mKey(nullptr), + mValue(nullptr), + mOptions(nullptr), + mConformantPart(0), + mState(0), + mX(-1), mY(-1), mW(0), mH(0), + mSerial(0), + mVisibilityType(0), + mVisibilityOption(0), + mPositionX(-1), mPositionY(-1) + {} + MockPolicyClient(const struct wl_registry_listener *listener) + : MockClient(listener, this) + { + ds_inf("%s", __func__); + } + ~MockPolicyClient() + { + ds_inf("%s", __func__); + } + + void SetWlCompositor(struct wl_compositor *global_res) + { + ds_inf("%s", __func__); + + compositor_res = global_res; + } + + void SetWlSubCompositor(struct wl_subcompositor *global_res) + { + ds_inf("%s", __func__); + + subcompositor_res = global_res; + } + + struct wl_compositor *GetWlCompositor() + { + ds_inf("%s", __func__); + + return compositor_res; + } + + struct wl_subcompositor *GetWlSubCompositor() + { + ds_inf("%s", __func__); + + return subcompositor_res; + } + + void SetTizenPolicy(struct tizen_policy *resource) + { + ds_inf("%s", __func__); + + policy_res = resource; + } + + struct tizen_policy *GetTizenPolicy() + { + ds_inf("%s", __func__); + + return policy_res; + } + +public: + struct wl_surface *mSurfaceRes; + uint32_t mIsConformant; + int32_t mLevel; + uint32_t mErrorState; + uint32_t mChildId; + uint32_t mWindowScreenMode; + uint32_t mIconified; + uint32_t mForce; + struct wl_array *mHints; + uint32_t mNumHints; + int32_t mHintId; + const char *mKey; + const char *mValue; + struct wl_array *mOptions; + uint32_t mConformantPart; + uint32_t mState; + int32_t mX, mY, mW, mH; + uint32_t mSerial; + uint32_t mVisibilityType; + uint32_t mVisibilityOption; + int32_t mPositionX; + int32_t mPositionY; + +private: + struct wl_compositor *compositor_res; + struct wl_subcompositor *subcompositor_res; + struct tizen_policy *policy_res; +}; + +static void +client_tizen_policy_cb_conformant(void *data, struct tizen_policy *policy_res, + struct wl_surface *surface_resource, uint32_t is_conformant) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mIsConformant = is_conformant; +} + +static void +client_tizen_policy_cb_conformant_area(void *data, + struct tizen_policy *policy_res, + struct wl_surface *surface_resource, uint32_t conformant_part, + uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mConformantPart = conformant_part; + client->mState = state; + client->mX = x; + client->mY = y; + client->mW = w; + client->mH = h; +} + +static void +client_tizen_policy_cb_notification_done(void *data, + struct tizen_policy *policy_res, + struct wl_surface *surface_resource, int32_t level, uint32_t error_state) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mLevel = level; + client->mErrorState = error_state; +} + +static void +client_tizen_policy_cb_transient_for_done(void *data, + struct tizen_policy *policy_res, uint32_t child_id) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mChildId = child_id; +} + +static void +client_tizen_policy_cb_window_screen_mode_done(void *data, + struct tizen_policy *policy_res, struct wl_surface *surface_resource, + uint32_t mode, uint32_t error_state) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mWindowScreenMode = mode; + client->mErrorState = error_state; +} + +static void +client_tizen_policy_cb_iconify_state_changed(void *data, + struct tizen_policy *policy_res, struct wl_surface *surface_resource, + uint32_t iconified, uint32_t force) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mIconified = iconified; + client->mForce = force; +} + +static void +client_tizen_policy_cb_supported_aux_hints(void *data, + struct tizen_policy *policy_res, struct wl_surface *surface_resource, + struct wl_array *hints, uint32_t num_hints) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mHints = hints; + client->mNumHints = num_hints; +} + +static void +client_tizen_policy_cb_allowed_aux_hint(void *data, + struct tizen_policy *policy_res, struct wl_surface *surface_resource, + int32_t id) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mHintId = id; +} + +static void +client_tizen_policy_cb_aux_message(void *data, + struct tizen_policy *policy_res, struct wl_surface *surface_resource, + const char *key, const char *value, struct wl_array *options) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mKey = key; + client->mValue = value; + client->mOptions = options; +} + +static void +client_tizen_policy_cb_conformant_region(void *data, + struct tizen_policy *policy_res, struct wl_surface *surface_resource, + uint32_t conformant_part, uint32_t state, + int32_t x, int32_t y, int32_t w, int32_t h, uint32_t serial) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mConformantPart = conformant_part; + client->mState = state; + client->mX = x; + client->mY = y; + client->mW = w; + client->mH = h; + client->mSerial = serial; +} + +static void +client_tizen_policy_cb_interactive_mode_done(void *data, + struct tizen_policy *policy_res, struct wl_surface *surface_resource, + int32_t x, int32_t y, uint32_t w, uint32_t h) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mX = x; + client->mY = y; + client->mW = w; + client->mH = h; +} + +static void +client_tizen_policy_cb_interactive_resize_done(void *data, + struct tizen_policy *policy_res, struct wl_surface *surface_resource, + int32_t x, int32_t y, uint32_t w, uint32_t h) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mSurfaceRes = surface_resource; + client->mX = x; + client->mY = y; + client->mW = w; + client->mH = h; +} + +static const struct +tizen_policy_listener policy_cb_listener = +{ + .conformant = client_tizen_policy_cb_conformant, + .conformant_area = client_tizen_policy_cb_conformant_area, + .notification_done = client_tizen_policy_cb_notification_done, + .transient_for_done = client_tizen_policy_cb_transient_for_done, + .window_screen_mode_done = client_tizen_policy_cb_window_screen_mode_done, + .iconify_state_changed = client_tizen_policy_cb_iconify_state_changed, + .supported_aux_hints = client_tizen_policy_cb_supported_aux_hints, + .allowed_aux_hint = client_tizen_policy_cb_allowed_aux_hint, + .aux_message = client_tizen_policy_cb_aux_message, + .conformant_region = client_tizen_policy_cb_conformant_region, + .interactive_move_done = client_tizen_policy_cb_interactive_mode_done, + .interactive_resize_done = client_tizen_policy_cb_interactive_resize_done, +}; + +static void +client_registry_cb_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + struct wl_compositor *compositor_res; + struct wl_subcompositor *subcompositor_res; + struct tizen_policy *policy_res; + + if (!strcmp(interface, "wl_compositor")) { + compositor_res = (struct wl_compositor *)wl_registry_bind(registry, + name, &wl_compositor_interface, 1); + if (compositor_res == nullptr) { + ds_err("wl_registry_bind() failed. wl_compositor resource."); + return; + } + client->SetWlCompositor(compositor_res); + } else if (!strcmp(interface, "wl_subcompositor")) { + subcompositor_res = (struct wl_subcompositor *) + wl_registry_bind(registry, name, &wl_subcompositor_interface, 1); + if (subcompositor_res == nullptr) { + ds_err("wl_registry_bind() failed. wl_subcompositor resource."); + return; + } + client->SetWlSubCompositor(subcompositor_res); + } else if (!strcmp(interface, "tizen_policy")) { + policy_res = (struct tizen_policy *)wl_registry_bind(registry, + name, &tizen_policy_interface, TIZEN_POLICY_VERSION); + if (policy_res == nullptr) { + ds_err("wl_registry_bind() failed. tizen_policy resource."); + return; + } + client->SetTizenPolicy(policy_res); + + tizen_policy_add_listener(policy_res, + &policy_cb_listener, client); + } +} + +static void +client_registry_cb_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + struct wl_compositor *compositor_res = client->GetWlCompositor(); + struct tizen_policy *policy_res = client->GetTizenPolicy(); + + tizen_policy_destroy(policy_res); + wl_compositor_destroy(compositor_res); +} + +static const struct wl_registry_listener registry_listener = { + .global = client_registry_cb_global, + .global_remove = client_registry_cb_global_remove +}; + +class PolicyTest : public ::testing::Test +{ +public: + void SetUp(void) override; + void TearDown(void) override; + + MockPolicyCompositor *comp; + MockPolicyClient *client; + struct wl_compositor *compositor_res; + struct wl_subcompositor *subcompositor_res; + struct tizen_policy *policy_res; + struct wl_surface *surface_res; +}; + +void +PolicyTest::SetUp(void) +{ + //ds_log_init(DS_DBG, NULL); + + ds_inf("%s", __func__); + + comp = new MockPolicyCompositor(); + client = new MockPolicyClient(®istry_listener); + compositor_res = client->GetWlCompositor(); + subcompositor_res = client->GetWlSubCompositor(); + policy_res = client->GetTizenPolicy(); + surface_res = wl_compositor_create_surface(compositor_res); + + client->RoundTrip(); +} + +void +PolicyTest::TearDown(void) +{ + ds_inf("%s", __func__); + + wl_surface_destroy(surface_res); + client->RoundTrip(); + + delete client; + delete comp; +} + +TEST_F(PolicyTest, Create_P) +{ + EXPECT_TRUE(true); +} + +TEST_F(PolicyTest, Req_ActivateBelowByUniversalId) +{ + uint32_t universal_id = 100; + uint32_t below_universal_id = 200; + + tizen_policy_activate_below_by_res_id(policy_res, + universal_id, below_universal_id); + client->RoundTrip(); + + EXPECT_TRUE(comp->mUniversalId == universal_id) + << comp->mUniversalId << ", " << universal_id; + EXPECT_TRUE(comp->mBelowUniversalId == below_universal_id) + << comp->mBelowUniversalId << ", " << below_universal_id; +} + +TEST_F(PolicyTest, Req_LowerByUniversalId) +{ + uint32_t universal_id = 100; + + tizen_policy_lower_by_res_id(policy_res,universal_id); + client->RoundTrip(); + + EXPECT_TRUE(comp->mUniversalId == universal_id) + << comp->mUniversalId << ", " << universal_id; +} + +TEST_F(PolicyTest, Req_SetTransientFor) +{ + uint32_t child_universal_id = 100; + uint32_t parent_universal_id = 200; + + tizen_policy_set_transient_for(policy_res, + child_universal_id, parent_universal_id); + client->RoundTrip(); + + EXPECT_TRUE(comp->mChildUniversalId == child_universal_id) + << comp->mChildUniversalId << ", " << child_universal_id; + EXPECT_TRUE(comp->mParentUniversalId == parent_universal_id) + << comp->mParentUniversalId << ", " << parent_universal_id; + + EXPECT_TRUE(client->mChildId == child_universal_id); +} + +TEST_F(PolicyTest, Req_UnsetTransientFor) +{ + uint32_t child_universal_id = 100; + + tizen_policy_unset_transient_for(policy_res, child_universal_id); + client->RoundTrip(); + + EXPECT_TRUE(comp->mChildUniversalId == child_universal_id) + << comp->mChildUniversalId << ", " << child_universal_id; + + EXPECT_TRUE(client->mChildId == child_universal_id); +} + +TEST_F(PolicyTest, Req_PlaceSubsurfaceBelowParent) +{ + struct wl_surface *parent_surface_res; + struct wl_subsurface *subsurface_res; + + parent_surface_res = wl_compositor_create_surface(compositor_res); + if (!parent_surface_res) + return; + + subsurface_res = wl_subcompositor_get_subsurface(subcompositor_res, + surface_res, parent_surface_res); + if (!subsurface_res) { + wl_surface_destroy(parent_surface_res); + return; + } + + tizen_policy_place_subsurface_below_parent(policy_res, subsurface_res); + client->RoundTrip(); + + EXPECT_TRUE(comp->bPlaceSubsurfaceBelowParent); + + wl_subsurface_destroy(subsurface_res); + wl_surface_destroy(parent_surface_res); +} + +TEST_F(PolicyTest, Req_SetSubsurfaceStandAlone) +{ + struct wl_surface *parent_surface_res; + struct wl_subsurface *subsurface_res; + + parent_surface_res = wl_compositor_create_surface(compositor_res); + if (!parent_surface_res) + return; + + subsurface_res = wl_subcompositor_get_subsurface(subcompositor_res, + surface_res, parent_surface_res); + if (!subsurface_res) { + wl_surface_destroy(parent_surface_res); + return; + } + + tizen_policy_set_subsurface_stand_alone(policy_res, subsurface_res); + client->RoundTrip(); + + EXPECT_TRUE(comp->bSetSubsurfaceStandAlone); + + wl_subsurface_destroy(subsurface_res); + wl_surface_destroy(parent_surface_res); +} + +TEST_F(PolicyTest, Req_ActivateAboveByUniversalId) +{ + uint32_t universal_id = 100; + uint32_t above_universal_id = 100; + + tizen_policy_activate_above_by_res_id(policy_res, universal_id, + above_universal_id); + client->RoundTrip(); + + EXPECT_TRUE(comp->mUniversalId == universal_id) + << comp->mUniversalId << ", " << universal_id; + EXPECT_TRUE(comp->mAboveUniversalId == above_universal_id) + << comp->mAboveUniversalId << ", " << above_universal_id; +} + +TEST_F(PolicyTest, Req_SetAppId) +{ + int32_t pid = getpid(); + std::string appid("APPLICATION_ID"); + char* c_appid = const_cast(appid.c_str()); + + tizen_policy_set_appid(policy_res, pid, c_appid); + client->RoundTrip(); + + EXPECT_TRUE(comp->mPid == pid) + << comp->mPid << ", " << pid; + EXPECT_TRUE(comp->mAppId.compare(appid) == false) + << comp->mAppId << ", " << appid; +} + +TEST_F(PolicyTest, Req_SetTransientForBelow) +{ + uint32_t universal_id = 100; + uint32_t parent_universal_id = 200; + + tizen_policy_set_transient_for_below(policy_res, universal_id, + parent_universal_id); + client->RoundTrip(); + + EXPECT_TRUE(comp->mUniversalId == universal_id) + << comp->mUniversalId << ", " << universal_id; + EXPECT_TRUE(comp->mParentUniversalId == parent_universal_id) + << comp->mParentUniversalId << ", " << parent_universal_id; +} + +static void +client_tizen_visibility_cb_notify(void *data, + struct tizen_visibility *visibility_res, uint32_t visibility) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mVisibilityType = visibility; +} + +static void +client_tizen_visibility_cb_changed(void *data, + struct tizen_visibility *visibility_res, uint32_t type, uint32_t option) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mVisibilityType = type; + client->mVisibilityOption = option; +} + +static const struct +tizen_visibility_listener visibility_cb_listener = +{ + .notify = client_tizen_visibility_cb_notify, + .changed = client_tizen_visibility_cb_changed, +}; + +TEST_F(PolicyTest, Req_PolicySurfaceGetVisibility) +{ + MockPolicySurface *policy_surface; + MockPolicyVisibility *visibility; + struct tizen_visibility *visibility_res; + uint32_t surface_res_id; + + visibility_res = tizen_policy_get_visibility(policy_res, surface_res); + EXPECT_TRUE(visibility_res != NULL); + + tizen_visibility_add_listener(visibility_res, + &visibility_cb_listener, client); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bGetVisibility); + + visibility = policy_surface->GetVisibility(); + + tizen_visibility_destroy(visibility_res); + client->RoundTrip(); + + EXPECT_TRUE(visibility->bDestroyed); +} + +TEST_F(PolicyTest, Ev_VisibilityNotify) +{ + MockPolicySurface *policy_surface; + MockPolicyVisibility *visibility; + struct tizen_visibility *visibility_res; + enum ds_tizen_policy_visibility_type type = + DS_TIZEN_POLICY_VISIBILITY_TYPE_FULLY_OBSCURED; + uint32_t surface_res_id; + + visibility_res = tizen_policy_get_visibility(policy_res, surface_res); + EXPECT_TRUE(visibility_res != NULL); + + tizen_visibility_add_listener(visibility_res, + &visibility_cb_listener, client); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bGetVisibility); + + visibility = policy_surface->GetVisibility(); + visibility->SendNotify(type); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->mVisibilityType == + TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED); + + tizen_visibility_destroy(visibility_res); + client->RoundTrip(); + + EXPECT_TRUE(visibility->bDestroyed); +} + +TEST_F(PolicyTest, Ev_VisibilityChanged) +{ + MockPolicySurface *policy_surface; + MockPolicyVisibility *visibility; + struct tizen_visibility *visibility_res; + enum ds_tizen_policy_visibility_type type = + DS_TIZEN_POLICY_VISIBILITY_TYPE_FULLY_OBSCURED; + uint32_t surface_res_id; + uint32_t option = 4; + + visibility_res = tizen_policy_get_visibility(policy_res, surface_res); + EXPECT_TRUE(visibility_res != NULL); + + tizen_visibility_add_listener(visibility_res, + &visibility_cb_listener, client); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bGetVisibility); + + visibility = policy_surface->GetVisibility(); + visibility->SendChanged(type, option); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->mVisibilityType == + TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED); + EXPECT_TRUE(client->mVisibilityOption == option); + + tizen_visibility_destroy(visibility_res); + client->RoundTrip(); + + EXPECT_TRUE(visibility->bDestroyed); +} + +static void +client_tizen_position_cb_changed(void *data, + struct tizen_position *position_res, int32_t x, int32_t y) +{ + ds_inf("%s", __func__); + + MockPolicyClient *client = static_cast(data); + + client->mPositionX = x; + client->mPositionY = y; +} + +static const struct +tizen_position_listener position_cb_listener = +{ + .changed = client_tizen_position_cb_changed, +}; + +TEST_F(PolicyTest, Req_PolicySurfaceGetPosition) +{ + MockPolicySurface *policy_surface; + struct tizen_position *position_res; + uint32_t surface_res_id; + + position_res = tizen_policy_get_position(policy_res, surface_res); + EXPECT_TRUE(position_res != NULL); + + tizen_position_add_listener(position_res, + &position_cb_listener, client); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bGetPosition); + + tizen_position_destroy(position_res); +} + +TEST_F(PolicyTest, Req_PositionSet) +{ + MockPolicySurface *policy_surface; + MockPolicyPosition *position; + struct tizen_position *position_res; + uint32_t surface_res_id; + int32_t x = 100, y = 200; + + position_res = tizen_policy_get_position(policy_res, surface_res); + EXPECT_TRUE(position_res != NULL); + + tizen_position_add_listener(position_res, + &position_cb_listener, client); + + tizen_position_set(position_res, x, y); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bGetPosition); + + position = policy_surface->GetPosition(); + EXPECT_TRUE(position->mX == x); + EXPECT_TRUE(position->mY == y); + + tizen_position_destroy(position_res); +} + +TEST_F(PolicyTest, Ev_PositionChanged) +{ + MockPolicySurface *policy_surface; + MockPolicyPosition *position; + struct tizen_position *position_res; + uint32_t surface_res_id; + int32_t x = 100, y = 200; + + position_res = tizen_policy_get_position(policy_res, surface_res); + EXPECT_TRUE(position_res != NULL); + + tizen_position_add_listener(position_res, + &position_cb_listener, client); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bGetPosition); + + position = policy_surface->GetPosition(); + position->SendChanged(x, y); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->mPositionX == x); + EXPECT_TRUE(client->mPositionY == y); + + tizen_position_destroy(position_res); +} + +TEST_F(PolicyTest, Req_PolicySurfaceActivate) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_activate(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bActivate); +} + +TEST_F(PolicyTest, Req_PolicySurfaceRaise) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_raise(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bRaise); +} + +TEST_F(PolicyTest, Req_PolicySurfaceLower) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_lower(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bLower); +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetFocusSkip) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_set_focus_skip(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bSetFocusSkip); +} + +TEST_F(PolicyTest, Req_PolicySurfaceUnsetFocusSkip) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_unset_focus_skip(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bSetFocusSkip == false); +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetRole) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + std::string role("APPLICATION_ID"); + char* c_role = const_cast(role.c_str()); + + tizen_policy_set_role(policy_res, surface_res, c_role); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->mRole.compare(role) == false) + << policy_surface->mRole << ", " << role; +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetType) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + uint32_t win_type = TIZEN_POLICY_WIN_TYPE_TOPLEVEL; + + tizen_policy_set_type(policy_res, surface_res, win_type); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->mWinType == DS_TIZEN_POLICY_WINDOW_TYPE_TOPLEVEL); +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetConformant) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_set_conformant(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bSetConformant == true); +} + +TEST_F(PolicyTest, Req_PolicySurfaceUnsetConformant) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_unset_conformant(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bSetConformant == false); +} + +TEST_F(PolicyTest, Req_Ev_PolicySurfaceGetConformant) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_get_conformant(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bGetConformant == true); +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetNotificationLevel) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + uint32_t noti_level = TIZEN_POLICY_LEVEL_HIGH; + + tizen_policy_set_notification_level(policy_res, surface_res, noti_level); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->mNotificationLevel == DS_TIZEN_POLICY_NOTIFICATION_LEVEL_HIGH); +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetWindowScreenMode) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + uint32_t screen_mode = TIZEN_POLICY_MODE_ALWAYS_ON; + + tizen_policy_set_window_screen_mode(policy_res, surface_res, screen_mode); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->mWindowScreenMode == DS_TIZEN_POLICY_WINDOW_SCREEN_MODE_ALWAYS_ON); +} + +TEST_F(PolicyTest, Req_PolicySurfaceGetSubsurface) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + struct wl_subsurface *subsurface_res; + uint32_t parent_universal_id = 100; + + subsurface_res = tizen_policy_get_subsurface(policy_res, surface_res, parent_universal_id); + EXPECT_TRUE(subsurface_res != NULL); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->mParentUniversalId == parent_universal_id); +} + +TEST_F(PolicyTest, Req_PolicySurfaceIconify) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_iconify(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bIconify == true); +} + +TEST_F(PolicyTest, Req_PolicySurfaceUniconify) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_uniconify(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bIconify == false); +} + +TEST_F(PolicyTest, Req_PolicySurfaceAddAuxHint) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + int32_t auxhint_id = 100; + std::string auxhint_name("AUX_HINT_NAME"); + std::string auxhint_value("AUX_HINT_VALUE"); + char* c_auxhint_name = const_cast(auxhint_name.c_str()); + char* c_auxhint_value = const_cast(auxhint_value.c_str()); + + tizen_policy_add_aux_hint(policy_res, surface_res, auxhint_id, + c_auxhint_name, c_auxhint_value); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->mAuxHintId == auxhint_id); + EXPECT_TRUE(policy_surface->mAuxHintName.compare(auxhint_name) == false) + << policy_surface->mAuxHintName << ", " << auxhint_name; + EXPECT_TRUE(policy_surface->mAuxHintValue.compare(auxhint_value) == false) + << policy_surface->mAuxHintValue << ", " << auxhint_value; +} + +TEST_F(PolicyTest, Req_PolicySurfaceChangeAuxHint) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + int32_t auxhint_id = 100; + std::string auxhint_value("AUX_HINT_VALUE"); + char* c_auxhint_value = const_cast(auxhint_value.c_str()); + + tizen_policy_change_aux_hint(policy_res, surface_res, auxhint_id, + c_auxhint_value); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->mAuxHintId == auxhint_id); + EXPECT_TRUE(policy_surface->mAuxHintValue.compare(auxhint_value) == false) + << policy_surface->mAuxHintValue << ", " << auxhint_value; +} + +TEST_F(PolicyTest, Req_PolicySurfaceDeleteAuxHint) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + int32_t auxhint_id = 100; + + tizen_policy_del_aux_hint(policy_res, surface_res, auxhint_id); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->mAuxHintId == auxhint_id); +} + +TEST_F(PolicyTest, Req_PolicySurfaceGetSupportAuxHints) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_get_supported_aux_hints(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bGetSupportedAuxHints); +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetBackgroundState) +{ + int32_t pid = getpid(); + + tizen_policy_set_background_state(policy_res, pid); + client->RoundTrip(); + + EXPECT_TRUE(comp->mPid == pid); +} + +TEST_F(PolicyTest, Req_PolicySurfaceUnsetBackgroundState) +{ + int32_t pid = getpid(); + + tizen_policy_unset_background_state(policy_res, pid); + client->RoundTrip(); + + EXPECT_TRUE(comp->mPid == pid); +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetFloatingMode) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_set_floating_mode(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bSetFloatingMode == true); +} + +TEST_F(PolicyTest, Req_PolicySurfaceUnsetFloatingMode) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_unset_floating_mode(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bSetFloatingMode == false); +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetStackMode) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_set_floating_mode(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bSetFloatingMode == true); +} + +TEST_F(PolicyTest, Req_PolicySurfaceGetSubsurfaceWatcher) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + struct tizen_subsurface_watcher *subsuface_watcher_res; + + subsuface_watcher_res = tizen_policy_get_subsurface_watcher(policy_res, surface_res); + EXPECT_TRUE(subsuface_watcher_res != NULL); + + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bGetSubsurfaceWatcher == true); + + tizen_subsurface_watcher_destroy(subsuface_watcher_res); +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetParent) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + struct wl_surface *parent_surface_res; + + parent_surface_res = wl_compositor_create_surface(compositor_res); + if (!parent_surface_res) + return; + + tizen_policy_set_parent(policy_res, surface_res, parent_surface_res); + + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->mParentSurface); +} + +TEST_F(PolicyTest, Req_PolicySurfaceAckConformantRegion) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + uint32_t serial = 100; + + tizen_policy_ack_conformant_region(policy_res, surface_res, serial); + + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->mSerial == serial); +} + +TEST_F(PolicyTest, Req_PolicySurfaceHasVideo) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + bool has_video = true; + + tizen_policy_has_video(policy_res, surface_res, (uint32_t)has_video); + + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bVideo == has_video); +} + +TEST_F(PolicyTest, Req_PolicySurfaceShow) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_show(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + + EXPECT_TRUE(policy_surface->bShow == true); +} + +TEST_F(PolicyTest, Req_PolicySurfaceHide) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + + tizen_policy_hide(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bHide == true); +} + +TEST_F(PolicyTest, Req_PolicySurfaceSetParentWithBelow) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + struct wl_surface *parent_surface_res; + + parent_surface_res = wl_compositor_create_surface(compositor_res); + if (!parent_surface_res) + return; + + tizen_policy_set_parent_with_below(policy_res, surface_res, + parent_surface_res); + + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->mParentSurface); +} + +TEST_F(PolicyTest, Ev_PolicySurfaceConformant) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + bool is_conformant = true; + + tizen_policy_get_conformant(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bGetConformant); + + policy_surface->SendConformant(is_conformant); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->mSurfaceRes == surface_res); + EXPECT_TRUE(client->mIsConformant == is_conformant); +} + +TEST_F(PolicyTest, Ev_PolicySurfaceConformant_Area) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + enum ds_tizen_policy_conformant_part part = + DS_TIZEN_POLICY_CONFORMANT_PART_INDICATOR; + bool visible = 1; + int32_t x = 100, y = 200, w = 300, h = 400; + + tizen_policy_get_conformant(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bGetConformant); + + policy_surface->SendConformantArea(part, visible, x, y, w, h); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->mSurfaceRes == surface_res); + EXPECT_TRUE(client->mConformantPart == TIZEN_POLICY_CONFORMANT_PART_INDICATOR); + EXPECT_TRUE(client->mState == (uint32_t)visible); + EXPECT_TRUE(client->mX == x); + EXPECT_TRUE(client->mY == y); + EXPECT_TRUE(client->mW == w); + EXPECT_TRUE(client->mH == h); +} + +TEST_F(PolicyTest, Ev_PolicySurfaceNotificationDone) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + int32_t noti_level = TIZEN_POLICY_LEVEL_HIGH; + enum ds_tizen_policy_notification_level notification_level = + DS_TIZEN_POLICY_NOTIFICATION_LEVEL_HIGH; + + tizen_policy_set_notification_level(policy_res, surface_res, noti_level); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->mNotificationLevel == notification_level); + + policy_surface->SendNotificationDone(notification_level, + DS_TIZEN_POLICY_ERROR_STATE_NONE); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->mSurfaceRes == surface_res); + EXPECT_TRUE(client->mLevel == noti_level); + EXPECT_TRUE(client->mErrorState == TIZEN_POLICY_ERROR_STATE_NONE); +} + +TEST_F(PolicyTest, Ev_PolicySurfaceWindowScreenModeDone) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + uint32_t screen_mode = TIZEN_POLICY_MODE_ALWAYS_ON; + enum ds_tizen_policy_window_screen_mode window_screen_mode = + DS_TIZEN_POLICY_WINDOW_SCREEN_MODE_ALWAYS_ON; + + tizen_policy_set_window_screen_mode(policy_res, surface_res, screen_mode); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->mWindowScreenMode == window_screen_mode); + + policy_surface->SendWindowScreenModeDone(window_screen_mode, + DS_TIZEN_POLICY_ERROR_STATE_NONE); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->mSurfaceRes == surface_res); + EXPECT_TRUE(client->mWindowScreenMode == window_screen_mode); + EXPECT_TRUE(client->mErrorState == TIZEN_POLICY_ERROR_STATE_NONE); +} + +TEST_F(PolicyTest, Ev_PolicySurfaceIconifyStateChanged) +{ + MockPolicySurface *policy_surface; + uint32_t surface_res_id; + bool iconified = true; + bool force = true; + + tizen_policy_iconify(policy_res, surface_res); + client->RoundTrip(); + + surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); + policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); + EXPECT_TRUE(policy_surface->bIconify == true); + + policy_surface->SendIconifyStateChanged(iconified, force); + comp->Process(); + + client->RoundTrip(); + EXPECT_TRUE(client->mSurfaceRes == surface_res); + EXPECT_TRUE(client->mIconified == iconified); + EXPECT_TRUE(client->mForce == force); +} + +TEST_F(PolicyTest, Ev_PolicySurfaceSupportedAuxHits) +{ + // TODO: +} + +TEST_F(PolicyTest, Ev_PolicySurfaceAllowedAuxHint) +{ + // TODO: +} + +TEST_F(PolicyTest, Ev_PolicySurfaceAuxMessage) +{ + // TODO: +} + +TEST_F(PolicyTest, Ev_PolicySurfaceConformantRegion) +{ +} + +TEST_F(PolicyTest, Ev_PolicySurfaceInteractiveModeDone) +{ + // TODO: +} + +TEST_F(PolicyTest, Ev_PolicySurfaceInteractiveResizeDone) +{ + // TODO: +} -- 2.7.4 From 6a86b7c2db782d8dfea4b696c29482fb518606c0 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Sat, 3 Sep 2022 10:12:39 +0900 Subject: [PATCH 05/16] tinyds-tdm: create ds_tizen_policy resource ds_tizen_policy provide the wayland server implementation of tizen_policy_interface. Change-Id: I056fae55b3dcd1b8b9d3a493a6f525cd4704a7f4 --- examples/meson.build | 1 + examples/tinyds-tdm.c | 965 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 965 insertions(+), 1 deletion(-) diff --git a/examples/meson.build b/examples/meson.build index 2d5c09c..6a81cbf 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -33,6 +33,7 @@ executable('tinyds-tdm', deps_libds_tizen_launch, deps_libds_tizen_input_method, deps_libds_tizen_text_input, + deps_libds_tizen_policy, dependency('pixman-1', required: true), dependency('threads', required: true), ], diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 26ff72c..0c9c968 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -30,6 +30,7 @@ #include #include #include +#include #define USE_TDM_BUFFER_QUEUE @@ -84,6 +85,99 @@ struct tinyds_dpms struct wl_listener get_dpms; }; +struct tinyds_policy +{ + struct ds_tizen_policy *policy; + + struct wl_listener destroy; + struct wl_listener get_surface; + struct wl_listener activate_below_by_univeral_id; + struct wl_listener lower_by_universal_id; + struct wl_listener set_transient_for; + struct wl_listener unset_transient_for; + struct wl_listener place_subsurface_below_parent; + struct wl_listener set_subsurface_stand_alone; + struct wl_listener set_background_state; + struct wl_listener unset_background_state; + struct wl_listener add_activate_above_by_universal_id; + struct wl_listener set_appid; + struct wl_listener set_transient_for_below; + + struct wl_list policy_surfaces; +}; + +struct tinyds_policy_surface +{ + struct ds_tizen_policy_surface *policy_surface; + + struct wl_listener destroy; + struct wl_listener get_visibility; + struct wl_listener get_position; + struct wl_listener activate; + struct wl_listener raise; + struct wl_listener lower; + struct wl_listener set_focus_skip; + struct wl_listener unset_focus_skip; + struct wl_listener set_role; + struct wl_listener set_window_type; + struct wl_listener set_conformant; + struct wl_listener unset_conformant; + struct wl_listener get_conformant; + struct wl_listener set_notification_level; + struct wl_listener set_window_screen_mode; + struct wl_listener get_subsurface; + struct wl_listener iconify; + struct wl_listener uniconify; + struct wl_listener add_aux_hint; + struct wl_listener change_aux_hint; + struct wl_listener delete_aux_hint; + struct wl_listener get_supported_aux_hints; + struct wl_listener set_floating_mode; + struct wl_listener unset_floating_mode; + struct wl_listener set_stack_mode; + struct wl_listener get_subsurface_watcher; + struct wl_listener set_parent; + struct wl_listener ack_conformant_region; + struct wl_listener set_video; + struct wl_listener show; + struct wl_listener hide; + struct wl_listener set_parent_with_below; + + struct wl_list visibilities; + struct wl_list positions; + struct wl_list subsurface_watchers; + + struct wl_list link; //tinyds_policy::policy_surfaces +}; + +struct tinyds_policy_visibility +{ + struct ds_tizen_policy_visibility *visibility; + + struct wl_listener destroy; + + struct wl_list link; //tinyds_policy::visibilities +}; + +struct tinyds_policy_position +{ + struct ds_tizen_policy_position *position; + + struct wl_listener destroy; + struct wl_listener set; + + struct wl_list link; //tinyds_policy::positions +}; + +struct tinyds_policy_subsurface_watcher +{ + struct ds_tizen_policy_subsurface_watcher *subsurface_watcher; + + struct wl_listener destroy; + + struct wl_list link; //tinyds_policy::subsurface_watchers +}; + struct tinyds_server { struct ds_tbm_server *tbm_server; @@ -103,6 +197,8 @@ struct tinyds_server struct tinyds_output *output; struct tinyds_dpms *dpms; + struct tinyds_policy *policy; + struct wl_event_source *stdin_source; struct wl_list views; @@ -276,7 +372,7 @@ static void server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev); static void server_add_touch(struct tinyds_server *server, struct ds_input_device *dev); - +static bool new_policy(struct tinyds_server *server); static struct tinyds_view * server_view_at(struct tinyds_server *server, double lx, double ly, double *sx, double *sy); @@ -862,6 +958,9 @@ init_server(struct tinyds_server *server, struct wl_display *display) if (!add_new_dpms(server)) goto err; + if (!new_policy(server)) + goto err; + server->seat = ds_seat_create(display, "seat0" /* arbitrary name */); if (!server->seat) goto err; @@ -2473,3 +2572,867 @@ add_new_input_method_context(struct tinyds_input_method *input_method, return true; } + +static void +visibility_handle_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_visibility *visibility; + + visibility = wl_container_of(listener, visibility, destroy); + + ds_inf("Policy Visibility(%p) destroy", visibility); + + wl_list_remove(&visibility->link); + free(visibility); +} + +static void +position_handle_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_position *position; + + position = wl_container_of(listener, position, destroy); + + ds_inf("Policy Position(%p) destroy", position); + + wl_list_remove(&position->link); + free(position); +} + +static void +position_handle_set(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_position *position; + + position = wl_container_of(listener, position, set); + + ds_inf("Policy Position(%p) set", position); + + // TODO: +} + +static void +subsurface_watcher_handle_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_subsurface_watcher *subsurface_watcher; + + subsurface_watcher = wl_container_of(listener, subsurface_watcher, destroy); + + ds_inf("Policy Subsurface_Watcher(%p) destroy", subsurface_watcher); + + wl_list_remove(&subsurface_watcher->link); + free(subsurface_watcher); +} + +static void +policy_surface_handle_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, destroy); + + ds_inf("Policy Info(%p) destroy", policy_surface); + + wl_list_remove(&policy_surface->link); + free(policy_surface); +} + +static void +policy_surface_handle_get_visibility(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + struct tinyds_policy_visibility *visibility; + struct ds_tizen_event_policy_surface_get_visibility *event; + + policy_surface = wl_container_of(listener, policy_surface, get_visibility); + event = (struct ds_tizen_event_policy_surface_get_visibility *)data; + + ds_inf("Policy Info(%p) get_visibility", policy_surface); + + visibility = calloc(1, sizeof *visibility); + if (!visibility) + return; + + visibility->visibility = event->visibility; + + visibility->destroy.notify = visibility_handle_destroy; + ds_tizen_policy_visibility_add_destroy_listener(visibility->visibility, + &visibility->destroy); + + wl_list_insert(&policy_surface->visibilities, &visibility->link); +} + +static void +policy_surface_handle_get_position(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + struct tinyds_policy_position *position; + struct ds_tizen_event_policy_surface_get_position *event; + + policy_surface = wl_container_of(listener, policy_surface, get_position); + event = (struct ds_tizen_event_policy_surface_get_position *)data; + + ds_inf("Policy Info(%p) get_position", policy_surface); + + position = calloc(1, sizeof *position); + if (!position) + return; + + position->position = event->position; + + position->destroy.notify = position_handle_destroy; + ds_tizen_policy_position_add_destroy_listener(position->position, + &position->destroy); + + position->set.notify = position_handle_set; + ds_tizen_policy_position_add_set_listener(position->position, + &position->set); + + wl_list_insert(&policy_surface->positions, &position->link); +} + +static void +policy_surface_handle_activate(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, activate); + + ds_inf("Policy Info(%p) activate", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_raise(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, raise); + + ds_inf("Policy Info(%p) raise", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_lower(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, raise); + + ds_inf("Policy Info(%p) lower", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_set_focus_skip(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_focus_skip); + + ds_inf("Policy Info(%p) set_focus_skip", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_unset_focus_skip(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, unset_focus_skip); + + ds_inf("Policy Info(%p) unset_focus_skip", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_set_role(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_role); + + ds_inf("Policy Info(%p) set_role", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_set_window_type(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_window_type); + + ds_inf("Policy Info(%p) set_window_type", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_set_conformant(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_conformant); + + ds_inf("Policy Info(%p) set_conformant", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_unset_conformant(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, unset_conformant); + + ds_inf("Policy Info(%p) unset_conformant", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_get_conformant(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, get_conformant); + + ds_inf("Policy Info(%p) get_conformant", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_set_notification_level(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_notification_level); + + ds_inf("Policy Info(%p) set_notification_level", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_set_window_screen_mode(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_window_screen_mode); + + ds_inf("Policy Info(%p) set_window_screen_mode", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_get_subsurface(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, get_subsurface); + + ds_inf("Policy Info(%p) get_subsurface", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_iconify(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, iconify); + + ds_inf("Policy Info(%p) iconify", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_uniconify(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, uniconify); + + ds_inf("Policy Info(%p) uniconify", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_add_aux_hint(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, add_aux_hint); + + ds_inf("Policy Info(%p) add_aux_hint", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_change_aux_hint(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, change_aux_hint); + + ds_inf("Policy Info(%p) change_aux_hint", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_delete_aux_hint(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, delete_aux_hint); + + ds_inf("Policy Info(%p) delete_aux_hint", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_get_supported_aux_hints(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, get_supported_aux_hints); + + ds_inf("Policy Info(%p) get_supported_aux_hints", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_set_floating_mode(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_floating_mode); + + ds_inf("Policy Info(%p) set_floating_mode", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_unset_floating_mode(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, unset_floating_mode); + + ds_inf("Policy Info(%p) unset_floating_mode", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_set_stack_mode(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_stack_mode); + + ds_inf("Policy Info(%p) set_stack_mode", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_get_subsurface_watcher(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + struct tinyds_policy_subsurface_watcher*subsurface_watcher; + struct ds_tizen_event_policy_surface_get_subsurface_watcher *event; + + policy_surface = wl_container_of(listener, policy_surface, get_subsurface_watcher); + event = (struct ds_tizen_event_policy_surface_get_subsurface_watcher *)data; + + ds_inf("Policy Info(%p) get_subsurface_watcher", policy_surface); + + subsurface_watcher = calloc(1, sizeof *subsurface_watcher); + if (!subsurface_watcher) + return; + + subsurface_watcher->subsurface_watcher = event->subsurface_watcher; + + subsurface_watcher->destroy.notify = subsurface_watcher_handle_destroy; + ds_tizen_policy_subsurface_watcher_add_destroy_listener(subsurface_watcher->subsurface_watcher, + &subsurface_watcher->destroy); + + wl_list_insert(&policy_surface->subsurface_watchers, &subsurface_watcher->link); +} + +static void +policy_surface_handle_set_parent(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_parent); + + ds_inf("Policy Info(%p) set_parent", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_ack_conformant_region(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, ack_conformant_region); + + ds_inf("Policy Info(%p) ack_conformant_region", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_set_video(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_video); + + ds_inf("Policy Info(%p) set_video", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_show(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, show); + + ds_inf("Policy Info(%p) show", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_hide(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, hide); + + ds_inf("Policy Info(%p) hide", policy_surface); + + // TODO: +} + +static void +policy_surface_handle_set_parent_with_below(struct wl_listener *listener, void *data) +{ + struct tinyds_policy_surface *policy_surface; + + policy_surface = wl_container_of(listener, policy_surface, set_parent_with_below); + + ds_inf("Policy Info(%p) set_parent_with_below", policy_surface); + + // TODO: +} + +static void +policy_handle_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, destroy); + + ds_inf("Policy(%p) destroy", policy); + + free(policy); +} + +static void +policy_handle_get_surface(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + struct tinyds_policy_surface *policy_surface; + struct ds_tizen_event_policy_get_surface *event; + + policy = wl_container_of(listener, policy, get_surface); + event = (struct ds_tizen_event_policy_get_surface *)data; + + ds_inf("Policy(%p) get_surface", policy); + + policy_surface = calloc(1, sizeof *policy_surface); + if (!policy_surface) + return; + + policy_surface->policy_surface = event->policy_surface; + + policy_surface->destroy.notify = policy_surface_handle_destroy; + ds_tizen_policy_surface_add_destroy_listener(policy_surface->policy_surface, + &policy_surface->destroy); + + policy_surface->get_visibility.notify = policy_surface_handle_get_visibility; + ds_tizen_policy_surface_add_get_visibility_listener(policy_surface->policy_surface, + &policy_surface->get_visibility); + + policy_surface->get_position.notify = policy_surface_handle_get_position; + ds_tizen_policy_surface_add_get_position_listener(policy_surface->policy_surface, + &policy_surface->get_position); + + policy_surface->activate.notify = policy_surface_handle_activate; + ds_tizen_policy_surface_add_activate_listener(policy_surface->policy_surface, + &policy_surface->activate); + + policy_surface->raise.notify = policy_surface_handle_raise; + ds_tizen_policy_surface_add_raise_listener(policy_surface->policy_surface, + &policy_surface->raise); + + policy_surface->lower.notify = policy_surface_handle_lower; + ds_tizen_policy_surface_add_lower_listener(policy_surface->policy_surface, + &policy_surface->lower); + + policy_surface->set_focus_skip.notify = policy_surface_handle_set_focus_skip; + ds_tizen_policy_surface_add_set_focus_skip_listener(policy_surface->policy_surface, + &policy_surface->set_focus_skip); + + policy_surface->unset_focus_skip.notify = policy_surface_handle_unset_focus_skip; + ds_tizen_policy_surface_add_unset_focus_skip_listener(policy_surface->policy_surface, + &policy_surface->unset_focus_skip); + + policy_surface->set_role.notify = policy_surface_handle_set_role; + ds_tizen_policy_surface_add_set_role_listener(policy_surface->policy_surface, + &policy_surface->set_role); + + policy_surface->set_window_type.notify = policy_surface_handle_set_window_type; + ds_tizen_policy_surface_add_set_window_type_listener(policy_surface->policy_surface, + &policy_surface->set_window_type); + + policy_surface->set_conformant.notify = policy_surface_handle_set_conformant; + ds_tizen_policy_surface_add_set_conformant_listener(policy_surface->policy_surface, + &policy_surface->set_conformant); + + policy_surface->unset_conformant.notify = policy_surface_handle_unset_conformant; + ds_tizen_policy_surface_add_unset_conformant_listener(policy_surface->policy_surface, + &policy_surface->unset_conformant); + + policy_surface->get_conformant.notify = policy_surface_handle_get_conformant; + ds_tizen_policy_surface_add_get_conformant_listener(policy_surface->policy_surface, + &policy_surface->get_conformant); + + policy_surface->set_notification_level.notify = + policy_surface_handle_set_notification_level; + ds_tizen_policy_surface_add_set_notification_level_listener( + policy_surface->policy_surface, &policy_surface->set_notification_level); + + policy_surface->set_window_screen_mode.notify = + policy_surface_handle_set_window_screen_mode; + ds_tizen_policy_surface_add_set_window_screen_mode_listener( + policy_surface->policy_surface, &policy_surface->set_window_screen_mode); + + policy_surface->get_subsurface.notify = policy_surface_handle_get_subsurface; + ds_tizen_policy_surface_add_get_subsurface_listener(policy_surface->policy_surface, + &policy_surface->get_subsurface); + + policy_surface->iconify.notify = policy_surface_handle_iconify; + ds_tizen_policy_surface_add_iconify_listener(policy_surface->policy_surface, + &policy_surface->iconify); + + policy_surface->uniconify.notify = policy_surface_handle_uniconify; + ds_tizen_policy_surface_add_uniconify_listener(policy_surface->policy_surface, + &policy_surface->uniconify); + + policy_surface->add_aux_hint.notify = policy_surface_handle_add_aux_hint; + ds_tizen_policy_surface_add_add_aux_hint_listener(policy_surface->policy_surface, + &policy_surface->add_aux_hint); + + policy_surface->change_aux_hint.notify = policy_surface_handle_change_aux_hint; + ds_tizen_policy_surface_add_change_aux_hint_listener(policy_surface->policy_surface, + &policy_surface->change_aux_hint); + + policy_surface->delete_aux_hint.notify = policy_surface_handle_delete_aux_hint; + ds_tizen_policy_surface_add_delete_aux_hint_listener(policy_surface->policy_surface, + &policy_surface->delete_aux_hint); + + policy_surface->get_supported_aux_hints.notify = + policy_surface_handle_get_supported_aux_hints; + ds_tizen_policy_surface_add_get_supported_aux_hints_listener( + policy_surface->policy_surface, &policy_surface->get_supported_aux_hints); + + policy_surface->set_floating_mode.notify = + policy_surface_handle_set_floating_mode; + ds_tizen_policy_surface_add_set_floating_mode_listener( + policy_surface->policy_surface, &policy_surface->set_floating_mode); + + policy_surface->unset_floating_mode.notify = + policy_surface_handle_unset_floating_mode; + ds_tizen_policy_surface_add_unset_floating_mode_listener( + policy_surface->policy_surface, &policy_surface->unset_floating_mode); + + policy_surface->set_stack_mode.notify = policy_surface_handle_set_stack_mode; + ds_tizen_policy_surface_add_set_stack_mode_listener(policy_surface->policy_surface, + &policy_surface->set_stack_mode); + + policy_surface->get_subsurface_watcher.notify = + policy_surface_handle_get_subsurface_watcher; + ds_tizen_policy_surface_add_get_subsurface_watcher_listener( + policy_surface->policy_surface, &policy_surface->get_subsurface_watcher); + + policy_surface->set_parent.notify = policy_surface_handle_set_parent; + ds_tizen_policy_surface_add_set_parent_listener(policy_surface->policy_surface, + &policy_surface->set_parent); + + policy_surface->ack_conformant_region.notify = + policy_surface_handle_ack_conformant_region; + ds_tizen_policy_surface_add_ack_conformant_region_listener( + policy_surface->policy_surface, &policy_surface->ack_conformant_region); + + policy_surface->set_video.notify = policy_surface_handle_set_video; + ds_tizen_policy_surface_add_set_video_listener(policy_surface->policy_surface, + &policy_surface->set_video); + + policy_surface->show.notify = policy_surface_handle_show; + ds_tizen_policy_surface_add_show_listener(policy_surface->policy_surface, + &policy_surface->show); + + policy_surface->hide.notify = policy_surface_handle_hide; + ds_tizen_policy_surface_add_hide_listener(policy_surface->policy_surface, + &policy_surface->hide); + + policy_surface->set_parent_with_below.notify = + policy_surface_handle_set_parent_with_below; + ds_tizen_policy_surface_add_set_parent_with_below_listener( + policy_surface->policy_surface, &policy_surface->set_parent_with_below); + + + wl_list_init(&policy_surface->visibilities); + wl_list_init(&policy_surface->positions); + wl_list_init(&policy_surface->subsurface_watchers); + + wl_list_insert(&policy->policy_surfaces, &policy_surface->link); +} + +static void +policy_handle_activate_below_by_univeral_id(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, activate_below_by_univeral_id); + + ds_inf("Policy(%p) activate_below_by_univeral_id", policy); + + // TODO: +} + +static void +policy_handle_lower_by_universal_id(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, lower_by_universal_id); + + ds_inf("Policy(%p) lower_by_universal_id", policy); + + // TODO: +} + +static void +policy_handle_set_transient_for(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, set_transient_for); + + ds_inf("Policy(%p) set_transient_for", policy); + + // TODO: +} + +static void +policy_handle_unset_transient_for(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, unset_transient_for); + + ds_inf("Policy(%p) unset_transient_for", policy); + + // TODO: +} + +static void +policy_handle_place_subsurface_below_parent(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, place_subsurface_below_parent); + + ds_inf("Policy(%p) place_subsurface_below_parent", policy); + + // TODO: +} + +static void +policy_handle_set_subsurface_stand_alone(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, set_subsurface_stand_alone); + + ds_inf("Policy(%p) set_subsurface_stand_alone", policy); + + // TODO: +} + +static void +policy_handle_set_background_state(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, set_background_state); + + ds_inf("Policy(%p) set_background_state", policy); + + // TODO: +} + +static void +policy_handle_unset_background_state(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, unset_background_state); + + ds_inf("Policy(%p) unset_background_state", policy); + + // TODO: +} + +static void +policy_handle_add_activate_above_by_universal_id(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, add_activate_above_by_universal_id); + + ds_inf("Policy(%p) add_activate_above_by_universal_id", policy); + + // TODO: +} + +static void +policy_handle_set_appid(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, set_appid); + + ds_inf("Policy(%p) set_appid", policy); + + // TODO: +} + +static void +policy_handle_set_transient_for_below(struct wl_listener *listener, void *data) +{ + struct tinyds_policy *policy; + + policy = wl_container_of(listener, policy, set_transient_for_below); + + ds_inf("Policy(%p) set_transient_for_below", policy); + + // TODO: +} + +static bool +new_policy(struct tinyds_server *server) +{ + struct tinyds_policy *policy; + + policy = calloc(1, sizeof *policy); + if (!policy) + return false; + + policy->policy = ds_tizen_policy_create(server->display); + if (!policy->policy) { + free(policy); + ds_err("Could not create ds_tizen_policy"); + return false; + } + + policy->destroy.notify = policy_handle_destroy; + ds_tizen_policy_add_destroy_listener(policy->policy, &policy->destroy); + + policy->get_surface.notify = policy_handle_get_surface; + ds_tizen_policy_add_get_surface_listener(policy->policy, &policy->get_surface); + + policy->activate_below_by_univeral_id.notify = + policy_handle_activate_below_by_univeral_id; + ds_tizen_policy_add_activate_below_by_univeral_id_listener(policy->policy, + &policy->activate_below_by_univeral_id); + + policy->lower_by_universal_id.notify = policy_handle_lower_by_universal_id; + ds_tizen_policy_add_lower_by_universal_id_listener(policy->policy, + &policy->lower_by_universal_id); + + policy->set_transient_for.notify = policy_handle_set_transient_for; + ds_tizen_policy_add_set_transient_for_listener(policy->policy, + &policy->set_transient_for); + + policy->unset_transient_for.notify = policy_handle_unset_transient_for; + ds_tizen_policy_add_unset_transient_for_listener(policy->policy, + &policy->unset_transient_for); + + policy->place_subsurface_below_parent.notify = + policy_handle_place_subsurface_below_parent; + ds_tizen_policy_add_place_subsurface_below_parent_listener(policy->policy, + &policy->place_subsurface_below_parent); + + policy->set_subsurface_stand_alone.notify = + policy_handle_set_subsurface_stand_alone; + ds_tizen_policy_add_set_subsurface_stand_alone_listener(policy->policy, + &policy->set_subsurface_stand_alone); + + policy->set_background_state.notify = policy_handle_set_background_state; + ds_tizen_policy_add_set_background_state_listener(policy->policy, + &policy->destroy); + + policy->unset_background_state.notify = policy_handle_unset_background_state; + ds_tizen_policy_add_unset_background_state_listener(policy->policy, + &policy->unset_background_state); + + policy->add_activate_above_by_universal_id.notify = + policy_handle_add_activate_above_by_universal_id; + ds_tizen_policy_add_activate_above_by_universal_id_listener(policy->policy, + &policy->add_activate_above_by_universal_id); + + policy->set_appid.notify = policy_handle_set_appid; + ds_tizen_policy_add_set_appid_listener(policy->policy, &policy->set_appid); + + policy->set_transient_for_below.notify = + policy_handle_set_transient_for_below; + ds_tizen_policy_add_set_transient_for_below_listener(policy->policy, + &policy->set_transient_for_below); + + wl_list_init(&policy->policy_surfaces); + + server->policy = policy; + + ds_inf("Policy (%p) created", policy); + + return true; +} -- 2.7.4 From 0db5a1246111bf1e3f0a17772bc92d7b9cc0db01 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 7 Sep 2022 15:15:22 +0900 Subject: [PATCH 06/16] tizen_policy: change get_surface to new_surface change the symbol name Change-Id: Icc7e8193d85abed07f2b1306f2e69ed3ffd384b2 --- examples/tinyds-tdm.c | 16 ++++++++-------- include/libds-tizen/policy.h | 4 ++-- src/policy/policy.c | 12 ++++++------ tests/tc_policy.cpp | 28 ++++++++++++++-------------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 0c9c968..30102fe 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -90,7 +90,7 @@ struct tinyds_policy struct ds_tizen_policy *policy; struct wl_listener destroy; - struct wl_listener get_surface; + struct wl_listener new_surface; struct wl_listener activate_below_by_univeral_id; struct wl_listener lower_by_universal_id; struct wl_listener set_transient_for; @@ -3065,16 +3065,16 @@ policy_handle_destroy(struct wl_listener *listener, void *data) } static void -policy_handle_get_surface(struct wl_listener *listener, void *data) +policy_handle_new_surface(struct wl_listener *listener, void *data) { struct tinyds_policy *policy; struct tinyds_policy_surface *policy_surface; - struct ds_tizen_event_policy_get_surface *event; + struct ds_tizen_event_policy_new_surface *event; - policy = wl_container_of(listener, policy, get_surface); - event = (struct ds_tizen_event_policy_get_surface *)data; + policy = wl_container_of(listener, policy, new_surface); + event = (struct ds_tizen_event_policy_new_surface *)data; - ds_inf("Policy(%p) get_surface", policy); + ds_inf("Policy(%p) new_surface", policy); policy_surface = calloc(1, sizeof *policy_surface); if (!policy_surface) @@ -3377,8 +3377,8 @@ new_policy(struct tinyds_server *server) policy->destroy.notify = policy_handle_destroy; ds_tizen_policy_add_destroy_listener(policy->policy, &policy->destroy); - policy->get_surface.notify = policy_handle_get_surface; - ds_tizen_policy_add_get_surface_listener(policy->policy, &policy->get_surface); + policy->new_surface.notify = policy_handle_new_surface; + ds_tizen_policy_add_new_surface_listener(policy->policy, &policy->new_surface); policy->activate_below_by_univeral_id.notify = policy_handle_activate_below_by_univeral_id; diff --git a/include/libds-tizen/policy.h b/include/libds-tizen/policy.h index f95e7cf..4d27c1f 100644 --- a/include/libds-tizen/policy.h +++ b/include/libds-tizen/policy.h @@ -83,7 +83,7 @@ enum ds_tizen_policy_visibility_type }; // policy event structures -struct ds_tizen_event_policy_get_surface +struct ds_tizen_event_policy_new_surface { struct ds_tizen_policy *policy; struct ds_tizen_policy_surface *policy_surface; @@ -352,7 +352,7 @@ ds_tizen_policy_add_destroy_listener(struct ds_tizen_policy *policy, struct wl_listener *listener); void -ds_tizen_policy_add_get_surface_listener( +ds_tizen_policy_add_new_surface_listener( struct ds_tizen_policy *policy, struct wl_listener *listener); diff --git a/src/policy/policy.c b/src/policy/policy.c index b349d8b..057b4f0 100644 --- a/src/policy/policy.c +++ b/src/policy/policy.c @@ -27,7 +27,7 @@ struct ds_tizen_policy struct { struct wl_signal destroy; - struct wl_signal get_surface; + struct wl_signal new_surface; struct wl_signal activate_below_by_univeral_id; struct wl_signal lower_by_universal_id; struct wl_signal set_transient_for; @@ -198,7 +198,7 @@ ds_tizen_policy_create(struct wl_display *display) } wl_signal_init(&policy->events.destroy); - wl_signal_init(&policy->events.get_surface); + wl_signal_init(&policy->events.new_surface); wl_signal_init(&policy->events.activate_below_by_univeral_id); wl_signal_init(&policy->events.lower_by_universal_id); wl_signal_init(&policy->events.set_transient_for); @@ -225,11 +225,11 @@ ds_tizen_policy_add_destroy_listener( } WL_EXPORT void -ds_tizen_policy_add_get_surface_listener( +ds_tizen_policy_add_new_surface_listener( struct ds_tizen_policy *policy, struct wl_listener *listener) { - wl_signal_add(&policy->events.get_surface, listener); + wl_signal_add(&policy->events.new_surface, listener); } WL_EXPORT void @@ -981,11 +981,11 @@ tizen_policy_client_get_surface(struct wl_resource *resource, wl_list_insert(&client->policy_surfaces, &policy_surface->link); - struct ds_tizen_event_policy_get_surface event = { + struct ds_tizen_event_policy_new_surface event = { .policy = client->policy, .policy_surface = policy_surface, }; - wl_signal_emit(&client->policy->events.get_surface, &event); + wl_signal_emit(&client->policy->events.new_surface, &event); return policy_surface; } diff --git a/tests/tc_policy.cpp b/tests/tc_policy.cpp index e099014..dc3da43 100644 --- a/tests/tc_policy.cpp +++ b/tests/tc_policy.cpp @@ -1151,7 +1151,7 @@ public: // initialize the flags to check bDestroyed = false; - bGetPolicySurface = false; + bNewPolicySurface = false; } ~MockPolicyCompositor() @@ -1195,12 +1195,12 @@ public: &mockComp->mDestroyListener); // policy listeners - mockComp->mGetPolicySurfaceListener.notify = - MockPolicyCompositor::GetPolicySurfaceCallback; - mockComp->mGetPolicySurfaceListener.parent = mockComp; - ds_tizen_policy_add_get_surface_listener( + mockComp->mNewPolicySurfaceListener.notify = + MockPolicyCompositor::NewPolicySurfaceCallback; + mockComp->mNewPolicySurfaceListener.parent = mockComp; + ds_tizen_policy_add_new_surface_listener( mockComp->mPolicy, - &mockComp->mGetPolicySurfaceListener); + &mockComp->mNewPolicySurfaceListener); mockComp->mActivateBelowByUniversalIdListener.notify = MockPolicyCompositor::ActivateBelowByUniversalIdCallback; @@ -1302,21 +1302,21 @@ public: mockComp->bDestroyed = true; } - static void GetPolicySurfaceCallback(struct wl_listener *listener, + static void NewPolicySurfaceCallback(struct wl_listener *listener, void *data) { ds_inf("%s", __func__); MockPolicyCompositor *mockComp = - reinterpret_cast(listener)->parent; - struct ds_tizen_event_policy_get_surface *event = - static_cast(data); + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_new_surface *event = + static_cast(data); struct ds_tizen_policy_surface *policy_surface = event->policy_surface; ds_inf("%s: mockComp(%p), policy_surface(%p)", __func__, mockComp, policy_surface); - mockComp->bGetPolicySurface = true; + mockComp->bNewPolicySurface = true; MockPolicySurface *policySurface = new MockPolicySurface(event->policy_surface); mockComp->mPolicySurfaces.push_back(policySurface); @@ -1490,7 +1490,7 @@ public: public: bool bDestroyed; - bool bGetPolicySurface; + bool bNewPolicySurface; int32_t mPid; std::string mAppId; uint32_t mUniversalId; @@ -1518,10 +1518,10 @@ private: DestroyListener mDestroyListener; // policy listener structure - struct GetPolicySurfaceListener : ::wl_listener { + struct NewPolicySurfaceListener : ::wl_listener { MockPolicyCompositor *parent; }; - GetPolicySurfaceListener mGetPolicySurfaceListener; + NewPolicySurfaceListener mNewPolicySurfaceListener; struct ActivateBelowByUniversalIdListener: ::wl_listener { MockPolicyCompositor *parent; -- 2.7.4 From 4f0015143c107a8ef4418be497cb18d6a3887c18 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 7 Sep 2022 15:17:04 +0900 Subject: [PATCH 07/16] tizen_policy: change the get_visibility to new_visibility change the symbol name Change-Id: Ic8c6fecd1f51b3aef6f7f0ca328f5805159f489d --- examples/tinyds-tdm.c | 18 ++++++++--------- include/libds-tizen/policy.h | 4 ++-- src/policy/policy.c | 12 ++++++------ tests/tc_policy.cpp | 46 ++++++++++++++++++++++---------------------- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 30102fe..60ba931 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -111,7 +111,7 @@ struct tinyds_policy_surface struct ds_tizen_policy_surface *policy_surface; struct wl_listener destroy; - struct wl_listener get_visibility; + struct wl_listener new_visibility; struct wl_listener get_position; struct wl_listener activate; struct wl_listener raise; @@ -2638,16 +2638,16 @@ policy_surface_handle_destroy(struct wl_listener *listener, void *data) } static void -policy_surface_handle_get_visibility(struct wl_listener *listener, void *data) +policy_surface_handle_new_visibility(struct wl_listener *listener, void *data) { struct tinyds_policy_surface *policy_surface; struct tinyds_policy_visibility *visibility; - struct ds_tizen_event_policy_surface_get_visibility *event; + struct ds_tizen_event_policy_surface_new_visibility *event; - policy_surface = wl_container_of(listener, policy_surface, get_visibility); - event = (struct ds_tizen_event_policy_surface_get_visibility *)data; + policy_surface = wl_container_of(listener, policy_surface, new_visibility); + event = (struct ds_tizen_event_policy_surface_new_visibility *)data; - ds_inf("Policy Info(%p) get_visibility", policy_surface); + ds_inf("Policy Info(%p) new_visibility", policy_surface); visibility = calloc(1, sizeof *visibility); if (!visibility) @@ -3086,9 +3086,9 @@ policy_handle_new_surface(struct wl_listener *listener, void *data) ds_tizen_policy_surface_add_destroy_listener(policy_surface->policy_surface, &policy_surface->destroy); - policy_surface->get_visibility.notify = policy_surface_handle_get_visibility; - ds_tizen_policy_surface_add_get_visibility_listener(policy_surface->policy_surface, - &policy_surface->get_visibility); + policy_surface->new_visibility.notify = policy_surface_handle_new_visibility; + ds_tizen_policy_surface_add_new_visibility_listener(policy_surface->policy_surface, + &policy_surface->new_visibility); policy_surface->get_position.notify = policy_surface_handle_get_position; ds_tizen_policy_surface_add_get_position_listener(policy_surface->policy_surface, diff --git a/include/libds-tizen/policy.h b/include/libds-tizen/policy.h index 4d27c1f..2dc87e4 100644 --- a/include/libds-tizen/policy.h +++ b/include/libds-tizen/policy.h @@ -161,7 +161,7 @@ struct ds_tizen_event_policy_set_transient_for_below }; // policy policy_surface event structures -struct ds_tizen_event_policy_surface_get_visibility +struct ds_tizen_event_policy_surface_new_visibility { struct ds_tizen_policy_surface *policy_surface; struct ds_tizen_policy_visibility *visibility; @@ -418,7 +418,7 @@ ds_tizen_policy_surface_add_destroy_listener( struct wl_listener *listener); void -ds_tizen_policy_surface_add_get_visibility_listener( +ds_tizen_policy_surface_add_new_visibility_listener( struct ds_tizen_policy_surface *policy_surface, struct wl_listener *listener); diff --git a/src/policy/policy.c b/src/policy/policy.c index 057b4f0..5bf32a4 100644 --- a/src/policy/policy.c +++ b/src/policy/policy.c @@ -77,7 +77,7 @@ struct ds_tizen_policy_surface struct { struct wl_signal destroy; - struct wl_signal get_visibility; + struct wl_signal new_visibility; struct wl_signal get_position; struct wl_signal activate; struct wl_signal raise; @@ -329,11 +329,11 @@ ds_tizen_policy_surface_add_destroy_listener( } WL_EXPORT void -ds_tizen_policy_surface_add_get_visibility_listener( +ds_tizen_policy_surface_add_new_visibility_listener( struct ds_tizen_policy_surface *policy_surface, struct wl_listener *listener) { - wl_signal_add(&policy_surface->events.get_visibility, listener); + wl_signal_add(&policy_surface->events.new_visibility, listener); } WL_EXPORT void @@ -947,7 +947,7 @@ tizen_policy_client_get_surface(struct wl_resource *resource, wl_list_init(&policy_surface->subsurface_watchers); wl_signal_init(&policy_surface->events.destroy); - wl_signal_init(&policy_surface->events.get_visibility); + wl_signal_init(&policy_surface->events.new_visibility); wl_signal_init(&policy_surface->events.get_position); wl_signal_init(&policy_surface->events.activate); wl_signal_init(&policy_surface->events.raise); @@ -1076,11 +1076,11 @@ policy_handle_get_visibility(struct wl_client *wl_client, struct wl_resource *re &visibility_impl, visibility, _tizen_policy_visibility_handle_destroy); - struct ds_tizen_event_policy_surface_get_visibility event = { + struct ds_tizen_event_policy_surface_new_visibility event = { .policy_surface = policy_surface, .visibility = visibility, }; - wl_signal_emit(&policy_surface->events.get_visibility, &event); + wl_signal_emit(&policy_surface->events.new_visibility, &event); } static void diff --git a/tests/tc_policy.cpp b/tests/tc_policy.cpp index dc3da43..f8e2d2a 100644 --- a/tests/tc_policy.cpp +++ b/tests/tc_policy.cpp @@ -246,10 +246,10 @@ public: ds_tizen_policy_surface_add_destroy_listener(policy_surface, &mDestroyListener); // policy_surface listeners - mGetVisibilityListener.notify = MockPolicySurface::GetVisibilityCallback; - mGetVisibilityListener.parent = this; - ds_tizen_policy_surface_add_get_visibility_listener(policy_surface, - &mGetVisibilityListener); + mNewVisibilityListener.notify = MockPolicySurface::NewVisibilityCallback; + mNewVisibilityListener.parent = this; + ds_tizen_policy_surface_add_new_visibility_listener(policy_surface, + &mNewVisibilityListener); mGetPositionListener.notify = MockPolicySurface::GetPositionCallback; mGetPositionListener.parent = this; @@ -405,9 +405,9 @@ public: { ds_inf("%s", __func__); - if (mGetVisibilityListener.notify) { - wl_list_remove(&mGetVisibilityListener.link); - mGetVisibilityListener.notify = nullptr; + if (mNewVisibilityListener.notify) { + wl_list_remove(&mNewVisibilityListener.link); + mNewVisibilityListener.notify = nullptr; } if (mDestroyListener.notify) { @@ -440,17 +440,17 @@ public: policySurface->bDestroyed = true; } - static void GetVisibilityCallback(struct wl_listener *listener, void *data) + static void NewVisibilityCallback(struct wl_listener *listener, void *data) { MockPolicySurface *policySurface = - reinterpret_cast(listener)->parent; - struct ds_tizen_event_policy_surface_get_visibility *event = - static_cast(data); + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_new_visibility *event = + static_cast(data); EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); EXPECT_TRUE(event->visibility != NULL); - policySurface->bGetVisibility = true; + policySurface->bNewVisibility = true; MockPolicyVisibility *policyVisibility = new MockPolicyVisibility(event->visibility); @@ -840,7 +840,7 @@ public: return wl_resource_get_id(surface_res); } - MockPolicyVisibility *GetVisibility() + MockPolicyVisibility *NewVisibility() { return mPolicyVisibility; } @@ -901,7 +901,7 @@ public: public: bool bDestroyed; - bool bGetVisibility; + bool bNewVisibility; bool bGetPosition; bool bActivate; bool bRaise; @@ -941,10 +941,10 @@ private: DestroyListener mDestroyListener; // policy policy_surface listener structure - struct GetVisibilityListener : ::wl_listener { + struct NewVisibilityListener : ::wl_listener { MockPolicySurface *parent; }; - GetVisibilityListener mGetVisibilityListener; + NewVisibilityListener mNewVisibilityListener; struct GetPositionListener : ::wl_listener { MockPolicySurface *parent; @@ -2177,7 +2177,7 @@ tizen_visibility_listener visibility_cb_listener = .changed = client_tizen_visibility_cb_changed, }; -TEST_F(PolicyTest, Req_PolicySurfaceGetVisibility) +TEST_F(PolicyTest, Req_PolicySurfaceNewVisibility) { MockPolicySurface *policy_surface; MockPolicyVisibility *visibility; @@ -2193,9 +2193,9 @@ TEST_F(PolicyTest, Req_PolicySurfaceGetVisibility) surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); - EXPECT_TRUE(policy_surface->bGetVisibility); + EXPECT_TRUE(policy_surface->bNewVisibility); - visibility = policy_surface->GetVisibility(); + visibility = policy_surface->NewVisibility(); tizen_visibility_destroy(visibility_res); client->RoundTrip(); @@ -2221,9 +2221,9 @@ TEST_F(PolicyTest, Ev_VisibilityNotify) surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); - EXPECT_TRUE(policy_surface->bGetVisibility); + EXPECT_TRUE(policy_surface->bNewVisibility); - visibility = policy_surface->GetVisibility(); + visibility = policy_surface->NewVisibility(); visibility->SendNotify(type); comp->Process(); @@ -2256,9 +2256,9 @@ TEST_F(PolicyTest, Ev_VisibilityChanged) surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); - EXPECT_TRUE(policy_surface->bGetVisibility); + EXPECT_TRUE(policy_surface->bNewVisibility); - visibility = policy_surface->GetVisibility(); + visibility = policy_surface->NewVisibility(); visibility->SendChanged(type, option); comp->Process(); -- 2.7.4 From 424dccb4e356b919f247c4b2e87862d09dccc128 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 7 Sep 2022 15:18:33 +0900 Subject: [PATCH 08/16] change the get_position to new_position change the symbol names Change-Id: I0b5f095ad75aa59f92ba90d9aa0dd1378309286c --- examples/tinyds-tdm.c | 18 +++++++++--------- include/libds-tizen/policy.h | 4 ++-- src/policy/policy.c | 12 ++++++------ tests/tc_policy.cpp | 38 +++++++++++++++++++------------------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 60ba931..d0cac7d 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -112,7 +112,7 @@ struct tinyds_policy_surface struct wl_listener destroy; struct wl_listener new_visibility; - struct wl_listener get_position; + struct wl_listener new_position; struct wl_listener activate; struct wl_listener raise; struct wl_listener lower; @@ -2663,16 +2663,16 @@ policy_surface_handle_new_visibility(struct wl_listener *listener, void *data) } static void -policy_surface_handle_get_position(struct wl_listener *listener, void *data) +policy_surface_handle_new_position(struct wl_listener *listener, void *data) { struct tinyds_policy_surface *policy_surface; struct tinyds_policy_position *position; - struct ds_tizen_event_policy_surface_get_position *event; + struct ds_tizen_event_policy_surface_new_position *event; - policy_surface = wl_container_of(listener, policy_surface, get_position); - event = (struct ds_tizen_event_policy_surface_get_position *)data; + policy_surface = wl_container_of(listener, policy_surface, new_position); + event = (struct ds_tizen_event_policy_surface_new_position *)data; - ds_inf("Policy Info(%p) get_position", policy_surface); + ds_inf("Policy Info(%p) new_position", policy_surface); position = calloc(1, sizeof *position); if (!position) @@ -3090,9 +3090,9 @@ policy_handle_new_surface(struct wl_listener *listener, void *data) ds_tizen_policy_surface_add_new_visibility_listener(policy_surface->policy_surface, &policy_surface->new_visibility); - policy_surface->get_position.notify = policy_surface_handle_get_position; - ds_tizen_policy_surface_add_get_position_listener(policy_surface->policy_surface, - &policy_surface->get_position); + policy_surface->new_position.notify = policy_surface_handle_new_position; + ds_tizen_policy_surface_add_new_position_listener(policy_surface->policy_surface, + &policy_surface->new_position); policy_surface->activate.notify = policy_surface_handle_activate; ds_tizen_policy_surface_add_activate_listener(policy_surface->policy_surface, diff --git a/include/libds-tizen/policy.h b/include/libds-tizen/policy.h index 2dc87e4..dd3d313 100644 --- a/include/libds-tizen/policy.h +++ b/include/libds-tizen/policy.h @@ -167,7 +167,7 @@ struct ds_tizen_event_policy_surface_new_visibility struct ds_tizen_policy_visibility *visibility; }; -struct ds_tizen_event_policy_surface_get_position +struct ds_tizen_event_policy_surface_new_position { struct ds_tizen_policy_surface *policy_surface; struct ds_tizen_policy_position *position; @@ -423,7 +423,7 @@ ds_tizen_policy_surface_add_new_visibility_listener( struct wl_listener *listener); void -ds_tizen_policy_surface_add_get_position_listener( +ds_tizen_policy_surface_add_new_position_listener( struct ds_tizen_policy_surface *policy_surface, struct wl_listener *listener); diff --git a/src/policy/policy.c b/src/policy/policy.c index 5bf32a4..87cd4a1 100644 --- a/src/policy/policy.c +++ b/src/policy/policy.c @@ -78,7 +78,7 @@ struct ds_tizen_policy_surface struct { struct wl_signal destroy; struct wl_signal new_visibility; - struct wl_signal get_position; + struct wl_signal new_position; struct wl_signal activate; struct wl_signal raise; struct wl_signal lower; @@ -337,11 +337,11 @@ ds_tizen_policy_surface_add_new_visibility_listener( } WL_EXPORT void -ds_tizen_policy_surface_add_get_position_listener( +ds_tizen_policy_surface_add_new_position_listener( struct ds_tizen_policy_surface *policy_surface, struct wl_listener *listener) { - wl_signal_add(&policy_surface->events.get_position, listener); + wl_signal_add(&policy_surface->events.new_position, listener); } WL_EXPORT void @@ -948,7 +948,7 @@ tizen_policy_client_get_surface(struct wl_resource *resource, wl_signal_init(&policy_surface->events.destroy); wl_signal_init(&policy_surface->events.new_visibility); - wl_signal_init(&policy_surface->events.get_position); + wl_signal_init(&policy_surface->events.new_position); wl_signal_init(&policy_surface->events.activate); wl_signal_init(&policy_surface->events.raise); wl_signal_init(&policy_surface->events.lower); @@ -1167,11 +1167,11 @@ policy_handle_get_position(struct wl_client *wl_client, struct wl_resource *reso &position_impl, position, _tizen_policy_position_handle_destroy); - struct ds_tizen_event_policy_surface_get_position event = { + struct ds_tizen_event_policy_surface_new_position event = { .policy_surface = policy_surface, .position = position, }; - wl_signal_emit(&policy_surface->events.get_position, &event); + wl_signal_emit(&policy_surface->events.new_position, &event); } static void diff --git a/tests/tc_policy.cpp b/tests/tc_policy.cpp index f8e2d2a..dd2296f 100644 --- a/tests/tc_policy.cpp +++ b/tests/tc_policy.cpp @@ -251,10 +251,10 @@ public: ds_tizen_policy_surface_add_new_visibility_listener(policy_surface, &mNewVisibilityListener); - mGetPositionListener.notify = MockPolicySurface::GetPositionCallback; - mGetPositionListener.parent = this; - ds_tizen_policy_surface_add_get_position_listener(policy_surface, - &mGetPositionListener); + mNewPositionListener.notify = MockPolicySurface::NewPositionCallback; + mNewPositionListener.parent = this; + ds_tizen_policy_surface_add_new_position_listener(policy_surface, + &mNewPositionListener); mActivateListener.notify = MockPolicySurface::ActivateCallback; mActivateListener.parent = this; @@ -458,17 +458,17 @@ public: policySurface->mPolicyVisibility = policyVisibility; } - static void GetPositionCallback(struct wl_listener *listener, void *data) + static void NewPositionCallback(struct wl_listener *listener, void *data) { MockPolicySurface *policySurface = - reinterpret_cast(listener)->parent; - struct ds_tizen_event_policy_surface_get_position *event = - static_cast(data); + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_new_position *event = + static_cast(data); EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); EXPECT_TRUE(event->position != NULL); - policySurface->bGetPosition = true; + policySurface->bNewPosition = true; MockPolicyPosition *policyPosition = new MockPolicyPosition(event->position); @@ -845,7 +845,7 @@ public: return mPolicyVisibility; } - MockPolicyPosition *GetPosition() + MockPolicyPosition *NewPosition() { return mPolicyPosition; } @@ -902,7 +902,7 @@ public: bool bDestroyed; bool bNewVisibility; - bool bGetPosition; + bool bNewPosition; bool bActivate; bool bRaise; bool bLower; @@ -946,10 +946,10 @@ private: }; NewVisibilityListener mNewVisibilityListener; - struct GetPositionListener : ::wl_listener { + struct NewPositionListener : ::wl_listener { MockPolicySurface *parent; }; - GetPositionListener mGetPositionListener; + NewPositionListener mNewPositionListener; struct ActivateListener : ::wl_listener { MockPolicySurface *parent; @@ -2291,7 +2291,7 @@ tizen_position_listener position_cb_listener = .changed = client_tizen_position_cb_changed, }; -TEST_F(PolicyTest, Req_PolicySurfaceGetPosition) +TEST_F(PolicyTest, Req_PolicySurfaceNewPosition) { MockPolicySurface *policy_surface; struct tizen_position *position_res; @@ -2306,7 +2306,7 @@ TEST_F(PolicyTest, Req_PolicySurfaceGetPosition) surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); - EXPECT_TRUE(policy_surface->bGetPosition); + EXPECT_TRUE(policy_surface->bNewPosition); tizen_position_destroy(position_res); } @@ -2330,9 +2330,9 @@ TEST_F(PolicyTest, Req_PositionSet) surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); - EXPECT_TRUE(policy_surface->bGetPosition); + EXPECT_TRUE(policy_surface->bNewPosition); - position = policy_surface->GetPosition(); + position = policy_surface->NewPosition(); EXPECT_TRUE(position->mX == x); EXPECT_TRUE(position->mY == y); @@ -2356,9 +2356,9 @@ TEST_F(PolicyTest, Ev_PositionChanged) surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); - EXPECT_TRUE(policy_surface->bGetPosition); + EXPECT_TRUE(policy_surface->bNewPosition); - position = policy_surface->GetPosition(); + position = policy_surface->NewPosition(); position->SendChanged(x, y); comp->Process(); -- 2.7.4 From 0f40c7fd5346b9f673b580b193ceaed1e4740239 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 7 Sep 2022 15:20:02 +0900 Subject: [PATCH 09/16] change get_subsurface_watcher to new_subsurface_watcher change the symbol names Change-Id: I05c21fedb75ebdc4fca9f23bad62df0a022de6c8 --- examples/tinyds-tdm.c | 20 ++++++++++---------- include/libds-tizen/policy.h | 4 ++-- src/policy/policy.c | 12 ++++++------ tests/tc_policy.cpp | 30 +++++++++++++++--------------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index d0cac7d..2108efc 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -135,7 +135,7 @@ struct tinyds_policy_surface struct wl_listener set_floating_mode; struct wl_listener unset_floating_mode; struct wl_listener set_stack_mode; - struct wl_listener get_subsurface_watcher; + struct wl_listener new_subsurface_watcher; struct wl_listener set_parent; struct wl_listener ack_conformant_region; struct wl_listener set_video; @@ -2956,16 +2956,16 @@ policy_surface_handle_set_stack_mode(struct wl_listener *listener, void *data) } static void -policy_surface_handle_get_subsurface_watcher(struct wl_listener *listener, void *data) +policy_surface_handle_new_subsurface_watcher(struct wl_listener *listener, void *data) { struct tinyds_policy_surface *policy_surface; struct tinyds_policy_subsurface_watcher*subsurface_watcher; - struct ds_tizen_event_policy_surface_get_subsurface_watcher *event; + struct ds_tizen_event_policy_surface_new_subsurface_watcher *event; - policy_surface = wl_container_of(listener, policy_surface, get_subsurface_watcher); - event = (struct ds_tizen_event_policy_surface_get_subsurface_watcher *)data; + policy_surface = wl_container_of(listener, policy_surface, new_subsurface_watcher); + event = (struct ds_tizen_event_policy_surface_new_subsurface_watcher *)data; - ds_inf("Policy Info(%p) get_subsurface_watcher", policy_surface); + ds_inf("Policy Info(%p) new_subsurface_watcher", policy_surface); subsurface_watcher = calloc(1, sizeof *subsurface_watcher); if (!subsurface_watcher) @@ -3187,10 +3187,10 @@ policy_handle_new_surface(struct wl_listener *listener, void *data) ds_tizen_policy_surface_add_set_stack_mode_listener(policy_surface->policy_surface, &policy_surface->set_stack_mode); - policy_surface->get_subsurface_watcher.notify = - policy_surface_handle_get_subsurface_watcher; - ds_tizen_policy_surface_add_get_subsurface_watcher_listener( - policy_surface->policy_surface, &policy_surface->get_subsurface_watcher); + policy_surface->new_subsurface_watcher.notify = + policy_surface_handle_new_subsurface_watcher; + ds_tizen_policy_surface_add_new_subsurface_watcher_listener( + policy_surface->policy_surface, &policy_surface->new_subsurface_watcher); policy_surface->set_parent.notify = policy_surface_handle_set_parent; ds_tizen_policy_surface_add_set_parent_listener(policy_surface->policy_surface, diff --git a/include/libds-tizen/policy.h b/include/libds-tizen/policy.h index dd3d313..5066e41 100644 --- a/include/libds-tizen/policy.h +++ b/include/libds-tizen/policy.h @@ -295,7 +295,7 @@ struct ds_tizen_event_policy_surface_set_stack_mode enum ds_tizen_policy_stack_mode mode; }; -struct ds_tizen_event_policy_surface_get_subsurface_watcher +struct ds_tizen_event_policy_surface_new_subsurface_watcher { struct ds_tizen_policy_surface *policy_surface; struct ds_tizen_policy_subsurface_watcher *subsurface_watcher; @@ -538,7 +538,7 @@ ds_tizen_policy_surface_add_set_stack_mode_listener( struct wl_listener *listener); void -ds_tizen_policy_surface_add_get_subsurface_watcher_listener( +ds_tizen_policy_surface_add_new_subsurface_watcher_listener( struct ds_tizen_policy_surface *policy_surface, struct wl_listener *listener); diff --git a/src/policy/policy.c b/src/policy/policy.c index 87cd4a1..c2acb39 100644 --- a/src/policy/policy.c +++ b/src/policy/policy.c @@ -101,7 +101,7 @@ struct ds_tizen_policy_surface struct wl_signal set_floating_mode; struct wl_signal unset_floating_mode; struct wl_signal set_stack_mode; - struct wl_signal get_subsurface_watcher; + struct wl_signal new_subsurface_watcher; struct wl_signal set_parent; struct wl_signal ack_conformant_region; struct wl_signal set_video; @@ -521,11 +521,11 @@ ds_tizen_policy_surface_add_set_stack_mode_listener( } WL_EXPORT void -ds_tizen_policy_surface_add_get_subsurface_watcher_listener( +ds_tizen_policy_surface_add_new_subsurface_watcher_listener( struct ds_tizen_policy_surface *policy_surface, struct wl_listener *listener) { - wl_signal_add(&policy_surface->events.get_subsurface_watcher, listener); + wl_signal_add(&policy_surface->events.new_subsurface_watcher, listener); } WL_EXPORT void @@ -971,7 +971,7 @@ tizen_policy_client_get_surface(struct wl_resource *resource, wl_signal_init(&policy_surface->events.set_floating_mode); wl_signal_init(&policy_surface->events.unset_floating_mode); wl_signal_init(&policy_surface->events.set_stack_mode); - wl_signal_init(&policy_surface->events.get_subsurface_watcher); + wl_signal_init(&policy_surface->events.new_subsurface_watcher); wl_signal_init(&policy_surface->events.set_parent); wl_signal_init(&policy_surface->events.ack_conformant_region); wl_signal_init(&policy_surface->events.set_video); @@ -2018,11 +2018,11 @@ policy_handle_get_subsurface_watcher(struct wl_client *wl_client, &subsurface_watcher_impl, subsurface_watcher, _tizen_policy_subsurface_watcher_handle_destroy); - struct ds_tizen_event_policy_surface_get_subsurface_watcher event = { + struct ds_tizen_event_policy_surface_new_subsurface_watcher event = { .policy_surface = policy_surface, .subsurface_watcher = subsurface_watcher, }; - wl_signal_emit(&policy_surface->events.get_subsurface_watcher, &event); + wl_signal_emit(&policy_surface->events.new_subsurface_watcher, &event); } static void diff --git a/tests/tc_policy.cpp b/tests/tc_policy.cpp index dd2296f..d38152e 100644 --- a/tests/tc_policy.cpp +++ b/tests/tc_policy.cpp @@ -366,10 +366,10 @@ public: ds_tizen_policy_surface_add_set_stack_mode_listener(policy_surface, &mSetStackModeListener); - mGetSubsurfaceWatcherListener.notify = MockPolicySurface::GetSubsurfaceWatcherCallback; - mGetSubsurfaceWatcherListener.parent = this; - ds_tizen_policy_surface_add_get_subsurface_watcher_listener(policy_surface, - &mGetSubsurfaceWatcherListener); + mNewSubsurfaceWatcherListener.notify = MockPolicySurface::NewSubsurfaceWatcherCallback; + mNewSubsurfaceWatcherListener.parent = this; + ds_tizen_policy_surface_add_new_subsurface_watcher_listener(policy_surface, + &mNewSubsurfaceWatcherListener); mSetParentListener.notify = MockPolicySurface::SetParentCallback; mSetParentListener.parent = this; @@ -742,17 +742,17 @@ public: policySurface->mStackMode = event->mode; } - static void GetSubsurfaceWatcherCallback(struct wl_listener *listener, void *data) + static void NewSubsurfaceWatcherCallback(struct wl_listener *listener, void *data) { MockPolicySurface *policySurface = - reinterpret_cast(listener)->parent; - struct ds_tizen_event_policy_surface_get_subsurface_watcher *event = - static_cast(data); + reinterpret_cast(listener)->parent; + struct ds_tizen_event_policy_surface_new_subsurface_watcher *event = + static_cast(data); EXPECT_TRUE(policySurface->mPolicySurface == event->policy_surface); EXPECT_TRUE(event->subsurface_watcher != NULL); - policySurface->bGetSubsurfaceWatcher = true; + policySurface->bNewSubsurfaceWatcher = true; MockPolicySubsurfaceWatcher *policySubsurfaceWatcher = new MockPolicySubsurfaceWatcher(event->subsurface_watcher); @@ -850,7 +850,7 @@ public: return mPolicyPosition; } - MockPolicySubsurfaceWatcher*GetSubsurfaceWatcher() + MockPolicySubsurfaceWatcher*NewSubsurfaceWatcher() { return mPolicySubsurfaceWatcher; } @@ -922,7 +922,7 @@ public: bool bGetSupportedAuxHints; bool bSetFloatingMode; enum ds_tizen_policy_stack_mode mStackMode; - bool bGetSubsurfaceWatcher; + bool bNewSubsurfaceWatcher; struct ds_surface *mParentSurface; uint32_t mSerial; bool bVideo; @@ -1061,10 +1061,10 @@ private: }; SetStackModeListener mSetStackModeListener; - struct GetSubsurfaceWatcherListener : ::wl_listener { + struct NewSubsurfaceWatcherListener : ::wl_listener { MockPolicySurface *parent; }; - GetSubsurfaceWatcherListener mGetSubsurfaceWatcherListener; + NewSubsurfaceWatcherListener mNewSubsurfaceWatcherListener; struct SetParentListener : ::wl_listener { MockPolicySurface *parent; @@ -2718,7 +2718,7 @@ TEST_F(PolicyTest, Req_PolicySurfaceSetStackMode) EXPECT_TRUE(policy_surface->bSetFloatingMode == true); } -TEST_F(PolicyTest, Req_PolicySurfaceGetSubsurfaceWatcher) +TEST_F(PolicyTest, Req_PolicySurfaceNewSubsurfaceWatcher) { MockPolicySurface *policy_surface; uint32_t surface_res_id; @@ -2732,7 +2732,7 @@ TEST_F(PolicyTest, Req_PolicySurfaceGetSubsurfaceWatcher) surface_res_id = wl_proxy_get_id((struct wl_proxy *)surface_res); policy_surface = comp->FindPolicySurfaceWidthResId(surface_res_id); - EXPECT_TRUE(policy_surface->bGetSubsurfaceWatcher == true); + EXPECT_TRUE(policy_surface->bNewSubsurfaceWatcher == true); tizen_subsurface_watcher_destroy(subsuface_watcher_res); } -- 2.7.4 From 2249b48be116ebd6bac2b9a4fe72f51e63b2a540 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 7 Sep 2022 15:59:23 +0900 Subject: [PATCH 10/16] tizen_policy: check the client's version of TIZEN_POLICY_CONFORMANT_REGION event Change-Id: Iaa6cd9fcc7e99933f8ff6f4a4ed9eee039d564d9 --- src/policy/policy.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/policy/policy.c b/src/policy/policy.c index c2acb39..95b9e02 100644 --- a/src/policy/policy.c +++ b/src/policy/policy.c @@ -638,9 +638,17 @@ ds_tizen_policy_surface_send_conformant_area(struct ds_tizen_policy_surface *pol return; } - tizen_policy_send_conformant_area(policy_surface->client->resource, - ds_surface_get_wl_resource(policy_surface->surface), conformant_part, visible, - x, y, w, h); + if (wl_resource_get_version(policy_surface->client->resource) >= + TIZEN_POLICY_CONFORMANT_REGION_SINCE_VERSION) { + tizen_policy_send_conformant_area(policy_surface->client->resource, + ds_surface_get_wl_resource(policy_surface->surface), conformant_part, visible, + x, y, w, h); + } else { + ds_err("client does not support TIZEN_POLICY_CONFORMANT_REGION." + "client version(%d) < server version(%d)", + wl_resource_get_version(policy_surface->client->resource), + TIZEN_POLICY_CONFORMANT_REGION_SINCE_VERSION); + } } WL_EXPORT void -- 2.7.4 From 82fd81f9fb4a00b01ddbe79fb69813a3d7d07436 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Tue, 6 Sep 2022 16:43:38 +0900 Subject: [PATCH 11/16] example: check if a input_method_context is null. Change-Id: I284fec4336d6235e2f8c88985c8965a6448fd6e7 --- examples/tinyds-tdm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/tinyds-tdm.c b/examples/tinyds-tdm.c index 2108efc..a797ca2 100644 --- a/examples/tinyds-tdm.c +++ b/examples/tinyds-tdm.c @@ -2513,6 +2513,10 @@ add_new_input_method_context(struct tinyds_input_method *input_method, context->input = text_input; context->context = ds_tizen_input_method_create_context(input_method->input_method); + if (context->context == NULL) { + ds_err("ds_tizen_input_method_create_context() failed."); + return false; + } context->destroy.notify = context_handle_destroy; ds_tizen_input_method_context_add_destroy_listener(context->context, -- 2.7.4 From de708ef11ae0031b65bce4d1b8806218c659cf6d Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Tue, 6 Sep 2022 16:44:56 +0900 Subject: [PATCH 12/16] input_method: check if a resource of input_method is null. Change-Id: I5932828b6ca1fefbdb81c2d747856d0761e5bd5b --- src/input_method/input_method.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/input_method/input_method.c b/src/input_method/input_method.c index 138193f..0c16b28 100644 --- a/src/input_method/input_method.c +++ b/src/input_method/input_method.c @@ -227,7 +227,10 @@ ds_tizen_input_method_create_context(struct ds_tizen_input_method *input_method) } binding = input_method->resource; - if (!binding) return NULL; + if (!binding) { + ds_err("context. there is no wl_resource_create() failed."); + return NULL; + } context->resource = wl_resource_create(wl_resource_get_client(binding), &zwp_input_method_context_v1_interface, INPUT_METHOD_VERSION, 0); if (context->resource == NULL) { -- 2.7.4 From a1a2e37791799079e18dee03e952c2ab9ecc64e2 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Tue, 6 Sep 2022 16:46:30 +0900 Subject: [PATCH 13/16] text_input: add dummy implementation of tizen only handlers to avoid a crash from a client's request. Change-Id: Ie224f2437fa38aad83fa983e32feb088df1ecc7e --- src/text_input/text_input.c | 154 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 139 insertions(+), 15 deletions(-) diff --git a/src/text_input/text_input.c b/src/text_input/text_input.c index d25b1a4..ad4bcf2 100644 --- a/src/text_input/text_input.c +++ b/src/text_input/text_input.c @@ -354,6 +354,130 @@ text_input_handle_invoke_action(struct wl_client *client, wl_signal_emit(&text_input->events.invoke_action, &ds_event); } +static void +text_input_handle_set_return_key_type(struct wl_client *client, + struct wl_resource *resource, uint32_t return_key_type) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_set_return_key_type"); +} + +static void +text_input_handle_set_return_key_disabled(struct wl_client *client, + struct wl_resource *resource, uint32_t return_key_disabled) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_set_return_key_disabled"); +} + +static void +text_input_handle_set_input_panel_data(struct wl_client *client, + struct wl_resource *resource, const char *input_panel_data, + uint32_t input_panel_length) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_set_input_panel_data"); +} + +static void +text_input_handle_bidi_direction(struct wl_client *client, + struct wl_resource *resource, uint32_t direction) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_bidi_direction"); +} + +static void +text_input_handle_set_cursor_position(struct wl_client *client, + struct wl_resource *resource, uint32_t cursor_position) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_set_cursor_position"); +} + +static void +text_input_handle_process_input_device_event(struct wl_client *client, + struct wl_resource *resource, uint32_t event_type, const char *event_data, + uint32_t event_length) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_process_input_device_event"); +} + +static void +text_input_handle_filter_key_event(struct wl_client *client, + struct wl_resource *resource, uint32_t serial, uint32_t time, + const char *keyname, uint32_t modifiers, const char *dev_name, + uint32_t dev_class, uint32_t dev_subclass, uint32_t keycode) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_filter_key_event"); +} + +static void +text_input_handle_get_hide_permission(struct wl_client *client, + struct wl_resource *resource) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_get_hide_permission"); +} + +static void +text_input_handle_set_capital_mode(struct wl_client *client, + struct wl_resource *resource, uint32_t mode) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_set_capital_mode"); +} + +static void +text_input_handle_prediction_hint(struct wl_client *client, + struct wl_resource *resource, const char *text) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_prediction_hint"); +} + +static void +text_input_handle_set_mime_type(struct wl_client *client, + struct wl_resource *resource, const char *type) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_set_mime_type"); +} + +static void +text_input_handle_set_input_panel_position(struct wl_client *client, + struct wl_resource *resource, uint32_t x, uint32_t y) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_set_input_panel_position"); +} + +static void +text_input_handle_finalize_content(struct wl_client *client, + struct wl_resource *resource, const char *text, uint32_t cursor_position) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_finalize_content"); +} + +static void +text_input_handle_prediction_hint_data(struct wl_client *client, + struct wl_resource *resource, const char *key, const char *value) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_prediction_hint_data"); +} + +static void +text_input_handle_input_panel_enabled(struct wl_client *client, + struct wl_resource *resource, uint32_t enabled) +{ + // TODO: + ds_inf("Not Implemented. text_input_handle_input_panel_enabled"); +} + static const struct wl_text_input_interface text_input_impl = { .destroy = text_input_handle_destroy, .activate = text_input_handle_activate, @@ -367,21 +491,21 @@ static const struct wl_text_input_interface text_input_impl = { .commit_state = text_input_handle_commit_state, .invoke_action = text_input_handle_invoke_action, //for tizen only - .set_return_key_type = NULL, - .set_return_key_disabled = NULL, - .set_input_panel_data = NULL, - .bidi_direction = NULL, - .set_cursor_position = NULL, - .process_input_device_event = NULL, - .filter_key_event = NULL, - .get_hide_permission = NULL, - .set_capital_mode = NULL, - .prediction_hint = NULL, - .set_mime_type = NULL, - .set_input_panel_position = NULL, - .finalize_content = NULL, - .prediction_hint_data = NULL, - .input_panel_enabled = NULL, + .set_return_key_type = text_input_handle_set_return_key_type, + .set_return_key_disabled = text_input_handle_set_return_key_disabled, + .set_input_panel_data = text_input_handle_set_input_panel_data, + .bidi_direction = text_input_handle_bidi_direction, + .set_cursor_position = text_input_handle_set_cursor_position, + .process_input_device_event = text_input_handle_process_input_device_event, + .filter_key_event = text_input_handle_filter_key_event, + .get_hide_permission = text_input_handle_get_hide_permission, + .set_capital_mode = text_input_handle_set_capital_mode, + .prediction_hint = text_input_handle_prediction_hint, + .set_mime_type = text_input_handle_set_mime_type, + .set_input_panel_position = text_input_handle_set_input_panel_position, + .finalize_content = text_input_handle_finalize_content, + .prediction_hint_data = text_input_handle_prediction_hint_data, + .input_panel_enabled = text_input_handle_input_panel_enabled, }; static void -- 2.7.4 From 9a4e6e809615a83d8ad45695332629b49b34413f Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 7 Sep 2022 17:16:27 +0900 Subject: [PATCH 14/16] fix the memory leak Change-Id: I58f5eb7d5ec611e41d78e2110a1d20fe1ee6b0da --- src/input_method/input_method.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/input_method/input_method.c b/src/input_method/input_method.c index 0c16b28..d2e6cbb 100644 --- a/src/input_method/input_method.c +++ b/src/input_method/input_method.c @@ -228,7 +228,8 @@ ds_tizen_input_method_create_context(struct ds_tizen_input_method *input_method) binding = input_method->resource; if (!binding) { - ds_err("context. there is no wl_resource_create() failed."); + ds_err("context. there is no resource of input_method."); + free(context); return NULL; } context->resource = wl_resource_create(wl_resource_get_client(binding), -- 2.7.4 From 64e627968bb6ec889e1387f2ae4ccb819acabbea Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Tue, 13 Sep 2022 10:25:38 +0900 Subject: [PATCH 15/16] text_input: Add a missing parameter This is to silence a warning. Change-Id: I0a8291a194a7bea1f8c651230e732f092bc31540 --- src/text_input/text_input.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/text_input/text_input.c b/src/text_input/text_input.c index ad4bcf2..709cadb 100644 --- a/src/text_input/text_input.c +++ b/src/text_input/text_input.c @@ -407,8 +407,9 @@ text_input_handle_process_input_device_event(struct wl_client *client, static void text_input_handle_filter_key_event(struct wl_client *client, struct wl_resource *resource, uint32_t serial, uint32_t time, - const char *keyname, uint32_t modifiers, const char *dev_name, - uint32_t dev_class, uint32_t dev_subclass, uint32_t keycode) + const char *keyname, uint32_t state, uint32_t modifiers, + const char *dev_name, uint32_t dev_class, uint32_t dev_subclass, + uint32_t keycode) { // TODO: ds_inf("Not Implemented. text_input_handle_filter_key_event"); -- 2.7.4 From 13ae5fb81f8193d65a4eccfbf624a4fd2936dfd6 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Wed, 7 Sep 2022 17:33:30 +0900 Subject: [PATCH 16/16] Init tizen-screenshooter Change-Id: I438cd7e690f93bc9f64894c968bbd8dedcc7c919 Signed-off-by: Junkyeong Kim --- include/libds-tizen/screenshooter.h | 97 +++++ packaging/libds-tizen.spec | 30 ++ src/meson.build | 1 + src/screenshooter/meson.build | 31 ++ src/screenshooter/screenmirror.c | 247 ++++++++++++ src/screenshooter/screenshooter.c | 215 +++++++++++ src/screenshooter/screenshooter.h | 62 +++ tests/meson.build | 20 + tests/tc_screenshooter.cpp | 747 ++++++++++++++++++++++++++++++++++++ 9 files changed, 1450 insertions(+) create mode 100644 include/libds-tizen/screenshooter.h create mode 100644 src/screenshooter/meson.build create mode 100644 src/screenshooter/screenmirror.c create mode 100644 src/screenshooter/screenshooter.c create mode 100644 src/screenshooter/screenshooter.h create mode 100644 tests/tc_screenshooter.cpp diff --git a/include/libds-tizen/screenshooter.h b/include/libds-tizen/screenshooter.h new file mode 100644 index 0000000..d16b899 --- /dev/null +++ b/include/libds-tizen/screenshooter.h @@ -0,0 +1,97 @@ +#ifndef LIBDS_TIZEN_SCREENSHOOTER_H +#define LIBDS_TIZEN_SCREENSHOOTER_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tizen_screenshooter; +struct ds_tizen_screenmirror; +struct ds_tizen_screenshooter_client; + +enum ds_tizen_screenmirror_stretch +{ + DS_TIZEN_SCREENMIRROR_STRETCH_KEEP_RATIO, + DS_TIZEN_SCREENMIRROR_STRETCH_FULLY, +}; + +enum ds_tizen_screenmirror_content +{ + DS_TIZEN_SCREENMIRROR_CONTENT_NORMAL, + DS_TIZEN_SCREENMIRROR_CONTENT_VIDEO, +}; + +struct ds_tizen_screenshooter_shoot_event +{ + struct ds_output *output; + struct ds_buffer *buffer; + struct ds_tizen_screenshooter_client *client; + bool auto_rotation; +}; + +struct ds_tizen_screenshooter * +ds_tizen_screenshooter_create(struct wl_display *display); + +void +ds_tizen_screenshooter_add_destroy_listener(struct ds_tizen_screenshooter *shot, + struct wl_listener *listener); + +void +ds_tizen_screenshooter_add_get_screenmirror_listener(struct ds_tizen_screenshooter *shot, + struct wl_listener *listener); + +void +ds_tizen_screenshooter_add_shoot_listener(struct ds_tizen_screenshooter *shot, + struct wl_listener *listener); + +void +ds_tizen_screenshooter_send_shoot_done(struct ds_tizen_screenshooter *shot, + struct ds_tizen_screenshooter_client *client); + +void +ds_tizen_screenmirror_add_destroy_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener); + +void +ds_tizen_screenmirror_add_set_stretch_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener); + +void +ds_tizen_screenmirror_add_queue_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener); + +void +ds_tizen_screenmirror_add_dequeue_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener); + +void +ds_tizen_screenmirror_add_start_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener); + +void +ds_tizen_screenmirror_add_stop_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener); + +void +ds_tizen_screenmirror_add_auto_rotation_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener); + +void +ds_tizen_screenmirror_send_content(struct ds_tizen_screenmirror *mirror, + enum ds_tizen_screenmirror_content content); + +void +ds_tizen_screenmirror_send_dequeued(struct ds_tizen_screenmirror *mirror, + struct ds_buffer *buffer); + +void +ds_tizen_screenmirror_send_stop(struct ds_tizen_screenmirror *mirror); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index e1d4c25..485abfc 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -327,6 +327,21 @@ Group: Development/Libraries %description policy-devel Development package for tizen policy +## libds-tizen-screenshooter +%package screenshooter +Summary: Library for tizen screenshooter +Group: Development/Libraries + +%description screenshooter +Library for tizen screenshooter + +%package screenshooter-devel +Summary: Development package for tizen screenshooter +Group: Development/Libraries + +%description screenshooter-devel +Development package for tizen screenshooter + %prep %setup -q cp %{SOURCE1001} . @@ -631,3 +646,18 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-policy.pc %{_libdir}/libds-tizen-policy.so %{_bindir}/libds-tizen-policy-tests + +%files screenshooter +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-screenshooter.so.* + +%files screenshooter-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/screenshooter.h +%{_libdir}/pkgconfig/libds-tizen-screenshooter.pc +%{_libdir}/libds-tizen-screenshooter.so +%{_bindir}/libds-tizen-screenshooter-tests diff --git a/src/meson.build b/src/meson.build index 227b7a9..9cc81b5 100644 --- a/src/meson.build +++ b/src/meson.build @@ -46,3 +46,4 @@ subdir('input_method') subdir('text_input') subdir('hwc') subdir('policy') +subdir('screenshooter') diff --git a/src/screenshooter/meson.build b/src/screenshooter/meson.build new file mode 100644 index 0000000..4a5f619 --- /dev/null +++ b/src/screenshooter/meson.build @@ -0,0 +1,31 @@ +libds_tizen_screenshooter_files = [ + 'screenshooter.c', + 'screenmirror.c', +] + +libds_tizen_screenshooter_deps = [ + deps_libds_tizen, + dependency('tizen-extension-server', required: true), + dependency('wayland-tbm-server', required: true), +] + +lib_libds_tizen_screenshooter = shared_library('ds-tizen-screenshooter', libds_tizen_screenshooter_files, + dependencies: libds_tizen_screenshooter_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +deps_libds_tizen_screenshooter = declare_dependency( + link_with: lib_libds_tizen_screenshooter, + dependencies: libds_tizen_screenshooter_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_screenshooter, + version: meson.project_version(), + filebase: 'libds-tizen-screenshooter', + name: 'libds-tizen-screenshooter', + description: 'tizen screenshooter extension of libds-tizen for tizen platform', +) diff --git a/src/screenshooter/screenmirror.c b/src/screenshooter/screenmirror.c new file mode 100644 index 0000000..4d15d87 --- /dev/null +++ b/src/screenshooter/screenmirror.c @@ -0,0 +1,247 @@ +#include +#include "screenshooter.h" +#include "util.h" + +static const struct tizen_screenmirror_interface _screenmirror_interface; + +WL_EXPORT void +ds_tizen_screenmirror_add_destroy_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener) +{ + wl_signal_add(&mirror->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_screenmirror_add_set_stretch_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener) +{ + wl_signal_add(&mirror->events.set_stretch, listener); +} + +WL_EXPORT void +ds_tizen_screenmirror_add_queue_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener) +{ + wl_signal_add(&mirror->events.queue, listener); +} + +WL_EXPORT void +ds_tizen_screenmirror_add_dequeue_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener) +{ + wl_signal_add(&mirror->events.dequeue, listener); +} + +WL_EXPORT void +ds_tizen_screenmirror_add_start_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener) +{ + wl_signal_add(&mirror->events.start, listener); +} + +WL_EXPORT void +ds_tizen_screenmirror_add_stop_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener) +{ + wl_signal_add(&mirror->events.stop, listener); +} + +WL_EXPORT void +ds_tizen_screenmirror_add_auto_rotation_listener(struct ds_tizen_screenmirror *mirror, + struct wl_listener *listener) +{ + wl_signal_add(&mirror->events.set_auto_rotation, listener); +} + +WL_EXPORT void +ds_tizen_screenmirror_send_content(struct ds_tizen_screenmirror *mirror, + enum ds_tizen_screenmirror_content content) +{ + if (content == DS_TIZEN_SCREENMIRROR_CONTENT_NORMAL) + tizen_screenmirror_send_content(mirror->resource, TIZEN_SCREENMIRROR_CONTENT_NORMAL); + else if (content == DS_TIZEN_SCREENMIRROR_CONTENT_VIDEO) + tizen_screenmirror_send_content(mirror->resource, TIZEN_SCREENMIRROR_CONTENT_VIDEO); +} + +WL_EXPORT void +ds_tizen_screenmirror_send_dequeued(struct ds_tizen_screenmirror *mirror, + struct ds_buffer *buffer) +{ + struct wl_resource *wl_buffer; + + wl_buffer = ds_buffer_get_resource(buffer); + tizen_screenmirror_send_dequeued(mirror->resource, wl_buffer); +} + +WL_EXPORT void +ds_tizen_screenmirror_send_stop(struct ds_tizen_screenmirror *mirror) +{ + tizen_screenmirror_send_stop(mirror->resource); +} + +void +ds_tizen_screenmirror_destroy(struct ds_tizen_screenmirror *mirror) +{ + if (mirror == NULL) + return; + + if (mirror->client_destroy_listener.notify) + wl_list_remove(&mirror->client_destroy_listener.link); + mirror->client_destroy_listener.notify = NULL; + + if (mirror->resource) + wl_resource_set_destructor(mirror->resource, NULL); + + wl_signal_emit(&mirror->events.destroy, NULL); + //should be called buffer_dequeued from server(ds_tizen_screenmirror_send_dequeued) + + free(mirror); +} + +static void +screenmirror_handle_resource_destroy(struct wl_resource *resource) +{ + struct ds_tizen_screenmirror *mirror = wl_resource_get_user_data(resource); + ds_tizen_screenmirror_destroy(mirror); +} + +static void +screenmirror_handle_client_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_screenmirror *mirror = wl_container_of(listener, mirror, client_destroy_listener); + ds_tizen_screenmirror_destroy(mirror); +} + +struct ds_tizen_screenmirror * +ds_tizen_screenmirror_create(struct ds_tizen_screenshooter_client *client, + int version, uint32_t id) +{ + struct ds_tizen_screenmirror *mirror; + + mirror = calloc(1, sizeof *mirror); + if (!mirror) { + ds_err("screenmirror create fail : memory alloc failed"); + return NULL; + } + + mirror->resource = wl_resource_create(client->client, &tizen_screenmirror_interface, + version, id); + if (mirror->resource == NULL) { + ds_err("screenmirror wl_resource create fail : memory alloc failed"); + free(mirror); + return NULL; + } + + wl_signal_init(&mirror->events.destroy); + wl_signal_init(&mirror->events.set_stretch); + wl_signal_init(&mirror->events.queue); + wl_signal_init(&mirror->events.dequeue); + wl_signal_init(&mirror->events.start); + wl_signal_init(&mirror->events.stop); + wl_signal_init(&mirror->events.set_auto_rotation); + + wl_resource_set_implementation(mirror->resource, &_screenmirror_interface, + mirror, screenmirror_handle_resource_destroy); + + + ds_inf("create : tizen_screenmirror(%p)", mirror); + + mirror->client_destroy_listener.notify = screenmirror_handle_client_destroy; + wl_client_add_destroy_listener(client->client, &mirror->client_destroy_listener); + + return mirror; +} + +static void +_tizen_screenmirror_handle_destroy(struct wl_client *client, struct wl_resource *resource) +{ + ds_inf("_tizen_screenmirror_handle_destroy (res:%p)", resource); + wl_resource_destroy(resource); +} + +static void +_tizen_screenmirror_handle_set_stretch(struct wl_client *client, struct wl_resource *resource, uint32_t stretch) +{ + struct ds_tizen_screenmirror *mirror = wl_resource_get_user_data(resource); + enum ds_tizen_screenmirror_stretch ds_stretch; + + if (stretch > TIZEN_SCREENMIRROR_STRETCH_FULLY) { + ds_err("set stretch error : not supported stretch(%d)", stretch); + return; + } + if (stretch == TIZEN_SCREENMIRROR_STRETCH_KEEP_RATIO) + ds_stretch = DS_TIZEN_SCREENMIRROR_STRETCH_KEEP_RATIO; + else + ds_stretch = DS_TIZEN_SCREENMIRROR_STRETCH_FULLY; + + wl_signal_emit(&mirror->events.set_stretch, &ds_stretch); +} + +static void +_tizen_screenmirror_handle_queue(struct wl_client *client, struct wl_resource *resource, struct wl_resource *wl_buffer) +{ + struct ds_tizen_screenmirror *mirror; + struct ds_buffer *buffer; + + mirror = wl_resource_get_user_data(resource); + buffer = ds_buffer_from_resource(wl_buffer); + if (!buffer) { + ds_err("ds_buffer_from_resource fail"); + return; + } + + wl_signal_emit(&mirror->events.queue, &buffer); +} + +static void +_tizen_screenmirror_handle_dequeue(struct wl_client *client, struct wl_resource *resource, struct wl_resource *wl_buffer) +{ + struct ds_tizen_screenmirror *mirror; + struct ds_buffer *buffer; + + mirror = wl_resource_get_user_data(resource); + buffer = ds_buffer_from_resource(wl_buffer); + if (!buffer) { + ds_err("ds_buffer_from_resource fail"); + return; + } + + wl_signal_emit(&mirror->events.dequeue, &buffer); +} + +static void +_tizen_screenmirror_handle_start(struct wl_client *client, struct wl_resource *resource) +{ + struct ds_tizen_screenmirror *mirror; + + mirror = wl_resource_get_user_data(resource); + wl_signal_emit(&mirror->events.start, NULL); +} + +static void +_tizen_screenmirror_handle_stop(struct wl_client *client, struct wl_resource *resource) +{ + struct ds_tizen_screenmirror *mirror; + + mirror = wl_resource_get_user_data(resource); + wl_signal_emit(&mirror->events.stop, NULL); +} + +static void +_tizen_screenmirror_handle_set_auto_rotation(struct wl_client *client, struct wl_resource *resource, uint32_t set) +{ + struct ds_tizen_screenmirror *mirror; + + mirror = wl_resource_get_user_data(resource); + wl_signal_emit(&mirror->events.set_auto_rotation, &set); +} + +static const struct tizen_screenmirror_interface _screenmirror_interface = { + _tizen_screenmirror_handle_destroy, + _tizen_screenmirror_handle_set_stretch, + _tizen_screenmirror_handle_queue, + _tizen_screenmirror_handle_dequeue, + _tizen_screenmirror_handle_start, + _tizen_screenmirror_handle_stop, + _tizen_screenmirror_handle_set_auto_rotation +}; diff --git a/src/screenshooter/screenshooter.c b/src/screenshooter/screenshooter.c new file mode 100644 index 0000000..890bd2f --- /dev/null +++ b/src/screenshooter/screenshooter.c @@ -0,0 +1,215 @@ +#include +#include "screenshooter.h" +#include "util.h" + +#define TIZEN_SCREENSHOOTER_VERSION 3 + +static void screenshooter_handle_display_destroy(struct wl_listener *listener, + void *data); + +static void screenshooter_bind(struct wl_client *wl_client, void *data, + uint32_t version, uint32_t id); + +WL_EXPORT struct ds_tizen_screenshooter * +ds_tizen_screenshooter_create(struct wl_display *display) +{ + struct ds_tizen_screenshooter *shot; + + shot = calloc(1, sizeof *shot); + if (!shot) { + ds_err("screenshooter create fail : memory alloc failed"); + return NULL; + } + + shot->global = wl_global_create(display, &tizen_screenshooter_interface, + TIZEN_SCREENSHOOTER_VERSION, NULL, screenshooter_bind); + + wl_list_init(&shot->clients); + wl_signal_init(&shot->events.destroy); + wl_signal_init(&shot->events.shoot); + + shot->destroy.notify = screenshooter_handle_display_destroy; + wl_display_add_destroy_listener(display, &shot->destroy); + + ds_inf("create : tizen_screenshooter(%p)", shot); + + return shot; +} + +WL_EXPORT void +ds_tizen_screenshooter_add_destroy_listener(struct ds_tizen_screenshooter *shot, + struct wl_listener *listener) +{ + wl_signal_add(&shot->events.destroy, listener); +} + +WL_EXPORT void +ds_tizen_screenshooter_add_get_screenmirror_listener(struct ds_tizen_screenshooter *shot, + struct wl_listener *listener) +{ + wl_signal_add(&shot->events.get_screenmirror, listener); +} + +WL_EXPORT void +ds_tizen_screenshooter_add_shoot_listener(struct ds_tizen_screenshooter *shot, + struct wl_listener *listener) +{ + wl_signal_add(&shot->events.shoot, listener); +} + +WL_EXPORT void +ds_tizen_screenshooter_send_shoot_done(struct ds_tizen_screenshooter *shot, + struct ds_tizen_screenshooter_client *client) +{ + struct ds_tizen_screenshooter_client *temp; + + wl_list_for_each(temp, &shot->clients, link) { + if (temp == client) { + ds_dbg("screenshooter send shoot done"); + tizen_screenshooter_send_done(client->res); + } + } +} + +static void +screenshooter_handle_display_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_screenshooter *shot; + + shot = wl_container_of(listener, shot, destroy); + + ds_inf("global destroy : tizen_screenshooter(%p)", shot); + + wl_signal_emit(&shot->events.destroy, shot); + wl_list_remove(&shot->destroy.link); + wl_global_destroy(shot->global); + free(shot); +} + +static void +_tizen_screenshooter_handle_get_screenmirror(struct wl_client *client, + struct wl_resource *resource, uint32_t id, struct wl_resource *output) +{ + struct ds_tizen_screenshooter *shot; + struct ds_tizen_screenshooter_client *shot_client; + int version = wl_resource_get_version(resource); + + shot_client = wl_resource_get_user_data(resource); + shot = shot_client->shot; + + if (shot_client->mirror) { + ds_err("screenshooter get_screenmirror error : already created"); + return; + } + + shot_client->mirror = ds_tizen_screenmirror_create(shot_client, version, id); + if (shot_client->mirror == NULL) + wl_client_post_no_memory(client); + else + wl_signal_emit(&shot->events.get_screenmirror, shot_client->mirror); +} + +static void +_tizen_screenshooter_handle_set_oneshot_auto_rotation(struct wl_client *client, + struct wl_resource *resource, uint32_t set) +{ + struct ds_tizen_screenshooter *shot; + struct ds_tizen_screenshooter_client *shot_client; + + shot_client = wl_resource_get_user_data(resource); + shot = shot_client->shot; + if (set) + shot->auto_rotation = true; + else + shot->auto_rotation = false; +} + +static void +_tizen_screenshooter_handle_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + ds_inf("_tizen_screenshooter_handle_destroy (res:%p)", resource); + wl_resource_destroy(resource); +} + +static void +_tizen_screenshooter_handle_shoot(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *wl_output, + struct wl_resource *wl_buffer) +{ + struct ds_tizen_screenshooter *shot; + struct ds_tizen_screenshooter_client *shot_client; + struct ds_output *output = NULL; + struct ds_buffer *buffer = NULL; + + shot_client = wl_resource_get_user_data(resource); + shot = shot_client->shot; + output = wl_resource_get_user_data(wl_output); + buffer = ds_buffer_from_resource(wl_buffer); + if (!buffer) { + ds_err("ds_buffer_from_resource fail"); + return; + } + + struct ds_tizen_screenshooter_shoot_event event = { + .output = output, + .buffer = buffer, + .client = shot_client, + .auto_rotation = shot->auto_rotation, + }; + + wl_signal_emit(&shot->events.shoot, &event); +} + +static const struct tizen_screenshooter_interface _tizen_screenshooter_interface = +{ + _tizen_screenshooter_handle_get_screenmirror, + _tizen_screenshooter_handle_set_oneshot_auto_rotation, + _tizen_screenshooter_handle_destroy, + _tizen_screenshooter_handle_shoot, +}; + +static void +_screenshooter_client_cb_destroy(struct wl_resource *resource) +{ + struct ds_tizen_screenshooter_client *shot_client; + + ds_inf("_screenshooter_client_cb_destroy (res:%p)", resource); + + shot_client = wl_resource_get_user_data(resource); + if (shot_client) { + wl_list_remove(&shot_client->link); + free(shot_client); + } +} + +static void +screenshooter_bind(struct wl_client *client, void *data, uint32_t version, + uint32_t id) +{ + struct ds_tizen_screenshooter *shot = data; + struct ds_tizen_screenshooter_client *shot_client; + + shot_client = calloc(1, sizeof *shot_client); + if (shot_client == NULL) { + wl_client_post_no_memory(client); + return; + } + + shot_client->shot = shot; + shot_client->client = client; + + shot_client->res = wl_resource_create(client, &tizen_screenshooter_interface, + MIN(version, TIZEN_SCREENSHOOTER_VERSION), id); + if (shot_client->res == NULL) { + ds_err("screenshooter bind error : wl_resource_create failed."); + wl_client_post_no_memory(client); + free(shot_client); + return; + } + + wl_resource_set_implementation(shot_client->res, &_tizen_screenshooter_interface, + shot_client, _screenshooter_client_cb_destroy); + + wl_list_insert(&shot->clients, &shot_client->link); +} diff --git a/src/screenshooter/screenshooter.h b/src/screenshooter/screenshooter.h new file mode 100644 index 0000000..bdc52bd --- /dev/null +++ b/src/screenshooter/screenshooter.h @@ -0,0 +1,62 @@ +#ifndef DS_TIZEN_SCREENSHOOTER_H +#define DS_TIZEN_SCREENSHOOTER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +struct ds_tizen_screenshooter +{ + struct wl_global *global; + struct wl_list clients; + + struct wl_listener destroy; + + struct { + struct wl_signal destroy; + struct wl_signal get_screenmirror; + struct wl_signal shoot; + } events; + + bool auto_rotation; +}; + +struct ds_tizen_screenshooter_client +{ + struct ds_tizen_screenshooter *shot; + struct ds_tizen_screenmirror *mirror; + struct wl_resource *res; + struct wl_client *client; + struct wl_list link; // ds_tizen_screenshooter::clients +}; + +struct ds_tizen_screenmirror +{ + struct wl_resource *resource; + struct ds_tizen_screenshooter_client *client; + struct wl_listener client_destroy_listener; + + struct { + struct wl_signal destroy; + struct wl_signal set_stretch; + struct wl_signal queue; + struct wl_signal dequeue; + struct wl_signal start; + struct wl_signal stop; + struct wl_signal set_auto_rotation; + } events; +}; + +struct ds_tizen_screenmirror * +ds_tizen_screenmirror_create(struct ds_tizen_screenshooter_client *client, + int version, uint32_t id); + +void +ds_tizen_screenmirror_destroy(struct ds_tizen_screenmirror *mirror); + +#endif diff --git a/tests/meson.build b/tests/meson.build index 030c3b0..e620eb0 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -324,3 +324,23 @@ executable('libds-tizen-policy-tests', install_dir: libds_tizen_bindir, install : true ) + +## screenshooter-compositor tests +tc_screenshooter_files = [ + 'tc_main.cpp', + 'tc_screenshooter.cpp', +] + +executable('libds-tizen-screenshooter-tests', + [ + tc_mock_files, + tc_screenshooter_files + ], + dependencies: [ + deps_test_common, + deps_libds_tizen_screenshooter, + dependency('tizen-extension-client', required: true), + ], + install_dir: libds_tizen_bindir, + install : true +) diff --git a/tests/tc_screenshooter.cpp b/tests/tc_screenshooter.cpp new file mode 100644 index 0000000..929ecdf --- /dev/null +++ b/tests/tc_screenshooter.cpp @@ -0,0 +1,747 @@ +#include +#include +#include +#ifdef TIZEN_SCREENMIRROR_STOP +#undef TIZEN_SCREENMIRROR_STOP +#endif +#include +#include +#include +#include +#include "tc_main.h" +#include "mockclient.h" +#include "mockcompositor.h" + +#define TIZEN_SCREENSHOOTER_VERSION 3 +#define SHM_BUF_WIDTH 1920 +#define SHM_BUF_HEIGHT 1080 +#define SHM_BUF_STRIDE 7680 //width * 4 +#define SHM_BUF_FORMAT WL_SHM_FORMAT_XRGB8888 + +class MockScreenShooterCompositor : public MockCompositor +{ +public: + MockScreenShooterCompositor() + : MockCompositor(&MockScreenShooterCompositor::TestSetup, this) + { + ds_inf("%s : this(%p)", __func__, this); + + bDestroyed = false; + bMirror = false; + bDestroyMirror = false; + bShoot = false; + bStart = false; + bAutoRotation = false; + mBackend = nullptr; + mBuffer = nullptr; + mOutput = nullptr;; + mScreenShooter = nullptr; + mScreenMirror = nullptr; + new_output = {}; + + mDestroyListener = {}; + mNewScreenMirrorListener = {}; + mScreenShootListener = {}; + mScreenMirrorDestroyListener = {}; + mScreenMirrorSetStretchListener = {}; + mScreenMirrorQueueListener = {}; + mScreenMirrorDequeueListener = {}; + mScreenMirrorStartListener = {}; + mScreenMirrorStopListener = {}; + mScreenMirrorAutoRotationListener = {}; + } + + ~MockScreenShooterCompositor() + { + ds_inf("%s : this(%p)", __func__, this); + } + + static void TestSetup(void *data) + { + MockScreenShooterCompositor *mockComp = + static_cast(data); + Compositor *comp = mockComp->compositor; + + ds_inf("%s: mockComp(%p)", __func__, mockComp); + + mockComp->mBackend = ds_wl_backend_create(comp->display, NULL); + mockComp->new_output.notify = screenshooter_backend_handle_new_output; + ds_backend_add_new_output_listener(mockComp->mBackend, &mockComp->new_output); + ds_backend_start(mockComp->mBackend); + + mockComp->mScreenShooter = + ds_tizen_screenshooter_create(comp->display); + + // add destroy listener + mockComp->mDestroyListener.notify = + MockScreenShooterCompositor::DestroyCallback; + mockComp->mDestroyListener.parent = mockComp; + ds_tizen_screenshooter_add_destroy_listener(mockComp->mScreenShooter, + &mockComp->mDestroyListener); + + // add newscreenmirror listener + mockComp->mNewScreenMirrorListener.notify = + MockScreenShooterCompositor::NewScreenMirrorCallback; + mockComp->mNewScreenMirrorListener.parent = mockComp; + ds_tizen_screenshooter_add_get_screenmirror_listener(mockComp->mScreenShooter, + &mockComp->mNewScreenMirrorListener); + + // add shoot listener + mockComp->mScreenShootListener.notify = + MockScreenShooterCompositor::ScreenShootCallback; + mockComp->mScreenShootListener.parent = mockComp; + ds_tizen_screenshooter_add_shoot_listener(mockComp->mScreenShooter, + &mockComp->mScreenShootListener); + } + + static void screenshooter_backend_handle_new_output(struct wl_listener *listener, + void *data) + { + MockScreenShooterCompositor *mockComp; + + mockComp = wl_container_of(listener, mockComp, new_output); + mockComp->mOutput = static_cast(data); + + ds_inf("New ds_output(%p)", mockComp->mOutput); + + ds_output_create_global(mockComp->mOutput); + ds_inf("create output global"); + } + + static void DestroyCallback(struct wl_listener *listener, void *data) + { + ds_inf("%s", __func__); + + MockScreenShooterCompositor *mockComp = + reinterpret_cast(listener)->parent; + + mockComp->bDestroyed = true; + } + + static void NewScreenMirrorCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenShooterCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_screenmirror *mirror = + static_cast(data); + + ds_inf("%s: mockComp(%p), mirror(%p)", __func__, mockComp, mirror); + + mockComp->bMirror = true; + mockComp->mScreenMirror = mirror; + + // add destroy listener + mockComp->mScreenMirrorDestroyListener.notify = + MockScreenShooterCompositor::ScreenMirrorDestroyCallback; + mockComp->mScreenMirrorDestroyListener.parent = mockComp; + ds_tizen_screenmirror_add_destroy_listener(mockComp->mScreenMirror, + &mockComp->mScreenMirrorDestroyListener); + + // add set_stretch listener + mockComp->mScreenMirrorSetStretchListener.notify = + MockScreenShooterCompositor::ScreenMirrorSetStretchCallback; + mockComp->mScreenMirrorSetStretchListener.parent = mockComp; + ds_tizen_screenmirror_add_set_stretch_listener(mockComp->mScreenMirror, + &mockComp->mScreenMirrorSetStretchListener); + + // add queue listener + mockComp->mScreenMirrorQueueListener.notify = + MockScreenShooterCompositor::ScreenMirrorQueueCallback; + mockComp->mScreenMirrorQueueListener.parent = mockComp; + ds_tizen_screenmirror_add_queue_listener(mockComp->mScreenMirror, + &mockComp->mScreenMirrorQueueListener); + + // add dequeue listener + mockComp->mScreenMirrorDequeueListener.notify = + MockScreenShooterCompositor::ScreenMirrorDequeueCallback; + mockComp->mScreenMirrorDequeueListener.parent = mockComp; + ds_tizen_screenmirror_add_dequeue_listener(mockComp->mScreenMirror, + &mockComp->mScreenMirrorDequeueListener); + + // add start listener + mockComp->mScreenMirrorStartListener.notify = + MockScreenShooterCompositor::ScreenMirrorStartCallback; + mockComp->mScreenMirrorStartListener.parent = mockComp; + ds_tizen_screenmirror_add_start_listener(mockComp->mScreenMirror, + &mockComp->mScreenMirrorStartListener); + + // add stop listener + mockComp->mScreenMirrorStopListener.notify = + MockScreenShooterCompositor::ScreenMirrorStopCallback; + mockComp->mScreenMirrorStopListener.parent = mockComp; + ds_tizen_screenmirror_add_stop_listener(mockComp->mScreenMirror, + &mockComp->mScreenMirrorStopListener); + + // add auto rotation listener + mockComp->mScreenMirrorAutoRotationListener.notify = + MockScreenShooterCompositor::ScreenMirrorAutoRotationCallback; + mockComp->mScreenMirrorAutoRotationListener.parent = mockComp; + ds_tizen_screenmirror_add_auto_rotation_listener(mockComp->mScreenMirror, + &mockComp->mScreenMirrorAutoRotationListener); + } + + static void ScreenShootCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenShooterCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_screenshooter_shoot_event *event = + static_cast(data); + + + ds_inf("%s: mockComp(%p), output(%p), buffer(%p), client(%p), auto_rotate:%d", + __func__, mockComp, event->output, event->buffer, event->client, + event->auto_rotation ? 1 : 0); + + mockComp->bShoot = true; + ds_tizen_screenshooter_send_shoot_done(mockComp->mScreenShooter, event->client); + } + + static void ScreenMirrorDestroyCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenShooterCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_tizen_screenmirror *mirror = + static_cast(data); + + ds_inf("%s: mockComp(%p), info(%p)", __func__, mockComp, mirror); + + if (mockComp->mScreenMirror == mirror) { + ds_inf("%s: info is deleted.", __func__); + mockComp->bDestroyMirror = true; + } + } + + static void ScreenMirrorSetStretchCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenShooterCompositor *mockComp = + reinterpret_cast(listener)->parent; + enum ds_tizen_screenmirror_stretch *stretch = (enum ds_tizen_screenmirror_stretch *)data; + + ds_inf("%s: mockComp(%p), stretch(%d)", __func__, mockComp, *stretch); + } + + static void ScreenMirrorQueueCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenShooterCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_buffer *buffer = + static_cast(data); + + ds_inf("%s: mockComp(%p), queue(%p)", __func__, mockComp, buffer); + } + + static void ScreenMirrorDequeueCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenShooterCompositor *mockComp = + reinterpret_cast(listener)->parent; + struct ds_buffer *buffer = + static_cast(data); + + ds_inf("%s: mockComp(%p), dequeue(%p)", __func__, mockComp, buffer); + + ds_tizen_screenmirror_send_dequeued(mockComp->mScreenMirror, buffer); + } + + static void ScreenMirrorStartCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenShooterCompositor *mockComp = + reinterpret_cast(listener)->parent; + + ds_inf("%s: mockComp(%p), start", __func__, mockComp); + + mockComp->bStart = true; + } + + static void ScreenMirrorStopCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenShooterCompositor *mockComp = + reinterpret_cast(listener)->parent; + + ds_inf("%s: mockComp(%p), stop", __func__, mockComp); + + mockComp->bStart = false; + } + + static void ScreenMirrorAutoRotationCallback(struct wl_listener *listener, + void *data) + { + ds_inf("%s", __func__); + + MockScreenShooterCompositor *mockComp = + reinterpret_cast(listener)->parent; + uint32_t *set = (uint32_t *)data; + + ds_inf("%s: mockComp(%p), autorotation(%d)", __func__, mockComp, *set); + + if (*set) + mockComp->bAutoRotation = true; + else + mockComp->bAutoRotation = false; + } + +public: + bool bDestroyed; + + bool bMirror; + bool bDestroyMirror; + bool bShoot; + bool bStart; + bool bAutoRotation; + +private: + struct ds_backend *mBackend; + struct ds_buffer *mBuffer; + struct ds_output *mOutput; + struct ds_tizen_screenshooter *mScreenShooter; + struct ds_tizen_screenmirror *mScreenMirror; + struct wl_listener new_output; + + struct DestroyListener : ::wl_listener { + MockScreenShooterCompositor *parent; + }; + DestroyListener mDestroyListener; + + struct NewScreenMirrorListener : ::wl_listener { + MockScreenShooterCompositor *parent; + }; + NewScreenMirrorListener mNewScreenMirrorListener; + + struct ScreenShootListener : ::wl_listener { + MockScreenShooterCompositor *parent; + }; + ScreenShootListener mScreenShootListener; + + struct ScreenMirrorDestroyListener : ::wl_listener { + MockScreenShooterCompositor *parent; + }; + ScreenMirrorDestroyListener mScreenMirrorDestroyListener; + + struct ScreenMirrorSetStretchListener : ::wl_listener { + MockScreenShooterCompositor *parent; + }; + ScreenMirrorSetStretchListener mScreenMirrorSetStretchListener; + + struct ScreenMirrorQueueListener : ::wl_listener { + MockScreenShooterCompositor *parent; + }; + ScreenMirrorQueueListener mScreenMirrorQueueListener; + + struct ScreenMirrorDequeueListener : ::wl_listener { + MockScreenShooterCompositor *parent; + }; + ScreenMirrorDequeueListener mScreenMirrorDequeueListener; + + struct ScreenMirrorStartListener : ::wl_listener { + MockScreenShooterCompositor *parent; + }; + ScreenMirrorStartListener mScreenMirrorStartListener; + + struct ScreenMirrorStopListener : ::wl_listener { + MockScreenShooterCompositor *parent; + }; + ScreenMirrorStopListener mScreenMirrorStopListener; + + struct ScreenMirrorAutoRotationListener : ::wl_listener { + MockScreenShooterCompositor *parent; + }; + ScreenMirrorAutoRotationListener mScreenMirrorAutoRotationListener; +}; + +class MockScreenShooterClient : public MockClient +{ +public: + MockScreenShooterClient() + : bShootEvent(false), + bMirrorStartEvent(false), + bMirrorStopEvent(false), + output_res(nullptr), + shm_res(nullptr), + shm_pool(nullptr), + screenshooter_res(nullptr), + screenmirror_res(nullptr) + {} + MockScreenShooterClient(const struct wl_registry_listener *listener) + : MockClient(listener, this) + { + ds_inf("%s", __func__); + + bShootEvent = false; + bMirrorStartEvent = false; + bMirrorStopEvent = false; + output_res = nullptr; + shm_res = nullptr; + shm_pool = nullptr; + screenshooter_res = nullptr; + screenmirror_res = nullptr; + } + ~MockScreenShooterClient() + { + ds_inf("%s", __func__); + } + + void SetWlOutput(struct wl_output *global_res) + { + ds_inf("%s", __func__); + + output_res = global_res; + } + + struct wl_output *GetWlOutput() + { + ds_inf("%s", __func__); + + return output_res; + } + + void SetWlShm(struct wl_shm *global_res) + { + ds_inf("%s", __func__); + + shm_res = global_res; + } + + struct wl_shm *GetWlShm() + { + ds_inf("%s", __func__); + + return shm_res; + } + + void SetWlShmPool(struct wl_shm_pool *_shm_pool) + { + ds_inf("%s", __func__); + + shm_pool = _shm_pool; + } + + struct wl_shm_pool *GetWlShmPool() + { + ds_inf("%s", __func__); + + return shm_pool; + } + + void SetTizenScreenShooter(struct tizen_screenshooter *resource) + { + ds_inf("%s", __func__); + + screenshooter_res = resource; + } + + struct tizen_screenshooter *GetTizenScreenShooter() + { + ds_inf("%s", __func__); + + return screenshooter_res; + } + + + void SetTizenScreenMirror(struct tizen_screenmirror *resource) + { + ds_inf("%s", __func__); + + screenmirror_res = resource; + } + + struct tizen_screenmirror *GetTizenScreenMirror() + { + ds_inf("%s", __func__); + + return screenmirror_res; + } + +public: + bool bShootEvent; + bool bMirrorStartEvent; + bool bMirrorStopEvent; + +private: + struct wl_output *output_res; + struct wl_shm *shm_res; + struct wl_shm_pool *shm_pool; + struct tizen_screenshooter *screenshooter_res; + struct tizen_screenmirror *screenmirror_res; +}; + +static void +client_tizen_screenshooter_cb_format(void *data, + struct tizen_screenshooter *screenshooter_res, uint32_t format) +{ +} + +static void +client_tizen_screenshooter_cb_noti(void *data, + struct tizen_screenshooter *screenshooter_res, uint32_t noti) +{ + ds_inf("noti : %d"); +} + +static void +client_tizen_screenshooter_cb_done(void *data, + struct tizen_screenshooter *screenshooter_res) +{ + MockScreenShooterClient *client = static_cast(data); + + client->bShootEvent = true; +} + +static const struct +tizen_screenshooter_listener screenshooter_cb_listener = { + client_tizen_screenshooter_cb_format, + client_tizen_screenshooter_cb_noti, + client_tizen_screenshooter_cb_done, +}; + +static void +_client_tizen_screenshooter_destroy_anonymous_file(int fd) +{ + if (fd < 0) + return; + + close(fd); +} + +static int +_client_tizen_screenshooter_create_anonymous_file(off_t size) +{ + static const char tempname[] = "/shooter-XXXXXX"; + const char *path; + char *name = NULL; + int fd = -1; + int ret = -1; + int path_len = 0; + + path = getenv("XDG_RUNTIME_DIR"); + if (!path) { + errno = ENOENT; + return -1; + } + path_len = strlen(path); + if (path_len == 0) + return -1; + + name = (char *)malloc(path_len + (int)sizeof(tempname)); + if (name == NULL) + return -1; + + strncpy(name, path, path_len); + strncat(name, tempname, (int)sizeof(tempname)); + + fd = mkstemp(name); + if (fd >= 0) + unlink(name); + + free(name); + + if (fd < 0) + return -1; + + ret = ftruncate(fd, size); + if (ret < 0) { + close(fd); + return -1; + } + + return fd; +} + +static struct wl_shm_pool * +_client_tizen_screenshooter_create_shm_pool(struct wl_shm *shm, int size) +{ + struct wl_shm_pool *shm_pool = NULL; + void *data = NULL; + int fd = -1; + + fd = _client_tizen_screenshooter_create_anonymous_file(size); + if (fd < 0) + goto fail; + + data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (data == NULL) + goto fail; + + memset(data, 0xff, size); + munmap(data, size); + + shm_pool = wl_shm_create_pool(shm, fd, size); + if (shm_pool == NULL) + goto fail; + + _client_tizen_screenshooter_destroy_anonymous_file(fd); + + return shm_pool; + +fail: + if (fd > 0) + _client_tizen_screenshooter_destroy_anonymous_file(fd); + + return NULL; +} + +void +_client_tizen_screenshooter_destroy_shm_pool(struct wl_shm_pool *shm_pool) +{ + if (!shm_pool) + return; + + wl_shm_pool_destroy(shm_pool); +} + +static void +client_registry_cb_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) +{ + ds_inf("%s", __func__); + + MockScreenShooterClient *client = static_cast(data); + struct tizen_screenshooter *screenshooter_res; + struct wl_shm *shm_res; + struct wl_shm_pool *shm_pool; + struct wl_output *output_res; + + if (!strcmp(interface, "wl_shm")) { + shm_res = (struct wl_shm *)wl_registry_bind(registry, + name, &wl_shm_interface, 1); + if (shm_res == nullptr) { + ds_err("wl_registry_bind() failed. wl_shm resource."); + return; + } + shm_pool = _client_tizen_screenshooter_create_shm_pool(shm_res, SHM_BUF_WIDTH * 4 * SHM_BUF_HEIGHT); + if (shm_pool == NULL) { + ds_err("wl_registry_bind() failed. wl_shm_pool create fail."); + wl_shm_destroy(shm_res); + return; + } + client->SetWlShm(shm_res); + client->SetWlShmPool(shm_pool); + } else if (!strcmp(interface, "wl_output")) { + output_res = (struct wl_output *)wl_registry_bind(registry, + name, &wl_output_interface, 1); + if (output_res == nullptr) { + ds_err("wl_registry_bind() failed. wl_output resource."); + return; + } + client->SetWlOutput(output_res); + } else if (!strcmp(interface, "tizen_screenshooter")) { + screenshooter_res = (struct tizen_screenshooter *)wl_registry_bind(registry, + name, &tizen_screenshooter_interface, TIZEN_SCREENSHOOTER_VERSION); + if (screenshooter_res == nullptr) { + ds_err("wl_registry_bind() failed. tizen_screenshooter resource."); + return; + } + client->SetTizenScreenShooter(screenshooter_res); + + tizen_screenshooter_add_listener(screenshooter_res, + &screenshooter_cb_listener, client); + } +} + +static void +client_registry_cb_global_remove(void *data, struct wl_registry *registry, + uint32_t name) +{ + ds_inf("%s", __func__); + + MockScreenShooterClient *client = static_cast(data); + struct wl_shm *shm_res = client->GetWlShm(); + struct wl_shm_pool *shm_pool = client->GetWlShmPool(); + struct tizen_screenshooter *screenshooter_res = client->GetTizenScreenShooter(); + struct tizen_screenmirror *screenmirror_res = client->GetTizenScreenMirror(); + + if (screenmirror_res) + tizen_screenmirror_destroy(screenmirror_res); + tizen_screenshooter_destroy(screenshooter_res); + _client_tizen_screenshooter_destroy_shm_pool(shm_pool); + wl_shm_destroy(shm_res); +} + +static const struct wl_registry_listener registry_listener = { + .global = client_registry_cb_global, + .global_remove = client_registry_cb_global_remove +}; + +class ScreenShooterTest : public ::testing::Test +{ +public: + void SetUp(void) override; + void TearDown(void) override; + + MockScreenShooterCompositor *comp; + MockScreenShooterClient *client; + struct wl_output *output_res; + struct wl_shm *shm_res; + struct wl_shm_pool *shm_pool; + struct wl_buffer *buffer_res1; + struct wl_buffer *buffer_res2; + struct wl_buffer *buffer_res3; + struct tizen_screenshooter *screenshooter_res; + struct tizen_screenmirror *screenmirror_res; +}; + +void +ScreenShooterTest::SetUp(void) +{ + //ds_log_init(DS_DBG, NULL); + + ds_inf("%s", __func__); + + comp = new MockScreenShooterCompositor(); + client = new MockScreenShooterClient(®istry_listener); + output_res = client->GetWlOutput(); + shm_res = client->GetWlShm(); + shm_pool = client->GetWlShmPool(); + screenshooter_res = client->GetTizenScreenShooter(); + + client->RoundTrip(); +} + +void +ScreenShooterTest::TearDown(void) +{ + ds_inf("%s", __func__); + + client->RoundTrip(); + + delete client; + delete comp; +} + +TEST_F(ScreenShooterTest, Create_P) +{ + EXPECT_TRUE(true); +} + +TEST_F(ScreenShooterTest, Req_TizenScreenShooterShot) +{ + buffer_res1 = wl_shm_pool_create_buffer(shm_pool, 0, + SHM_BUF_WIDTH, SHM_BUF_HEIGHT, SHM_BUF_STRIDE, SHM_BUF_FORMAT); + tizen_screenshooter_shoot(screenshooter_res, output_res, buffer_res1); + client->RoundTrip(); + EXPECT_TRUE(comp->bShoot); + comp->Process(); + EXPECT_TRUE(client->bShootEvent); +} -- 2.7.4