Commit "FS#10468 - USB HID: Show keypad mode on screen"


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22852 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/SOURCES b/apps/SOURCES
index 0408c32..bac3765 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -150,6 +150,9 @@
 eq_arm.S
 #endif
 #endif
+#ifdef USB_ENABLE_HID
+usb_keymaps.c
+#endif
 metadata.c
 metadata/mp3.c
 #if CONFIG_CODEC == SWCODEC
diff --git a/apps/action.h b/apps/action.h
index 5df8639..39e3e09 100644
--- a/apps/action.h
+++ b/apps/action.h
@@ -76,6 +76,7 @@
     CONTEXT_KEYBOARD,
     CONTEXT_FM,
     CONTEXT_USB_HID,
+    CONTEXT_USB_HID_MOUSE,
 };
 
 
@@ -241,14 +242,52 @@
 #endif    
 
     /* USB HID codes */
-    ACTION_USB_HID_PLAY,
-    ACTION_USB_HID_STOP,
-    ACTION_USB_HID_SKIPPREV,
-    ACTION_USB_HID_SKIPNEXT,
-    ACTION_USB_HID_VOLDOWN,
-    ACTION_USB_HID_VOLUP,
-    ACTION_USB_HID_MUTE,
+    ACTION_USB_HID_FIRST, /* Place holder */
+    ACTION_USB_HID_DEC,
+    ACTION_USB_HID_INC,
+    ACTION_USB_HID_START,
+    ACTION_USB_HID_START_LONG,
+    ACTION_USB_HID_QUIT,
+    ACTION_USB_HID_QUIT_LONG,
+    ACTION_USB_HID_LEFT,
+    ACTION_USB_HID_LEFT_LONG,
+    ACTION_USB_HID_RIGHT,
+    ACTION_USB_HID_RIGHT_LONG,
+    ACTION_USB_HID_SELECT,
+    ACTION_USB_HID_SELECT_LONG,
     ACTION_USB_HID_MENU,
+    ACTION_USB_HID_MENU_LONG,
+    ACTION_USB_HID_MODE,
+    ACTION_USB_HID_MODE_LONG,
+    ACTION_USB_HID_MOUSE_UP,
+    ACTION_USB_HID_MOUSE_UP_REP,
+    ACTION_USB_HID_MOUSE_DOWN,
+    ACTION_USB_HID_MOUSE_DOWN_REP,
+    ACTION_USB_HID_MOUSE_LEFT,
+    ACTION_USB_HID_MOUSE_LEFT_REP,
+    ACTION_USB_HID_MOUSE_RIGHT,
+    ACTION_USB_HID_MOUSE_RIGHT_REP,
+    ACTION_USB_HID_MOUSE_LDRAG_UP,
+    ACTION_USB_HID_MOUSE_LDRAG_UP_REP,
+    ACTION_USB_HID_MOUSE_LDRAG_DOWN,
+    ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,
+    ACTION_USB_HID_MOUSE_LDRAG_LEFT,
+    ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,
+    ACTION_USB_HID_MOUSE_LDRAG_RIGHT,
+    ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP,
+    ACTION_USB_HID_MOUSE_RDRAG_UP,
+    ACTION_USB_HID_MOUSE_RDRAG_UP_REP,
+    ACTION_USB_HID_MOUSE_RDRAG_DOWN,
+    ACTION_USB_HID_MOUSE_RDRAG_DOWN_REP,
+    ACTION_USB_HID_MOUSE_RDRAG_LEFT,
+    ACTION_USB_HID_MOUSE_RDRAG_LEFT_REP,
+    ACTION_USB_HID_MOUSE_RDRAG_RIGHT,
+    ACTION_USB_HID_MOUSE_RDRAG_RIGHT_REP,
+    ACTION_USB_HID_MOUSE_BUTTON_LEFT,
+    ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL,
+    ACTION_USB_HID_MOUSE_BUTTON_RIGHT,
+    ACTION_USB_HID_MOUSE_BUTTON_RIGHT_REL,
+    ACTION_USB_HID_LAST, /* Place holder */
 
     LAST_ACTION_PLACEHOLDER, /* custom actions should be this + something */
 };
diff --git a/apps/keymaps/keymap-c100.c b/apps/keymaps/keymap-c100.c
index a19549d..fcb747b 100644
--- a/apps/keymaps/keymap-c100.c
+++ b/apps/keymaps/keymap-c100.c
@@ -232,17 +232,60 @@
     LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
 }; /* button_context_bmark */
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_UP,              BUTTON_NONE },
-    { ACTION_USB_HID_STOP,     BUTTON_POWER,           BUTTON_NONE },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_LEFT,            BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RIGHT,           BUTTON_NONE },
-    { ACTION_USB_HID_MUTE,     BUTTON_VOLDOWN,         BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_DOWN,            BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOLUP,                 BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOLUP|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOLDOWN,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOLDOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,       BUTTON_UP|BUTTON_REL,         BUTTON_UP },
+    { ACTION_USB_HID_START_LONG,  BUTTON_UP|BUTTON_REPEAT,      BUTTON_UP },
+    { ACTION_USB_HID_QUIT,        BUTTON_POWER|BUTTON_REL,      BUTTON_POWER },
+    { ACTION_USB_HID_QUIT_LONG,   BUTTON_POWER|BUTTON_REPEAT,   BUTTON_POWER },
+    { ACTION_USB_HID_LEFT,        BUTTON_LEFT|BUTTON_REL,       BUTTON_LEFT },
+    { ACTION_USB_HID_LEFT_LONG,   BUTTON_LEFT|BUTTON_REPEAT,    BUTTON_LEFT },
+    { ACTION_USB_HID_RIGHT,       BUTTON_RIGHT|BUTTON_REL,      BUTTON_RIGHT },
+    { ACTION_USB_HID_RIGHT_LONG,  BUTTON_RIGHT|BUTTON_REPEAT,   BUTTON_RIGHT },
+    { ACTION_USB_HID_SELECT,      BUTTON_SELECT|BUTTON_REL,     BUTTON_SELECT },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_SELECT|BUTTON_REPEAT,  BUTTON_SELECT },
+    { ACTION_USB_HID_MENU,        BUTTON_DOWN|BUTTON_REPEAT,    BUTTON_DOWN },
+    { ACTION_USB_HID_MODE,        BUTTON_DOWN|BUTTON_REL,       BUTTON_DOWN },
 
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
+
+static const struct button_mapping button_context_usb_hid_mouse[] = {
+    { ACTION_USB_HID_MOUSE_UP,               BUTTON_UP,                                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_UP_REP,           BUTTON_UP|BUTTON_REPEAT,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN,             BUTTON_DOWN,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN_REP,         BUTTON_DOWN|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT,             BUTTON_LEFT,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT_REP,         BUTTON_LEFT|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT,            BUTTON_RIGHT,                             BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT_REP,        BUTTON_RIGHT|BUTTON_REPEAT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP,         BUTTON_SELECT|BUTTON_UP,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP_REP,     BUTTON_SELECT|BUTTON_UP|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN,       BUTTON_SELECT|BUTTON_DOWN,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,   BUTTON_SELECT|BUTTON_DOWN|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT,       BUTTON_SELECT|BUTTON_LEFT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,   BUTTON_SELECT|BUTTON_LEFT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT,      BUTTON_SELECT|BUTTON_RIGHT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP,  BUTTON_SELECT|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP,         BUTTON_POWER|BUTTON_UP,                   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP_REP,     BUTTON_POWER|BUTTON_UP|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN,       BUTTON_POWER|BUTTON_DOWN,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN_REP,   BUTTON_POWER|BUTTON_DOWN|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT,       BUTTON_POWER|BUTTON_LEFT,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT_REP,   BUTTON_POWER|BUTTON_LEFT|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT,      BUTTON_POWER|BUTTON_RIGHT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT_REP,  BUTTON_POWER|BUTTON_RIGHT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT,      BUTTON_SELECT,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL,  BUTTON_SELECT|BUTTON_REL,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT,     BUTTON_POWER,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT_REL, BUTTON_POWER|BUTTON_REL,                 BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
+}; /* button_context_usb_hid_mouse */
 #endif
 
 /* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
@@ -293,9 +336,11 @@
 #endif
         case CONTEXT_KEYBOARD:
             return button_context_keyboard;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
+        case CONTEXT_USB_HID_MOUSE:
+            return button_context_usb_hid_mouse;
 #endif
         default:
             return button_context_standard;
diff --git a/apps/keymaps/keymap-c200.c b/apps/keymaps/keymap-c200.c
index acc4a6a..fa6c64c 100644
--- a/apps/keymaps/keymap-c200.c
+++ b/apps/keymaps/keymap-c200.c
@@ -264,21 +264,62 @@
     LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
 }; /* button_context_bmark */
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_UP|BUTTON_REL,             BUTTON_UP },
-    { ACTION_USB_HID_STOP,     BUTTON_UP|BUTTON_REPEAT,          BUTTON_UP },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_LEFT,                      BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RIGHT,                     BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP,                    BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP|BUTTON_REPEAT,      BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN,                  BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN|BUTTON_REPEAT,    BUTTON_NONE },
-    { ACTION_USB_HID_MUTE,     BUTTON_DOWN,                      BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_POWER,                     BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOL_UP,                    BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOL_UP|BUTTON_REPEAT,      BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOL_DOWN,                  BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOL_DOWN|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_START,       BUTTON_UP|BUTTON_REL,             BUTTON_UP },
+    { ACTION_USB_HID_START_LONG,  BUTTON_UP|BUTTON_REPEAT,          BUTTON_UP },
+    { ACTION_USB_HID_QUIT,        BUTTON_POWER|BUTTON_REL,          BUTTON_POWER },
+    { ACTION_USB_HID_QUIT_LONG,   BUTTON_POWER|BUTTON_REPEAT,       BUTTON_POWER },
+    { ACTION_USB_HID_LEFT,        BUTTON_LEFT|BUTTON_REL,           BUTTON_LEFT },
+    { ACTION_USB_HID_LEFT_LONG,   BUTTON_LEFT|BUTTON_REPEAT,        BUTTON_LEFT },
+    { ACTION_USB_HID_RIGHT,       BUTTON_RIGHT|BUTTON_REL,          BUTTON_RIGHT },
+    { ACTION_USB_HID_RIGHT_LONG,  BUTTON_RIGHT|BUTTON_REPEAT,       BUTTON_RIGHT },
+    { ACTION_USB_HID_SELECT,      BUTTON_SELECT|BUTTON_REL,         BUTTON_SELECT },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_SELECT|BUTTON_REPEAT,      BUTTON_SELECT },
+    { ACTION_USB_HID_MENU,        BUTTON_DOWN|BUTTON_REL,           BUTTON_DOWN },
+    { ACTION_USB_HID_MENU_LONG,   BUTTON_DOWN|BUTTON_REPEAT,        BUTTON_DOWN },
+    { ACTION_USB_HID_MODE,        BUTTON_REC|BUTTON_REL,            BUTTON_REC },
+    { ACTION_USB_HID_MODE_LONG,   BUTTON_REC|BUTTON_REPEAT,         BUTTON_REC },
 
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
+
+static const struct button_mapping button_context_usb_hid_mouse[] = {
+    { ACTION_USB_HID_MOUSE_UP,               BUTTON_UP,                                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_UP_REP,           BUTTON_UP|BUTTON_REPEAT,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN,             BUTTON_DOWN,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN_REP,         BUTTON_DOWN|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT,             BUTTON_LEFT,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT_REP,         BUTTON_LEFT|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT,            BUTTON_RIGHT,                             BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT_REP,        BUTTON_RIGHT|BUTTON_REPEAT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP,         BUTTON_SELECT|BUTTON_UP,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP_REP,     BUTTON_SELECT|BUTTON_UP|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN,       BUTTON_SELECT|BUTTON_DOWN,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,   BUTTON_SELECT|BUTTON_DOWN|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT,       BUTTON_SELECT|BUTTON_LEFT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,   BUTTON_SELECT|BUTTON_LEFT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT,      BUTTON_SELECT|BUTTON_RIGHT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP,  BUTTON_SELECT|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP,         BUTTON_POWER|BUTTON_UP,                   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP_REP,     BUTTON_POWER|BUTTON_UP|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN,       BUTTON_POWER|BUTTON_DOWN,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN_REP,   BUTTON_POWER|BUTTON_DOWN|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT,       BUTTON_POWER|BUTTON_LEFT,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT_REP,   BUTTON_POWER|BUTTON_LEFT|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT,      BUTTON_POWER|BUTTON_RIGHT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT_REP,  BUTTON_POWER|BUTTON_RIGHT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT,      BUTTON_SELECT,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL,  BUTTON_SELECT|BUTTON_REL,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT,     BUTTON_POWER,                             BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT_REL, BUTTON_POWER|BUTTON_REL,                  BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
+}; /* button_context_usb_hid_mouse */
 #endif
 
 /* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
@@ -327,9 +368,11 @@
 #endif
         case CONTEXT_KEYBOARD:
             return button_context_keyboard;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
+        case CONTEXT_USB_HID_MOUSE:
+            return button_context_usb_hid_mouse;
 #endif
         default:
             return button_context_standard;
diff --git a/apps/keymaps/keymap-clip.c b/apps/keymaps/keymap-clip.c
index 5b45f4f..21728db 100644
--- a/apps/keymaps/keymap-clip.c
+++ b/apps/keymaps/keymap-clip.c
@@ -273,21 +273,62 @@
     LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
 }; /* button_context_bmark */
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_UP,                        BUTTON_NONE },
-    { ACTION_USB_HID_STOP,     BUTTON_POWER,                     BUTTON_NONE },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_LEFT,                      BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RIGHT,                     BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP,                    BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP|BUTTON_REPEAT,      BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN,                  BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN|BUTTON_REPEAT,    BUTTON_NONE },
-    { ACTION_USB_HID_MUTE,     BUTTON_SELECT,                    BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_DOWN,                      BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOL_UP,                 BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOL_DOWN,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,       BUTTON_UP|BUTTON_REL,          BUTTON_UP },
+    { ACTION_USB_HID_START_LONG,  BUTTON_UP|BOTTOM_REPEAT,       BUTTON_UP },
+    { ACTION_USB_HID_QUIT,        BUTTON_HOME|BUTTON_REL,        BUTTON_HOME },
+    { ACTION_USB_HID_QUIT_LONG,   BUTTON_HOME|BUTTON_REPEAT,     BUTTON_HOME },
+    { ACTION_USB_HID_LEFT,        BUTTON_LEFT|BUTTON_REL,        BUTTON_LEFT },
+    { ACTION_USB_HID_LEFT_LONG,   BUTTON_LEFT|BUTTON_REPEAT,     BUTTON_LEFT },
+    { ACTION_USB_HID_RIGHT,       BUTTON_RIGHT|BUTTON_REL,       BUTTON_RIGHT },
+    { ACTION_USB_HID_RIGHT_LONG,  BUTTON_RIGHT|BUTTON_REPEAT,    BUTTON_RIGHT },
+    { ACTION_USB_HID_SELECT,      BUTTON_SELECT|BUTTON_REL,      BUTTON_SELECT },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_SELECT|BUTTON_REPEAT,   BUTTON_SELECT },
+    { ACTION_USB_HID_MENU,        BUTTON_DOWN|BUTTON_REL,        BUTTON_DOWN },
+    { ACTION_USB_HID_MENU_LONG,   BUTTON_DOWN|BUTTON_REPEAT,     BUTTON_DOWN },
+    { ACTION_USB_HID_MODE,        BUTTON_POWER|BUTTON_REL,       BUTTON_POWER },
+    { ACTION_USB_HID_MODE_LONG,   BUTTON_POWER|BUTTON_REPEAT,    BUTTON_POWER },
 
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
+
+static const struct button_mapping button_context_usb_hid_mouse[] = {
+    { ACTION_USB_HID_MOUSE_UP,               BUTTON_UP,                                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_UP_REP,           BUTTON_UP|BUTTON_REPEAT,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN,             BUTTON_DOWN,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN_REP,         BUTTON_DOWN|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT,             BUTTON_LEFT,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT_REP,         BUTTON_LEFT|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT,            BUTTON_RIGHT,                             BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT_REP,        BUTTON_RIGHT|BUTTON_REPEAT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP,         BUTTON_SELECT|BUTTON_UP,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP_REP,     BUTTON_SELECT|BUTTON_UP|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN,       BUTTON_SELECT|BUTTON_DOWN,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,   BUTTON_SELECT|BUTTON_DOWN|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT,       BUTTON_SELECT|BUTTON_LEFT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,   BUTTON_SELECT|BUTTON_LEFT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT,      BUTTON_SELECT|BUTTON_RIGHT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP,  BUTTON_SELECT|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP,         BUTTON_HOME|BUTTON_UP,                    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP_REP,     BUTTON_HOME|BUTTON_UP|BUTTON_REPEAT,      BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN,       BUTTON_HOME|BUTTON_DOWN,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN_REP,   BUTTON_HOME|BUTTON_DOWN|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT,       BUTTON_HOME|BUTTON_LEFT,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT_REP,   BUTTON_HOME|BUTTON_LEFT|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT,      BUTTON_HOME|BUTTON_RIGHT,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT_REP,  BUTTON_HOME|BUTTON_RIGHT|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT,      BUTTON_SELECT,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL,  BUTTON_SELECT|BUTTON_REL,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT,     BUTTON_HOME,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT_REL, BUTTON_HOME|BUTTON_REL,                   BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
+}; /* button_context_usb_hid_mouse */
 #endif
 
 /* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
@@ -337,9 +378,11 @@
 #endif
         case CONTEXT_KEYBOARD:
             return button_context_keyboard;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
+        case CONTEXT_USB_HID_MOUSE:
+            return button_context_usb_hid_mouse;
 #endif
         default:
             return button_context_standard;
diff --git a/apps/keymaps/keymap-e200.c b/apps/keymaps/keymap-e200.c
index ede0651..ef5c932 100644
--- a/apps/keymaps/keymap-e200.c
+++ b/apps/keymaps/keymap-e200.c
@@ -275,21 +275,62 @@
     LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
 }; /* button_context_bmark */
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_UP,                        BUTTON_NONE },
-    { ACTION_USB_HID_STOP,     BUTTON_POWER,                     BUTTON_NONE },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_LEFT,                      BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RIGHT,                     BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_SCROLL_FWD,                BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_SCROLL_FWD|BUTTON_REPEAT,  BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_SCROLL_BACK,               BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE },
-    { ACTION_USB_HID_MUTE,     BUTTON_SELECT,                    BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_DOWN,                      BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_SCROLL_FWD,                BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_SCROLL_FWD|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_SCROLL_BACK,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,       BUTTON_UP|BUTTON_REL,             BUTTON_UP },
+    { ACTION_USB_HID_START_LONG,  BUTTON_UP|BUTTON_REPEAT,          BUTTON_UP },
+    { ACTION_USB_HID_QUIT,        BUTTON_POWER|BUTTON_REL,          BUTTON_POWER },
+    { ACTION_USB_HID_QUIT_LONG,   BUTTON_POWER|BUTTON_REPEAT,       BUTTON_POWER },
+    { ACTION_USB_HID_LEFT,        BUTTON_LEFT|BUTTON_REL,           BUTTON_LEFT },
+    { ACTION_USB_HID_LEFT_LONG,   BUTTON_LEFT|BUTTON_REPEAT,        BUTTON_LEFT },
+    { ACTION_USB_HID_RIGHT,       BUTTON_RIGHT|BUTTON_REL,          BUTTON_RIGHT },
+    { ACTION_USB_HID_RIGHT_LONG,  BUTTON_RIGHT|BUTTON_REPEAT,       BUTTON_RIGHT },
+    { ACTION_USB_HID_SELECT,      BUTTON_SELECT|BUTTON_REL,         BUTTON_SELECT },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_SELECT|BUTTON_REPEAT,      BUTTON_SELECT },
+    { ACTION_USB_HID_MENU,        BUTTON_DOWN|BUTTON_REL,           BUTTON_DOWN },
+    { ACTION_USB_HID_MENU_LONG,   BUTTON_DOWN|BUTTON_REPEAT,        BUTTON_DOWN },
+    { ACTION_USB_HID_MODE,        BUTTON_REC|BUTTON_REL,            BUTTON_REC },
+    { ACTION_USB_HID_MODE_LONG,   BUTTON_REC|BUTTON_REPEAT,         BUTTON_REC },
 
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
+
+static const struct button_mapping button_context_usb_hid_mouse[] = {
+    { ACTION_USB_HID_MOUSE_UP,               BUTTON_UP,                                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_UP_REP,           BUTTON_UP|BUTTON_REPEAT,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN,             BUTTON_DOWN,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN_REP,         BUTTON_DOWN|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT,             BUTTON_LEFT,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT_REP,         BUTTON_LEFT|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT,            BUTTON_RIGHT,                             BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT_REP,        BUTTON_RIGHT|BUTTON_REPEAT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP,         BUTTON_SELECT|BUTTON_UP,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP_REP,     BUTTON_SELECT|BUTTON_UP|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN,       BUTTON_SELECT|BUTTON_DOWN,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,   BUTTON_SELECT|BUTTON_DOWN|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT,       BUTTON_SELECT|BUTTON_LEFT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,   BUTTON_SELECT|BUTTON_LEFT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT,      BUTTON_SELECT|BUTTON_RIGHT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP,  BUTTON_SELECT|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP,         BUTTON_POWER|BUTTON_UP,                   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP_REP,     BUTTON_POWER|BUTTON_UP|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN,       BUTTON_POWER|BUTTON_DOWN,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN_REP,   BUTTON_POWER|BUTTON_DOWN|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT,       BUTTON_POWER|BUTTON_LEFT,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT_REP,   BUTTON_POWER|BUTTON_LEFT|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT,      BUTTON_POWER|BUTTON_RIGHT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT_REP,  BUTTON_POWER|BUTTON_RIGHT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT,      BUTTON_SELECT,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL,  BUTTON_SELECT|BUTTON_REL,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT,     BUTTON_POWER,                             BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT_REL, BUTTON_POWER|BUTTON_REL,                  BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
+}; /* button_context_usb_hid_mouse */
 #endif
 
 /* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
@@ -339,9 +380,11 @@
             return button_context_recscreen;
         case CONTEXT_KEYBOARD:
             return button_context_keyboard;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
+        case CONTEXT_USB_HID_MOUSE:
+            return button_context_usb_hid_mouse;
 #endif
         default:
             return button_context_standard;
diff --git a/apps/keymaps/keymap-gigabeat-s.c b/apps/keymaps/keymap-gigabeat-s.c
index 4fb7e1b..6c5b6de 100644
--- a/apps/keymaps/keymap-gigabeat-s.c
+++ b/apps/keymaps/keymap-gigabeat-s.c
@@ -468,40 +468,91 @@
     LAST_ITEM_IN_LIST
 }; /* remote_button_context_right_is_inc */
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_PLAY,                      BUTTON_NONE },
-    { ACTION_USB_HID_STOP,     BUTTON_POWER,                     BUTTON_NONE },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_LEFT,                      BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RIGHT,                     BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_UP,                        BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_UP|BUTTON_REPEAT,          BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP,                    BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP|BUTTON_REPEAT,      BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_DOWN,                      BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_DOWN|BUTTON_REPEAT,        BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN,                  BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN|BUTTON_REPEAT,    BUTTON_NONE },
-    { ACTION_USB_HID_MUTE,     BUTTON_SELECT,                    BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_MENU,                      BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOL_UP,                 BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOL_DOWN,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,       BUTTON_PLAY|BUTTON_REL,        BUTTON_START },
+    { ACTION_USB_HID_START_LONG,  BUTTON_PLAY|BUTTON_REPEAT,     BUTTON_START },
+    { ACTION_USB_HID_QUIT,        BUTTON_MENU|BUTTON_REL,        BUTTON_MENU },
+    { ACTION_USB_HID_QUIT_LONG,   BUTTON_MENU|BUTTON_REPEAT,     BUTTON_MENU },
+    { ACTION_USB_HID_LEFT,        BUTTON_LEFT|BUTTON_REL,        BUTTON_LEFT },
+    { ACTION_USB_HID_LEFT_LONG,   BUTTON_LEFT|BUTTON_REPEAT,     BUTTON_LEFT },
+    { ACTION_USB_HID_RIGHT,       BUTTON_RIGHT|BUTTON_REL,       BUTTON_RIGHT },
+    { ACTION_USB_HID_RIGHT_LONG,  BUTTON_RIGHT|BUTTON_REPEAT,    BUTTON_RIGHT },
+    { ACTION_USB_HID_SELECT,      BUTTON_SELECT|BUTTON_REL,      BUTTON_SELECT },
+    { ACTION_USB_HID_SELECT,      BUTTON_BACK|BUTTON_REL,        BUTTON_BACK },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_SELECT|BUTTON_REPEAT,   BUTTON_SELECT },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_BACK|BUTTON_REPEAT,     BUTTON_BACK },
+    { ACTION_USB_HID_MENU,        BUTTON_DOWN|BUTTON_REL,        BUTTON_DOWN },
+    { ACTION_USB_HID_MENU_LONG,   BUTTON_DOWN|BUTTON_REPEAT,     BUTTON_DOWN },
+    { ACTION_USB_HID_MODE,        BUTTON_POWER|BUTTON_REL,       BUTTON_POWER },
+    { ACTION_USB_HID_MODE_LONG,   BUTTON_POWER|BUTTON_REPEAT,    BUTTON_POWER },
 
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
 
 static const struct button_mapping remote_button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_RC_PLAY,                   BUTTON_NONE },
