diff --git a/libs/input/evdev/inputlib.c b/libs/input/evdev/inputlib.c
index cf5ff7bbd..065c57dc0 100644
--- a/libs/input/evdev/inputlib.c
+++ b/libs/input/evdev/inputlib.c
@@ -17,6 +17,7 @@
 #include <string.h>
 
 #include "QF/dstring.h"
+#include "QF/sys.h"
 
 #include "evdev/hotplug.h"
 #include "evdev/inputlib.h"
@@ -39,7 +40,7 @@ setup_buttons (device_t *dev)
 	dev->buttons = 0;
 	len = ioctl (dev->fd, EVIOCGBIT (EV_KEY, sizeof (buf)), buf);
 	for (i = 0; i < len; i++) {
-		//printf("%c%02x", !(i % 16) ? '\n': !(i % 8) ? '-' : ' ', buf[i]);
+		//Sys_Printf("%c%02x", !(i % 16) ? '\n': !(i % 8) ? '-' : ' ', buf[i]);
 		for (j = 0; j < 8; j++) {
 			if (buf[i] & (1 << j)) {
 				dev->num_buttons++;
@@ -47,7 +48,7 @@ setup_buttons (device_t *dev)
 			}
 		}
 	}
-	//printf("\n");
+	//Sys_Printf("\n");
 	dev->button_map = malloc ((dev->max_button + 1) * sizeof (int));
 	dev->buttons = malloc (dev->num_buttons * sizeof (button_t));
 	for (i = 0, button = dev->buttons; i < len; i++) {
@@ -212,10 +213,10 @@ check_device (const char *path)
 
 	dev->event_count = 0;
 
-	printf ("%s:\n", path);
-	printf ("\tname: %s\n", dev->name);
-	printf ("\tbuttons: %d\n", dev->num_buttons);
-	printf ("\taxes: %d\n", dev->num_axes);
+	//Sys_Printf ("%s:\n", path);
+	//Sys_Printf ("\tname: %s\n", dev->name);
+	//Sys_Printf ("\tbuttons: %d\n", dev->num_buttons);
+	//Sys_Printf ("\taxes: %d\n", dev->num_axes);
 
 	if (device_add) {
 		device_add (dev);
@@ -261,7 +262,7 @@ read_device_input (device_t *dev)
 			return;
 		}
 		//const char *ev = event_codes[event.type];
-		//printf ("%6d(%s) %6d %6x\n", event.type, ev ? ev : "?", event.code, event.value);
+		//Sys_Printf ("%6d(%s) %6d %6x\n", event.type, ev ? ev : "?", event.code, event.value);
 		switch (event.type) {
 			case EV_SYN:
 				dev->event_count++;
@@ -278,7 +279,7 @@ read_device_input (device_t *dev)
 				break;
 			case EV_REL:
 				axis = &dev->axes[dev->rel_axis_map[event.code]];
-				//printf ("EV_REL %6d %6x %6d %p\n", event.code, event.value,
+				//Sys_Printf ("EV_REL %6d %6x %6d %p\n", event.code, event.value,
 				//		dev->rel_axis_map[event.code], axis);
 				axis->value = event.value;
 				break;
@@ -289,7 +290,7 @@ read_device_input (device_t *dev)
 			case EV_FF:
 			case EV_PWR:
 			case EV_FF_STATUS:
-				//printf ("%6d %6d %6x\n", event.type, event.code, event.value);
+				//Sys_Printf ("%6d %6d %6x\n", event.type, event.code, event.value);
 				break;
 		}
 	}
@@ -403,7 +404,7 @@ device_created (const char *name)
 		}
 	}
 	if (!olddev && check_device (devname) >= 0) {
-		//printf ("found device %s\n", devname);
+		//Sys_Printf ("found device %s\n", devname);
 	}
 	free (devname);
 }
@@ -416,7 +417,7 @@ device_deleted (const char *name)
 
 	for (dev = &devices; *dev; dev = &(*dev)->next) {
 		if (strcmp ((*dev)->path, devname) == 0) {
-			//printf ("lost device %s\n", (*dev)->path);
+			//Sys_Printf ("lost device %s\n", (*dev)->path);
 			close_device (*dev);
 			device_t *d = *dev;
 			*dev = (*dev)->next;
@@ -448,7 +449,7 @@ scan_devices (void)
 		if (check_input_device (devinput_path, dirent->d_name) < 0) {
 			continue;
 		}
-		//printf("%s\n", dirent->d_name);
+		//Sys_Printf("%s\n", dirent->d_name);
 	}
 	closedir (dir);
 	return 0;
diff --git a/ruamoko/qwaq/builtins/curses.c b/ruamoko/qwaq/builtins/curses.c
index 9e4b5269e..ee301c6bc 100644
--- a/ruamoko/qwaq/builtins/curses.c
+++ b/ruamoko/qwaq/builtins/curses.c
@@ -2040,15 +2040,6 @@ static builtin_t builtins[] = {
 	{0}
 };
 
-static FILE *logfile;
-
-static __attribute__((format(PRINTF, 1, 0))) void
-qwaq_print (const char *fmt, va_list args)
-{
-	vfprintf (logfile, fmt, args);
-	fflush (logfile);
-}
-
 void
 qwaq_init_cond (rwcond_t *cond)
 {
@@ -2079,6 +2070,4 @@ BI_Init (progs_t *pr)
 	PR_Resources_Register (pr, "qwaq", res, bi_qwaq_clear);
 	PR_RegisterBuiltins (pr, builtins);
 	Sys_RegisterShutdown (bi_shutdown, pr);
-	logfile = fopen ("qwaq-curses.log", "wt");
-	Sys_SetStdPrintf (qwaq_print);
 }
diff --git a/ruamoko/qwaq/builtins/input.c b/ruamoko/qwaq/builtins/input.c
index 67d491cc8..94a95764b 100644
--- a/ruamoko/qwaq/builtins/input.c
+++ b/ruamoko/qwaq/builtins/input.c
@@ -46,6 +46,7 @@
 
 #include "QF/dstring.h"
 #include "QF/hash.h"
+#include "QF/input.h"
 #include "QF/keys.h"
 #include "QF/sys.h"
 
@@ -355,7 +356,7 @@ static void process_char (qwaq_resources_t *res, char ch)
 					// will wind up accepting P;P... but meh
 					res->escstate = esc_key;
 					dstring_clear (&res->escbuff);
-					// start the buffer with what got us hear: eases key lookup
+					// start the buffer with what got us here: eases key lookup
 					dstring_append (&res->escbuff, "\033O", 2);
 				} else {
 					res->escstate = esc_ground;
@@ -371,7 +372,7 @@ static void process_char (qwaq_resources_t *res, char ch)
 				} else if (ch >= '0' && ch < 127) {
 					res->escstate = esc_key;
 					dstring_clear (&res->escbuff);
-					// start the buffer with what got us hear: eases key lookup
+					// start the buffer with what got us here: eases key lookup
 					dstring_append (&res->escbuff, "\033[", 2);
 					// the csi code might be short (eg, \e[H for home) so
 					// need to check for end of string right away
@@ -422,8 +423,60 @@ key_sequence_getkey (const void *_seq, void *unused)
 	return seq->sequence;
 }
 
