Index: uspace/drv/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/usbhid/mouse/mousedev.c	(revision e67399ef1606651d887b3ccc2c7ddfd81c02f364)
+++ uspace/drv/usbhid/mouse/mousedev.c	(revision 30710035642aabd1cc1e4d0730571b41dd5d20be)
@@ -39,4 +39,5 @@
 #include <usb/classes/hid.h>
 #include <usb/classes/hidreq.h>
+#include <usb/classes/hidut.h>
 #include <errno.h>
 #include <str_error.h>
@@ -45,4 +46,6 @@
 #include "mousedev.h"
 #include "../usbhid.h"
+
+#define NAME "mouse"
 
 /*----------------------------------------------------------------------------*/
@@ -62,4 +65,5 @@
 /** Default idle rate for mouses. */
 static const uint8_t IDLE_RATE = 0;
+static const size_t USB_MOUSE_BUTTON_COUNT = 3;
 
 /*----------------------------------------------------------------------------*/
@@ -170,59 +174,124 @@
 /*----------------------------------------------------------------------------*/
 
-static bool usb_mouse_process_boot_report(usb_mouse_t *mouse_dev,
+static bool usb_mouse_process_boot_report(usb_hid_dev_t *hid_dev,
     uint8_t *buffer, size_t buffer_size)
 {
+	usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
+	
 	usb_log_debug2("got buffer: %s.\n",
 	    usb_debug_str_buffer(buffer, buffer_size, 0));
-
-	uint8_t butt = buffer[0];
-	char str_buttons[4] = {
-		butt & 1 ? '#' : '.',
-		butt & 2 ? '#' : '.',
-		butt & 4 ? '#' : '.',
-		0
-	};
-
-	int shift_x = ((int) buffer[1]) - 127;
-	int shift_y = ((int) buffer[2]) - 127;
-	int wheel = ((int) buffer[3]) - 127;
-
-	if (buffer[1] == 0) {
-		shift_x = 0;
-	}
-	if (buffer[2] == 0) {
-		shift_y = 0;
-	}
-	if (buffer[3] == 0) {
-		wheel = 0;
-	}
-	
-	if (mouse_dev->console_phone >= 0) {
-		usb_log_debug("Console phone: %d\n", mouse_dev->console_phone);
-		if ((shift_x != 0) || (shift_y != 0)) {
-			/* FIXME: guessed for QEMU */
+	
+	if (mouse_dev->console_phone < 0) {
+		usb_log_error(NAME " No console phone.\n");
+		return false;	// ??
+	}
+
+	/*
+	 * parse the input report
+	 */
+	
+	usb_log_debug(NAME " Calling usb_hid_parse_report() with "
+	    "buffer %s\n", usb_debug_str_buffer(buffer, buffer_size, 0));
+	
+	uint8_t report_id;
+	
+	int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 
+	    &report_id);
+	
+	if (rc != EOK) {
+		usb_log_warning(NAME "Error in usb_hid_parse_report(): %s\n", 
+		    str_error(rc));
+		return true;
+	}
+	
+	/*
+	 * X
+	 */
+	int shift_x = 0;
+	
+	usb_hid_report_path_t *path = usb_hid_report_path();
+	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 
+	    USB_HIDUT_USAGE_GENERIC_DESKTOP_X);
+
+	usb_hid_report_path_set_report_id(path, report_id);
+
+	usb_hid_report_field_t *field = usb_hid_report_get_sibling(
+	    hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END, 
+	    USB_HID_REPORT_TYPE_INPUT);
+
+	if (field != NULL) {
+		usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 
+		    field->usage);
+		shift_x = field->value;
+	}
+
+	usb_hid_report_path_free(path);
+	
+	/*
+	 * Y
+	 */
+	int shift_y = 0;
+	
+	path = usb_hid_report_path();
+	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP, 
+	    USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);
+
+	usb_hid_report_path_set_report_id(path, report_id);
+
+	field = usb_hid_report_get_sibling(
+	    hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END, 
+	    USB_HID_REPORT_TYPE_INPUT);
+
+	if (field != NULL) {
+		usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 
+		    field->usage);
+		shift_y = field->value;
+	}
+
+	usb_hid_report_path_free(path);
+	
+	if ((shift_x != 0) || (shift_y != 0)) {
+		async_req_2_0(mouse_dev->console_phone,
+		    MEVENT_MOVE, shift_x, shift_y);
+	}
+	
+	/*
+	 * Buttons
+	 */
+	path = usb_hid_report_path();
+	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
+	usb_hid_report_path_set_report_id(path, report_id);
+	
+	field = usb_hid_report_get_sibling(
+	    hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
+	    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
+	    USB_HID_REPORT_TYPE_INPUT);
+
+	if (field != NULL) {
+		usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value, 
+		    field->usage);
+		
+		if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0
+		    && field->value != 0) {
 			async_req_2_0(mouse_dev->console_phone,
-			    MEVENT_MOVE,
-			    - shift_x / 10,  - shift_y / 10);
-		} else {
-			usb_log_error("No move reported\n");
-		}
-		if (butt) {
-			/* FIXME: proper button clicking. */
-			async_req_2_0(mouse_dev->console_phone,
-			    MEVENT_BUTTON, 1, 1);
-			async_req_2_0(mouse_dev->console_phone,
-			    MEVENT_BUTTON, 1, 0);
-		}
-	} else {
-		usb_log_error("No console phone in mouse!!\n");
-	}
-
-	usb_log_debug("buttons=%s  dX=%+3d  dY=%+3d  wheel=%+3d\n",
-	    str_buttons, shift_x, shift_y, wheel);
-
-	/* Guess. */
-	//async_usleep(1000);
-	// no sleep right now
+			    MEVENT_BUTTON, field->usage, 1);
+			mouse_dev->buttons[field->usage - field->usage_minimum]
+			    = field->value;
+		} else if (
+		    mouse_dev->buttons[field->usage - field->usage_minimum] != 0
+		    && field->value == 0) {
+		       async_req_2_0(mouse_dev->console_phone,
+			   MEVENT_BUTTON, field->usage, 0);
+		       mouse_dev->buttons[field->usage - field->usage_minimum]
+			   = field->value;
+	       }
+		
+		field = usb_hid_report_get_sibling(
+		    hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
+		    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
+		    USB_HID_REPORT_TYPE_INPUT);
+	}
+	
+	usb_hid_report_path_free(path);
 
 	return true;