-    { ACTION_USB_HID_STOP,     BUTTON_RC_PLAY|BUTTON_REPEAT,     BUTTON_NONE },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_RC_REW,                    BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RC_FF,                     BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_RC_VOL_UP,                 BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_RC_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_RC_VOL_DOWN,               BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
-    { ACTION_USB_HID_MUTE,     BUTTON_RC_DSP|BUTTON_REPEAT,      BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_RC_DSP,                    BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_RC_VOL_UP,                 BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_RC_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_RC_VOL_DOWN,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,       BUTTON_RC_PLAY|BUTTON_REL,        BUTTON_RC_PLAY },
+    { ACTION_USB_HID_QUIT,        BUTTON_RC_PLAY|BUTTON_REPEAT,     BUTTON_RC_PLAY },
+    { ACTION_USB_HID_LEFT,        BUTTON_RC_REW|BUTTON_REL,         BUTTON_RC_REW },
+    { ACTION_USB_HID_RIGHT,       BUTTON_RC_FF|BUTTON_REL,          BUTTON_RC_FF},
+    { ACTION_USB_HID_SELECT,      BUTTON_RC_FF|BUTTON_REPEAT,       BUTTON_RC_FF },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_RC_REW|BUTTON_REPEAT,      BUTTON_RC_REW },
+    { ACTION_USB_HID_MENU,        BUTTON_RC_DSP|BUTTON_REPEAT,      BUTTON_RC_DSP },
+    { ACTION_USB_HID_MODE,        BUTTON_RC_DSP|BUTTON_REL,         BUTTON_RC_DSP },
 
     LAST_ITEM_IN_LIST
 }; /* remote_button_context_usb_hid */
+
+static const struct button_mapping button_context_usb_hid_mouse[] = {
+    { ACTION_USB_HID_MOUSE_UP,               BUTTON_UP,                                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_UP_REP,           BUTTON_UP|BUTTON_REPEAT,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN,             BUTTON_DOWN,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN_REP,         BUTTON_DOWN|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT,             BUTTON_LEFT,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT_REP,         BUTTON_LEFT|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT,            BUTTON_RIGHT,                             BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT_REP,        BUTTON_RIGHT|BUTTON_REPEAT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP,         BUTTON_SELECT|BUTTON_UP,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP,         BUTTON_BACK|BUTTON_UP,                    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP_REP,     BUTTON_SELECT|BUTTON_UP|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP_REP,     BUTTON_BACK|BUTTON_UP|BUTTON_REPEAT,      BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN,       BUTTON_SELECT|BUTTON_DOWN,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN,       BUTTON_BACK|BUTTON_DOWN,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,   BUTTON_SELECT|BUTTON_DOWN|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,   BUTTON_BACK|BUTTON_DOWN|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT,       BUTTON_SELECT|BUTTON_LEFT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT,       BUTTON_BACK|BUTTON_LEFT,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,   BUTTON_SELECT|BUTTON_LEFT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,   BUTTON_BACK|BUTTON_LEFT|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT,      BUTTON_SELECT|BUTTON_RIGHT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT,      BUTTON_BACK|BUTTON_RIGHT,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP,  BUTTON_SELECT|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP,  BUTTON_BACK|BUTTON_RIGHT|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP,         BUTTON_MENU|BUTTON_UP,                    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP_REP,     BUTTON_MENU|BUTTON_UP|BUTTON_REPEAT,      BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN,       BUTTON_MENU|BUTTON_DOWN,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN_REP,   BUTTON_MENU|BUTTON_DOWN|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT,       BUTTON_MENU|BUTTON_LEFT,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT_REP,   BUTTON_MENU|BUTTON_LEFT|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT,      BUTTON_MENU|BUTTON_RIGHT,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT_REP,  BUTTON_MENU|BUTTON_RIGHT|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT,      BUTTON_SELECT,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT,      BUTTON_BACK,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL,  BUTTON_SELECT|BUTTON_REL,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL,  BUTTON_BACK|BUTTON_REL,                   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT,     BUTTON_MENU,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT_REL, BUTTON_MENU|BUTTON_REL,                   BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
+}; /* button_context_usb_hid_mouse */
 #endif
 
 static const struct button_mapping* get_context_mapping_remote( int context )
@@ -546,7 +597,7 @@
         case CONTEXT_FM:
             return remote_button_context_radio;
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return remote_button_context_usb_hid;
 #endif
@@ -617,9 +668,11 @@
         case CONTEXT_FM:
             return button_context_radio;
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
+        case CONTEXT_USB_HID_MOUSE:
+            return button_context_usb_hid_mouse;
 #endif
         default:
             return button_context_standard;
diff --git a/apps/keymaps/keymap-h10.c b/apps/keymaps/keymap-h10.c
index ad1ed64..8167339 100644
--- a/apps/keymaps/keymap-h10.c
+++ b/apps/keymaps/keymap-h10.c
@@ -337,30 +337,37 @@
     
 };
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_PLAY|BUTTON_REL,           BUTTON_PLAY },
-    { ACTION_USB_HID_STOP,     BUTTON_PLAY|BUTTON_REPEAT,        BUTTON_PLAY },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_REW,                       BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_FF,                        BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_SCROLL_UP,                 BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_SCROLL_UP|BUTTON_REPEAT,   BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_SCROLL_DOWN,               BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_SCROLL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_POWER,                     BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_SCROLL_UP,                 BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_SCROLL_UP|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_SCROLL_DOWN,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_SCROLL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,       BUTTON_PLAY|BUTTON_REL,           BUTTON_PLAY },
+    { ACTION_USB_HID_START_LONG,  BUTTON_PLAY|BUTTON_REPEAT,        BUTTON_PLAY },
+    { ACTION_USB_HID_QUIT,        BUTTON_REW|BUTTON_REL,            BUTTON_REW },
+    { ACTION_USB_HID_LEFT,        BUTTON_LEFT|BUTTON_REL,           BUTTON_LEFT },
+    { ACTION_USB_HID_LEFT_LONG,   BUTTON_LEFT|BUTTON_REPEAT,        BUTTON_LEFT },
+    { ACTION_USB_HID_RIGHT,       BUTTON_RIGHT|BUTTON_REL,          BUTTON_RIGHT },
+    { ACTION_USB_HID_RIGHT_LONG,  BUTTON_RIGHT|BUTTON_REPEAT,       BUTTON_RIGHT },
+    { ACTION_USB_HID_SELECT,      BUTTON_FF|BUTTON_REL,             BUTTON_FF },
+    { ACTION_USB_HID_MENU,        BUTTON_POWER|BUTTON_REL,          BUTTON_POWER },
+    { ACTION_USB_HID_MODE,        BUTTON_POWER|BUTTON_REPEAT,       BUTTON_POWER },
 
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
 
 static const struct button_mapping remote_button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_RC_PLAY,                   BUTTON_NONE },
-    { ACTION_USB_HID_STOP,     BUTTON_RC_PLAY|BUTTON_REPEAT,     BUTTON_NONE },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_RC_REW,                    BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RC_FF,                     BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_RC_VOL_UP,                 BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_RC_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_RC_VOL_DOWN,               BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_INC,        BUTTON_RC_VOL_UP,                 BUTTON_NONE },
+    { ACTION_USB_HID_INC,        BUTTON_RC_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,        BUTTON_RC_VOL_DOWN,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,        BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,      BUTTON_RC_PLAY|BUTTON_REL,        BUTTON_RC_PLAY },
+    { ACTION_USB_HID_QUIT,       BUTTON_RC_PLAY|BUTTON_REPEAT,     BUTTON_RC_PLAY },
+    { ACTION_USB_HID_LEFT,       BUTTON_RC_REW|BUTTON_REL,         BUTTON_RC_REW },
+    { ACTION_USB_HID_LEFT_LONG,  BUTTON_RC_REW|BUTTON_REPEAT,      BUTTON_RC_REW },
+    { ACTION_USB_HID_RIGHT,      BUTTON_RC_FF|BUTTON_REL,          BUTTON_RC_FF },
+    { ACTION_USB_HID_RIGHT_LONG, BUTTON_RC_FF|BUTTON_REPEAT,       BUTTON_RC_FF },
 
     LAST_ITEM_IN_LIST
 }; /* remote_button_context_usb_hid */
