Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 8a99c7ed8506480ce279d2129b1efc24cd26f307)
+++ uspace/srv/hid/console/console.c	(revision 6d5e378b28e2c858f3813b5d4d57fa46f709d753)
@@ -44,12 +44,11 @@
 #include <event.h>
 #include <io/keycode.h>
-#include <screenbuffer.h>
-#include <fb.h>
-#include <imgmap.h>
+#include <io/chargrid.h>
+#include <io/console.h>
+#include <io/output.h>
 #include <align.h>
 #include <malloc.h>
 #include <as.h>
 #include <fibril_synch.h>
-#include "images.h"
 #include "console.h"
 
@@ -57,67 +56,38 @@
 #define NAMESPACE  "term"
 
-#define CONSOLE_TOP     66
-#define CONSOLE_MARGIN  12
-
-#define STATE_START   100
-#define STATE_TOP     8
-#define STATE_SPACE   4
-#define STATE_WIDTH   48
-#define STATE_HEIGHT  48
-
-typedef enum {
-	CONS_DISCONNECTED = 0,
-	CONS_DISCONNECTED_SELECTED,
-	CONS_SELECTED,
-	CONS_IDLE,
-	CONS_DATA,
-	CONS_KERNEL,
-	CONS_LAST
-} console_state_t;
-
-#define UTF8_CHAR_BUFFER_SIZE (STR_BOUNDS(1) + 1)
+#define UTF8_CHAR_BUFFER_SIZE  (STR_BOUNDS(1) + 1)
 
 typedef struct {
-	atomic_t refcnt;           /**< Connection reference count */
-	prodcons_t input_pc;       /**< Incoming keyboard events */
-	char char_remains[UTF8_CHAR_BUFFER_SIZE]; /**< Not yet sent bytes of last char event. */
-	size_t char_remains_len;   /**< Number of not yet sent bytes. */
-	
-	fibril_mutex_t mtx;        /**< Lock protecting mutable fields */
-	
-	size_t index;              /**< Console index */
-	console_state_t state;     /**< Console state */
-	service_id_t dsid;         /**< Service handle */
-	
-	vp_handle_t state_vp;      /**< State icon viewport */
-	sysarg_t cols;             /**< Number of columns */
-	sysarg_t rows;             /**< Number of rows */
-	console_caps_t ccaps;      /**< Console capabilities */
-	
-	screenbuffer_t *frontbuf;  /**< Front buffer */
-	frontbuf_handle_t fbid;    /**< Front buffer handle */
+	atomic_t refcnt;      /**< Connection reference count */
+	prodcons_t input_pc;  /**< Incoming keyboard events */
+	
+	/**
+	 * Not yet sent bytes of last char event.
+	 */
+	char char_remains[UTF8_CHAR_BUFFER_SIZE];
+	size_t char_remains_len;  /**< Number of not yet sent bytes. */
+	
+	fibril_mutex_t mtx;  /**< Lock protecting mutable fields */
+	
+	size_t index;           /**< Console index */
+	service_id_t dsid;      /**< Service handle */
+	
+	sysarg_t cols;         /**< Number of columns */
+	sysarg_t rows;         /**< Number of rows */
+	console_caps_t ccaps;  /**< Console capabilities */
+	
+	chargrid_t *frontbuf;    /**< Front buffer */
+	frontbuf_handle_t fbid;  /**< Front buffer handle */
 } console_t;
-
-typedef enum {
-	GRAPHICS_NONE = 0,
-	GRAPHICS_BASIC = 1,
-	GRAPHICS_FULL = 2
-} graphics_state_t;
-
-/** Current console state */
-static graphics_state_t graphics_state = GRAPHICS_NONE;
-
-/** State icons */
-static imagemap_handle_t state_icons[CONS_LAST];
 
 /** Session to the input server */
 static async_sess_t *input_sess;
 
-/** Session to the framebuffer server */
-static async_sess_t *fb_sess;
-
-/** Framebuffer resolution */
-static sysarg_t xres;
-static sysarg_t yres;
+/** Session to the output server */
+static async_sess_t *output_sess;
+
+/** Output dimensions */
+static sysarg_t cols;
+static sysarg_t rows;
 
 /** Array of data for virtual consoles */
@@ -131,175 +101,48 @@
 static console_t *kernel_console = &consoles[KERNEL_CONSOLE];
 
