#include <tbm_surface_internal.h>
#include "xdg-shell-client-protocol.h"
#include <tizen-extension-client-protocol.h>
+#include <text-client-protocol.h>
+#include <xkbcommon/xkbcommon.h>
static uint64_t buffer_info_key;
#define BUFFER_INFO_KEY (unsigned long)(&buffer_info_key)
+struct text_entry;
struct display {
struct wl_display *display;
int notified;
bool blocked;
struct wl_surface *entered_surface;
+
+ struct wl_text_input_manager *text_input_mgr;
+ struct text_entry *entry;
};
struct 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,
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);
+ }
}
}
.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)
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");
}
}
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);
+++ /dev/null
-/*
- * 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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <assert.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <signal.h>
-#include <errno.h>
-
-#include <wayland-client.h>
-#include <wayland-tbm-client.h>
-#include <tbm_surface.h>
-#include <tbm_surface_internal.h>
-#include "xdg-shell-client-protocol.h"
-#include <text-client-protocol.h>
-#include <xkbcommon/xkbcommon.h>
-
-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;
-}