[PATCH 2/3] text: add preedit_string and a reset event
Philipp Brüschweiler
blei42 at gmail.com
Sun Jul 22 15:07:39 PDT 2012
---
clients/editor.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++-------
protocol/text.xml | 6 +++++
src/text-backend.c | 23 ++++++++++++++--
3 Dateien geändert, 95 Zeilen hinzugefügt(+), 11 Zeilen entfernt(-)
diff --git a/clients/editor.c b/clients/editor.c
index 19f7073..ba235bc 100644
--- a/clients/editor.c
+++ b/clients/editor.c
@@ -31,9 +31,16 @@
#include "window.h"
#include "text-client-protocol.h"
+struct buffer {
+ char *data;
+ size_t length;
+ size_t capacity;
+};
+
struct text_entry {
struct widget *widget;
- char *text;
+ struct buffer text;
+ struct buffer preedit;
int active;
struct rectangle allocation;
struct text_model *model;
@@ -49,12 +56,41 @@ struct editor {
};
static void
-text_entry_append(struct text_entry *entry, const char *text)
+buffer_append(struct buffer *buffer, const char *text)
+{
+ size_t new_length = strlen(text) + buffer->length;
+ if (new_length > buffer->capacity) {
+ buffer->data = realloc(buffer->data, new_length);
+ buffer->capacity = new_length;
+ }
+ strcat(buffer->data, text);
+ buffer->length = new_length;
+}
+
+static void
+buffer_set(struct buffer *buffer, const char *text)
+{
+ size_t length = strlen(text) + 1;
+ if (length > buffer->length) {
+ buffer->data = realloc(buffer->data, length);
+ buffer->capacity = length;
+ }
+ strcpy(buffer->data, text);
+ buffer->length = length;
+}
+
+static void
+text_entry_commit(struct text_entry *entry, const char *text)
{
- entry->text = realloc(entry->text, strlen(entry->text) + strlen(text) + 1);
- strcat(entry->text, text);
+ buffer_set(&entry->preedit, "");
+ buffer_append(&entry->text, text);
}
+static void
+text_entry_preedit(struct text_entry *entry, const char *text)
+{
+ buffer_set(&entry->preedit, text);
+}
static void
text_model_commit_string(void *data,
@@ -64,13 +100,27 @@ text_model_commit_string(void *data,
{
struct text_entry *entry = data;
- text_entry_append(entry, text);
+ text_entry_commit(entry, text);
+
+ widget_schedule_redraw(entry->widget);
+}
+
+static void
+text_model_preedit_string(void *data,
+ struct text_model *text_model,
+ const char *text,
+ uint32_t index)
+{
+ struct text_entry *entry = data;
+
+ text_entry_preedit(entry, text);
widget_schedule_redraw(entry->widget);
}
static const struct text_model_listener text_model_listener = {
- text_model_commit_string
+ text_model_commit_string,
+ text_model_preedit_string
};
static struct text_entry*
@@ -84,7 +134,10 @@ text_entry_create(struct editor *editor, const char *text)
surface = window_get_wl_surface(editor->window);
entry->widget = editor->widget;
- entry->text = strdup(text);
+ entry->text.data = strdup(text);
+ entry->text.length = entry->text.capacity = strlen(text) + 1;
+ entry->preedit.data = calloc(1, 1);
+ entry->preedit.length = entry->preedit.capacity = 1;
entry->active = 0;
entry->model = text_model_manager_create_text_model(editor->text_model_manager, surface);
text_model_add_listener(entry->model, &text_model_listener, entry);
@@ -96,7 +149,8 @@ static void
text_entry_destroy(struct text_entry *entry)
{
text_model_destroy(entry->model);
- free(entry->text);
+ free(entry->text.data);
+ free(entry->preedit.data);
free(entry);
}
@@ -126,7 +180,8 @@ text_entry_draw(struct text_entry *entry, cairo_t *cr)
cairo_set_font_size(cr, 14);
cairo_translate(cr, 10, entry->allocation.height / 2);
- cairo_show_text(cr, entry->text);
+ cairo_show_text(cr, entry->text.data);
+ cairo_show_text(cr, entry->preedit.data);
cairo_restore(cr);
}
@@ -211,6 +266,10 @@ text_entry_activate(struct text_entry *entry)
static void
text_entry_deactivate(struct text_entry *entry)
{
+ if (entry->preedit.length > 1) {
+ buffer_set(&entry->preedit, "");
+ widget_schedule_redraw(entry->widget);
+ }
text_model_deactivate(entry->model);
}
diff --git a/protocol/text.xml b/protocol/text.xml
index 42c8f35..9324668 100644
--- a/protocol/text.xml
+++ b/protocol/text.xml
@@ -48,8 +48,14 @@
<arg name="text" type="string"/>
<arg name="index" type="uint"/>
</request>
+ <request name="preedit_string">
+ <arg name="text" type="string"/>
+ <arg name="index" type="uint"/>
+ </request>
<request name="request_keyboard">
<arg name="keyboard" type="new_id" interface="wl_keyboard"/>
</request>
+
+ <event name="reset"/>
</interface>
</protocol>
diff --git a/src/text-backend.c b/src/text-backend.c
index 5b1b00d..41905ac 100644
--- a/src/text-backend.c
+++ b/src/text-backend.c
@@ -55,15 +55,19 @@ deactivate_text_model(struct text_model *text_model)
{
struct weston_compositor *ec = text_model->input_method->ec;
struct wl_keyboard_grab *grab = &text_model->grab;
+ struct input_method *input_method = text_model->input_method;
if (grab->keyboard && (grab->keyboard->grab == grab)) {
wl_keyboard_end_grab(grab->keyboard);
weston_log("end keyboard grab\n");
}
- if (text_model->input_method->active_model == text_model) {
- text_model->input_method->active_model = NULL;
+ if (input_method->active_model == text_model) {
+ input_method->active_model = NULL;
wl_signal_emit(&ec->hide_input_panel_signal, ec);
+ if (input_method->input_method_binding) {
+ input_method_send_reset(input_method->input_method_binding);
+ }
}
}
@@ -262,6 +266,20 @@ input_method_commit_string(struct wl_client *client,
}
static void
+input_method_preedit_string(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *text,
+ uint32_t index)
+{
+ struct input_method *input_method = resource->data;
+
+ if (input_method->active_model) {
+ text_model_send_preedit_string(
+ &input_method->active_model->resource, text, index);
+ }
+}
+
+static void
unbind_keyboard_binding(struct wl_resource *resource)
{
struct input_method *input_method = resource->data;
@@ -300,6 +318,7 @@ input_method_request_keyboard(struct wl_client *client,
static const struct input_method_interface input_method_implementation = {
input_method_commit_string,
+ input_method_preedit_string,
input_method_request_keyboard
};
--
1.7.11.2
More information about the wayland-devel
mailing list