-static imgmap_t *logo_img;
-static imgmap_t *nameic_img;
-
-static imgmap_t *anim_1_img;
-static imgmap_t *anim_2_img;
-static imgmap_t *anim_3_img;
-static imgmap_t *anim_4_img;
-
-static imagemap_handle_t anim_1;
-static imagemap_handle_t anim_2;
-static imagemap_handle_t anim_3;
-static imagemap_handle_t anim_4;
-
-static sequence_handle_t anim_seq;
-
-static imgmap_t *cons_data_img;
-static imgmap_t *cons_dis_img;
-static imgmap_t *cons_dis_sel_img;
-static imgmap_t *cons_idle_img;
-static imgmap_t *cons_kernel_img;
-static imgmap_t *cons_sel_img;
-
-static vp_handle_t logo_vp;
-static imagemap_handle_t logo_handle;
-
-static vp_handle_t nameic_vp;
-static imagemap_handle_t nameic_handle;
-
-static vp_handle_t screen_vp;
-static vp_handle_t console_vp;
-
-struct {
-	sysarg_t x;
-	sysarg_t y;
-	
-	sysarg_t btn_x;
-	sysarg_t btn_y;
-	
-	bool pressed;
-} mouse;
-
-static void cons_redraw_state(console_t *cons)
-{
-	if (graphics_state == GRAPHICS_FULL) {
-		fibril_mutex_lock(&cons->mtx);
-		
-		fb_vp_imagemap_damage(fb_sess, cons->state_vp,
-		    state_icons[cons->state], 0, 0, STATE_WIDTH, STATE_HEIGHT);
-		
-		if ((cons->state != CONS_DISCONNECTED) &&
-		    (cons->state != CONS_KERNEL) &&
-		    (cons->state != CONS_DISCONNECTED_SELECTED)) {
-			char data[5];
-			snprintf(data, 5, "%zu", cons->index + 1);
-			
-			for (size_t i = 0; data[i] != 0; i++)
-				fb_vp_putchar(fb_sess, cons->state_vp, i + 2, 1, data[i]);
-		}
-		
-		fibril_mutex_unlock(&cons->mtx);
-	}
-}
-
-static void cons_kernel_sequence_start(console_t *cons)
-{
-	if (graphics_state == GRAPHICS_FULL) {
-		fibril_mutex_lock(&cons->mtx);
-		
-		fb_vp_sequence_start(fb_sess, cons->state_vp, anim_seq);
-		fb_vp_imagemap_damage(fb_sess, cons->state_vp,
-		    state_icons[cons->state], 0, 0, STATE_WIDTH, STATE_HEIGHT);
-		
-		fibril_mutex_unlock(&cons->mtx);
-	}
-}
-
-static void cons_update_state(console_t *cons, console_state_t state)
-{
-	bool update = false;
-	
-	fibril_mutex_lock(&cons->mtx);
-	
-	if (cons->state != state) {
-		cons->state = state;
-		update = true;
-	}
-	
-	fibril_mutex_unlock(&cons->mtx);
-	
-	if (update)
-		cons_redraw_state(cons);
-}
-
-static void cons_notify_data(console_t *cons)
+static void cons_update(console_t *cons)
 {
 	fibril_mutex_lock(&switch_mtx);
-	
-	if (cons != active_console)
-		cons_update_state(cons, CONS_DATA);
-	
+	fibril_mutex_lock(&cons->mtx);
+	
+	if ((cons == active_console) && (active_console != kernel_console)) {
+		output_update(output_sess, cons->fbid);
+		output_cursor_update(output_sess, cons->fbid);
+	}
+	
+	fibril_mutex_unlock(&cons->mtx);
 	fibril_mutex_unlock(&switch_mtx);
 }
 
-static void cons_notify_connect(console_t *cons)
+static void cons_update_cursor(console_t *cons)
 {
 	fibril_mutex_lock(&switch_mtx);
-	
-	if (cons == active_console)
-		cons_update_state(cons, CONS_SELECTED);
-	else
-		cons_update_state(cons, CONS_IDLE);
-	
+	fibril_mutex_lock(&cons->mtx);
+	
+	if ((cons == active_console) && (active_console != kernel_console))
+		output_cursor_update(output_sess, cons->fbid);
+	
+	fibril_mutex_unlock(&cons->mtx);
 	fibril_mutex_unlock(&switch_mtx);
 }
 
