Index: uspace/srv/hid/fb/serial_console.c
===================================================================
--- uspace/srv/hid/fb/serial_console.c	(revision 19f857a3b361739b06d4f547174ae4ac1b99c651)
+++ uspace/srv/hid/fb/serial_console.c	(revision 6c39a9074d1bf9a23bf5243a2c35b2a8549f41d3)
@@ -31,7 +31,7 @@
 /**
  * @defgroup serial Serial console
- * @brief    Serial console services (putc, puts, clear screen, cursor goto,...)
+ * @brief Serial console services (putc, puts, clear screen, cursor goto,...)
  * @{
- */ 
+ */
 
 /** @file
@@ -47,6 +47,6 @@
 #include <io/style.h>
 #include <str.h>
-
-#include "../console/screenbuffer.h"
+#include <io/screenbuffer.h>
+
 #include "main.h"
 #include "serial_console.h"
@@ -54,12 +54,16 @@
 #define MAX_CONTROL 20
 
-static void serial_sgr(const unsigned int mode);
-void serial_putchar(wchar_t ch);
-
-static unsigned int scr_width;
-static unsigned int scr_height;
-static bool color = true;	/** True if producing color output. */
-static bool utf8 = false;	/** True if producing UTF8 output. */
+static ipcarg_t scr_width;
+static ipcarg_t scr_height;
+static bool color = true;    /**< True if producing color output. */
+static bool utf8 = false;    /**< True if producing UTF8 output. */
 static putc_function_t putc_function;
+
+static ipcarg_t lastcol = 0;
+static ipcarg_t lastrow = 0;
+static attrs_t cur_attr = {
+	.t = at_style,
+	.a.s.style = STYLE_NORMAL
+};
 
 /* Allow only 1 connection */
@@ -67,35 +71,35 @@
 
 enum sgr_color_index {
-	CI_BLACK	= 0,
-	CI_RED		= 1,
-	CI_GREEN	= 2,
-	CI_BROWN	= 3,
-	CI_BLUE		= 4,
-	CI_MAGENTA	= 5,
-	CI_CYAN		= 6,
-	CI_WHITE	= 7,
+	CI_BLACK   = 0,
+	CI_RED     = 1,
+	CI_GREEN   = 2,
+	CI_BROWN   = 3,
+	CI_BLUE    = 4,
+	CI_MAGENTA = 5,
+	CI_CYAN    = 6,
+	CI_WHITE   = 7
 };
 
 enum sgr_command {
-	SGR_RESET	= 0,
-	SGR_BOLD	= 1,
-	SGR_BLINK	= 5,
-	SGR_REVERSE	= 7,
-	SGR_NORMAL_INT	= 22,
-	SGR_BLINK_OFF	= 25,
+	SGR_RESET       = 0,
+	SGR_BOLD        = 1,
+	SGR_BLINK       = 5,
+	SGR_REVERSE     = 7,
+	SGR_NORMAL_INT  = 22,
+	SGR_BLINK_OFF   = 25,
 	SGR_REVERSE_OFF = 27,
-	SGR_FGCOLOR	= 30,
-	SGR_BGCOLOR	= 40
+	SGR_FGCOLOR     = 30,
+	SGR_BGCOLOR     = 40
 };
 
 static int color_map[] = {
-	[COLOR_BLACK]	= CI_BLACK,
-	[COLOR_BLUE]	= CI_RED,
-	[COLOR_GREEN]	= CI_GREEN,
-	[COLOR_CYAN]	= CI_CYAN,
-	[COLOR_RED]	= CI_RED,
+	[COLOR_BLACK]   = CI_BLACK,
+	[COLOR_BLUE]    = CI_RED,
+	[COLOR_GREEN]   = CI_GREEN,
+	[COLOR_CYAN]    = CI_CYAN,
+	[COLOR_RED]     = CI_RED,
 	[COLOR_MAGENTA] = CI_MAGENTA,
-	[COLOR_YELLOW]	= CI_BROWN,
-	[COLOR_WHITE]	= CI_WHITE
+	[COLOR_YELLOW]  = CI_BROWN,
+	[COLOR_WHITE]   = CI_WHITE
 };
 
@@ -106,29 +110,26 @@
 }
 
