Index: uspace/srv/hid/input/Makefile
===================================================================
--- uspace/srv/hid/input/Makefile	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/Makefile	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -29,12 +29,7 @@
 
 USPACE_PREFIX = ../../..
-EXTRA_CFLAGS = -Iinclude
 BINARY = input
 
 SOURCES = \
-	generic/gsp.c \
-	generic/input.c \
-	generic/layout.c \
-	generic/stroke.c \
 	layout/cz.c \
 	layout/us_qwerty.c \
@@ -56,5 +51,9 @@
 	ctl/pc.c \
 	ctl/stty.c \
-	ctl/sun.c
+	ctl/sun.c \
+	gsp.c \
+	input.c \
+	layout.c \
+	stroke.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hid/input/ctl/apple.c
===================================================================
--- uspace/srv/hid/input/ctl/apple.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/ctl/apple.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -36,9 +36,9 @@
  */
 
-#include <kbd.h>
 #include <io/console.h>
 #include <io/keycode.h>
-#include <kbd_ctl.h>
-#include <kbd_port.h>
+#include "../kbd.h"
+#include "../kbd_ctl.h"
+#include "../kbd_port.h"
 
 static void apple_ctl_parse(sysarg_t);
Index: uspace/srv/hid/input/ctl/gxe_fb.c
===================================================================
--- uspace/srv/hid/input/ctl/gxe_fb.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/ctl/gxe_fb.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -33,14 +33,14 @@
 /**
  * @file
- * @brief	GXEmul framebuffer-mode keyboard controller driver.
+ * @brief GXEmul framebuffer-mode keyboard controller driver.
  */
 
-#include <kbd.h>
 #include <io/console.h>
 #include <io/keycode.h>
-#include <kbd_ctl.h>
-#include <kbd_port.h>
-#include <gsp.h>
-#include <stroke.h>
+#include "../stroke.h"
+#include "../gsp.h"
+#include "../kbd.h"
+#include "../kbd_port.h"
+#include "../kbd_ctl.h"
 
 static void gxe_fb_ctl_parse(sysarg_t);
Index: uspace/srv/hid/input/ctl/kbdev.c
===================================================================
--- uspace/srv/hid/input/ctl/kbdev.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/ctl/kbdev.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -40,16 +40,16 @@
 #include <errno.h>
 #include <fcntl.h>
-#include <gsp.h>
 #include <io/console.h>
 #include <io/keycode.h>
 #include <ipc/kbdev.h>
-#include <input.h>
-#include <kbd.h>
-#include <kbd_ctl.h>
-#include <kbd_port.h>
 #include <loc.h>
 #include <stdlib.h>
 #include <vfs/vfs_sess.h>
 #include <sys/typefmt.h>
+#include "../gsp.h"
+#include "../input.h"
+#include "../kbd.h"
+#include "../kbd_ctl.h"
+#include "../kbd_port.h"
 
 static int kbdev_ctl_init(kbd_dev_t *);
Index: uspace/srv/hid/input/ctl/pc.c
===================================================================
--- uspace/srv/hid/input/ctl/pc.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/ctl/pc.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -36,10 +36,10 @@
  */
 
-#include <kbd.h>
 #include <io/console.h>
 #include <io/keycode.h>
-#include <kbd_ctl.h>
-#include <kbd_port.h>
-#include <gsp.h>
+#include "../gsp.h"
+#include "../kbd.h"
+#include "../kbd_port.h"
+#include "../kbd_ctl.h"
 
 static void pc_ctl_parse(sysarg_t);
Index: uspace/srv/hid/input/ctl/stty.c
===================================================================
--- uspace/srv/hid/input/ctl/stty.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/ctl/stty.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -38,10 +38,10 @@
  */
 
-#include <kbd.h>
 #include <io/keycode.h>
-#include <kbd_ctl.h>
-#include <kbd_port.h>
-#include <gsp.h>
-#include <stroke.h>
+#include "../stroke.h"
+#include "../gsp.h"
+#include "../kbd.h"
+#include "../kbd_port.h"
+#include "../kbd_ctl.h"
 
 static void stty_ctl_parse(sysarg_t);
Index: uspace/srv/hid/input/ctl/sun.c
===================================================================
--- uspace/srv/hid/input/ctl/sun.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/ctl/sun.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -37,9 +37,9 @@
  */
 
-#include <kbd.h>
 #include <io/console.h>
 #include <io/keycode.h>
-#include <kbd_ctl.h>
-#include <kbd_port.h>
+#include "../kbd.h"
+#include "../kbd_port.h"
+#include "../kbd_ctl.h"
 
 static void sun_ctl_parse(sysarg_t);