@@ -248,4 +317,25 @@
 	}
 	
+//	usb_hid_report_path_t *path = usb_hid_report_path();
+//	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
+	
+//	usb_hid_report_path_set_report_id(path, 0);
+	
+//	mouse_dev->button_count = usb_hid_report_input_length(
+//	    hid_dev->report, path, 
+//	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
+//	usb_hid_report_path_free(path);
+	
+//	usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
+	
+	mouse_dev->buttons = (int32_t *)calloc(USB_MOUSE_BUTTON_COUNT, 
+	    sizeof(int32_t));
+	
+	if (mouse_dev->buttons == NULL) {
+		usb_log_fatal("No memory!\n");
+		free(mouse_dev);
+		return ENOMEM;
+	}
+	
 	// save the Mouse device structure into the HID device structure
 	hid_dev->data = mouse_dev;
@@ -255,6 +345,6 @@
 	
 	// TODO: how to know if the device supports the request???
-	usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 
-	    hid_dev->usb_dev->interface_no, IDLE_RATE);
+//	usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 
+//	    hid_dev->usb_dev->interface_no, IDLE_RATE);
 	
 	return EOK;
@@ -280,7 +370,6 @@
 		return false;
 	}
-	usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
-	
-	return usb_mouse_process_boot_report(mouse_dev, buffer, buffer_size);
+	
+	return usb_mouse_process_boot_report(hid_dev, buffer, buffer_size);
 }
 
Index: uspace/drv/usbhid/mouse/mousedev.h
===================================================================
--- uspace/drv/usbhid/mouse/mousedev.h	(revision e67399ef1606651d887b3ccc2c7ddfd81c02f364)
+++ uspace/drv/usbhid/mouse/mousedev.h	(revision 30710035642aabd1cc1e4d0730571b41dd5d20be)
@@ -49,4 +49,6 @@
 	/** IPC phone to console (consumer). */
 	int console_phone;
+	
+	int32_t *buttons;
 } usb_mouse_t;
 
Index: uspace/lib/usb/include/usb/classes/hidut.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidut.h	(revision e67399ef1606651d887b3ccc2c7ddfd81c02f364)
+++ uspace/lib/usb/include/usb/classes/hidut.h	(revision 30710035642aabd1cc1e4d0730571b41dd5d20be)
@@ -59,5 +59,8 @@
 	USB_HIDUT_USAGE_GENERIC_DESKTOP_GAMEPAD = 5,
 	USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD = 6,
-	USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYPAD = 7
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYPAD = 7,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_X = 0x30,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_Y = 0x31,
+	USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL = 0x38
 	/* USB_HIDUT_USAGE_GENERIC_DESKTOP_ = , */
 	
