text: add pre-edit styling support to protocol
authorJan Arne Petersen <jpetersen@openismus.com>
Wed, 16 Jan 2013 20:26:38 +0000 (21:26 +0100)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 15 Feb 2013 21:55:27 +0000 (16:55 -0500)
Also add a separate preedit-cursor event and add a commit argument to
preedit-string to allow to support commit on reset. Fix editor and
keyboard example to adapt to the protocol changes.

Signed-off-by: Jan Arne Petersen <jpetersen@openismus.com>
clients/editor.c
clients/keyboard.c
clients/weston-simple-im.c
protocol/input-method.xml
protocol/text.xml
src/text-backend.c

index b42b5a1..2198813 100644 (file)
@@ -51,8 +51,14 @@ struct text_entry {
        int active;
        uint32_t cursor;
        uint32_t anchor;
-       char *preedit_text;
-       uint32_t preedit_cursor;
+       struct {
+               char *text;
+               int32_t cursor;
+               char *commit;
+       } preedit;
+       struct {
+               int32_t cursor;
+       } preedit_info;
        struct text_model *model;
        struct text_layout *layout;
        struct {
@@ -312,17 +318,12 @@ static void
 text_model_preedit_string(void *data,
                          struct text_model *text_model,
                          const char *text,
-                         uint32_t index)
+                         const char *commit)
 {
        struct text_entry *entry = data;
 
-       if (index > strlen(text)) {
-               fprintf(stderr, "Invalid cursor index %d\n", index);
-               index = strlen(text);
-       }
-
        text_entry_delete_selected_text(entry);
-       text_entry_set_preedit(entry, text, index);
+       text_entry_set_preedit(entry, text, entry->preedit_info.cursor);
 
        widget_schedule_redraw(entry->widget);
 }
@@ -360,8 +361,21 @@ text_model_delete_surrounding_text(void *data,
 
 static void
 text_model_preedit_styling(void *data,
-                          struct text_model *text_model)
+                          struct text_model *text_model,
+                          uint32_t index,
+                          uint32_t length,
+                          uint32_t style)
+{
+}
+
+static void
+text_model_preedit_cursor(void *data,
+                         struct text_model *text_model,
+                         int32_t index)
 {
+       struct text_entry *entry = data;
+
+       entry->preedit_info.cursor = index;
 }
 
 static void
@@ -474,6 +488,7 @@ static const struct text_model_listener text_model_listener = {
        text_model_preedit_string,
        text_model_delete_surrounding_text,
        text_model_preedit_styling,
+       text_model_preedit_cursor,
        text_model_modifiers_map,
        text_model_keysym,
        text_model_selection_replacement,
@@ -496,8 +511,6 @@ text_entry_create(struct editor *editor, const char *text)
        entry->active = 0;
        entry->cursor = strlen(text);
        entry->anchor = entry->cursor;
-       entry->preedit_text = NULL;
-       entry->preedit_cursor = 0;
        entry->model = text_model_factory_create_text_model(editor->text_model_factory);
        text_model_add_listener(entry->model, &text_model_listener, entry);
 
@@ -600,17 +613,17 @@ text_entry_update_layout(struct text_entry *entry)
        char *text;
 
        assert(((unsigned int)entry->cursor) <= strlen(entry->text) +
-              (entry->preedit_text ? strlen(entry->preedit_text) : 0));
+              (entry->preedit.text ? strlen(entry->preedit.text) : 0));
 
-       if (!entry->preedit_text) {
+       if (!entry->preedit.text) {
                text_layout_set_text(entry->layout, entry->text);
                return;
        }
 
-       text = malloc(strlen(entry->text) + strlen(entry->preedit_text) + 1);
+       text = malloc(strlen(entry->text) + strlen(entry->preedit.text) + 1);
        strncpy(text, entry->text, entry->cursor);
-       strcpy(text + entry->cursor, entry->preedit_text);
-       strcpy(text + entry->cursor + strlen(entry->preedit_text),
+       strcpy(text + entry->cursor, entry->preedit.text);
+       strcpy(text + entry->cursor + strlen(entry->preedit.text),
               entry->text + entry->cursor);
 
        text_layout_set_text(entry->layout, text);
@@ -647,17 +660,17 @@ text_entry_set_preedit(struct text_entry *entry,
                       const char *preedit_text,
                       int preedit_cursor)
 {
-       if (entry->preedit_text) {
-               free(entry->preedit_text);
-               entry->preedit_text = NULL;
-               entry->preedit_cursor = 0;
+       if (entry->preedit.text) {
+               free(entry->preedit.text);
+               entry->preedit.text = NULL;
+               entry->preedit.cursor = 0;
        }
 
        if (!preedit_text)
                return;
 
-       entry->preedit_text = strdup(preedit_text);
-       entry->preedit_cursor = preedit_cursor;
+       entry->preedit.text = strdup(preedit_text);
+       entry->preedit.cursor = preedit_cursor;
 
        text_entry_update_layout(entry);
 }
@@ -670,8 +683,9 @@ text_entry_set_cursor_position(struct text_entry *entry,
 
        text_model_reset(entry->model);
 
-       if (entry->cursor >= entry->preedit_cursor) {
-               entry->cursor -= entry->preedit_cursor;
+       if (entry->preedit.cursor > 0 &&
+           entry->cursor >= (uint32_t)entry->preedit.cursor) {
+               entry->cursor -= entry->preedit.cursor;
        }
 
        text_entry_update_layout(entry);
@@ -760,9 +774,12 @@ text_entry_draw_cursor(struct text_entry *entry, cairo_t *cr)
        cairo_text_extents_t extents;
        cairo_rectangle_t cursor_pos;
 
+       if (entry->preedit.text && entry->preedit.cursor < 0)
+               return;
+
        text_layout_extents(entry->layout, &extents);
        text_layout_get_cursor_pos(entry->layout,
-                                  entry->cursor + entry->preedit_cursor,
+                                  entry->cursor + entry->preedit.cursor,
                                   &cursor_pos);
 
        cairo_set_line_width(cr, 1.0);
@@ -778,14 +795,14 @@ text_entry_draw_preedit(struct text_entry *entry, cairo_t *cr)
        cairo_rectangle_t start;
        cairo_rectangle_t end;
 
-       if (!entry->preedit_text)
+       if (!entry->preedit.text)
                return;
 
        text_layout_extents(entry->layout, &extents);
 
        text_layout_index_to_pos(entry->layout, entry->cursor, &start);
        text_layout_index_to_pos(entry->layout,
-                                entry->cursor + strlen(entry->preedit_text),
+                                entry->cursor + strlen(entry->preedit.text),
                                 &end);
 
        cairo_save (cr);
index ff35617..a32cf60 100644 (file)
@@ -226,9 +226,11 @@ virtual_keyboard_commit_preedit(struct virtual_keyboard *keyboard)
            strlen(keyboard->preedit_string) == 0)
                return;
 
+       input_method_context_preedit_cursor(keyboard->context,
+                                           0);
        input_method_context_preedit_string(keyboard->context,
                                            "",
-                                           0);
+                                           "");
        input_method_context_commit_string(keyboard->context,
                                           keyboard->preedit_string,
                                           strlen(keyboard->preedit_string));
@@ -250,9 +252,11 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
 
                        keyboard->keyboard->preedit_string = strcat(keyboard->keyboard->preedit_string,
                                                                    label);
+                       input_method_context_preedit_cursor(keyboard->keyboard->context,
+                                                           strlen(keyboard->keyboard->preedit_string));
                        input_method_context_preedit_string(keyboard->keyboard->context,
                                                            keyboard->keyboard->preedit_string,
-                                                           strlen(keyboard->keyboard->preedit_string));
+                                                           keyboard->keyboard->preedit_string);
                        break;
                case keytype_backspace:
                        if (state != WL_POINTER_BUTTON_STATE_PRESSED)
@@ -263,9 +267,11 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *
                                                                             -1, 1);
                        } else {
                                keyboard->keyboard->preedit_string[strlen(keyboard->keyboard->preedit_string) - 1] = '\0';
+                               input_method_context_preedit_cursor(keyboard->keyboard->context,
+                                                                   strlen(keyboard->keyboard->preedit_string));
                                input_method_context_preedit_string(keyboard->keyboard->context,
                                                                    keyboard->keyboard->preedit_string,
-                                                                   strlen(keyboard->keyboard->preedit_string));
+                                                                   keyboard->keyboard->preedit_string);
                        }
                        break;
                case keytype_enter:
