Fuze+: add a configurable deadzone area for touchpad buttons

To stop erroneous button presses, allow users to add a deadzone between
the button via the Settings > General > System menu > Touch Dead Zone.

The configuration was chosen this way: the touchpad has the same DPI
in both direction so the setting applies the same on both the X and Y
axis. The setting ranges from 0 to 100 and is internally multiplied by 2
giving a maximum deadzone of 2*100 = 200 around each button, which
account for 400 total (once around each button), effectively reducing
each virtual button from 1000x600 to 600x200 when using the maximum value.

Change-Id: I8683c63d2950200eb32d1dda0a00bbd92d83d5be
Reviewed-on: http://gerrit.rockbox.org/677
Reviewed-by: Benjamin Brown <foolshperson@gmail.com>
Tested: Benjamin Brown <foolshperson@gmail.com>
Reviewed-by: Amaury Pouly <amaury.pouly@gmail.com>
This commit is contained in:
Amaury Pouly 2013-12-01 18:25:42 +00:00
parent 847106cdb2
commit 8146b40e73
10 changed files with 108 additions and 28 deletions

View file

@ -199,6 +199,10 @@ lineout_poweroff
touchscreen touchscreen
#endif #endif
#if defined(HAVE_TOUCHPAD_DEADZONE)
touchpad_deadzone
#endif
#if defined(HAVE_IMX233_CODEC) || defined(HAVE_WM8750) || defined(HAVE_WM8978) #if defined(HAVE_IMX233_CODEC) || defined(HAVE_WM8750) || defined(HAVE_WM8978)
depth_3d depth_3d
#endif #endif

View file

@ -10605,6 +10605,23 @@
gigabeatfx,sansafuzeplus: "Touchpad Sensitivity" gigabeatfx,sansafuzeplus: "Touchpad Sensitivity"
</voice> </voice>
</phrase> </phrase>
<phrase>
id: LANG_DEADZONE
desc: touchpad deadzone setting
user: core
<source>
*: none
sansafuzeplus: "Touchpad Dead Zone"
</source>
<dest>
*: none
sansafuzeplus: "Touchpad Dead Zone"
</dest>
<voice>
*: none
sansafuzeplus: "Touchpad Dead Zone"
</voice>
</phrase>
<phrase> <phrase>
id: LANG_HIGH id: LANG_HIGH
desc: in settings_menu desc: in settings_menu

View file

@ -10692,6 +10692,23 @@
gigabeatfx,sansafuzeplus: "Touchpad Sensitivity" gigabeatfx,sansafuzeplus: "Touchpad Sensitivity"
</voice> </voice>
</phrase> </phrase>
<phrase>
id: LANG_DEADZONE
desc: touchpad deadzone setting
user: core
<source>
*: none
sansafuzeplus: "Touchpad Dead Zone"
</source>
<dest>
*: none
sansafuzeplus: "Touchpad Dead Zone"
</dest>
<voice>
*: none
sansafuzeplus: "Touchpad Dead Zone"
</voice>
</phrase>
<phrase> <phrase>
id: LANG_HIGH id: LANG_HIGH
desc: in settings_menu desc: in settings_menu

View file