-void qwaq_input_init (qwaq_resources_t *res)
+static void
+term_init (void *_res)
 {
+}
+
+static void
+term_shutdown (void *_res)
+{
+}
+
+static void
+term_process_events (void *_res)
+{
+	qwaq_resources_t *res = _res;
+	char        buf[256];
+	int         len;
+#ifdef HAVE_SIGACTION
+	sigset_t    save_set;
+	int         saw_winch;
+
+	pthread_sigmask (SIG_BLOCK, &winch_mask, &save_set);
+	saw_winch = winch_arrived;
+	winch_arrived = 0;
+	pthread_sigmask (SIG_SETMASK, &save_set, 0);
+	if (saw_winch) {
+		resize_event (res);
+	}
+#endif
+	while (Sys_CheckInput (1, -1)) {
+		len = read(0, buf, sizeof (buf));
+		for (int i = 0; i < len; i++) {
+			process_char (res, buf[i]);
+		}
+	}
+}
+
+static in_driver_t term_driver = {
+	.init = term_init,
+	.shutdown = term_shutdown,
+	.process_events = term_process_events,
+};
+static int term_driver_handle;
+
+static void __attribute__((constructor))
+term_register_driver (void)
+{
+	term_driver_handle = IN_RegisterDriver (&term_driver, 0);
+}
+
+void
+qwaq_input_init (qwaq_resources_t *res)
+{
+	IN_DriverData (term_driver_handle, res);
+
 	if (res->key_sequences) {
 		Hash_FlushTable (res->key_sequences);
 	} else {
@@ -449,8 +502,17 @@ void qwaq_input_init (qwaq_resources_t *res)
 	(void) !write(1, SGR_ON, sizeof (SGR_ON) - 1);
 }
 
-void qwaq_input_shutdown (qwaq_resources_t *res)
+void
+qwaq_process_input (qwaq_resources_t *res)
 {
+	IN_ProcessEvents ();
+}
+
+void
+qwaq_input_shutdown (qwaq_resources_t *res)
+{
+	IN_DriverData (term_driver_handle, 0);
+
 	// ncurses takes care of input mode for us, so need only tell xterm
 	// what we need
 	(void) !write(1, SGR_OFF, sizeof (SGR_OFF) - 1);
@@ -460,27 +522,3 @@ void qwaq_input_shutdown (qwaq_resources_t *res)
 	sigaction (SIGWINCH, &save_winch, 0);
 #endif
 }
-
-void qwaq_process_input (qwaq_resources_t *res)
-{
-	char        buf[256];
-	int         len;
-#ifdef HAVE_SIGACTION
-	sigset_t    save_set;
-	int         saw_winch;
-
-	pthread_sigmask (SIG_BLOCK, &winch_mask, &save_set);
-	saw_winch = winch_arrived;
-	winch_arrived = 0;
-	pthread_sigmask (SIG_SETMASK, &save_set, 0);
-	if (saw_winch) {
-		resize_event (res);
-	}
-#endif
-	while (Sys_CheckInput (1, -1)) {
-		len = read(0, buf, sizeof (buf));
-		for (int i = 0; i < len; i++) {
-			process_char (res, buf[i]);
-		}
-	}
-}
diff --git a/ruamoko/qwaq/builtins/qwaq-curses.c b/ruamoko/qwaq/builtins/qwaq-curses.c
index 354f7acb9..a5695babc 100644
--- a/ruamoko/qwaq/builtins/qwaq-curses.c
+++ b/ruamoko/qwaq/builtins/qwaq-curses.c
@@ -70,11 +70,23 @@ static progsinit_f target_app[] = {
 	0
 };
 
+static FILE *logfile;
+
+static __attribute__((format(PRINTF, 1, 0))) void
+qwaq_print (const char *fmt, va_list args)
+{
+	vfprintf (logfile, fmt, args);
+	fflush (logfile);
+}
+
 int
 qwaq_init_threads (qwaq_thread_set_t *thread_data)
 {
 	int         main_ind = -1;
 
+	logfile = fopen ("qwaq-curses.log", "wt");
+	Sys_SetStdPrintf (qwaq_print);
+
 	IN_Init_Cvars ();
 	IN_Init (qwaq_cbuf);