@@ -395,7 +402,7 @@
             return remote_button_context_pitchscreen;
         case CONTEXT_RECSCREEN:
             return button_context_recscreen;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return remote_button_context_usb_hid;
 #endif
@@ -453,7 +460,7 @@
             return button_context_recscreen;
         case CONTEXT_FM:
             return button_context_radio;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
 #endif
diff --git a/apps/keymaps/keymap-hdd1630.c b/apps/keymaps/keymap-hdd1630.c
index 4565c28..ddb357a 100644
--- a/apps/keymaps/keymap-hdd1630.c
+++ b/apps/keymaps/keymap-hdd1630.c
@@ -284,25 +284,62 @@
 };
 #endif
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_VIEW,                      BUTTON_NONE },
-    { ACTION_USB_HID_STOP,     BUTTON_POWER,                     BUTTON_NONE },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_LEFT,                      BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RIGHT,                     BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_UP,                        BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_UP|BUTTON_REPEAT,          BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP,                    BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP|BUTTON_REPEAT,      BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_DOWN,                      BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_DOWN|BUTTON_REPEAT,        BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN,                  BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN|BUTTON_REPEAT,    BUTTON_NONE },
-    { ACTION_USB_HID_MUTE,     BUTTON_SELECT,                    BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_MENU,                      BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOL_UP,                 BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOL_DOWN,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,       BUTTON_UP|BUTTON_REL,          BUTTON_UP },
+    { ACTION_USB_HID_START_LONG,  BUTTON_UP|BUTTON_REPEAT,       BUTTON_UP },
+    { ACTION_USB_HID_QUIT,        BUTTON_POWER|BUTTON_REL,       BUTTON_POWER },
+    { ACTION_USB_HID_QUIT_LONG,   BUTTON_POWER|BUTTON_REPEAT,    BUTTON_POWER },
+    { ACTION_USB_HID_LEFT,        BUTTON_LEFT|BUTTON_REL,        BUTTON_LEFT },
+    { ACTION_USB_HID_LEFT_LONG,   BUTTON_LEFT|BUTTON_REPEAT,     BUTTON_LEFT },
+    { ACTION_USB_HID_RIGHT,       BUTTON_RIGHT|BUTTON_REL,       BUTTON_RIGHT },
+    { ACTION_USB_HID_RIGHT_LONG,  BUTTON_RIGHT|BUTTON_REPEAT,    BUTTON_RIGHT },
+    { ACTION_USB_HID_SELECT,      BUTTON_SELECT|BUTTON_REL,      BUTTON_SELECT },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_SELECT|BUTTON_REPEAT,   BUTTON_SELECT },
+    { ACTION_USB_HID_MENU,        BUTTON_MENU|BUTTON_REL,        BUTTON_MENU },
+    { ACTION_USB_HID_MENU_LONG,   BUTTON_MENU|BUTTON_REPEAT,     BUTTON_MENU },
+    { ACTION_USB_HID_MODE,        BUTTON_VIEW|BUTTON_REL,        BUTTON_VIEW },
+    { ACTION_USB_HID_MODE_LONG,   BUTTON_VIEW|BUTTON_REPEAT,     BUTTON_VIEW },
 
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
+
+static const struct button_mapping button_context_usb_hid_mouse[] = {
+    { ACTION_USB_HID_MOUSE_UP,               BUTTON_UP,                                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_UP_REP,           BUTTON_UP|BUTTON_REPEAT,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN,             BUTTON_DOWN,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN_REP,         BUTTON_DOWN|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT,             BUTTON_LEFT,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT_REP,         BUTTON_LEFT|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT,            BUTTON_RIGHT,                             BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT_REP,        BUTTON_RIGHT|BUTTON_REPEAT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP,         BUTTON_SELECT|BUTTON_UP,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP_REP,     BUTTON_SELECT|BUTTON_UP|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN,       BUTTON_SELECT|BUTTON_DOWN,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,   BUTTON_SELECT|BUTTON_DOWN|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT,       BUTTON_SELECT|BUTTON_LEFT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,   BUTTON_SELECT|BUTTON_LEFT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT,      BUTTON_SELECT|BUTTON_RIGHT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP,  BUTTON_SELECT|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP,         BUTTON_POWER|BUTTON_UP,                   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP_REP,     BUTTON_POWER|BUTTON_UP|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN,       BUTTON_POWER|BUTTON_DOWN,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN_REP,   BUTTON_POWER|BUTTON_DOWN|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT,       BUTTON_POWER|BUTTON_LEFT,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT_REP,   BUTTON_POWER|BUTTON_LEFT|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT,      BUTTON_POWER|BUTTON_RIGHT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT_REP,  BUTTON_POWER|BUTTON_RIGHT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT,      BUTTON_SELECT,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL,  BUTTON_SELECT|BUTTON_REL,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT,     BUTTON_POWER,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT_REL, BUTTON_POWER|BUTTON_REL,                 BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
+}; /* button_context_usb_hid_mouse */
 #endif
 
 const struct button_mapping* get_context_mapping(int context)
@@ -352,9 +389,11 @@
         case CONTEXT_FM:
             return button_context_radio;
 #endif
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
+        case CONTEXT_USB_HID_MOUSE:
+            return button_context_usb_hid_mouse;
 #endif
     }
     return button_context_standard;
diff --git a/apps/keymaps/keymap-ipod.c b/apps/keymaps/keymap-ipod.c
index 774597a..99c7f93 100644
--- a/apps/keymaps/keymap-ipod.c
+++ b/apps/keymaps/keymap-ipod.c
@@ -193,21 +193,48 @@
 }; /* button_context_recscreen */
 #endif
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_PLAY|BUTTON_REL,           BUTTON_PLAY },
-    { ACTION_USB_HID_STOP,     BUTTON_PLAY|BUTTON_REPEAT,        BUTTON_PLAY },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_LEFT,                      BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RIGHT,                     BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_SCROLL_FWD,                BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_SCROLL_FWD|BUTTON_REPEAT,  BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_SCROLL_BACK,               BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE },
-    { ACTION_USB_HID_MUTE,     BUTTON_SELECT,                    BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_MENU,                      BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_SCROLL_FWD,                BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_SCROLL_FWD|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_SCROLL_BACK,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,       BUTTON_PLAY|BUTTON_REL,           BUTTON_PLAY },
+    { ACTION_USB_HID_QUIT,        BUTTON_PLAY|BUTTON_REPEAT,        BUTTON_PLAY },
+    { ACTION_USB_HID_LEFT,        BUTTON_LEFT|BUTTON_REL,           BUTTON_LEFT },
+    { ACTION_USB_HID_LEFT_LONG,   BUTTON_LEFT|BUTTON_REPEAT,        BUTTON_LEFT },
+    { ACTION_USB_HID_RIGHT,       BUTTON_RIGHT|BUTTON_REL,          BUTTON_RIGHT },
+    { ACTION_USB_HID_RIGHT_LONG,  BUTTON_RIGHT|BUTTON_REPEAT,       BUTTON_RIGHT },
+    { ACTION_USB_HID_SELECT,      BUTTON_SELECT|BUTTON_REL,         BUTTON_SELECT },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_SELECT|BUTTON_REPEAT,      BUTTON_SELECT },
+    { ACTION_USB_HID_MENU,        BUTTON_MENU|BUTTON_REL,           BUTTON_MENU },
+    { ACTION_USB_HID_MODE,        BUTTON_MENU|BUTTON_REPEAT,        BUTTON_MENU },
 
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
+
+static const struct button_mapping button_context_usb_hid_mouse[] = {
+    { ACTION_USB_HID_MOUSE_UP,              BUTTON_MENU,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_UP_REP,          BUTTON_MENU|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN,            BUTTON_PLAY,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN_REP,        BUTTON_PLAY|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT,            BUTTON_LEFT,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT_REP,        BUTTON_LEFT|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT,           BUTTON_RIGHT,                             BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT_REP,       BUTTON_RIGHT|BUTTON_REPEAT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP,        BUTTON_SELECT|BUTTON_MENU,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP_REP,    BUTTON_SELECT|BUTTON_MENU|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN,      BUTTON_SELECT|BUTTON_PLAY,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,  BUTTON_SELECT|BUTTON_PLAY|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT,      BUTTON_SELECT|BUTTON_LEFT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,  BUTTON_SELECT|BUTTON_LEFT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT,     BUTTON_SELECT|BUTTON_RIGHT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP, BUTTON_SELECT|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT,     BUTTON_SELECT,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL, BUTTON_SELECT|BUTTON_REL,                 BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
+}; /* button_context_usb_hid_mouse */
 #endif
 
 #if BUTTON_REMOTE != 0
@@ -242,16 +269,18 @@
     LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
 };
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping remote_button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_RC_PLAY,                   BUTTON_NONE },
-    { ACTION_USB_HID_STOP,     BUTTON_RC_PLAY|BUTTON_REPEAT,     BUTTON_NONE },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_RC_LEFT,                   BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RC_RIGHT,                  BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_RC_VOL_UP,                 BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_RC_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_RC_VOL_DOWN,               BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_INC,        BUTTON_RC_VOL_UP,                 BUTTON_NONE },
+    { ACTION_USB_HID_INC,        BUTTON_RC_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,        BUTTON_RC_VOL_DOWN,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,        BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,      BUTTON_RC_PLAY|BUTTON_REL,        BUTTON_RC_PLAY },
+    { ACTION_USB_HID_QUIT,       BUTTON_RC_PLAY|BUTTON_REPEAT,     BUTTON_RC_PLAY },
+    { ACTION_USB_HID_LEFT,       BUTTON_RC_LEFT|BUTTON_REL,        BUTTON_RC_LEFT },
+    { ACTION_USB_HID_LEFT_LONG,  BUTTON_RC_LEFT|BUTTON_REPEAT,     BUTTON_RC_LEFT },
+    { ACTION_USB_HID_RIGHT,      BUTTON_RC_RIGHT|BUTTON_REL,       BUTTON_RC_RIGHT },
+    { ACTION_USB_HID_RIGHT_LONG, BUTTON_RC_RIGHT|BUTTON_REPEAT,    BUTTON_RC_RIGHT },
 
     LAST_ITEM_IN_LIST
 }; /* remote_button_context_usb_hid */
@@ -265,7 +294,7 @@
     {
         case CONTEXT_WPS:
             return remote_button_context_wps;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return remote_button_context_usb_hid;
 #endif
@@ -321,9 +350,11 @@
         case CONTEXT_RECSCREEN:
             return button_context_recscreen;
 #endif
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
+        case CONTEXT_USB_HID_MOUSE:
+            return button_context_usb_hid_mouse;
 #endif
         default:
             return button_context_standard;
diff --git a/apps/keymaps/keymap-mr100.c b/apps/keymaps/keymap-mr100.c
index bf9da0d..a605131 100644
--- a/apps/keymaps/keymap-mr100.c
+++ b/apps/keymaps/keymap-mr100.c
@@ -315,7 +315,7 @@
     LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
 };
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
     { ACTION_USB_HID_PLAY,     BUTTON_PLAY,                      BUTTON_NONE },
     { ACTION_USB_HID_STOP,     BUTTON_POWER,                     BUTTON_NONE },
@@ -357,7 +357,7 @@
         case CONTEXT_MAINMENU:
         case CONTEXT_TREE:
             return remote_button_context_tree;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return remote_button_context_usb_hid;
 #endif
@@ -411,7 +411,7 @@
             return button_context_pitchscreen;
         case CONTEXT_KEYBOARD:
             return button_context_keyboard;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
 #endif
diff --git a/apps/keymaps/keymap-ondavx747.c b/apps/keymaps/keymap-ondavx747.c
index 6eb2230..ee59059 100644
--- a/apps/keymaps/keymap-ondavx747.c
+++ b/apps/keymaps/keymap-ondavx747.c
@@ -167,14 +167,16 @@
     LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
 }; /* button_context_keyboard */
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP,                    BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP|BUTTON_REPEAT,      BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN,                  BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN|BUTTON_REPEAT,    BUTTON_NONE },
-    { ACTION_USB_HID_MUTE,     BUTTON_POWER,                     BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_MENU,                      BUTTON_NONE },
+    { ACTION_USB_HID_INC,    BUTTON_VOL_UP,                 BUTTON_NONE },
+    { ACTION_USB_HID_INC,    BUTTON_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,    BUTTON_VOL_DOWN,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,    BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_QUIT,   BUTTON_POWER|BUTTON_REPEAT,    BUTTON_SELECT },
+    { ACTION_USB_HID_SELECT, BUTTON_POWER|BUTTON_REL,       BUTTON_SELECT },
+    { ACTION_USB_HID_MENU,   BUTTON_MENU|BUTTON_REPEAT,     BUTTON_MENU },
+    { ACTION_USB_HID_MODE,   BUTTON_MENU|BUTTON_REL,        BUTTON_MENU },
 
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
diff --git a/apps/keymaps/keymap-ondavx777.c b/apps/keymaps/keymap-ondavx777.c
index 99f509b..f492a19 100644
--- a/apps/keymaps/keymap-ondavx777.c
+++ b/apps/keymaps/keymap-ondavx777.c
@@ -110,7 +110,7 @@
     LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
 }; /* button_context_keyboard */
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
@@ -162,7 +162,7 @@
             return button_context_pitchscreen;
         case CONTEXT_KEYBOARD:
             return button_context_keyboard;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
 #endif
diff --git a/apps/keymaps/keymap-sa9200.c b/apps/keymaps/keymap-sa9200.c
index 3e83932..cb9c746 100644
--- a/apps/keymaps/keymap-sa9200.c
+++ b/apps/keymaps/keymap-sa9200.c
@@ -276,30 +276,66 @@
     LAST_ITEM_IN_LIST
 }; /* button_context_keyboard */
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_PLAY,                     BUTTON_NONE },
-    { ACTION_USB_HID_STOP,     BUTTON_PREV,                     BUTTON_NONE },
-    { ACTION_USB_HID_STOP,     BUTTON_POWER,                    BUTTON_NONE },
-
-    { ACTION_USB_HID_SKIPPREV, BUTTON_LEFT,                     BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_RIGHT,                    BUTTON_NONE },
-
-    { ACTION_USB_HID_VOLUP,    BUTTON_UP,                       BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_UP|BUTTON_REPEAT,         BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP,                   BUTTON_NONE },
-    { ACTION_USB_HID_VOLUP,    BUTTON_VOL_UP|BUTTON_REPEAT,     BUTTON_NONE },
-
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_DOWN,                     BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_DOWN|BUTTON_REPEAT,       BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN,                 BUTTON_NONE },
-    { ACTION_USB_HID_VOLDOWN,  BUTTON_VOL_DOWN|BUTTON_REPEAT,   BUTTON_NONE },
-
-    { ACTION_USB_HID_MUTE,     BUTTON_NEXT,                     BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_MENU,                     BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_UP,                     BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_UP|BUTTON_REPEAT,       BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOL_UP,                 BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_VOL_UP|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_DOWN,                   BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_DOWN|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOL_DOWN,               BUTTON_NONE },
+    { ACTION_USB_HID_DEC,         BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_START,       BUTTON_PLAY|BUTTON_REL,        BUTTON_PLAY },
+    { ACTION_USB_HID_START_LONG,  BUTTON_PLAY|BUTTON_REPEAT,     BUTTON_PLAY },
+    { ACTION_USB_HID_QUIT,        BUTTON_PREV|BUTTON_REL,        BUTTON_PREV },
+    { ACTION_USB_HID_QUIT_LONG,   BUTTON_PREV|BUTTON_REPEAT,     BUTTON_PREV },
+    { ACTION_USB_HID_LEFT,        BUTTON_LEFT|BUTTON_REL,        BUTTON_LEFT },
+    { ACTION_USB_HID_LEFT_LONG,   BUTTON_LEFT|BUTTON_REPEAT,     BUTTON_LEFT },
+    { ACTION_USB_HID_RIGHT,       BUTTON_RIGHT|BUTTON_REL,       BUTTON_RIGHT },
+    { ACTION_USB_HID_RIGHT_LONG,  BUTTON_RIGHT|BUTTON_REPEAT     BUTTON_RIGHT },
+    { ACTION_USB_HID_SELECT,      BUTTON_NEXT|BUTTON_REL,        BUTTON_NEXT },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_NEXT|BUTTON_REPEAT,     BUTTON_NEXT },
+    { ACTION_USB_HID_MENU,        BUTTON_MENU|BUTTON_REL,        BUTTON_MENU },
+    { ACTION_USB_HID_MENU_LONG,   BUTTON_MENU|BUTTON_REPEAT,     BUTTON_MENU },
+    { ACTION_USB_HID_MODE,        BUTTON_POWER|BUTTON_REL,       BUTTON_POWER },
+    { ACTION_USB_HID_MODE_LONG,   BUTTON_POWER|BUTTON_REPEAT,    BUTTON_POWER },
 
     LAST_ITEM_IN_LIST
 }; /* button_context_usb_hid */
