[patch 1/5] Define separate structs for events passed via the interlink socket.

Kalle Olavi Niemitalo <[email protected]>
Newsgroups gmane.comp.web.links
Message-ID <[email protected]>
_______________________________________________
elinks-dev mailing list
[email protected]
http://linuxfromscratch.org/mailman/listinfo/elinks-dev
(unnamed) (text/x-patch, 37.8 KB)
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);
signature.asc (application/pgp-signature, 188 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFE0oTrHm9IGt60eMgRAsRRAKCbOK6zlCcD8Ck7tDX90kWzs0EBLACgqF9K
QQleNXX4e4tN5y4Y+6mBOpY=
=yblN
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.