diff options
author | Rich Felker <dalias@aerifal.cx> | 2006-10-25 04:52:48 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2006-10-25 04:52:48 +0000 |
commit | 734da46346f62d0af0feed2ffd74c47e06de7157 (patch) | |
tree | 2b55dfcb62ba3fbce2a65367dda5111a399b8485 | |
parent | 9b7a5f39380ca50f0efbb30689cd3ca97bac3920 (diff) |
major changes to input handling in preparation for pasting, which will
require support for large blocks of input:
output which cannot be written to the tty (pty) is no longer
discarded. instead, the display module is responsible for keeping the
buffer alive until it has been entirely consumed. one simple (and
smart) way to ensure this is to refuse to process events that could
generate new input text as long as there is unwritten data. this works
as long as there is an earlier layer of buffering (for fbcon, kernel;
for x11, xlib). a direct-on-x-protocol display implementation will
have to do its own buffer management.
this architecture allows pasting to be performed direct from a buffer
owned by the display module, which could reside in static or shared
memory, or even as a memory-mapped file. it also facilitates reuse of
the code in non-tty-connected settings.
-rw-r--r-- | fbcon.c | 6 | ||||
-rw-r--r-- | main.c | 19 | ||||
-rw-r--r-- | xlib.c | 48 |
3 files changed, 37 insertions, 36 deletions
@@ -154,7 +154,7 @@ int uudisp_fd_set(struct uudisp *d, int tty, void *fds) { struct priv *p = (struct priv *)&d->priv; if (p->ms >= 0) FD_SET(p->ms, (fd_set *)fds); - FD_SET(p->kb, (fd_set *)fds); + if (!d->inlen) FD_SET(p->kb, (fd_set *)fds); return p->kb > tty ? p->kb+1 : tty+1; } @@ -165,10 +165,8 @@ void uudisp_next_event(struct uudisp *d, void *fds) get_fb_size(d); - d->inlen = 0; - d->intext = d->inbuf; - if (FD_ISSET(p->kb, (fd_set *)fds)) { + d->intext = d->inbuf; d->inlen = read(p->kb, d->inbuf, sizeof d->inbuf); if (d->inlen < 0) d->inlen = 0; } @@ -23,7 +23,7 @@ int main(int argc, char *argv[]) int tty, max; int i, l; unsigned char b[256]; - fd_set fds; + fd_set fds, wfds; struct timeval tv; void *buf; @@ -59,11 +59,13 @@ int main(int argc, char *argv[]) for (;;) { /* Setup fd_set containing fd's used by display and our tty */ FD_ZERO(&fds); + FD_ZERO(&wfds); FD_SET(tty, &fds); max = uudisp_fd_set(&d, tty, &fds); + if (d.inlen) FD_SET(tty, &wfds); tv.tv_sec = 0; tv.tv_usec = 250000; - if (select(max, &fds, NULL, NULL, &tv) <= 0) { + if (select(max, &fds, &wfds, NULL, &tv) <= 0) { d.blink++; FD_ZERO(&fds); } @@ -78,6 +80,15 @@ int main(int argc, char *argv[]) } } + /* Write input from previous event */ + if (d.inlen) { + int l = write(tty, d.intext, d.inlen); + if (l < 0) l = 0; + d.intext += l; + d.inlen -= l; + d.blink = 1; + } + /* Look for events from the display */ uudisp_next_event(&d, &fds); @@ -90,10 +101,6 @@ int main(int argc, char *argv[]) uutty_resize(tty, d.w, d.h); } } - if (d.inlen) { - write(tty, d.intext, d.inlen); - d.blink = 1; - } /* If no more input is pending, refresh display */ FD_ZERO(&fds); @@ -217,14 +217,13 @@ void uudisp_next_event(struct uudisp *d, void *fds) int status; int i, n; int y1, y2; + long mask = -1; - d->inlen = 0; - d->intext = d->inbuf; + if (d->inlen) mask &= ~KeyPressMask; if (!FD_ISSET(p->fd, (fd_set *)fds)) return; - while (XPending(p->display)) { - XNextEvent(p->display, &ev); + while (XCheckMaskEvent(p->display, mask, &ev)) { if (XFilterEvent(&ev, 0)) continue; switch (ev.type) { case FocusIn: @@ -244,6 +243,7 @@ void uudisp_next_event(struct uudisp *d, void *fds) resize_window(d, ev.xconfigure.width, ev.xconfigure.height); break; case KeyPress: + d->intext = d->inbuf; if (p->ic) { r = XmbLookupString(p->ic, (void *)&ev, tmp, sizeof(tmp), &ks, &status); switch(status) { @@ -260,7 +260,7 @@ void uudisp_next_event(struct uudisp *d, void *fds) } else r = XLookupString((void *)&ev, tmp, sizeof(tmp), &ks, 0); if (r>=sizeof(tmp)) continue; tmp[r] = 0; - if ((ev.xkey.state & Mod1Mask) && l) { + if (ev.xkey.state & Mod1Mask) { *s++ = '\033'; l--; } @@ -270,40 +270,36 @@ void uudisp_next_event(struct uudisp *d, void *fds) memcpy(s, keys[i].s, keys[i].l); s += keys[i].l; l -= keys[i].l; - continue; - } - if ((ev.xkey.state & ControlMask) && ks == XK_minus && l) { + } else if ((ev.xkey.state & ControlMask) + && ks == XK_minus && l) { *s++ = '_' & 0x1f; l--; - continue; - } - if ((ev.xkey.state & ControlMask) && (ks == XK_2 || ks == XK_space) && l) { + } else if ((ev.xkey.state & ControlMask) + && (ks == XK_2 || ks == XK_space) && l) { *s++ = 0; l--; + } else if (!r) { continue; - } - if (!r) continue; - - if (p->ic) { + } else if (p->ic) { if (r > l) continue; memcpy(s, tmp, r); s += r; l -= r; - continue; - } - - /* Deal with Latin-1 crap.. */ - for (i=0; i<=r; i++) wtmp[i] = tmp[i]; - r = wcstombs(mbtmp, wtmp, sizeof mbtmp); - if ((int)r > 0 && r <= l) { - memcpy(s, mbtmp, r); - s += r; - l -= r; + } else { + /* Deal with Latin-1 crap.. */ + for (i=0; i<=r; i++) wtmp[i] = tmp[i]; + r = wcstombs(mbtmp, wtmp, sizeof mbtmp); + if ((int)r > 0 && r <= l) { + memcpy(s, mbtmp, r); + s += r; + l -= r; + } } + d->inlen = s - d->inbuf; + mask &= ~KeyPressMask; break; } } - d->inlen = s - d->inbuf; } void uudisp_close(struct uudisp *d) |