+
+static const struct button_mapping button_context_usb_hid_mouse[] = {
+    { ACTION_USB_HID_MOUSE_UP,               BUTTON_UP,                                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_UP_REP,           BUTTON_UP|BUTTON_REPEAT,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN,             BUTTON_DOWN,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_DOWN_REP,         BUTTON_DOWN|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT,             BUTTON_LEFT,                              BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LEFT_REP,         BUTTON_LEFT|BUTTON_REPEAT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT,            BUTTON_RIGHT,                             BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RIGHT_REP,        BUTTON_RIGHT|BUTTON_REPEAT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP,         BUTTON_PREV|BUTTON_UP,                  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_UP_REP,     BUTTON_PREV|BUTTON_UP|BUTTON_REPEAT,    BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN,       BUTTON_PREV|BUTTON_DOWN,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,   BUTTON_PREV|BUTTON_DOWN|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT,       BUTTON_PREV|BUTTON_LEFT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,   BUTTON_PREV|BUTTON_LEFT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT,      BUTTON_PREV|BUTTON_RIGHT,               BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP,  BUTTON_PREV|BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP,         BUTTON_NEXT|BUTTON_UP,                   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_UP_REP,     BUTTON_NEXT|BUTTON_UP|BUTTON_REPEAT,     BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN,       BUTTON_NEXT|BUTTON_DOWN,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_DOWN_REP,   BUTTON_NEXT|BUTTON_DOWN|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT,       BUTTON_NEXT|BUTTON_LEFT,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_LEFT_REP,   BUTTON_NEXT|BUTTON_LEFT|BUTTON_REPEAT,   BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT,      BUTTON_NEXT|BUTTON_RIGHT,                BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_RDRAG_RIGHT_REP,  BUTTON_NEXT|BUTTON_RIGHT|BUTTON_REPEAT,  BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT,      BUTTON_PREV,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL,  BUTTON_PREV|BUTTON_REL,                 BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT,     BUTTON_NEXT,                            BUTTON_NONE },
+    { ACTION_USB_HID_MOUSE_BUTTON_RIGHT_REL, BUTTON_NEXT|BUTTON_REL,                 BUTTON_NONE },
+
+    LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
+}; /* button_context_usb_hid_mouse */
 #endif
 
 const struct button_mapping* get_context_mapping(int context)
@@ -349,9 +385,11 @@
         case CONTEXT_KEYBOARD:
             return button_context_keyboard;
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
+        case CONTEXT_USB_HID_MOUSE:
+            return button_context_usb_hid_mouse;
 #endif
     }
     return button_context_standard;
diff --git a/apps/keymaps/keymap-touchscreen.c b/apps/keymaps/keymap-touchscreen.c
index 4b86efa..499eb2b 100644
--- a/apps/keymaps/keymap-touchscreen.c
+++ b/apps/keymaps/keymap-touchscreen.c
@@ -251,13 +251,26 @@
     LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM2|CONTEXT_FM)
 }; /* button_context_radio */
 
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
 static const struct button_mapping button_context_usb_hid[] = {
-    { ACTION_USB_HID_PLAY,     BUTTON_TOPRIGHT,                  BUTTON_NONE },
-    { ACTION_USB_HID_SKIPPREV, BUTTON_MIDLEFT,                   BUTTON_NONE },
-    { ACTION_USB_HID_SKIPNEXT, BUTTON_MIDRIGHT,                  BUTTON_NONE },
-    { ACTION_USB_HID_MUTE,     BUTTON_CENTER,                    BUTTON_NONE },
-    { ACTION_USB_HID_MENU,     BUTTON_TOPLEFT,                   BUTTON_NONE },
+    { ACTION_USB_HID_INC,         BUTTON_BOTTOMRIGHT|BUTTON_REL,     BUTTON_BOTTOMRIGHT },
+    { ACTION_USB_HID_INC,         BUTTON_BOTTOMRIGHT|BUTTON_REPEAT,  BUTTON_BOTTOMRIGHT },
+    { ACTION_USB_HID_DEC,         BUTTON_BOTTOMMIDDLE|BUTTON_REL,    BUTTON_BOTTOMMIDDLE },
+    { ACTION_USB_HID_DEC,         BUTTON_BOTTOMMIDDLE|BUTTON_REPEAT, BUTTON_BOTTOMMIDDLE },
+    { ACTION_USB_HID_START,       BUTTON_TOPMIDDLE|BUTTON_REL,       BUTTON_TOPMIDDLE },
+    { ACTION_USB_HID_START_LONG,  BUTTON_TOPMIDDLE|BUTTON_REPEAT,    BUTTON_TOPMIDDLE },
+    { ACTION_USB_HID_QUIT,        BUTTON_BOTTOMLEFT|BUTTON_REL,      BUTTON_BOTTOMLEFT },
+    { ACTION_USB_HID_QUIT_LONG,   BUTTON_BOTTOMLEFT|BUTTON_REPEAT,   BUTTON_BOTTOMLEFT },
+    { ACTION_USB_HID_LEFT,        BUTTON_MIDLEFT|BUTTON_REL,         BUTTON_MIDLEFT },
+    { ACTION_USB_HID_LEFT_LONG,   BUTTON_MIDLEFT|BUTTON_REPEAT,      BUTTON_MIDLEFT },
+    { ACTION_USB_HID_RIGHT,       BUTTON_MIDRIGHT|BUTTON_REL,        BUTTON_MIDRIGHT },
+    { ACTION_USB_HID_RIGHT_LONG,  BUTTON_MIDRIGHT|BUTTON_REPEAT,     BUTTON_MIDRIGHT },
+    { ACTION_USB_HID_SELECT,      BUTTON_CENTER|BUTTON_REL,          BUTTON_CENTER },
+    { ACTION_USB_HID_SELECT_LONG, BUTTON_CENTER|BUTTON_REPEAT,       BUTTON_CENTER },
+    { ACTION_USB_HID_MENU,        BUTTON_TOPRIGHT|BUTTON_REL,        BUTTON_TOPRIGHT },
+    { ACTION_USB_HID_MENU_LONG,   BUTTON_TOPRIGHT|BUTTON_REPEAT,     BUTTON_TOPRIGHT },
+    { ACTION_USB_HID_MODE,        BUTTON_TOPLEFT|BUTTON_REL,         BUTTON_TOPLEFT },
+    { ACTION_USB_HID_MODE_LONG,   BUTTON_TOPLEFT|BUTTON_REPEAT,      BUTTON_TOPLEFT },
 
     LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM2|CONTEXT_USB_HID)
 }; /* button_context_usb_hid */
@@ -315,7 +328,7 @@
             return button_context_pitchscreen;
         case CONTEXT_KEYBOARD:
             return button_context_keyboard;
-#ifdef HAVE_USBSTACK
+#ifdef USB_ENABLE_HID
         case CONTEXT_USB_HID:
             return button_context_usb_hid;
 #endif
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 72e0a4c..541e7ff 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -12654,6 +12654,76 @@
   </voice>
 </phrase>
 <phrase>
+  id: LANG_USB_KEYPAD_MODE
+  desc: in settings_menu
+  user: core
+  <source>
+    *: "USB Keypad Mode:"
+  </source>
+  <dest>
+    *: "USB Keypad Mode:"
+  </dest>
+  <voice>
+    *: "USB Keypad Mode"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_MULTIMEDIA
+  desc: in settings_menu
+  user: core
+  <source>
+    *: "Multimedia"
+  </source>
+  <dest>
+    *: "Multimedia"
+  </dest>
+  <voice>
+    *: "Multimedia"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_PRESENTATION
+  desc: in settings_menu
+  user: core
+  <source>
+    *: "Presentation"
+  </source>
+  <dest>
+    *: "Presentation"
+  </dest>
+  <voice>
+    *: "Presentation"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_BROWSER
+  desc: in settings_menu
+  user: core
+  <source>
+    *: "Browser"
+  </source>
+  <dest>
+    *: "Browser"
+  </dest>
+  <voice>
+    *: "Browser"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_MOUSE
+  desc: in settings_menu
+  user: core
+  <source>
+    *: "Mouse"
+  </source>
+  <dest>
+    *: "Mouse"
+  </dest>
+  <voice>
+    *: "Mouse"
+  </voice>
+</phrase>
+<phrase>
   id: LANG_SKIN_RAM_USAGE
   desc: how much RAM the skins are using
   user: core
diff --git a/apps/menus/settings_menu.c b/apps/menus/settings_menu.c
index fdc7758..71a6089 100644
--- a/apps/menus/settings_menu.c
+++ b/apps/menus/settings_menu.c
@@ -252,6 +252,9 @@
 MENUITEM_SETTING(accessory_supply, &global_settings.accessory_supply, NULL);
 #endif
 MENUITEM_SETTING(start_screen, &global_settings.start_in_screen, NULL);
+#ifdef USB_ENABLE_HID
+MENUITEM_SETTING(usb_keypad_mode, &global_settings.usb_keypad_mode, NULL);
+#endif
 
 #ifdef HAVE_BUTTON_LIGHT
 MENUITEM_SETTING(buttonlight_timeout, &global_settings.buttonlight_timeout, NULL);
@@ -300,6 +303,9 @@
 #ifdef HAVE_TOUCHPAD_SENSITIVITY_SETTING
             &touchpad_sensitivity,
 #endif
+#ifdef USB_ENABLE_HID
+            &usb_keypad_mode,
+#endif
          );
 
 /*    SYSTEM MENU                  */
diff --git a/apps/plugin.c b/apps/plugin.c
index aa7077e..945e99e 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -51,7 +51,7 @@
 #include "bidi.h"
 #endif
 
-#if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID)
+#ifdef USB_ENABLE_HID
 #include "usbstack/usb_hid.h"
 #endif
 
@@ -367,7 +367,7 @@
     queue_reply,
 #endif
     usb_acknowledge,
-#if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID)
+#ifdef USB_ENABLE_HID
     usb_hid_send,
 #endif
 #ifdef RB_PROFILE
diff --git a/apps/plugin.h b/apps/plugin.h
index b4a6b4f..766a309 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -105,7 +105,7 @@
 
 #include "yesno.h"
 
-#if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID)
+#ifdef USB_ENABLE_HID
 #include "usbstack/usb_hid_usage_tables.h"
 #endif
 
@@ -491,7 +491,7 @@
 #endif /* CONFIG_CODEC == SWCODEC */
 
     void (*usb_acknowledge)(long id);
-#if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID)
+#ifdef USB_ENABLE_HID
     void (*usb_hid_send)(usage_page_t usage_page, int id);
 #endif
 #ifdef RB_PROFILE
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index b9061ee..4cfc3a8 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -169,6 +169,6 @@
 lua.c
 #endif
 
-#if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID)
+#ifdef USB_ENABLE_HID
 remote_control.c
 #endif
diff --git a/apps/screens.c b/apps/screens.c
index a7a4b27..65b64ea 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -37,7 +37,7 @@
 #if defined(HAVE_USBSTACK)
 #include "usb_core.h"
 #ifdef USB_ENABLE_HID
-#include "usbstack/usb_hid.h"
+#include "usb_keymaps.h"
 #endif
 #endif
 #include "settings.h"
@@ -93,59 +93,32 @@
 #endif
 
 #ifndef SIMULATOR
+
+#ifdef USB_ENABLE_HID
+int usb_keypad_mode;
+#endif
+
 static int handle_usb_events(void)
 {
 #if (CONFIG_STORAGE & STORAGE_MMC)
     int next_update=0;
 #endif /* STORAGE_MMC */
 
-#ifdef HAVE_TOUCHSCREEN
-    enum touchscreen_mode old_mode = touchscreen_get_mode();
-
-    /* TODO: Paint buttons on screens OR switch to point mode and use
-     * touchscreen as a touchpad to move the host's mouse cursor */
-    touchscreen_set_mode(TOUCHSCREEN_BUTTON);
-#endif
-
     /* Don't return until we get SYS_USB_DISCONNECTED or SYS_TIMEOUT */
     while(1)
     {
         int button;
-#if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID)
-        bool hid_enabled = usb_core_driver_enabled(USB_DRIVER_HID);
-
-        if (hid_enabled)
+#ifdef USB_ENABLE_HID
+        if (usb_core_driver_enabled(USB_DRIVER_HID))
         {
-            int id = HID_CONSUMER_USAGE_UNASSIGNED;
-            button = get_action(CONTEXT_USB_HID, HZ/2);
+            button = get_hid_usb_action();
 
-            switch (button)
+            /* On mode change, we need to refresh the screen */
+            if (button == ACTION_USB_HID_MODE ||
+                    button == ACTION_USB_HID_MODE_LONG)
             {
-                case ACTION_USB_HID_PLAY:
-                    id = HID_CONSUMER_USAGE_PLAY_PAUSE;
-                    break;
-                case ACTION_USB_HID_STOP:
-                    id = HID_CONSUMER_USAGE_STOP;
-                    break;
-                case ACTION_USB_HID_SKIPPREV:
-                    id = HID_CONSUMER_USAGE_SCAN_PREVIOUS_TRACK;
-                    break;
-                case ACTION_USB_HID_SKIPNEXT:
-                    id = HID_CONSUMER_USAGE_SCAN_NEXT_TRACK;
-                    break;
-                case ACTION_USB_HID_VOLDOWN:
-                    id = HID_CONSUMER_USAGE_VOLUME_DECREMENT;
-                    break;
-                case ACTION_USB_HID_VOLUP:
-                    id = HID_CONSUMER_USAGE_VOLUME_INCREMENT;
-                    break;
-                case ACTION_USB_HID_MUTE:
-                    id = HID_CONSUMER_USAGE_MUTE;
-                    break;
+                break;
             }
-
-            if (id != HID_CONSUMER_USAGE_UNASSIGNED)
-                usb_hid_send(HID_USAGE_PAGE_CONSUMER, id);
         }
         else
 #endif
@@ -159,7 +132,7 @@
         {
             case SYS_USB_DISCONNECTED:
                 usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
-                goto Exit;
+                return 1;
             case SYS_TIMEOUT:
                 break;
         }
@@ -174,14 +147,12 @@
         }
 #endif /* STORAGE_MMC */
     }
-Exit:
-#ifdef HAVE_TOUCHSCREEN
-    touchscreen_set_mode(old_mode);
-#endif
+
     return 0;
 }
 #endif
 
