Index: console/console.c
===================================================================
--- console/console.c	(revision d552ab9f50dc40770f01d677f59b35f6bdfac849)
+++ console/console.c	(revision 1f8324407bb9b8ee5bc8b0cf01d0ec3fbcf23961)
@@ -229,4 +229,5 @@
 		curs_visibility(0);
 
+		async_serialize_start();
 		if (kernel_pixmap == -1) { 
 			/* store/restore unsupported */
@@ -238,4 +239,5 @@
 			kernel_pixmap = -1;
 		}
+		async_serialize_end();
 
 		__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
@@ -243,4 +245,6 @@
 	} 
 	
+	async_serialize_start();
+
 	if (console_pixmap != -1) {
 		kernel_pixmap = switch_screens(console_pixmap);
@@ -281,4 +285,6 @@
 	curs_goto(conn->screenbuffer.position_y, conn->screenbuffer.position_x);
 	curs_visibility(conn->screenbuffer.is_cursor_visible);
+
+	async_serialize_end();
 }
 
@@ -291,4 +297,5 @@
 	int c;
 	connection_t *conn;
+	int newcon;
 	
 	/* Ignore parameters, the connection is alread opened */
@@ -299,4 +306,9 @@
 			/* TODO: Handle hangup */
 			return;
+		case KBD_MS_LEFT:
+			newcon = gcons_mouse_btn(IPC_GET_ARG1(call));
+			if (newcon != -1)
+				change_console(newcon);
+			break;
 		case KBD_MS_MOVE:
 			gcons_mouse_move(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
@@ -312,10 +324,8 @@
 //			if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + CONSOLE_COUNT)) {
 			if ((c >= 0x101) && (c < 0x101 + CONSOLE_COUNT)) {
-				async_serialize_start();
 				if (c == 0x112)
 					change_console(KERNEL_CONSOLE);
 				else
 					change_console(c - 0x101);
-				async_serialize_end();
 				break;
 			}
Index: console/gcons.c
===================================================================
--- console/gcons.c	(revision d552ab9f50dc40770f01d677f59b35f6bdfac849)
+++ console/gcons.c	(revision 1f8324407bb9b8ee5bc8b0cf01d0ec3fbcf23961)
@@ -241,13 +241,63 @@
 }
 
+int mouse_x, mouse_y;
+int btn_pressed, btn_x, btn_y;
+
+/** Handle mouse move
+ *
+ * @param dx Delta X of mouse move
+ * @param dy Delta Y of mouse move
+ */
 void gcons_mouse_move(int dx, int dy)
 {
-	static int x = 0;
-	static int y = 0;
-
-	x = limit(x+dx, 0, xres);
-	y = limit(y+dy, 0, yres);
-
-	async_msg_2(fbphone, FB_POINTER_MOVE, x, y);
+	mouse_x = limit(mouse_x+dx, 0, xres);
+	mouse_y = limit(mouse_y+dy, 0, yres);
+
+	async_msg_2(fbphone, FB_POINTER_MOVE, mouse_x, mouse_y);
+}
+
+static int gcons_find_conbut(int x, int y)
+{
+	int status_start = STATUS_START + (xres-800) / 2;;
+
+	if (y < STATUS_TOP || y >= STATUS_TOP+STATUS_HEIGHT)
+		return -1;
+	
+	if (x < status_start)
+		return -1;
+	
+	if (x >= status_start + (STATUS_WIDTH+STATUS_SPACE)*CONSOLE_COUNT)
+		return -1;
+	if (((x - status_start) % (STATUS_WIDTH+STATUS_SPACE)) >= STATUS_WIDTH)
+		return -1;
+	
+	return (x-status_start) / (STATUS_WIDTH+STATUS_SPACE);
+}
+
+/** Handle mouse click
+ *
+ * @param state New state (1-pressed, 0-depressed)
+ */
+int gcons_mouse_btn(int state)
+{
+	int conbut;
+
+	if (state) {
+		conbut = gcons_find_conbut(mouse_x, mouse_y);
+		if (conbut != -1) {
+			btn_pressed = 1;
+			btn_x = mouse_x;
+			btn_y = mouse_y;
+		}
+		return -1;
+	} 
+	if (!state && !btn_pressed)
+		return -1;
+	btn_pressed = 0;
+
+	conbut = gcons_find_conbut(mouse_x, mouse_y);
+	if (conbut == gcons_find_conbut(btn_x, btn_y))
+		return conbut;
+	return -1;
 }
 
Index: console/gcons.h
===================================================================
--- console/gcons.h	(revision d552ab9f50dc40770f01d677f59b35f6bdfac849)
+++ console/gcons.h	(revision 1f8324407bb9b8ee5bc8b0cf01d0ec3fbcf23961)
@@ -43,4 +43,5 @@
 void gcons_notify_disconnect(int consnum);
 void gcons_mouse_move(int dx, int dy);
+int gcons_mouse_btn(int state);
 
 #endif
Index: kbd/include/keys.h
===================================================================
--- kbd/include/keys.h	(revision d552ab9f50dc40770f01d677f59b35f6bdfac849)
+++ kbd/include/keys.h	(revision 1f8324407bb9b8ee5bc8b0cf01d0ec3fbcf23961)
