diff --git a/include/hwstate.h b/include/hwstate.h index ac4fd17..2268c69 100644 --- a/include/hwstate.h +++ b/include/hwstate.h @@ -26,7 +26,9 @@ #include "capabilities.h" struct FingerState { + /* The size of the contact area */ int touch_major, touch_minor; + /* The size of the approaching tool */ int width_major, width_minor; int orientation, pressure; int position_x, position_y; diff --git a/include/mconfig.h b/include/mconfig.h index a760464..75133f9 100644 --- a/include/mconfig.h +++ b/include/mconfig.h @@ -84,7 +84,9 @@ #define MCFG_NONE 0 #define MCFG_SCALE 1 #define MCFG_SIZE 2 -#define MCFG_PRESSURE 3 +#define MCFG_MAJOR_PRESSURE_AND_MINOR_SIZE 3 +#define MCFG_MAJOR_SIZE_AND_MINOR_PRESSURE 4 /* same capabilities as above, but with higher resolution of touches*/ +#define MCFG_PRESSURE 5 struct MConfig { /* Used by MTState */ @@ -94,6 +96,8 @@ struct MConfig { int touch_minor; // Does the touchpad report touches as ellipses? 0 or 1 int touch_min; // Minimum touch value. int touch_max; // Maximum touch value. + int pressure_min; // Minimum pressure value. + int pressure_max; // Maximum pressure value. int pad_width; // Width of the touchpad. int pad_height; // Height of the touchpad. diff --git a/src/mconfig.c b/src/mconfig.c index 5ebf357..ebf3554 100644 --- a/src/mconfig.c +++ b/src/mconfig.c @@ -85,7 +85,7 @@ void mconfig_init(struct MConfig* cfg, cfg->touch_minor = caps->has_abs[MTDEV_TOUCH_MINOR]; cfg->pad_width = get_cap_xsize(caps); cfg->pad_height = get_cap_ysize(caps); - + if (caps->has_abs[MTDEV_TOUCH_MAJOR] && caps->has_abs[MTDEV_WIDTH_MAJOR]) { cfg->touch_type = MCFG_SCALE; cfg->touch_min = caps->abs[MTDEV_TOUCH_MAJOR].minimum; @@ -93,6 +93,20 @@ void mconfig_init(struct MConfig* cfg, xf86Msg(X_INFO, "Touchpad supports regular and approaching touches.\n"); xf86Msg(X_INFO, " touch_min = %d, touch_max = %d\n", cfg->touch_min, cfg->touch_max); } + else if (caps->has_abs[MTDEV_TOUCH_MAJOR] && caps->has_abs[MTDEV_PRESSURE]) { + cfg->touch_min = caps->abs[MTDEV_TOUCH_MAJOR].minimum; + cfg->touch_max = caps->abs[MTDEV_TOUCH_MAJOR].maximum; + cfg->pressure_min = caps->abs[MTDEV_PRESSURE].minimum; + cfg->pressure_max = caps->abs[MTDEV_PRESSURE].maximum; + /* select source of the events basing on its resolution */ + if(cfg->pressure_max - cfg->pressure_min >= cfg->touch_max - cfg->touch_min) + cfg->touch_type = MCFG_MAJOR_PRESSURE_AND_MINOR_SIZE; + else + cfg->touch_type = MCFG_MAJOR_SIZE_AND_MINOR_PRESSURE; + xf86Msg(X_INFO, "Touchpad is pressure based, but supports regular touches also.\n"); + xf86Msg(X_INFO, " touch_min = %d, touch_max = %d\n", cfg->touch_min, cfg->touch_max); + xf86Msg(X_INFO, " pressure_min = %d, pressure_max = %d\n", cfg->pressure_min, cfg->pressure_max); + } else if (caps->has_abs[MTDEV_TOUCH_MAJOR]) { cfg->touch_type = MCFG_SIZE; cfg->touch_min = caps->abs[MTDEV_TOUCH_MAJOR].minimum; @@ -102,10 +116,10 @@ void mconfig_init(struct MConfig* cfg, } else if (caps->has_abs[MTDEV_PRESSURE]) { cfg->touch_type = MCFG_PRESSURE; - cfg->touch_min = caps->abs[MTDEV_PRESSURE].minimum; - cfg->touch_max = caps->abs[MTDEV_PRESSURE].maximum; + cfg->pressure_min = caps->abs[MTDEV_PRESSURE].minimum; + cfg->pressure_max = caps->abs[MTDEV_PRESSURE].maximum; xf86Msg(X_INFO, "Touchpad is pressure based.\n"); - xf86Msg(X_INFO, " touch_min = %d, touch_max = %d\n", cfg->touch_min, cfg->touch_max); + xf86Msg(X_INFO, " pressure_min = %d, pressure_max = %d\n", cfg->pressure_min, cfg->pressure_max); } else { cfg->touch_type = MCFG_NONE; diff --git a/src/mtstate.c b/src/mtstate.c index abe5096..0904304 100644 --- a/src/mtstate.c +++ b/src/mtstate.c @@ -33,19 +33,32 @@ static int inline touch_range_ratio(const struct MConfig* cfg, int value) return (double)(value - cfg->touch_min) / (double)(cfg->touch_max - cfg->touch_min) * 100; } +static int inline pressure_range_ratio(const struct MConfig* cfg, int value) +{ + return percentage(value - cfg->pressure_min, cfg->pressure_max - cfg->pressure_min); +} + +static int finger_touch_ratio(const struct MConfig* cfg, const struct FingerState* hw) +{ + switch(cfg->touch_type){ + case MCFG_SCALE: + return percentage(hw->touch_major, hw->width_major); /* = estimated pressure */ + case MCFG_SIZE: + case MCFG_MAJOR_SIZE_AND_MINOR_PRESSURE: + return touch_range_ratio(cfg, hw->touch_major); + case MCFG_MAJOR_PRESSURE_AND_MINOR_SIZE: + case MCFG_PRESSURE: + return pressure_range_ratio(cfg, hw->pressure); + default: return 101; /* sholuld it be additional argument? or maybe it should return -1? */ + } +} + /* Check if a finger is touching the trackpad. */ static int is_touch(const struct MConfig* cfg, const struct FingerState* hw) { - if (cfg->touch_type == MCFG_SCALE) - return percentage(hw->touch_major, hw->width_major) > cfg->touch_down; - else if (cfg->touch_type == MCFG_SIZE) - return touch_range_ratio(cfg, hw->touch_major) > cfg->touch_down; - else if (cfg->touch_type == MCFG_PRESSURE) - return touch_range_ratio(cfg, hw->pressure) > cfg->touch_down; - else - return 1; + return finger_touch_ratio(cfg, hw) > cfg->touch_down; } /* Check if a finger is released from the touchpad. @@ -53,14 +66,7 @@ static int is_touch(const struct MConfig* cfg, static int is_release(const struct MConfig* cfg, const struct FingerState* hw) { - if (cfg->touch_type == MCFG_SCALE) - return percentage(hw->touch_major, hw->width_major) < cfg->touch_up; - else if (cfg->touch_type == MCFG_SIZE) - return touch_range_ratio(cfg, hw->touch_major) < cfg->touch_up; - else if (cfg->touch_type == MCFG_PRESSURE) - return touch_range_ratio(cfg, hw->pressure) < cfg->touch_up; - else - return 0; + return finger_touch_ratio(cfg, hw) < cfg->touch_up; } static int is_thumb(const struct MConfig* cfg, @@ -93,25 +99,31 @@ static int is_thumb(const struct MConfig* cfg, static int is_palm(const struct MConfig* cfg, const struct FingerState* hw) { - int size; - if ((cfg->touch_type == MCFG_SCALE) || (cfg->touch_type == MCFG_SIZE)) { - size = hw->touch_major; - } else if (cfg->touch_type == MCFG_PRESSURE) { - size = hw->pressure; - } else { - return 0; + int ratio; + switch(cfg->touch_type){ + case MCFG_SCALE: + ratio = percentage(hw->touch_major, hw->width_major); + break; + case MCFG_SIZE: + case MCFG_MAJOR_SIZE_AND_MINOR_PRESSURE: + case MCFG_MAJOR_PRESSURE_AND_MINOR_SIZE: + ratio = touch_range_ratio(cfg, hw->touch_major); + break; + case MCFG_PRESSURE: + ratio = pressure_range_ratio(cfg, hw->pressure); + break; + default: return 0; } - size = touch_range_ratio(cfg, size); - if (size > cfg->palm_size) { + if (ratio > cfg->palm_size) { #if DEBUG_MTSTATE - xf86Msg(X_INFO, "is_palm: yes %d > %d\n", size, cfg->palm_size); + xf86Msg(X_INFO, "is_palm: yes %d > %d\n", ratio, cfg->palm_size); #endif return 1; } else { #if DEBUG_MTSTATE - xf86Msg(X_INFO, "is_palm: no %d > %d\n", size, cfg->palm_size); + xf86Msg(X_INFO, "is_palm: no %d > %d\n", ratio, cfg->palm_size); #endif return 0; }