Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for pressure based touchpads. #99

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/hwstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion include/mconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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.

Expand Down
22 changes: 18 additions & 4 deletions src/mconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,28 @@ 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;
cfg->touch_max = caps->abs[MTDEV_TOUCH_MAJOR].maximum;
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;
Expand All @@ -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;
Expand Down
66 changes: 39 additions & 27 deletions src/mtstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,34 +33,40 @@ 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.
*/
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,
Expand Down Expand Up @@ -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;
}
Expand Down