Define separate structs for events passed via the interlink socket.

This way, struct term_event can be changed without any interprocess
compatibility problems.

---
commit 0c424d5c8c9e3cdb2b46f6b2e8f95f6a3407707f
tree 1dfaf20ec647ea89058fb3fb10aaa94d76162d51
parent f9ecbc7636e9e864a55e1bf5cd992b4e2a31cc43
author Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Thu, 03 Aug 2006 19:40:17 +0300
committer Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Thu, 03 Aug 2006 19:40:17 +0300

 src/osdep/os2/os2.c   |   14 +++++++-------
 src/osdep/unix/bsd.c  |    8 ++++----
 src/osdep/unix/unix.c |    6 +++---
 src/terminal/event.c  |   49 ++++++++++++++++++++++++++++++-------------------
 src/terminal/event.h  |   45 ++++++++++++++++++++++++++++++++++++++++++++-
 src/terminal/kbd.c    |   30 +++++++++++++++---------------
 src/terminal/kbd.h    |    5 +++++
 src/terminal/mouse.c  |    6 +++---
 src/terminal/mouse.h  |    5 +++--
 9 files changed, 114 insertions(+), 54 deletions(-)

diff --git a/src/osdep/os2/os2.c b/src/osdep/os2/os2.c
index 6eb00d6..922e0c9 100644
--- a/src/osdep/os2/os2.c
+++ b/src/osdep/os2/os2.c
@@ -456,7 +456,7 @@ struct os2_mouse_spec {
 	int p[2];
 	void (*fn)(void *, unsigned char *, int);
 	void *data;
-	unsigned char buffer[sizeof(struct term_event)];
+	unsigned char buffer[sizeof(struct interlink_event)];
 	int bufptr;
 	int terminate;
 };
@@ -483,8 +483,8 @@ mouse_thread(void *p)
 	status = -1;
 
 	while (1) {
-		struct term_event ev;
-		struct term_event_mouse mouse;
+		struct interlink_event ev;
+		struct interlink_event_mouse mouse;
 		int w, ww;
 
 		if (MouReadEventQue(ms, rd, *mh)) break;
@@ -514,7 +514,7 @@ #endif
 			status = -1;
 		}
 
-		set_mouse_term_event(&ev, mouse.x, mouse.y, mouse.button);
+		set_mouse_interlink_event(&ev, mouse.x, mouse.y, mouse.button);
 		if (hard_write(oms->p[1], (unsigned char *) &ev, sizeof(ev)) != sizeof(ev)) break;
 	}
 #ifdef HAVE_SYS_FMUTEX_H
@@ -535,7 +535,7 @@ void
 mouse_handle(struct os2_mouse_spec *oms)
 {
 	ssize_t r = safe_read(oms->p[0], oms->buffer + oms->bufptr,
-		          sizeof(struct term_event) - oms->bufptr);
+		          sizeof(struct interlink_event) - oms->bufptr);
 
 	if (r <= 0) {
 		unhandle_mouse(oms);
@@ -543,9 +543,9 @@ mouse_handle(struct os2_mouse_spec *oms)
 	}
 
 	oms->bufptr += r;
-	if (oms->bufptr == sizeof(struct term_event)) {
+	if (oms->bufptr == sizeof(struct interlink_event)) {
 		oms->bufptr = 0;
-		oms->fn(oms->data, oms->buffer, sizeof(struct term_event));
+		oms->fn(oms->data, oms->buffer, sizeof(struct interlink_event));
 	}
 }
 
diff --git a/src/osdep/unix/bsd.c b/src/osdep/unix/bsd.c
index 42ff9bf..bac3a6c 100644
--- a/src/osdep/unix/bsd.c
+++ b/src/osdep/unix/bsd.c
@@ -36,7 +36,7 @@ struct sysmouse_spec {
 static void
 sysmouse_handler(void *data)
 {
-	static struct term_event_mouse prev_mouse;
+	static struct interlink_event_mouse prev_mouse;
 	static int prev_buttons;
 	struct sysmouse_spec *sp = data;
 	void *itrm = sp->itrm;
@@ -44,8 +44,8 @@ sysmouse_handler(void *data)
 	int buttons, change;
 	int extended_button;
 	mouse_info_t mi;
-	struct term_event_mouse mouse;
-	struct term_event ev;
+	struct interlink_event_mouse mouse;
+	struct interlink_event ev;
 
 	mi.operation = MOUSE_GETINFO;
 	if (ioctl(fd, CONS_MOUSECTL, &mi) == -1) return;
@@ -154,7 +154,7 @@ #endif
 	}
 
 	prev_buttons = buttons;
-	set_mouse_term_event(&ev, mouse.x, mouse.y, mouse.button);
+	set_mouse_interlink_event(&ev, mouse.x, mouse.y, mouse.button);
 	sp->fn(itrm, (unsigned char *)&ev, sizeof(ev));
 }
 
