Index: uspace/srv/hid/input/generic/input.c
===================================================================
--- uspace/srv/hid/input/generic/input.c	(revision b72efe87f3e33beaa3b0d0cf7c8b598a58f6a6de)
+++ uspace/srv/hid/input/generic/input.c	(revision 4d4988ed64e25f70ccfc9f9bcd6850a87a04b88b)
@@ -58,4 +58,5 @@
 #include <kbd_port.h>
 #include <kbd_ctl.h>
+#include <mouse_proto.h>
 #include <layout.h>
 #include <mouse.h>
@@ -65,23 +66,7 @@
 
 /* In microseconds */
-#define DISCOVERY_POLL_INTERVAL		(10*1000*1000)
-
-static void kbd_devs_yield(void);
-static void kbd_devs_reclaim(void);
-
-static void input_event_key(int, unsigned int, unsigned, wchar_t);
-
-int client_phone = -1;
-
-/** List of keyboard devices */
-static list_t kbd_devs;
-
-/** List of mouse devices */
-list_t mouse_devs;
-
-bool irc_service = false;
-int irc_phone = -1;
-
-#define NUM_LAYOUTS 3
+#define DISCOVERY_POLL_INTERVAL  (10 * 1000 * 1000)
+
+#define NUM_LAYOUTS  3
 
 static layout_ops_t *layout[NUM_LAYOUTS] = {
@@ -91,15 +76,33 @@
 };
 
-void kbd_push_scancode(kbd_dev_t *kdev, int scancode)
-{
-/*	printf("scancode: 0x%x\n", scancode);*/
-	(*kdev->ctl_ops->parse_scancode)(scancode);
-}
-
-void kbd_push_ev(kbd_dev_t *kdev, int type, unsigned int key)
+static void kbd_devs_yield(void);
+static void kbd_devs_reclaim(void);
+
+int client_phone = -1;
+
+/** List of keyboard devices */
+static list_t kbd_devs;
+
+/** List of mouse devices */
+static list_t mouse_devs;
+
+bool irc_service = false;
+int irc_phone = -1;
+
+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 mod_mask;
-
+	unsigned int mod_mask;
+	
 	switch (key) {
 	case KC_LCTRL: mod_mask = KM_LCTRL; break;
@@ -111,5 +114,5 @@
 	default: mod_mask = 0; break;
 	}
-
+	
 	if (mod_mask != 0) {
 		if (type == KEY_PRESS)
@@ -118,5 +121,5 @@
 			kdev->mods = kdev->mods & ~mod_mask;
 	}
-
+	
 	switch (key) {
 	case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
@@ -125,5 +128,5 @@
 	default: mod_mask = 0; break;
 	}
-
+	
 	if (mod_mask != 0) {
 		if (type == KEY_PRESS) {
@@ -135,5 +138,5 @@
 			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);
@@ -142,48 +145,37 @@
 		}
 	}
-/*
-	printf("type: %d\n", type);
-	printf("mods: 0x%x\n", mods);
-	printf("keycode: %u\n", key);
-*/
+	
 	if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) &&
-		key == KC_F1) {
+	    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) {
+	    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) {
+	    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);
-	input_event_key(ev.type, ev.key, ev.mods, ev.c);
-}
-
-/** Key has been pressed or released. */
-static void input_event_key(int type, unsigned int key, unsigned mods,
-    wchar_t c)
-{
-	async_obsolete_msg_4(client_phone, INPUT_EVENT_KEY, type, key,
-	    mods, c);
+	async_obsolete_msg_4(client_phone, INPUT_EVENT_KEY, ev.type, ev.key,
+	    ev.mods, ev.c);
 }
 
 /** Mouse pointer has moved. */