+#define MODE_NAME_LEN 32
 void usb_screen(void)
 {
 #ifdef USB_NONE
@@ -190,55 +161,107 @@
     int i;
     int usb_bars = VP_SB_ALLSCREENS; /* force statusbars */
     int old_bars  = viewportmanager_get_statusbar();
+#if defined HAVE_TOUCHSCREEN
+    enum touchscreen_mode old_mode = touchscreen_get_mode();
 
-    FOR_NB_SCREENS(i)
-    {
-        screens[i].backdrop_show(BACKDROP_MAIN);
-        screens[i].backlight_on();
-        screens[i].clear_display();
-#ifdef HAVE_REMOTE_LCD
-        if (i == SCREEN_REMOTE)
-        {
-            screens[i].bitmap(remote_usblogo,
-                      (LCD_REMOTE_WIDTH-BMPWIDTH_remote_usblogo),
-                      (LCD_REMOTE_HEIGHT-BMPHEIGHT_remote_usblogo)/2,
-                      BMPWIDTH_remote_usblogo, BMPHEIGHT_remote_usblogo);
-        }
-        else 
+    /* TODO: Paint buttons on screens OR switch to point mode and use
+     * touchscreen as a touchpad to move the host's mouse cursor */
+    touchscreen_set_mode(TOUCHSCREEN_BUTTON);
 #endif
-        {
-#ifdef HAVE_LCD_BITMAP
-            screens[i].transparent_bitmap(usblogo, 
-                        (LCD_WIDTH-BMPWIDTH_usblogo),
-                        (LCD_HEIGHT-BMPHEIGHT_usblogo)/2,
-                         BMPWIDTH_usblogo, BMPHEIGHT_usblogo);
-#else
-            screens[i].double_height(false);
-            screens[i].puts_scroll(0, 0, "[USB Mode]");
-            status_set_param(false);
-            status_set_audio(false);
-            status_set_usb(true);
-#endif /* HAVE_LCD_BITMAP */
-        }
-        screens[i].update();
 
-        /* force statusbar by ignoring the setting */
-        usb_bars |= VP_SB_IGNORE_SETTING(i);
-    }
+#ifndef SIMULATOR
+    usb_acknowledge(SYS_USB_CONNECTED_ACK);
+#endif
 
-    viewportmanager_set_statusbar(usb_bars);
+#ifdef USB_ENABLE_HID
+    usb_keypad_mode = global_settings.usb_keypad_mode;
+#endif
 
-#ifdef SIMULATOR
     while (1)
     {
+        FOR_NB_SCREENS(i)
+        {
+            screens[i].backdrop_show(BACKDROP_MAIN);
+            screens[i].backlight_on();
+            screens[i].clear_display();
+#ifdef HAVE_REMOTE_LCD
+            if (i == SCREEN_REMOTE)
+            {
+                screens[i].bitmap(remote_usblogo,
+                        (LCD_REMOTE_WIDTH-BMPWIDTH_remote_usblogo),
+                        (LCD_REMOTE_HEIGHT-BMPHEIGHT_remote_usblogo)/2,
+                        BMPWIDTH_remote_usblogo, BMPHEIGHT_remote_usblogo);
+            }
+            else
+#endif
+            {
+                char mode_name[MODE_NAME_LEN];
+
+#ifdef HAVE_LCD_BITMAP
+                screens[i].transparent_bitmap(usblogo,
+                        (LCD_WIDTH-BMPWIDTH_usblogo),
+                        (LCD_HEIGHT-BMPHEIGHT_usblogo)/2,
+                        BMPWIDTH_usblogo, BMPHEIGHT_usblogo);
+
+#ifdef USB_ENABLE_HID
+                int y, w, h;
+
+                screens[i].getstringsize(str(LANG_USB_KEYPAD_MODE), &w, &h);
+
+                y = (LCD_HEIGHT - BMPHEIGHT_usblogo) / 2 + BMPHEIGHT_usblogo + h;
+                screens[i].putsxy((LCD_WIDTH - w) / 2, y,
+                        str(LANG_USB_KEYPAD_MODE));
+                y += 3 * h / 2;
+
+                snprintf(mode_name, MODE_NAME_LEN, "%s",
+                        str(keypad_mode_name_get()));
+                screens[i].getstringsize(mode_name, &w, &h);
+                screens[i].putsxy((LCD_WIDTH - w) / 2, y, mode_name);
+#endif /* HID */
+#else /* HAVE_LCD_BITMAP */
+                screens[i].double_height(false);
+#ifdef USB_ENABLE_HID
+                snprintf(mode_name, MODE_NAME_LEN, "[USB Mode; %s]",
+                        str(keypad_mode_name_get()));
+                screens[i].puts_scroll(0, 0, mode_name);
+#else
+                screens[i].puts_scroll(0, 0, "[USB Mode]");
+#endif
+                status_set_param(false);
+                status_set_audio(false);
+                status_set_usb(true);
+#endif /* HAVE_LCD_BITMAP */
+            }
+            screens[i].update();
+
+            /* force statusbar by ignoring the setting */
+            usb_bars |= VP_SB_IGNORE_SETTING(i);
+        }
+
+        viewportmanager_set_statusbar(usb_bars);
+
+#ifdef SIMULATOR
         if (button_get_w_tmo(HZ/2))
             break;
         send_event(GUI_EVENT_ACTIONUPDATE, NULL);
-    }
 #else
-    usb_acknowledge(SYS_USB_CONNECTED_ACK);
-    while (handle_usb_events());
+        if (handle_usb_events())
+            break;
 #endif /* SIMULATOR */
+    }
+
+#ifdef USB_ENABLE_HID
+    if (global_settings.usb_keypad_mode != usb_keypad_mode)
+    {
+        global_settings.usb_keypad_mode = usb_keypad_mode;
+        settings_save();
+    }
+#endif
+
+#ifdef HAVE_TOUCHSCREEN
+    touchscreen_set_mode(old_mode);
+#endif
+
 #ifdef HAVE_LCD_CHARCELLS
     status_set_usb(false);
 #endif /* HAVE_LCD_CHARCELLS */
@@ -248,7 +271,7 @@
     }
     viewportmanager_set_statusbar(old_bars);
     send_event(GUI_EVENT_REFRESH, NULL);
-    
+
 #endif /* USB_NONE */
 }
 
diff --git a/apps/settings.h b/apps/settings.h
index ec92a81..b208ee5 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -768,7 +768,11 @@
     /* If values are just added to the end, no need to bump plugin API
        version. */
     /* new stuff to be added at the end */
-    
+
+#ifdef USB_ENABLE_HID
+    int usb_keypad_mode;
+#endif
+
 #ifdef HAVE_LCD_BITMAP
     unsigned char ui_vp_config[64]; /* viewport string for the lists */
 #ifdef HAVE_REMOTE_LCD
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 2e3632b..34e8854 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1613,6 +1613,13 @@
 #endif
 #endif
 
+#ifdef USB_ENABLE_HID
+    CHOICE_SETTING(0, usb_keypad_mode, LANG_USB_KEYPAD_MODE, 0,
+            "usb keypad mode", "multimedia,presentation,browser,mouse",
+            NULL, 3, ID2P(LANG_MULTIMEDIA), ID2P(LANG_PRESENTATION),
+            ID2P(LANG_BROWSER), ID2P(LANG_MOUSE)),
+#endif
+
     /* Customizable list */
 #ifdef HAVE_LCD_BITMAP
     VIEWPORT_SETTING(ui_vp_config, "ui viewport"),
diff --git a/apps/usb_keymaps.c b/apps/usb_keymaps.c
new file mode 100644
index 0000000..c791b11
--- /dev/null
+++ b/apps/usb_keymaps.c
@@ -0,0 +1,249 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2009 Tomer Shalev
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+
+#ifdef USB_ENABLE_HID
+#include "action.h"
+#include "lang.h"
+#include "usbstack/usb_hid.h"
+//#define LOGF_ENABLE
+#include "logf.h"
+
+#define MODIFIER(modifier, key) ((key) | (modifier << 8))
+
+#define ALT(key) MODIFIER(HID_KEYBOARD_LEFT_ALT, key)
+#define CTRL(key) MODIFIER(HID_KEYBOARD_LEFT_CONTROL, key)
+#define SHIFT(key) MODIFIER(HID_KEYBOARD_LEFT_SHIFT, key)
+
+#define NUM_KEY_MAPPINGS (sizeof(hid_key_mappings) / \
+        sizeof(hid_key_mappings[0]))
+
+typedef struct
+{
+    int action;
+    int id;
+} mapping_t;
+
+typedef struct
+{
+    int lang_name;
+    usage_page_t usage_page;
+    mapping_t mapping[];
+} hid_key_mapping_t;
+
+static const hid_key_mapping_t hid_key_mapping_multimedia = {
+    LANG_MULTIMEDIA,
+    HID_USAGE_PAGE_CONSUMER,
+    {
+        /* Volume up */
+        { ACTION_USB_HID_DEC,    HID_CONSUMER_USAGE_VOLUME_DECREMENT },
+        /* Volume down */
+        { ACTION_USB_HID_INC,    HID_CONSUMER_USAGE_VOLUME_INCREMENT },
+        /* Volume mute */
+        { ACTION_USB_HID_SELECT, HID_CONSUMER_USAGE_MUTE },
+        /* Play / pause */
+        { ACTION_USB_HID_START,  HID_CONSUMER_USAGE_PLAY_PAUSE },
+        /* Stop */
+        { ACTION_USB_HID_QUIT,   HID_CONSUMER_USAGE_STOP },
+        /* Scan previous track */
+        { ACTION_USB_HID_LEFT,   HID_CONSUMER_USAGE_SCAN_PREVIOUS_TRACK },
+        /* Scan next track */
+        { ACTION_USB_HID_RIGHT,  HID_CONSUMER_USAGE_SCAN_NEXT_TRACK },
+        { 0,                     0 },
+    }
+};
+
+static const hid_key_mapping_t hid_key_mapping_presentation = {
+    LANG_PRESENTATION,
+    HID_USAGE_PAGE_KEYBOARD_KEYPAD,
+    {
+        /* Slideshow start */
+        { ACTION_USB_HID_START,       HID_KEYBOARD_F5 },
+        /* Slideshow leave */
+        { ACTION_USB_HID_QUIT,        HID_KEYBOARD_ESCAPE },
+        /* Slide previous */
+        { ACTION_USB_HID_LEFT,        HID_KEYBOARD_P },
+        /* Slide next */
+        { ACTION_USB_HID_RIGHT,       HID_KEYBOARD_N },
+        /* Slide first */
+        { ACTION_USB_HID_LEFT_LONG,   HID_KEYBOARD_HOME },
+        /* Slide Last */
+        { ACTION_USB_HID_RIGHT_LONG,  HID_KEYBOARD_END },
+        /* Black screen */
+        { ACTION_USB_HID_MENU,        HID_KEYBOARD_DOT },
+        /* White screen */
+        { ACTION_USB_HID_MENU_LONG,   HID_KEYBOARD_COMMA },
+        /* Link previous */
+        { ACTION_USB_HID_DEC,         SHIFT(HID_KEYBOARD_TAB) },
+        /* Link next */
+        { ACTION_USB_HID_INC,         HID_KEYBOARD_TAB },
+        /* 'Mouse click' */
+        { ACTION_USB_HID_SELECT,      HID_KEYBOARD_RETURN },
+        /* 'Mouse over' */
+        { ACTION_USB_HID_SELECT_LONG, SHIFT(HID_KEYBOARD_RETURN) },
+        { 0,                          0 },
+    }
+};
+
+static const hid_key_mapping_t hid_key_mapping_browser = {
+    LANG_BROWSER,
+    HID_USAGE_PAGE_KEYBOARD_KEYPAD,
+    {
+        /* Scroll up */
+        { ACTION_USB_HID_DEC,         HID_KEYBOARD_UP_ARROW },
+        /* Scroll down */
+        { ACTION_USB_HID_INC,         HID_KEYBOARD_DOWN_ARROW },
+        /* Scroll page up */
+        { ACTION_USB_HID_START,       HID_KEYBOARD_PAGE_UP },
+        /* Scroll page down */
+        { ACTION_USB_HID_MENU,        HID_KEYBOARD_PAGE_DOWN },
+        /* Zoom in */
+        { ACTION_USB_HID_START_LONG,  CTRL(HID_KEYPAD_PLUS) },
+        /* Zoom out */
+        { ACTION_USB_HID_MENU_LONG,   CTRL(HID_KEYPAD_MINUS) },
+        /* Zoom reset */
+        { ACTION_USB_HID_SELECT_LONG, CTRL(HID_KEYPAD_0_AND_INSERT) },
+        /* Tab previous */
+        { ACTION_USB_HID_LEFT,        CTRL(HID_KEYBOARD_PAGE_UP) },
+        /* Tab next */
+        { ACTION_USB_HID_RIGHT,       CTRL(HID_KEYBOARD_PAGE_DOWN) },
+        /* Tab close */
+        { ACTION_USB_HID_QUIT_LONG,   CTRL(HID_KEYBOARD_W) },
+        /* History back */
+        { ACTION_USB_HID_LEFT_LONG,   ALT(HID_KEYBOARD_LEFT_ARROW) },
+        /* History forward */
+        { ACTION_USB_HID_RIGHT_LONG,  ALT(HID_KEYBOARD_RIGHT_ARROW) },
+        /* Full-Screen */
+        { ACTION_USB_HID_SELECT,      HID_KEYBOARD_F11 },
+        { 0,                          0 },
+    }
+};
+
+#ifdef HAVE_USB_HID_MOUSE
+static const hid_key_mapping_t hid_key_mapping_mouse = {
+    LANG_MOUSE,
+    HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS,
+    {
+        /* Mouse up */
+        { ACTION_USB_HID_MOUSE_UP,               HID_MOUSE_UP },
+        { ACTION_USB_HID_MOUSE_UP_REP,           HID_MOUSE_UP_REP },
+        { ACTION_USB_HID_MOUSE_LDRAG_UP,         HID_MOUSE_LDRAG_UP },
+        { ACTION_USB_HID_MOUSE_LDRAG_UP_REP,     HID_MOUSE_LDRAG_UP_REP },
+        { ACTION_USB_HID_MOUSE_RDRAG_UP,         HID_MOUSE_RDRAG_UP },
+        { ACTION_USB_HID_MOUSE_RDRAG_UP_REP,     HID_MOUSE_RDRAG_UP_REP },
+        /* Mouse down */
+        { ACTION_USB_HID_MOUSE_DOWN,             HID_MOUSE_DOWN },
+        { ACTION_USB_HID_MOUSE_DOWN_REP,         HID_MOUSE_DOWN_REP },
+        { ACTION_USB_HID_MOUSE_LDRAG_DOWN,       HID_MOUSE_LDRAG_DOWN },
+        { ACTION_USB_HID_MOUSE_LDRAG_DOWN_REP,   HID_MOUSE_LDRAG_DOWN_REP },
+        { ACTION_USB_HID_MOUSE_RDRAG_DOWN,       HID_MOUSE_RDRAG_DOWN },
+        { ACTION_USB_HID_MOUSE_RDRAG_DOWN_REP,   HID_MOUSE_RDRAG_DOWN_REP },
+        /* Mouse left */
+        { ACTION_USB_HID_MOUSE_LEFT,             HID_MOUSE_LEFT },
+        { ACTION_USB_HID_MOUSE_LEFT_REP,         HID_MOUSE_LEFT_REP },
+        { ACTION_USB_HID_MOUSE_LDRAG_LEFT,       HID_MOUSE_LDRAG_LEFT },
+        { ACTION_USB_HID_MOUSE_LDRAG_LEFT_REP,   HID_MOUSE_LDRAG_LEFT_REP },
+        { ACTION_USB_HID_MOUSE_RDRAG_LEFT,       HID_MOUSE_RDRAG_LEFT },
+        { ACTION_USB_HID_MOUSE_RDRAG_LEFT_REP,   HID_MOUSE_RDRAG_LEFT_REP },
+        /* Mouse right */
+        { ACTION_USB_HID_MOUSE_RIGHT,            HID_MOUSE_RIGHT },
+        { ACTION_USB_HID_MOUSE_RIGHT_REP,        HID_MOUSE_RIGHT_REP },
+        { ACTION_USB_HID_MOUSE_LDRAG_RIGHT,      HID_MOUSE_LDRAG_RIGHT },
+        { ACTION_USB_HID_MOUSE_LDRAG_RIGHT_REP,  HID_MOUSE_LDRAG_RIGHT_REP },
+        { ACTION_USB_HID_MOUSE_RDRAG_RIGHT,      HID_MOUSE_RDRAG_RIGHT },
+        { ACTION_USB_HID_MOUSE_RDRAG_RIGHT_REP,  HID_MOUSE_RDRAG_RIGHT_REP },
+        /* Mouse buttons */
+        { ACTION_USB_HID_MOUSE_BUTTON_LEFT,      HID_MOUSE_BUTTON_LEFT },
+        { ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL,  HID_MOUSE_BUTTON_LEFT_REL },
+        { ACTION_USB_HID_MOUSE_BUTTON_RIGHT,     HID_MOUSE_BUTTON_RIGHT },
+        { ACTION_USB_HID_MOUSE_BUTTON_RIGHT_REL, HID_MOUSE_BUTTON_RIGHT_REL },
+        /* Mouse wheel scroll up */
+        { ACTION_USB_HID_DEC,                    HID_MOUSE_SCROLL_UP },
+        /* Mouse wheel scroll down */
+        { ACTION_USB_HID_INC,                    HID_MOUSE_SCROLL_DOWN },
+        { 0,                                     0 },
+    }
+};
+
+#define USB_KEYPAD_MODE_MOUSE 3 /* Value of the mouse setting (hard-coded) */
+#endif /* HAVE_USB_HID_MOUSE */
+
+static const hid_key_mapping_t *hid_key_mappings[] =
+{
+    &hid_key_mapping_multimedia,
+    &hid_key_mapping_presentation,
+    &hid_key_mapping_browser,
+#ifdef HAVE_USB_HID_MOUSE
+    &hid_key_mapping_mouse,
+#endif
+};
+
+extern int usb_keypad_mode;
+
+int get_hid_usb_action(void)
+{
+    int action, context = CONTEXT_USB_HID;
+
+#ifdef HAVE_USB_HID_MOUSE
+    if (usb_keypad_mode == USB_KEYPAD_MODE_MOUSE)
+        context = CONTEXT_USB_HID_MOUSE;
+#endif
+
+    action = get_action(context, HZ/4);
+    /* Skip key mappings in a cyclic way */
+    if (action == ACTION_USB_HID_MODE)
+    {
+        usb_keypad_mode = (usb_keypad_mode + 1) % NUM_KEY_MAPPINGS;
+    }
+    else if (action == ACTION_USB_HID_MODE_LONG)
+    {
+        usb_keypad_mode = (usb_keypad_mode - 1) % NUM_KEY_MAPPINGS;
+    }
+    else if (action > ACTION_USB_HID_FIRST && action < ACTION_USB_HID_LAST)
+    {
+        const mapping_t *mapping;
+        const hid_key_mapping_t *key_mapping =
+            hid_key_mappings[usb_keypad_mode];
+
+        for (mapping = key_mapping->mapping; mapping->action; mapping++)
+        {
+            if (action == mapping->action)
+            {
+                logf("Action %d", action);
+                usb_hid_send(key_mapping->usage_page, mapping->id);
+                break;
+            }
+        }
+#ifdef DEBUG
+        if (!mapping->action)
+            logf("Action %d not found", action);
+#endif
+    }
+
+    return action;
+}
+
+int keypad_mode_name_get(void)
+{
+    return hid_key_mappings[usb_keypad_mode]->lang_name;
+}
+
+#endif
diff --git a/apps/usb_keymaps.h b/apps/usb_keymaps.h
new file mode 100644
index 0000000..8b08bfd
--- /dev/null
+++ b/apps/usb_keymaps.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2009 Tomer Shalev
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _USB_KEYMAPS_H_
+#define _USB_KEYMAPS_H_
+
+int get_hid_usb_action(void);
+
+int keypad_mode_name_get(void);
+
+#endif
diff --git a/firmware/export/config-c200.h b/firmware/export/config-c200.h
index 654ac7b..ab70396 100644
--- a/firmware/export/config-c200.h
+++ b/firmware/export/config-c200.h
@@ -190,6 +190,7 @@
 #define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x0781
 #define USB_PRODUCT_ID 0x7451
