Index: uspace/srv/console/Makefile
===================================================================
--- uspace/srv/console/Makefile	(revision 1601f3c9eb5071cab69e10771d77749bb525fcd5)
+++ uspace/srv/console/Makefile	(revision bf1fb9f49ca7a033e969484ce601cf42dfbecd12)
@@ -47,5 +47,5 @@
 	console.c \
 	screenbuffer.c \
-	../kbd/generic/key_buffer.c \
+	../kbd/generic/keybuffer.c \
 	gcons.c
 
Index: uspace/srv/console/console.c
===================================================================
--- uspace/srv/console/console.c	(revision 1601f3c9eb5071cab69e10771d77749bb525fcd5)
+++ uspace/srv/console/console.c	(revision bf1fb9f49ca7a033e969484ce601cf42dfbecd12)
@@ -37,14 +37,13 @@
 #include <ipc/ipc.h>
 #include <kbd.h>
-#include <kbd/keycode.h>
+#include <io/keycode.h>
 #include <ipc/fb.h>
 #include <ipc/services.h>
 #include <errno.h>
-#include <key_buffer.h>
+#include <keybuffer.h>
 #include <ipc/console.h>
 #include <unistd.h>
 #include <async.h>
 #include <libadt/fifo.h>
-#include <screenbuffer.h>
 #include <sys/mman.h>
 #include <stdio.h>
@@ -52,19 +51,13 @@
 #include <sysinfo.h>
 #include <event.h>
+#include <devmap.h>
 
 #include "console.h"
 #include "gcons.h"
+#include "screenbuffer.h"
 
 #define NAME  "console"
 
-#define MAX_KEYREQUESTS_BUFFERED  32
-
-/** Size of cwrite_buf. */
-#define CWRITE_BUF_SIZE  256
-
-/** Index of currently used virtual console.
- */
-int active_console = 0;
-int prev_console = 0;
+#define MAX_DEVICE_NAME  32
 
 /** Phone to the keyboard driver. */
@@ -74,25 +67,23 @@
 struct {
 	int phone;      /**< Framebuffer phone */
+	ipcarg_t cols;  /**< Framebuffer columns */
 	ipcarg_t rows;  /**< Framebuffer rows */
-	ipcarg_t cols;  /**< Framebuffer columns */
 } fb_info;
 
 typedef struct {
-	keybuffer_t keybuffer;        /**< Buffer for incoming keys. */
-	
-	/** Buffer for unsatisfied request for keys. */
-	FIFO_CREATE_STATIC(keyrequests, ipc_callid_t,
-	    MAX_KEYREQUESTS_BUFFERED);
-	
-	int keyrequest_counter;       /**< Number of requests in buffer. */
-	int client_phone;             /**< Phone to connected client. */
-	int used;                     /**< 1 if this virtual console is
-	                                   connected to some client. */
-	screenbuffer_t screenbuffer;  /**< Screenbuffer for saving screen
-	                                   contents and related settings. */
-} connection_t;
+	size_t index;             /**< Console index */
+	size_t refcount;          /**< Connection reference count */
+	dev_handle_t dev_handle;  /**< Device handle */
+	keybuffer_t keybuffer;    /**< Buffer for incoming keys. */
+	screenbuffer_t scr;       /**< Screenbuffer for saving screen
+	                               contents and related settings. */
+} console_t;
 
 /** Array of data for virtual consoles */
-static connection_t connections[CONSOLE_COUNT];
+static console_t consoles[CONSOLE_COUNT];
+
+static console_t *active_console = &consoles[0];
+static console_t *prev_console = &consoles[0];
+static console_t *kernel_console = &consoles[KERNEL_CONSOLE];
 
 /** Pointer to memory shared with framebufer used for
@@ -102,47 +93,87 @@
 /** Information on row-span yet unsent to FB driver. */
 struct {
-	int row;  /**< Row where the span lies. */
-	int col;  /**< Leftmost column of the span. */
-	int cnt;  /**< Width of the span. */
+	size_t col;  /**< Leftmost column of the span. */
+	size_t row;  /**< Row where the span lies. */
+	size_t cnt;  /**< Width of the span. */
 } fb_pending;
 
-/** Buffer for receiving data via the CONSOLE_WRITE call from the client. */
-static char cwrite_buf[CWRITE_BUF_SIZE];
-
-/** Find unused virtual console.
- *
- */
-static int find_free_connection(void) 
-{
-	int i;
-	
-	for (i = 0; i < CONSOLE_COUNT; i++) {
-		if (!connections[i].used)
-			return i;
-	}
-	
-	return -1;
-}
-
-static void clrscr(void)
+/** Pending input structure. */
+typedef struct {
+	link_t link;
+	console_t *cons;      /**< Console waiting for input */
+	ipc_callid_t rid;     /**< Call ID waiting for input */
+	ipc_callid_t callid;  /**< Call ID waiting for IPC_DATA_READ */
+	
+	size_t pos;           /**< Position of the last stored data */
+	size_t size;          /**< Size of ther buffer */
+	char *data;           /**< Already stored data */
+} pending_input_t;
+
+LIST_INITIALIZE(pending_input);
+
+/** Process pending input requests */
+static void process_pending_input(void)
+{
+	async_serialize_start();
+	
+	link_t *cur;
+	
+loop:
+	for (cur = pending_input.next; cur != &pending_input; cur = cur->next) {
+		pending_input_t *pr = list_get_instance(cur, pending_input_t, link);
+		
+		console_event_t ev;
+		if (keybuffer_pop(&pr->cons->keybuffer, &ev)) {
+			
+			if (pr->data != NULL) {
+				if (ev.type == KEY_PRESS) {
+					pr->data[pr->pos] = ev.c;
+					pr->pos++;
+				}
+			} else {
+				ipc_answer_4(pr->rid, EOK, ev.type, ev.key, ev.mods, ev.c);
+				
+				list_remove(cur);
+				free(pr);
+				
+				goto loop;
+			}
+		}
+		
+		if ((pr->data != NULL) && (pr->pos == pr->size)) {
+			(void) ipc_data_read_finalize(pr->callid, pr->data, pr->size);
+			ipc_answer_1(pr->rid, EOK, pr->size);
+			
+			free(pr->data);
+			list_remove(cur);
+			free(pr);
+			
+			goto loop;
+		}
+	}
+	
+	async_serialize_end();
+}
+
+static void curs_visibility(bool visible)
+{
+	async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible); 
+}
+
+static void curs_hide_sync(void)
+{
+	ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false); 
+}
+
+static void curs_goto(size_t x, size_t y)
+{
+	async_msg_2(fb_info.phone, FB_CURSOR_GOTO, x, y);
+}
+
+static void screen_clear(void)
 {
 	async_msg_0(fb_info.phone, FB_CLEAR);
 }
 
