1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

terminal: Rewrite process_queue.

This commit is contained in:
Kalle Olavi Niemitalo 2006-07-28 15:57:50 +03:00 committed by Miciah Dashiel Butler Masters
parent 62c0bff87e
commit 886dbf64df

View File

@ -848,8 +848,6 @@ kbd_timeout(struct itrm *itrm)
while (process_queue(itrm)); while (process_queue(itrm));
} }
/* I feeeeeel the neeeed ... to rewrite this ... --pasky */
/* Just Do it ! --Zas */
/* Parse one event from itrm->in.queue and append to itrm->out.queue. /* Parse one event from itrm->in.queue and append to itrm->out.queue.
* Return the number of bytes removed from itrm->in.queue; at least 0. * Return the number of bytes removed from itrm->in.queue; at least 0.
* If this function leaves the queue not full, it also reenables reading * If this function leaves the queue not full, it also reenables reading
@ -861,7 +859,7 @@ process_queue(struct itrm *itrm)
struct term_event ev; struct term_event ev;
int el = 0; int el = 0;
if (!itrm->in.queue.len) goto end; if (!itrm->in.queue.len) goto return_without_event;
assert(!itrm->blocked); assert(!itrm->blocked);
if_assert_failed return 0; /* unlike goto, don't enable reading */ if_assert_failed return 0; /* unlike goto, don't enable reading */
@ -885,32 +883,55 @@ process_queue(struct itrm *itrm)
} }
#endif /* DEBUG_ITRM_QUEUE */ #endif /* DEBUG_ITRM_QUEUE */
/* el == -1 means itrm->in.queue appears to be the beginning of an
* escape sequence but it is not yet complete. Set a timer;
* if it times out, then assume it wasn't an escape sequence
* after all.
* el == 0 means this function has not yet figured out what the data
* in itrm->in.queue is, but some possibilities remain.
* One of them will be chosen before returning.
* el > 0 means some bytes were successfully parsed from the beginning
* of itrm->in.queue and should now be removed from there.
* However, this does not always imply an event will be queued.
*/
/* ELinks should also recognize U+009B CONTROL SEQUENCE INTRODUCER /* ELinks should also recognize U+009B CONTROL SEQUENCE INTRODUCER
* as meaning the same as ESC 0x5B, and U+008F SINGLE SHIFT THREE as * as meaning the same as ESC 0x5B, and U+008F SINGLE SHIFT THREE as
* meaning the same as ESC 0x4F, but those cannot yet be implemented * meaning the same as ESC 0x4F, but those cannot yet be implemented
* because of bug 777: the UTF-8 decoder is run too late. */ * because of bug 777: the UTF-8 decoder is run too late. */
if (itrm->in.queue.data[0] == ASCII_ESC) { if (itrm->in.queue.data[0] == ASCII_ESC) {
if (itrm->in.queue.len < 2) goto ret; if (itrm->in.queue.len < 2) {
if (itrm->in.queue.data[1] == '[' || itrm->in.queue.data[1] == 'O') { el = -1;
} else if (itrm->in.queue.data[1] == 0x5B /* CSI */
|| itrm->in.queue.data[1] == 0x4F /* SS3 */) {
el = decode_terminal_escape_sequence(itrm, &ev); el = decode_terminal_escape_sequence(itrm, &ev);
} else if (itrm->in.queue.data[1] == ASCII_ESC) {
if (el == -1) goto ret; /* ESC ESC can be either Alt-Esc or the
* beginning of e.g. ESC ESC 0x5B 0x41,
} else { * which we should parse as Esc Up. */
el = 2; if (itrm->in.queue.len < 3) {
/* Need more data to figure it out. */
if (itrm->in.queue.data[1] == ASCII_ESC) { el = -1;
if (itrm->in.queue.len >= 3 && } else if (itrm->in.queue.data[2] == 0x5B
(itrm->in.queue.data[2] == '[' || || itrm->in.queue.data[2] == 0x4F) {
itrm->in.queue.data[2] == 'O')) { /* The first ESC appears to be followed
el = 1; * by an escape sequence. Treat it as
} * a standalone Esc. */
el = 1;
set_kbd_event(&ev, KBD_ESC, KBD_MOD_NONE); set_kbd_event(&ev, itrm->in.queue.data[0],
KBD_MOD_NONE);
} else { } else {
set_kbd_event(&ev, itrm->in.queue.data[1], KBD_MOD_ALT); /* The second ESC of ESC ESC is not the
* beginning of any known escape sequence.
* This must be Alt-Esc, then. */
el = 2;
set_kbd_event(&ev, itrm->in.queue.data[1],
KBD_MOD_ALT);
} }
} else { /* ESC followed by something else */
el = 2;
set_kbd_event(&ev, itrm->in.queue.data[1],
KBD_MOD_ALT);
} }
} else if (itrm->in.queue.data[0] == 0) { } else if (itrm->in.queue.data[0] == 0) {
@ -918,39 +939,42 @@ process_queue(struct itrm *itrm)
#include "terminal/key.inc" #include "terminal/key.inc"
}; };
if (itrm->in.queue.len < 2) goto ret; if (itrm->in.queue.len < 2)
copy_struct(&ev.info.keyboard, &os2xtd[itrm->in.queue.data[1]]); el = -1;
el = 2; else {
el = 2;
} else { copy_struct(&ev.info.keyboard, &os2xtd[itrm->in.queue.data[1]]);
el = 1; }
set_kbd_event(&ev, itrm->in.queue.data[0], 0);
} }
assertm(itrm->in.queue.len >= el, "event queue underflow"); if (el == 0) {
if_assert_failed { itrm->in.queue.len = el; } el = 1;
set_kbd_event(&ev, itrm->in.queue.data[0], KBD_MOD_NONE);
itrm->in.queue.len -= el; }
/* The call to decode_terminal_escape_sequence() might have changed the /* The call to decode_terminal_escape_sequence() might have changed the
* keyboard event to a mouse event. */ * keyboard event to a mouse event. */
if (ev.ev == EVENT_MOUSE || ev.info.keyboard.key != KBD_UNDEF) if (ev.ev == EVENT_MOUSE || ev.info.keyboard.key != KBD_UNDEF)
itrm_queue_event(itrm, (char *) &ev, sizeof(ev)); itrm_queue_event(itrm, (char *) &ev, sizeof(ev));
if (itrm->in.queue.len) return_without_event:
memmove(itrm->in.queue.data, itrm->in.queue.data + el, itrm->in.queue.len); if (el == -1) {
install_timer(&itrm->timer, ESC_TIMEOUT, (void (*)(void *)) kbd_timeout,
itrm);
return 0;
} else {
assertm(itrm->in.queue.len >= el, "event queue underflow");
if_assert_failed { itrm->in.queue.len = el; }
end: itrm->in.queue.len -= el;
if (itrm->in.queue.len < ITRM_IN_QUEUE_SIZE) if (itrm->in.queue.len)
handle_itrm_stdin(itrm); memmove(itrm->in.queue.data, itrm->in.queue.data + el, itrm->in.queue.len);
return el; if (itrm->in.queue.len < ITRM_IN_QUEUE_SIZE)
handle_itrm_stdin(itrm);
ret: return el;
install_timer(&itrm->timer, ESC_TIMEOUT, (void (*)(void *)) kbd_timeout, }
itrm);
return 0;
} }