diff --git a/src/osdep/unix/unix.c b/src/osdep/unix/unix.c
index 0f78740..122d334 100644
--- a/src/osdep/unix/unix.c
+++ b/src/osdep/unix/unix.c
@@ -34,8 +34,8 @@ static void
 gpm_mouse_in(struct gpm_mouse_spec *gms)
 {
 	Gpm_Event gev;
-	struct term_event ev;
-	struct term_event_mouse mouse;
+	struct interlink_event ev;
+	struct interlink_event_mouse mouse;
 
 	if (Gpm_GetEvent(&gev) <= 0) {
 		clear_handlers(gms->h);
@@ -72,7 +72,7 @@ gpm_mouse_in(struct gpm_mouse_spec *gms)
 	else
 		return;
 
-	set_mouse_term_event(&ev, mouse.x, mouse.y, mouse.button);
+	set_mouse_interlink_event(&ev, mouse.x, mouse.y, mouse.button);
 	gms->fn(gms->data, (char *) &ev, sizeof(ev));
 }
 
diff --git a/src/terminal/event.c b/src/terminal/event.c
index 291d3ef..58c53d8 100644
--- a/src/terminal/event.c
+++ b/src/terminal/event.c
@@ -199,17 +199,18 @@ ignore_mouse_event(struct terminal *term
 #endif
 
 static int
-handle_interlink_event(struct terminal *term, struct term_event *ev)
+handle_interlink_event(struct terminal *term, struct interlink_event *ilev)
 {
 	struct terminal_info *info = NULL;
 	struct terminal_interlink *interlink = term->interlink;
+	struct term_event tev;
 
-	switch (ev->ev) {
+	switch (ilev->ev) {
 	case EVENT_INIT:
 		if (interlink->qlen < TERMINAL_INFO_SIZE)
 			return 0;
 
-		info = (struct terminal_info *) ev;
+		info = (struct terminal_info *) ilev;
 
 		if (interlink->qlen < TERMINAL_INFO_SIZE + info->length)
 			return 0;
@@ -226,7 +227,9 @@ handle_interlink_event(struct terminal *
 		 * terminal screen before decoding the session info so that
 		 * handling of bad URL syntax by openning msg_box() will be
 		 * possible. */
-		term_send_event(term, ev);
+		set_wh_term_event(&tev, ilev->ev,
+				  ilev->info.size.width, ilev->info.size.height);
+		term_send_event(term, &tev);
 
 		/* Either the initialization of the first session failed or we
 		 * are doing a remote session so quit.*/
@@ -241,29 +244,37 @@ handle_interlink_event(struct terminal *
 			return 0;
 		}
 
-		ev->ev = EVENT_REDRAW;
+		ilev->ev = EVENT_REDRAW;
 		/* Fall through */
 	case EVENT_REDRAW:
 	case EVENT_RESIZE:
-		term_send_event(term, ev);
+		tev.ev = ilev->ev;
+		copy_struct(&tev.info.size, &ilev->info.size);
+		term_send_event(term, &tev);
 		break;
 
 	case EVENT_MOUSE:
 #ifdef CONFIG_MOUSE
 		reset_timer();
-		if (!ignore_mouse_event(term, ev))
-			term_send_event(term, ev);
+		tev.ev = ilev->ev;
+		copy_struct(&tev.info.mouse, &ilev->info.mouse);
+		if (!ignore_mouse_event(term, &tev))
+			term_send_event(term, &tev);
 #endif
 		break;
 
 	case EVENT_KBD:
 	{
 		int utf8_io = -1;
-		int key = get_kbd_key(ev);
+		int key;
+
+		set_kbd_term_event(&tev, ilev->info.keyboard.key, ilev->info.keyboard.modifier);
+
+		key = get_kbd_key(&tev);
 
 		reset_timer();
 
-		if (check_kbd_modifier(ev, KBD_MOD_CTRL) && toupper(key) == 'L') {
+		if (check_kbd_modifier(&tev, KBD_MOD_CTRL) && toupper(key) == 'L') {
 			redraw_terminal_cls(term);
 			break;
 
@@ -287,18 +298,18 @@ #endif /* CONFIG_UTF_8 */
 
 					if (u < interlink->utf_8.min)
 						u = UCS_NO_CHAR;
-					term_send_ucs(term, ev, u);
+					term_send_ucs(term, &tev, u);
 				}
 				break;
 
 			} else {
 				interlink->utf_8.len = 0;
-				term_send_ucs(term, ev, UCS_NO_CHAR);
+				term_send_ucs(term, &tev, UCS_NO_CHAR);
 			}
 		}
 
 		if (key < 0x80 || key > 0xFF || !utf8_io) {
-			term_send_event(term, ev);
+			term_send_event(term, &tev);
 			break;
 
 		} else if ((key & 0xC0) == 0xC0 && (key & 0xFE) != 0xFE) {
@@ -313,11 +324,11 @@ #endif /* CONFIG_UTF_8 */
 
 			interlink->utf_8.len = len - 1;
 			interlink->utf_8.ucs = key & (mask - 1);
-			interlink->utf_8.modifier = get_kbd_modifier(ev);
+			interlink->utf_8.modifier = get_kbd_modifier(&tev);
 			break;
 		}
 
-		term_send_ucs(term, ev, UCS_NO_CHAR);
+		term_send_ucs(term, &tev, UCS_NO_CHAR);
 		break;
 	}
 
@@ -326,12 +337,12 @@ #endif /* CONFIG_UTF_8 */
 		return 0;
 
 	default:
-		ERROR(gettext("Bad event %d"), ev->ev);
+		ERROR(gettext("Bad event %d"), ilev->ev);
 	}
 
 	/* For EVENT_INIT we read a liitle more */
 	if (info) return TERMINAL_INFO_SIZE + info->length;
-	return sizeof(*ev);
+	return sizeof(*ilev);
 }
 
 void
@@ -376,8 +387,8 @@ in_term(struct terminal *term)
 	interlink->qlen += r;
 	interlink->qfreespace -= r;
 
-	while (interlink->qlen >= sizeof(struct term_event)) {
-		struct term_event *ev = (struct term_event *) iq;
+	while (interlink->qlen >= sizeof(struct interlink_event)) {
+		struct interlink_event *ev = (struct interlink_event *) iq;
 		int event_size = handle_interlink_event(term, ev);
 
 		/* If the event was not handled save the bytes in the queue for
diff --git a/src/terminal/event.h b/src/terminal/event.h
index 284c4ae..f65a623 100644
--- a/src/terminal/event.h
+++ b/src/terminal/event.h
@@ -38,6 +38,22 @@ struct term_event {
 	} info;
 };
 
+struct interlink_event {
+	enum term_event_type ev;
+
+	union {
+		/* EVENT_MOUSE */
+		struct interlink_event_mouse mouse;
+
+		/* EVENT_KBD */
+		struct interlink_event_keyboard keyboard;
+
+		/* EVENT_INIT, EVENT_RESIZE, EVENT_REDRAW */
+#define interlink_event_size term_event_size
+		struct interlink_event_size size;
+	} info;
+};
+
 static inline void
 set_mouse_term_event(struct term_event *ev, int x, int y, unsigned int button)
 {
@@ -47,6 +63,14 @@ set_mouse_term_event(struct term_event *
 }
 
 static inline void
+set_mouse_interlink_event(struct interlink_event *ev, int x, int y, unsigned int button)
+{
+	memset(ev, 0, sizeof(*ev));
+	ev->ev = EVENT_MOUSE;
+	set_mouse(&ev->info.mouse, x, y, button);
+}
+
+static inline void
 set_kbd_term_event(struct term_event *ev, int key, int modifier)
 {
 	memset(ev, 0, sizeof(*ev));
@@ -55,6 +79,14 @@ set_kbd_term_event(struct term_event *ev
 }
 
 static inline void
+set_kbd_interlink_event(struct interlink_event *ev, int key, int modifier)
+{
+	memset(ev, 0, sizeof(*ev));
+	ev->ev = EVENT_KBD;
+	kbd_set(&ev->info.keyboard, key, modifier);
+}
+
+static inline void
 set_abort_term_event(struct term_event *ev)
 {
 	memset(ev, 0, sizeof(*ev));
@@ -74,6 +106,17 @@ #define set_init_term_event(ev, w, h) se
 #define set_resize_term_event(ev, w, h) set_wh_term_event(ev, EVENT_RESIZE, w, h)
 #define set_redraw_term_event(ev, w, h) set_wh_term_event(ev, EVENT_REDRAW, w, h)
 
+static inline void
+set_wh_interlink_event(struct interlink_event *ev, enum term_event_type type, int width, int height)
+{
+	memset(ev, 0, sizeof(*ev));
+	ev->ev = type;
+	ev->info.size.width = width;
+	ev->info.size.height = height;
+}
+
+#define set_resize_interlink_event(ev, w, h) set_wh_interlink_event(ev, EVENT_RESIZE, w, h)
+
 
 /* This holds the information used when handling the initial connection between
  * a dumb and master terminal. */
@@ -83,7 +126,7 @@ #define set_redraw_term_event(ev, w, h) 
  * add new members add them at the bottom and use magic variables to
  * distinguish them when decoding the terminal info. */
 struct terminal_info {
-	struct term_event event;		/* The EVENT_INIT event */
+	struct interlink_event event;		/* The EVENT_INIT event */
 	unsigned char name[MAX_TERM_LEN];	/* $TERM environment name */
 	unsigned char cwd[MAX_CWD_LEN];		/* Current working directory */
 	int system_env;				/* System info (X, screen) */
diff --git a/src/terminal/kbd.c b/src/terminal/kbd.c
index caabf50..a2a8827 100644
--- a/src/terminal/kbd.c
+++ b/src/terminal/kbd.c
@@ -135,10 +135,10 @@ itrm_queue_event(struct itrm *itrm, unsi
 void
 kbd_ctrl_c(void)
 {
-	struct term_event ev;
+	struct interlink_event ev;
 
 	if (!ditrm) return;
-	set_kbd_term_event(&ev, KBD_CTRL_C, KBD_MOD_NONE);
+	set_kbd_interlink_event(&ev, KBD_CTRL_C, KBD_MOD_NONE);
 	itrm_queue_event(ditrm, (unsigned char *) &ev, sizeof(ev));
 }
 
@@ -190,11 +190,11 @@ #undef write_sequence
 void
 resize_terminal(void)
 {
-	struct term_event ev;
+	struct interlink_event ev;
 	int width, height;
 
 	get_terminal_size(ditrm->out.std, &width, &height);
-	set_resize_term_event(&ev, width, height);
+	set_resize_interlink_event(&ev, width, height);
 	itrm_queue_event(ditrm, (char *) &ev, sizeof(ev));
 }
 
@@ -265,7 +265,7 @@ handle_trm(int std_in, int std_out, int 
 {
 	struct itrm *itrm;
 	struct terminal_info info;
-	struct term_event_size *size = &info.event.info.size;
+	struct interlink_event_size *size = &info.event.info.size;
 	unsigned char *ts;
 
 	memset(&info, 0, sizeof(info));
@@ -654,9 +654,9 @@ #endif
 /* Returns length of the escape sequence or -1 if the caller needs to set up
  * the ESC delay timer. */
 static int
-decode_terminal_escape_sequence(struct itrm *itrm, struct term_event *ev)
+decode_terminal_escape_sequence(struct itrm *itrm, struct interlink_event *ev)
 {
-	struct term_event_keyboard kbd = { KBD_UNDEF, KBD_MOD_NONE };
+	struct interlink_event_keyboard kbd = { KBD_UNDEF, KBD_MOD_NONE };
 	unsigned char c;
 	int v;
 	int el;
@@ -786,10 +786,10 @@ #endif /* CONFIG_MOUSE */
  *   The length of the escape sequence otherwise.
  * Returning >0 does not imply this function has altered *ev.  */
 static int
-decode_terminal_application_key(struct itrm *itrm, struct term_event *ev)
+decode_terminal_application_key(struct itrm *itrm, struct interlink_event *ev)
 {
 	unsigned char c;
-	struct term_event_keyboard kbd = { KBD_UNDEF, KBD_MOD_NONE };
+	struct interlink_event_keyboard kbd = { KBD_UNDEF, KBD_MOD_NONE };
 
 	assert(itrm->in.queue.len >= 2);
 	assert(itrm->in.queue.data[0] == ASCII_ESC);
@@ -835,7 +835,7 @@ decode_terminal_application_key(struct i
 
 
 static void
-set_kbd_event(struct term_event *ev, int key, int modifier)
+set_kbd_event(struct interlink_event *ev, int key, int modifier)
 {
 	switch (key) {
 	case ASCII_TAB:
@@ -870,13 +870,13 @@ #endif
 		}
 	}
 
-	set_kbd_term_event(ev, key, modifier);
+	set_kbd_interlink_event(ev, key, modifier);
 }
 
 static void
 kbd_timeout(struct itrm *itrm)
 {
-	struct term_event ev;
+	struct interlink_event ev;
 	int el;
 
 	itrm->timer = TIMER_ID_UNDEF;
@@ -915,14 +915,14 @@ kbd_timeout(struct itrm *itrm)
 static int
 process_queue(struct itrm *itrm)
 {
-	struct term_event ev;
+	struct interlink_event ev;
 	int el = 0;
 
 	if (!itrm->in.queue.len) goto return_without_event;
 	assert(!itrm->blocked);
 	if_assert_failed return 0; /* unlike goto, don't enable reading */
 
-	set_kbd_term_event(&ev, KBD_UNDEF, KBD_MOD_NONE);
+	set_kbd_interlink_event(&ev, KBD_UNDEF, KBD_MOD_NONE);
 
 #ifdef DEBUG_ITRM_QUEUE
 	{
@@ -995,7 +995,7 @@ #endif /* DEBUG_ITRM_QUEUE */
 		}
 
 	} else if (itrm->in.queue.data[0] == 0) {
-		static const struct term_event_keyboard os2xtd[256] = {
+		static const struct interlink_event_keyboard os2xtd[256] = {
 #include "terminal/key.inc"
 		};
 
diff --git a/src/terminal/kbd.h b/src/terminal/kbd.h
index 958e1b3..d8d5462 100644
--- a/src/terminal/kbd.h
+++ b/src/terminal/kbd.h
@@ -8,6 +8,11 @@ struct term_event_keyboard {
 	int modifier;
 };
 
+struct interlink_event_keyboard {
+	int key;
+	int modifier;
+};
+
 #define KBD_UNDEF	-1
 
 #define KBD_ENTER	0x100
diff --git a/src/terminal/mouse.c b/src/terminal/mouse.c
index 2cf2f83..7af40ee 100644
--- a/src/terminal/mouse.c
+++ b/src/terminal/mouse.c
@@ -126,11 +126,11 @@ #define TW_BUTT_RIGHT	4
 /* Returns length of the escape sequence or -1 if the caller needs to set up
  * the ESC delay timer. */
 int
-decode_terminal_mouse_escape_sequence(struct itrm *itrm, struct term_event *ev,
+decode_terminal_mouse_escape_sequence(struct itrm *itrm, struct interlink_event *ev,
 				      int el, int v)
 {
 	static int xterm_button = -1;
-	struct term_event_mouse mouse;
+	struct interlink_event_mouse mouse;
 
 	if (itrm->in.queue.len - el < 3)
 		return -1;
@@ -203,7 +203,7 @@ decode_terminal_mouse_escape_sequence(st
 
 	/* Postpone changing of the event type until all sanity
 	 * checks have been done. */
-	set_mouse_term_event(ev, mouse.x, mouse.y, mouse.button);
+	set_mouse_interlink_event(ev, mouse.x, mouse.y, mouse.button);
 
 	return el;
 }
diff --git a/src/terminal/mouse.h b/src/terminal/mouse.h
index 068e6ae..3e65012 100644
--- a/src/terminal/mouse.h
+++ b/src/terminal/mouse.h
@@ -1,7 +1,7 @@
 #ifndef EL__TERMINAL_MOUSE_H
 #define EL__TERMINAL_MOUSE_H
 
-struct term_event;
+struct interlink_event;
 struct itrm;
 
 /* The mouse reporting button byte looks like:
@@ -80,6 +80,7 @@ struct term_event_mouse {
 	int x, y;
 	unsigned int button;
 };
+#define interlink_event_mouse term_event_mouse
 
 #define BM_BUTT		7
 #define B_LEFT		0
@@ -116,7 +117,7 @@ void send_mouse_done_sequence(int h);
 void disable_mouse(void);
 void enable_mouse(void);
 void toggle_mouse(void);
-int decode_terminal_mouse_escape_sequence(struct itrm *itrm, struct term_event *ev, int el, int v);
+int decode_terminal_mouse_escape_sequence(struct itrm *itrm, struct interlink_event *ev, int el, int v);
 
 
 #endif
!-------------------------------------------------------------flip-
Renumber special keys to negative values, making room for Unicode.

This version should still be interlink compatible with previous ones.

---
commit d25b037cf7e09aff4b0051804355e48d4fcc7460
tree 00672299f4623229a4f490cf80106a0fc2a6baff
parent 0c424d5c8c9e3cdb2b46f6b2e8f95f6a3407707f
author Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Thu, 03 Aug 2006 21:09:29 +0300
committer Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Thu, 03 Aug 2006 21:09:29 +0300

 src/bfu/menu.c       |    2 +-
 src/config/kbdbind.c |    4 ++-
 src/terminal/event.c |    8 +++---
 src/terminal/event.h |    4 +++
 src/terminal/kbd.c   |   19 ++++++++------
 src/terminal/kbd.h   |   66 ++++++++++++++++++++++++++++++--------------------
 6 files changed, 60 insertions(+), 43 deletions(-)

diff --git a/src/bfu/menu.c b/src/bfu/menu.c
index c80bf4c..dfd9a66 100644
--- a/src/bfu/menu.c
+++ b/src/bfu/menu.c
@@ -950,7 +950,7 @@ menu_kbd_handler(struct menu *menu, stru
 		{
 			int key = get_kbd_key(ev);
 
-			if ((key >= KBD_F1 && key <= KBD_F12)
+			if (is_kbd_fkey(key)
 			    || check_kbd_modifier(ev, KBD_MOD_ALT)) {
 				delete_window_ev(win, ev);
 				return;
diff --git a/src/config/kbdbind.c b/src/config/kbdbind.c
index 0e3996e..abc2809 100644
--- a/src/config/kbdbind.c
+++ b/src/config/kbdbind.c
@@ -437,7 +437,7 @@ parse_keystroke(unsigned char *s, int ca
 	}
 
 	kbd->key = read_key(s);
-	return (kbd->key < 0) ? -1 : 0;
+	return (kbd->key == KBD_UNDEF) ? -1 : 0;
 }
 
 void
@@ -449,7 +449,7 @@ add_keystroke_to_string(struct string *s
 	struct key *key;
 	const struct modifier *modp;
 
-	if (kbd->key < 0) return;
+	if (kbd->key == KBD_UNDEF) return;
 
 	for (modp = modifiers; modp->name_and_dash != NULL; ++modp) {
 		if (kbd->modifier & modp->bitmask)
diff --git a/src/terminal/event.c b/src/terminal/event.c
index 58c53d8..5943aea 100644
--- a/src/terminal/event.c
+++ b/src/terminal/event.c
@@ -266,11 +266,11 @@ #endif
 	case EVENT_KBD:
 	{
 		int utf8_io = -1;
-		int key;
+		int key = ilev->info.keyboard.key;
 
-		set_kbd_term_event(&tev, ilev->info.keyboard.key, ilev->info.keyboard.modifier);
-
-		key = get_kbd_key(&tev);
+		if (key >= 0x100)
+			key = -key;
+		set_kbd_term_event(&tev, key, ilev->info.keyboard.modifier);
 
 		reset_timer();
 
diff --git a/src/terminal/event.h b/src/terminal/event.h
index f65a623..7e954af 100644
--- a/src/terminal/event.h
+++ b/src/terminal/event.h
@@ -78,11 +78,15 @@ set_kbd_term_event(struct term_event *ev
 	kbd_set(&ev->info.keyboard, key, modifier);
 }
 
+/* @key can be e.g. KBD_ENTER as in term_event_keyboard.key.
+ * This function then sets ev->info.keyboard.key = -KBD_ENTER.  */
 static inline void
 set_kbd_interlink_event(struct interlink_event *ev, int key, int modifier)
 {
 	memset(ev, 0, sizeof(*ev));
 	ev->ev = EVENT_KBD;
+	if (key <= -0x100)
+		key = -key;
 	kbd_set(&ev->info.keyboard, key, modifier);
 }
 
diff --git a/src/terminal/kbd.c b/src/terminal/kbd.c
index a2a8827..07fd305 100644
--- a/src/terminal/kbd.c
+++ b/src/terminal/kbd.c
@@ -656,7 +656,7 @@ #endif
 static int
 decode_terminal_escape_sequence(struct itrm *itrm, struct interlink_event *ev)
 {
-	struct interlink_event_keyboard kbd = { KBD_UNDEF, KBD_MOD_NONE };
+	struct term_event_keyboard kbd = { KBD_UNDEF, KBD_MOD_NONE };
 	unsigned char c;
 	int v;
 	int el;
@@ -670,8 +670,8 @@ decode_terminal_escape_sequence(struct i
 		if (itrm->in.queue.len >= 4
 		    && itrm->in.queue.data[3] >= 'A'
 		    && itrm->in.queue.data[3] <= 'L') {
-			kbd.key = KBD_F1 + itrm->in.queue.data[3] - 'A';
-			copy_struct(&ev->info.keyboard, &kbd);
+			kbd.key = number_to_kbd_fkey(itrm->in.queue.data[3] - 'A' + 1);
+			set_kbd_interlink_event(ev, kbd.key, kbd.modifier);
 			return 4;
 		}
 
@@ -770,10 +770,9 @@ #endif /* CONFIG_MOUSE */
 		break;
 	}
 
-	/* The event might have been changed to a mouse event */
-	if (ev->ev == EVENT_KBD && kbd.key != KBD_UNDEF) {
-		copy_struct(&ev->info.keyboard, &kbd);
-	}
+	/* KBD_UNDEF here means it was unrecognized or a mouse event.  */
+	if (kbd.key != KBD_UNDEF)
+		set_kbd_interlink_event(ev, kbd.key, kbd.modifier);
 
 	return el;
 }
@@ -995,7 +994,7 @@ #endif /* DEBUG_ITRM_QUEUE */
 		}
 
 	} else if (itrm->in.queue.data[0] == 0) {
-		static const struct interlink_event_keyboard os2xtd[256] = {
+		static const struct term_event_keyboard os2xtd[256] = {
 #include "terminal/key.inc"
 		};
 
@@ -1003,7 +1002,9 @@ #include "terminal/key.inc"
 			el = -1;
 		else {
 			el = 2;
-			copy_struct(&ev.info.keyboard, &os2xtd[itrm->in.queue.data[1]]);
+			set_kbd_interlink_event(&ev,
+						os2xtd[itrm->in.queue.data[1]].key,
+						os2xtd[itrm->in.queue.data[1]].modifier);
 		}
 	}
 
diff --git a/src/terminal/kbd.h b/src/terminal/kbd.h
index d8d5462..fb101cc 100644
--- a/src/terminal/kbd.h
+++ b/src/terminal/kbd.h
@@ -4,46 +4,58 @@ #define EL__TERMINAL_KBD_H
 struct itrm;
 
 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.  */
 	int key;
 	int modifier;
 };
 
 struct interlink_event_keyboard {
+	/* Values <= -2 are not used, for ELinks 0.11 compatibility.
+	 * Value  == -1 is KBD_UNDEF; not sent via socket.
+	 * Values between 0 and 0xFF are bytes received from the terminal.
+	 * Values >= 0x100 are special; e.g. -KBD_ENTER.  */
 	int key;
 	int modifier;
 };
 
 #define KBD_UNDEF	-1
 
-#define KBD_ENTER	0x100
-#define KBD_BS		0x101
-#define KBD_TAB		0x102
-#define KBD_ESC		0x103
-#define KBD_LEFT	0x104
-#define KBD_RIGHT	0x105
-#define KBD_UP		0x106
-#define KBD_DOWN	0x107
-#define KBD_INS		0x108
-#define KBD_DEL		0x109
-#define KBD_HOME	0x10a
-#define KBD_END		0x10b
-#define KBD_PAGE_UP	0x10c
-#define KBD_PAGE_DOWN	0x10d
+#define KBD_ENTER	(-0x100)
+#define KBD_BS		(-0x101)
+#define KBD_TAB		(-0x102)
+#define KBD_ESC		(-0x103)
+#define KBD_LEFT	(-0x104)
+#define KBD_RIGHT	(-0x105)
+#define KBD_UP		(-0x106)
+#define KBD_DOWN	(-0x107)
+#define KBD_INS		(-0x108)
+#define KBD_DEL		(-0x109)
+#define KBD_HOME	(-0x10a)
+#define KBD_END		(-0x10b)
+#define KBD_PAGE_UP	(-0x10c)
+#define KBD_PAGE_DOWN	(-0x10d)
 
-#define KBD_F1		0x120
-#define KBD_F2		0x121
-#define KBD_F3		0x122
-#define KBD_F4		0x123
-#define KBD_F5		0x124
-#define KBD_F6		0x125
-#define KBD_F7		0x126
-#define KBD_F8		0x127
-#define KBD_F9		0x128
-#define KBD_F10		0x129
-#define KBD_F11		0x12a
-#define KBD_F12		0x12b
+#define KBD_F1		(-0x120)
+#define KBD_F2		(-0x121)
+#define KBD_F3		(-0x122)
+#define KBD_F4		(-0x123)
+#define KBD_F5		(-0x124)
+#define KBD_F6		(-0x125)
+#define KBD_F7		(-0x126)
+#define KBD_F8		(-0x127)
+#define KBD_F9		(-0x128)
+#define KBD_F10		(-0x129)
+#define KBD_F11		(-0x12a)
+#define KBD_F12		(-0x12b)
+#define is_kbd_fkey(key) ((unsigned long) (KBD_F1 - (key)) <= (unsigned long) (KBD_F1 - KBD_F12))
+#define number_to_kbd_fkey(num) (KBD_F1 - (num) + 1)
+#define kbd_fkey_to_number(key) (KBD_F1 - (key) + 1)
 
-#define KBD_CTRL_C	0x200
+#define KBD_CTRL_C	(-0x200)
 
 #define KBD_MOD_NONE	0
 #define KBD_MOD_SHIFT	1
!-------------------------------------------------------------flip-
#ifdef CONFIG_UTF_8, translate all terminal input via UCS-4.

---
commit f630e1e0081ffc6d0974f43868e5ae3d1c076847
tree 7428ac527293a5cd0efe2ee188fc2d7c2e0622b8
parent d25b037cf7e09aff4b0051804355e48d4fcc7460
author Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Thu, 03 Aug 2006 23:55:05 +0300
committer Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Thu, 03 Aug 2006 23:55:05 +0300

 src/intl/charsets.c  |   38 ++++++++++++++++++++++++++++------
 src/intl/charsets.h  |    1 +
 src/terminal/event.c |   56 +++++++++++++++++++++++++++++++++++++++-----------
 3 files changed, 76 insertions(+), 19 deletions(-)

diff --git a/src/intl/charsets.c b/src/intl/charsets.c
index 33bc507..912ea09 100644
--- a/src/intl/charsets.c
+++ b/src/intl/charsets.c
@@ -458,22 +458,46 @@ utf_8_to_unicode(unsigned char **string,
 }
 #endif /* CONFIG_UTF_8 */
 
+/* Slow algorithm, the common part of cp2u and cp2utf_8.  */
+static unicode_val_T
+cp2u_shared(const struct codepage_desc *from, unsigned char c)
+{
+	int j;
+
+	for (j = 0; from->table[j].c; j++)
+		if (from->table[j].c == c)
+			return from->table[j].u;
+
+	return UCS_NO_CHAR;
+}
+
+#ifdef CONFIG_UTF_8
+/* Slow algorithm, used for converting input from the terminal.  */
+unicode_val_T
+cp2u(int from, unsigned char c)
+{
+	from &= ~SYSTEM_CHARSET_FLAG;
+
+	/* UTF-8 is a multibyte codepage and cannot be handled with
+	 * this function.  */
+	assert(codepages[from].table != table_utf_8);
+	if_assert_failed return UCS_NO_CHAR;
+
+	if (c < 0x80) return c;
+	else return cp2u_shared(&codepages[from], c);
+}
+#endif	/* CONFIG_UTF_8 */
+
 /* This slow and ugly code is used by the terminal utf_8_io */
 unsigned char *
 cp2utf_8(int from, int c)
 {
-	int j;
-
 	from &= ~SYSTEM_CHARSET_FLAG;
 
 	if (codepages[from].table == table_utf_8 || c < 128)
 		return strings[c];
 
-	for (j = 0; codepages[from].table[j].c; j++)
-		if (codepages[from].table[j].c == c)
-			return encode_utf_8(codepages[from].table[j].u);
-
-	return encode_utf_8(UCS_NO_CHAR);
+	return encode_utf_8(cp2u_shared(&codepages[from], c));
 }
 
 static void
diff --git a/src/intl/charsets.h b/src/intl/charsets.h
index 246606b..8d11707 100644
--- a/src/intl/charsets.h
+++ b/src/intl/charsets.h
@@ -64,6 +64,7 @@ int utf8_cells2bytes(unsigned char *, in
 inline int unicode_to_cell(unicode_val_T);
 inline int strlen_utf8(unsigned char **);
 inline unicode_val_T utf_8_to_unicode(unsigned char **, unsigned char *);
+unicode_val_T cp2u(int, unsigned char);
 #endif /* CONFIG_UTF_8 */
 
 unsigned char *cp2utf_8(int, int);
diff --git a/src/terminal/event.c b/src/terminal/event.c
index 5943aea..2937998 100644
--- a/src/terminal/event.c
+++ b/src/terminal/event.c
@@ -133,16 +133,17 @@ term_send_event(struct terminal *term, s
 }
 
 static void
-term_send_ucs(struct terminal *term, struct term_event *ev, unicode_val_T u)
+term_send_ucs(struct terminal *term, unicode_val_T u, int modifier)
 {
 	unsigned char *recoded;
+	struct term_event ev;
 
+	set_kbd_term_event(&ev, KBD_UNDEF, modifier);
 	recoded = u2cp_no_nbsp(u, get_opt_codepage_tree(term->spec, "charset"));
 	if (!recoded) recoded = "*";
 	while (*recoded) {
-		ev->info.keyboard.modifier = term->interlink->utf_8.modifier;
-		ev->info.keyboard.key = *recoded;
-		term_send_event(term, ev);
+		ev.info.keyboard.key = *recoded;
+		term_send_event(term, &ev);
 		recoded++;
 	}
 }
@@ -267,14 +268,14 @@ #endif
 	{
 		int utf8_io = -1;
 		int key = ilev->info.keyboard.key;
+		int modifier = ilev->info.keyboard.modifier;
 
 		if (key >= 0x100)
 			key = -key;
-		set_kbd_term_event(&tev, key, ilev->info.keyboard.modifier);
 
 		reset_timer();
 
-		if (check_kbd_modifier(&tev, KBD_MOD_CTRL) && toupper(key) == 'L') {
+		if (modifier == KBD_MOD_CTRL && (key == 'l' || key == 'L')) {
 			redraw_terminal_cls(term);
 			break;
 
@@ -283,14 +284,33 @@ #endif
 			return 0;
 		}
 
+		/* Character Conversions.  */
 #ifdef CONFIG_UTF_8
-		utf8_io = !!term->utf8;
+		/* struct term_event_keyboard carries UCS-4.
+		 * - If the "utf_8_io" option (i.e. term->utf8) is
+		 *   true or the "charset" option refers to UTF-8,
+		 *   then handle_interlink_event() converts from UTF-8
+		 *   to UCS-4.
+		 * - Otherwise, handle_interlink_event() converts from
+		 *   the codepage specified with the "charset" option
+		 *   to UCS-4.  */
+		utf8_io = term->utf8
+			|| is_cp_utf8(get_opt_codepage_tree(term->spec, "charset"));
 #else
+		/* struct term_event_keyboard carries bytes in the
+		 * charset of the terminal.
+		 * - If the "utf_8_io" option is true, then
+		 *   handle_interlink_event() converts from UTF-8 to
+		 *   UCS-4, and term_send_ucs() converts from UCS-4 to
+		 *   the codepage specified with the "charset" option;
+		 *   this codepage cannot be UTF-8.
+		 * - Otherwise, handle_interlink_event() passes the
+		 *   bytes straight through.  */
 		utf8_io = get_opt_bool_tree(term->spec, "utf_8_io");
 #endif /* CONFIG_UTF_8 */
 
 		if (interlink->utf_8.len) {
-			if ((key & 0xC0) == 0x80 && utf8_io) {
+			if (key >= 0x80 && key <= 0xBF && utf8_io) {
 				interlink->utf_8.ucs <<= 6;
 				interlink->utf_8.ucs |= key & 0x3F;
 				if (! --interlink->utf_8.len) {
@@ -298,17 +318,29 @@ #endif /* CONFIG_UTF_8 */
 
 					if (u < interlink->utf_8.min)
 						u = UCS_NO_CHAR;
-					term_send_ucs(term, &tev, u);
+					term_send_ucs(term, u,
+						      term->interlink->utf_8.modifier);
 				}
 				break;
 
 			} else {
 				interlink->utf_8.len = 0;
-				term_send_ucs(term, &tev, UCS_NO_CHAR);
+				term_send_ucs(term, UCS_NO_CHAR,
+					      term->interlink->utf_8.modifier);
 			}
 		}
 
 		if (key < 0x80 || key > 0xFF || !utf8_io) {
+#ifdef CONFIG_UTF_8
+			if (key >= 0 && key <= 0xFF && !utf8_io) {
+				key = cp2u(get_opt_codepage_tree(term->spec,
+								 "charset"),
+					   key);
+				term_send_ucs(term, key, modifier);
+				break;
+			}
+#endif /* !CONFIG_UTF_8 */
+			set_kbd_term_event(&tev, key, modifier);
 			term_send_event(term, &tev);
 			break;
 
@@ -324,11 +356,11 @@ #endif /* CONFIG_UTF_8 */
 
 			interlink->utf_8.len = len - 1;
 			interlink->utf_8.ucs = key & (mask - 1);
-			interlink->utf_8.modifier = get_kbd_modifier(&tev);
+			interlink->utf_8.modifier = modifier;
 			break;
 		}
 
-		term_send_ucs(term, &tev, UCS_NO_CHAR);
+		term_send_ucs(term, UCS_NO_CHAR, KBD_MOD_NONE);
 		break;
 	}
 
!-------------------------------------------------------------flip-
terminal doc: The interlink protocol no longer uses struct term_event.

---
commit fef18a956aa0f93d36a20365997b4d41000cb66c
tree 7f7dc83c08b702a411e04d7e31dc4f79776667a4
parent f630e1e0081ffc6d0974f43868e5ae3d1c076847
author Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Fri, 04 Aug 2006 00:07:18 +0300
committer Kalle Olavi Niemitalo <[EMAIL PROTECTED]> Fri, 04 Aug 2006 00:07:18 +0300

 src/terminal/itrm.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/terminal/itrm.h b/src/terminal/itrm.h
index f2033c1..441ab04 100644
--- a/src/terminal/itrm.h
+++ b/src/terminal/itrm.h
@@ -67,7 +67,7 @@ struct itrm_out {
 	 * socket connection is terminal.fdin in the master process.
 	 * If the connection is from the master process to itself, it
 	 * uses a pipe; otherwise a socket.  The events are formatted
-	 * as struct term_event, but at the beginning of the
+	 * as struct interlink_event, but at the beginning of the
 	 * connection, a struct terminal_info and extra data are also
 	 * sent.  */
 	int sock;
!-------------------------------------------------------------flip-
#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: pgpxOWONiXAgr.pgp
Description: PGP signature

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

Reply via email to