From 83d24f89df743452512357b11f4331c17f5bd6f4 Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Fri, 23 Oct 2009 13:29:19 +0000 Subject: [PATCH] FS#10704 - Make a configuration option to disable USB HID git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23322 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/usb_screen.c | 41 ++++++++------ apps/lang/english.lang | 17 ++++++ apps/menus/settings_menu.c | 2 + apps/misc.c | 12 ++++ apps/misc.h | 7 +++ apps/screens.c | 12 ---- apps/settings.h | 1 + apps/settings_list.c | 2 + apps/usb_keymaps.c | 62 ++++++++++++--------- firmware/export/usb.h | 4 ++ firmware/usb.c | 16 +++++- manual/appendix/config_file_options.tex | 5 ++ manual/configure_rockbox/system_options.tex | 8 +++ manual/rockbox_interface/main.tex | 5 ++ 14 files changed, 137 insertions(+), 57 deletions(-) diff --git a/apps/gui/usb_screen.c b/apps/gui/usb_screen.c index f2c25554df..50188274d2 100644 --- a/apps/gui/usb_screen.c +++ b/apps/gui/usb_screen.c @@ -49,6 +49,7 @@ #ifdef USB_ENABLE_HID int usb_keypad_mode; +static bool usb_hid; #endif #ifndef SIMULATOR @@ -64,7 +65,7 @@ static int handle_usb_events(void) { int button; #ifdef USB_ENABLE_HID - if (usb_core_driver_enabled(USB_DRIVER_HID)) + if (usb_hid) { button = get_hid_usb_action(); @@ -157,20 +158,24 @@ static void usb_screen_fix_viewports(struct screen *screen, logo->height = logo_height; #ifdef USB_ENABLE_HID - struct viewport *title = &usb_screen_vps->title; - int char_height, nb_lines; + if (usb_hid) + { + struct viewport *title = &usb_screen_vps->title; + int char_height, nb_lines; - /* nb_lines only returns the number of fully visible lines, small screens - or really large fonts could cause problems with the calculation below. - */ - nb_lines = viewport_get_nb_lines(parent); - if (nb_lines == 0) - nb_lines++; + /* nb_lines only returns the number of fully visible lines, small + * screens or really large fonts could cause problems with the + * calculation below. + */ + nb_lines = viewport_get_nb_lines(parent); + if (nb_lines == 0) + nb_lines++; - char_height = parent->height/nb_lines; + char_height = parent->height/nb_lines; - *title = *parent; - title->y = logo->y + logo->height + char_height; + *title = *parent; + title->y = logo->y + logo->height + char_height; + } #endif } #endif @@ -209,9 +214,12 @@ static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar) screen->transparent_bitmap(usblogo, 0, 0, logo->width, logo->height); #ifdef USB_ENABLE_HID - screen->set_viewport(&usb_screen_vps->title); - usb_screen_vps->title.flags |= VP_FLAG_ALIGN_CENTER; - screen->puts_scroll(0, 0, str(keypad_mode_name_get())); + if (usb_hid) + { + screen->set_viewport(&usb_screen_vps->title); + usb_screen_vps->title.flags |= VP_FLAG_ALIGN_CENTER; + screen->puts_scroll(0, 0, str(keypad_mode_name_get())); + } #endif /* USB_ENABLE_HID */ } screen->set_viewport(parent); @@ -252,6 +260,7 @@ void gui_usb_screen_run(void) #endif #ifdef USB_ENABLE_HID + usb_hid = global_settings.usb_hid; usb_keypad_mode = global_settings.usb_keypad_mode; #endif @@ -283,7 +292,7 @@ void gui_usb_screen_run(void) const struct viewport* vp = NULL; #if defined(HAVE_LCD_BITMAP) && defined(USB_ENABLE_HID) - vp = &usb_screen_vps_ar[i].title; + vp = usb_hid ? &usb_screen_vps_ar[i].title : NULL; #elif !defined(HAVE_LCD_BITMAP) vp = &usb_screen_vps_ar[i].parent; #endif diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 16fc022af6..d7dba2f3c0 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -13165,3 +13165,20 @@ remote: "Remote Custom Statusbar" + + id: LANG_USB_HID + desc: in settings_menu + user: core + + *: none + usb_hid: "USB HID" + + + *: none + usb_hid: "USB HID" + + + *: none + usb_hid: "USB Human Interface Device" + + diff --git a/apps/menus/settings_menu.c b/apps/menus/settings_menu.c index 71a6089e68..c11bf0eb3d 100644 --- a/apps/menus/settings_menu.c +++ b/apps/menus/settings_menu.c @@ -253,6 +253,7 @@ 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_hid, &global_settings.usb_hid, NULL); MENUITEM_SETTING(usb_keypad_mode, &global_settings.usb_keypad_mode, NULL); #endif @@ -304,6 +305,7 @@ MAKE_MENU(system_menu, ID2P(LANG_SYSTEM), &touchpad_sensitivity, #endif #ifdef USB_ENABLE_HID + &usb_hid, &usb_keypad_mode, #endif ); diff --git a/apps/misc.c b/apps/misc.c index 47ebf58080..5af57feb11 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -1047,4 +1047,16 @@ err: va_end(ap); return 0; } + +/* only used in USB HID and set_time screen */ +#if defined(USB_ENABLE_HID) || (CONFIG_RTC != 0) +int clamp_value_wrap(int value, int max, int min) +{ + if (value > max) + return min; + if (value < min) + return max; + return value; +} +#endif #endif diff --git a/apps/misc.h b/apps/misc.h index a8ed6029a3..857d9ab4da 100644 --- a/apps/misc.h +++ b/apps/misc.h @@ -92,6 +92,7 @@ bool dir_exists(const char *path); */ char *strip_extension(char* buffer, int buffer_size, const char *filename); +#ifdef HAVE_LCD_BITMAP /* A simplified scanf */ /* * Checks whether the value at position 'position' was really read @@ -103,4 +104,10 @@ char *strip_extension(char* buffer, int buffer_size, const char *filename); const char* parse_list(const char *fmt, uint32_t *set_vals, const char sep, const char* str, ...); +/* only used in USB HID and set_time screen */ +#if defined(USB_ENABLE_HID) || (CONFIG_RTC != 0) +int clamp_value_wrap(int value, int max, int min); +#endif +#endif + #endif /* MISC_H */ diff --git a/apps/screens.c b/apps/screens.c index ab721a8654..5f84830c00 100644 --- a/apps/screens.c +++ b/apps/screens.c @@ -60,18 +60,6 @@ #include "dsp.h" #endif -/* only used in set_time screen */ -#if defined(HAVE_LCD_BITMAP) && (CONFIG_RTC != 0) -static int clamp_value_wrap(int value, int max, int min) -{ - if (value > max) - return min; - if (value < min) - return max; - return value; -} -#endif - #if (CONFIG_STORAGE & STORAGE_MMC) int mmc_remove_request(void) { diff --git a/apps/settings.h b/apps/settings.h index d1179ed5bc..c9ff3f9dd3 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -781,6 +781,7 @@ struct user_settings /* new stuff to be added at the end */ #ifdef USB_ENABLE_HID + bool usb_hid; int usb_keypad_mode; #endif diff --git a/apps/settings_list.c b/apps/settings_list.c index 5bfce331cd..5a0e05d7d2 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -31,6 +31,7 @@ #include "backlight.h" #include "settings.h" #include "settings_list.h" +#include "usb.h" #include "sound.h" #include "dsp.h" #include "mpeg.h" @@ -1623,6 +1624,7 @@ const struct settings_list settings[] = { #endif #ifdef USB_ENABLE_HID + OFFON_SETTING(0, usb_hid, LANG_USB_HID, true, "usb hid", usb_set_hid), CHOICE_SETTING(0, usb_keypad_mode, LANG_USB_KEYPAD_MODE, 0, "usb keypad mode", "multimedia,presentation,browser" #ifdef HAVE_USB_HID_MOUSE diff --git a/apps/usb_keymaps.c b/apps/usb_keymaps.c index f787de692f..f04fa54c3d 100644 --- a/apps/usb_keymaps.c +++ b/apps/usb_keymaps.c @@ -23,6 +23,7 @@ #ifdef USB_ENABLE_HID #include "action.h" #include "lang.h" +#include "misc.h" #include "usbstack/usb_hid.h" //#define LOGF_ENABLE #include "logf.h" @@ -174,40 +175,47 @@ extern int usb_keypad_mode; int get_hid_usb_action(void) { - int action; + int action, step; const hid_key_mapping_t *key_mapping = hid_key_mappings[usb_keypad_mode]; + step = -1; action = get_action(key_mapping->context, HZ/4); - /* Skip key mappings in a cyclic way */ - if (action == ACTION_USB_HID_MODE_SWITCH_NEXT) + switch (action) { - /* TODO: Use clamp_value_wrap() */ - usb_keypad_mode = (usb_keypad_mode + 1) % NUM_KEY_MAPPINGS; - } - else if (action == ACTION_USB_HID_MODE_SWITCH_PREV) - { - /* TODO: Use clamp_value_wrap() */ - 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) + case ACTION_USB_HID_MODE_SWITCH_NEXT: + step = 1; + case ACTION_USB_HID_MODE_SWITCH_PREV: + /* Switch key mappings in a cyclic way */ + usb_keypad_mode = clamp_value_wrap(usb_keypad_mode + step, + NUM_KEY_MAPPINGS - 1, 0); + break; + default: { - logf("Action %d", action); - usb_hid_send(key_mapping->usage_page, mapping->id); + const mapping_t *mapping; + const hid_key_mapping_t *key_mapping = + hid_key_mappings[usb_keypad_mode]; + + if (action <= ACTION_USB_HID_FIRST || + action >= ACTION_USB_HID_LAST) + { + break; + } + + 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 break; } - } -#ifdef DEBUG - if (!mapping->action) - logf("Action %d not found", action); -#endif } return action; diff --git a/firmware/export/usb.h b/firmware/export/usb.h index 911fa931d9..c380ac518d 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h @@ -148,4 +148,8 @@ bool firewire_detect(void); void usb_firewire_connect_event(void); #endif +#ifdef USB_ENABLE_HID +void usb_set_hid(bool enable); +#endif + #endif diff --git a/firmware/usb.c b/firmware/usb.c index 62a335f712..dd0ef9dfe4 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -218,6 +218,10 @@ static inline bool usb_reboot_button(void) #endif #endif /* HAVE_USB_POWER */ +#ifdef USB_ENABLE_HID +static bool usb_hid = true; +#endif + static void usb_thread(void) { int num_acks_to_expect = 0; @@ -284,7 +288,7 @@ static void usb_thread(void) #ifdef USB_ENABLE_CHARGING_ONLY usb_core_enable_driver(USB_DRIVER_HID, false); #else - usb_core_enable_driver(USB_DRIVER_HID, true); + usb_core_enable_driver(USB_DRIVER_HID, usb_hid); #endif /* USB_ENABLE_CHARGING_ONLY */ #endif /* USB_ENABLE_HID */ @@ -307,7 +311,7 @@ static void usb_thread(void) usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, true); #endif #ifdef USB_ENABLE_HID - usb_core_enable_driver(USB_DRIVER_HID, true); + usb_core_enable_driver(USB_DRIVER_HID, usb_hid); #endif #ifdef USB_ENABLE_CHARGING_ONLY usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, false); @@ -691,6 +695,14 @@ bool usb_powered(void) } #endif +#ifdef USB_ENABLE_HID +void usb_set_hid(bool enable) +{ + usb_hid = enable; + usb_core_enable_driver(USB_DRIVER_HID, usb_hid); +} +#endif + #else #ifdef USB_NONE diff --git a/manual/appendix/config_file_options.tex b/manual/appendix/config_file_options.tex index f6c95652a9..43f6aea203 100644 --- a/manual/appendix/config_file_options.tex +++ b/manual/appendix/config_file_options.tex @@ -95,6 +95,11 @@ \opt{accessory_supply}{ accessory power supply & on, off & N/A\\ } + \opt{usb_hid}{ + usb hid & on, off & N/A\\ + usb keypad mode + & multimedia, presentation, browser\opt{usb_hid_mouse}{, mouse}& N/A\\ + } idle poweroff & off, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 30, 45, 60 & minutes\\ max files in playlist & 1000 - 32000 & N/A\\ diff --git a/manual/configure_rockbox/system_options.tex b/manual/configure_rockbox/system_options.tex index 6a98b32a20..0651d61f7d 100644 --- a/manual/configure_rockbox/system_options.tex +++ b/manual/configure_rockbox/system_options.tex @@ -183,6 +183,14 @@ this option \setting{On}. If it is not required, then turning this setting } } \opt{usb_hid}{ + \subsection{USB HID} + \label{ref:USB_HID} + This option turns the USB HID feature \setting{On} and \setting{Off}. + When this feature is enabled, the \dap{} enumerates as a Human Interface + Device (HID), composed of several HID sub devices. + Since the \dap{} also enumerates as a Mass Storage Device, it becomes a USB + Composite Device, which contains both these devices. + \subsection{USB Keypad Mode} This setting control the keypad mode when the \dap{} is attached to a computer through USB. Pressing a key on the \dap{} sends a keystroke the diff --git a/manual/rockbox_interface/main.tex b/manual/rockbox_interface/main.tex index d992fdea97..834a039053 100644 --- a/manual/rockbox_interface/main.tex +++ b/manual/rockbox_interface/main.tex @@ -580,6 +580,11 @@ To turn on and off your Rockbox enabled \dap{} use the following keys: } \subsection{Putting music on your \dap{}} +\note{Due to a bug in some OS X versions, the \dap{} can not be mounted, unless + the USB HID feature is disabled. See \reference{ref:USB_HID} for more + information.\newline +} + With the \dap{} connected to the computer as an MSC/UMS device (like a USB Drive), music files can be put on the player via any standard file transfer method that you would use to copy files between drives (e.g. Drag 'n' Drop).