-static void curs_visibility(bool visible)
-{
-	async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible); 
-}
-
-static void curs_hide_sync(void)
-{
-	ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false); 
-}
-
-static void curs_goto(int row, int col)
-{
-	async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col); 
-}
-
 static void screen_yield(void)
 {
@@ -167,5 +198,5 @@
 static void set_style(int style)
 {
-	async_msg_1(fb_info.phone, FB_SET_STYLE, style); 
+	async_msg_1(fb_info.phone, FB_SET_STYLE, style);
 }
 
@@ -197,21 +228,19 @@
 
 /** Send an area of screenbuffer to the FB driver. */
-static void fb_update_area(connection_t *conn, int x, int y, int w, int h)
-{
-	int i;
-	int j;
-	attrs_t *attrs;
-	keyfield_t *field;
-	
+static void fb_update_area(console_t *cons, ipcarg_t x0, ipcarg_t y0, ipcarg_t width, ipcarg_t height)
+{
 	if (interbuffer) {
-		for (j = 0; j < h; j++) {
-			for (i = 0; i < w; i++) {
-				interbuffer[i + j * w] =
-				    *get_field_at(&conn->screenbuffer, x + i, y + j);
+		ipcarg_t x;
+		ipcarg_t y;
+		
+		for (y = 0; y < height; y++) {
+			for (x = 0; x < width; x++) {
+				interbuffer[y * width + x] =
+				    *get_field_at(&cons->scr, x0 + x, y0 + y);
 			}
 		}
 		
 		async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
-		    x, y, w, h);
+		    x0, y0, width, height);
 	}
 }
@@ -220,9 +249,6 @@
 static void fb_pending_flush(void)
 {
-	screenbuffer_t *scr
-	    = &(connections[active_console].screenbuffer);
-	
 	if (fb_pending.cnt > 0) {
-		fb_update_area(&connections[active_console], fb_pending.col,
+		fb_update_area(active_console, fb_pending.col,
 		    fb_pending.row, fb_pending.cnt, 1);
 		fb_pending.cnt = 0;
@@ -236,9 +262,9 @@
  *
  */
-static void cell_mark_changed(int row, int col)
+static void cell_mark_changed(size_t col, size_t row)
 {
 	if (fb_pending.cnt != 0) {
-		if ((row != fb_pending.row)
-		    || (col != fb_pending.col + fb_pending.cnt)) {
+		if ((col != fb_pending.col + fb_pending.cnt)
+		    || (row != fb_pending.row)) {
 			fb_pending_flush();
 		}
@@ -246,6 +272,6 @@
 	
 	if (fb_pending.cnt == 0) {
+		fb_pending.col = col;
 		fb_pending.row = row;
-		fb_pending.col = col;
 	}
 	
@@ -254,80 +280,65 @@
 
 /** Print a character to the active VC with buffering. */
-static void fb_putchar(wchar_t c, int row, int col)
-{
-	async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);
+static void fb_putchar(wchar_t c, ipcarg_t col, ipcarg_t row)
+{
+	async_msg_3(fb_info.phone, FB_PUTCHAR, c, col, row);
 }
 
 /** Process a character from the client (TTY emulation). */
-static void write_char(int console, wchar_t ch)
-{
-	bool flush_cursor = false;
-	screenbuffer_t *scr = &(connections[console].screenbuffer);
-	
+static void write_char(console_t *cons, wchar_t ch)
+{
 	switch (ch) {
 	case '\n':
 		fb_pending_flush();
-		flush_cursor = true;
-		scr->position_y++;
-		scr->position_x = 0;
+		cons->scr.position_y++;
+		cons->scr.position_x = 0;
 		break;
 	case '\r':
 		break;
 	case '\t':
-		scr->position_x += 8;
-		scr->position_x -= scr->position_x % 8;
+		cons->scr.position_x += 8;
+		cons->scr.position_x -= cons->scr.position_x % 8;
 		break;
 	case '\b':
-		if (scr->position_x == 0) 
-			break;
-		scr->position_x--;
-		if (console == active_console)
-			cell_mark_changed(scr->position_y, scr->position_x);
-		screenbuffer_putchar(scr, ' ');
+		if (cons->scr.position_x == 0)
+			break;
+		cons->scr.position_x--;
+		if (cons == active_console)
+			cell_mark_changed(cons->scr.position_x, cons->scr.position_y);
+		screenbuffer_putchar(&cons->scr, ' ');
 		break;
 	default:
-		if (console == active_console)
-			cell_mark_changed(scr->position_y, scr->position_x);
-		
-		screenbuffer_putchar(scr, ch);
-		scr->position_x++;
-	}
-	
-	if (scr->position_x >= scr->size_x) {
-		flush_cursor = true;
-		scr->position_y++;
-	}
-	
-	if (scr->position_y >= scr->size_y) {
+		if (cons == active_console)
+			cell_mark_changed(cons->scr.position_x, cons->scr.position_y);
+		
+		screenbuffer_putchar(&cons->scr, ch);
+		cons->scr.position_x++;
+	}
+	
+	if (cons->scr.position_x >= cons->scr.size_x)
+		cons->scr.position_y++;
+	
+	if (cons->scr.position_y >= cons->scr.size_y) {
 		fb_pending_flush();
-		scr->position_y = scr->size_y - 1;
-		screenbuffer_clear_line(scr, scr->top_line);
-		scr->top_line = (scr->top_line + 1) % scr->size_y;
-		if (console == active_console)
+		cons->scr.position_y = cons->scr.size_y - 1;
+		screenbuffer_clear_line(&cons->scr, cons->scr.top_line);
+		cons->scr.top_line = (cons->scr.top_line + 1) % cons->scr.size_y;
+		
+		if (cons == active_console)
 			async_msg_1(fb_info.phone, FB_SCROLL, 1);
 	}
 	
-	scr->position_x = scr->position_x % scr->size_x;
-	
-	if (console == active_console && flush_cursor)
-		curs_goto(scr->position_y, scr->position_x);
+	cons->scr.position_x = cons->scr.position_x % cons->scr.size_x;
 }
 
 /** Switch to new console */
-static void change_console(int newcons)
-{
-	connection_t *conn;
-	int i;
-	int j;
-	int rc;
-	keyfield_t *field;
-	attrs_t *attrs;
-	
-	if (newcons == active_console)
+static void change_console(console_t *cons)
+{
+	if (cons == active_console)
 		return;
 	
 	fb_pending_flush();
 	
-	if (newcons == KERNEL_CONSOLE) {
+	if (cons == kernel_console) {
 		async_serialize_start();
 		curs_hide_sync();
@@ -337,16 +348,19 @@
 		async_serialize_end();
 		
-		
 		if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
 			prev_console = active_console;
-			active_console = KERNEL_CONSOLE;
+			active_console = kernel_console;
 		} else
-			newcons = active_console;
-	}
-	
-	if (newcons != KERNEL_CONSOLE) {
+			cons = active_console;
+	}
+	
+	if (cons != kernel_console) {
+		size_t x;
+		size_t y;
+		int rc = 0;
+		
 		async_serialize_start();
 		
-		if (active_console == KERNEL_CONSOLE) {
+		if (active_console == kernel_console) {
 			screen_reclaim();
 			kbd_reclaim();
@@ -354,48 +368,45 @@
 		}
 		
-		active_console = newcons;
-		gcons_change_console(newcons);
-		conn = &connections[active_console];
-		
-		set_attrs(&conn->screenbuffer.attrs);
+		active_console = cons;
+		gcons_change_console(cons->index);
+		
+		set_attrs(&cons->scr.attrs);
 		curs_visibility(false);
 		if (interbuffer) {
-			for (j = 0; j < conn->screenbuffer.size_y; j++) {
-				for (i = 0; i < conn->screenbuffer.size_x; i++) {
-					unsigned int size_x;
-					
-					size_x = conn->screenbuffer.size_x; 
-					interbuffer[j * size_x + i] =
-					    *get_field_at(&conn->screenbuffer, i, j);
+			for (y = 0; y < cons->scr.size_y; y++) {
+				for (x = 0; x < cons->scr.size_x; x++) {
+					interbuffer[y * cons->scr.size_x + x] =
+					    *get_field_at(&cons->scr, x, y);
 				}
 			}
+			
 			/* This call can preempt, but we are already at the end */
 			rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
-			    0, 0, conn->screenbuffer.size_x,
-			    conn->screenbuffer.size_y);
+			    0, 0, cons->scr.size_x,
+			    cons->scr.size_y);
 		}
 		
 		if ((!interbuffer) || (rc != 0)) {
-			set_attrs(&conn->screenbuffer.attrs);
-			clrscr();
-			attrs = &conn->screenbuffer.attrs;
-			
-			for (j = 0; j < conn->screenbuffer.size_y; j++)
-				for (i = 0; i < conn->screenbuffer.size_x; i++) {
-					field = get_field_at(&conn->screenbuffer, i, j);
-					if (!attrs_same(*attrs, field->attrs))
+			set_attrs(&cons->scr.attrs);
+			screen_clear();
+			
+			for (y = 0; y < cons->scr.size_y; y++)
+				for (x = 0; x < cons->scr.size_x; x++) {
+					keyfield_t *field = get_field_at(&cons->scr, x, y);
+					
+					if (!attrs_same(cons->scr.attrs, field->attrs))
 						set_attrs(&field->attrs);
-					attrs = &field->attrs;
+					
+					cons->scr.attrs = field->attrs;
 					if ((field->character == ' ') &&
-					    (attrs_same(field->attrs, conn->screenbuffer.attrs)))
+					    (attrs_same(field->attrs, cons->scr.attrs)))
 						continue;
 					
-					fb_putchar(field->character, j, i);
+					fb_putchar(field->character, x, y);
 				}
 		}
 		
-		curs_goto(conn->screenbuffer.position_y,
-		    conn->screenbuffer.position_x);
-		curs_visibility(conn->screenbuffer.is_cursor_visible);
+		curs_goto(cons->scr.position_x, cons->scr.position_y);
+		curs_visibility(cons->scr.is_cursor_visible);
 		
 		async_serialize_end();
@@ -406,29 +417,17 @@
 static void keyboard_events(ipc_callid_t iid, ipc_call_t *icall)
 {
-	ipc_callid_t callid;
-	ipc_call_t call;
-	int retval;
-	kbd_event_t ev;
-	connection_t *conn;
-	int newcon;
-	
-	/* Ignore parameters, the connection is alread opened */
+	/* Ignore parameters, the connection is already opened */
 	while (true) {
-		callid = async_get_call(&call);
+		
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		int retval;
+		console_event_t ev;
+		
 		switch (IPC_GET_METHOD(call)) {
 		case IPC_M_PHONE_HUNGUP:
 			/* TODO: Handle hangup */
 			return;
-		case KBD_MS_LEFT:
-			newcon = gcons_mouse_btn(IPC_GET_ARG1(call));
-			if (newcon != -1)
-				change_console(newcon);
-			retval = 0;
-			break;
-		case KBD_MS_MOVE:
-			gcons_mouse_move(IPC_GET_ARG1(call),
-			    IPC_GET_ARG2(call));
-			retval = 0;
-			break;
 		case KBD_EVENT:
 			/* Got event from keyboard driver. */
@@ -439,27 +438,14 @@
 			ev.c = IPC_GET_ARG4(call);
 			
-			/* Switch to another virtual console */
-			conn = &connections[active_console];
-			
 			if ((ev.key >= KC_F1) && (ev.key < KC_F1 +
 			    CONSOLE_COUNT) && ((ev.mods & KM_CTRL) == 0)) {
-				if (ev.key == KC_F12)
-					change_console(KERNEL_CONSOLE);
+				if (ev.key == KC_F1 + KERNEL_CONSOLE)
+					change_console(kernel_console);
 				else
-					change_console(ev.key - KC_F1);
+					change_console(&consoles[ev.key - KC_F1]);
 				break;
 			}
 			
-			/* If client is awaiting key, send it */
-			if (conn->keyrequest_counter > 0) {
-				conn->keyrequest_counter--;
-				ipc_answer_4(fifo_pop(conn->keyrequests), EOK,
-				    ev.type, ev.key, ev.mods, ev.c);
-				break;
-			}
-			
-			keybuffer_push(&conn->keybuffer, &ev);
-			retval = 0;
-			
+			keybuffer_push(&active_console->keybuffer, &ev);
 			break;
 		default:
@@ -470,12 +456,8 @@
 }
 
-/** Handle CONSOLE_WRITE call. */
-static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request)
+static void cons_write(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
 {
 	ipc_callid_t callid;
 	size_t size;
-	wchar_t ch;
-	size_t off;
-	
 	if (!ipc_data_write_receive(&callid, &size)) {
 		ipc_answer_0(callid, EINVAL);
@@ -484,21 +466,108 @@
 	}
 	
-	if (size > CWRITE_BUF_SIZE)
-		size = CWRITE_BUF_SIZE;
-	
-	(void) ipc_data_write_finalize(callid, cwrite_buf, size);
+	char *buf = (char *) malloc(size);
+	if (buf == NULL) {
+		ipc_answer_0(callid, ENOMEM);
+		ipc_answer_0(rid, ENOMEM);
+		return;
+	}
+	
+	(void) ipc_data_write_finalize(callid, buf, size);
 	
 	async_serialize_start();
 	
-	off = 0;
+	size_t off = 0;
 	while (off < size) {
-		ch = str_decode(cwrite_buf, &off, size);
-		write_char(consnum, ch);
-	}
+		wchar_t ch = str_decode(buf, &off, size);
+		write_char(cons, ch);
+	}
+	
+	if (cons == active_console)
+		curs_goto(cons->scr.position_x, cons->scr.position_y);
 	
 	async_serialize_end();
 	
-	gcons_notify_char(consnum);
+	gcons_notify_char(cons->index);
 	ipc_answer_1(rid, EOK, size);
+	
+	free(buf);
+}
+
+static void cons_read(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
+{
+	ipc_callid_t callid;
+	size_t size;
+	if (!ipc_data_read_receive(&callid, &size)) {
+		ipc_answer_0(callid, EINVAL);
+		ipc_answer_0(rid, EINVAL);
+		return;
+	}
+	
+	char *buf = (char *) malloc(size);
+	if (buf == NULL) {
+		ipc_answer_0(callid, ENOMEM);
+		ipc_answer_0(rid, ENOMEM);
+		return;
+	}
+	
+	async_serialize_start();
+	
+	size_t pos = 0;
+	console_event_t ev;
+	while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) {
+		if (ev.type == KEY_PRESS) {
+			buf[pos] = ev.c;
+			pos++;
+		}
+	}
+	
+	if (pos == size) {
+		(void) ipc_data_read_finalize(callid, buf, size);
+		ipc_answer_1(rid, EOK, size);
+		free(buf);
+	} else {
+		pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
+		if (!pr) {
+			ipc_answer_0(rid, ENOMEM);
+			free(buf);
+			async_serialize_end();
+			return;
+		}
+		
+		pr->cons = cons;
+		pr->rid = rid;
+		pr->callid = callid;
+		pr->pos = pos;
+		pr->size = size;
+		pr->data = buf;
+		list_append(&pr->link, &pending_input);
+	}
+	
+	async_serialize_end();
+}
+
+static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request)
+{
+	async_serialize_start();
+	
+	console_event_t ev;
+	if (keybuffer_pop(&cons->keybuffer, &ev)) {
+		ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c);
+	} else {
+		pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t));
+		if (!pr) {
+			ipc_answer_0(rid, ENOMEM);
+			async_serialize_end();
+			return;
+		}
+		
+		pr->cons = cons;
+		pr->rid = rid;
+		pr->callid = 0;
+		pr->data = NULL;
+		list_append(&pr->link, &pending_input);
+	}
+	
+	async_serialize_end();
 }
 
@@ -506,24 +575,33 @@
 static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
 {
+	console_t *cons = NULL;
+	
+	size_t i;
+	for (i = 0; i < CONSOLE_COUNT; i++) {
+		if (i == KERNEL_CONSOLE)
+			continue;
+		
+		if (consoles[i].dev_handle == (dev_handle_t) IPC_GET_ARG1(*icall)) {
+			cons = &consoles[i];
+			break;
+		}
+	}
+	
+	if (cons == NULL) {
+		ipc_answer_0(iid, ENOENT);
+		return;
+	}
+	
 	ipc_callid_t callid;
 	ipc_call_t call;
-	int consnum;
-	ipcarg_t arg1, arg2, arg3, arg4;
-	connection_t *conn;
-	screenbuffer_t *scr;
-	
-	if ((consnum = find_free_connection()) == -1) {
-		ipc_answer_0(iid, ELIMIT);
-		return;
-	}
-	conn = &connections[consnum];
-	conn->used = 1;
+	ipcarg_t arg1;
+	ipcarg_t arg2;
+	ipcarg_t arg3;
 	
 	async_serialize_start();
-	gcons_notify_connect(consnum);
-	conn->client_phone = IPC_GET_ARG5(*icall);
-	screenbuffer_clear(&conn->screenbuffer);
-	if (consnum == active_console)
-		clrscr();
+	if (cons->refcount == 0)
+		gcons_notify_connect(cons->index);
+	
+	cons->refcount++;
 	
 	/* Accept the connection */
@@ -538,62 +616,53 @@
 		arg2 = 0;
 		arg3 = 0;
-		arg4 = 0;
 		
 		switch (IPC_GET_METHOD(call)) {
 		case IPC_M_PHONE_HUNGUP:
-			gcons_notify_disconnect(consnum);
-			
-			/* Answer all pending requests */
-			while (conn->keyrequest_counter > 0) {
-				conn->keyrequest_counter--;
-				ipc_answer_0(fifo_pop(conn->keyrequests),
-				    ENOENT);
-				break;
-			}
-			conn->used = 0;
+			cons->refcount--;
+			if (cons->refcount == 0)
+				gcons_notify_disconnect(cons->index);
 			return;
-		case CONSOLE_PUTCHAR:
-			write_char(consnum, IPC_GET_ARG1(call));
-			gcons_notify_char(consnum);
-			break;
-		case CONSOLE_WRITE:
+		case VFS_READ:
 			async_serialize_end();
-			cons_write(consnum, callid, &call);
+			cons_read(cons, callid, &call);
 			async_serialize_start();
 			continue;
+		case VFS_WRITE:
+			async_serialize_end();
+			cons_write(cons, callid, &call);
+			async_serialize_start();
+			continue;
+		case VFS_SYNC:
+			fb_pending_flush();
+			if (cons == active_console) {
+				async_req_0_0(fb_info.phone, FB_FLUSH);
+				
+				curs_goto(cons->scr.position_x, cons->scr.position_y);
+			}
+			break;
 		case CONSOLE_CLEAR:
 			/* Send message to fb */
-			if (consnum == active_console) {
-				async_msg_0(fb_info.phone, FB_CLEAR); 
-			}
-			
-			screenbuffer_clear(&conn->screenbuffer);
+			if (cons == active_console)
+				async_msg_0(fb_info.phone, FB_CLEAR);
+			
+			screenbuffer_clear(&cons->scr);
 			
 			break;
 		case CONSOLE_GOTO:
-			screenbuffer_goto(&conn->screenbuffer,
-			    IPC_GET_ARG2(call), IPC_GET_ARG1(call));
-			if (consnum == active_console)
+			screenbuffer_goto(&cons->scr,
+			    IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			if (cons == active_console)
 				curs_goto(IPC_GET_ARG1(call),
 				    IPC_GET_ARG2(call));
 			break;
-		case CONSOLE_GETSIZE:
-			arg1 = fb_info.rows;
-			arg2 = fb_info.cols;
-			break;
-		case CONSOLE_FLUSH:
-			fb_pending_flush();
-			if (consnum == active_console) {
-				async_req_0_0(fb_info.phone, FB_FLUSH);
-				
-				scr = &(connections[consnum].screenbuffer);
-				curs_goto(scr->position_y, scr->position_x);
-			}
+		case CONSOLE_GET_SIZE:
+			arg1 = fb_info.cols;
+			arg2 = fb_info.rows;
 			break;
 		case CONSOLE_SET_STYLE:
 			fb_pending_flush();
 			arg1 = IPC_GET_ARG1(call);
-			screenbuffer_set_style(&conn->screenbuffer, arg1);
-			if (consnum == active_console)
+			screenbuffer_set_style(&cons->scr, arg1);
+			if (cons == active_console)
 				set_style(arg1);
 			break;
@@ -603,7 +672,6 @@
 			arg2 = IPC_GET_ARG2(call);
 			arg3 = IPC_GET_ARG3(call);
-			screenbuffer_set_color(&conn->screenbuffer, arg1,
-			    arg2, arg3);
-			if (consnum == active_console)
+			screenbuffer_set_color(&cons->scr, arg1, arg2, arg3);
+			if (cons == active_console)
 				set_color(arg1, arg2, arg3);
 			break;
@@ -612,7 +680,6 @@
 			arg1 = IPC_GET_ARG1(call);
 			arg2 = IPC_GET_ARG2(call);
-			screenbuffer_set_rgb_color(&conn->screenbuffer, arg1,
-			    arg2);
-			if (consnum == active_console)
+			screenbuffer_set_rgb_color(&cons->scr, arg1, arg2);
+			if (cons == active_console)
 				set_rgb_color(arg1, arg2);
 			break;
@@ -620,36 +687,18 @@
 			fb_pending_flush();
 			arg1 = IPC_GET_ARG1(call);
-			conn->screenbuffer.is_cursor_visible = arg1;
-			if (consnum == active_console)
+			cons->scr.is_cursor_visible = arg1;
+			if (cons == active_console)
 				curs_visibility(arg1);
 			break;
-		case CONSOLE_GETKEY:
-			if (keybuffer_empty(&conn->keybuffer)) {
-				/* buffer is empty -> store request */
-				if (conn->keyrequest_counter <
-					MAX_KEYREQUESTS_BUFFERED) {
-					fifo_push(conn->keyrequests, callid);
-					conn->keyrequest_counter++;
-				} else {
-					/*
-					 * No key available and too many
-					 * requests => fail.
-					*/
-					ipc_answer_0(callid, ELIMIT);
-				}
-				continue;
-			}
-			kbd_event_t ev;
-			keybuffer_pop(&conn->keybuffer, &ev);
-			arg1 = ev.type;
-			arg2 = ev.key;
-			arg3 = ev.mods;
-			arg4 = ev.c;
-			break;
+		case CONSOLE_GET_EVENT:
+			async_serialize_end();
+			cons_get_event(cons, callid, &call);
+			async_serialize_start();
+			continue;
 		case CONSOLE_KCON_ENABLE:
-			change_console(KERNEL_CONSOLE);
-			break;
-		}
-		ipc_answer_4(callid, EOK, arg1, arg2, arg3, arg4);
+			change_console(kernel_console);
+			break;
+		}
+		ipc_answer_3(callid, EOK, arg1, arg2, arg3);
 	}
 }
@@ -660,26 +709,21 @@
 }
 
-int main(int argc, char *argv[])
-{
-	printf(NAME ": HelenOS Console service\n");
-	
-	ipcarg_t phonehash;
-	size_t ib_size;
-	int i;
-	
-	async_set_client_connection(client_connection);
-	
+static bool console_init(void)
+{
 	/* Connect to keyboard driver */
+	
 	kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0);
 	if (kbd_phone < 0) {
 		printf(NAME ": Failed to connect to keyboard service\n");
-		return -1;
-	}
-	
+		return false;
+	}
+	
+	ipcarg_t phonehash;
 	if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
 		printf(NAME ": Failed to create callback from keyboard service\n");
-		return -1;
-	}
-	
+		return false;
+	}
+	
+	async_set_pending(process_pending_input);
 	async_new_connection(phonehash, 0, NULL, keyboard_events);
 	
@@ -691,45 +735,25 @@
 	}
 	
-	/* Disable kernel output to the console */
-	__SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
+	/* Register driver */
+	int rc = devmap_driver_register(NAME, client_connection);
+	if (rc < 0) {
+		printf(NAME ": Unable to register driver (%d)\n", rc);
+		return false;
+	}
 	
 	/* Initialize gcons */
 	gcons_init(fb_info.phone);
-	/* Synchronize, the gcons can have something in queue */
+	
+	/* Synchronize, the gcons could put something in queue */
 	async_req_0_0(fb_info.phone, FB_FLUSH);
-	
-	async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.rows,
-	    &fb_info.cols); 
-	set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
-	clrscr();
-	
-	/* Init virtual consoles */
-	for (i = 0; i < CONSOLE_COUNT; i++) {
-		connections[i].used = 0;
-		keybuffer_init(&connections[i].keybuffer);
-		
-		connections[i].keyrequests.head = 0;
-		connections[i].keyrequests.tail = 0;
-		connections[i].keyrequests.items = MAX_KEYREQUESTS_BUFFERED;
-		connections[i].keyrequest_counter = 0;
-		
-		if (screenbuffer_init(&connections[i].screenbuffer,
-		    fb_info.cols, fb_info.rows) == NULL) {
-			/* FIXME: handle error */
-			return -1;
-		}
-	}
-	connections[KERNEL_CONSOLE].used = 1;
+	async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows);
 	
 	/* Set up shared memory buffer. */
-	ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows;
+	size_t ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows;
 	interbuffer = as_get_mappable_page(ib_size);
 	
-	fb_pending.cnt = 0;
-	
 	if (as_area_create(interbuffer, ib_size, AS_AREA_READ |
-	    AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer) {
+	    AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer)
 		interbuffer = NULL;
-	}
 	
 	if (interbuffer) {
@@ -741,11 +765,36 @@
 	}
 	
+	fb_pending.cnt = 0;
+	
+	/* Inititalize consoles */
+	size_t i;
+	for (i = 0; i < CONSOLE_COUNT; i++) {
+		if (i != KERNEL_CONSOLE) {
+			if (screenbuffer_init(&consoles[i].scr,
+			    fb_info.cols, fb_info.rows) == NULL) {
+				printf(NAME ": Unable to allocate screen buffer %u\n", i);
+				return false;
+			}
+			screenbuffer_clear(&consoles[i].scr);
+			keybuffer_init(&consoles[i].keybuffer);
+			consoles[i].index = i;
+			consoles[i].refcount = 0;
+			
+			char vc[MAX_DEVICE_NAME];
+			snprintf(vc, MAX_DEVICE_NAME, "vc%u", i);
+			
+			if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) {
+				devmap_hangup_phone(DEVMAP_DRIVER);
+				printf(NAME ": Unable to register device %s\n", vc);
+				return false;
+			}
+		}
+	}
+	
+	/* Initialize the screen */
+	set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
+	screen_clear();
 	curs_goto(0, 0);
-	curs_visibility(
-	    connections[active_console].screenbuffer.is_cursor_visible);
-	
-	/* Register at NS */
-	if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, 0, &phonehash) != 0)
-		return -1;
+	curs_visibility(active_console->scr.is_cursor_visible);
 	
 	/* Receive kernel notifications */
