[PATCH v2 02/28] text: Add example for language/text direction

Jan Arne Petersen jpetersen at openismus.com
Thu Apr 18 07:47:16 PDT 2013


From: Jan Arne Petersen <jpetersen at openismus.com>

Signed-off-by: Jan Arne Petersen <jpetersen at openismus.com>
---
 clients/editor.c   | 36 +++++++++++++++++++++-
 clients/keyboard.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 121 insertions(+), 4 deletions(-)

diff --git a/clients/editor.c b/clients/editor.c
index e037c2f..58c6911 100644
--- a/clients/editor.c
+++ b/clients/editor.c
@@ -65,6 +65,7 @@ struct text_entry {
 	uint32_t serial;
 	uint32_t content_purpose;
 	uint32_t click_to_show;
+	char *preferred_language;
 };
 
 struct editor {
@@ -397,6 +398,7 @@ text_model_language(void *data,
 		    uint32_t serial,
 		    const char *language)
 {
+	fprintf(stderr, "input language is %s \n", language);
 }
 
 static void
@@ -405,6 +407,24 @@ text_model_text_direction(void *data,
 			  uint32_t serial,
 			  uint32_t direction)
 {
+	struct text_entry *entry = data;
+	PangoContext *context = pango_layout_get_context(entry->layout);
+	PangoDirection pango_direction;
+
+
+	switch (direction) {
+		case TEXT_MODEL_TEXT_DIRECTION_LTR:
+			pango_direction = PANGO_DIRECTION_LTR;
+			break;
+		case TEXT_MODEL_TEXT_DIRECTION_RTL:
+			pango_direction = PANGO_DIRECTION_RTL;
+			break;
+		case TEXT_MODEL_TEXT_DIRECTION_AUTO:
+		default:
+			pango_direction = PANGO_DIRECTION_NEUTRAL;
+	}
+	
+	pango_context_set_base_dir(context, pango_direction);
 }
 
 static const struct text_model_listener text_model_listener = {
@@ -616,6 +636,10 @@ text_entry_update(struct text_entry *entry)
 					entry->cursor,
 					entry->anchor);
 
+	if (entry->preferred_language)
+		text_model_set_preferred_language(entry->model,
+						  entry->preferred_language);
+
 	text_model_commit(entry->model);
 }
 
@@ -1063,10 +1087,18 @@ main(int argc, char *argv[])
 	struct editor editor;
 	int i;
 	uint32_t click_to_show = 0;
+	const char *preferred_language = NULL;
 
-	for (i = 1; i < argc; i++)
+	for (i = 1; i < argc; i++) {
 		if (strcmp("--click-to-show", argv[i]) == 0)
 			click_to_show = 1;
+		else if (strcmp("--preferred-language", argv[i]) == 0) {
+			if (i + 1 < argc) {
+				preferred_language = argv[i + 1];
+				i++;
+			}
+		}
+	}
 
 	memset(&editor, 0, sizeof editor);
 
@@ -1088,6 +1120,8 @@ main(int argc, char *argv[])
 
 	editor.entry = text_entry_create(&editor, "Entry");
 	editor.entry->click_to_show = click_to_show;
+	if (preferred_language)
+		editor.entry->preferred_language = strdup(preferred_language);
 	editor.editor = text_entry_create(&editor, "Numeric");
 	editor.editor->content_purpose = TEXT_MODEL_CONTENT_PURPOSE_NUMBER;
 	editor.editor->click_to_show = click_to_show;