Index: pace/srv/hid/input/generic/gsp.c
===================================================================
--- uspace/srv/hid/input/generic/gsp.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,291 +1,0 @@
-/*
- * Copyright (c) 2009 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @addtogroup kbdgen generic
- * @ingroup  input
- * @{
- */ 
-/** @file
- * @brief	Generic scancode parser.
- *
- * The scancode parser is a simple finite state machine. It is described
- * using sequences of input symbols (scancodes) and the corresponding output
- * value (mods, key pair). When the parser recognizes a sequence,
- * it outputs the value and restarts. If a transition is undefined,
- * the parser restarts, too.
- *
- * Apart from precise values, GSP_DEFAULT allows to catch general cases.
- * I.e. if we knew that after 0x1b 0x4f there always follow two more
- * scancodes, we can define (0x1b, 0x4f, GSP_DEFAULT, GSP_DEFAULT, GSP_END)
- * with null output. This will force the parser to read the entire sequence,
- * not leaving garbage on the input if it does not recognize the specific
- * sequence.
- */
-
-#include <gsp.h>
-#include <adt/hash_table.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define TRANS_TABLE_CHAINS 256
-
-/*
- * Hash table operations for the transition function.
- */
-
-static hash_index_t trans_op_hash(unsigned long key[]);
-static int trans_op_compare(unsigned long key[], hash_count_t keys,
-    link_t *item);
-static void trans_op_remove_callback(link_t *item);
-
-static hash_table_operations_t trans_ops = {
-	.hash = trans_op_hash,
-	.compare = trans_op_compare,
-	.remove_callback = trans_op_remove_callback
-};
-
-static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input);
-static void trans_insert(gsp_t *p, gsp_trans_t *t);
-static gsp_trans_t *trans_new(void);
-
-/** Initialise scancode parser. */
-void gsp_init(gsp_t *p)
-{
-	p->states = 1;
-	hash_table_create(&p->trans, TRANS_TABLE_CHAINS, 2, &trans_ops);
-}
-
-/** Insert a series of definitions into the parser.
- *
- * @param p	The parser.
- * @param defs	Definition list. Each definition starts with two output values
- *		(mods, key) and continues with a sequence of input values
- *		terminated with GSP_END. The definition list is terminated
- *		with two zeroes (0, 0) for output values.
- */
-int gsp_insert_defs(gsp_t *p, const int *defs)
-{
-	unsigned mods, key;
-	const int *dp;
-	int rc;
-
-	dp = defs;
-
-	while (1) {
-		/* Read the output values. */
-		mods = *dp++;
-		key = *dp++;
-		if (key == 0) break;
-
-		/* Insert one sequence. */
-		rc = gsp_insert_seq(p, dp, mods, key);
-		if (rc != 0)
-			return rc;
-
-		/* Skip to the next definition. */
-		while (*dp != GSP_END)
-			++dp;
-		++dp;
-	}
-
-	return 0;
-}
-
-/** Insert one sequence into the parser.
- *
- * @param p	The parser.
- * @param seq	Sequence of input values terminated with GSP_END.
- * @param mods	Corresponsing output value.
- * @param key	Corresponsing output value.
- */
-int gsp_insert_seq(gsp_t *p, const int *seq, unsigned mods, unsigned key)
-{
-	int state;
-	gsp_trans_t *t;
-
-	state = 0;
-	t = NULL;
-
-	/* Input sequence must be non-empty. */
-	if (*seq == GSP_END)
-		return -1;
-
-	while (*(seq + 1) != GSP_END) {
-		t = trans_lookup(p, state, *seq);
-		if (t == NULL) {
-			/* Create new state. */
-			t = trans_new();
-			t->old_state = state;
-			t->input = *seq;
-			t->new_state = p->states++;
-
-			t->out_mods = 0;
-			t->out_key = 0;
-
-			trans_insert(p, t);
-		}
-		state = t->new_state;
-		++seq;
-	}
-
-	/* Process the last transition. */
-	t = trans_lookup(p, state, *seq);
-	if (t != NULL) {
-		exit(1);
-		return -1;	/* Conflicting definition. */
-	}
-
-	t = trans_new();
-	t->old_state = state;
-	t->input = *seq;
-	t->new_state = 0;
-
-	t->out_mods = mods;
-	t->out_key = key;
-
-	trans_insert(p, t);
-
-	return 0;
-}
-
-/** Compute one parser step.
- *
- * Computes the next state and output values for a given state and input.
- * This handles everything including restarts and default branches.
- *
- * @param p		The parser.
- * @param state		Old state.
- * @param input		Input symbol (scancode).
- * @param mods		Output value (modifier).
- * @param key		Output value (key).
- * @return		New state.
- */
-int gsp_step(gsp_t *p, int state, int input, unsigned *mods, unsigned *key)
-{
-	gsp_trans_t *t;
-
-	t = trans_lookup(p, state, input);
-	if (t == NULL) {
-		t = trans_lookup(p, state, GSP_DEFAULT);
-	}
-
-	if (t == NULL) {
-		printf("gsp_step: not found, state=%d, input=0x%x\n",
-		    state, input);
-		*mods = 0;
-		*key = 0;
-		return 0;
-	}
-
-	*mods = t->out_mods;
-	*key = t->out_key;
-
-	return t->new_state;
-}
-
-/** Transition function lookup.
- *
- * Returns the value of the transition function for the given state
- * and input. Note that the transition must be specified precisely,
- * to obtain the default branch use input = GSP_DEFAULT.
- *
- * @param p		Parser.
- * @param state		Current state.
- * @param input		Input value.
- * @return		The transition or @c NULL if not defined.
- */
-static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input)
-{
-	link_t *item;
-	unsigned long key[2];
-
-	key[0] = state;
-	key[1] = input;
-
-	item = hash_table_find(&p->trans, key);
-	if (item == NULL) return NULL;
-
-	return hash_table_get_instance(item, gsp_trans_t, link);
-}
-
-/** Define a new transition.
- *
- * @param p	The parser.
- * @param t	Transition with all fields defined.
- */
-static void trans_insert(gsp_t *p, gsp_trans_t *t)
-{
-	unsigned long key[2];
-
-	key[0] = t->old_state;
-	key[1] = t->input;
-
-	hash_table_insert(&p->trans, key, &t->link);
-}
-
-/** Allocate transition structure. */
-static gsp_trans_t *trans_new(void)
-{
-	gsp_trans_t *t;
-
-	t = malloc(sizeof(gsp_trans_t));
-	if (t == NULL) {
-		printf("Memory allocation failed.\n");
-		exit(1);
-	}
-
-	return t;
-}
-
-/*
- * Transition function hash table operations.
- */
-
-static hash_index_t trans_op_hash(unsigned long key[])
-{
-	return (key[0] * 17 + key[1]) % TRANS_TABLE_CHAINS;
-}
-
-static int trans_op_compare(unsigned long key[], hash_count_t keys,
-    link_t *item)
-{
-	gsp_trans_t *t;
-
-	t = hash_table_get_instance(item, gsp_trans_t, link);
-	return ((key[0] == (unsigned long) t->old_state)
-	    && (key[1] == (unsigned long) t->input));
-}
-
-static void trans_op_remove_callback(link_t *item)
-{
-}
-
-/**
- * @}
- */ 
Index: pace/srv/hid/input/generic/input.c
===================================================================
--- uspace/srv/hid/input/generic/input.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,702 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @addtogroup inputgen generic
- * @brief HelenOS input server.
- * @ingroup input
- * @{
- */
-/** @file
- */
-
-#include <adt/list.h>
-#include <bool.h>
-#include <fibril_synch.h>
-#include <ipc/services.h>
-#include <ipc/input.h>
-#include <sysinfo.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ns.h>
-#include <async.h>
-#include <errno.h>
-#include <adt/fifo.h>
-#include <io/console.h>
-#include <io/keycode.h>
-#include <loc.h>
-#include <input.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <kbd_ctl.h>
-#include <mouse_proto.h>
-#include <layout.h>
-#include <mouse.h>
-
-#define NUM_LAYOUTS  3
-
-static layout_ops_t *layout[NUM_LAYOUTS] = {
-	&us_qwerty_ops,
-	&us_dvorak_ops,
-	&cz_ops
-};
-
-static void kbd_devs_yield(void);
-static void kbd_devs_reclaim(void);
-
-async_sess_t *client_sess = NULL;
-
-/** List of keyboard devices */
-static list_t kbd_devs;
-
-/** List of mouse devices */
-static list_t mouse_devs;
-
-bool irc_service = false;
-async_sess_t *irc_sess = NULL;
-
-static FIBRIL_MUTEX_INITIALIZE(discovery_lock);
-
-void kbd_push_data(kbd_dev_t *kdev, sysarg_t data)
-{
-	(*kdev->ctl_ops->parse)(data);
-}
-
-void mouse_push_data(mouse_dev_t *mdev, sysarg_t data)
-{
-	(*mdev->proto_ops->parse)(data);
-}
-
-void kbd_push_event(kbd_dev_t *kdev, int type, unsigned int key)
-{
-	kbd_event_t ev;
-	unsigned int mod_mask;
-	
-	switch (key) {
-	case KC_LCTRL: mod_mask = KM_LCTRL; break;
-	case KC_RCTRL: mod_mask = KM_RCTRL; break;
-	case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
-	case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
-	case KC_LALT: mod_mask = KM_LALT; break;
-	case KC_RALT: mod_mask = KM_RALT; break;
-	default: mod_mask = 0; break;
-	}
-	
-	if (mod_mask != 0) {
-		if (type == KEY_PRESS)
-			kdev->mods = kdev->mods | mod_mask;
-		else
-			kdev->mods = kdev->mods & ~mod_mask;
-	}
-	
-	switch (key) {
-	case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
-	case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
-	case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
-	default: mod_mask = 0; break;
-	}
-	
-	if (mod_mask != 0) {
-		if (type == KEY_PRESS) {
-			/*
-			 * Only change lock state on transition from released
-			 * to pressed. This prevents autorepeat from messing
-			 * up the lock state.
-			 */
-			kdev->mods = kdev->mods ^ (mod_mask & ~kdev->lock_keys);
-			kdev->lock_keys = kdev->lock_keys | mod_mask;
-			
-			/* Update keyboard lock indicator lights. */
-			(*kdev->ctl_ops->set_ind)(kdev, kdev->mods);
-		} else {
-			kdev->lock_keys = kdev->lock_keys & ~mod_mask;
-		}
-	}
-	
-	if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
-	    key == KC_F1) {
-		layout_destroy(kdev->active_layout);
-		kdev->active_layout = layout_create(layout[0]);
-		return;
-	}
-	
-	if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
-	    key == KC_F2) {
-		layout_destroy(kdev->active_layout);
-		kdev->active_layout = layout_create(layout[1]);
-		return;
-	}
-	
-	if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
-	    key == KC_F3) {
-		layout_destroy(kdev->active_layout);
-		kdev->active_layout = layout_create(layout[2]);
-		return;
-	}
-	
-	ev.type = type;
-	ev.key = key;
-	ev.mods = kdev->mods;
-	
-	ev.c = layout_parse_ev(kdev->active_layout, &ev);
-	
-	async_exch_t *exch = async_exchange_begin(client_sess);
-	async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c);
-	async_exchange_end(exch);
-}
-
-/** Mouse pointer has moved. */
-void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy, int dz)
-{
-	async_exch_t *exch = async_exchange_begin(client_sess);
-	if (dx || dy)
-		async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy);
-	if (dz) {
-		// TODO: Implement proper wheel support
-		keycode_t code = dz > 0 ? KC_UP : KC_DOWN;
-		for (int i = 0; i < 3; ++i) {
-			async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0);
-		}
-		async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0);
-	}
-	async_exchange_end(exch);
-}
-
-/** Mouse pointer has moved in absolute mode. */
-void mouse_push_event_abs_move(mouse_dev_t *mdev, unsigned int x, unsigned int y,
-    unsigned int max_x, unsigned int max_y)
-{
-	if (max_x && max_y) {
-		async_exch_t *exch = async_exchange_begin(client_sess);
-		async_msg_4(exch, INPUT_EVENT_ABS_MOVE, x, y, max_x, max_y);
-		async_exchange_end(exch);
-	}
-}
-
-/** Mouse button has been pressed. */
-void mouse_push_event_button(mouse_dev_t *mdev, int bnum, int press)
-{
-	async_exch_t *exch = async_exchange_begin(client_sess);
-	async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press);
-	async_exchange_end(exch);
-}
-
-static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	async_answer_0(iid, EOK);
-	
-	while (true) {
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-		
-		if (!IPC_GET_IMETHOD(call)) {
-			if (client_sess != NULL) {
-				async_hangup(client_sess);
-				client_sess = NULL;
-			}
-			
-			async_answer_0(callid, EOK);
-			return;
-		}
-		
-		async_sess_t *sess =
-		    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
-		if (sess != NULL) {
-			if (client_sess == NULL) {
-				client_sess = sess;
-				async_answer_0(callid, EOK);
-			} else
-				async_answer_0(callid, ELIMIT);
-		} else {
-			switch (IPC_GET_IMETHOD(call)) {
-			case INPUT_YIELD:
-				kbd_devs_yield();
-				async_answer_0(callid, EOK);
-				break;
-			case INPUT_RECLAIM:
-				kbd_devs_reclaim();
-				async_answer_0(callid, EOK);
-				break;
-			default:
-				async_answer_0(callid, EINVAL);
-			}
-		}
-	}
-}
-
-static kbd_dev_t *kbd_dev_new(void)
-{
-	kbd_dev_t *kdev = calloc(1, sizeof(kbd_dev_t));
-	if (kdev == NULL) {
-		printf("%s: Error allocating keyboard device. "
-		    "Out of memory.\n", NAME);
-		return NULL;
-	}
-	
-	link_initialize(&kdev->kbd_devs);
-	
-	kdev->mods = KM_NUM_LOCK;
-	kdev->lock_keys = 0;
-	kdev->active_layout = layout_create(layout[0]);
-	
-	return kdev;
-}
-
-static mouse_dev_t *mouse_dev_new(void)
-{
-	mouse_dev_t *mdev = calloc(1, sizeof(mouse_dev_t));
-	if (mdev == NULL) {
-		printf("%s: Error allocating keyboard device. "
-		    "Out of memory.\n", NAME);
-		return NULL;
-	}
-	
-	link_initialize(&mdev->mouse_devs);
-	
-	return mdev;
-}
-
-/** Add new legacy keyboard device. */
-static void kbd_add_dev(kbd_port_ops_t *port, kbd_ctl_ops_t *ctl)
-{
-	kbd_dev_t *kdev = kbd_dev_new();
-	if (kdev == NULL)
-		return;
-	
-	kdev->port_ops = port;
-	kdev->ctl_ops = ctl;
-	kdev->svc_id = 0;
-	
-	/* Initialize port driver. */
-	if ((*kdev->port_ops->init)(kdev) != 0)
-		goto fail;
-	
-	/* Initialize controller driver. */
-	if ((*kdev->ctl_ops->init)(kdev) != 0) {
-		/* XXX Uninit port */
-		goto fail;
-	}
-	
-	list_append(&kdev->kbd_devs, &kbd_devs);
-	return;
-	
-fail:
-	free(kdev);
-}
-
-/** Add new legacy mouse device. */
-static void mouse_add_dev(mouse_port_ops_t *port, mouse_proto_ops_t *proto)
-{
-	mouse_dev_t *mdev = mouse_dev_new();
-	if (mdev == NULL)
-		return;
-	
-	mdev->port_ops = port;
-	mdev->proto_ops = proto;
-	mdev->svc_id = 0;
-	
-	/* Initialize port driver. */
-	if ((*mdev->port_ops->init)(mdev) != 0)
-		goto fail;
-	
-	/* Initialize protocol driver. */
-	if ((*mdev->proto_ops->init)(mdev) != 0) {
-		/* XXX Uninit port */
-		goto fail;
-	}
-	
-	list_append(&mdev->mouse_devs, &mouse_devs);
-	return;
-	
-fail:
-	free(mdev);
-}
-
-/** Add new kbdev device.
- *
- * @param service_id	Service ID of the keyboard device
- *
- */
-static int kbd_add_kbdev(service_id_t service_id, kbd_dev_t **kdevp)
-{
-	kbd_dev_t *kdev = kbd_dev_new();
-	if (kdev == NULL)
-		return -1;
-	
-	kdev->svc_id = service_id;
-	kdev->port_ops = NULL;
-	kdev->ctl_ops = &kbdev_ctl;
-	
-	int rc = loc_service_get_name(service_id, &kdev->svc_name);
-	if (rc != EOK) {
-		kdev->svc_name = NULL;
-		goto fail;
-	}
-	
-	/* Initialize controller driver. */
-	if ((*kdev->ctl_ops->init)(kdev) != 0) {
-		goto fail;
-	}
-	
-	list_append(&kdev->kbd_devs, &kbd_devs);
-	*kdevp = kdev;
-	return EOK;
-	
-fail:
-	if (kdev->svc_name != NULL)
-		free(kdev->svc_name);
-	free(kdev);
-	return -1;
-}
-
-/** Add new mousedev device.
- *
- * @param service_id	Service ID of the mouse device
- *
- */
-static int mouse_add_mousedev(service_id_t service_id, mouse_dev_t **mdevp)
-{
-	mouse_dev_t *mdev = mouse_dev_new();
-	if (mdev == NULL)
-		return -1;
-	
-	mdev->svc_id = service_id;
-	mdev->port_ops = NULL;
-	mdev->proto_ops = &mousedev_proto;
-	
-	int rc = loc_service_get_name(service_id, &mdev->svc_name);
-	if (rc != EOK) {
-		mdev->svc_name = NULL;
-		goto fail;
-	}
-	
-	/* Initialize controller driver. */
-	if ((*mdev->proto_ops->init)(mdev) != 0) {
-		goto fail;
-	}
-	
-	list_append(&mdev->mouse_devs, &mouse_devs);
-	*mdevp = mdev;
-	return EOK;
-	
-fail:
-	free(mdev);
-	return -1;
-}
-
-/** Add legacy drivers/devices. */
-static void kbd_add_legacy_devs(void)
-{
-	/*
-	 * Need to add these drivers based on config unless we can probe
-	 * them automatically.
-	 */
-#if defined(UARCH_arm32) && defined(MACHINE_gta02)
-	kbd_add_dev(&chardev_port, &stty_ctl);
-#endif
-#if defined(UARCH_arm32) && defined(MACHINE_testarm) && defined(CONFIG_FB)
-	kbd_add_dev(&gxemul_port, &gxe_fb_ctl);
-#endif
-#if defined(UARCH_arm32) && defined(MACHINE_testarm) && !defined(CONFIG_FB)
-	kbd_add_dev(&gxemul_port, &stty_ctl);
-#endif
-#if defined(UARCH_arm32) && defined(MACHINE_integratorcp)
-	kbd_add_dev(&pl050_port, &pc_ctl);
-#endif
-#if defined(MACHINE_ski)
-	kbd_add_dev(&ski_port, &stty_ctl);
-#endif
-#if defined(MACHINE_msim)
-	kbd_add_dev(&msim_port, &stty_ctl);
-#endif
-#if (defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)) && defined(CONFIG_FB)
-	kbd_add_dev(&gxemul_port, &gxe_fb_ctl);
-#endif
-#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul) && !defined(CONFIG_FB)
-	kbd_add_dev(&gxemul_port, &stty_ctl);
-#endif
-#if defined(UARCH_ppc32)
-	kbd_add_dev(&adb_port, &apple_ctl);
-#endif
-#if defined(UARCH_sparc64) && defined(PROCESSOR_sun4v)
-	kbd_add_dev(&niagara_port, &stty_ctl);
-#endif
-#if defined(UARCH_sparc64) && defined(MACHINE_generic)
-	kbd_add_dev(&ns16550_port, &sun_ctl);
-#endif
-	/* Silence warning on abs32le about kbd_add_dev() being unused */
-	(void) kbd_add_dev;
-}
-
-/** Add legacy drivers/devices. */
-static void mouse_add_legacy_devs(void)
-{
-	/*
-	 * Need to add these drivers based on config unless we can probe
-	 * them automatically.
-	 */
-#if defined(UARCH_ppc32)
-	mouse_add_dev(&adb_mouse_port, &adb_proto);
-#endif
-	/* Silence warning on abs32le about mouse_add_dev() being unused */
-	(void) mouse_add_dev;
-}
-
-static void kbd_devs_yield(void)
-{
-	/* For each keyboard device */
-	list_foreach(kbd_devs, kdev_link) {
-		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
-		    kbd_devs);
-		
-		/* Yield port */
-		if (kdev->port_ops != NULL)
-			(*kdev->port_ops->yield)();
-	}
-}
-
-static void kbd_devs_reclaim(void)
-{
-	/* For each keyboard device */
-	list_foreach(kbd_devs, kdev_link) {
-		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
-		    kbd_devs);
-		
-		/* Reclaim port */
-		if (kdev->port_ops != NULL)
-			(*kdev->port_ops->reclaim)();
-	}
-}
-
-static int dev_check_new_kbdevs(void)
-{
-	category_id_t keyboard_cat;
-	service_id_t *svcs;
-	size_t count, i;
-	bool already_known;
-	int rc;
-	
-	rc = loc_category_get_id("keyboard", &keyboard_cat, IPC_FLAG_BLOCKING);
-	if (rc != EOK) {
-		printf("%s: Failed resolving category 'keyboard'.\n", NAME);
-		return ENOENT;
-	}
-	
-	/*
-	 * Check for new keyboard devices
-	 */
-	rc = loc_category_get_svcs(keyboard_cat, &svcs, &count);
-	if (rc != EOK) {
-		printf("%s: Failed getting list of keyboard devices.\n",
-		    NAME);
-		return EIO;
-	}
-
-	for (i = 0; i < count; i++) {
-		already_known = false;
-		
-		/* Determine whether we already know this device. */
-		list_foreach(kbd_devs, kdev_link) {
-			kbd_dev_t *kdev = list_get_instance(kdev_link,
-			    kbd_dev_t, kbd_devs);
-			if (kdev->svc_id == svcs[i]) {
-				already_known = true;
-				break;
-			}
-		}
-		
-		if (!already_known) {
-			kbd_dev_t *kdev;
-			if (kbd_add_kbdev(svcs[i], &kdev) == EOK) {
-				printf("%s: Connected keyboard device '%s'\n",
-				    NAME, kdev->svc_name);
-			}
-		}
-	}
-	
-	free(svcs);
-	
-	/* XXX Handle device removal */
-	
-	return EOK;
-}
-
-static int dev_check_new_mousedevs(void)
-{
-	category_id_t mouse_cat;
-	service_id_t *svcs;
-	size_t count, i;
-	bool already_known;
-	int rc;
-	
-	rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING);
-	if (rc != EOK) {
-		printf("%s: Failed resolving category 'mouse'.\n", NAME);
-		return ENOENT;
-	}
-	
-	/*
-	 * Check for new mouse devices
-	 */
-	rc = loc_category_get_svcs(mouse_cat, &svcs, &count);
-	if (rc != EOK) {
-		printf("%s: Failed getting list of mouse devices.\n",
-		    NAME);
-		return EIO;
-	}
-	
-	for (i = 0; i < count; i++) {
-		already_known = false;
-		
-		/* Determine whether we already know this device. */
-		list_foreach(mouse_devs, mdev_link) {
-			mouse_dev_t *mdev = list_get_instance(mdev_link,
-			    mouse_dev_t, mouse_devs);
-			if (mdev->svc_id == svcs[i]) {
-				already_known = true;
-				break;
-			}
-		}
-		
-		if (!already_known) {
-			mouse_dev_t *mdev;
-			if (mouse_add_mousedev(svcs[i], &mdev) == EOK) {
-				printf("%s: Connected mouse device '%s'\n",
-				    NAME, mdev->svc_name);
-			}
-		}
-	}
-	
-	free(svcs);
-	
-	/* XXX Handle device removal */
-	
-	return EOK;
-}
-
-static int dev_check_new(void)
-{
-	int rc;
-	
-	fibril_mutex_lock(&discovery_lock);
-	
-	rc = dev_check_new_kbdevs();
-	if (rc != EOK) {
-		fibril_mutex_unlock(&discovery_lock);
-		return rc;
-	}
-	
-	rc = dev_check_new_mousedevs();
-	if (rc != EOK) {
-		fibril_mutex_unlock(&discovery_lock);
-		return rc;
-	}
-	
-	fibril_mutex_unlock(&discovery_lock);
-	
-	return EOK;
-}
-
-static void cat_change_cb(void)
-{
-	dev_check_new();
-}
-
-/** Start listening for new devices. */
-static int input_start_dev_discovery(void)
-{
-	int rc;
-
-	rc = loc_register_cat_change_cb(cat_change_cb);
-	if (rc != EOK) {
-		printf("%s: Failed registering callback for device discovery. "
-		    "(%d)\n", NAME, rc);
-		return rc;
-	}
-
-	return dev_check_new();
-}
-
-int main(int argc, char **argv)
-{
-	printf("%s: HelenOS input service\n", NAME);
-	
-	sysarg_t obio;
-	
-	list_initialize(&kbd_devs);
-	list_initialize(&mouse_devs);
-	
-	if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))
-		irc_service = true;
-	
-	if (irc_service) {
-		while (irc_sess == NULL)
-			irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
-			    SERVICE_IRC, 0, 0);
-	}
-	
-	/* Add legacy keyboard devices. */
-	kbd_add_legacy_devs();
-	
-	/* Add legacy mouse devices. */
-	mouse_add_legacy_devs();
-	
-	/* Register driver */
-	async_set_client_connection(client_connection);
-	int rc = loc_server_register(NAME);
-	if (rc != EOK) {
-		printf("%s: Unable to register server\n", NAME);
-		return rc;
-	}
-	
-	char kbd[LOC_NAME_MAXLEN + 1];
-	snprintf(kbd, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);
-	
-	service_id_t service_id;
-	rc = loc_service_register(kbd, &service_id);
-	if (rc != EOK) {
-		printf("%s: Unable to register service %s\n", NAME, kbd);
-		return rc;
-	}
-	
-	/* Start looking for new input devices */
-	input_start_dev_discovery();
-	
-	printf("%s: Accepting connections\n", NAME);
-	async_manager();
-	
-	/* Not reached. */
-	return 0;
-}
-
-/**
- * @}
- */
Index: pace/srv/hid/input/generic/layout.c
===================================================================
--- uspace/srv/hid/input/generic/layout.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,78 +1,0 @@
-/*
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @addtogroup inputgen generic
- * @brief Keyboard layouts
- * @ingroup input
- * @{
- */
-/** @file
- */
-
-#include <errno.h>
-#include <input.h>
-#include <layout.h>
-#include <stdlib.h>
-
-/** Create a new layout instance. */
-layout_t *layout_create(layout_ops_t *ops)
-{
-	layout_t *layout;
-
-	layout = calloc(1, sizeof(layout_t));
-	if (layout == NULL) {
-		printf("%s: Out of memory.\n", NAME);
-		return NULL;
-	}
-
-	layout->ops = ops;
-	if ((*ops->create)(layout) != EOK) {
-		free(layout);
-		return NULL;
-	}
-
-	return layout;
-}
-
-/** Destroy layout instance. */
-void layout_destroy(layout_t *layout)
-{
-	(*layout->ops->destroy)(layout);
-	free(layout);
-}
-
-/** Parse keyboard event. */
-wchar_t layout_parse_ev(layout_t *layout, kbd_event_t *ev)
-{
-	return (*layout->ops->parse_ev)(layout, ev);
-}
-
-/**
- * @}
- */
Index: pace/srv/hid/input/generic/stroke.c
===================================================================
--- uspace/srv/hid/input/generic/stroke.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,85 +1,0 @@
-/*
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup input
- * @{
- */
-/**
- * @file
- * @brief Stroke simulator.
- *
- * When simulating a keyboard using a serial TTY we need to convert the
- * recognized strokes (such as Shift-A) to sequences of key presses and
- * releases (such as 'press Shift, press A, release A, release Shift').
- *
- */
-
-#include <stroke.h>
-#include <kbd.h>
-#include <io/console.h>
-#include <io/keycode.h>
-
-/** Correspondence between modifers and the modifier keycodes. */
-static unsigned int mods_keys[][2] = {
-	{ KM_LSHIFT, KC_LSHIFT },
-	{ 0, 0 }
-};
-
-/** Simulate keystroke using sequences of key presses and releases. */
-void stroke_sim(kbd_dev_t *kdev, unsigned mod, unsigned key)
-{
-	int i;
-
-	/* Simulate modifier presses. */
-	i = 0;
-	while (mods_keys[i][0] != 0) {
-		if (mod & mods_keys[i][0]) {
-			kbd_push_event(kdev, KEY_PRESS, mods_keys[i][1]);
-		}
-		++i;
-	}
-
-	/* Simulate key press and release. */
-	if (key != 0) {
-		kbd_push_event(kdev, KEY_PRESS, key);
-		kbd_push_event(kdev, KEY_RELEASE, key);
-	}
-
-	/* Simulate modifier releases. */
-	i = 0;
-	while (mods_keys[i][0] != 0) {
-		if (mod & mods_keys[i][0]) {
-			kbd_push_event(kdev, KEY_RELEASE, mods_keys[i][1]);
-		}
-		++i;
-	}
-}
-
-/**
- * @}
- */
Index: uspace/srv/hid/input/gsp.c
===================================================================
--- uspace/srv/hid/input/gsp.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/gsp.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup kbdgen generic
+ * @ingroup  input
+ * @{
+ */
+/** @file
+ * @brief Generic scancode parser.
+ *
+ * The scancode parser is a simple finite state machine. It is described
+ * using sequences of input symbols (scancodes) and the corresponding output
+ * value (mods, key pair). When the parser recognizes a sequence,
+ * it outputs the value and restarts. If a transition is undefined,
+ * the parser restarts, too.
+ *
+ * Apart from precise values, GSP_DEFAULT allows to catch general cases.
+ * I.e. if we knew that after 0x1b 0x4f there always follow two more
+ * scancodes, we can define (0x1b, 0x4f, GSP_DEFAULT, GSP_DEFAULT, GSP_END)
+ * with null output. This will force the parser to read the entire sequence,
+ * not leaving garbage on the input if it does not recognize the specific
+ * sequence.
+ */
+
+#include <adt/hash_table.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "gsp.h"
+
+#define TRANS_TABLE_CHAINS  256
+
+/*
+ * Hash table operations for the transition function.
+ */
+
+static hash_index_t trans_op_hash(unsigned long key[]);
+static int trans_op_compare(unsigned long key[], hash_count_t keys,
+    link_t *item);
+static void trans_op_remove_callback(link_t *item);
+
+static hash_table_operations_t trans_ops = {
+	.hash = trans_op_hash,
+	.compare = trans_op_compare,
+	.remove_callback = trans_op_remove_callback
+};
+
+static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input);
+static void trans_insert(gsp_t *p, gsp_trans_t *t);
+static gsp_trans_t *trans_new(void);
+
+/** Initialise scancode parser. */
+void gsp_init(gsp_t *p)
+{
+	p->states = 1;
+	hash_table_create(&p->trans, TRANS_TABLE_CHAINS, 2, &trans_ops);
+}
+
+/** Insert a series of definitions into the parser.
+ *
+ * @param p	The parser.
+ * @param defs	Definition list. Each definition starts with two output values
+ *		(mods, key) and continues with a sequence of input values
+ *		terminated with GSP_END. The definition list is terminated
+ *		with two zeroes (0, 0) for output values.
+ */
+int gsp_insert_defs(gsp_t *p, const int *defs)
+{
+	unsigned mods, key;
+	const int *dp;
+	int rc;
+
+	dp = defs;
+
+	while (1) {
+		/* Read the output values. */
+		mods = *dp++;
+		key = *dp++;
+		if (key == 0) break;
+
+		/* Insert one sequence. */
+		rc = gsp_insert_seq(p, dp, mods, key);
+		if (rc != 0)
+			return rc;
+
+		/* Skip to the next definition. */
+		while (*dp != GSP_END)
+			++dp;
+		++dp;
+	}
+
+	return 0;
+}
+
+/** Insert one sequence into the parser.
+ *
+ * @param p	The parser.
+ * @param seq	Sequence of input values terminated with GSP_END.
+ * @param mods	Corresponsing output value.
+ * @param key	Corresponsing output value.
+ */
+int gsp_insert_seq(gsp_t *p, const int *seq, unsigned mods, unsigned key)
+{
+	int state;
+	gsp_trans_t *t;
+
+	state = 0;
+	t = NULL;
+
+	/* Input sequence must be non-empty. */
+	if (*seq == GSP_END)
+		return -1;
+
+	while (*(seq + 1) != GSP_END) {
+		t = trans_lookup(p, state, *seq);
+		if (t == NULL) {
+			/* Create new state. */
+			t = trans_new();
+			t->old_state = state;
+			t->input = *seq;
+			t->new_state = p->states++;
+
+			t->out_mods = 0;
+			t->out_key = 0;
+
+			trans_insert(p, t);
+		}
+		state = t->new_state;
+		++seq;
+	}
+
+	/* Process the last transition. */
+	t = trans_lookup(p, state, *seq);
+	if (t != NULL) {
+		exit(1);
+		return -1;	/* Conflicting definition. */
+	}
+
+	t = trans_new();
+	t->old_state = state;
+	t->input = *seq;
+	t->new_state = 0;
+
+	t->out_mods = mods;
+	t->out_key = key;
+
+	trans_insert(p, t);
+
+	return 0;
+}
+
+/** Compute one parser step.
+ *
+ * Computes the next state and output values for a given state and input.
+ * This handles everything including restarts and default branches.
+ *
+ * @param p		The parser.
+ * @param state		Old state.
+ * @param input		Input symbol (scancode).
+ * @param mods		Output value (modifier).
+ * @param key		Output value (key).
+ * @return		New state.
+ */
+int gsp_step(gsp_t *p, int state, int input, unsigned *mods, unsigned *key)
+{
+	gsp_trans_t *t;
+
+	t = trans_lookup(p, state, input);
+	if (t == NULL) {
+		t = trans_lookup(p, state, GSP_DEFAULT);
+	}
+
+	if (t == NULL) {
+		printf("gsp_step: not found, state=%d, input=0x%x\n",
+		    state, input);
+		*mods = 0;
+		*key = 0;
+		return 0;
+	}
+
+	*mods = t->out_mods;
+	*key = t->out_key;
+
+	return t->new_state;
+}
+
+/** Transition function lookup.
+ *
+ * Returns the value of the transition function for the given state
+ * and input. Note that the transition must be specified precisely,
+ * to obtain the default branch use input = GSP_DEFAULT.
+ *
+ * @param p		Parser.
+ * @param state		Current state.
+ * @param input		Input value.
+ * @return		The transition or @c NULL if not defined.
+ */
+static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input)
+{
+	link_t *item;
+	unsigned long key[2];
+
+	key[0] = state;
+	key[1] = input;
+
+	item = hash_table_find(&p->trans, key);
+	if (item == NULL) return NULL;
+
+	return hash_table_get_instance(item, gsp_trans_t, link);
+}
+
+/** Define a new transition.
+ *
+ * @param p	The parser.
+ * @param t	Transition with all fields defined.
+ */
+static void trans_insert(gsp_t *p, gsp_trans_t *t)
+{
+	unsigned long key[2];
+
+	key[0] = t->old_state;
+	key[1] = t->input;
+
+	hash_table_insert(&p->trans, key, &t->link);
+}
+
+/** Allocate transition structure. */
+static gsp_trans_t *trans_new(void)
+{
+	gsp_trans_t *t;
+
+	t = malloc(sizeof(gsp_trans_t));
+	if (t == NULL) {
+		printf("Memory allocation failed.\n");
+		exit(1);
+	}
+
+	return t;
+}
+
+/*
+ * Transition function hash table operations.
+ */
+
+static hash_index_t trans_op_hash(unsigned long key[])
+{
+	return (key[0] * 17 + key[1]) % TRANS_TABLE_CHAINS;
+}
+
+static int trans_op_compare(unsigned long key[], hash_count_t keys,
+    link_t *item)
+{
+	gsp_trans_t *t;
+
+	t = hash_table_get_instance(item, gsp_trans_t, link);
+	return ((key[0] == (unsigned long) t->old_state)
+	    && (key[1] == (unsigned long) t->input));
+}
+
+static void trans_op_remove_callback(link_t *item)
+{
+}
+
+/**
+ * @}
+ */ 
Index: uspace/srv/hid/input/gsp.h
===================================================================
--- uspace/srv/hid/input/gsp.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/gsp.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup inputgen generic
+ * @brief	Generic scancode parser.
+ * @ingroup  input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_GSP_H_
+#define KBD_GSP_H_
+
+#include <adt/hash_table.h>
+
+enum {
+	GSP_END		= -1,	/**< Terminates a sequence. */
+	GSP_DEFAULT	= -2	/**< Wildcard, catches unhandled cases. */
+};
+
+/** Scancode parser description */
+typedef struct {
+	/** Transition table, (state, input) -> (state, output) */
+	hash_table_t trans;
+
+	/** Number of states */
+	int states;
+} gsp_t;
+
+/** Scancode parser transition. */
+typedef struct {
+	link_t link;		/**< Link to hash table in @c gsp_t */ 
+
+	/* Preconditions */
+
+	int old_state;		/**< State before transition */
+	int input;		/**< Input symbol (scancode) */
+
+	/* Effects */
+
+	int new_state;		/**< State after transition */
+
+	/* Output emitted during transition */
+
+	unsigned out_mods;	/**< Modifier to emit */
+	unsigned out_key;	/**< Keycode to emit */
+} gsp_trans_t;
+
+extern void gsp_init(gsp_t *);
+extern int gsp_insert_defs(gsp_t *, const int *);
+extern int gsp_insert_seq(gsp_t *, const int *, unsigned, unsigned);
+extern int gsp_step(gsp_t *, int, int, unsigned *, unsigned *);
+
+#endif
+
+/**
+ * @}
+ */ 
Index: pace/srv/hid/input/include/gsp.h
===================================================================
--- uspace/srv/hid/input/include/gsp.h	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,84 +1,0 @@
-/*
- * Copyright (c) 2009 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inputgen generic
- * @brief	Generic scancode parser.
- * @ingroup  input
- * @{
- */
-/** @file
- */
-
-#ifndef KBD_GSP_H_
-#define KBD_GSP_H_
-
-#include <adt/hash_table.h>
-
-enum {
-	GSP_END		= -1,	/**< Terminates a sequence. */
-	GSP_DEFAULT	= -2	/**< Wildcard, catches unhandled cases. */
-};
-
-/** Scancode parser description */
-typedef struct {
-	/** Transition table, (state, input) -> (state, output) */
-	hash_table_t trans;
-
-	/** Number of states */
-	int states;
-} gsp_t;
-
-/** Scancode parser transition. */
-typedef struct {
-	link_t link;		/**< Link to hash table in @c gsp_t */ 
-
-	/* Preconditions */
-
-	int old_state;		/**< State before transition */
-	int input;		/**< Input symbol (scancode) */
-
-	/* Effects */
-
-	int new_state;		/**< State after transition */
-
-	/* Output emitted during transition */
-
-	unsigned out_mods;	/**< Modifier to emit */
-	unsigned out_key;	/**< Keycode to emit */
-} gsp_trans_t;
-
-extern void gsp_init(gsp_t *);
-extern int gsp_insert_defs(gsp_t *, const int *);
-extern int gsp_insert_seq(gsp_t *, const int *, unsigned, unsigned);
-extern int gsp_step(gsp_t *, int, int, unsigned *, unsigned *);
-
-#endif
-
-/**
- * @}
- */ 
Index: pace/srv/hid/input/include/input.h
===================================================================
--- uspace/srv/hid/input/include/input.h	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inputgen generic
- * @brief HelenOS input server.
- * @ingroup input
- * @{
- */
-/** @file
- */
-
-#ifndef INPUT_H_
-#define INPUT_H_
-
-#include <bool.h>
-#include <async.h>
-
-#define NAME       "input"
-#define NAMESPACE  "hid"
-
-extern bool irc_service;
-extern async_sess_t *irc_sess;
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/input/include/kbd.h
===================================================================
--- uspace/srv/hid/input/include/kbd.h	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,84 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inputgen generic
- * @brief HelenOS input server.
- * @ingroup input
- * @{
- */
-/** @file
- */
-
-#ifndef KBD_KBD_H_
-#define KBD_KBD_H_
-
-#include <adt/list.h>
-#include <ipc/loc.h>
-
-struct kbd_port_ops;
-struct kbd_ctl_ops;
-struct layout;
-
-typedef struct kbd_dev {
-	/** Link to kbd_devs list */
-	link_t kbd_devs;
-
-	/** Service ID (only for kbdev devices) */
-	service_id_t svc_id;
-
-	/** Device service name (only for kbdev devices) */
-	char *svc_name;
-
-	/** Port ops */
-	struct kbd_port_ops *port_ops;
-
-	/** Ctl ops */
-	struct kbd_ctl_ops *ctl_ops;
-
-	/** Controller-private data */
-	void *ctl_private;
-
-	/** Currently active modifiers. */
-	unsigned mods;
-
-	/** Currently pressed lock keys. We track these to tackle autorepeat. */
-	unsigned lock_keys;
-
-	/** Active keyboard layout */
-	struct layout *active_layout;
-} kbd_dev_t;
-
-extern void kbd_push_data(kbd_dev_t *, sysarg_t);
-extern void kbd_push_event(kbd_dev_t *, int, unsigned int);
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/input/include/kbd_ctl.h
===================================================================
--- uspace/srv/hid/input/include/kbd_ctl.h	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,61 +1,0 @@
-/*
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inputgen generic
- * @brief Keyboard controller driver interface.
- * @ingroup input
- * @{
- */
-/** @file
- */
-
-#ifndef KBD_CTL_H_
-#define KBD_CTL_H_
-
-#include <kbd_port.h>
-
-struct kbd_dev;
-
-typedef struct kbd_ctl_ops {
-	void (*parse)(sysarg_t);
-	int (*init)(struct kbd_dev *);
-	void (*set_ind)(struct kbd_dev *, unsigned int);
-} kbd_ctl_ops_t;
-
-extern kbd_ctl_ops_t apple_ctl;
-extern kbd_ctl_ops_t gxe_fb_ctl;
-extern kbd_ctl_ops_t kbdev_ctl;
-extern kbd_ctl_ops_t pc_ctl;
-extern kbd_ctl_ops_t stty_ctl;
-extern kbd_ctl_ops_t sun_ctl;
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/input/include/kbd_port.h
===================================================================
--- uspace/srv/hid/input/include/kbd_port.h	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,64 +1,0 @@
-/*
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inputgen generic
- * @brief Keyboard port driver interface.
- * @ingroup input
- * @{
- */
-/** @file
- */
-
-#ifndef KBD_PORT_H_
-#define KBD_PORT_H_
-
-#include <sys/types.h>
-
-struct kbd_dev;
-
-typedef struct kbd_port_ops {
-	int (*init)(struct kbd_dev *);
-	void (*yield)(void);
-	void (*reclaim)(void);
-	void (*write)(uint8_t);
-} kbd_port_ops_t;
-
-extern kbd_port_ops_t adb_port;
-extern kbd_port_ops_t chardev_port;
-extern kbd_port_ops_t gxemul_port;
-extern kbd_port_ops_t msim_port;
-extern kbd_port_ops_t niagara_port;
-extern kbd_port_ops_t ns16550_port;
-extern kbd_port_ops_t pl050_port;
-extern kbd_port_ops_t ski_port;
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/input/include/layout.h
===================================================================
--- uspace/srv/hid/input/include/layout.h	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,71 +1,0 @@
-/*
- * Copyright (c) 2009 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inputgen generic
- * @brief Keyboard layout interface.
- * @ingroup input
- * @{
- */
-/** @file
- */
-
-#ifndef KBD_LAYOUT_H_
-#define KBD_LAYOUT_H_
-
-#include <sys/types.h>
-#include <io/console.h>
-
-/** Layout instance state */
-typedef struct layout {
-	/** Ops structure */
-	struct layout_ops *ops;
-
-	/* Layout-private data */
-	void *layout_priv;
-} layout_t;
-
-/** Layout ops */
-typedef struct layout_ops {
-	int (*create)(layout_t *);
-	void (*destroy)(layout_t *);
-	wchar_t (*parse_ev)(layout_t *, kbd_event_t *);
-} layout_ops_t;
-
-extern layout_ops_t us_qwerty_ops;
-extern layout_ops_t us_dvorak_ops;
-extern layout_ops_t cz_ops;
-
-extern layout_t *layout_create(layout_ops_t *);
-extern void layout_destroy(layout_t *);
-extern wchar_t layout_parse_ev(layout_t *, kbd_event_t *);
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/input/include/mouse.h
===================================================================
--- uspace/srv/hid/input/include/mouse.h	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,73 +1,0 @@
-/*
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inputgen generic
- * @brief Mouse device handling.
- * @ingroup input
- * @{
- */
-/** @file
- */
-
-#ifndef MOUSE_H_
-#define MOUSE_H_
-
-#include <adt/list.h>
-#include <ipc/loc.h>
-
-struct mouse_port_ops;
-struct mouse_proto_ops;
-
-typedef struct mouse_dev {
-	/** Link to mouse_devs list */
-	link_t mouse_devs;
-	
-	/** Service ID (only for mousedev devices) */
-	service_id_t svc_id;
-	
-	/** Device service name (only for mousedev devices) */
-	char *svc_name;
-	
-	/** Port ops */
-	struct mouse_port_ops *port_ops;
-	
-	/** Protocol ops */
-	struct mouse_proto_ops *proto_ops;
-} mouse_dev_t;
-
-extern void mouse_push_data(mouse_dev_t *, sysarg_t);
-extern void mouse_push_event_move(mouse_dev_t *, int, int, int);
-extern void mouse_push_event_abs_move(mouse_dev_t *, unsigned int, unsigned int,
-    unsigned int, unsigned int);
-extern void mouse_push_event_button(mouse_dev_t *, int, int);
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/input/include/mouse_port.h
===================================================================
--- uspace/srv/hid/input/include/mouse_port.h	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inputgen generic
- * @brief Mouse port driver interface.
- * @ingroup input
- * @{
- */
-/** @file
- */
-
-#ifndef MOUSE_PORT_H_
-#define MOUSE_PORT_H_
-
-#include <sys/types.h>
-
-struct mouse_dev;
-
-typedef struct mouse_port_ops {
-	int (*init)(struct mouse_dev *);
-	void (*yield)(void);
-	void (*reclaim)(void);
-	void (*write)(uint8_t);
-} mouse_port_ops_t;
-
-extern mouse_port_ops_t adb_mouse_port;
-extern mouse_port_ops_t chardev_mouse_port;
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/input/include/mouse_proto.h
===================================================================
--- uspace/srv/hid/input/include/mouse_proto.h	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inputgen generic
- * @brief Mouse protocol driver interface.
- * @ingroup input
- * @{
- */
-/** @file
- */
-
-#ifndef MOUSE_PROTO_H_
-#define MOUSE_PROTO_H_
-
-#include <mouse_port.h>
-
-struct mouse_dev;
-
-typedef struct mouse_proto_ops {
-	void (*parse)(sysarg_t);
-	int (*init)(struct mouse_dev *);
-} mouse_proto_ops_t;
-
-extern mouse_proto_ops_t adb_proto;
-extern mouse_proto_ops_t mousedev_proto;
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/hid/input/include/stroke.h
===================================================================
--- uspace/srv/hid/input/include/stroke.h	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inputgen generic
- * @brief	Generic scancode parser.
- * @ingroup  input
- * @{
- */ 
-/** @file
- */
-
-#ifndef KBD_STROKE_H_
-#define KBD_STROKE_H_
-
-#include <kbd.h>
-
-extern void stroke_sim(kbd_dev_t *, unsigned, unsigned);
-
-#endif
-
-/**
- * @}
- */ 
-
Index: uspace/srv/hid/input/input.c
===================================================================
--- uspace/srv/hid/input/input.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/input.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,713 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup inputgen generic
+ * @brief HelenOS input server.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#include <adt/list.h>
+#include <bool.h>
+#include <fibril_synch.h>
+#include <ipc/services.h>
+#include <ipc/input.h>
+#include <sysinfo.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ns.h>
+#include <async.h>
+#include <errno.h>
+#include <adt/fifo.h>
+#include <io/console.h>
+#include <io/keycode.h>
+#include <loc.h>
+#include "layout.h"
+#include "kbd.h"
+#include "kbd_port.h"
+#include "kbd_ctl.h"
+#include "mouse.h"
+#include "mouse_proto.h"
+#include "input.h"
+
+#define NUM_LAYOUTS  3
+
+static layout_ops_t *layout[NUM_LAYOUTS] = {
+	&us_qwerty_ops,
+	&us_dvorak_ops,
+	&cz_ops
+};
+
+static void kbd_devs_yield(void);
+static void kbd_devs_reclaim(void);
+
+async_sess_t *client_sess = NULL;
+
+/** List of keyboard devices */
+static list_t kbd_devs;
+
+/** List of mouse devices */
+static list_t mouse_devs;
+
+bool irc_service = false;
+async_sess_t *irc_sess = NULL;
+
+static FIBRIL_MUTEX_INITIALIZE(discovery_lock);
+
+void kbd_push_data(kbd_dev_t *kdev, sysarg_t data)
+{
+	(*kdev->ctl_ops->parse)(data);
+}
+
+void mouse_push_data(mouse_dev_t *mdev, sysarg_t data)
+{
+	(*mdev->proto_ops->parse)(data);
+}
+
+void kbd_push_event(kbd_dev_t *kdev, int type, unsigned int key)
+{
+	kbd_event_t ev;
+	unsigned int mod_mask;
+	
+	switch (key) {
+	case KC_LCTRL: mod_mask = KM_LCTRL; break;
+	case KC_RCTRL: mod_mask = KM_RCTRL; break;
+	case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
+	case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
+	case KC_LALT: mod_mask = KM_LALT; break;
+	case KC_RALT: mod_mask = KM_RALT; break;
+	default: mod_mask = 0; break;
+	}
+	
+	if (mod_mask != 0) {
+		if (type == KEY_PRESS)
+			kdev->mods = kdev->mods | mod_mask;
+		else
+			kdev->mods = kdev->mods & ~mod_mask;
+	}
+	
+	switch (key) {
+	case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
+	case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
+	case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
+	default: mod_mask = 0; break;
+	}
+	
+	if (mod_mask != 0) {
+		if (type == KEY_PRESS) {
+			/*
+			 * Only change lock state on transition from released
+			 * to pressed. This prevents autorepeat from messing
+			 * up the lock state.
+			 */
+			kdev->mods = kdev->mods ^ (mod_mask & ~kdev->lock_keys);
+			kdev->lock_keys = kdev->lock_keys | mod_mask;
+			
+			/* Update keyboard lock indicator lights. */
+			(*kdev->ctl_ops->set_ind)(kdev, kdev->mods);
+		} else {
+			kdev->lock_keys = kdev->lock_keys & ~mod_mask;
+		}
+	}
+	
+	if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
+	    key == KC_F1) {
+		layout_destroy(kdev->active_layout);
+		kdev->active_layout = layout_create(layout[0]);
+		return;
+	}
+	
+	if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
+	    key == KC_F2) {
+		layout_destroy(kdev->active_layout);
+		kdev->active_layout = layout_create(layout[1]);
+		return;
+	}
+	
+	if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
+	    key == KC_F3) {
+		layout_destroy(kdev->active_layout);
+		kdev->active_layout = layout_create(layout[2]);
+		return;
+	}
+	
+	ev.type = type;
+	ev.key = key;
+	ev.mods = kdev->mods;
+	
+	ev.c = layout_parse_ev(kdev->active_layout, &ev);
+	
+	async_exch_t *exch = async_exchange_begin(client_sess);
+	async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c);
+	async_exchange_end(exch);
+}
+
+/** Mouse pointer has moved. */
+void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy, int dz)
+{
+	async_exch_t *exch = async_exchange_begin(client_sess);
+	if (dx || dy)
+		async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy);
+	if (dz) {
+		// TODO: Implement proper wheel support
+		keycode_t code = dz > 0 ? KC_UP : KC_DOWN;
+		for (int i = 0; i < 3; ++i) {
+			async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0);
+		}
+		async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0);
+	}
+	async_exchange_end(exch);
+}
+
+/** Mouse pointer has moved in absolute mode. */
+void mouse_push_event_abs_move(mouse_dev_t *mdev, unsigned int x, unsigned int y,
+    unsigned int max_x, unsigned int max_y)
+{
+	if (max_x && max_y) {
+		async_exch_t *exch = async_exchange_begin(client_sess);
+		async_msg_4(exch, INPUT_EVENT_ABS_MOVE, x, y, max_x, max_y);
+		async_exchange_end(exch);
+	}
+}
+
+/** Mouse button has been pressed. */
+void mouse_push_event_button(mouse_dev_t *mdev, int bnum, int press)
+{
+	async_exch_t *exch = async_exchange_begin(client_sess);
+	async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press);
+	async_exchange_end(exch);
+}
+
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	async_answer_0(iid, EOK);
+	
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call)) {
+			if (client_sess != NULL) {
+				async_hangup(client_sess);
+				client_sess = NULL;
+			}
+			
+			async_answer_0(callid, EOK);
+			return;
+		}
+		
+		async_sess_t *sess =
+		    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
+		if (sess != NULL) {
+			if (client_sess == NULL) {
+				client_sess = sess;
+				async_answer_0(callid, EOK);
+			} else
+				async_answer_0(callid, ELIMIT);
+		} else {
+			switch (IPC_GET_IMETHOD(call)) {
+			case INPUT_YIELD:
+				kbd_devs_yield();
+				async_answer_0(callid, EOK);
+				break;
+			case INPUT_RECLAIM:
+				kbd_devs_reclaim();
+				async_answer_0(callid, EOK);
+				break;
+			default:
+				async_answer_0(callid, EINVAL);
+			}
+		}
+	}
+}
+
+static kbd_dev_t *kbd_dev_new(void)
+{
+	kbd_dev_t *kdev = calloc(1, sizeof(kbd_dev_t));
+	if (kdev == NULL) {
+		printf("%s: Error allocating keyboard device. "
+		    "Out of memory.\n", NAME);
+		return NULL;
+	}
+	
+	link_initialize(&kdev->kbd_devs);
+	
+	kdev->mods = KM_NUM_LOCK;
+	kdev->lock_keys = 0;
+	kdev->active_layout = layout_create(layout[0]);
+	
+	return kdev;
+}
+
+static mouse_dev_t *mouse_dev_new(void)
+{
+	mouse_dev_t *mdev = calloc(1, sizeof(mouse_dev_t));
+	if (mdev == NULL) {
+		printf("%s: Error allocating keyboard device. "
+		    "Out of memory.\n", NAME);
+		return NULL;
+	}
+	
+	link_initialize(&mdev->mouse_devs);
+	
+	return mdev;
+}
+
+/** Add new legacy keyboard device. */
+static void kbd_add_dev(kbd_port_ops_t *port, kbd_ctl_ops_t *ctl)
+{
+	kbd_dev_t *kdev = kbd_dev_new();
+	if (kdev == NULL)
+		return;
+	
+	kdev->port_ops = port;
+	kdev->ctl_ops = ctl;
+	kdev->svc_id = 0;
+	
+	/* Initialize port driver. */
+	if ((*kdev->port_ops->init)(kdev) != 0)
+		goto fail;
+	
+	/* Initialize controller driver. */
+	if ((*kdev->ctl_ops->init)(kdev) != 0) {
+		/* XXX Uninit port */
+		goto fail;
+	}
+	
+	list_append(&kdev->kbd_devs, &kbd_devs);
+	return;
+	
+fail:
+	free(kdev);
+}
+
+/** Add new legacy mouse device. */
+static void mouse_add_dev(mouse_port_ops_t *port, mouse_proto_ops_t *proto)
+{
+	mouse_dev_t *mdev = mouse_dev_new();
+	if (mdev == NULL)
+		return;
+	
+	mdev->port_ops = port;
+	mdev->proto_ops = proto;
+	mdev->svc_id = 0;
+	
+	/* Initialize port driver. */
+	if ((*mdev->port_ops->init)(mdev) != 0)
+		goto fail;
+	
+	/* Initialize protocol driver. */
+	if ((*mdev->proto_ops->init)(mdev) != 0) {
+		/* XXX Uninit port */
+		goto fail;
+	}
+	
+	list_append(&mdev->mouse_devs, &mouse_devs);
+	return;
+	
+fail:
+	free(mdev);
+}
+
+/** Add new kbdev device.
+ *
+ * @param service_id	Service ID of the keyboard device
+ *
+ */
+static int kbd_add_kbdev(service_id_t service_id, kbd_dev_t **kdevp)
+{
+	kbd_dev_t *kdev = kbd_dev_new();
+	if (kdev == NULL)
+		return -1;
+	
+	kdev->svc_id = service_id;
+	kdev->port_ops = NULL;
+	kdev->ctl_ops = &kbdev_ctl;
+	
+	int rc = loc_service_get_name(service_id, &kdev->svc_name);
+	if (rc != EOK) {
+		kdev->svc_name = NULL;
+		goto fail;
+	}
+	
+	/* Initialize controller driver. */
+	if ((*kdev->ctl_ops->init)(kdev) != 0) {
+		goto fail;
+	}
+	
+	list_append(&kdev->kbd_devs, &kbd_devs);
+	*kdevp = kdev;
+	return EOK;
+	
+fail:
+	if (kdev->svc_name != NULL)
+		free(kdev->svc_name);
+	free(kdev);
+	return -1;
+}
+
+/** Add new mousedev device.
+ *
+ * @param service_id	Service ID of the mouse device
+ *
+ */
+static int mouse_add_mousedev(service_id_t service_id, mouse_dev_t **mdevp)
+{
+	mouse_dev_t *mdev = mouse_dev_new();
+	if (mdev == NULL)
+		return -1;
+	
+	mdev->svc_id = service_id;
+	mdev->port_ops = NULL;
+	mdev->proto_ops = &mousedev_proto;
+	
+	int rc = loc_service_get_name(service_id, &mdev->svc_name);
+	if (rc != EOK) {
+		mdev->svc_name = NULL;
+		goto fail;
+	}
+	
+	/* Initialize controller driver. */
+	if ((*mdev->proto_ops->init)(mdev) != 0) {
+		goto fail;
+	}
+	
+	list_append(&mdev->mouse_devs, &mouse_devs);
+	*mdevp = mdev;
+	return EOK;
+	
+fail:
+	free(mdev);
+	return -1;
+}
+
+/** Add legacy drivers/devices. */
+static void kbd_add_legacy_devs(void)
+{
+	/*
+	 * Need to add these drivers based on config unless we can probe
+	 * them automatically.
+	 */
+#if defined(UARCH_arm32) && defined(MACHINE_gta02)
+	kbd_add_dev(&chardev_port, &stty_ctl);
+#endif
+#if defined(UARCH_arm32) && defined(MACHINE_testarm) && defined(CONFIG_FB)
+	kbd_add_dev(&gxemul_port, &gxe_fb_ctl);
+#endif
+#if defined(UARCH_arm32) && defined(MACHINE_testarm) && !defined(CONFIG_FB)
+	kbd_add_dev(&gxemul_port, &stty_ctl);
+#endif
+#if defined(UARCH_arm32) && defined(MACHINE_integratorcp)
+	kbd_add_dev(&pl050_port, &pc_ctl);
+#endif
+#if defined(MACHINE_ski)
+	kbd_add_dev(&ski_port, &stty_ctl);
+#endif
+#if defined(MACHINE_msim)
+	kbd_add_dev(&msim_port, &stty_ctl);
+#endif
+#if (defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)) && defined(CONFIG_FB)
+	kbd_add_dev(&gxemul_port, &gxe_fb_ctl);
+#endif
+#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul) && !defined(CONFIG_FB)
+	kbd_add_dev(&gxemul_port, &stty_ctl);
+#endif
+#if defined(UARCH_ppc32)
+	kbd_add_dev(&adb_port, &apple_ctl);
+#endif
+#if defined(UARCH_sparc64) && defined(PROCESSOR_sun4v)
+	kbd_add_dev(&niagara_port, &stty_ctl);
+#endif
+#if defined(UARCH_sparc64) && defined(MACHINE_generic)
+	kbd_add_dev(&ns16550_port, &sun_ctl);
+#endif
+	/* Silence warning on abs32le about kbd_add_dev() being unused */
+	(void) kbd_add_dev;
+}
+
+/** Add legacy drivers/devices. */
+static void mouse_add_legacy_devs(void)
+{
+	/*
+	 * Need to add these drivers based on config unless we can probe
+	 * them automatically.
+	 */
+#if defined(UARCH_ppc32)
+	mouse_add_dev(&adb_mouse_port, &adb_proto);
+#endif
+	/* Silence warning on abs32le about mouse_add_dev() being unused */
+	(void) mouse_add_dev;
+}
+
+static void kbd_devs_yield(void)
+{
+	/* For each keyboard device */
+	list_foreach(kbd_devs, kdev_link) {
+		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
+		    kbd_devs);
+		
+		/* Yield port */
+		if (kdev->port_ops != NULL)
+			(*kdev->port_ops->yield)();
+	}
+}
+
+static void kbd_devs_reclaim(void)
+{
+	/* For each keyboard device */
+	list_foreach(kbd_devs, kdev_link) {
+		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
+		    kbd_devs);
+		
+		/* Reclaim port */
+		if (kdev->port_ops != NULL)
+			(*kdev->port_ops->reclaim)();
+	}
+}
+
+static int dev_check_new_kbdevs(void)
+{
+	category_id_t keyboard_cat;
+	service_id_t *svcs;
+	size_t count, i;
+	bool already_known;
+	int rc;
+	
+	rc = loc_category_get_id("keyboard", &keyboard_cat, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("%s: Failed resolving category 'keyboard'.\n", NAME);
+		return ENOENT;
+	}
+	
+	/*
+	 * Check for new keyboard devices
+	 */
+	rc = loc_category_get_svcs(keyboard_cat, &svcs, &count);
+	if (rc != EOK) {
+		printf("%s: Failed getting list of keyboard devices.\n",
+		    NAME);
+		return EIO;
+	}
+
+	for (i = 0; i < count; i++) {
+		already_known = false;
+		
+		/* Determine whether we already know this device. */
+		list_foreach(kbd_devs, kdev_link) {
+			kbd_dev_t *kdev = list_get_instance(kdev_link,
+			    kbd_dev_t, kbd_devs);
+			if (kdev->svc_id == svcs[i]) {
+				already_known = true;
+				break;
+			}
+		}
+		
+		if (!already_known) {
+			kbd_dev_t *kdev;
+			if (kbd_add_kbdev(svcs[i], &kdev) == EOK) {
+				printf("%s: Connected keyboard device '%s'\n",
+				    NAME, kdev->svc_name);
+			}
+		}
+	}
+	
+	free(svcs);
+	
+	/* XXX Handle device removal */
+	
+	return EOK;
+}
+
+static int dev_check_new_mousedevs(void)
+{
+	category_id_t mouse_cat;
+	service_id_t *svcs;
+	size_t count, i;
+	bool already_known;
+	int rc;
+	
+	rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		printf("%s: Failed resolving category 'mouse'.\n", NAME);
+		return ENOENT;
+	}
+	
+	/*
+	 * Check for new mouse devices
+	 */
+	rc = loc_category_get_svcs(mouse_cat, &svcs, &count);
+	if (rc != EOK) {
+		printf("%s: Failed getting list of mouse devices.\n",
+		    NAME);
+		return EIO;
+	}
+	
+	for (i = 0; i < count; i++) {
+		already_known = false;
+		
+		/* Determine whether we already know this device. */
+		list_foreach(mouse_devs, mdev_link) {
+			mouse_dev_t *mdev = list_get_instance(mdev_link,
+			    mouse_dev_t, mouse_devs);
+			if (mdev->svc_id == svcs[i]) {
+				already_known = true;
+				break;
+			}
+		}
+		
+		if (!already_known) {
+			mouse_dev_t *mdev;
+			if (mouse_add_mousedev(svcs[i], &mdev) == EOK) {
+				printf("%s: Connected mouse device '%s'\n",
+				    NAME, mdev->svc_name);
+			}
+		}
+	}
+	
+	free(svcs);
+	
+	/* XXX Handle device removal */
+	
+	return EOK;
+}
+
+static int dev_check_new(void)
+{
+	int rc;
+	
+	fibril_mutex_lock(&discovery_lock);
+	
+	rc = dev_check_new_kbdevs();
+	if (rc != EOK) {
+		fibril_mutex_unlock(&discovery_lock);
+		return rc;
+	}
+	
+	rc = dev_check_new_mousedevs();
+	if (rc != EOK) {
+		fibril_mutex_unlock(&discovery_lock);
+		return rc;
+	}
+	
+	fibril_mutex_unlock(&discovery_lock);
+	
+	return EOK;
+}
+
+static void cat_change_cb(void)
+{
+	dev_check_new();
+}
+
+/** Start listening for new devices. */
+static int input_start_dev_discovery(void)
+{
+	int rc;
+
+	rc = loc_register_cat_change_cb(cat_change_cb);
+	if (rc != EOK) {
+		printf("%s: Failed registering callback for device discovery. "
+		    "(%d)\n", NAME, rc);
+		return rc;
+	}
+
+	return dev_check_new();
+}
+
+static void usage(char *name)
+{
+	printf("Usage: %s <service_name>\n", name);
+}
+
+int main(int argc, char **argv)
+{
+	if (argc < 2) {
+		usage(argv[0]);
+		return 1;
+	}
+	
+	printf("%s: HelenOS input service\n", NAME);
+	
+	sysarg_t obio;
+	
+	list_initialize(&kbd_devs);
+	list_initialize(&mouse_devs);
+	
+	if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))
+		irc_service = true;
+	
+	if (irc_service) {
+		while (irc_sess == NULL)
+			irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
+			    SERVICE_IRC, 0, 0);
+	}
+	
+	/* Add legacy keyboard devices. */
+	kbd_add_legacy_devs();
+	
+	/* Add legacy mouse devices. */
+	mouse_add_legacy_devs();
+	
+	/* Register driver */
+	async_set_client_connection(client_connection);
+	int rc = loc_server_register(NAME);
+	if (rc != EOK) {
+		printf("%s: Unable to register server\n", NAME);
+		return rc;
+	}
+	
+	char kbd[LOC_NAME_MAXLEN + 1];
+	snprintf(kbd, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);
+	
+	service_id_t service_id;
+	rc = loc_service_register(argv[1], &service_id);
+	if (rc != EOK) {
+		printf("%s: Unable to register service %s\n", NAME, argv[1]);
+		return rc;
+	}
+	
+	/* Start looking for new input devices */
+	input_start_dev_discovery();
+	
+	printf("%s: Accepting connections\n", NAME);
+	task_retval(0);
+	async_manager();
+	
+	/* Not reached. */
+	return 0;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/input.h
===================================================================
--- uspace/srv/hid/input/input.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/input.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup inputgen generic
+ * @brief HelenOS input server.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef INPUT_H_
+#define INPUT_H_
+
+#include <bool.h>
+#include <async.h>
+
+#define NAME  "input"
+
+extern bool irc_service;
+extern async_sess_t *irc_sess;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/kbd.h
===================================================================
--- uspace/srv/hid/input/kbd.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/kbd.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup inputgen generic
+ * @brief HelenOS input server.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_KBD_H_
+#define KBD_KBD_H_
+
+#include <adt/list.h>
+#include <ipc/loc.h>
+
+struct kbd_port_ops;
+struct kbd_ctl_ops;
+struct layout;
+
+typedef struct kbd_dev {
+	/** Link to kbd_devs list */
+	link_t kbd_devs;
+
+	/** Service ID (only for kbdev devices) */
+	service_id_t svc_id;
+
+	/** Device service name (only for kbdev devices) */
+	char *svc_name;
+
+	/** Port ops */
+	struct kbd_port_ops *port_ops;
+
+	/** Ctl ops */
+	struct kbd_ctl_ops *ctl_ops;
+
+	/** Controller-private data */
+	void *ctl_private;
+
+	/** Currently active modifiers. */
+	unsigned mods;
+
+	/** Currently pressed lock keys. We track these to tackle autorepeat. */
+	unsigned lock_keys;
+
+	/** Active keyboard layout */
+	struct layout *active_layout;
+} kbd_dev_t;
+
+extern void kbd_push_data(kbd_dev_t *, sysarg_t);
+extern void kbd_push_event(kbd_dev_t *, int, unsigned int);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/kbd_ctl.h
===================================================================
--- uspace/srv/hid/input/kbd_ctl.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/kbd_ctl.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup inputgen generic
+ * @brief Keyboard controller driver interface.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_CTL_H_
+#define KBD_CTL_H_
+
+#include "kbd_port.h"
+
+struct kbd_dev;
+
+typedef struct kbd_ctl_ops {
+	void (*parse)(sysarg_t);
+	int (*init)(struct kbd_dev *);
+	void (*set_ind)(struct kbd_dev *, unsigned int);
+} kbd_ctl_ops_t;
+
+extern kbd_ctl_ops_t apple_ctl;
+extern kbd_ctl_ops_t gxe_fb_ctl;
+extern kbd_ctl_ops_t kbdev_ctl;
+extern kbd_ctl_ops_t pc_ctl;
+extern kbd_ctl_ops_t stty_ctl;
+extern kbd_ctl_ops_t sun_ctl;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/kbd_port.h
===================================================================
--- uspace/srv/hid/input/kbd_port.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/kbd_port.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup inputgen generic
+ * @brief Keyboard port driver interface.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_PORT_H_
+#define KBD_PORT_H_
+
+#include <sys/types.h>
+
+struct kbd_dev;
+
+typedef struct kbd_port_ops {
+	int (*init)(struct kbd_dev *);
+	void (*yield)(void);
+	void (*reclaim)(void);
+	void (*write)(uint8_t);
+} kbd_port_ops_t;
+
+extern kbd_port_ops_t adb_port;
+extern kbd_port_ops_t chardev_port;
+extern kbd_port_ops_t gxemul_port;
+extern kbd_port_ops_t msim_port;
+extern kbd_port_ops_t niagara_port;
+extern kbd_port_ops_t ns16550_port;
+extern kbd_port_ops_t pl050_port;
+extern kbd_port_ops_t ski_port;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/layout.c
===================================================================
--- uspace/srv/hid/input/layout.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/layout.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup inputgen generic
+ * @brief Keyboard layouts
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include "input.h"
+#include "layout.h"
+
+/** Create a new layout instance. */
+layout_t *layout_create(layout_ops_t *ops)
+{
+	layout_t *layout;
+
+	layout = calloc(1, sizeof(layout_t));
+	if (layout == NULL) {
+		printf("%s: Out of memory.\n", NAME);
+		return NULL;
+	}
+
+	layout->ops = ops;
+	if ((*ops->create)(layout) != EOK) {
+		free(layout);
+		return NULL;
+	}
+
+	return layout;
+}
+
+/** Destroy layout instance. */
+void layout_destroy(layout_t *layout)
+{
+	(*layout->ops->destroy)(layout);
+	free(layout);
+}
+
+/** Parse keyboard event. */
+wchar_t layout_parse_ev(layout_t *layout, kbd_event_t *ev)
+{
+	return (*layout->ops->parse_ev)(layout, ev);
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/layout.h
===================================================================
--- uspace/srv/hid/input/layout.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/layout.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2009 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup inputgen generic
+ * @brief Keyboard layout interface.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_LAYOUT_H_
+#define KBD_LAYOUT_H_
+
+#include <sys/types.h>
+#include <io/console.h>
+
+/** Layout instance state */
+typedef struct layout {
+	/** Ops structure */
+	struct layout_ops *ops;
+
+	/* Layout-private data */
+	void *layout_priv;
+} layout_t;
+
+/** Layout ops */
+typedef struct layout_ops {
+	int (*create)(layout_t *);
+	void (*destroy)(layout_t *);
+	wchar_t (*parse_ev)(layout_t *, kbd_event_t *);
+} layout_ops_t;
+
+extern layout_ops_t us_qwerty_ops;
+extern layout_ops_t us_dvorak_ops;
+extern layout_ops_t cz_ops;
+
+extern layout_t *layout_create(layout_ops_t *);
+extern void layout_destroy(layout_t *);
+extern wchar_t layout_parse_ev(layout_t *, kbd_event_t *);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/layout/cz.c
===================================================================
--- uspace/srv/hid/input/layout/cz.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/layout/cz.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -33,10 +33,10 @@
 
 #include <errno.h>
-#include <input.h>
 #include <io/console.h>
 #include <io/keycode.h>
 #include <bool.h>
-#include <layout.h>
 #include <stdlib.h>
+#include "../input.h"
+#include "../layout.h"
 
 static int cz_create(layout_t *);
Index: uspace/srv/hid/input/layout/us_dvorak.c
===================================================================
--- uspace/srv/hid/input/layout/us_dvorak.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/layout/us_dvorak.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -33,8 +33,8 @@
 
 #include <errno.h>
-#include <kbd.h>
 #include <io/console.h>
 #include <io/keycode.h>
-#include <layout.h>
+#include "../layout.h"
+#include "../kbd.h"
 
 static int us_dvorak_create(layout_t *);
Index: uspace/srv/hid/input/layout/us_qwerty.c
===================================================================
--- uspace/srv/hid/input/layout/us_qwerty.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/layout/us_qwerty.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -28,13 +28,13 @@
 
 /** @addtogroup input
- * @brief	US QWERTY layout.
+ * @brief US QWERTY layout.
  * @{
  */
 
 #include <errno.h>
-#include <kbd.h>
 #include <io/console.h>
 #include <io/keycode.h>
-#include <layout.h>
+#include "../layout.h"
+#include "../kbd.h"
 
 static int us_qwerty_create(layout_t *);
Index: uspace/srv/hid/input/mouse.h
===================================================================
--- uspace/srv/hid/input/mouse.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/mouse.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup inputgen generic
+ * @brief Mouse device handling.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef MOUSE_H_
+#define MOUSE_H_
+
+#include <adt/list.h>
+#include <ipc/loc.h>
+
+struct mouse_port_ops;
+struct mouse_proto_ops;
+
+typedef struct mouse_dev {
+	/** Link to mouse_devs list */
+	link_t mouse_devs;
+	
+	/** Service ID (only for mousedev devices) */
+	service_id_t svc_id;
+	
+	/** Device service name (only for mousedev devices) */
+	char *svc_name;
+	
+	/** Port ops */
+	struct mouse_port_ops *port_ops;
+	
+	/** Protocol ops */
+	struct mouse_proto_ops *proto_ops;
+} mouse_dev_t;
+
+extern void mouse_push_data(mouse_dev_t *, sysarg_t);
+extern void mouse_push_event_move(mouse_dev_t *, int, int, int);
+extern void mouse_push_event_abs_move(mouse_dev_t *, unsigned int, unsigned int,
+    unsigned int, unsigned int);
+extern void mouse_push_event_button(mouse_dev_t *, int, int);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/mouse_port.h
===================================================================
--- uspace/srv/hid/input/mouse_port.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/mouse_port.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup inputgen generic
+ * @brief Mouse port driver interface.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef MOUSE_PORT_H_
+#define MOUSE_PORT_H_
+
+#include <sys/types.h>
+
+struct mouse_dev;
+
+typedef struct mouse_port_ops {
+	int (*init)(struct mouse_dev *);
+	void (*yield)(void);
+	void (*reclaim)(void);
+	void (*write)(uint8_t);
+} mouse_port_ops_t;
+
+extern mouse_port_ops_t adb_mouse_port;
+extern mouse_port_ops_t chardev_mouse_port;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/mouse_proto.h
===================================================================
--- uspace/srv/hid/input/mouse_proto.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/mouse_proto.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup inputgen generic
+ * @brief Mouse protocol driver interface.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef MOUSE_PROTO_H_
+#define MOUSE_PROTO_H_
+
+#include "mouse_port.h"
+
+struct mouse_dev;
+
+typedef struct mouse_proto_ops {
+	void (*parse)(sysarg_t);
+	int (*init)(struct mouse_dev *);
+} mouse_proto_ops_t;
+
+extern mouse_proto_ops_t adb_proto;
+extern mouse_proto_ops_t mousedev_proto;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/port/adb.c
===================================================================
--- uspace/srv/hid/input/port/adb.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/port/adb.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -37,11 +37,11 @@
 #include <ipc/adb.h>
 #include <async.h>
-#include <input.h>
-#include <kbd_port.h>
-#include <kbd.h>
 #include <vfs/vfs.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <loc.h>
+#include "../input.h"
+#include "../kbd_port.h"
+#include "../kbd.h"
 
 static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg);
