Index: dblbuf.c
===================================================================
--- dblbuf.c	(revision 17)
+++ dblbuf.c	(working copy)
@@ -127,6 +127,9 @@
 	int h = t->h < d->h ? t->h : d->h;
 	int x1, x2, idx, y;
 
+	if (vt_inactive)
+		return;
+
 	/* Clean up cursor first.. */
 	idx = t->rows[b->curs_y]->idx;
 	if ((unsigned)b->slices[idx].y < d->h)
Index: main.c
===================================================================
--- main.c	(revision 17)
+++ main.c	(working copy)
@@ -1,5 +1,6 @@
 /* uuterm, Copyright (C) 2006 Rich Felker; licensed under GNU GPL v2 only */
 
+#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -11,6 +12,8 @@
 #include "uuterm.h"
 #include "ucf.h"
 
+int vt_inactive;
+
 int ucf_load(struct ucf *, const char *);
 extern const unsigned char vga_ascii_ucf[];
 
@@ -62,13 +65,20 @@
 		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, vt_inactive ? NULL : &tv) == 0)
 			d.blink++;
 
 		/* Process input from the tty, up to buffer size */
 		if (FD_ISSET(tty, &fds)) {
-			if ((l = read(tty, b, sizeof b)) <= 0)
+			if ((l = read(tty, b, sizeof b)) <= 0) {
+				if (errno == EAGAIN) {
+					/* XXX: vt switch back to us causes
+					 * read() return EAGAIN, so we need
+					 * to ignore that. */
+					continue;
+				}
 				break;
+			}
 			for (i=0; i<l; i++) {
 				uuterm_stuff_byte(&t, b[i]);
 				if (t.reslen) write(tty, t.res, t.reslen);
Index: uuterm.h
===================================================================
--- uuterm.h	(revision 17)
+++ uuterm.h	(working copy)
@@ -73,6 +73,8 @@
 	long priv[64];
 };
 
+extern int vt_inactive;
+
 #define UU_FULLWIDTH 0xfffe
 
 #define UU_ROW_SIZE(w) (sizeof(struct uurow) + (w)*sizeof(struct uucell))
Index: fbcon.c
===================================================================
--- fbcon.c	(revision 17)
+++ fbcon.c	(working copy)
@@ -9,6 +9,7 @@
 #include <sys/ioctl.h>
 
 #include <sys/kd.h>
+#include <sys/vt.h>
 #include <linux/fb.h>
 
 #include "uuterm.h"
@@ -74,87 +75,19 @@
 {
 }
 
-static int mapkey(unsigned *m, unsigned k, unsigned char *s)
+static int ttyfd;
+
+static void vtchange(int x)
 {
-#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";
+	vt_inactive = !vt_inactive;
+	ioctl(ttyfd, VT_RELDISP, VT_ACKACQ);
+	signal(SIGUSR1, vtchange);
+}
 
-	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;
+static int mapkey(unsigned *m, unsigned k, unsigned char *s)
+{
+	*s = k;
+	return 1;
 }
 
 int uudisp_open(struct uudisp *d)
@@ -162,6 +95,7 @@
 	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 +108,19 @@
 	if (p->b.vidmem == MAP_FAILED)
 		goto error;
 
-	if ((p->kb = open("/dev/tty", O_RDONLY)) < 0
+	if ((p->kb = ttyfd = open("/dev/tty", O_RDONLY)) < 0
 	 || ioctl(p->kb, KDGKBMODE, &p->kbmode) < 0
-	 || ioctl(p->kb, KDSKBMODE, K_MEDIUMRAW) < 0)
+	 || ioctl(p->kb, KDSKBMODE, K_UNICODE) < 0)
 		goto error;
 
 	/* If the above succeeds, the below cannot fail */
 	ioctl(p->kb, KDSETMODE, KD_GRAPHICS);
+	vtm.mode = VT_PROCESS;
+	vtm.waitv = 0;
+	vtm.relsig = SIGUSR1;
+	vtm.acqsig = SIGUSR1;
+	vtm.frsig = 0;
+	ioctl(p->kb, VT_SETMODE, &vtm);
 	tcgetattr(p->kb, &p->tio);
 	tio = p->tio;
 	tio.c_cflag = B38400 | CS8 | CLOCAL | CREAD;
@@ -190,6 +130,7 @@
 	tcsetattr(p->kb, TCSANOW, &tio);
 
 	signal(SIGWINCH, dummy); /* just to interrupt select! */
+	signal(SIGUSR1, vtchange);
 	signal(SIGTSTP, SIG_IGN);
 	signal(SIGTTIN, SIG_IGN);
 	signal(SIGTTOU, SIG_IGN);
@@ -236,9 +177,13 @@
 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);