-static void cons_notify_disconnect(console_t *cons)
+static void cons_clear(console_t *cons)
+{
+	fibril_mutex_lock(&cons->mtx);
+	chargrid_clear(cons->frontbuf);
+	fibril_mutex_unlock(&cons->mtx);
+	
+	cons_update(cons);
+}
+
+static void cons_damage(console_t *cons)
 {
 	fibril_mutex_lock(&switch_mtx);
-	
-	if (cons == active_console)
-		cons_update_state(cons, CONS_DISCONNECTED_SELECTED);
-	else
-		cons_update_state(cons, CONS_DISCONNECTED);
-	
-	fibril_mutex_unlock(&switch_mtx);
-}
-
-static void cons_update(console_t *cons)
-{
-	fibril_mutex_lock(&switch_mtx);
 	fibril_mutex_lock(&cons->mtx);
 	
 	if ((cons == active_console) && (active_console != kernel_console)) {
-		fb_vp_update(fb_sess, console_vp, cons->fbid);
-		fb_vp_cursor_update(fb_sess, console_vp, cons->fbid);
-	}
-	
-	fibril_mutex_unlock(&cons->mtx);
-	fibril_mutex_unlock(&switch_mtx);
-}
-
-static void cons_update_cursor(console_t *cons)
-{
-	fibril_mutex_lock(&switch_mtx);
-	fibril_mutex_lock(&cons->mtx);
-	
-	if ((cons == active_console) && (active_console != kernel_console))
-		fb_vp_cursor_update(fb_sess, console_vp, cons->fbid);
-	
-	fibril_mutex_unlock(&cons->mtx);
-	fibril_mutex_unlock(&switch_mtx);
-}
-
-static void cons_clear(console_t *cons)
-{
-	fibril_mutex_lock(&cons->mtx);
-	screenbuffer_clear(cons->frontbuf);
-	fibril_mutex_unlock(&cons->mtx);
-	
-	cons_update(cons);
-}
-
-static void cons_damage_all(console_t *cons)
-{
-	fibril_mutex_lock(&switch_mtx);
-	fibril_mutex_lock(&cons->mtx);
-	
-	if ((cons == active_console) && (active_console != kernel_console)) {
-		fb_vp_damage(fb_sess, console_vp, cons->fbid, 0, 0, cons->cols,
+		output_damage(output_sess, cons->fbid, 0, 0, cons->cols,
 		    cons->rows);
-		fb_vp_cursor_update(fb_sess, console_vp, cons->fbid);
+		output_cursor_update(output_sess, cons->fbid);
 	}
 	
@@ -318,7 +161,7 @@
 	
 	if (cons == kernel_console) {
-		fb_yield(fb_sess);
+		output_yield(output_sess);
 		if (!console_kcon()) {
-			fb_claim(fb_sess);
+			output_claim(output_sess);
 			fibril_mutex_unlock(&switch_mtx);
 			return;
@@ -327,23 +170,12 @@
 	
 	if (active_console == kernel_console)
-		fb_claim(fb_sess);
+		output_claim(output_sess);
 	
 	prev_console = active_console;
 	active_console = cons;
 	
-	if (prev_console->state == CONS_DISCONNECTED_SELECTED)
-		cons_update_state(prev_console, CONS_DISCONNECTED);
-	else
-		cons_update_state(prev_console, CONS_IDLE);
-	
-	if ((cons->state == CONS_DISCONNECTED) ||
-	    (cons->state == CONS_DISCONNECTED_SELECTED))
-		cons_update_state(cons, CONS_DISCONNECTED_SELECTED);
-	else
-		cons_update_state(cons, CONS_SELECTED);
-	
 	fibril_mutex_unlock(&switch_mtx);
 	
-	cons_damage_all(cons);
+	cons_damage(cons);
 }
 
@@ -351,104 +183,14 @@
 {
 	fibril_mutex_lock(&switch_mtx);
-
+	
 	console_t *active_uspace = active_console;
-	if (active_uspace == kernel_console) {
+	if (active_uspace == kernel_console)
 		active_uspace = prev_console;
-	}
+	
 	assert(active_uspace != kernel_console);
-
+	
 	fibril_mutex_unlock(&switch_mtx);
-
+	
 	return active_uspace;
-}
-
-static ssize_t limit(ssize_t val, ssize_t lo, ssize_t hi)
-{
-	if (val > hi)
-		return hi;
-	
-	if (val < lo)
-		return lo;
-	
-	return val;
-}
-
-static void cons_mouse_move(sysarg_t dx, sysarg_t dy)
-{
-	ssize_t sx = (ssize_t) dx;
-	ssize_t sy = (ssize_t) dy;
-	
-	mouse.x = limit(mouse.x + sx, 0, xres);
-	mouse.y = limit(mouse.y + sy, 0, yres);
-	
-	fb_pointer_update(fb_sess, mouse.x, mouse.y, true);
-}
-
-static void cons_mouse_abs_move(sysarg_t x, sysarg_t y,
-    sysarg_t max_x, sysarg_t max_y)
-{
-	if (max_x && max_y) {
-		mouse.x = limit(x * xres / max_x, 0, xres);
-		mouse.y = limit(y * yres / max_y, 0, yres);
-		
-		fb_pointer_update(fb_sess, mouse.x, mouse.y, true);
-	}
-}
-
-static console_t *cons_find_icon(sysarg_t x, sysarg_t y)
-{
-	sysarg_t status_start =
-	    STATE_START + (xres - 800) / 2 + CONSOLE_MARGIN;
-	
-	if ((y < STATE_TOP) || (y >= STATE_TOP + STATE_HEIGHT))
-		return NULL;
-	
-	if (x < status_start)
-		return NULL;
-	
-	if (x >= status_start + (STATE_WIDTH + STATE_SPACE) * CONSOLE_COUNT)
-		return NULL;
-	
-	if (((x - status_start) % (STATE_WIDTH + STATE_SPACE)) >= STATE_WIDTH)
-		return NULL;
-	
-	sysarg_t btn = (x - status_start) / (STATE_WIDTH + STATE_SPACE);
-	
-	if (btn < CONSOLE_COUNT)
-		return consoles + btn;
-	
-	return NULL;
-}
-
-/** Handle mouse click
- *
- * @param state Button state (true - pressed, false - depressed)
- *
- */
-static console_t *cons_mouse_button(bool state)
-{
-	if (graphics_state != GRAPHICS_FULL)
-		return NULL;
-	
-	if (state) {
-		console_t *cons = cons_find_icon(mouse.x, mouse.y);
-		if (cons != NULL) {
-			mouse.btn_x = mouse.x;
-			mouse.btn_y = mouse.y;
-			mouse.pressed = true;
-		}
-		
-		return NULL;
-	}
-	
-	if ((!state) && (!mouse.pressed))
-		return NULL;
-	
-	console_t *cons = cons_find_icon(mouse.x, mouse.y);
-	if (cons == cons_find_icon(mouse.btn_x, mouse.btn_y))
-		return cons;
-	
-	mouse.pressed = false;
-	return NULL;
 }
 
@@ -511,20 +253,7 @@
 			break;
 		case INPUT_EVENT_MOVE:
-			cons_mouse_move(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
-			async_answer_0(callid, EOK);
-			break;
-		case INPUT_EVENT_ABS_MOVE:
-			cons_mouse_abs_move(IPC_GET_ARG1(call), IPC_GET_ARG2(call),
-			    IPC_GET_ARG3(call), IPC_GET_ARG4(call));
 			async_answer_0(callid, EOK);
 			break;
 		case INPUT_EVENT_BUTTON:
-			/* Got pointer button press/release event */
-			if (IPC_GET_ARG1(call) == 1) {
-				console_t *cons =
-				    cons_mouse_button((bool) IPC_GET_ARG2(call));
-				if (cons != NULL)
-					cons_switch(cons);
-			}
 			async_answer_0(callid, EOK);
 			break;
@@ -544,16 +273,16 @@
 	switch (ch) {
 	case '\n':
-		updated = screenbuffer_newline(cons->frontbuf);
+		updated = chargrid_newline(cons->frontbuf);
 		break;
 	case '\r':
 		break;
 	case '\t':
-		updated = screenbuffer_tabstop(cons->frontbuf, 8);
+		updated = chargrid_tabstop(cons->frontbuf, 8);
 		break;
 	case '\b':
-		updated = screenbuffer_backspace(cons->frontbuf);
+		updated = chargrid_backspace(cons->frontbuf);
 		break;
 	default:
-		updated = screenbuffer_putchar(cons->frontbuf, ch, true);
+		updated = chargrid_putchar(cons->frontbuf, ch, true);
 	}
 	
@@ -567,5 +296,5 @@
 {
 	fibril_mutex_lock(&cons->mtx);
-	screenbuffer_set_cursor(cons->frontbuf, col, row);
+	chargrid_set_cursor(cons->frontbuf, col, row);
 	fibril_mutex_unlock(&cons->mtx);
 	
@@ -576,5 +305,5 @@
 {
 	fibril_mutex_lock(&cons->mtx);
-	screenbuffer_set_cursor_visibility(cons->frontbuf, visible);
+	chargrid_set_cursor_visibility(cons->frontbuf, visible);
 	fibril_mutex_unlock(&cons->mtx);
 	
@@ -588,5 +317,5 @@
 	
 	fibril_mutex_lock(&cons->mtx);
-	screenbuffer_get_cursor(cons->frontbuf, &col, &row);
+	chargrid_get_cursor(cons->frontbuf, &col, &row);
 	fibril_mutex_unlock(&cons->mtx);
 	
@@ -611,6 +340,4 @@
 	async_answer_1(iid, EOK, size);
 	free(buf);
-	
-	cons_notify_data(cons);
 }
 
@@ -676,5 +403,5 @@
 {
 	fibril_mutex_lock(&cons->mtx);
-	screenbuffer_set_style(cons->frontbuf, style);
+	chargrid_set_style(cons->frontbuf, style);
 	fibril_mutex_unlock(&cons->mtx);
 }
@@ -684,5 +411,5 @@
 {
 	fibril_mutex_lock(&cons->mtx);
-	screenbuffer_set_color(cons->frontbuf, bgcolor, fgcolor, attr);
+	chargrid_set_color(cons->frontbuf, bgcolor, fgcolor, attr);
 	fibril_mutex_unlock(&cons->mtx);
 }
@@ -692,5 +419,5 @@
 {
 	fibril_mutex_lock(&cons->mtx);
-	screenbuffer_set_rgb_color(cons->frontbuf, bgcolor, fgcolor);
+	chargrid_set_rgb_color(cons->frontbuf, bgcolor, fgcolor);
 	fibril_mutex_unlock(&cons->mtx);
 }
@@ -724,8 +451,6 @@
 	}
 	
-	if (atomic_postinc(&cons->refcnt) == 0) {
+	if (atomic_postinc(&cons->refcnt) == 0)
 		cons_set_cursor_visibility(cons, true);
-		cons_notify_connect(cons);
-	}
 	
 	/* Accept the connection */
@@ -736,10 +461,6 @@
 		ipc_callid_t callid = async_get_call(&call);
 		
-		if (!IPC_GET_IMETHOD(call)) {
-			if (atomic_postdec(&cons->refcnt) == 1)
-				cons_notify_disconnect(cons);
-			
+		if (!IPC_GET_IMETHOD(call))
 			return;
-		}
 		
 		switch (IPC_GET_IMETHOD(call)) {
@@ -832,5 +553,5 @@
 }
 
-static async_sess_t *fb_connect(const char *svc)
+static async_sess_t *output_connect(const char *svc)
 {
 	async_sess_t *sess;
@@ -841,5 +562,5 @@
 		sess = loc_service_connect(EXCHANGE_SERIALIZE, dsid, 0);
 		if (sess == NULL) {
-			printf("%s: Unable to connect to framebuffer service %s\n",
+			printf("%s: Unable to connect to output service %s\n",
 			    NAME, svc);
 			return NULL;
@@ -851,10 +572,6 @@
 }
 
-static bool console_srv_init(char *input_svc, char *fb_svc)
-{
-	/* Avoid double initialization */
-	if (graphics_state != GRAPHICS_NONE)
-		return false;
-	
+static bool console_srv_init(char *input_svc, char *output_svc)
+{
 	/* Connect to input service */
 	input_sess = input_connect(input_svc);
@@ -862,7 +579,7 @@
 		return false;
 	
-	/* Connect to framebuffer service */
-	fb_sess = fb_connect(fb_svc);
-	if (fb_sess == NULL)
+	/* Connect to output service */
+	output_sess = output_connect(output_svc);
+	if (output_sess == NULL)
 		return false;
 	
@@ -876,94 +593,9 @@
 	}
 	
-	fb_get_resolution(fb_sess, &xres, &yres);
-	
-	/* Initialize the screen */
-	screen_vp = fb_vp_create(fb_sess, 0, 0, xres, yres);
-	
-	if ((xres >= 800) && (yres >= 600)) {
-		logo_vp = fb_vp_create(fb_sess, xres - 66, 2, 64, 60);
-		logo_img = imgmap_decode_tga((void *) helenos_tga,
-		    helenos_tga_size, IMGMAP_FLAG_SHARED);
-		logo_handle = fb_imagemap_create(fb_sess, logo_img);
-		
-		nameic_vp = fb_vp_create(fb_sess, 5, 17, 100, 26);
-		nameic_img = imgmap_decode_tga((void *) nameic_tga,
-		    nameic_tga_size, IMGMAP_FLAG_SHARED);
-		nameic_handle = fb_imagemap_create(fb_sess, nameic_img);
-		
-		cons_data_img = imgmap_decode_tga((void *) cons_data_tga,
-		    cons_data_tga_size, IMGMAP_FLAG_SHARED);
-		cons_dis_img = imgmap_decode_tga((void *) cons_dis_tga,
-		    cons_dis_tga_size, IMGMAP_FLAG_SHARED);
-		cons_dis_sel_img = imgmap_decode_tga((void *) cons_dis_sel_tga,
-		    cons_dis_sel_tga_size, IMGMAP_FLAG_SHARED);
-		cons_idle_img = imgmap_decode_tga((void *) cons_idle_tga,
-		    cons_idle_tga_size, IMGMAP_FLAG_SHARED);
-		cons_kernel_img = imgmap_decode_tga((void *) cons_kernel_tga,
-		    cons_kernel_tga_size, IMGMAP_FLAG_SHARED);
-		cons_sel_img = imgmap_decode_tga((void *) cons_sel_tga,
-		    cons_sel_tga_size, IMGMAP_FLAG_SHARED);
-		
-		state_icons[CONS_DISCONNECTED] =
-		    fb_imagemap_create(fb_sess, cons_dis_img);
-		state_icons[CONS_DISCONNECTED_SELECTED] =
-		    fb_imagemap_create(fb_sess, cons_dis_sel_img);
-		state_icons[CONS_SELECTED] =
-		    fb_imagemap_create(fb_sess, cons_sel_img);
-		state_icons[CONS_IDLE] =
-		    fb_imagemap_create(fb_sess, cons_idle_img);
-		state_icons[CONS_DATA] =
-		    fb_imagemap_create(fb_sess, cons_data_img);
-		state_icons[CONS_KERNEL] =
-		    fb_imagemap_create(fb_sess, cons_kernel_img);
-		
-		anim_1_img = imgmap_decode_tga((void *) anim_1_tga,
-		    anim_1_tga_size, IMGMAP_FLAG_SHARED);
-		anim_2_img = imgmap_decode_tga((void *) anim_2_tga,
-		    anim_2_tga_size, IMGMAP_FLAG_SHARED);
-		anim_3_img = imgmap_decode_tga((void *) anim_3_tga,
-		    anim_3_tga_size, IMGMAP_FLAG_SHARED);
-		anim_4_img = imgmap_decode_tga((void *) anim_4_tga,
-		    anim_4_tga_size, IMGMAP_FLAG_SHARED);
-		
-		anim_1 = fb_imagemap_create(fb_sess, anim_1_img);
-		anim_2 = fb_imagemap_create(fb_sess, anim_2_img);
-		anim_3 = fb_imagemap_create(fb_sess, anim_3_img);
-		anim_4 = fb_imagemap_create(fb_sess, anim_4_img);
-		
-		anim_seq = fb_sequence_create(fb_sess);
-		fb_sequence_add_imagemap(fb_sess, anim_seq, anim_1);
-		fb_sequence_add_imagemap(fb_sess, anim_seq, anim_2);
-		fb_sequence_add_imagemap(fb_sess, anim_seq, anim_3);
-		fb_sequence_add_imagemap(fb_sess, anim_seq, anim_4);
-		
-		console_vp = fb_vp_create(fb_sess, CONSOLE_MARGIN, CONSOLE_TOP,
-		    xres - 2 * CONSOLE_MARGIN, yres - (CONSOLE_TOP + CONSOLE_MARGIN));
-		
-		fb_vp_clear(fb_sess, screen_vp);
-		fb_vp_imagemap_damage(fb_sess, logo_vp, logo_handle,
-		    0, 0, 64, 60);
-		fb_vp_imagemap_damage(fb_sess, nameic_vp, nameic_handle,
-		    0, 0, 100, 26);
-		
-		graphics_state = GRAPHICS_FULL;
-	} else {
-		console_vp = screen_vp;
-		graphics_state = GRAPHICS_BASIC;
-	}
-	
-	fb_vp_set_style(fb_sess, console_vp, STYLE_NORMAL);
-	fb_vp_clear(fb_sess, console_vp);
-	
-	sysarg_t cols;
-	sysarg_t rows;
-	fb_vp_get_dimensions(fb_sess, console_vp, &cols, &rows);
+	output_get_dimensions(output_sess, &cols, &rows);
+	output_set_style(output_sess, STYLE_NORMAL);
 	
 	console_caps_t ccaps;
-	fb_vp_get_caps(fb_sess, console_vp, &ccaps);
-	
-	mouse.x = xres / 2;
-	mouse.y = yres / 2;
-	mouse.pressed = false;
+	output_get_caps(output_sess, &ccaps);
 	
 	/* Inititalize consoles */
@@ -975,23 +607,6 @@
 		consoles[i].char_remains_len = 0;
 		
-		if (graphics_state == GRAPHICS_FULL) {
-			/* Create state buttons */
-			consoles[i].state_vp =
-			    fb_vp_create(fb_sess, STATE_START + (xres - 800) / 2 +
-			    CONSOLE_MARGIN + i * (STATE_WIDTH + STATE_SPACE),
-			    STATE_TOP, STATE_WIDTH, STATE_HEIGHT);
-		}
-		
-		if (i == KERNEL_CONSOLE) {
-			consoles[i].state = CONS_KERNEL;
-			cons_redraw_state(&consoles[i]);
-			cons_kernel_sequence_start(&consoles[i]);
+		if (i == KERNEL_CONSOLE)
 			continue;
-		}
-		
-		if (i == 0)
-			consoles[i].state = CONS_DISCONNECTED_SELECTED;
-		else
-			consoles[i].state = CONS_DISCONNECTED;
 		
 		consoles[i].cols = cols;
@@ -999,5 +614,5 @@
 		consoles[i].ccaps = ccaps;
 		consoles[i].frontbuf =
-		    screenbuffer_create(cols, rows, SCREENBUFFER_FLAG_SHARED);
+		    chargrid_create(cols, rows, CHARGRID_FLAG_SHARED);
 		
 		if (consoles[i].frontbuf == NULL) {
@@ -1006,5 +621,6 @@
 		}
 		
-		consoles[i].fbid = fb_frontbuf_create(fb_sess, consoles[i].frontbuf);
+		consoles[i].fbid = output_frontbuf_create(output_sess,
+		    consoles[i].frontbuf);
 		if (consoles[i].fbid == 0) {
 			printf("%s: Unable to create frontbuffer %zu\n", NAME, i);
@@ -1012,6 +628,4 @@
 		}
 		
-		cons_redraw_state(&consoles[i]);
-		
 		char vc[LOC_NAME_MAXLEN + 1];
 		snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i);
@@ -1022,4 +636,6 @@
 		}
 	}
+	
+	cons_damage(active_console);
 	
 	/* Receive kernel notifications */
@@ -1033,7 +649,7 @@
 }
 
-static void usage(void)
-{
-	printf("Usage: console <input_dev> <framebuffer_dev>\n");
+static void usage(char *name)
+{
+	printf("Usage: %s <input_dev> <output_dev>\n", name);
 }
 
@@ -1041,5 +657,5 @@
 {
 	if (argc < 3) {
-		usage();
+		usage(argv[0]);
 		return -1;
 	}
@@ -1054,4 +670,5 @@
 	async_manager();
 	
+	/* Never reached */
 	return 0;
 }