-void serial_putchar(wchar_t ch)
-{
-	char buf[STR_BOUNDS(1)];
-	size_t offs;
-	size_t i;
-
+static void serial_putchar(wchar_t ch)
+{
 	if (utf8 != true) {
 		if (ch >= 0 && ch < 128)
 			(*putc_function)((uint8_t) ch);
-		else 
+		else
 			(*putc_function)('?');
+		
 		return;
 	}
-
-	offs = 0;
+	
+	size_t offs = 0;
+	char buf[STR_BOUNDS(1)];
 	if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) {
+		size_t i;
 		for (i = 0; i < offs; i++)
 			(*putc_function)(buf[i]);
-	} else {
+	} else
 		(*putc_function)('?');
-	}
-
-}
-
-void serial_goto(const unsigned int col, const unsigned int row)
+}
+
+void serial_goto(const ipcarg_t col, const ipcarg_t row)
 {
 	if ((col > scr_width) || (row > scr_height))
@@ -138,4 +139,94 @@
 	snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1);
 	serial_puts(control);
+}
+
+/** ECMA-48 Set Graphics Rendition. */
+static void serial_sgr(const unsigned int mode)
+{
+	char control[MAX_CONTROL];
+	snprintf(control, MAX_CONTROL, "\033[%um", mode);
+	serial_puts(control);
+}
+
+static void serial_set_style(console_style_t style)
+{
+	switch (style) {
+	case STYLE_EMPHASIS:
+		if (color) {
+			serial_sgr(SGR_RESET);
+			serial_sgr(SGR_FGCOLOR + CI_RED);
+			serial_sgr(SGR_BGCOLOR + CI_WHITE);
+		}
+		serial_sgr(SGR_BOLD);
+		break;
+	case STYLE_INVERTED:
+		if (color) {
+			serial_sgr(SGR_RESET);
+			serial_sgr(SGR_FGCOLOR + CI_WHITE);
+			serial_sgr(SGR_BGCOLOR + CI_BLACK);
+			serial_sgr(SGR_NORMAL_INT);
+		} else
+			serial_sgr(SGR_REVERSE);
+		break;
+	case STYLE_SELECTED:
+		if (color) {
+			serial_sgr(SGR_RESET);
+			serial_sgr(SGR_FGCOLOR + CI_WHITE);
+			serial_sgr(SGR_BGCOLOR + CI_RED);
+			serial_sgr(SGR_NORMAL_INT);
+		} else {
+			serial_sgr(SGR_BOLD);
+			serial_sgr(SGR_REVERSE);
+		}
+		break;
+	default:
+		if (color) {
+			serial_sgr(SGR_RESET);
+			serial_sgr(SGR_FGCOLOR + CI_BLACK);
+			serial_sgr(SGR_BGCOLOR + CI_WHITE);
+		}
+		serial_sgr(SGR_NORMAL_INT);
+	}
+}
+
+static void serial_set_idx(uint8_t fgcolor, uint8_t bgcolor,
+    uint8_t flags)
+{
+	if (color) {
+		serial_sgr(SGR_RESET);
+		serial_sgr(SGR_FGCOLOR + color_map[fgcolor]);
+		serial_sgr(SGR_BGCOLOR + color_map[bgcolor]);
+	} else {
+		if (fgcolor < bgcolor)
+			serial_sgr(SGR_RESET);
+		else
+			serial_sgr(SGR_REVERSE);
+	}	
+}
+
+static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
+{
+	serial_sgr(SGR_RESET);
+	
+	if (fgcolor < bgcolor)
+		serial_sgr(SGR_REVERSE_OFF);
+	else
+		serial_sgr(SGR_REVERSE);
+}
+
+static void serial_set_attrs(attrs_t *a)
+{
+	switch (a->t) {
+	case at_style:
+		serial_set_style(a->a.s.style);
+		break;
+	case at_rgb:
+		serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color);
+		break;
+	case at_idx:
+		serial_set_idx(a->a.i.fg_color, a->a.i.bg_color,
+		    a->a.i.flags);
+		break;
+	}
 }
 
@@ -148,9 +239,11 @@
 		serial_sgr(SGR_BGCOLOR + CI_WHITE);
 	}
-
+	
 	serial_puts("\033[2J");
