From: duna.oh Date: Wed, 7 Sep 2022 06:44:23 +0000 (+0900) Subject: clients: merge text-entry code to simple-tbm X-Git-Tag: accepted/tizen/unified/20220908.124855~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1bd5d3b200f9c1dc7d7f02c863a0cd21bf206fac;p=platform%2Fcore%2Fuifw%2Flibds-tizen.git clients: merge text-entry code to simple-tbm Change-Id: I9c74e6155cb570d74cdb24c6b05e0515cc8362bf --- 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