-void input_event_move(int dx, int dy)
+void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy)
 {
 	async_obsolete_msg_2(client_phone, INPUT_EVENT_MOVE, dx, dy);
@@ -191,5 +183,5 @@
 
 /** Mouse button has been pressed. */
-void input_event_button(int bnum, int press)
+void mouse_push_event_button(mouse_dev_t *mdev, int bnum, int press)
 {
 	async_obsolete_msg_2(client_phone, INPUT_EVENT_BUTTON, bnum, press);
@@ -201,7 +193,7 @@
 	ipc_call_t call;
 	int retval;
-
+	
 	async_answer_0(iid, EOK);
-
+	
 	while (true) {
 		callid = async_get_call(&call);
@@ -237,26 +229,39 @@
 			retval = EINVAL;
 		}
+		
 		async_answer_0(callid, retval);
-	}	
+	}
 }
 
 static kbd_dev_t *kbd_dev_new(void)
 {
-	kbd_dev_t *kdev;
-
-	kdev = calloc(1, sizeof(kbd_dev_t));
+	kbd_dev_t *kdev = calloc(1, sizeof(kbd_dev_t));
 	if (kdev == NULL) {
-		printf(NAME ": Error allocating keyboard device. "
-		    "Out of memory.\n");
+		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;
 }
 
@@ -264,18 +269,16 @@
 static void kbd_add_dev(kbd_port_ops_t *port, kbd_ctl_ops_t *ctl)
 {
-	kbd_dev_t *kdev;
-
-	kdev = kbd_dev_new();
+	kbd_dev_t *kdev = kbd_dev_new();
 	if (kdev == NULL)
 		return;
-
+	
 	kdev->port_ops = port;
 	kdev->ctl_ops = ctl;
 	kdev->dev_path = NULL;
-
+	
 	/* Initialize port driver. */
 	if ((*kdev->port_ops->init)(kdev) != 0)
 		goto fail;
-
+	
 	/* Initialize controller driver. */
 	if ((*kdev->ctl_ops->init)(kdev) != 0) {
@@ -283,36 +286,93 @@
 		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->dev_path = NULL;
+	
+	/* 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 dev_path	Filesystem path to the device (/dev/class/...)
+ * @param dev_path Filesystem path to the device (/dev/class/...)
+ *
  */
 static int kbd_add_kbdev(const char *dev_path)
 {
-	kbd_dev_t *kdev;
-
-	kdev = kbd_dev_new();
+	kbd_dev_t *kdev = kbd_dev_new();
 	if (kdev == NULL)
 		return -1;
-
+	
 	kdev->dev_path = dev_path;
 	kdev->port_ops = NULL;
 	kdev->ctl_ops = &kbdev_ctl;
-
+	
 	/* Initialize controller driver. */
 	if ((*kdev->ctl_ops->init)(kdev) != 0) {
 		goto fail;
 	}
-
+	
 	list_append(&kdev->kbd_devs, &kbd_devs);
 	return EOK;
+	
 fail:
 	free(kdev);
+	return -1;
+}
+
+/** Add new mousedev device.
+ *
+ * @param dev_path Filesystem path to the device (/dev/class/...)
+ *
+ */
+static int mouse_add_mousedev(const char *dev_path)
+{
+	mouse_dev_t *mdev = mouse_dev_new();
+	if (mdev == NULL)
+		return -1;
+	
+	mdev->dev_path = dev_path;
+	mdev->port_ops = NULL;
+	mdev->proto_ops = &mousedev_proto;
+	
+	/* Initialize controller driver. */
+	if ((*mdev->proto_ops->init)(mdev) != 0) {
+		goto fail;
+	}
+	
+	list_append(&mdev->mouse_devs, &mouse_devs);
+	return EOK;
+	
+fail:
+	free(mdev);
 	return -1;
 }
@@ -375,4 +435,27 @@
 }
 
+/** 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_amd64)
+	mouse_add_dev(&chardev_mouse_port, &ps2_proto);
+#endif
+#if defined(UARCH_ia32)
+	mouse_add_dev(&chardev_mouse_port, &ps2_proto);
+#endif
+#if defined(MACHINE_i460GX)
+	mouse_add_dev(&chardev_mouse_port, &ps2_proto);
+#endif
+#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)
 {
@@ -381,5 +464,5 @@
 		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
 		    kbd_devs);
-
+		
 		/* Yield port */
 		if (kdev->port_ops != NULL)
@@ -394,5 +477,5 @@
 		kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,
 		    kbd_devs);
-
+		
 		/* Reclaim port */
 		if (kdev->port_ops != NULL)
@@ -405,5 +488,6 @@
  * Looks under /dev/class/keyboard and /dev/class/mouse.
  *
- * @param arg	Ignored
+ * @param arg Ignored
+ *
  */
 static int dev_discovery_fibril(void *arg)
@@ -413,8 +497,8 @@
 	size_t mouse_id = 1;
 	int rc;
-
+	
 	while (true) {
 		async_usleep(DISCOVERY_POLL_INTERVAL);
-
+		
 		/*
 		 * Check for new keyboard device
@@ -423,15 +507,15 @@
 		if (rc < 0)
 			continue;
-
+		
 		if (kbd_add_kbdev(dev_path) == EOK) {
-			printf(NAME ": Connected keyboard device '%s'\n",
-			    dev_path);
-
+			printf("%s: Connected keyboard device '%s'\n",
+			    NAME, dev_path);
+			
 			/* XXX Handle device removal */
 			++kbd_id;
 		}
-
+		
 		free(dev_path);
-
+		
 		/*
 		 * Check for new mouse device
@@ -440,16 +524,16 @@
 		if (rc < 0)
 			continue;
-
-		if (mouse_add_dev(dev_path) == EOK) {
-			printf(NAME ": Connected mouse device '%s'\n",
-			    dev_path);
-
+		
+		if (mouse_add_mousedev(dev_path) == EOK) {
+			printf("%s: Connected mouse device '%s'\n",
+			    NAME, dev_path);
+			
 			/* XXX Handle device removal */
 			++mouse_id;
 		}
-
+		
 		free(dev_path);
 	}
-
+	
 	return EOK;
 }
@@ -458,12 +542,11 @@
 static void input_start_dev_discovery(void)
 {
-	fid_t fid;
-
-	fid = fibril_create(dev_discovery_fibril, NULL);
+	fid_t fid = fibril_create(dev_discovery_fibril, NULL);
 	if (!fid) {
-		printf(NAME ": Failed to create device discovery fibril.\n");
+		printf("%s: Failed to create device discovery fibril.\n",
+		    NAME);
 		return;
 	}
-
+	
 	fibril_add_ready(fid);
 }
@@ -490,7 +573,7 @@
 	/* Add legacy keyboard devices. */
 	kbd_add_legacy_devs();
-
-	/* Add legacy (devmap-style) mouse device. */
-	(void) mouse_add_dev("/dev/hid_in/mouse");
+	
+	/* Add legacy mouse devices. */
+	mouse_add_legacy_devs();
 	
 	/* Register driver */
@@ -509,11 +592,11 @@
 		return -1;
 	}
-
+	
 	/* Start looking for new input devices */
 	input_start_dev_discovery();
-
-	printf(NAME ": Accepting connections\n");
+	
+	printf("%s: Accepting connections\n", NAME);
 	async_manager();
-
+	
 	/* Not reached. */
 	return 0;