+#define HAVE_USB_HID_MOUSE
 
 /* Define this if you have adjustable CPU frequency */
 #define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-e200.h b/firmware/export/config-e200.h
index 8b7e0d6..18de2f6 100644
--- a/firmware/export/config-e200.h
+++ b/firmware/export/config-e200.h
@@ -184,7 +184,7 @@
 #define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x0781
 #define USB_PRODUCT_ID 0x7421
-
+#define HAVE_USB_HID_MOUSE
 
 /* Define this if you have adjustable CPU frequency */
 #define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-gigabeat-s.h b/firmware/export/config-gigabeat-s.h
index 3f001af..ae57825 100644
--- a/firmware/export/config-gigabeat-s.h
+++ b/firmware/export/config-gigabeat-s.h
@@ -187,6 +187,7 @@
 #define USB_PORTSCX_PHY_TYPE PORTSCX_PTS_ULPI
 #define USB_VENDOR_ID 0x0930
 #define USB_PRODUCT_ID 0x0010
+#define HAVE_USB_HID_MOUSE
 
 /* Define this if you have ATA power-off control */
 #define HAVE_ATA_POWER_OFF
diff --git a/firmware/export/config-hdd1630.h b/firmware/export/config-hdd1630.h
index 05450e0..1d7bff3 100755
--- a/firmware/export/config-hdd1630.h
+++ b/firmware/export/config-hdd1630.h
@@ -187,6 +187,7 @@
 #define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x0471
 #define USB_PRODUCT_ID 0x014C
+#define HAVE_USB_HID_MOUSE
 
 /* Define this if you have adjustable CPU frequency */
 #define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-ipod4g.h b/firmware/export/config-ipod4g.h
index 6c08e75..232e0aa 100644
--- a/firmware/export/config-ipod4g.h
+++ b/firmware/export/config-ipod4g.h
@@ -183,6 +183,7 @@
 #define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x05ac
 #define USB_PRODUCT_ID 0x1203
+#define HAVE_USB_HID_MOUSE
 
 /* Virtual LED (icon) */
 #define CONFIG_LED LED_VIRTUAL
diff --git a/firmware/export/config-ipodcolor.h b/firmware/export/config-ipodcolor.h
index ea02b90..3254c0a 100644
--- a/firmware/export/config-ipodcolor.h
+++ b/firmware/export/config-ipodcolor.h
@@ -160,6 +160,7 @@
 #define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x05ac
 #define USB_PRODUCT_ID 0x1204
+#define HAVE_USB_HID_MOUSE
 
 /* Define this if you have adjustable CPU frequency */
 #define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-ipodmini.h b/firmware/export/config-ipodmini.h
index 9036adc..9cf377f 100644
--- a/firmware/export/config-ipodmini.h
+++ b/firmware/export/config-ipodmini.h
@@ -179,6 +179,7 @@
 #define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x05ac
 #define USB_PRODUCT_ID 0x1205
+#define HAVE_USB_HID_MOUSE
 
 /* Define this if you have adjustable CPU frequency */
 #define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-ipodmini2g.h b/firmware/export/config-ipodmini2g.h
index b69810e..dcd3113 100644
--- a/firmware/export/config-ipodmini2g.h
+++ b/firmware/export/config-ipodmini2g.h
@@ -186,6 +186,7 @@
 #define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x05ac
 #define USB_PRODUCT_ID 0x1205
+#define HAVE_USB_HID_MOUSE
 
 /* Define this if you have adjustable CPU frequency */
 #define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-ipodnano.h b/firmware/export/config-ipodnano.h
index 3110809..005d2ff 100644
--- a/firmware/export/config-ipodnano.h
+++ b/firmware/export/config-ipodnano.h
@@ -170,6 +170,7 @@
 #define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x05ac
 #define USB_PRODUCT_ID 0x120a
+#define HAVE_USB_HID_MOUSE
 
 /* Define this if you have adjustable CPU frequency */
 #define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-ipodvideo.h b/firmware/export/config-ipodvideo.h
index bd93f8f..f760a56 100644
--- a/firmware/export/config-ipodvideo.h
+++ b/firmware/export/config-ipodvideo.h
@@ -194,6 +194,7 @@
 #define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x05ac
 #define USB_PRODUCT_ID 0x1209
+#define HAVE_USB_HID_MOUSE
 
 /* Virtual LED (icon) */
 #define CONFIG_LED LED_VIRTUAL
diff --git a/firmware/export/config-sa9200.h b/firmware/export/config-sa9200.h
index 7af50b5..2ab538e 100755
--- a/firmware/export/config-sa9200.h
+++ b/firmware/export/config-sa9200.h
@@ -171,6 +171,7 @@
 #define USE_ROCKBOX_USB
 #define USB_VENDOR_ID 0x0471
 #define USB_PRODUCT_ID 0x014f
+#define HAVE_USB_HID_MOUSE
 
 /* WARNING! Enable Rockbox USB mass storage. */
 #ifndef BOOTLOADER
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index d45c0ef..7321d3e 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -43,7 +43,7 @@
 #include "usb_charging_only.h"
 #endif
 
-#if defined(USB_ENABLE_HID)
+#ifdef USB_ENABLE_HID
 #include "usb_hid.h"
 #endif
 
diff --git a/firmware/usbstack/usb_hid.c b/firmware/usbstack/usb_hid.c
index 4eb2584..4e9795b 100644
--- a/firmware/usbstack/usb_hid.c
+++ b/firmware/usbstack/usb_hid.c
@@ -28,11 +28,6 @@
 //#define LOGF_ENABLE
 #include "logf.h"
 
-#define CONCAT(low, high)               ((high << 8) | low)
-#define PACK_VAL1(dest, val)            *(dest)++ = (val) & 0xff
-#define PACK_VAL2(dest, val)            PACK_VAL1((dest), (val)); \
-                                        PACK_VAL1((dest), (val >> 8))
-
 /* Documents avaiable here: http://www.usb.org/developers/devclass_docs/ */
 
 #define HID_VER                         0x0110 /* 1.1 */
@@ -47,6 +42,7 @@
 #define INPUT                           0x80
 #define OUTPUT                          0x90
 #define COLLECTION                      0xA0
+#define COLLECTION_PHYSICAL             0x00
 #define COLLECTION_APPLICATION          0x01
 #define END_COLLECTION                  0xC0
 /* Parts (HID1_11.pdf, page 40) */
@@ -90,24 +86,30 @@
 
 #define HID_BUF_SIZE_MSG                16
 #define HID_BUF_SIZE_CMD                16
-#define HID_BUF_SIZE_REPORT             96
+#define HID_BUF_SIZE_REPORT             160
 #define HID_NUM_BUFFERS                 5
 #define SET_REPORT_BUF_LEN 2
 
+//#ifdef LOGF_ENABLE
 #ifdef LOGF_ENABLE
+
 #define BUF_DUMP_BUF_LEN       HID_BUF_SIZE_REPORT
 #define BUF_DUMP_PREFIX_SIZE   5
-#define BUF_DUMP_LINE_SIZE     (MAX_LOGF_ENTRY - BUF_DUMP_PREFIX_SIZE)
-#define BUF_DUMP_ITEMS_IN_LINE (BUF_DUMP_LINE_SIZE / 3)
-#define BUF_DUMP_NUM_LINES     (BUF_DUMP_BUF_LEN / (BUF_DUMP_LINE_SIZE / 3))
+#define BUF_DUMP_ITEMS_IN_LINE 8
+#define BUF_DUMP_LINE_SIZE     (BUF_DUMP_ITEMS_IN_LINE * 3)
+#define BUF_DUMP_NUM_LINES     (BUF_DUMP_BUF_LEN / BUF_DUMP_ITEMS_IN_LINE)
 #endif
 
 #define HID_BUF_INC(i) do { (i) = ((i) + 1) % HID_NUM_BUFFERS; } while (0)
+#define PACK_VAL(dest, val) *(dest)++ = (val) & 0xff
 
 typedef enum
 {
     REPORT_ID_KEYBOARD = 1,
     REPORT_ID_CONSUMER,
+#ifdef HAVE_USB_HID_MOUSE
+    REPORT_ID_MOUSE,
+#endif
     REPORT_ID_COUNT,
 } report_id_t;
 
@@ -164,6 +166,7 @@
     /* Write the id into the buffer in the appropriate location, and returns the
      * buffer length */
     uint8_t (*buf_set)(unsigned char *buf, int id);
+    bool is_key_released;
 } usb_hid_report_t;
 
 usb_hid_report_t usb_hid_reports[REPORT_ID_COUNT];
@@ -183,7 +186,7 @@
 
 static void usb_hid_try_send_drv(void);
 
-static void pack_parameter(unsigned char **dest, bool is_signed,
+static void pack_parameter(unsigned char **dest, bool is_signed, bool mark_size,
         uint8_t parameter, uint32_t value)
 {
     uint8_t size_value = 1; /* # of bytes */
@@ -216,7 +219,7 @@
             size_value++;
     }
 
-    **dest = parameter | size_value;
+    **dest = parameter | (mark_size ? size_value : 0);
     (*dest)++;
 
     while (size_value--)
@@ -244,11 +247,10 @@
 }
 
 #ifdef LOGF_ENABLE
-static unsigned char
-    buf_dump_ar[BUF_DUMP_NUM_LINES][BUF_DUMP_LINE_SIZE + 1]
+static unsigned char buf_dump_ar[BUF_DUMP_NUM_LINES][BUF_DUMP_LINE_SIZE + 1]
     USB_DEVBSS_ATTR __attribute__((aligned(32)));
 
-void buf_dump(unsigned char *buf, size_t size)
+void buf_dump(unsigned char *buf, size_t size, char *msg)
 {
     size_t i;
     int line;
@@ -269,7 +271,7 @@
         *b = 0;
 
         /* Prefix must be of len BUF_DUMP_PREFIX_SIZE */
-        logf("%03d: %s", i0, buf_dump_ar[line]);
+        logf("%03d: %s %s", i0, buf_dump_ar[line], msg);
     }
 }
 #else
@@ -277,26 +279,178 @@
 #define buf_dump(...)
 #endif
 
+#define BUF_LEN_KEYBOARD 7
 static uint8_t buf_set_keyboard(unsigned char *buf, int id)
 {
-    memset(buf, 0, 7);
+    memset(buf, 0, BUF_LEN_KEYBOARD);
+    int key, i = 1;
 
-    if (HID_KEYBOARD_LEFT_CONTROL <= id && id <= HID_KEYBOARD_RIGHT_GUI)
-        buf[0] = (1 << (id - HID_KEYBOARD_LEFT_CONTROL));
-    else
-        buf[1] = (uint8_t)id;
+    /* Each key is a word in id (up to 4 keys supported) */
+    while ((key = id & 0xff))
+    {
+        /* Each modifier key is a bit in the first byte */
+        if (HID_KEYBOARD_LEFT_CONTROL <= key && key <= HID_KEYBOARD_RIGHT_GUI)
+            buf[0] |= (1 << (key - HID_KEYBOARD_LEFT_CONTROL));
+        else /* Any other key should be set in a separate byte */
+            buf[i++] = (uint8_t)key;
 
-    return 7;
+        id >>= 8;
+    }
+
+    return BUF_LEN_KEYBOARD;
 }
 
+#define BUF_LEN_CONSUMER 4
 static uint8_t buf_set_consumer(unsigned char *buf, int id)
 {
-    memset(buf, 0, 4);
+    memset(buf, 0, BUF_LEN_CONSUMER);
     buf[0] = (uint8_t)id;
 
-    return 4;
+    return BUF_LEN_CONSUMER;
 }
 