@ -317,6 +317,10 @@ MENUITEM_SETTING(buttonlight_brightness, &global_settings.buttonlight_brightness
MENUITEM_SETTING(touchpad_sensitivity, &global_settings.touchpad_sensitivity, NULL); MENUITEM_SETTING(touchpad_sensitivity, &global_settings.touchpad_sensitivity, NULL);
#endif #endif
#ifdef HAVE_TOUCHPAD_DEADZONE
MENUITEM_SETTING(touchpad_deadzone, &global_settings.touchpad_deadzone, NULL);
#endif
#ifdef HAVE_QUICKSCREEN #ifdef HAVE_QUICKSCREEN
MENUITEM_SETTING(shortcuts_replaces_quickscreen, &global_settings.shortcuts_replaces_qs, NULL); MENUITEM_SETTING(shortcuts_replaces_quickscreen, &global_settings.shortcuts_replaces_qs, NULL);
#endif #endif
@ -363,6 +367,9 @@ MAKE_MENU(system_menu, ID2P(LANG_SYSTEM),
#ifdef HAVE_TOUCHPAD_SENSITIVITY_SETTING #ifdef HAVE_TOUCHPAD_SENSITIVITY_SETTING
&touchpad_sensitivity, &touchpad_sensitivity,
#endif #endif
#ifdef HAVE_TOUCHPAD_DEADZONE
&touchpad_deadzone,
#endif
#ifdef USB_ENABLE_HID #ifdef USB_ENABLE_HID
&usb_hid, &usb_hid,
&usb_keypad_mode, &usb_keypad_mode,

View file

@ -1061,6 +1061,10 @@ void settings_apply(bool read_disk)
touchpad_set_sensitivity(global_settings.touchpad_sensitivity); touchpad_set_sensitivity(global_settings.touchpad_sensitivity);
#endif #endif
#ifdef HAVE_TOUCHPAD_DEADZONE
touchpad_set_deadzone(global_settings.touchpad_deadzone);
#endif
#ifdef HAVE_USB_CHARGING_ENABLE #ifdef HAVE_USB_CHARGING_ENABLE
usb_charging_enable(global_settings.usb_charging); usb_charging_enable(global_settings.usb_charging);
#endif #endif

View file

@ -460,6 +460,10 @@ struct user_settings
int touchpad_sensitivity; int touchpad_sensitivity;
#endif #endif
#ifdef HAVE_TOUCHPAD_DEADZONE
int touchpad_deadzone;
#endif
int pause_rewind; /* time in s to rewind when pausing */ int pause_rewind; /* time in s to rewind when pausing */
#ifdef HAVE_HEADPHONE_DETECTION #ifdef HAVE_HEADPHONE_DETECTION
int unplug_mode; /* pause on headphone unplug */ int unplug_mode; /* pause on headphone unplug */

View file

@ -2024,6 +2024,14 @@ const struct settings_list settings[] = {
ID2P(LANG_NORMAL), ID2P(LANG_HIGH)), ID2P(LANG_NORMAL), ID2P(LANG_HIGH)),
#endif /* boolean or analogig values */ #endif /* boolean or analogig values */
#endif /* HAVE_TOUCHPAD_SENSITIVITY_SETTING */ #endif /* HAVE_TOUCHPAD_SENSITIVITY_SETTING */
#ifdef HAVE_TOUCHPAD_DEADZONE
INT_SETTING(F_NO_WRAP, touchpad_deadzone, LANG_DEADZONE,
DEFAULT_TOUCHPAD_DEADZONE_SETTING, "touchpad deadzone", UNIT_INT,
MIN_TOUCHPAD_DEADSPACE_SETTING, MAX_TOUCHPAD_DEADSPACE_SETTING, 1,
NULL, NULL, touchpad_set_deadzone),
#endif
#ifdef HAVE_QUICKSCREEN #ifdef HAVE_QUICKSCREEN
CUSTOM_SETTING(0, qs_items[QUICKSCREEN_TOP], LANG_TOP_QS_ITEM, CUSTOM_SETTING(0, qs_items[QUICKSCREEN_TOP], LANG_TOP_QS_ITEM,
NULL, "qs top", NULL, "qs top",

View file

@ -80,6 +80,14 @@
#define MAX_TOUCHPAD_SENSITIVITY_SETTING 25 #define MAX_TOUCHPAD_SENSITIVITY_SETTING 25
#define DEFAULT_TOUCHPAD_SENSITIVITY_SETTING 13 #define DEFAULT_TOUCHPAD_SENSITIVITY_SETTING 13
/* Define this to enable dead zone on touchpad */
#ifndef SIMULATOR
#define HAVE_TOUCHPAD_DEADZONE
#define DEFAULT_TOUCHPAD_DEADZONE_SETTING 30
#define MIN_TOUCHPAD_DEADSPACE_SETTING 0
#define MAX_TOUCHPAD_DEADSPACE_SETTING 100
#endif
/* Define this to enable morse code input */ /* Define this to enable morse code input */
#define HAVE_MORSE_INPUT #define HAVE_MORSE_INPUT

View file

@ -192,26 +192,12 @@ bool button_debug_screen(void)
return true; return true;
} }
struct button_area_t /* we emulate a 3x3 grid, this gives the button mapping */
int button_mapping[3][3] =
{ {
/* define a rectangle region */ {BUTTON_BOTTOMLEFT, BUTTON_LEFT, BUTTON_BACK},
int lx, ly; {BUTTON_DOWN, BUTTON_SELECT, BUTTON_UP},
int rx, ry; {BUTTON_BOTTOMRIGHT, BUTTON_RIGHT, BUTTON_PLAYPAUSE},
int button;
};
static struct button_area_t button_areas[] =
{
{1003, 658, 2006, 1316, BUTTON_SELECT},
{0, 658, 1003, 1316, BUTTON_LEFT},
{2006, 658, 3009, 1316, BUTTON_RIGHT},
{1003, 0 , 2006, 658, BUTTON_DOWN},
{1003, 1316, 2006, 1974, BUTTON_UP},
{2006, 1316, 3009, 1974, BUTTON_PLAYPAUSE},
{0, 1316, 1003, 1974, BUTTON_BACK},
{0, 0 , 1003, 658, BUTTON_BOTTOMLEFT},
{2006, 0 , 3009, 658, BUTTON_BOTTOMRIGHT},
{0, 0, 0, 0, 0},
}; };
#define RMI_INTERRUPT 1 #define RMI_INTERRUPT 1
@ -219,6 +205,9 @@ static struct button_area_t button_areas[] =
#define RMI_SET_SLEEP_MODE 3 #define RMI_SET_SLEEP_MODE 3
/* timeout before lowering touchpad power from lack of activity */ /* timeout before lowering touchpad power from lack of activity */
#define ACTIVITY_TMO (5 * HZ) #define ACTIVITY_TMO (5 * HZ)
#define TOUCHPAD_WIDTH 3010
#define TOUCHPAD_HEIGHT 1975
#define DEADZONE_MULTIPLIER 2 /* deadzone multiplier */
static int touchpad_btns = 0; static int touchpad_btns = 0;
static long rmi_stack [DEFAULT_STACK_SIZE/sizeof(long)]; static long rmi_stack [DEFAULT_STACK_SIZE/sizeof(long)];
@ -226,17 +215,38 @@ static const char rmi_thread_name[] = "rmi";
static struct event_queue rmi_queue; static struct event_queue rmi_queue;
static unsigned last_activity = 0; static unsigned last_activity = 0;
static bool t_enable = true; static bool t_enable = true;
static int deadzone;
/* Ignore deadzone function. If outside of the pad, project to border. */
static int find_button_no_deadzone(int x, int y)
{
/* compute grid coordinate */
int gx = MAX(MIN(x * 3 / TOUCHPAD_WIDTH, 2), 0);
int gy = MAX(MIN(y * 3 / TOUCHPAD_HEIGHT, 2), 0);
return button_mapping[gx][gy];
}
static int find_button(int x, int y) static int find_button(int x, int y)
{ {
struct button_area_t *area = button_areas; /* find button ignoring deadzones */
for(; area->button != 0; area++) int btn = find_button_no_deadzone(x, y);
{ /* To check if we are in a deadzone, we try to shift the coordinates
if(area->lx <= x && x <= area->rx && * and see if we get the same button. Not that we do not want to apply
area->ly <= y && y <= area->ry) * the deadzone in the borders ! The code works even in the borders because
return area->button; * the find_button_no_deadzone() project out-of-bound coordinates to the
} * borders */
if(find_button_no_deadzone(x + deadzone, y) != btn ||
find_button_no_deadzone(x - deadzone, y) != btn ||
find_button_no_deadzone(x, y + deadzone) != btn ||
find_button_no_deadzone(x, y - deadzone) != btn)
return 0; return 0;
return btn;
}
void touchpad_set_deadzone(int touchpad_deadzone)
{
deadzone = touchpad_deadzone * DEADZONE_MULTIPLIER;
} }
static int touchpad_read_device(void) static int touchpad_read_device(void)

View file

@ -24,6 +24,7 @@
#include <stdbool.h> #include <stdbool.h>
bool button_debug_screen(void); bool button_debug_screen(void);
void touchpad_set_sensitivity(int level); void touchpad_set_sensitivity(int level);
void touchpad_set_deadzone(int touchpad_deadzone);
void touchpad_enable_device(bool en); void touchpad_enable_device(bool en);
/* Main unit's buttons */ /* Main unit's buttons */