@@ -755,6 +804,20 @@
 	async_set_interrupt_received(interrupt_received);
 	
-	// FIXME: avoid connectiong to itself, keep using klog
-	// printf(NAME ": Accepting connections\n");
+	return true;
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": HelenOS Console service\n");
+	
+	/* Disable kernel output to the console */
+	__SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
+	
+	if (!console_init()) {
+		__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
+		return -1;
+	}
+	
+	printf(NAME ": Accepting connections\n");
 	async_manager();
 	
Index: uspace/srv/console/gcons.c
===================================================================
--- uspace/srv/console/gcons.c	(revision 1601f3c9eb5071cab69e10771d77749bb525fcd5)
+++ uspace/srv/console/gcons.c	(revision bf1fb9f49ca7a033e969484ce601cf42dfbecd12)
@@ -40,4 +40,5 @@
 #include <string.h>
 #include <align.h>
+#include <bool.h>
 
 #include "console.h"
@@ -55,6 +56,7 @@
 #define MAIN_COLOR  0xffffff
 
-static int use_gcons = 0;
-static ipcarg_t xres,yres;
+static bool use_gcons = false;
+static ipcarg_t xres;
+static ipcarg_t yres;
 
 enum butstate {
@@ -78,5 +80,12 @@
 static int animation = -1;
 
-static int active_console = 0;
+static size_t active_console = 0;
+
+size_t mouse_x;
+size_t mouse_y;
+
+bool btn_pressed;
+size_t btn_x;
+size_t btn_y;
 
 static void vp_switch(int vp)
@@ -86,6 +95,5 @@
 
 /** Create view port */
-static int vp_create(unsigned int x, unsigned int y, unsigned int width,
-    unsigned int height)
+static int vp_create(size_t x, size_t y, size_t width, size_t height)
 {
 	return async_req_2_0(fbphone, FB_VIEWPORT_CREATE, (x << 16) | y,
@@ -98,5 +106,5 @@
 }
 
-static void set_rgb_color(int fgcolor, int bgcolor)
+static void set_rgb_color(uint32_t fgcolor, uint32_t bgcolor)
 {
 	async_msg_2(fbphone, FB_SET_RGB_COLOR, fgcolor, bgcolor);
@@ -104,40 +112,44 @@
 
 /** Transparent putchar */
-static void tran_putch(char c, int row, int col)
-{
-	async_msg_3(fbphone, FB_PUTCHAR, c, row, col);
+static void tran_putch(wchar_t ch, size_t col, size_t row)
+{
+	async_msg_3(fbphone, FB_PUTCHAR, ch, col, row);
 }
 
 /** Redraw the button showing state of a given console */
-static void redraw_state(int consnum)
-{
-	char data[5];
-	int i;
-	enum butstate state = console_state[consnum];
-	
-	vp_switch(cstatus_vp[consnum]);
+static void redraw_state(size_t index)
+{
+	vp_switch(cstatus_vp[index]);
+	
+	enum butstate state = console_state[index];
+	
 	if (ic_pixmaps[state] != -1)
-		async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[consnum],
+		async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[index],
 		    ic_pixmaps[state]);
 	
-	if (state != CONS_DISCONNECTED && state != CONS_KERNEL &&
-	    state != CONS_DISCONNECTED_SEL) {
-		snprintf(data, 5, "%d", consnum + 1);
-		for (i = 0; data[i]; i++)
-			tran_putch(data[i], 1, 2 + i);
+	if ((state != CONS_DISCONNECTED) && (state != CONS_KERNEL)
+	    && (state != CONS_DISCONNECTED_SEL)) {
+		
+		char data[5];
+		snprintf(data, 5, "%u", index + 1);
+		
+		size_t i;
+		for (i = 0; data[i] != 0; i++)
+			tran_putch(data[i], 2 + i, 1);
 	}
 }
 
 /** Notification run on changing console (except kernel console) */
-void gcons_change_console(int consnum)
-{
-	int i;
-	
+void gcons_change_console(size_t index)
+{
 	if (!use_gcons)
 		return;
 	
 	if (active_console == KERNEL_CONSOLE) {
+		size_t i;
+		
 		for (i = 0; i < CONSOLE_COUNT; i++)
 			redraw_state(i);
+		
 		if (animation != -1)
 			async_msg_1(fbphone, FB_ANIM_START, animation);
@@ -147,71 +159,72 @@
 		else
 			console_state[active_console] = CONS_IDLE;
+		
 		redraw_state(active_console);
 	}
-	active_console = consnum;
-	
-	if (console_state[consnum] == CONS_DISCONNECTED) {
-		console_state[consnum] = CONS_DISCONNECTED_SEL;
-		redraw_state(consnum);
-	} else
-		console_state[consnum] = CONS_SELECTED;
-	redraw_state(consnum);
-	
+	
+	active_console = index;
+	
+	if ((console_state[index] == CONS_DISCONNECTED)
+	    || (console_state[index] == CONS_DISCONNECTED_SEL))
+		console_state[index] = CONS_DISCONNECTED_SEL;
+	else
+		console_state[index] = CONS_SELECTED;
+	
+	redraw_state(index);
 	vp_switch(console_vp);
 }
 
 /** Notification function that gets called on new output to virtual console */
-void gcons_notify_char(int consnum)
+void gcons_notify_char(size_t index)
 {
 	if (!use_gcons)
 		return;
 	
-	if ((consnum == active_console) ||
-	    (console_state[consnum] == CONS_HAS_DATA))
-		return;
-	
-	console_state[consnum] = CONS_HAS_DATA;
+	if ((index == active_console)
+	    || (console_state[index] == CONS_HAS_DATA))
+		return;
+	
+	console_state[index] = CONS_HAS_DATA;
 	
 	if (active_console == KERNEL_CONSOLE)
 		return;
 	
-	redraw_state(consnum);
-	
+	redraw_state(index);
 	vp_switch(console_vp);
 }
 
 /** Notification function called on service disconnect from console */
-void gcons_notify_disconnect(int consnum)
+void gcons_notify_disconnect(size_t index)
 {
 	if (!use_gcons)
 		return;
 	
-	if (active_console == consnum)
-		console_state[consnum] = CONS_DISCONNECTED_SEL;
+	if (index == active_console)
+		console_state[index] = CONS_DISCONNECTED_SEL;
 	else
-		console_state[consnum] = CONS_DISCONNECTED;
+		console_state[index] = CONS_DISCONNECTED;
 	
 	if (active_console == KERNEL_CONSOLE)
 		return;
 	
-	redraw_state(consnum);
+	redraw_state(index);
 	vp_switch(console_vp);
 }
 
 /** Notification function called on console connect */
-void gcons_notify_connect(int consnum)
+void gcons_notify_connect(size_t index)
 {
 	if (!use_gcons)
 		return;
 	
-	if (active_console == consnum)
-		console_state[consnum] = CONS_SELECTED;
+	if (index == active_console)
+		console_state[index] = CONS_SELECTED;
 	else
-		console_state[consnum] = CONS_IDLE;
+		console_state[index] = CONS_IDLE;
 	
 	if (active_console == KERNEL_CONSOLE)
 		return;
 	
-	redraw_state(consnum);
+	redraw_state(index);
 	vp_switch(console_vp);
 }
@@ -227,16 +240,15 @@
 }
 
-/** Return x, where left <= x <= right && |a-x|==min(|a-x|) is smallest */
-static inline int limit(int a, int left, int right)
+/** Return x, where left <= x <= right && |a-x| == min(|a-x|) is smallest */
+static inline int limit(size_t a, size_t left, size_t right)
 {
 	if (a < left)
 		a = left;
+	
 	if (a >= right)
 		a = right - 1;
+	
 	return a;
 }
-
-int mouse_x, mouse_y;
-int btn_pressed, btn_x, btn_y;
 
 /** Handle mouse move
@@ -245,5 +257,5 @@
  * @param dy Delta Y of mouse move
  */
-void gcons_mouse_move(int dx, int dy)
+void gcons_mouse_move(ssize_t dx, ssize_t dy)
 {
 	mouse_x = limit(mouse_x + dx, 0, xres);
@@ -273,7 +285,7 @@
 /** Handle mouse click
  *
- * @param state New state (1-pressed, 0-depressed)
- */
-int gcons_mouse_btn(int state)
+ * @param state New state (true - pressed, false - depressed)
+ */
+int gcons_mouse_btn(bool state)
 {
 	int conbut;
@@ -282,5 +294,5 @@
 		conbut = gcons_find_conbut(mouse_x, mouse_y);
 		if (conbut != -1) {
-			btn_pressed = 1;
+			btn_pressed = true;
 			btn_x = mouse_x;
 			btn_y = mouse_y;
@@ -292,5 +304,5 @@
 		return -1;
 	
-	btn_pressed = 0;
+	btn_pressed = false;
 	
 	conbut = gcons_find_conbut(mouse_x, mouse_y);
@@ -374,7 +386,9 @@
  * @param data PPM data
  * @param size PPM data size
+ *
  * @return Pixmap identification
- */
-static int make_pixmap(char *data, int size)
+ *
+ */
+static int make_pixmap(char *data, size_t size)
 {
 	char *shm;
@@ -465,11 +479,7 @@
 void gcons_init(int phone)
 {
-	int rc;
-	int i;
-	int status_start = STATUS_START;
-	
 	fbphone = phone;
 	
-	rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
+	int rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
 	if (rc)
 		return;
@@ -484,15 +494,19 @@
 	    ALIGN_DOWN(xres - 2 * CONSOLE_MARGIN, 8),
 	    ALIGN_DOWN(yres - (CONSOLE_TOP + CONSOLE_MARGIN), 16));
+	
 	if (console_vp < 0)
 		return;
 	
 	/* Create status buttons */
-	status_start += (xres - 800) / 2;
+	size_t status_start = STATUS_START + (xres - 800) / 2;
+	size_t i;
 	for (i = 0; i < CONSOLE_COUNT; i++) {
 		cstatus_vp[i] = vp_create(status_start + CONSOLE_MARGIN +
 		    i * (STATUS_WIDTH + STATUS_SPACE), STATUS_TOP,
 		    STATUS_WIDTH, STATUS_HEIGHT);
+		
 		if (cstatus_vp[i] < 0)
 			return;
+		
 		vp_switch(cstatus_vp[i]);
 		set_rgb_color(0x202020, 0xffffff);
@@ -502,24 +516,25 @@
 	ic_pixmaps[CONS_SELECTED] =
 	    make_pixmap(_binary_gfx_cons_selected_ppm_start,
-	    (int) &_binary_gfx_cons_selected_ppm_size);
+	    (size_t) &_binary_gfx_cons_selected_ppm_size);
 	ic_pixmaps[CONS_IDLE] =
 	    make_pixmap(_binary_gfx_cons_idle_ppm_start,
-	    (int) &_binary_gfx_cons_idle_ppm_size);
+	    (size_t) &_binary_gfx_cons_idle_ppm_size);
 	ic_pixmaps[CONS_HAS_DATA] =
 	    make_pixmap(_binary_gfx_cons_has_data_ppm_start,
-	    (int) &_binary_gfx_cons_has_data_ppm_size);
+	    (size_t) &_binary_gfx_cons_has_data_ppm_size);
 	ic_pixmaps[CONS_DISCONNECTED] =
 	    make_pixmap(_binary_gfx_cons_idle_ppm_start,
-	    (int) &_binary_gfx_cons_idle_ppm_size);
+	    (size_t) &_binary_gfx_cons_idle_ppm_size);
 	ic_pixmaps[CONS_KERNEL] =
 	    make_pixmap(_binary_gfx_cons_kernel_ppm_start,
-	    (int) &_binary_gfx_cons_kernel_ppm_size);
+	    (size_t) &_binary_gfx_cons_kernel_ppm_size);
 	ic_pixmaps[CONS_DISCONNECTED_SEL] = ic_pixmaps[CONS_SELECTED];
 	
 	make_anim();
 	
-	use_gcons = 1;
+	use_gcons = true;
 	console_state[0] = CONS_DISCONNECTED_SEL;
 	console_state[KERNEL_CONSOLE] = CONS_KERNEL;
+	
 	gcons_redraw_console();
 }
Index: uspace/srv/console/gcons.h
===================================================================
--- uspace/srv/console/gcons.h	(revision 1601f3c9eb5071cab69e10771d77749bb525fcd5)
+++ uspace/srv/console/gcons.h	(revision bf1fb9f49ca7a033e969484ce601cf42dfbecd12)
@@ -33,16 +33,21 @@
  */
 
-#ifndef _GCONS_H_
-#define _GCONS_H_
+#ifndef GCONS_H_
+#define GCONS_H_
+
+#include <sys/types.h>
 
 void gcons_init(int phone);
+
 void gcons_redraw_console(void);
-void gcons_change_console(int consnum);
-void gcons_notify_char(int consnum);
+void gcons_change_console(size_t index);
+void gcons_notify_char(size_t index);
 void gcons_in_kernel(void);
-void gcons_notify_connect(int consnum);
-void gcons_notify_disconnect(int consnum);
-void gcons_mouse_move(int dx, int dy);
-int gcons_mouse_btn(int state);
+
+void gcons_notify_connect(size_t index);
+void gcons_notify_disconnect(size_t index);
+
+void gcons_mouse_move(ssize_t dx, ssize_t dy);
+int gcons_mouse_btn(bool state);
 
 #endif
Index: uspace/srv/console/screenbuffer.c
===================================================================
--- uspace/srv/console/screenbuffer.c	(revision 1601f3c9eb5071cab69e10771d77749bb525fcd5)
+++ uspace/srv/console/screenbuffer.c	(revision bf1fb9f49ca7a033e969484ce601cf42dfbecd12)
@@ -34,5 +34,5 @@
 
 #include <screenbuffer.h>
-#include <console/style.h>
+#include <io/style.h>
 #include <malloc.h>
 #include <unistd.h>
@@ -67,5 +67,5 @@
  *
  */
-screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, int size_x, int size_y) 
+screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y)
 {
 	scr->buffer = (keyfield_t *) malloc(sizeof(keyfield_t) * size_x * size_y);
@@ -91,5 +91,5 @@
 void screenbuffer_clear(screenbuffer_t *scr)
 {
-	unsigned int i;
+	size_t i;
 	
 	for (i = 0; i < (scr->size_x * scr->size_y); i++) {
@@ -99,6 +99,6 @@
 	
 	scr->top_line = 0;
+	scr->position_x = 0;
 	scr->position_y = 0;
-	scr->position_x = 0;
 }
 
@@ -109,11 +109,11 @@
  *
  */
-void screenbuffer_clear_line(screenbuffer_t *scr, unsigned int line)
+void screenbuffer_clear_line(screenbuffer_t *scr, size_t line)
 {
-	unsigned int i;
+	size_t x;
 	
-	for (i = 0; i < scr->size_x; i++) {
-		scr->buffer[i + line * scr->size_x].character = ' ';
-		scr->buffer[i + line * scr->size_x].attrs = scr->attrs;
+	for (x = 0; x < scr->size_x; x++) {
+		scr->buffer[x + line * scr->size_x].character = ' ';
+		scr->buffer[x + line * scr->size_x].attrs = scr->attrs;
 	}
 }
@@ -125,9 +125,9 @@
  *
  */
-void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest) 
+void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest)
 {
-	unsigned int i;
+	size_t i;
 	
-	for (i = 0; i < scr->size_x * scr->size_y; i++)
+	for (i = 0; i < (scr->size_x * scr->size_y); i++)
 		dest[i] = scr->buffer[i];
 }
@@ -140,5 +140,5 @@
  *
  */
-void screenbuffer_goto(screenbuffer_t *scr, unsigned int x, unsigned int y)
+void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y)
 {
 	scr->position_x = x % scr->size_x;
@@ -153,5 +153,5 @@
  *
  */
-void screenbuffer_set_style(screenbuffer_t *scr, int style)
+void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style)
 {
 	scr->attrs.t = at_style;
@@ -166,5 +166,5 @@
  *
  */
-void screenbuffer_set_color(screenbuffer_t *scr, unsigned int fg_color, unsigned int bg_color, unsigned int flags)
+void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color, uint8_t bg_color, uint8_t flags)
 {
 	scr->attrs.t = at_idx;
@@ -181,5 +181,5 @@
  *
  */
-void screenbuffer_set_rgb_color(screenbuffer_t *scr, unsigned int fg_color, unsigned int bg_color)
+void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color, uint32_t bg_color)
 {
 	scr->attrs.t = at_rgb;
Index: uspace/srv/console/screenbuffer.h
===================================================================
--- uspace/srv/console/screenbuffer.h	(revision 1601f3c9eb5071cab69e10771d77749bb525fcd5)
+++ uspace/srv/console/screenbuffer.h	(revision bf1fb9f49ca7a033e969484ce601cf42dfbecd12)
@@ -38,7 +38,8 @@
 #include <stdint.h>
 #include <sys/types.h>
+#include <bool.h>
 
-#define DEFAULT_FOREGROUND 0x0       /**< default console foreground color */
-#define DEFAULT_BACKGROUND 0xf0f0f0  /**< default console background color */
+#define DEFAULT_FOREGROUND  0x0       /**< default console foreground color */
+#define DEFAULT_BACKGROUND  0xf0f0f0  /**< default console background color */
 
 typedef struct {
@@ -73,5 +74,5 @@
 typedef struct {
 	wchar_t character;  /**< Character itself */
-	attrs_t attrs;      /**< Character`s attributes */
+	attrs_t attrs;      /**< Character attributes */
 } keyfield_t;
 
@@ -79,17 +80,17 @@
  */
 typedef struct {
-	keyfield_t *buffer;               /**< Screen content - characters and
-	                                       their attributes (used as a circular buffer) */
-	unsigned int size_x;              /**< Number of columns  */
-	unsigned int size_y;              /**< Number of rows */
+	keyfield_t *buffer;      /**< Screen content - characters and
+	                              their attributes (used as a circular buffer) */
+	size_t size_x;           /**< Number of columns  */
+	size_t size_y;           /**< Number of rows */
 	
 	/** Coordinates of last printed character for determining cursor position */
-	unsigned int position_x;
-	unsigned int position_y;
+	size_t position_x;
+	size_t position_y;
 	
-	attrs_t attrs;                    /**< Current attributes. */
-	unsigned int top_line;            /**< Points to buffer[][] line that will
-	                                       be printed at screen as the first line */
-	unsigned char is_cursor_visible;  /**< Cursor state - default is visible */
+	attrs_t attrs;           /**< Current attributes. */
+	size_t top_line;         /**< Points to buffer[][] line that will
+	                              be printed at screen as the first line */
+	bool is_cursor_visible;  /**< Cursor state - default is visible */
 } screenbuffer_t;
 
@@ -106,5 +107,5 @@
  *
  */
-static inline keyfield_t *get_field_at(screenbuffer_t *scr, unsigned int x, unsigned int y)
+static inline keyfield_t *get_field_at(screenbuffer_t *scr, size_t x, size_t y)
 {
 	return scr->buffer + x + ((y + scr->top_line) % scr->size_y) * scr->size_x;
@@ -139,15 +140,15 @@
 
 void screenbuffer_putchar(screenbuffer_t *scr, wchar_t c);
-screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, int size_x, int size_y);
+screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y);
 
 void screenbuffer_clear(screenbuffer_t *scr);
-void screenbuffer_clear_line(screenbuffer_t *scr, unsigned int line);
+void screenbuffer_clear_line(screenbuffer_t *scr, size_t line);
 void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest);
-void screenbuffer_goto(screenbuffer_t *scr, unsigned int x, unsigned int y);
-void screenbuffer_set_style(screenbuffer_t *scr, int style);
-void screenbuffer_set_color(screenbuffer_t *scr, unsigned int fg_color,
-    unsigned int bg_color, unsigned int attr);
-void screenbuffer_set_rgb_color(screenbuffer_t *scr, unsigned int fg_color,
-    unsigned int bg_color);
+void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y);
+void screenbuffer_set_style(screenbuffer_t *scr, uint8_t style);
+void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color,
+    uint8_t bg_color, uint8_t attr);
+void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color,
+    uint32_t bg_color);
 
 #endif