+#ifdef HAVE_USB_HID_MOUSE
+#define MOUSE_WHEEL_STEP       1
+#define MOUSE_STEP             8
+#define MOUSE_BUTTON_LEFT    0x1
+#define MOUSE_BUTTON_RIGHT   0x2
+//#define MOUSE_BUTTON_MIDDLE  0x4
+#define MOUSE_BUTTON           0
+#define MOUSE_X                1
+#define MOUSE_Y                2
+#define MOUSE_WHEEL            3
+#define BUF_LEN_MOUSE          4
+#define MOUSE_ACCEL_FACTOR(count) ((count) / 2)
+#define MOUSE_DO(item, step) (buf[(item)] = ((uint8_t)(step)))
+
+static uint8_t buf_set_mouse(unsigned char *buf, int id)
+{
+    static int count = 0;
+    int step = MOUSE_STEP;
+
+    memset(buf, 0, BUF_LEN_MOUSE);
+
+    /* Set proper button */
+    switch (id)
+    {
+        case HID_MOUSE_BUTTON_LEFT:
+        case HID_MOUSE_LDRAG_UP:
+        case HID_MOUSE_LDRAG_UP_REP:
+        case HID_MOUSE_LDRAG_DOWN:
+        case HID_MOUSE_LDRAG_DOWN_REP:
+        case HID_MOUSE_LDRAG_LEFT:
+        case HID_MOUSE_LDRAG_LEFT_REP:
+        case HID_MOUSE_LDRAG_RIGHT:
+        case HID_MOUSE_LDRAG_RIGHT_REP:
+            MOUSE_DO(MOUSE_BUTTON, MOUSE_BUTTON_LEFT);
+            break;
+        case HID_MOUSE_BUTTON_RIGHT:
+        case HID_MOUSE_RDRAG_UP:
+        case HID_MOUSE_RDRAG_UP_REP:
+        case HID_MOUSE_RDRAG_DOWN:
+        case HID_MOUSE_RDRAG_DOWN_REP:
+        case HID_MOUSE_RDRAG_LEFT:
+        case HID_MOUSE_RDRAG_LEFT_REP:
+        case HID_MOUSE_RDRAG_RIGHT:
+        case HID_MOUSE_RDRAG_RIGHT_REP:
+            MOUSE_DO(MOUSE_BUTTON, MOUSE_BUTTON_RIGHT);
+            break;
+        case HID_MOUSE_BUTTON_LEFT_REL:
+        case HID_MOUSE_BUTTON_RIGHT_REL:
+            /* Keep buf empty, to mark mouse button release */
+            break;
+        default:
+            break;
+    }
+
+    /* Handle mouse accelarated movement */
+    switch (id)
+    {
+        case HID_MOUSE_UP:
+        case HID_MOUSE_DOWN:
+        case HID_MOUSE_LEFT:
+        case HID_MOUSE_RIGHT:
+        case HID_MOUSE_LDRAG_UP:
+        case HID_MOUSE_LDRAG_DOWN:
+        case HID_MOUSE_LDRAG_LEFT:
+        case HID_MOUSE_LDRAG_RIGHT:
+        case HID_MOUSE_RDRAG_UP:
+        case HID_MOUSE_RDRAG_DOWN:
+        case HID_MOUSE_RDRAG_LEFT:
+        case HID_MOUSE_RDRAG_RIGHT:
+            count = 0;
+            break;
+        case HID_MOUSE_UP_REP:
+        case HID_MOUSE_DOWN_REP:
+        case HID_MOUSE_LEFT_REP:
+        case HID_MOUSE_RIGHT_REP:
+        case HID_MOUSE_LDRAG_UP_REP:
+        case HID_MOUSE_LDRAG_DOWN_REP:
+        case HID_MOUSE_LDRAG_LEFT_REP:
+        case HID_MOUSE_LDRAG_RIGHT_REP:
+        case HID_MOUSE_RDRAG_UP_REP:
+        case HID_MOUSE_RDRAG_DOWN_REP:
+        case HID_MOUSE_RDRAG_LEFT_REP:
+        case HID_MOUSE_RDRAG_RIGHT_REP:
+            count++;
+            /* TODO: Find a better mouse accellaration algorithm */
+            step *= 1 + MOUSE_ACCEL_FACTOR(count);
+            if (step > 255)
+                step = 255;
+            break;
+        default:
+            break;
+    }
+
+    /* Move/scroll mouse */
+    switch (id)
+    {
+        case HID_MOUSE_UP:
+        case HID_MOUSE_UP_REP:
+        case HID_MOUSE_LDRAG_UP:
+        case HID_MOUSE_LDRAG_UP_REP:
+        case HID_MOUSE_RDRAG_UP:
+        case HID_MOUSE_RDRAG_UP_REP:
+            MOUSE_DO(MOUSE_Y, -step);
+            break;
+        case HID_MOUSE_DOWN:
+        case HID_MOUSE_DOWN_REP:
+        case HID_MOUSE_LDRAG_DOWN:
+        case HID_MOUSE_LDRAG_DOWN_REP:
+        case HID_MOUSE_RDRAG_DOWN:
+        case HID_MOUSE_RDRAG_DOWN_REP:
+            MOUSE_DO(MOUSE_Y, step);
+            break;
+        case HID_MOUSE_LEFT:
+        case HID_MOUSE_LEFT_REP:
+        case HID_MOUSE_LDRAG_LEFT:
+        case HID_MOUSE_LDRAG_LEFT_REP:
+        case HID_MOUSE_RDRAG_LEFT:
+        case HID_MOUSE_RDRAG_LEFT_REP:
+            MOUSE_DO(MOUSE_X, -step);
+            break;
+        case HID_MOUSE_RIGHT:
+        case HID_MOUSE_RIGHT_REP:
+        case HID_MOUSE_LDRAG_RIGHT:
+        case HID_MOUSE_LDRAG_RIGHT_REP:
+        case HID_MOUSE_RDRAG_RIGHT:
+        case HID_MOUSE_RDRAG_RIGHT_REP:
+            MOUSE_DO(MOUSE_X, step);
+            break;
+        case HID_MOUSE_SCROLL_UP:
+            MOUSE_DO(MOUSE_WHEEL, MOUSE_WHEEL_STEP);
+            break;
+        case HID_MOUSE_SCROLL_DOWN:
+            MOUSE_DO(MOUSE_WHEEL, -MOUSE_WHEEL_STEP);
+            break;
+        default:
+            break;
+    }
+
+    return BUF_LEN_MOUSE;
+}
+#endif /* HAVE_USB_HID_MOUSE */
+
 static size_t descriptor_report_get(unsigned char *dest)
 {
     unsigned char *report = dest;
@@ -306,59 +460,97 @@
     usb_hid_report = &usb_hid_reports[REPORT_ID_KEYBOARD];
     usb_hid_report->usage_page = HID_USAGE_PAGE_KEYBOARD_KEYPAD;
     usb_hid_report->buf_set = buf_set_keyboard;
+    usb_hid_report->is_key_released = 1;
 
-    pack_parameter(&report, 0, USAGE_PAGE,
+    pack_parameter(&report, 0, 1, USAGE_PAGE,
             HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS);
-    PACK_VAL2(report, CONCAT(CONSUMER_USAGE, HID_GENERIC_DESKTOP_KEYBOARD));
-    pack_parameter(&report, 0, COLLECTION, COLLECTION_APPLICATION);
-    pack_parameter(&report, 0, REPORT_ID, REPORT_ID_KEYBOARD);
-    pack_parameter(&report, 0, USAGE_PAGE, HID_GENERIC_DESKTOP_KEYPAD);
-    pack_parameter(&report, 0, USAGE_MINIMUM, HID_KEYBOARD_LEFT_CONTROL);
-    pack_parameter(&report, 0, USAGE_MAXIMUM, HID_KEYBOARD_RIGHT_GUI);
-    pack_parameter(&report, 1, LOGICAL_MINIMUM, 0);
-    pack_parameter(&report, 1, LOGICAL_MAXIMUM, 1);
-    pack_parameter(&report, 0, REPORT_SIZE, 1);
-    pack_parameter(&report, 0, REPORT_COUNT, 8);
-    pack_parameter(&report, 0, INPUT, MAIN_ITEM_VARIABLE);
-    pack_parameter(&report, 0, REPORT_SIZE, 1);
-    pack_parameter(&report, 0, REPORT_COUNT, 5);
-    pack_parameter(&report, 0, USAGE_PAGE, HID_USAGE_PAGE_LEDS);
-    pack_parameter(&report, 0, USAGE_MINIMUM, HID_LED_NUM_LOCK);
-    pack_parameter(&report, 0, USAGE_MAXIMUM, HID_LED_KANA);
-    pack_parameter(&report, 0, OUTPUT, MAIN_ITEM_VARIABLE);
-    pack_parameter(&report, 0, REPORT_SIZE, 3);
-    pack_parameter(&report, 0, REPORT_COUNT, 1);
-    pack_parameter(&report, 0, OUTPUT, MAIN_ITEM_CONSTANT);
-    pack_parameter(&report, 0, REPORT_SIZE, 8);
-    pack_parameter(&report, 0, REPORT_COUNT, 6);
-    pack_parameter(&report, 1, LOGICAL_MINIMUM, 0);
-    pack_parameter(&report, 1, LOGICAL_MAXIMUM, HID_KEYBOARD_EX_SEL);
-    pack_parameter(&report, 0, USAGE_PAGE, HID_USAGE_PAGE_KEYBOARD_KEYPAD);
-    pack_parameter(&report, 0, USAGE_MINIMUM, 0);
-    pack_parameter(&report, 0, USAGE_MAXIMUM, HID_KEYBOARD_EX_SEL);
-    pack_parameter(&report, 0, INPUT, 0);
-    PACK_VAL1(report, END_COLLECTION);
+    pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_KEYBOARD);
+    pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
+    pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_KEYBOARD);
+    pack_parameter(&report, 0, 1, USAGE_PAGE, HID_GENERIC_DESKTOP_KEYPAD);
+    pack_parameter(&report, 0, 1, USAGE_MINIMUM, HID_KEYBOARD_LEFT_CONTROL);
+    pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_KEYBOARD_RIGHT_GUI);
+    pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 0);
+    pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, 1);
+    pack_parameter(&report, 0, 1, REPORT_SIZE, 1);
+    pack_parameter(&report, 0, 1, REPORT_COUNT, 8);
+    pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE);
+    pack_parameter(&report, 0, 1, REPORT_SIZE, 1);
+    pack_parameter(&report, 0, 1, REPORT_COUNT, 5);
+    pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_LEDS);
+    pack_parameter(&report, 0, 1, USAGE_MINIMUM, HID_LED_NUM_LOCK);
+    pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_LED_KANA);
+    pack_parameter(&report, 0, 1, OUTPUT, MAIN_ITEM_VARIABLE);
+    pack_parameter(&report, 0, 1, REPORT_SIZE, 3);
+    pack_parameter(&report, 0, 1, REPORT_COUNT, 1);
+    pack_parameter(&report, 0, 1, OUTPUT, MAIN_ITEM_CONSTANT);
+    pack_parameter(&report, 0, 1, REPORT_SIZE, 8);
+    pack_parameter(&report, 0, 1, REPORT_COUNT, 6);
+    pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 0);
+    pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, HID_KEYBOARD_EX_SEL);
+    pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_KEYBOARD_KEYPAD);
+    pack_parameter(&report, 0, 1, USAGE_MINIMUM, 0);
+    pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_KEYBOARD_EX_SEL);
+    pack_parameter(&report, 0, 1, INPUT, 0);
+    PACK_VAL(report, END_COLLECTION);
 
     /* Consumer usage controls - play/pause, stop, etc. */
     usb_hid_report = &usb_hid_reports[REPORT_ID_CONSUMER];
     usb_hid_report->usage_page = HID_USAGE_PAGE_CONSUMER;
     usb_hid_report->buf_set = buf_set_consumer;
+    usb_hid_report->is_key_released = 1;
 
-    pack_parameter(&report, 0, USAGE_PAGE, HID_USAGE_PAGE_CONSUMER);
-    PACK_VAL2(report, CONCAT(CONSUMER_USAGE,
-                HID_CONSUMER_USAGE_CONSUMER_CONTROL));
-    pack_parameter(&report, 0, COLLECTION, COLLECTION_APPLICATION);
-    pack_parameter(&report, 0, REPORT_ID, REPORT_ID_CONSUMER);
-    pack_parameter(&report, 0, REPORT_SIZE, 16);
-    pack_parameter(&report, 0, REPORT_COUNT, 2);
-    pack_parameter(&report, 1, LOGICAL_MINIMUM, 1);
-    pack_parameter(&report, 1, LOGICAL_MAXIMUM, 652);
-    pack_parameter(&report, 0, USAGE_MINIMUM,
+    pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_CONSUMER);
+    pack_parameter(&report, 0, 0, CONSUMER_USAGE,
             HID_CONSUMER_USAGE_CONSUMER_CONTROL);
-    pack_parameter(&report, 0, USAGE_MAXIMUM, HID_CONSUMER_USAGE_AC_SEND);
-    pack_parameter(&report, 0, INPUT, MAIN_ITEM_NO_PREFERRED |
+    pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
+    pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_CONSUMER);
+    pack_parameter(&report, 0, 1, REPORT_SIZE, 16);
+    pack_parameter(&report, 0, 1, REPORT_COUNT, 2);
+    pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 1);
+    pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, 652);
+    pack_parameter(&report, 0, 1, USAGE_MINIMUM,
+            HID_CONSUMER_USAGE_CONSUMER_CONTROL);
+    pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_CONSUMER_USAGE_AC_SEND);
+    pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_NO_PREFERRED |
             MAIN_ITEM_NULL_STATE);
-    PACK_VAL1(report, END_COLLECTION);
+    PACK_VAL(report, END_COLLECTION);
+
+#ifdef HAVE_USB_HID_MOUSE
+    /* Mouse control */
+    usb_hid_report = &usb_hid_reports[REPORT_ID_MOUSE];
+    usb_hid_report->usage_page = HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS;
+    usb_hid_report->buf_set = buf_set_mouse;
+    usb_hid_report->is_key_released = 0;
+
+    pack_parameter(&report, 0, 1, USAGE_PAGE,
+            HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS);
+    pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_MOUSE);
+    pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
+    pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_MOUSE);
+    pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_POINTER);
+    pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_PHYSICAL);
+    pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_BUTTON);
+    pack_parameter(&report, 0, 1, USAGE_MINIMUM, 1);
+    pack_parameter(&report, 0, 1, USAGE_MAXIMUM, 8);
+    pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 0);
+    pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, 1);
+    pack_parameter(&report, 0, 1, REPORT_SIZE, 1);
+    pack_parameter(&report, 0, 1, REPORT_COUNT, 8);
+    pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE);
+    pack_parameter(&report, 0, 1, USAGE_PAGE,
+            HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS);
+    pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_X);
+    pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_Y);
+    pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_WHEEL);
+    pack_parameter(&report, 0, 1, LOGICAL_MINIMUM, -127 & 0xFF);
+    pack_parameter(&report, 0, 1, LOGICAL_MAXIMUM, 127);
+    pack_parameter(&report, 0, 1, REPORT_SIZE, 8);
+    pack_parameter(&report, 0, 1, REPORT_COUNT, 3);
+    pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE | MAIN_ITEM_RELATIVE);
+    PACK_VAL(report, END_COLLECTION);
+    PACK_VAL(report, END_COLLECTION);
+#endif /* HAVE_USB_HID_MOUSE */
 
     return (size_t)((uint32_t)report - (uint32_t)dest);
 }
@@ -368,6 +560,9 @@
     hid_descriptor.wDescriptorLength0 =
         (uint16_t)descriptor_report_get(report_descriptor);
 
+    logf("hid: desc len %u", hid_descriptor.wDescriptorLength0);
+    buf_dump(report_descriptor, hid_descriptor.wDescriptorLength0, "desc");
+
     PACK_DATA(*dest, hid_descriptor);
 }
 
@@ -457,8 +652,8 @@
  * to the DAP using the host's custom driver */
 static int usb_hid_set_report(struct usb_ctrlrequest *req)
 {
-    static unsigned char buf[SET_REPORT_BUF_LEN]
-        USB_DEVBSS_ATTR __attribute__((aligned(32)));
+    static unsigned char buf[SET_REPORT_BUF_LEN] USB_DEVBSS_ATTR
+        __attribute__((aligned(32)));
     int length;
     int rc = 0;
 
@@ -645,16 +840,22 @@
     length = report->buf_set(&buf[1], id) + 1;
     logf("length %u", length);
 
+    if (!length)
+        return;
+
     /* Key pressed */
-    buf_dump(buf, length);
+    buf_dump(buf, length, "key press");
     usb_hid_queue(buf, length);
 
-    /* Key released */
-    memset(buf, 0, length);
-    buf[0] = report_id;
+    if (report->is_key_released)
+    {
+        /* Key released */
+        memset(buf, 0, length);
+        buf[0] = report_id;
 
-    buf_dump(buf, length);
-    usb_hid_queue(buf, length);
+        buf_dump(buf, length, "key release");
+        usb_hid_queue(buf, length);
+    }
 
     usb_hid_try_send_drv();
 }
diff --git a/firmware/usbstack/usb_hid_usage_tables.h b/firmware/usbstack/usb_hid_usage_tables.h
index 9b64cd0..d23c704 100644
--- a/firmware/usbstack/usb_hid_usage_tables.h
+++ b/firmware/usbstack/usb_hid_usage_tables.h
@@ -701,5 +701,39 @@
 #define HID_CONSUMER_USAGE_AC_DISRIBUTE_HORIZONTALLY                      0x29B
 #define HID_CONSUMER_USAGE_AC_DISTRIBUTE_VERTICALLY                       0x29C
 
-#endif
+#ifdef HAVE_USB_HID_MOUSE
+/* Mouse defines (custom made - Rockbox specific) */
+#define HID_MOUSE_NONE                                                    0x00
+#define HID_MOUSE_UP                                                      0x01
+#define HID_MOUSE_UP_REP                                                  0x02
+#define HID_MOUSE_DOWN                                                    0x03
+#define HID_MOUSE_DOWN_REP                                                0x04
+#define HID_MOUSE_LEFT                                                    0x05
+#define HID_MOUSE_LEFT_REP                                                0x06
+#define HID_MOUSE_RIGHT                                                   0x07
+#define HID_MOUSE_RIGHT_REP                                               0x08
+#define HID_MOUSE_LDRAG_UP                                                0x09
+#define HID_MOUSE_LDRAG_UP_REP                                            0x0A
+#define HID_MOUSE_LDRAG_DOWN                                              0x0B
+#define HID_MOUSE_LDRAG_DOWN_REP                                          0x0C
+#define HID_MOUSE_LDRAG_LEFT                                              0x0D
+#define HID_MOUSE_LDRAG_LEFT_REP                                          0x0E
+#define HID_MOUSE_LDRAG_RIGHT                                             0x0F
+#define HID_MOUSE_LDRAG_RIGHT_REP                                         0x10
+#define HID_MOUSE_RDRAG_UP                                                0x11
+#define HID_MOUSE_RDRAG_UP_REP                                            0x12
+#define HID_MOUSE_RDRAG_DOWN                                              0x13
+#define HID_MOUSE_RDRAG_DOWN_REP                                          0x14
+#define HID_MOUSE_RDRAG_LEFT                                              0x15
+#define HID_MOUSE_RDRAG_LEFT_REP                                          0x16
+#define HID_MOUSE_RDRAG_RIGHT                                             0x17
+#define HID_MOUSE_RDRAG_RIGHT_REP                                         0x18
+#define HID_MOUSE_SCROLL_UP                                               0x19
+#define HID_MOUSE_SCROLL_DOWN                                             0x1A
+#define HID_MOUSE_BUTTON_LEFT                                             0x1B
+#define HID_MOUSE_BUTTON_LEFT_REL                                         0x1C
+#define HID_MOUSE_BUTTON_RIGHT                                            0x1D
+#define HID_MOUSE_BUTTON_RIGHT_REL                                        0x1E
+#endif /* HAVE_USB_HID_MOUSE */
 
+#endif
diff --git a/manual/configure_rockbox/system_options.tex b/manual/configure_rockbox/system_options.tex
index 52c42e0..be6e08a 100644
--- a/manual/configure_rockbox/system_options.tex
+++ b/manual/configure_rockbox/system_options.tex
@@ -182,3 +182,266 @@
       Changes the brightness of the button lights.
   }
 }