@@ -386,9 +392,11 @@ input_method_context_reset(void *data,
        fprintf(stderr, "Reset pre-edit buffer\n");
 
        if (strlen(keyboard->preedit_string)) {
+               input_method_context_preedit_cursor(context,
+                                                   0);
                input_method_context_preedit_string(context,
                                                    "",
-                                                   0);
+                                                   "");
                free(keyboard->preedit_string);
                keyboard->preedit_string = strdup("");
        }
index 46887e8..1b6a3fd 100644 (file)
@@ -370,8 +370,10 @@ simple_im_key_handler(struct simple_im *keyboard,
 
                if (cs) {
                        if (cs->keys[i + 1] == 0) {
+                               input_method_context_preedit_cursor(keyboard->context,
+                                                                   0);
                                input_method_context_preedit_string(keyboard->context,
-                                                                   "", 0);
+                                                                   "", "");
                                input_method_context_commit_string(keyboard->context,
                                                                   cs->text,
                                                                   strlen(cs->text));
@@ -383,9 +385,11 @@ simple_im_key_handler(struct simple_im *keyboard,
                                        idx += xkb_keysym_to_utf8(cs->keys[j], text + idx, sizeof(text) - idx);
                                }
 
+                               input_method_context_preedit_cursor(keyboard->context,
+                                                                   strlen(text));
                                input_method_context_preedit_string(keyboard->context,
                                                                    text,
-                                                                   strlen(text));
+                                                                   text);
                        }
                } else {
                        uint32_t j = 0, idx = 0;
@@ -393,8 +397,10 @@ simple_im_key_handler(struct simple_im *keyboard,
                        for (; j <= i; j++) {
                                idx += xkb_keysym_to_utf8(keyboard->compose_seq.keys[j], text + idx, sizeof(text) - idx);
                        }
+                       input_method_context_preedit_cursor(keyboard->context,
+                                                           0);
                        input_method_context_preedit_string(keyboard->context,
-                                                           "", 0);
+                                                           "", "");
                        input_method_context_commit_string(keyboard->context,
                                                           text,
                                                           strlen(text));
index 487be0b..20d3667 100644 (file)
         Send the pre-edit string text to the applications text model.
       </description>
       <arg name="text" type="string"/>
+      <arg name="commit" type="string"/>
+    </request>
+    <request name="preedit_styling">
       <arg name="index" type="uint"/>
+      <arg name="length" type="uint"/>
+      <arg name="style" type="uint"/>
+    </request>
+    <request name="preedit_cursor">
+      <description summary="pre-edit cursor">
+        Sets the cursor position inside the composing text (as byte index)
+        relative to the start of the composing text.
+      </description>
+      <arg name="index" type="int"/>
     </request>
     <request name="delete_surrounding_text">
       <arg name="index" type="int"/>
index 4701f7d..5efeec8 100644 (file)
@@ -73,7 +73,7 @@
         be reseted, for example after the text was changed outside of the
         normal input method flow.
       </description>
-     </request>
+    </request>
     <request name="set_micro_focus">
       <arg name="x" type="int"/>
       <arg name="y" type="int"/>
         to the start of the composing text.
       </description>
       <arg name="text" type="string"/>
-      <arg name="index" type="uint"/>
+      <arg name="commit" type="string"/>
     </event>
     <event name="delete_surrounding_text">
       <description summary="delete surrounding text">
       <arg name="index" type="int"/>
       <arg name="length" type="uint"/>
     </event>
-    <event name="preedit_styling"/>
+    <enum name="preedit_style">
+      <entry name="default" value="1"/>
+      <entry name="active" value="2"/>
+      <entry name="inactive" value="3"/>
+      <entry name="highlight" value="4"/>
+      <entry name="underline" value="5"/>
+      <entry name="selection" value="6"/>
+      <entry name="incorrect" value="7"/>
+    </enum>
+    <event name="preedit_styling">
+      <arg name="index" type="uint"/>
+      <arg name="length" type="uint"/>
+      <arg name="style" type="uint"/>
+    </event>
+    <event name="preedit_cursor">
+      <description summary="pre-edit cursor">
+        Sets the cursor position inside the composing text (as byte index)
+        relative to the start of the composing text.
+      </description>
+      <arg name="index" type="int"/>
+    </event>
     <event name="modifiers_map">
       <description summary="modifiers map">
         Transfer an array of 0-terminated modifiers names. The position in
index d123da9..7f8c16e 100644 (file)
@@ -338,13 +338,35 @@ input_method_context_commit_string(struct wl_client *client,
 
 static void
 input_method_context_preedit_string(struct wl_client *client,
-                                  struct wl_resource *resource,
-                                  const char *text,
-                                  uint32_t index)
+                                   struct wl_resource *resource,
+                                   const char *text,
+                                   const char *commit)
+{
+       struct input_method_context *context = resource->data;
+
+       text_model_send_preedit_string(&context->model->resource, text, commit);
+}
+
+static void
+input_method_context_preedit_styling(struct wl_client *client,
+                                    struct wl_resource *resource,
+                                    uint32_t index,
+                                    uint32_t length,
+                                    uint32_t style)
+{
+       struct input_method_context *context = resource->data;
+
+       text_model_send_preedit_styling(&context->model->resource, index, length, style);
+}
+
+static void
+input_method_context_preedit_cursor(struct wl_client *client,
+                                   struct wl_resource *resource,
+                                   int32_t cursor)
 {
        struct input_method_context *context = resource->data;
 
-       text_model_send_preedit_string(&context->model->resource, text, index);
+       text_model_send_preedit_cursor(&context->model->resource, cursor);
 }
 
 static void
@@ -495,6 +517,8 @@ static const struct input_method_context_interface input_method_context_implemen
        input_method_context_destroy,
        input_method_context_commit_string,
        input_method_context_preedit_string,
+       input_method_context_preedit_styling,
+       input_method_context_preedit_cursor,
        input_method_context_delete_surrounding_text,
        input_method_context_modifiers_map,
        input_method_context_keysym,