Index: uspace/drv/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.c	(revision 3bcac681e8c0f507f808ef21d13ce5d53da62735)
+++ uspace/drv/usbhid/kbd/kbddev.c	(revision e60436b9b1559e569d97b0261d8781cc0d88bee5)
@@ -177,10 +177,10 @@
 /*----------------------------------------------------------------------------*/
 
-static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
-    uint8_t report_id, void *arg);
-
-static const usb_hid_report_in_callbacks_t usb_kbd_parser_callbacks = {
-	.keyboard = usb_kbd_process_keycodes
-};
+//static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
+//    uint8_t report_id, void *arg);
+
+//static const usb_hid_report_in_callbacks_t usb_kbd_parser_callbacks = {
+//	.keyboard = usb_kbd_process_keycodes
+//};
 
 /*----------------------------------------------------------------------------*/
@@ -320,10 +320,14 @@
 	// TODO: COMPOSE and KANA
 	
-	usb_log_debug("Creating output report: %s\n", usb_debug_str_buffer ((uint8_t *)kbd_dev->led_data, kbd_dev->led_output_size * 4, 0));
-
-	usb_hid_report_output_set_data(hid_dev->parser, kbd_dev->led_path, 
-	                               USB_HID_PATH_COMPARE_END , kbd_dev->led_data, 
-	                               kbd_dev->led_output_size);
-	int rc = usb_hid_report_output_translate(hid_dev->parser, 0,
+	usb_log_debug("Creating output report: ");
+	for (i = 0; i < kbd_dev->led_output_size; ++i) {
+		usb_log_debug("%d ", kbd_dev->led_data[i]);
+	}
+	usb_log_debug("\n");
+
+	usb_hid_report_output_set_data(hid_dev->report, kbd_dev->led_path, 
+	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
+	    kbd_dev->led_data, kbd_dev->led_output_size);
+	int rc = usb_hid_report_output_translate(hid_dev->report, 0,
 	    kbd_dev->output_buffer, kbd_dev->output_size);
 	
@@ -333,4 +337,6 @@
 		return;
 	}
