diff options
author | Rich Felker <dalias@aerifal.cx> | 2006-10-08 23:43:13 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2006-10-08 23:43:13 +0000 |
commit | 916c3fb0040ff697e2abfe3791e89512499f8ccb (patch) | |
tree | 39c1689ffed8e89100a25045329e999751b874bc | |
parent | 91f215a78c28986a12f4cd9d5e03ffea17b3363e (diff) |
fbcon target: let the kernel do the key mapping for us...
this made it easy to fix vc switching and window resizing, so i'm
fixing those in the same commit as well.
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | dblbuf.c | 3 | ||||
-rw-r--r-- | dblbuf.h | 1 | ||||
-rw-r--r-- | fbcon.c | 134 | ||||
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | term.c | 2 |
6 files changed, 48 insertions, 98 deletions
@@ -7,7 +7,6 @@ Critical usability issues: - Indic character reordering - Porting to X - Mouse support/selection -- Configurable keyboard mappings - Support for input methods @@ -18,7 +17,6 @@ Convenience/eyecandy/etc.: - Fontsets instead of monolithic font - UCF compiler - Terminal escapes for input method interaction -- Allow VC switching Long term goals: @@ -127,6 +127,9 @@ void uudisp_refresh(struct uudisp *d, struct uuterm *t) int h = t->h < d->h ? t->h : d->h; int x1, x2, idx, y; + if (!b->active) return; + if (b->repaint) for (idx=0; idx<h; idx++) b->slices[idx].y = -1; + /* Clean up cursor first.. */ idx = t->rows[b->curs_y]->idx; if ((unsigned)b->slices[idx].y < d->h) @@ -13,6 +13,7 @@ struct dblbuf struct slice *slices; unsigned cs, ch; + int active, repaint; unsigned curs_x; unsigned curs_y; @@ -8,6 +8,7 @@ #include <sys/mman.h> #include <sys/ioctl.h> +#include <sys/vt.h> #include <sys/kd.h> #include <linux/fb.h> @@ -23,8 +24,6 @@ struct priv int kb; int ms; struct termios tio; - int kbmode; - int mod; int xres, yres; void *buf_mem; }; @@ -56,6 +55,8 @@ static int get_fb_size(struct uudisp *d) p->yres = var.yres; d->w = w; d->h = h; + p->b.repaint = 1; + p->b.curs_x = p->b.curs_y = 0; } return 0; @@ -74,87 +75,12 @@ static void dummy(int x) { } -static int mapkey(unsigned *m, unsigned k, unsigned char *s) +static void vtswitch(int sig) { -#define LSHIFT "\200" -#define LCTRL "\201" -#define LALT "\202" -#define RSHIFT "\203" -#define RCTRL "\204" -#define RALT "\205" -#define CAPSLK "\206" -#define NUMLK "\207" -#define SCRLK "\210" -#define WTF "\377" - static const unsigned char keymap[] = - "\0\033" "1234567890-=\177" - "\t" "qwertyuiop[]\r" - LCTRL "asdfghjkl;'`" - LSHIFT "\\zxcvbnm,./" RSHIFT "*" - LALT " " CAPSLK - "\301\302\303\304\305\306\307\310\311\312" - NUMLK SCRLK; - static const unsigned char keymap_sh[] = - "\0\033" "!@#$%^&*()_+\177" - "\t" "QWERTYUIOP{}\r" - LCTRL "ASDFGHJKL:\"~" - LSHIFT "|ZXCVBNM<>?" RSHIFT "*" - LALT " " CAPSLK - "\301\302\303\304\305\306\307\310\311\312" - NUMLK SCRLK; - //71... - static const unsigned char keypad[] = "789-456+1230."; - //64..95 useless - //96... - static const unsigned char keypad2[] = "\r" RCTRL WTF "/" RALT WTF; - //102... - static const unsigned char cursblk[] = "1A5DC4B623"; - - unsigned c; - unsigned rel = k & 0x80; - int i = 0; - - k &= 0x7f; - if (*m & 4) s[i++] = '\033'; - if (k < sizeof(keymap)) { - c = keymap[k]; - if (c-0200 < 6) { - c &= 15; - if (rel) *m &= ~(1<<c); - else *m |= 1<<c; - return 0; - } - if (rel) return 0; - if (c > 0300) { - c -= 0300; - s[i++] = '\033'; - s[i++] = '['; - if (c < 6) s[i++] = '['; - else if (c < 9) s[i++] = '1'; - else s[i++] = '2'; - s[i++] = "ABCDE7890134"[c-1]; - if (c >= 6) s[i++] = '~'; - return i; - } - if (c > 0x80) return 0; - if (*m & 9) c = keymap_sh[k]; - if (*m & 18) { - if (keymap_sh[k] >= '@') c = keymap_sh[k] & 0x1f; - else c &= 0x1f; - } - s[i++] = c; - return i; - } - if (k-102 < sizeof(cursblk)) { - if (rel) return 0; - s[i++] = '\033'; - s[i++] = '['; - c = cursblk[k-102]; - s[i++] = c; - if (c < 'A') s[i++] = '~'; - return i; - } - return 0; + struct priv *p = (void *)&display->priv; + p->b.repaint = p->b.active = sig == SIGUSR2; + ioctl(p->kb, VT_RELDISP, VT_ACKACQ); + signal(sig, vtswitch); } int uudisp_open(struct uudisp *d) @@ -162,6 +88,7 @@ int uudisp_open(struct uudisp *d) struct priv *p = (void *)&d->priv; struct fb_fix_screeninfo fix; struct termios tio; + struct vt_mode vtm; p->fb = p->kb = p->ms = -1; p->b.vidmem = MAP_FAILED; @@ -174,13 +101,23 @@ int uudisp_open(struct uudisp *d) if (p->b.vidmem == MAP_FAILED) goto error; + display = d; + + signal(SIGINT, fatalsignal); + signal(SIGTERM, fatalsignal); + signal(SIGSEGV, fatalsignal); + signal(SIGBUS, fatalsignal); + signal(SIGABRT, fatalsignal); + signal(SIGFPE, fatalsignal); + + signal(SIGUSR1, vtswitch); + signal(SIGUSR2, vtswitch); + if ((p->kb = open("/dev/tty", O_RDONLY)) < 0 - || ioctl(p->kb, KDGKBMODE, &p->kbmode) < 0 - || ioctl(p->kb, KDSKBMODE, K_MEDIUMRAW) < 0) + || ioctl(p->kb, KDSETMODE, KD_GRAPHICS) < 0) goto error; /* If the above succeeds, the below cannot fail */ - ioctl(p->kb, KDSETMODE, KD_GRAPHICS); tcgetattr(p->kb, &p->tio); tio = p->tio; tio.c_cflag = B38400 | CS8 | CLOCAL | CREAD; @@ -189,18 +126,20 @@ int uudisp_open(struct uudisp *d) tio.c_lflag = 0; tcsetattr(p->kb, TCSANOW, &tio); + vtm.mode = VT_PROCESS; + vtm.waitv = 0; + vtm.relsig = SIGUSR1; + vtm.acqsig = SIGUSR2; + vtm.frsig = 0; + ioctl(p->kb, VT_SETMODE, &vtm); + signal(SIGWINCH, dummy); /* just to interrupt select! */ signal(SIGTSTP, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); - display = d; - signal(SIGINT, fatalsignal); - signal(SIGTERM, fatalsignal); - signal(SIGSEGV, fatalsignal); - signal(SIGBUS, fatalsignal); - signal(SIGABRT, fatalsignal); - signal(SIGFPE, fatalsignal); + /* FIXME: need to actually detect if the VC is active */ + p->b.active = 1; return 0; error: @@ -229,16 +168,21 @@ void uudisp_next_event(struct uudisp *d, void *fds) d->inlen = 0; d->intext = d->inbuf; - if (FD_ISSET(p->kb, (fd_set *)fds) && read(p->kb, &b, 1) == 1) - d->inlen = mapkey(&p->mod, b, d->intext); + if (FD_ISSET(p->kb, (fd_set *)fds)) { + d->inlen = read(p->kb, d->inbuf, sizeof d->inbuf); + if (d->inlen < 0) d->inlen = 0; + } } void uudisp_close(struct uudisp *d) { struct priv *p = (struct priv *)&d->priv; + struct vt_mode vtm; tcsetattr(p->kb, TCSANOW, &p->tio); - ioctl(p->kb, KDSKBMODE, p->kbmode); ioctl(p->kb, KDSETMODE, KD_TEXT); + vtm.mode = VT_AUTO; + vtm.waitv = 0; + ioctl(p->kb, VT_SETMODE, &vtm); close(p->fb); close(p->kb); close(p->ms); @@ -62,8 +62,10 @@ int main(int argc, char *argv[]) max = uudisp_fd_set(&d, tty, &fds); tv.tv_sec = 0; tv.tv_usec = 250000; - if (select(max, &fds, NULL, NULL, &tv) == 0) + if (select(max, &fds, NULL, NULL, &tv) <= 0) { d.blink++; + FD_ZERO(&fds); + } /* Process input from the tty, up to buffer size */ if (FD_ISSET(tty, &fds)) { @@ -486,6 +486,8 @@ void uuterm_replace_buffer(struct uuterm *t, int w, int h, void *buf) rows[i]->x2 = w-1; } + if (t->sr_y2 == t->h-1) t->sr_y2 = h-1; + t->w = w; t->h = h; t->rows = rows; |