text: Add delete_surrounding_text to protocol

Add delete_surrounding_text event in the text_model interface and the
request in the input_method_context interface. Implement it in the
example editor client and in the example keyboard so that the backspace
key works with it.

Signed-off-by: Jan Arne Petersen <jpetersen@openismus.com>
diff --git a/clients/editor.c b/clients/editor.c
index b6a1742..0ed217f 100644
--- a/clients/editor.c
+++ b/clients/editor.c
@@ -212,6 +212,8 @@
 static void text_entry_set_preedit(struct text_entry *entry,
 				   const char *preedit_text,
 				   int preedit_cursor);
+static void text_entry_delete_text(struct text_entry *entry,
+				   uint32_t index, uint32_t length);
 
 static void
 text_model_commit_string(void *data,
@@ -250,6 +252,31 @@
 }
 
 static void
+text_model_delete_surrounding_text(void *data,
+				   struct text_model *text_model,
+				   int32_t index,
+				   uint32_t length)
+{
+	struct text_entry *entry = data;
+	uint32_t cursor_index = index + entry->cursor;
+
+	if (cursor_index > strlen(entry->text)) {
+		fprintf(stderr, "Invalid cursor index %d\n", index);
+		return;
+	}
+
+	if (cursor_index + length > strlen(entry->text)) {
+		fprintf(stderr, "Invalid length %d\n", length);
+		return;
+	}
+
+	if (length == 0)
+		return;
+
+	text_entry_delete_text(entry, cursor_index, length);
+}
+
+static void
 text_model_preedit_styling(void *data,
 			   struct text_model *text_model)
 {
@@ -304,6 +331,7 @@
 static const struct text_model_listener text_model_listener = {
 	text_model_commit_string,
 	text_model_preedit_string,
+	text_model_delete_surrounding_text,
 	text_model_preedit_styling,
 	text_model_key,
 	text_model_selection_replacement,
@@ -516,6 +544,21 @@
 }
 
 static void
+text_entry_delete_text(struct text_entry *entry,
+		       uint32_t index, uint32_t length)
+{
+	if (entry->cursor > index)
+		entry->cursor -= length;
+
+	entry->text[index] = '\0';
+	strcat(entry->text, entry->text + index + length);
+
+	text_entry_update_layout(entry);
+
+	widget_schedule_redraw(entry->widget);
+}
+
+static void
 text_entry_draw_selection(struct text_entry *entry, cairo_t *cr)
 {
 	cairo_text_extents_t extents;