diff --git a/clients/keyboard.c b/clients/keyboard.c
index b23de42..e792eba 100644
--- a/clients/keyboard.c
+++ b/clients/keyboard.c
@@ -45,6 +45,7 @@ struct virtual_keyboard {
 	uint32_t serial;
 	uint32_t content_hint;
 	uint32_t content_purpose;
+	char *preferred_language;
 	char *surrounding_text;
 	struct window *window;
 	struct widget *widget;
@@ -80,6 +81,9 @@ struct layout {
 
 	uint32_t columns;
 	uint32_t rows;
+
+	const char *language;
+	uint32_t text_direction;
 };
 
 static const struct key normal_keys[] = {
@@ -150,18 +154,81 @@ static const struct key numeric_keys[] = {
 	{ keytype_style, "", "", 2}
 };
 
+static const struct key arabic_keys[] = {
+	{ keytype_default, "ض", "ض", 1},
+	{ keytype_default, "ص", "ص", 1},
+	{ keytype_default, "ث", "ث", 1},
+	{ keytype_default, "ق", "ق", 1},
+	{ keytype_default, "ف", "ف", 1},
+	{ keytype_default, "غ", "إ", 1},
+	{ keytype_default, "ع", "ع", 1},
+	{ keytype_default, "ه", "ه", 1},
+	{ keytype_default, "خ", "خ", 1},
+	{ keytype_default, "ح", "ح", 1},
+	{ keytype_default, "ج", "ج", 1},
+	{ keytype_backspace, "-->", "-->", 2},
+
+	{ keytype_tab, "->|", "->|", 1},
+	{ keytype_default, "ش", "ش", 1},
+	{ keytype_default, "س", "س", 1},
+	{ keytype_default, "ي", "ي", 1},
+	{ keytype_default, "ب", "ب", 1},
+	{ keytype_default, "ل", "ل", 1},
+	{ keytype_default, "ا", "أ", 1},
+	{ keytype_default, "ت", "ت", 1},
+	{ keytype_default, "ن", "ن", 1},
+	{ keytype_default, "م", "م", 1},
+	{ keytype_default, "ك", "ك", 1},
+	{ keytype_default, "د", "د", 1},
+	{ keytype_enter, "Enter", "Enter", 2},
+
+	{ keytype_switch, "ABC", "abc", 2},
+	{ keytype_default, "ئ", "ئ", 1},
+	{ keytype_default, "ء", "ء", 1},
+	{ keytype_default, "ؤ", "ؤ", 1},
+	{ keytype_default, "ر", "ر", 1},
+	{ keytype_default, "ى", "آ", 1},
+	{ keytype_default, "ة", "ة", 1},
+	{ keytype_default, "و", "و", 1},
+	{ keytype_default, "ز", "ز", 1},
+	{ keytype_default, "ظ", "ظ", 1},
+	{ keytype_switch, "ABC", "abc", 2},
+
+	{ keytype_symbols, "؟٣٢١", "؟٣٢١", 1},
+	{ keytype_default, "ذ", "ذ", 1},
+	{ keytype_default, "،", "،", 1},
+	{ keytype_space, "", "", 6},
+	{ keytype_default, ".", ".", 1},
+	{ keytype_default, "ط", "ط", 1},
+	{ keytype_style, "", "", 2}
+};
+
+
 static const struct layout normal_layout = {
 	normal_keys,
 	sizeof(normal_keys) / sizeof(*normal_keys),
 	12,
-	4
+	4,
+	"en",
+	TEXT_MODEL_TEXT_DIRECTION_LTR
 };
 
 static const struct layout numeric_layout = {
 	numeric_keys,
 	sizeof(numeric_keys) / sizeof(*numeric_keys),
 	12,
-	2
+	2,
+	"en",
+	TEXT_MODEL_TEXT_DIRECTION_LTR
+};
+
+static const struct layout arabic_layout = {
+	arabic_keys,
+	sizeof(arabic_keys) / sizeof(*arabic_keys),
+	13,
+	4,
+	"ar",
+	TEXT_MODEL_TEXT_DIRECTION_RTL
 };
 
 static const char *style_labels[] = {
@@ -250,7 +317,11 @@ get_current_layout(struct virtual_keyboard *keyboard)
 		case TEXT_MODEL_CONTENT_PURPOSE_NUMBER:
 			return &numeric_layout;
 		default:
-			return &normal_layout;
+			if (keyboard->preferred_language &&
+			    strcmp(keyboard->preferred_language, "ar") == 0)
+				return &arabic_layout;
+			else
+				return &normal_layout;
 	}
 }
 
@@ -570,6 +641,9 @@ handle_commit(void *data,
 			       layout->columns * key_width,
 			       layout->rows * key_height);
 
+	input_method_context_language(context, keyboard->serial, layout->language);
+	input_method_context_text_direction(context, keyboard->serial, layout->text_direction);
+
 	widget_schedule_redraw(keyboard->widget);
 }
 
@@ -578,6 +652,15 @@ handle_preferred_language(void *data,
 			  struct input_method_context *context,
 			  const char *language)
 {
+	struct virtual_keyboard *keyboard = data;
+
+	if (keyboard->preferred_language)
+		free(keyboard->preferred_language);
+
+	keyboard->preferred_language = NULL;
+
+	if (language)
+		keyboard->preferred_language = strdup(language);
 }
 
 static const struct input_method_context_listener input_method_context_listener = {
-- 
1.8.1.4



More information about the wayland-devel mailing list