Index: uspace/srv/hid/input/port/adb_mouse.c
===================================================================
--- uspace/srv/hid/input/port/adb_mouse.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/port/adb_mouse.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -37,10 +37,10 @@
 #include <ipc/adb.h>
 #include <async.h>
-#include <input.h>
-#include <mouse_port.h>
-#include <mouse.h>
 #include <errno.h>
 #include <loc.h>
 #include <stdio.h>
+#include "../mouse.h"
+#include "../mouse_port.h"
+#include "../input.h"
 
 static mouse_dev_t *mouse_dev;
Index: uspace/srv/hid/input/port/chardev.c
===================================================================
--- uspace/srv/hid/input/port/chardev.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/port/chardev.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -37,10 +37,10 @@
 #include <ipc/char.h>
 #include <async.h>
-#include <input.h>
-#include <kbd_port.h>
-#include <kbd.h>
 #include <loc.h>
 #include <errno.h>
 #include <stdio.h>
+#include "../input.h"
+#include "../kbd_port.h"
+#include "../kbd.h"
 
 static void kbd_port_events(ipc_callid_t iid, ipc_call_t *icall, void *arg);
Index: uspace/srv/hid/input/port/gxemul.c
===================================================================
--- uspace/srv/hid/input/port/gxemul.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/port/gxemul.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -31,15 +31,15 @@
  * @{
  * @ingroup  kbd
- */ 
+ */
 /** @file
- * @brief	GXEmul keyboard port driver.
+ * @brief GXEmul keyboard port driver.
  */
 
 #include <async.h>
 #include <sysinfo.h>
-#include <kbd_port.h>
-#include <kbd.h>
 #include <ddi.h>
 #include <errno.h>
+#include "../kbd_port.h"
+#include "../kbd.h"
 
 static int gxemul_port_init(kbd_dev_t *);
Index: uspace/srv/hid/input/port/msim.c
===================================================================
--- uspace/srv/hid/input/port/msim.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/port/msim.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -38,8 +38,8 @@
 #include <async.h>
 #include <sysinfo.h>
-#include <kbd_port.h>
-#include <kbd.h>
 #include <ddi.h>
 #include <errno.h>
+#include "../kbd_port.h"
+#include "../kbd.h"
 
 static int msim_port_init(kbd_dev_t *);
Index: uspace/srv/hid/input/port/niagara.c
===================================================================
--- uspace/srv/hid/input/port/niagara.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/port/niagara.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -31,7 +31,7 @@
  * @ingroup  kbd
  * @{
- */ 
+ */
 /** @file
- * @brief	Niagara console keyboard port driver.
+ * @brief Niagara console keyboard port driver.
  */
 
@@ -39,6 +39,4 @@
 #include <ddi.h>
 #include <async.h>
-#include <kbd.h>
-#include <kbd_port.h>
 #include <sysinfo.h>
 #include <stdio.h>
@@ -46,4 +44,6 @@
 #include <bool.h>
 #include <errno.h>
+#include "../kbd_port.h"
+#include "../kbd.h"
 
 static int niagara_port_init(kbd_dev_t *);
Index: uspace/srv/hid/input/port/ns16550.c
===================================================================
--- uspace/srv/hid/input/port/ns16550.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/port/ns16550.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -39,9 +39,9 @@
 #include <async.h>
 #include <sysinfo.h>
-#include <input.h>
-#include <kbd.h>
-#include <kbd_port.h>
 #include <ddi.h>
 #include <errno.h>
+#include "../input.h"
+#include "../kbd_port.h"
+#include "../kbd.h"
 
 static int ns16550_port_init(kbd_dev_t *);
Index: uspace/srv/hid/input/port/pl050.c
===================================================================
--- uspace/srv/hid/input/port/pl050.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/port/pl050.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -41,9 +41,9 @@
 #include <unistd.h>
 #include <sysinfo.h>
-#include <kbd_port.h>
-#include <kbd.h>
 #include <ddi.h>
 #include <stdio.h>
 #include <errno.h>
+#include "../kbd_port.h"
+#include "../kbd.h"
 
 static int pl050_port_init(kbd_dev_t *);
Index: uspace/srv/hid/input/port/ski.c
===================================================================
--- uspace/srv/hid/input/port/ski.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/port/ski.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -31,17 +31,16 @@
  * @ingroup  kbd
  * @{
- */ 
+ */
 /** @file
- * @brief	Ski console keyboard port driver.
+ * @brief Ski console keyboard port driver.
  */
-
 
 #include <stdlib.h>
 #include <unistd.h>
-#include <kbd.h>
-#include <kbd_port.h>
 #include <sys/types.h>
 #include <thread.h>
 #include <bool.h>
+#include "../kbd_port.h"
+#include "../kbd.h"
 
 static int ski_port_init(kbd_dev_t *);
Index: uspace/srv/hid/input/proto/adb.c
===================================================================
--- uspace/srv/hid/input/proto/adb.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/proto/adb.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -37,7 +37,7 @@
 
 #include <bool.h>
-#include <mouse.h>
-#include <mouse_port.h>
-#include <mouse_proto.h>
+#include "../mouse.h"
+#include "../mouse_port.h"
+#include "../mouse_proto.h"
 
 static mouse_dev_t *mouse_dev;
Index: uspace/srv/hid/input/proto/mousedev.c
===================================================================
--- uspace/srv/hid/input/proto/mousedev.c	(revision 9f5cf682316ed39433d78a5a4d75f3d62faf22be)
+++ uspace/srv/hid/input/proto/mousedev.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -43,10 +43,10 @@
 #include <errno.h>
 #include <ipc/mouseev.h>
-#include <input.h>
 #include <loc.h>
-#include <mouse.h>
-#include <mouse_port.h>
-#include <mouse_proto.h>
 #include <sys/typefmt.h>
+#include "../mouse.h"
+#include "../mouse_port.h"
+#include "../mouse_proto.h"
+#include "../input.h"
 
 /** Mousedev softstate */
Index: uspace/srv/hid/input/stroke.c
===================================================================
--- uspace/srv/hid/input/stroke.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/stroke.c	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup input
+ * @{
+ */
+/**
+ * @file
+ * @brief Stroke simulator.
+ *
+ * When simulating a keyboard using a serial TTY we need to convert the
+ * recognized strokes (such as Shift-A) to sequences of key presses and
+ * releases (such as 'press Shift, press A, release A, release Shift').
+ *
+ */
+
+#include <io/console.h>
+#include <io/keycode.h>
+#include "stroke.h"
+#include "kbd.h"
+
+/** Correspondence between modifers and the modifier keycodes. */
+static unsigned int mods_keys[][2] = {
+	{ KM_LSHIFT, KC_LSHIFT },
+	{ 0, 0 }
+};
+
+/** Simulate keystroke using sequences of key presses and releases. */
+void stroke_sim(kbd_dev_t *kdev, unsigned mod, unsigned key)
+{
+	int i;
+
+	/* Simulate modifier presses. */
+	i = 0;
+	while (mods_keys[i][0] != 0) {
+		if (mod & mods_keys[i][0]) {
+			kbd_push_event(kdev, KEY_PRESS, mods_keys[i][1]);
+		}
+		++i;
+	}
+
+	/* Simulate key press and release. */
+	if (key != 0) {
+		kbd_push_event(kdev, KEY_PRESS, key);
+		kbd_push_event(kdev, KEY_RELEASE, key);
+	}
+
+	/* Simulate modifier releases. */
+	i = 0;
+	while (mods_keys[i][0] != 0) {
+		if (mod & mods_keys[i][0]) {
+			kbd_push_event(kdev, KEY_RELEASE, mods_keys[i][1]);
+		}
+		++i;
+	}
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hid/input/stroke.h
===================================================================
--- uspace/srv/hid/input/stroke.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
+++ uspace/srv/hid/input/stroke.h	(revision b6a088fcb1dd32d5b6970439fa4b960a6545239e)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup inputgen generic
+ * @brief Generic scancode parser.
+ * @ingroup input
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KBD_STROKE_H_
+#define KBD_STROKE_H_
+
+#include "kbd.h"
+
+extern void stroke_sim(kbd_dev_t *, unsigned, unsigned);
+
+#endif
+
+/**
+ * @}
+ */
