Index: uspace/srv/kbd/generic/kbd.c
===================================================================
--- uspace/srv/kbd/generic/kbd.c	(revision e00938c830a66b90fc18e4a1a29bd6099075f762)
+++ uspace/srv/kbd/generic/kbd.c	(revision fa094491c49be2130cd1f5bbad081181cbad82b1)
@@ -43,10 +43,12 @@
 #include <stdio.h>
 #include <ipc/ns.h>
+#include <async.h>
 #include <errno.h>
+#include <libadt/fifo.h>
+#include <kbd/kbd.h>
+
 #include <arch/kbd.h>
 #include <kbd.h>
-#include <libadt/fifo.h>
 #include <key_buffer.h>
-#include <async.h>
 #include <keys.h>
 
@@ -59,5 +61,5 @@
 static void irq_handler(ipc_callid_t iid, ipc_call_t *call)
 {
-	int chr;
+	kbd_event_t ev;
 
 #ifdef MOUSE_ENABLED
@@ -70,12 +72,13 @@
 	if (cons_connected && phone2cons != -1) {
 		/*
-		 * recode to ASCII - one interrupt can produce more than one
-		 * code so result is stored in fifo
+		 * One interrupt can produce more than one event so the result
+		 * is stored in a FIFO.
 		 */
 		while (!keybuffer_empty(&keybuffer)) {
-			if (!keybuffer_pop(&keybuffer, (int *)&chr))
+			if (!keybuffer_pop(&keybuffer, &ev))
 				break;
 
-			async_msg_1(phone2cons, KBD_PUSHCHAR, chr);
+			async_msg_4(phone2cons, KBD_EVENT, ev.type, ev.key,
+			    ev.mods, ev.c);
 		}
 	}
Index: uspace/srv/kbd/generic/key_buffer.c
===================================================================
--- uspace/srv/kbd/generic/key_buffer.c	(revision e00938c830a66b90fc18e4a1a29bd6099075f762)
+++ uspace/srv/kbd/generic/key_buffer.c	(revision fa094491c49be2130cd1f5bbad081181cbad82b1)
@@ -41,5 +41,5 @@
 /** Clear key buffer.
  */
-void keybuffer_free(keybuffer_t *keybuffer) 
+void keybuffer_free(keybuffer_t *keybuffer)
 {
 	futex_down(&keybuffer_futex);
@@ -76,13 +76,16 @@
 }
 
-/** Push key to key buffer.
- * If buffer is full, character is ignored.
- * @param key code of stored key
+/** Push key event to key buffer.
+ *
+ * If the buffer is full, the event is ignored.
+ *
+ * @param keybuffer	The keybuffer.
+ * @param ev		The event to push.
  */
-void keybuffer_push(keybuffer_t *keybuffer, int key)
+void keybuffer_push(keybuffer_t *keybuffer, const kbd_event_t *ev)
 {
 	futex_down(&keybuffer_futex);
 	if (keybuffer->items < KEYBUFFER_SIZE) {
-		keybuffer->fifo[keybuffer->tail] = key;
+		keybuffer->fifo[keybuffer->tail] = *ev;
 		keybuffer->tail = (keybuffer->tail + 1) % KEYBUFFER_SIZE;
 		keybuffer->items++;
@@ -91,14 +94,23 @@
 }
 
-/** Pop character from buffer.
- * @param c pointer to space where to store character from buffer.
- * @return zero on empty buffer, nonzero else
+void keybuffer_push0(keybuffer_t *keybuffer, int c)
+{
+	kbd_event_t ev;
+
+	ev.key = c; ev.mods = 0; ev.c = c;
+	keybuffer_push(keybuffer, &ev);
+}
+
+/** Pop event from buffer.
+ *
+ * @param edst	Pointer to where the event should be saved.
+ * @return	Zero on empty buffer, nonzero otherwise.
  */
-int keybuffer_pop(keybuffer_t *keybuffer, int *c)
+int keybuffer_pop(keybuffer_t *keybuffer, kbd_event_t *edst)
 {
 	futex_down(&keybuffer_futex);
 	if (keybuffer->items > 0) {
 		keybuffer->items--;
-		*c = (keybuffer->fifo[keybuffer->head]) ;
+		*edst = (keybuffer->fifo[keybuffer->head]) ;
 		keybuffer->head = (keybuffer->head + 1) % KEYBUFFER_SIZE;
 		futex_up(&keybuffer_futex);