-}
-
-void serial_scroll(int i)
+	
+	serial_set_attrs(&cur_attr);
+}
+
+void serial_scroll(ssize_t i)
 {
 	if (i > 0) {
@@ -165,14 +258,6 @@
 }
 
-/** ECMA-48 Set Graphics Rendition. */
-static void serial_sgr(const unsigned int mode)
-{
-	char control[MAX_CONTROL];
-	snprintf(control, MAX_CONTROL, "\033[%um", mode);
-	serial_puts(control);
-}
-
 /** Set scrolling region. */
-void serial_set_scroll_region(unsigned last_row)
+void serial_set_scroll_region(ipcarg_t last_row)
 {
 	char control[MAX_CONTROL];
@@ -191,5 +276,5 @@
 }
 
-void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
+void serial_console_init(putc_function_t putc_fn, ipcarg_t w, ipcarg_t h)
 {
 	scr_width = w;
@@ -198,63 +283,5 @@
 }
 
-static void serial_set_style(int style)
-{
-	if (style == STYLE_EMPHASIS) {
-		if (color) {
-			serial_sgr(SGR_RESET);
-			serial_sgr(SGR_FGCOLOR + CI_RED);
-			serial_sgr(SGR_BGCOLOR + CI_WHITE);
-		}
-		serial_sgr(SGR_BOLD);
-	} else {
-		if (color) {
-			serial_sgr(SGR_RESET);
-			serial_sgr(SGR_FGCOLOR + CI_BLACK);
-			serial_sgr(SGR_BGCOLOR + CI_WHITE);
-		}
-		serial_sgr(SGR_NORMAL_INT);
-	}
-}
-
-static void serial_set_idx(unsigned fgcolor, unsigned bgcolor,
-    unsigned flags)
-{
-	if (color) {
-		serial_sgr(SGR_RESET);
-		serial_sgr(SGR_FGCOLOR + color_map[fgcolor]);
-		serial_sgr(SGR_BGCOLOR + color_map[bgcolor]);
-	} else {
-		if (fgcolor < bgcolor)
-			serial_sgr(SGR_RESET);
-		else
-			serial_sgr(SGR_REVERSE);
-	}	
-}
-
-static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
-{
-	if (fgcolor < bgcolor)
-		serial_sgr(SGR_REVERSE_OFF);
-	else
-		serial_sgr(SGR_REVERSE);
-}
-
-static void serial_set_attrs(const attrs_t *a)
-{
-	switch (a->t) {
-	case at_style:
-		serial_set_style(a->a.s.style);
-		break;
-	case at_rgb:
-		serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color);
-		break;
-	case at_idx:
-		serial_set_idx(a->a.i.fg_color,
-		    a->a.i.bg_color, a->a.i.flags);
-		break;
-	default:
-		break;
-	}
-}
+
 
 /** Draw text data to viewport.
@@ -262,38 +289,35 @@
  * @param vport Viewport id
  * @param data  Text data.
- * @param x	Leftmost column of the area.
- * @param y	Topmost row of the area.
- * @param w	Number of rows.
- * @param h	Number of columns.
- */
-static void draw_text_data(keyfield_t *data, unsigned int x,
-    unsigned int y, unsigned int w, unsigned int h)
-{
-	unsigned int i, j;
-	keyfield_t *field;
-	attrs_t *a0, *a1;
-
+ * @param x     Leftmost column of the area.
+ * @param y     Topmost row of the area.
+ * @param w     Number of rows.
+ * @param h     Number of columns.
+ *
+ */
+static void draw_text_data(keyfield_t *data, ipcarg_t x, ipcarg_t y,
+    ipcarg_t w, ipcarg_t h)
+{
 	serial_goto(x, y);
-	a0 = &data[0].attrs;
-	serial_set_attrs(a0);
-
+	ipcarg_t i;
+	ipcarg_t j;
+	
+	attrs_t *a0 = &data[0].attrs;
+	
 	for (j = 0; j < h; j++) {
-		if (j > 0 && w != scr_width)
+		if ((j > 0) && (w != scr_width))
 			serial_goto(x, j);
-
+		
 		for (i = 0; i < w; i++) {
-			field = &data[j * w + i];
-
-			a1 = &field->attrs;
-			if (!attrs_same(*a0, *a1))
+			attrs_t *a1 = &data[j * w + i].attrs;
+			
+			if (!attrs_same(*a0, *a1)) {
 				serial_set_attrs(a1);
-			serial_putchar(field->character);
-			a0 = a1;
+				a0 = a1;
+			}
+			
+			serial_putchar(data[j * w + i].character);
 		}
 	}
 }
-
-unsigned int lastcol = 0;
-unsigned int lastrow = 0;
 
 /**
@@ -302,18 +326,6 @@
 void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
 {
-	int retval;
-	ipc_callid_t callid;
-	ipc_call_t call;
 	keyfield_t *interbuf = NULL;
 	size_t intersize = 0;
-
-	wchar_t c;
-	unsigned int col;
-	unsigned int row;
-	unsigned int w;
-	unsigned int h;
-	int i;
-
-	attrs_t cur_attr;
 	
 	if (client_connected) {
@@ -324,7 +336,4 @@
 	client_connected = 1;
 	ipc_answer_0(iid, EOK);
-
-	cur_attr.t = at_style;
-	cur_attr.a.s.style = STYLE_NORMAL;
 	
 	/* Clear the terminal, set scrolling region
@@ -335,9 +344,23 @@
 	
 	while (true) {
-		callid = async_get_call(&call);
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		wchar_t c;
+		ipcarg_t col;
+		ipcarg_t row;
+		ipcarg_t w;
+		ipcarg_t h;
+		attrs_t attr;
+		ssize_t rows;
+		
+		int retval;
+		
 		switch (IPC_GET_METHOD(call)) {
 		case IPC_M_PHONE_HUNGUP:
 			client_connected = 0;
 			ipc_answer_0(callid, EOK);
+			
+			/* Exit thread */
 			return;
 		case IPC_M_SHARE_OUT:
@@ -350,4 +373,5 @@
 				continue;
 			}