+	
+	// TODO: output translating does not work!!
 	
 	usb_log_debug("Output report buffer: %s\n", 
@@ -485,5 +491,5 @@
  */
 static void usb_kbd_check_key_changes(usb_hid_dev_t *hid_dev, 
-    usb_kbd_t *kbd_dev, const uint8_t *key_codes, size_t count)
+    usb_kbd_t *kbd_dev/*, const uint8_t *key_codes, size_t count*/)
 {
 	unsigned int key;
@@ -499,30 +505,27 @@
 	 */
 	i = 0;
-	while (i < count && key_codes[i] != ERROR_ROLLOVER) {
+	while (i < kbd_dev->key_count && kbd_dev->keys[i] != ERROR_ROLLOVER) {
 		++i;
 	}
-	if (i != count) {
+	if (i != kbd_dev->key_count) {
 		usb_log_debug("Phantom state occured.\n");
 		// phantom state, do nothing
 		return;
 	}
-	
-	/* TODO: quite dummy right now, think of better implementation */
-	assert(count == kbd_dev->key_count);
 	
 	/*
 	 * 1) Key releases
 	 */
-	for (j = 0; j < count; ++j) {
+	for (j = 0; j < kbd_dev->key_count; ++j) {
 		// try to find the old key in the new key list
 		i = 0;
 		while (i < kbd_dev->key_count
-		    && key_codes[i] != kbd_dev->keys[j]) {
+		    && kbd_dev->keys[i] != kbd_dev->keys_old[j]) {
 			++i;
 		}
 		
-		if (i == count) {
+		if (i == kbd_dev->key_count) {
 			// not found, i.e. the key was released
-			key = usbhid_parse_scancode(kbd_dev->keys[j]);
+			key = usbhid_parse_scancode(kbd_dev->keys_old[j]);
 			if (!usb_kbd_is_lock(key)) {
 				usb_kbd_repeat_stop(kbd_dev, key);
@@ -541,15 +544,15 @@
 		// try to find the new key in the old key list
 		j = 0;
-		while (j < count && kbd_dev->keys[j] != key_codes[i]) { 
+		while (j < kbd_dev->key_count 
+		    && kbd_dev->keys_old[j] != kbd_dev->keys[i]) { 
 			++j;
 		}
 		
-		if (j == count) {
+		if (j == kbd_dev->key_count) {
 			// not found, i.e. new key pressed
-			key = usbhid_parse_scancode(key_codes[i]);
+			key = usbhid_parse_scancode(kbd_dev->keys[i]);
 			usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
-			    key_codes[i]);
-			usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, 
-			    key);
+			    kbd_dev->keys[i]);
+			usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key);
 			if (!usb_kbd_is_lock(key)) {
 				usb_kbd_repeat_start(kbd_dev, key);
@@ -560,8 +563,24 @@
 	}
 	
-	memcpy(kbd_dev->keys, key_codes, count);
-
-	usb_log_debug("New stored keycodes: %s\n", 
-	    usb_debug_str_buffer(kbd_dev->keys, kbd_dev->key_count, 0));
+//	usb_log_debug("Old keys: ");
+//	for (i = 0; i < kbd_dev->key_count; ++i) {
+//		usb_log_debug("%d ", kbd_dev->keys_old[i]);
+//	}
+//	usb_log_debug("\n");
+	
+	
+//	usb_log_debug("New keys: ");
+//	for (i = 0; i < kbd_dev->key_count; ++i) {
+//		usb_log_debug("%d ", kbd_dev->keys[i]);
+//	}
+//	usb_log_debug("\n");
+	
+	memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4);
+	
+	usb_log_debug2("New stored keys: ");
+	for (i = 0; i < kbd_dev->key_count; ++i) {
+		usb_log_debug2("%d ", kbd_dev->keys_old[i]);
+	}
+	usb_log_debug2("\n");
 }
 
@@ -585,34 +604,34 @@
  * @sa usb_kbd_check_key_changes(), usb_kbd_check_modifier_changes()
  */
-static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
-    uint8_t report_id, void *arg)
-{
-	if (arg == NULL) {
-		usb_log_warning("Missing argument in callback "
-		    "usbhid_process_keycodes().\n");
-		return;
-	}
-	
-	usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
-	
-	if (hid_dev->data == NULL) {
-		usb_log_warning("Missing KBD device structure in callback.\n");
-		return;
-	}
-	
-	usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
-
-	usb_log_debug("Got keys from parser (report id: %u): %s\n", 
-	    report_id, usb_debug_str_buffer(key_codes, count, 0));
-	
-	if (count != kbd_dev->key_count) {
-		usb_log_warning("Number of received keycodes (%zu) differs from"
-		    " expected (%zu).\n", count, kbd_dev->key_count);
-		return;
-	}
-	
-	///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count);
-	usb_kbd_check_key_changes(hid_dev, kbd_dev, key_codes, count);
-}
+//static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
+//    uint8_t report_id, void *arg)
+//{
+//	if (arg == NULL) {
+//		usb_log_warning("Missing argument in callback "
+//		    "usbhid_process_keycodes().\n");
+//		return;
+//	}
+	
+//	usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
+	
+//	if (hid_dev->data == NULL) {
+//		usb_log_warning("Missing KBD device structure in callback.\n");
+//		return;
+//	}
+	
+//	usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
+
+//	usb_log_debug("Got keys from parser (report id: %u): %s\n", 
+//	    report_id, usb_debug_str_buffer(key_codes, count, 0));
+	
+//	if (count != kbd_dev->key_count) {
+//		usb_log_warning("Number of received keycodes (%zu) differs from"
+//		    " expected (%zu).\n", count, kbd_dev->key_count);
+//		return;
+//	}
+	
+//	///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count);
+//	usb_kbd_check_key_changes(hid_dev, kbd_dev, key_codes, count);
+//}
 
 /*----------------------------------------------------------------------------*/
@@ -638,5 +657,9 @@
                                  uint8_t *buffer, size_t actual_size)
 {
-	assert(hid_dev->parser != NULL);
+	assert(hid_dev->report != NULL);
+	assert(hid_dev != NULL);
+	assert(hid_dev->data != NULL);
+	
+	usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
 
 	usb_log_debug("Calling usb_hid_parse_report() with "
@@ -649,23 +672,47 @@
 	//usb_hid_report_path_set_report_id(path, 0);
 	
-	int rc = usb_hid_parse_report(hid_dev->parser, buffer, actual_size);	
-	usb_hid_report_field_t *field = usb_hid_report_get_sibling(hid_dev->parser, 
-	                    NULL, path, USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
-						USB_HID_REPORT_TYPE_INPUT);
-	
-	while(field != NULL) {
-		usb_log_debug("FIELD (%p) - VALUE(%d) USAGE(%u)\n", field, field->value, field->usage);
-		field = usb_hid_report_get_sibling(hid_dev->parser, field, path, 
-		                                   USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
-		                                   USB_HID_REPORT_TYPE_INPUT);
-	}
+	int rc = usb_hid_parse_report(hid_dev->report, buffer, actual_size);
+	
+	if (rc != EOK) {
+		usb_log_warning("Error in usb_hid_parse_report():"
+		    "%s\n", str_error(rc));
+	}
+	
+	// fill in the currently pressed keys
+	
+	usb_hid_report_field_t *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);
+	unsigned i = 0;
+	
+	// TODO: remove this hack - skipping first field
+	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);
+	
+	while (field != NULL) {
+		usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n", 
+		    field, field->value, field->usage);
 		
+		assert(i < kbd_dev->key_count);
+//		if (i == kbd_dev->key_count) {
+//			break;
+//		}
+		
+		// save the key usage
+		kbd_dev->keys[i] = field->usage;
+		usb_log_debug2("Saved %u. key usage %d\n", i, kbd_dev->keys[i]);
+		
+		++i;
+		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);
 	
-	if (rc != EOK) {
-		usb_log_warning("Error in usb_hid_boot_keyboard_input_report():"
-		    "%s\n", str_error(rc));
-	}
+	usb_kbd_check_key_changes(hid_dev, kbd_dev);
 }
 
@@ -755,5 +802,5 @@
 	
 	kbd_dev->key_count = usb_hid_report_input_length(
-	    hid_dev->parser, path, 
+	    hid_dev->report, path, 
 	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
 	usb_hid_report_path_free(path);
@@ -761,5 +808,5 @@
 	usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
 	
-	kbd_dev->keys = (uint8_t *)calloc(kbd_dev->key_count, sizeof(uint8_t));
+	kbd_dev->keys = (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
 	
 	if (kbd_dev->keys == NULL) {
@@ -769,10 +816,20 @@
 	}
 	
+	kbd_dev->keys_old = 
+		(int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
+	
+	if (kbd_dev->keys_old == NULL) {
+		usb_log_fatal("No memory!\n");
+		free(kbd_dev->keys);
+		free(kbd_dev);
+		return ENOMEM;
+	}
+	
 	/*
 	 * Output report
 	 */
 	kbd_dev->output_size = 0;
-	kbd_dev->output_buffer = usb_hid_report_output(hid_dev->parser, 
-	    &kbd_dev->output_size, 0x00);
+	kbd_dev->output_buffer = usb_hid_report_output(hid_dev->report, 
+	    &kbd_dev->output_size, 0);
 	if (kbd_dev->output_buffer == NULL) {
 		usb_log_warning("Error creating output report buffer.\n");
@@ -787,5 +844,5 @@
 	    kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
 	
-	kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev->parser, 
+	kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev->report, 
 	    kbd_dev->led_path, 
 	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
@@ -944,5 +1001,5 @@
 int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev)
 {
-	int rc = usb_hid_parse_report_descriptor(hid_dev->parser, 
+	int rc = usb_hid_parse_report_descriptor(hid_dev->report, 
 	    USB_KBD_BOOT_REPORT_DESCRIPTOR, 
 	    USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE);
Index: uspace/drv/usbhid/kbd/kbddev.h
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.h	(revision 3bcac681e8c0f507f808ef21d13ce5d53da62735)
+++ uspace/drv/usbhid/kbd/kbddev.h	(revision e60436b9b1559e569d97b0261d8781cc0d88bee5)
@@ -65,6 +65,8 @@
  */
 typedef struct usb_kbd_t {
+	/** Previously pressed keys (not translated to key codes). */
+	int32_t *keys_old;
 	/** Currently pressed keys (not translated to key codes). */
-	uint8_t *keys;
+	int32_t *keys;
 	/** Count of stored keys (i.e. number of keys in the report). */
 	size_t key_count;
Index: uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c
===================================================================
--- uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c	(revision 3bcac681e8c0f507f808ef21d13ce5d53da62735)
+++ uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c	(revision e60436b9b1559e569d97b0261d8781cc0d88bee5)
@@ -83,7 +83,7 @@
 	usb_hid_report_path_set_report_id(path, 0);
 	
-	int rc = usb_hid_parse_report(hid_dev->parser, buffer, buffer_size);
+	int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size);
 
-	usb_hid_report_field_t *field = usb_hid_report_get_sibling(hid_dev->parser, NULL, path, USB_HID_PATH_COMPARE_END , USB_HID_REPORT_TYPE_INPUT);
+	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);
 	while(field != NULL) {
 		usb_log_debug("KEY VALUE(%X) USAGE(%X)\n", field->value, field->usage);
Index: uspace/drv/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/usbhid/mouse/mousedev.c	(revision 3bcac681e8c0f507f808ef21d13ce5d53da62735)
+++ uspace/drv/usbhid/mouse/mousedev.c	(revision e60436b9b1559e569d97b0261d8781cc0d88bee5)
@@ -296,5 +296,5 @@
 int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev)
 {
-	int rc = usb_hid_parse_report_descriptor(hid_dev->parser, 
+	int rc = usb_hid_parse_report_descriptor(hid_dev->report, 
 	    USB_MOUSE_BOOT_REPORT_DESCRIPTOR, 
 	    USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE);
Index: uspace/drv/usbhid/usbhid.c
===================================================================
--- uspace/drv/usbhid/usbhid.c	(revision 3bcac681e8c0f507f808ef21d13ce5d53da62735)
+++ uspace/drv/usbhid/usbhid.c	(revision e60436b9b1559e569d97b0261d8781cc0d88bee5)
@@ -192,8 +192,8 @@
 	}
 	
-	assert(hid_dev->parser != NULL);
+	assert(hid_dev->report != NULL);
 	
 	usb_log_debug("Compare flags: %d\n", mapping->compare);
-	size_t size = usb_hid_report_input_length(hid_dev->parser, usage_path, 
+	size_t size = usb_hid_report_input_length(hid_dev->report, usage_path, 
 	    mapping->compare);
 	usb_log_debug("Size of the input report: %zuB\n", size);
@@ -341,7 +341,7 @@
 	}
 	
-	hid_dev->parser = (usb_hid_report_t *)(malloc(sizeof(
+	hid_dev->report = (usb_hid_report_t *)(malloc(sizeof(
 	    usb_hid_report_t)));
-	if (hid_dev->parser == NULL) {
+	if (hid_dev->report == NULL) {
 		usb_log_fatal("No memory!\n");
 		free(hid_dev);
@@ -385,5 +385,5 @@
 	/* Get the report descriptor and parse it. */
 	rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 
-	    hid_dev->parser);
+	    hid_dev->report);
 	
 	bool fallback = false;
@@ -583,6 +583,6 @@
 
 	// destroy the parser
-	if ((*hid_dev)->parser != NULL) {
-		usb_hid_free_report((*hid_dev)->parser);
+	if ((*hid_dev)->report != NULL) {
+		usb_hid_free_report((*hid_dev)->report);
 	}
 
Index: uspace/drv/usbhid/usbhid.h
===================================================================
--- uspace/drv/usbhid/usbhid.h	(revision 3bcac681e8c0f507f808ef21d13ce5d53da62735)
+++ uspace/drv/usbhid/usbhid.h	(revision e60436b9b1559e569d97b0261d8781cc0d88bee5)
@@ -91,5 +91,5 @@
 	
 	/** HID Report parser. */
-	usb_hid_report_t *parser;
+	usb_hid_report_t *report;
 	
 	/** Arbitrary data (e.g. a special structure for handling keyboard). */