+\opt{USB_ENABLE_HID}{
+  \subsection{USB keypad Mode}
+    This setting control the keypad mode when the \dap{} is attached to a
+    computer through USB. The \dap{} registers itself as a USB keyboard (in
+    addition to being identified as a mass-storage device). Pressing a button
+    on the \dap{} sends a keystroke the computer the \dap{} is attached to,
+    according to the mapping set by the keypad mode.
+    The \dap{}'s keys can be mapped in different sets (modes) to achieve
+    different functionality. The following modes are available:
+    \begin{description}
+
+      \item [Multimedia: ]This mode lets you control the volume, playback, and
+        skips tracks on the host computer. It is equivalent for the multimedia
+        keys found on top of some multimedia keyboards.
+        \begin{table}
+          \begin{btnmap}{}{}
+            \opt{SANSA_E200_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonScrollBack / \ButtonScrollFwd}
+            \opt{GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}
+              {\ButtonVolUp / \ButtonVolDown}
+            \opt{IRIVER_H10_PAD}{\ButtonScrollUp / \ButtonScrollDown}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{\ButtonRCVolUp / \ButtonRCVolDown}%
+            }
+            & Volume up / down, respectively \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD,IPOD_4G_PAD%
+                ,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonSelect}
+            \opt{GIGABEAT_S_PAD}{\ButtonSelect; \ButtonBack}
+            \opt{IRIVER_H10_PAD}{\ButtonFF}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{Long \ButtonRCFF}%
+            }
+            & Volume mute \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}{\ButtonUp}
+            \opt{GIGABEAT_S_PAD,IRIVER_H10_PAD,IPOD_4G_PAD,IPOD_3G_PAD%
+                ,IPOD_1G2G_PAD}
+              {\ButtonPlay}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{\ButtonRCPlay}%
+            }
+            & Play / Pause \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD}{\ButtonPower}
+            \opt{GIGABEAT_S_PAD}{\ButtonMenu}
+            \opt{SANSA_CLIP_PAD}{\ButtonHome}
+            \opt{IRIVER_H10_PAD}{\ButtonRew}
+            \opt{IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}{Long \ButtonPlay}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{Long \ButtonRCPlay}%
+            }
+            & Stop \\
+            %
+            \opt{SANSA_E200_PAD,GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD%
+                ,IRIVER_H10_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonLeft / \ButtonRight}
+            \opt{SANSA_E200_PAD}{\ButtonMenu}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{\ButtonRCRew / \ButtonRCFF}%
+            }
+            & Scan previous / next track \\
+          \end{btnmap}
+        \end{table}
+
+      \item [Presentation: ]This mode lets you control a presentation program
+        (e.g. OpenOffice Impress, and some other popular application), making
+        the \dap{} a wired remote control device. This mode is can be useful
+        for lecturers who does not have a wireless remote control for this
+        purpose.
+        \begin{table}
+          \begin{btnmap}{}{}
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD}{\ButtonUp / \ButtonPower}
+            \opt{GIGABEAT_S_PADIRIVER_H10_PAD}{\ButtonPlay / \ButtonMenu}
+            \opt{SANSA_CLIP_PAD}{\ButtonUp / \ButtonHome}
+            \opt{IRIVER_H10_PAD}{\ButtonPlay / \ButtonRew}
+            \opt{IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonPlay / Long \ButtonPlay}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{\ButtonRCPlay / Long \ButtonRCPlay}%
+            }
+            & Slideshow start / leave, respectively \\
+            %
+            \opt{SANSA_E200_PAD,GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD%
+            ,IRIVER_H10_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonLeft / \ButtonRight}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{\ButtonRCRew / \ButtonRCFF}%
+            }
+            & Slide previous / next, respectively \\
+            %
+            \opt{SANSA_E200_PAD,GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD%
+            ,IRIVER_H10_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {Long \ButtonLeft / Long \ButtonRight}
+            \opt{HAVEREMOTEKEYMAP}{& }
+            & Slide first / last, respectively \\
+            %
+            \opt{SANSA_E200_PAD,GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}
+              {\ButtonDown}
+            \opt{IRIVER_H10_PAD}{\ButtonPower}
+            \opt{IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}{\ButtonMenu}
+            \opt{HAVEREMOTEKEYMAP}{& }
+            & Blank screen \\
+            %
+            \opt{SANSA_E200_PAD,GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}
+              {Long \ButtonDown}
+            \opt{HAVEREMOTEKEYMAP}{& }
+            & White screen \\
+            %
+            \opt{SANSA_E200_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonScrollBack / \ButtonScrollFwd}
+            \opt{GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}
+              {\ButtonVolUp / \ButtonVolDown}
+            \opt{IRIVER_H10_PAD}{\ButtonScrollUp / \ButtonScrollDown}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{\ButtonRCVolUp / \ButtonRCVolDown}%
+            }
+            & Previous / next link in slide, respectively \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD,IPOD_4G_PAD%
+                ,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonSelect}
+            \opt{GIGABEAT_S_PAD}{\ButtonSelect; \ButtonBack}
+            \opt{IRIVER_H10_PAD}{\ButtonFF}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{Long \ButtonRCFF}%
+            }
+            & Perform a 'mouse click' over a link \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD,IPOD_4G_PAD%
+                ,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {Long \ButtonSelect}
+            \opt{GIGABEAT_S_PAD}{Long \ButtonSelect; Long \ButtonBack}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{Long \ButtonRCRew}%
+            }
+            & Perform a 'mouse over' over a link \\
+          \end{btnmap}
+        \end{table}
+
+      \item [Browser: ]This mode lets you control a web browser (e.g. Firefox).
+        It uses the \dap{}'s keys to navigate through the web page and
+        different tabs, navigate through history, and to control zoom.
+        \begin{table}
+          \begin{btnmap}{}{}
+            \opt{SANSA_E200_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonScrollBack / \ButtonScrollFwd}
+            \opt{GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}
+              {\ButtonVolUp / \ButtonVolDown}
+            \opt{IRIVER_H10_PAD}{\ButtonScrollUp / \ButtonScrollDown}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{\ButtonRCVolUp / \ButtonRCVolDown}%
+            }
+            & Scroll up / down, respectively \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}
+              {\ButtonUp / \ButtonDown}
+            \opt{GIGABEAT_S_PAD}{\ButtonPlay / \ButtonDown}
+            \opt{IRIVER_H10_PAD}{\ButtonPlay / \ButtonPower}
+            \opt{IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonPlay / \ButtonMenu}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{\ButtonRCPlay / Long \ButtonRCDsp}%
+            }
+            & Scroll page up / down, respectively \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}
+              {Long \ButtonUp / Long \ButtonDown}
+            \opt{GIGABEAT_S_PAD}{Long \ButtonPlay / Long \ButtonPower}
+            \opt{HAVEREMOTEKEYMAP}{& }
+            & Zoom in / out, respectively \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}
+              {Long \ButtonSelect}
+            \opt{GIGABEAT_S_PAD}{Long \ButtonSelect; Long \ButtonBack}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{Long \ButtonRCRew}%
+            }
+            & Zoom reset \\
+            %
+            \opt{SANSA_E200_PAD,GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD%
+                ,IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonLeft / \ButtonRight}
+            \opt{IRIVER_H10_PAD}{\ButtonRew / \ButtonFF}
+            \opt{HAVEREMOTEKEYMAP}{& }
+            & Tab previous / next, respectively \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD}{Long \ButtonPower}
+            \opt{GIGABEAT_S_PAD}{Long \ButtonMenu}
+            \opt{SANSA_CLIP_PAD}{Long \ButtonHome}
+            \opt{HAVEREMOTEKEYMAP}{& }
+            & Tab close \\
+            %
+            \opt{SANSA_E200_PAD,GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD%
+            ,IRIVER_H10_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {Long \ButtonLeft / Long \ButtonRight}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{\ButtonRCRew / \ButtonRCFF}%
+            }
+            & History back / forward \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD,IPOD_4G_PAD%
+                ,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonSelect}
+            \opt{GIGABEAT_S_PAD}{Long \ButtonSelect; Long \ButtonBack}
+            \opt{IRIVER_H10_PAD}{\ButtonFF}
+            \opt{HAVEREMOTEKEYMAP}{
+              &
+              \opt{GIGABEAT_RC_PAD}{Long \ButtonRCRew}%
+            }
+            & View full screen toggle \\
+          \end{btnmap}
+        \end{table}
+
+      \item [Mouse: ]This mode emulates a mouse. Features supported: Mouse
+        movement; left and right button clicking; and dragging and dropping.
+        \begin{table}
+          \begin{btnmap}{}{}
+            \opt{SANSA_E200_PAD,GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}
+              {\ButtonUp / \ButtonDown / \ButtonLeft / \ButtonRight}
+            \opt{IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonMenu / \ButtonPlay / \ButtonLeft / \ButtonRight}
+            \opt{HAVEREMOTEKEYMAP}{& }
+            & Move cursor up / down / left / right, respectively \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD,IPOD_4G_PAD%
+                ,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonSelect}
+            \opt{GIGABEAT_S_PAD}{\ButtonSelect; \ButtonBack}
+            \opt{HAVEREMOTEKEYMAP}{& }
+            & Left mouse button click \\
+            %
+            \opt{SANSA_E200_PAD,SANSA_C200_PAD}{\ButtonPower}
+            \opt{GIGABEAT_S_PAD}{\ButtonMenu}
+            \opt{SANSA_CLIP_PAD}{\ButtonHome}
+            \opt{HAVEREMOTEKEYMAP}{& }
+            & Right mouse button click \\
+            %
+            \opt{SANSA_E200_PAD,IPOD_4G_PAD,IPOD_3G_PAD,IPOD_1G2G_PAD}
+              {\ButtonScrollBack / \ButtonScrollFwd}
+            \opt{GIGABEAT_S_PAD,SANSA_C200_PAD,SANSA_CLIP_PAD}
+              {\ButtonVolUp / \ButtonVolDown}
+            \opt{HAVEREMOTEKEYMAP}{& }
+            & Mouse wheel scroll up / down, respectively \\
+          \end{btnmap}
+        \end{table}
+    \end{description}
+}
diff --git a/manual/platform/c200.tex b/manual/platform/c200.tex
index 0c7473e..9b5c9b5 100644
--- a/manual/platform/c200.tex
+++ b/manual/platform/c200.tex
@@ -5,6 +5,7 @@
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_CAR_ADAPTER_MODE}
 \edef\UseOption{\UseOption,HAVE_BUTTON_LIGHTS}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,sansa}
 
 \newcommand{\playerman}{Sansa}
diff --git a/manual/platform/clip.tex b/manual/platform/clip.tex
index c6811b6..f0cf719 100644
--- a/manual/platform/clip.tex
+++ b/manual/platform/clip.tex
@@ -4,6 +4,7 @@
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_CAR_ADAPTER_MODE}
 \edef\UseOption{\UseOption,HAVE_BUTTON_LIGHTS}
+%\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,sansaAMS}
 
 \newcommand{\playerman}{Sansa}
diff --git a/manual/platform/e200.tex b/manual/platform/e200.tex
index d20d34f..ec10b59 100644
--- a/manual/platform/e200.tex
+++ b/manual/platform/e200.tex
@@ -5,6 +5,7 @@
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_CAR_ADAPTER_MODE}
 \edef\UseOption{\UseOption,HAVE_BUTTON_LIGHTS}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,sansa}
 
 \newcommand{\playerman}{Sansa}
diff --git a/manual/platform/gigabeats.tex b/manual/platform/gigabeats.tex
index 920eb17..6a470db 100644
--- a/manual/platform/gigabeats.tex
+++ b/manual/platform/gigabeats.tex
@@ -8,6 +8,7 @@
 \edef\UseOption{\UseOption,gigabeat}
 \edef\UseOption{\UseOption,GIGABEAT_RC_PAD}
 \edef\UseOption{\UseOption,HAVEREMOTEKEYMAP}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 
 \newcommand{\playerman}{Toshiba}
 \newcommand{\playertype}{Gigabeat S Series}
diff --git a/manual/platform/h10.tex b/manual/platform/h10.tex
index 4b99b1b..406985d 100644
--- a/manual/platform/h10.tex
+++ b/manual/platform/h10.tex
@@ -5,6 +5,7 @@
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_DISK_STORAGE}
 \edef\UseOption{\UseOption,HAVE_CAR_ADAPTER_MODE}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,iriver}
 
 \newcommand{\playerman}{Iriver}
diff --git a/manual/platform/h10_5gb.tex b/manual/platform/h10_5gb.tex
index d89e1ea..e338062 100644
--- a/manual/platform/h10_5gb.tex
+++ b/manual/platform/h10_5gb.tex
@@ -5,6 +5,7 @@
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_DISK_STORAGE}
 \edef\UseOption{\UseOption,HAVE_CAR_ADAPTER_MODE}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,iriver}
 
 \newcommand{\playerman}{Iriver}
diff --git a/manual/platform/ipod1g2g.tex b/manual/platform/ipod1g2g.tex
index 28679a5..d26ee26 100644
--- a/manual/platform/ipod1g2g.tex
+++ b/manual/platform/ipod1g2g.tex
@@ -4,6 +4,7 @@
 \edef\UseOption{\UseOption,IPOD_3G_PAD}
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_DISK_STORAGE}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,ipod}
 
 \newcommand{\playerman}{Ipod}
diff --git a/manual/platform/ipod3g.tex b/manual/platform/ipod3g.tex
index 21ca69a..ed24202 100644
--- a/manual/platform/ipod3g.tex
+++ b/manual/platform/ipod3g.tex
@@ -4,6 +4,7 @@
 \edef\UseOption{\UseOption,IPOD_3G_PAD}
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_DISK_STORAGE}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,ipod}
 
 \newcommand{\playerman}{Ipod}
diff --git a/manual/platform/ipod4g.tex b/manual/platform/ipod4g.tex
index 06483fa..51f5a1f 100644
--- a/manual/platform/ipod4g.tex
+++ b/manual/platform/ipod4g.tex
@@ -4,6 +4,7 @@
 \edef\UseOption{\UseOption,IPOD_4G_PAD}
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_DISK_STORAGE}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,ipod}
 
 \newcommand{\playerman}{Ipod}
diff --git a/manual/platform/ipodcolor.tex b/manual/platform/ipodcolor.tex
index 04dc457..aed9089 100644
--- a/manual/platform/ipodcolor.tex
+++ b/manual/platform/ipodcolor.tex
@@ -4,6 +4,7 @@
 \edef\UseOption{\UseOption,IPOD_4G_PAD}
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_DISK_STORAGE}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,ipod}
 
 \newcommand{\playerman}{Ipod}
diff --git a/manual/platform/ipodmini.tex b/manual/platform/ipodmini.tex
index 7671a4f..24dbfb0 100644
--- a/manual/platform/ipodmini.tex
+++ b/manual/platform/ipodmini.tex
@@ -4,6 +4,7 @@
 \edef\UseOption{\UseOption,IPOD_4G_PAD}
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_DISK_STORAGE}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,ipod}
 
 \newcommand{\playerman}{Ipod}
diff --git a/manual/platform/ipodnano.tex b/manual/platform/ipodnano.tex
index 974fe68..027ec8d 100644
--- a/manual/platform/ipodnano.tex
+++ b/manual/platform/ipodnano.tex
@@ -3,6 +3,7 @@
 \edef\UseOption{\UseOption,HAVE_RB_BL_ON_DISK}
 \edef\UseOption{\UseOption,IPOD_4G_PAD}
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,ipod}
 
 \newcommand{\playerman}{Ipod}
diff --git a/manual/platform/ipodvideo.tex b/manual/platform/ipodvideo.tex
index ff18551..3712a96 100644
--- a/manual/platform/ipodvideo.tex
+++ b/manual/platform/ipodvideo.tex
@@ -5,6 +5,7 @@
 \edef\UseOption{\UseOption,HAVE_BACKLIGHT}
 \edef\UseOption{\UseOption,HAVE_DISK_STORAGE}
 \edef\UseOption{\UseOption,HAVE_CAR_ADAPTER_MODE}
+\edef\UseOption{\UseOption,USB_ENABLE_HID}
 \edef\UseOption{\UseOption,ipod}
 
 \newcommand{\playerman}{Ipod}
diff --git a/manual/platform/keymap-gigabeats.tex b/manual/platform/keymap-gigabeats.tex
index f0f3f12..004f5ad 100644
--- a/manual/platform/keymap-gigabeats.tex
+++ b/manual/platform/keymap-gigabeats.tex
@@ -7,8 +7,8 @@
 \newcommand{\ButtonRight}{\btnfnt{Right}}
 \newcommand{\ButtonUp}{\btnfnt{Up}}
 \newcommand{\ButtonDown}{\btnfnt{Down}}
-\newcommand{\ButtonVolUp}{\btnfnt{Volume up}}
-\newcommand{\ButtonVolDown}{\btnfnt{Volume down}}
+\newcommand{\ButtonVolUp}{\btnfnt{Volume Up}}
+\newcommand{\ButtonVolDown}{\btnfnt{Volume Down}}
 \newcommand{\ButtonSelect}{\btnfnt{Select}}
 \newcommand{\ButtonPrev}{\btnfnt{Previous}}
 \newcommand{\ButtonPlay}{\btnfnt{Play}}