+			
 			retval = EINVAL;
 			break;
@@ -357,12 +381,15 @@
 			w = IPC_GET_ARG3(call);
 			h = IPC_GET_ARG4(call);
+			
 			if (!interbuf) {
 				retval = EINVAL;
 				break;
 			}
+			
 			if ((col + w > scr_width) || (row + h > scr_height)) {
 				retval = EINVAL;
 				break;
 			}
+			
 			draw_text_data(interbuf, col, row, w, h);
 			lastcol = col + w;
@@ -374,6 +401,8 @@
 			col = IPC_GET_ARG2(call);
 			row = IPC_GET_ARG3(call);
+			
 			if ((lastcol != col) || (lastrow != row))
 				serial_goto(col, row);
+			
 			lastcol = col + 1;
 			lastrow = row;
@@ -401,35 +430,40 @@
 			break;
 		case FB_SET_STYLE:
-			cur_attr.t = at_style;
-			cur_attr.a.s.style = IPC_GET_ARG1(call);
-			cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
+			attr.t = at_style;
+			attr.a.s.style = IPC_GET_ARG1(call);
 			serial_set_attrs(&cur_attr);
-
 			retval = 0;
 			break;
 		case FB_SET_COLOR:
-			cur_attr.t = at_idx;
-			cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
-			cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
-			cur_attr.a.i.flags = IPC_GET_ARG3(call);
+			attr.t = at_idx;
+			attr.a.i.fg_color = IPC_GET_ARG1(call);
+			attr.a.i.bg_color = IPC_GET_ARG2(call);
+			attr.a.i.flags = IPC_GET_ARG3(call);
 			serial_set_attrs(&cur_attr);
-
 			retval = 0;
 			break;
 		case FB_SET_RGB_COLOR:
-			cur_attr.t = at_rgb;
-			cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
-			cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
+			attr.t = at_rgb;
+			attr.a.r.fg_color = IPC_GET_ARG1(call);
+			attr.a.r.bg_color = IPC_GET_ARG2(call);
 			serial_set_attrs(&cur_attr);
-
 			retval = 0;
 			break;
 		case FB_SCROLL:
-			i = IPC_GET_ARG1(call);
-			if ((i > (int) scr_height) || (i < -((int) scr_height))) {
-				retval = EINVAL;
-				break;
+			rows = IPC_GET_ARG1(call);
+			
+			if (rows >= 0) {
+				if ((ipcarg_t) rows > scr_height) {
+					retval = EINVAL;
+					break;
+				}
+			} else {
+				if ((ipcarg_t) (-rows) > scr_height) {
+					retval = EINVAL;
+					break;
+				}
 			}
-			serial_scroll(i);
+			
+			serial_scroll(rows);
 			serial_goto(lastcol, lastrow);
 			retval = 0;
@@ -451,5 +485,4 @@
 		case FB_SCREEN_RECLAIM:
 			serial_clrscr();
-			serial_set_attrs(&cur_attr);
 			retval = 0;
 			break;
