#ifdef CONFIG_UTF_8, term_event_keyboard.key is UCS-4.

Form fields and BFU text-input widgets then convert from UCS-4 to UTF-8.
If not all UTF-8 bytes fit, they don't insert anything.  Thus it is no
longer possible to get invalid UTF-8 by hitting the length limit.

It is unclear to me which charset is supposed to be used for strings
in internal buffers.  I made BFU insert UTF-8 whenever CONFIG_UTF_8,
but form fields use the charset of the terminal; that may have to be
changed.

As a side effect, this change should solve bug 782, because
term_send_ucs no longer encodes in UTF-8 if CONFIG_UTF_8 is defined.
I think the UTF-8 and codepage encoding calls I added are safe, too.
A similar bug may still surface somewhere else, but 782 could be
closed for now.

This change also lays the foundation for binding actions to non-ASCII
keys, but the keystroke name parser doesn't yet support that.

---
commit d4b830d8a891c81105fcf8b5bfde3bf212fb2c62
tree 2a3289cb4f4fd81177e17b719272e710a4ad4467
parent fef18a956aa0f93d36a20365997b4d41000cb66c
author Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Fri, 04 Aug 2006 01:37:08 +0300
committer Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Fri, 04 Aug 2006 01:37:08 +0300

 src/bfu/inpfield.c     |   33 ++++++++++++-----------------
 src/terminal/event.c   |    9 +++++++-
 src/terminal/event.h   |    4 ++-
 src/terminal/kbd.h     |    4 ++-
 src/viewer/text/form.c |   55 +++++++++++++++++++-----------------------------
 5 files changed, 48 insertions(+), 57 deletions(-)

diff --git a/src/bfu/inpfield.c b/src/bfu/inpfield.c
index ff7c9c1..dcb948a 100644
--- a/src/bfu/inpfield.c
+++ b/src/bfu/inpfield.c
@@ -680,32 +680,27 @@ #endif /* CONFIG_UTF_8 */
 			if (check_kbd_textinput_key(ev)) {
 				unsigned char *text = widget_data->cdata;
 				int textlen = strlen(text);
+#ifdef CONFIG_UTF_8
+				const unsigned char *ins = encode_utf_8(get_kbd_key(ev));
+				int inslen = utf8charlen(ins);
+#else  /* !CONFIG_UTF_8 */
+				const int inslen = 1;
+#endif /* !CONFIG_UTF_8 */
 
-				if (textlen >= widget_data->widget->datalen - 1)
+				if (textlen >= widget_data->widget->datalen - inslen)
 					goto display_field;
 
 				/* Shift to position of the cursor */
 				textlen -= widget_data->info.field.cpos;
-				text	+= widget_data->info.field.cpos++;
+				text	+= widget_data->info.field.cpos;
 
-				memmove(text + 1, text, textlen + 1);
-				*text = get_kbd_key(ev);
+				memmove(text + inslen, text, textlen + 1);
 #ifdef CONFIG_UTF_8
-				if (term->utf8) {
-					static unsigned char buf[7];
-					unsigned char *t = buf;
-					static int i = 0;
-					unicode_val_T data;
-
-					buf[i++] = *text;
-					buf[i] = '\0';
-					data = utf_8_to_unicode(&t, buf + i);
-					if (i == 6) i = 0;
-					if (data == UCS_NO_CHAR)
-						return EVENT_PROCESSED;
-					else i = 0;
-				}
-#endif /* CONFIG_UTF_8 */
+				memcpy(text, ins, inslen);
+#else  /* !CONFIG_UTF_8 */
+				*text = get_kbd_key(ev);
+#endif /* !CONFIG_UTF_8 */
+				widget_data->info.field.cpos += inslen;
 				goto display_field;
 			}
 	}
diff --git a/src/terminal/event.c b/src/terminal/event.c
index 2937998..35d32dc 100644
--- a/src/terminal/event.c
+++ b/src/terminal/event.c
@@ -135,9 +135,15 @@ term_send_event(struct terminal *term, s
 static void
 term_send_ucs(struct terminal *term, unicode_val_T u, int modifier)
 {
-	unsigned char *recoded;
+#ifdef CONFIG_UTF_8
 	struct term_event ev;
 
+	set_kbd_term_event(&ev, u, modifier);
+	term_send_event(term, &ev);
+#else  /* !CONFIG_UTF_8 */
+	struct term_event ev;
+	unsigned char *recoded;
+
 	set_kbd_term_event(&ev, KBD_UNDEF, modifier);
 	recoded = u2cp_no_nbsp(u, get_opt_codepage_tree(term->spec, "charset"));
 	if (!recoded) recoded = "*";
@@ -146,6 +152,7 @@ term_send_ucs(struct terminal *term, uni
 		term_send_event(term, &ev);
 		recoded++;
 	}
+#endif	/* CONFIG_UTF_8 */
 }
 
 static void
diff --git a/src/terminal/event.h b/src/terminal/event.h
index 7e954af..f6b8eec 100644
--- a/src/terminal/event.h
+++ b/src/terminal/event.h
@@ -165,8 +165,8 @@ #define check_kbd_key(event, key)	(kbd_k
 #define get_kbd_modifier(event)		(kbd_get_modifier(&(event)->info.keyboard))
 #define check_kbd_modifier(event, mod)	(kbd_modifier_is(&(event)->info.keyboard, (mod)))
 
-#define check_kbd_textinput_key(event)	(get_kbd_key(event) >= ' ' && get_kbd_key(event) < 256 && check_kbd_modifier(event, KBD_MOD_NONE))
-#define check_kbd_label_key(event)	(get_kbd_key(event) > ' ' && get_kbd_key(event) < 256 && (check_kbd_modifier(event, KBD_MOD_NONE) || check_kbd_modifier(event, KBD_MOD_ALT)))
+#define check_kbd_textinput_key(event)	(get_kbd_key(event) >= ' ' && check_kbd_modifier(event, KBD_MOD_NONE))
+#define check_kbd_label_key(event)	(get_kbd_key(event) > ' ' && (check_kbd_modifier(event, KBD_MOD_NONE) || check_kbd_modifier(event, KBD_MOD_ALT)))
 
 
 /* For mouse events handling */
diff --git a/src/terminal/kbd.h b/src/terminal/kbd.h
index fb101cc..cded613 100644
--- a/src/terminal/kbd.h
+++ b/src/terminal/kbd.h
@@ -7,8 +7,8 @@ struct term_event_keyboard {
 	/* Values <= 0x100 are special; e.g. KBD_ENTER.
 	 * Values between -0xFF and -2 are not used yet; treat as special.
 	 * Value  == -1 is KBD_UNDEF; not sent via socket. 
-	 * Values between 0 and 0xFF are bytes received from the terminal.
-	 * Values >= 0x100 are not used.  */
+	 * Values >= 0 are characters received from the terminal;
+	 * in UCS-4 #ifdef CONFIG_UTF_8. */
 	int key;
 	int modifier;
 };
diff --git a/src/viewer/text/form.c b/src/viewer/text/form.c
index 867e001..ee3ad33 100644
--- a/src/viewer/text/form.c
+++ b/src/viewer/text/form.c
@@ -1712,8 +1712,8 @@ #endif /* CONFIG_UTF_8 */
 			}
 
 			if (form_field_is_readonly(fc)
-					|| strlen(fs->value) >= fc->maxlength
 #ifndef CONFIG_UTF_8
+					|| strlen(fs->value) >= fc->maxlength
 					|| !insert_in_string(&fs->value, fs->state, "?", 1)
 #endif /* CONFIG_UTF_8 */
 					)
@@ -1721,42 +1721,31 @@ #endif /* CONFIG_UTF_8 */
 				status = FRAME_EVENT_OK;
 				break;
 			}
+
 #ifdef CONFIG_UTF_8
-			if (utf8) {
-				static unsigned char buf[7];
-				static int i = 0;
-				unicode_val_T data;
-				unsigned char *t;
-
-				t = buf;
-				buf[i++] = get_kbd_key(ev);
-				buf[i] = 0;
-				data = utf_8_to_unicode(&t, buf + i);
-				if (data != UCS_NO_CHAR) {
-					if (!insert_in_string(&fs->value, fs->state, buf, i)) {
-					    	i = 0;
-						return FRAME_EVENT_OK;
-					}
-					fs->state += i;
-					if (fc->type == FC_PASSWORD)
-						fs->state_cell++;
-					else if (fc->type == FC_TEXTAREA)
-						fs->state_cell = 0;
-					else
-						fs->state_cell += unicode_to_cell(data);
-					i = 0;
+			{
+				/* The charset of the terminal; we assume
+				 * fs->value is in this charset.
+				 * (Is that OK?)  */
+				int cp = get_opt_codepage_tree(ses->tab->term->spec,
+							       "charset");
+
+				text = u2cp_no_nbsp(get_kbd_key(ev), cp);
+				length = strlen(text);
+
+				if (strlen(fs->value) + length > fc->maxlength
+				    || !insert_in_string(&fs->value, fs->state, text, length)) {
+					status = FRAME_EVENT_OK;
 					break;
 				}
 
-				if (i == 6) {
-					i = 0;
-				}
-				return FRAME_EVENT_OK;
-
-			} else {
-				if (!insert_in_string(&fs->value, fs->state, "?", 1))
-					return FRAME_EVENT_OK;
-				fs->value[fs->state++] = get_kbd_key(ev);
+				fs->state += length;
+				if (fc->type == FC_PASSWORD)
+					fs->state_cell += (is_cp_utf8(cp) ? 1 : length);
+				else if (fc->type == FC_TEXTAREA)
+					fs->state_cell = 0;
+				else
+					fs->state_cell += (is_cp_utf8(cp) ? unicode_to_cell(get_kbd_key(ev)) : length);
 			}
 #else
 			fs->value[fs->state++] = get_kbd_key(ev);

Attachment: pgpHHAM9C8p2r.pgp
Description: PGP signature

_______________________________________________
elinks-dev mailing list
[email protected]
http://linuxfromscratch.org/mailman/listinfo/elinks-dev

Reply via email to