From 5a61c098e1d0c9ef354d70cd25b93db3a6bf43df Mon Sep 17 00:00:00 2001 From: pawelT <1pawel123@gmail.com> Date: Fri, 10 Jul 2015 21:25:13 +0200 Subject: [PATCH 1/6] Added support for touchpads that report incorrect ( = 0) touch_major variable value. This corner case forces me to push my DLL060A:00 06CB:2734 trackpad really hard. --- src/mtstate.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mtstate.c b/src/mtstate.c index 2cc0c32..6b30c0f 100644 --- a/src/mtstate.c +++ b/src/mtstate.c @@ -41,7 +41,7 @@ static int is_touch(const struct MConfig* cfg, 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; + 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 @@ -231,24 +231,24 @@ static void touches_update(struct MTState* ms, SETBIT(ms->touch[n].state, MT_THUMB); else CLEARBIT(ms->touch[n].state, MT_THUMB); - + if (is_palm(cfg, &hs->data[i])) SETBIT(ms->touch[n].state, MT_PALM); else CLEARBIT(ms->touch[n].state, MT_PALM); - + if (ms->touch[n].y > (100 - cfg->bottom_edge)*cfg->pad_height/100) { if (GETBIT(ms->touch[n].state, MT_NEW)) SETBIT(ms->touch[n].state, MT_BOTTOM_EDGE); } else CLEARBIT(ms->touch[n].state, MT_BOTTOM_EDGE); - + MODBIT(ms->touch[n].state, MT_INVALID, GETBIT(ms->touch[n].state, MT_THUMB) && cfg->ignore_thumb || GETBIT(ms->touch[n].state, MT_PALM) && cfg->ignore_palm || GETBIT(ms->touch[n].state, MT_BOTTOM_EDGE)); - + disable |= cfg->disable_on_thumb && GETBIT(ms->touch[n].state, MT_THUMB); disable |= cfg->disable_on_palm && GETBIT(ms->touch[n].state, MT_PALM); } From 232a2abe1966310c7f2b0c7081674061876b25d2 Mon Sep 17 00:00:00 2001 From: p2rkw Date: Wed, 15 Jul 2015 13:19:47 +0200 Subject: [PATCH 2/6] Added configurable delays to button events generated by scroll, swipe and swipe4 gestures. Till now gestures were delayed, but delay was before any button down event, so after first gesture you had to "wait" for button down event, and button up was fired immediately after button down. It was like: 0 ms: gesture was made ... : delay for configured number of miliseconds x ms: send button down and button up events (othen multiple times). As a result actions bound to gestures via tools like xbindkeys were executed too late and othen more than once. This comes from fact that xserver can "see" generated events only when 'read_input' callback returns. To fix that I had to modify code to generate and "commit" buttown down events as fast as possible, and use timer to be able to fire delayed button up events. Actual flow looks like: 0 ms: gesture was made, button down ...: delay x ms: one button up event and so on. During development I merged code and data structures responsible for gestures configuration and execution. Two finger scroll, swipes and four finger swipes are now executed by same function. There are still some areas to merge, mostly in 'moving_update' and configuration code, but I didn't pushed it further right now. I also find and fixed bug with "ClickTime" property: it was set, but it wasn't used. Now taps will delay button up for configured amount of time. Be aware to not set it to higher value than tap to drag wait time. Otherwise delayed button up event may interrupt dragging. --- README.md | 64 +++++++++++- driver/mprops.c | 226 ++++++++++++++++++------------------------ driver/mtrack.c | 59 +++++++++-- include/common.h | 12 ++- include/gestures.h | 14 +-- include/mconfig.h | 31 +++--- include/mprops.h | 17 ++-- include/mtouch.h | 2 + required_packages.txt | 1 + src/gestures.c | 219 ++++++++++++++++++++-------------------- src/mconfig.c | 86 ++++++++++------ 11 files changed, 418 insertions(+), 313 deletions(-) create mode 100644 required_packages.txt diff --git a/README.md b/README.md index b218f3e..3a31ade 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,14 @@ This is a standard autoconf package. So: make && make install It is likely that you will need to change system-dependent paths such as the -xorg module directory. See `configure --help` for options. +xorg module directory. Otherwise mtrack may be not installed in xserver search +path. +See `configure --help` for options. + +To build deb package and install in system wide you will usually have to change +installation prefix to /usr like so: + ./configure --prefix=/usr + dpkg-buildpackage Configuration ------------- @@ -153,10 +160,13 @@ disables three-finger tapping. Defaults to 0. **ClickTime** - When tapping, how much time to hold down the emulated button. Integer value -representing milliseconds. Defaults to 50. +representing milliseconds. Too high value (greater than tap to drag wait time) +may interrupt dragging when tap to drag is enabled. +Integer value representing miliseconds. Defaults to 50. **MaxTapTime** - -The amount of time to wait for a tap to release before counting it as a move. +The amount of time to wait for incoming touches after first one before counting +it as emulated button click. Integer value representing milliseconds. Defaults to 120. **MaxTapMove** - @@ -194,6 +204,22 @@ Integer value. A value of 0 disables scrolling left. Defaults to 6. For two finger scrolling. The button that is triggered by scrolling right. Integer value. A value of 0 disables scrolling right. Defaults to 7. +**ScrollUpClickTime** - +For two finger scrolling. How long button triggered by scrolling right +will be hold down. Integer value representing milliseconds. Defaults to 20. + +**ScrollDownClickTime** - +For two finger scrolling. How long button triggered by scrolling down +will be hold down. Integer value representing milliseconds. Defaults to 20. + +**ScrollLeftClickTime** - +For two finger scrolling. How long button triggered by scrolling left +will be hold down. Integer value representing milliseconds. Defaults to 20. + +**ScrollRightClickTime** - +For two finger scrolling. How long button triggered by scrolling right +will be hold down. Integer value representing milliseconds. Defaults to 20. + **SwipeDistance** - For three finger swiping. How far you must move your fingers before a button click is triggered. Integer value. Defaults to 700. @@ -214,6 +240,22 @@ value. A value of 0 disables swiping left. Defaults to 10. For three finger swiping. The button that is triggered by swiping right. Integer value. A value of 0 disables swiping right. Defaults to 11. +**SwipeUpClickTime** - +For three finger swiping. How long button triggered by swiping up +will be hold down. Integer value representing milliseconds. Defaults to 300. + +**SwipeDownClickTime** - +For three finger swiping. How long button triggered by swiping down +will be hold down. Integer value representing milliseconds. Defaults to 300. + +**SwipeRightClickTime** - +For three finger swiping. How long button triggered by swiping right +will be hold down. Integer value representing milliseconds. Defaults to 300. + +**SwipeLeftClickTime** - +For three finger swiping. How long button triggered by swiping left +will be hold down. Integer value representing milliseconds. Defaults to 300. + **Swipe4Distance** - For four finger swiping. How far you must move your fingers before a button click is triggered. Integer value. Defaults to 700. @@ -234,6 +276,22 @@ value. A value of 0 disables swiping left. Defaults to 10. For four finger swiping. The button that is triggered by swiping right. Integer value. A value of 0 disables swiping right. Defaults to 11. +**Swipe4UpClickTime** - +For four finger swiping. How long button triggered by swiping up +will be hold down. Integer value representing milliseconds. Defaults to 300. + +**Swipe4DownClickTime** - +For four finger swiping. How long button triggered by swiping down +will be hold down. Integer value representing milliseconds. Defaults to 300. + +**Swipe4RightClickTime** - +For four finger swiping. How long button triggered by swiping right +will be hold down. Integer value representing milliseconds. Defaults to 300. + +**Swipe4LeftClickTime** - +For four finger swiping. How long button triggered by swiping left +will be hold down. Integer value representing milliseconds. Defaults to 300. + **ScaleDistance** - For pinch scaling. How far you must move your fingers before a button click is triggered. Integer value. Defaults to 150. diff --git a/driver/mprops.c b/driver/mprops.c index 3ded861..902eecf 100644 --- a/driver/mprops.c +++ b/driver/mprops.c @@ -75,6 +75,26 @@ Atom atom_init_float(DeviceIntPtr dev, char* name, int nvalues, float* values, A return atom; } +static void init_swipe_props(DeviceIntPtr dev, struct MPropsSwipe* propsSwipe, + struct MConfigSwipe* cfgSwipe, char const* distPropName, + char const* buttonsPropName, char const* holdPropName){ + int ivals[MAX_INT_VALUES]; + ivals[0] = cfgSwipe->dist; + propsSwipe->dist = atom_init_integer(dev, (char*)distPropName, 1, ivals, 32); + + ivals[0] = cfgSwipe->up_btn; + ivals[1] = cfgSwipe->dn_btn; + ivals[2] = cfgSwipe->lt_btn; + ivals[3] = cfgSwipe->rt_btn; + propsSwipe->buttons = atom_init_integer(dev, (char*)buttonsPropName, 4, ivals, 8); + + ivals[0] = cfgSwipe->up_hold; + ivals[1] = cfgSwipe->dn_hold; + ivals[2] = cfgSwipe->lt_hold; + ivals[3] = cfgSwipe->rt_hold; + propsSwipe->hold = atom_init_integer(dev, (char*)holdPropName, 4, ivals, 16); +} + void mprops_init(struct MConfig* cfg, InputInfoPtr local) { int ivals[MAX_INT_VALUES]; float fvals[MAX_FLOAT_VALUES]; @@ -142,32 +162,11 @@ void mprops_init(struct MConfig* cfg, InputInfoPtr local) { ivals[1] = cfg->gesture_wait; mprops.gesture_settings = atom_init_integer(local->dev, MTRACK_PROP_GESTURE_SETTINGS, 2, ivals, 16); - ivals[0] = cfg->scroll_dist; - mprops.scroll_dist = atom_init_integer(local->dev, MTRACK_PROP_SCROLL_DIST, 1, ivals, 32); - - ivals[0] = cfg->scroll_up_btn; - ivals[1] = cfg->scroll_dn_btn; - ivals[2] = cfg->scroll_lt_btn; - ivals[3] = cfg->scroll_rt_btn; - mprops.scroll_buttons = atom_init_integer(local->dev, MTRACK_PROP_SCROLL_BUTTONS, 4, ivals, 8); + init_swipe_props(local->dev, &mprops.scroll, &cfg->scroll, MTRACK_PROP_SCROLL_DIST, MTRACK_PROP_SCROLL_BUTTONS, MTRACK_PROP_SCROLL_CLICK_TIME); - ivals[0] = cfg->swipe_dist; - mprops.swipe_dist = atom_init_integer(local->dev, MTRACK_PROP_SWIPE_DIST, 1, ivals, 32); + init_swipe_props(local->dev, &mprops.swipe3, &cfg->swipe3, MTRACK_PROP_SWIPE_DIST, MTRACK_PROP_SWIPE_BUTTONS, MTRACK_PROP_SWIPE_CLICK_TIME); - ivals[0] = cfg->swipe_up_btn; - ivals[1] = cfg->swipe_dn_btn; - ivals[2] = cfg->swipe_lt_btn; - ivals[3] = cfg->swipe_rt_btn; - mprops.swipe_buttons = atom_init_integer(local->dev, MTRACK_PROP_SWIPE_BUTTONS, 4, ivals, 8); - - ivals[0] = cfg->swipe4_dist; - mprops.swipe4_dist = atom_init_integer(local->dev, MTRACK_PROP_SWIPE4_DIST, 1, ivals, 32); - - ivals[0] = cfg->swipe4_up_btn; - ivals[1] = cfg->swipe4_dn_btn; - ivals[2] = cfg->swipe4_lt_btn; - ivals[3] = cfg->swipe4_rt_btn; - mprops.swipe4_buttons = atom_init_integer(local->dev, MTRACK_PROP_SWIPE4_BUTTONS, 4, ivals, 8); + init_swipe_props(local->dev, &mprops.swipe4, &cfg->swipe4, MTRACK_PROP_SWIPE4_DIST, MTRACK_PROP_SWIPE4_BUTTONS, MTRACK_PROP_SWIPE4_CLICK_TIME); ivals[0] = cfg->scale_dist; mprops.scale_dist = atom_init_integer(local->dev, MTRACK_PROP_SCALE_DIST, 1, ivals, 32); @@ -194,6 +193,71 @@ void mprops_init(struct MConfig* cfg, InputInfoPtr local) { mprops.axis_invert = atom_init_integer(local->dev, MTRACK_PROP_AXIS_INVERT, 2, ivals, 8); } +static int set_swipe_properties(Atom property, BOOL checkonly, XIPropertyValuePtr prop, + struct MPropsSwipe* propsSwipe, struct MConfigSwipe* cfgSwipe){ + + uint8_t* ivals8; + uint16_t* ivals16; + uint32_t* ivals32; + + if (property == propsSwipe->dist) { + if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) + return BadMatch; + + ivals32 = (uint32_t*)prop->data; + if (ivals32[0] < 1) + return BadMatch; + + if (!checkonly) { + cfgSwipe->dist = ivals32[0]; +#ifdef DEBUG_PROPS + xf86Msg(X_INFO, "mtrack: set swipe distance to %d\n", + cfgSwipe->dist); +#endif + } + } + else if (property == propsSwipe->buttons) { + if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) + return BadMatch; + + ivals8 = (uint8_t*)prop->data; + if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) + return BadMatch; + + if (!checkonly) { + cfgSwipe->up_btn = ivals8[0]; + cfgSwipe->dn_btn = ivals8[1]; + cfgSwipe->lt_btn = ivals8[2]; + cfgSwipe->rt_btn = ivals8[3]; +#ifdef DEBUG_PROPS + xf86Msg(X_INFO, "mtrack: set swipe buttons to %d %d %d %d\n", + cfgSwipe->up_btn, cfgSwipe->dn_btn, cfgSwipe->lt_btn, cfgSwipe->rt_btn); +#endif + } + } + else if (property == propsSwipe->hold) { + if (prop->size != 4 || prop->format != 16 || prop->type != XA_INTEGER) + return BadMatch; + + ivals16 = (uint16_t*)prop->data; + + if (!checkonly) { + cfgSwipe->up_hold = ivals16[0]; + cfgSwipe->dn_hold = ivals16[1]; + cfgSwipe->lt_hold = ivals16[2]; + cfgSwipe->rt_hold = ivals16[3]; +#ifdef DEBUG_PROPS + xf86Msg(X_INFO, "mtrack: set swipe hold to %d %d %d %d\n", + cfgSwipe->up_hold, cfgSwipe->dn_hold, cfgSwipe->lt_hold, cfgSwipe->rt_hold); +#endif + } + } + else{ + return 0; + } + return 1; +} + int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, BOOL checkonly) { InputInfoPtr local = dev->public.devicePrivate; struct MConfig* cfg = &((struct MTouch*)local->private)->cfg; @@ -237,7 +301,7 @@ int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop } } else if (property == mprops.pressure) { - if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) + if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; @@ -254,7 +318,7 @@ int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop } } else if (property == mprops.button_settings) { - if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) + if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; ivals8 = (uint8_t*)prop->data; @@ -332,7 +396,7 @@ int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) return BadMatch; - if (!checkonly) { + if (!checkonly) { cfg->tap_1touch = ivals8[0]; cfg->tap_2touch = ivals8[1]; cfg->tap_3touch = ivals8[2]; @@ -427,110 +491,14 @@ int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop #endif } } - else if (property == mprops.scroll_dist) { - if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) - return BadMatch; - - ivals32 = (uint32_t*)prop->data; - if (ivals32[0] < 1) - return BadMatch; - - if (!checkonly) { - cfg->scroll_dist = ivals32[0]; -#ifdef DEBUG_PROPS - xf86Msg(X_INFO, "mtrack: set scroll distance to %d\n", - cfg->scroll_dist); -#endif - } + else if (set_swipe_properties(property, checkonly, prop, &mprops.scroll, &cfg->scroll)) { + /* nothing to do */ } - else if (property == mprops.scroll_buttons) { - if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) - return BadMatch; - - ivals8 = (uint8_t*)prop->data; - if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) - return BadMatch; - - if (!checkonly) { - cfg->scroll_up_btn = ivals8[0]; - cfg->scroll_dn_btn = ivals8[1]; - cfg->scroll_lt_btn = ivals8[2]; - cfg->scroll_rt_btn = ivals8[3]; -#ifdef DEBUG_PROPS - xf86Msg(X_INFO, "mtrack: set scroll buttons to %d %d %d %d\n", - cfg->scroll_up_btn, cfg->scroll_dn_btn, cfg->scroll_lt_btn, cfg->scroll_rt_btn); -#endif - } + else if (set_swipe_properties(property, checkonly, prop, &mprops.swipe3, &cfg->swipe3)) { + /* nothing to do */ } - else if (property == mprops.swipe_dist) { - if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) - return BadMatch; - - ivals32 = (uint32_t*)prop->data; - if (ivals32[0] < 1) - return BadMatch; - - if (!checkonly) { - cfg->swipe_dist = ivals32[0]; -#ifdef DEBUG_PROPS - xf86Msg(X_INFO, "mtrack: set swipe distance to %d\n", - cfg->swipe_dist); -#endif - } - } - else if (property == mprops.swipe_buttons) { - if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) - return BadMatch; - - ivals8 = (uint8_t*)prop->data; - if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) - return BadMatch; - - if (!checkonly) { - cfg->swipe_up_btn = ivals8[0]; - cfg->swipe_dn_btn = ivals8[1]; - cfg->swipe_lt_btn = ivals8[2]; - cfg->swipe_rt_btn = ivals8[3]; -#ifdef DEBUG_PROPS - xf86Msg(X_INFO, "mtrack: set swipe buttons to %d %d %d %d\n", - cfg->swipe_up_btn, cfg->swipe_dn_btn, cfg->swipe_lt_btn, cfg->swipe_rt_btn); -#endif - } - } - else if (property == mprops.swipe4_dist) { - if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) - return BadMatch; - - ivals32 = (uint32_t*)prop->data; - if (ivals32[0] < 1) - return BadMatch; - - if (!checkonly) { - cfg->swipe4_dist = ivals32[0]; -#ifdef DEBUG_PROPS - xf86Msg(X_INFO, "mtrack: set swipe4 distance to %d\n", - cfg->swipe4_dist); -#endif - } - } - else if (property == mprops.swipe4_buttons) { - if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) - return BadMatch; - - ivals8 = (uint8_t*)prop->data; - if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) - return BadMatch; - - if (!checkonly) { - cfg->swipe4_up_btn = ivals8[0]; - cfg->swipe4_dn_btn = ivals8[1]; - cfg->swipe4_lt_btn = ivals8[2]; - cfg->swipe4_rt_btn = ivals8[3]; -#ifdef DEBUG_PROPS - xf86Msg(X_INFO, "mtrack: set swipe4 buttons to %d %d %d %d\n", - cfg->swipe4_up_btn, cfg->swipe4_dn_btn, cfg->swipe4_lt_btn, cfg->swipe4_rt_btn); -#endif - } + else if (set_swipe_properties(property, checkonly, prop, &mprops.swipe4, &cfg->swipe4)) { + /* nothing to do */ } else if (property == mprops.scale_dist) { if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) diff --git a/driver/mtrack.c b/driver/mtrack.c index 6bf1821..ad53428 100644 --- a/driver/mtrack.c +++ b/driver/mtrack.c @@ -22,6 +22,7 @@ #include "mtouch.h" #include "mprops.h" +#include "os.h" /* xorg/os.h for timers */ #include #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 @@ -156,6 +157,8 @@ static int device_init(DeviceIntPtr dev, LocalDevicePtr local) mprops_init(&mt->cfg, local); XIRegisterPropertyHandler(dev, mprops_set_property, NULL, NULL); + TimerInit(); + mt->timer = NULL; /* allocated later in device_on */ return Success; } @@ -218,14 +221,53 @@ static void handle_gestures(LocalDevicePtr local, xf86PostMotionEvent(local->dev, 0, 0, 2, gs->move_dx, gs->move_dy); } -/* called for each full received packet from the touchpad */ +/* + * Timers documentation: + * http://www.x.org/releases/X11R7.7/doc/xorg-server/Xserver-spec.html#id2536042 + * + * This function indirectly may call itself recursively using timer to guarantee correct + * event delivery time. Ususally recursion ends after first recursive call. + */ +static CARD32 check_resolve_delayed(OsTimerPtr timer, CARD32 time, void *arg){ + LocalDevicePtr local = arg; + struct MTouch *mt = local->private; + // If it was to early to trigger delayed button, next timer will be set, + // but when called by timer such situation shouldn't take place. + switch (mtouch_delayed(mt)){ + case 1: + mt->timer = TimerSet(mt->timer, 0, timertoms(&mt->gs.button_delayed_delta), + check_resolve_delayed, local); + break; + case 2: handle_gestures(local, &mt->gs); break; + case 0: + default: break; + } + return 0; +} + +/* + * Called for each full received packet from the touchpad. + * Any xf86 input event generated by int this callback function fill be queued by + * xorg server, and fired when control return from this function. + * So to fire event as early as possible this function should return quickly. + * For delayed events we can't simply wait in this function, because it will delay + * all events generated by 'handle_gestures'. + * Moreover we don't know when next input event will occur, so to guarantee proper + * timing I have to use timer. + * + * If mtouch_delayed() retured 1 this means it was to early to trigger delayed button, + * and new timer have to be installed. Otherwise events generated inside can be handled + * as usual. + * + * More on input event processing: + * http://www.x.org/wiki/Development/Documentation/InputEventProcessing/ + */ static void read_input(LocalDevicePtr local) { struct MTouch *mt = local->private; while (mtouch_read(mt) > 0) handle_gestures(local, &mt->gs); - if (mtouch_delayed(mt)) - handle_gestures(local, &mt->gs); + check_resolve_delayed(mt->timer, 0, local); } static Bool device_control(DeviceIntPtr dev, int mode) @@ -266,10 +308,10 @@ static int preinit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) pInfo->read_input = read_input; pInfo->switch_mode = 0; - xf86CollectInputOptions(pInfo, NULL); - xf86OptionListReport(pInfo->options); - xf86ProcessCommonOptions(pInfo, pInfo->options); - mconfig_configure(&mt->cfg, pInfo->options); + xf86CollectInputOptions(pInfo, NULL); + xf86OptionListReport(pInfo->options); + xf86ProcessCommonOptions(pInfo, pInfo->options); + mconfig_configure(&mt->cfg, pInfo->options); return Success; } @@ -310,6 +352,9 @@ static void uninit(InputDriverPtr drv, InputInfoPtr local, int flags) xf86DeleteInput(local, 0); } +/* About xorg drivers, modules: + * http://www.x.org/wiki/Development/Documentation/XorgInputHOWTO/ + */ static InputDriverRec MTRACK = { 1, "mtrack", diff --git a/include/common.h b/include/common.h index 1021067..d80302a 100644 --- a/include/common.h +++ b/include/common.h @@ -53,7 +53,7 @@ typedef unsigned int bitmask_t; #define MODBIT(m, x, b) ((b) ? SETBIT(m, x) : CLEARBIT(m, x)) #define ABSVAL(x) ((x) < 0 ? -1*(x) : (x)) -#define MINVAL(x, y) ((x) < (y) ? (x) : (y)) +#define MINVAL(x, y) ((x) < (y) ? (x) : (y)) #define MAXVAL(x, y) ((x) > (y) ? (x) : (y)) #define MODVAL(x, y) ((x) - ((int)((x) / (y))) * (y)) #define SQRVAL(x) ((x) * (x)) @@ -105,6 +105,16 @@ static inline void timeraddms(const struct timeval* a, const mstime_t b, struct timeradd(a, &tv, dest); } +/* Check if given timeval a is set to epoch time. + */ +static inline int isepochtime(const struct timeval* a) +{ + struct timeval epoch; + timerclear(&epoch); + + return timercmp(a, &epoch, ==); +} + /* Clamp value to 15 bits. */ static inline int clamp15(int x) diff --git a/include/gestures.h b/include/gestures.h index dc5784b..68893dc 100644 --- a/include/gestures.h +++ b/include/gestures.h @@ -36,12 +36,14 @@ struct MTouch; #define GS_NONE 0 #define GS_MOVE 1 #define GS_SCROLL 2 -#define GS_SWIPE 3 -#define GS_SCALE 4 -#define GS_ROTATE 5 -#define GS_DRAG_READY 6 -#define GS_DRAG_WAIT 7 -#define GS_DRAG_ACTIVE 8 +#define GS_SWIPE2 GS_SCROLL +#define GS_SWIPE3 3 +#define GS_SWIPE4 4 +#define GS_SCALE 5 +#define GS_ROTATE 6 +#define GS_DRAG_READY 7 +#define GS_DRAG_WAIT 8 +#define GS_DRAG_ACTIVE 9 struct Gestures { /* Taps, physical buttons, and gestures will trigger diff --git a/include/mconfig.h b/include/mconfig.h index 6cead2a..3cc4bd1 100644 --- a/include/mconfig.h +++ b/include/mconfig.h @@ -57,11 +57,13 @@ #define DEFAULT_SCROLL_DN_BTN 5 #define DEFAULT_SCROLL_LT_BTN 6 #define DEFAULT_SCROLL_RT_BTN 7 +#define DEFAULT_SCROLL_HOLD 20 #define DEFAULT_SWIPE_DIST 700 #define DEFAULT_SWIPE_UP_BTN 8 #define DEFAULT_SWIPE_DN_BTN 9 #define DEFAULT_SWIPE_LT_BTN 10 #define DEFAULT_SWIPE_RT_BTN 11 +#define DEFAULT_SWIPE_HOLD 300 #define DEFAULT_SWIPE4_DIST 700 #define DEFAULT_SWIPE4_UP_BTN 0 #define DEFAULT_SWIPE4_DN_BTN 0 @@ -131,26 +133,23 @@ struct MConfig { int tap_2touch; // What button to emulate for two touch taps? 0 to 32 int tap_3touch; // What button to emulate for three touch taps? 0 to 32 int tap_4touch; // What button to emulate for four touch taps? 0 to 32 - int tap_timeout; // Window for touches when counting for the button. > 0 + int tap_timeout; // Window for touches when counting for the button. + // How long to wait for incoming touches after first one. > 0 int tap_hold; // How long to "hold down" the emulated button on tap. > 0 int tap_dist; // How far to allow a touch to move before it's a moving touch. > 0 int gesture_hold; // How long to "hold down" the emulated button for gestures. > 0 int gesture_wait; // How long after a gesture to wait before movement is allowed. >= 0 - int scroll_dist; // Distance needed to trigger a button. >= 0, 0 disables - int scroll_up_btn; // Button to use for scroll up. >= 0, 0 is none - int scroll_dn_btn; // Button to use for scroll down. >= 0, 0 is none - int scroll_lt_btn; // Button to use for scroll left. >= 0, 0 is none - int scroll_rt_btn; // Button to use for scroll right. >= 0, 0 is none - int swipe_dist; // Distance needed to trigger a button. >= 0, 0 disables - int swipe_up_btn; // Button to use for swipe up. >= 0, 0 is none - int swipe_dn_btn; // Button to use for swipe down. >= 0, 0 is none - int swipe_lt_btn; // Button to use for swipe left. >= 0, 0 is none - int swipe_rt_btn; // Button to use for swipe right. >= 0, 0 is none - int swipe4_dist; // Distance needed to trigger a button. >= 0, 0 disables - int swipe4_up_btn; // Button to use for four finger swipe up. >= 0, 0 is none - int swipe4_dn_btn; // Button to use for four finger swipe down. >= 0, 0 is none - int swipe4_lt_btn; // Button to use for four finger swipe left. >= 0, 0 is none - int swipe4_rt_btn; // Button to use for four finger swipe right. >= 0, 0 is none + struct MConfigSwipe{ + int dist; // Distance needed to trigger a button. >= 0, 0 disables + int up_btn; // Button to use for swipe up. >= 0, 0 is none + int dn_btn; // Button to use for swipe down. >= 0, 0 is none + int lt_btn; // Button to use for swipe left. >= 0, 0 is none + int rt_btn; // Button to use for swipe right. >= 0, 0 is none + int up_hold; // How long to "hold down" the emulated button for swipe up gesture. > 0 + int dn_hold; // How long to "hold down" the emulated button for swipe down gesture. > 0 + int lt_hold; // How long to "hold down" the emulated button for swipe left gesture. > 0 + int rt_hold; // How long to "hold down" the emulated button for swipe right gesture. > 0 + } scroll, swipe3, swipe4/*, swipe5*/; int scale_dist; // Distance needed to trigger a button. >= 0, 0 disables int scale_up_btn; // Button to use for scale up. >= 0, 0 is none int scale_dn_btn; // Button to use for scale down. >= 0, 0 is none diff --git a/include/mprops.h b/include/mprops.h index 6672741..26a9aa1 100644 --- a/include/mprops.h +++ b/include/mprops.h @@ -66,14 +66,20 @@ #define MTRACK_PROP_SCROLL_DIST "Trackpad Scroll Distance" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SCROLL_BUTTONS "Trackpad Scroll Buttons" +// int, 4 values - how much milliseconds button will be hold after {up,down,left,right} scroll +#define MTRACK_PROP_SCROLL_CLICK_TIME "Trackpad Scroll Click Time" // int, 1 value - distance before a swipe event is triggered #define MTRACK_PROP_SWIPE_DIST "Trackpad Swipe Distance" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SWIPE_BUTTONS "Trackpad Swipe Buttons" +// int, 4 values - how much milliseconds button will be hold after {up,down,left,right} swipe +#define MTRACK_PROP_SWIPE_CLICK_TIME "Trackpad Swipe Click Time" // int, 1 value - distance before a swipe event is triggered #define MTRACK_PROP_SWIPE4_DIST "Trackpad Swipe4 Distance" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SWIPE4_BUTTONS "Trackpad Swipe4 Buttons" +// int, 4 values - how much milliseconds button will be hold after {up,down,left,right} swipe4 +#define MTRACK_PROP_SWIPE4_CLICK_TIME "Trackpad Swipe4 Click Time" // int, 1 value - distance before a scale event is triggered #define MTRACK_PROP_SCALE_DIST "Trackpad Scale Distance" // int, 2 values - up button, down button @@ -106,12 +112,11 @@ struct MProps { Atom palm_detect; Atom palm_size; Atom gesture_settings; - Atom scroll_dist; - Atom scroll_buttons; - Atom swipe_dist; - Atom swipe_buttons; - Atom swipe4_dist; - Atom swipe4_buttons; + struct MPropsSwipe{ + Atom dist; + Atom buttons; + Atom hold; + } scroll, swipe3, swipe4/*, swipe5*/; Atom scale_dist; Atom scale_buttons; Atom rotate_dist; diff --git a/include/mtouch.h b/include/mtouch.h index 91fc41c..b6ad51c 100644 --- a/include/mtouch.h +++ b/include/mtouch.h @@ -29,6 +29,7 @@ #include "mtstate.h" #include "mconfig.h" #include "gestures.h" +#include "os.h" /* xorg/os.h for timers */ struct MTouch { int fd; @@ -38,6 +39,7 @@ struct MTouch { struct MTState state; struct MConfig cfg; struct Gestures gs; + OsTimerPtr timer; }; int mtouch_configure(struct MTouch* mt, int fd); diff --git a/required_packages.txt b/required_packages.txt new file mode 100644 index 0000000..f849d6a --- /dev/null +++ b/required_packages.txt @@ -0,0 +1 @@ +xserver-xorg-dev mtdev-dev xutils-dev diff --git a/src/gestures.c b/src/gestures.c index 5262fbd..9b9c05b 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -77,20 +77,23 @@ static void trigger_button_emulation(struct Gestures* gs, int button) static void trigger_button_click(struct Gestures* gs, int button, struct timeval* trigger_up_time) { - struct timeval epoch; - timerclear(&epoch); - - if (IS_VALID_BUTTON(button) && timercmp(&gs->button_delayed_time, &epoch, ==)) { + if (!IS_VALID_BUTTON(button)) + return; + if (isepochtime(&gs->button_delayed_time)) { trigger_button_down(gs, button); gs->button_delayed = button; - timercp(&gs->button_delayed_time, trigger_up_time); - timerclear(&gs->button_delayed_delta); -#ifdef DEBUG_GESTRUES - xf86Msg(X_INFO, "trigger_button_click: %d placed in delayed mode\n"); + if(trigger_up_time == NULL || isepochtime(trigger_up_time)) + timercp(&gs->button_delayed_time, &gs->time); + else + timercp(&gs->button_delayed_time, trigger_up_time); + + timersub(&gs->button_delayed_time, &gs->time, &gs->button_delayed_delta); +#ifdef DEBUG_GESTURES + xf86Msg(X_INFO, "trigger_button_click: %d placed in delayed mode; delta: %d ms\n", button, timertoms(&gs->button_delayed_delta)); #endif } #ifdef DEBUG_GESTURES - else if (IS_VALID_BUTTON(button)) + else xf86Msg(X_INFO, "trigger_button_click: %d ignored, in delayed mode\n", button); #endif } @@ -164,7 +167,7 @@ static void trigger_drag_stop(struct Gestures* gs, int force) #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_drag_stop: drag stopped\n"); #endif - } + } } static void buttons_update(struct Gestures* gs, @@ -300,6 +303,7 @@ static void tapping_update(struct Gestures* gs, timerclear(&epoch); timeraddms(&gs->tap_time_down, cfg->tap_timeout, &tv_tmp); if (!timercmp(&gs->tap_time_down, &epoch, ==) && !timercmp(&gs->time, &tv_tmp, <)) { + // too much time passed by from first touch, stop waiting for incoming touches gs->tap_touching = 0; gs->tap_released = 0; timerclear(&gs->tap_time_down); @@ -355,11 +359,13 @@ static void tapping_update(struct Gestures* gs, } if ((gs->tap_touching == 0 && gs->tap_released > 0) || gs->tap_released >= released_max) { + // in this branch tap was recognized as button click + // clear tap flags from touches foreach_bit(i, ms->touch_used) { if (GETBIT(ms->touch[i].flags, GS_TAP)) CLEARBIT(ms->touch[i].flags, GS_TAP); } - + // determinate which button was "tapped" by counting touches if (gs->tap_released == 1) n = cfg->tap_1touch - 1; else if (gs->tap_released == 2) @@ -369,6 +375,8 @@ static void tapping_update(struct Gestures* gs, else n = cfg->tap_4touch - 1; + // how long button should be hold down + timeraddms(&gs->time, cfg->tap_hold, &tv_tmp); trigger_button_click(gs, n, &tv_tmp); if (cfg->drag_enable && n == 0) trigger_drag_ready(gs, cfg); @@ -403,92 +411,58 @@ static void trigger_move(struct Gestures* gs, } } -static void trigger_scroll(struct Gestures* gs, - const struct MConfig* cfg, - double dist, int dir) -{ - if (gs->move_type == GS_SCROLL || !timercmp(&gs->time, &gs->move_wait, <)) { - struct timeval tv_tmp; - trigger_drag_stop(gs, 1); - if (gs->move_type != GS_SCROLL || gs->move_dir != dir) - gs->move_dist = 0; - gs->move_dx = 0; - gs->move_dy = 0; - gs->move_type = GS_SCROLL; - gs->move_dist += (int)ABSVAL(dist); - gs->move_dir = dir; - gs->move_speed = dist/timertomicro(&gs->dt); - timeraddms(&gs->time, cfg->gesture_wait, &gs->move_wait); - - if (gs->move_dist >= cfg->scroll_dist) { - gs->move_dist = MODVAL(gs->move_dist, cfg->scroll_dist); - timeraddms(&gs->time, cfg->gesture_hold, &tv_tmp); - if (dir == TR_DIR_UP) - trigger_button_click(gs, cfg->scroll_up_btn - 1, &tv_tmp); - else if (dir == TR_DIR_DN) - trigger_button_click(gs, cfg->scroll_dn_btn - 1, &tv_tmp); - else if (dir == TR_DIR_LT) - trigger_button_click(gs, cfg->scroll_lt_btn - 1, &tv_tmp); - else if (dir == TR_DIR_RT) - trigger_button_click(gs, cfg->scroll_rt_btn - 1, &tv_tmp); +static void trigger_swipe_button(struct Gestures* gs, + const struct MConfig* cfg, + const struct MConfigSwipe* swipeCfg, int dir, double dist){ + struct timeval tv_tmp; + if (swipeCfg->dist > 0 && gs->move_dist >= swipeCfg->dist) { + gs->move_dist = MODVAL(gs->move_dist, swipeCfg->dist); + if (dir == TR_DIR_UP){ + timeraddms(&gs->time, swipeCfg->up_hold, &tv_tmp); + trigger_button_click(gs, swipeCfg->up_btn - 1, &tv_tmp); } + else if (dir == TR_DIR_DN){ + timeraddms(&gs->time, swipeCfg->dn_hold, &tv_tmp); + trigger_button_click(gs, swipeCfg->dn_btn - 1, &tv_tmp); + } + else if (dir == TR_DIR_LT){ + timeraddms(&gs->time, swipeCfg->lt_hold, &tv_tmp); + trigger_button_click(gs, swipeCfg->lt_btn - 1, &tv_tmp); + } + else if (dir == TR_DIR_RT){ + timeraddms(&gs->time, swipeCfg->rt_hold, &tv_tmp); + trigger_button_click(gs, swipeCfg->rt_btn - 1, &tv_tmp); + } + } #ifdef DEBUG_GESTURES - xf86Msg(X_INFO, "trigger_scroll: scrolling %+f in direction %d (at %d of %d) (speed %f)\n", - dist, dir, gs->move_dist, cfg->scroll_dist, gs->move_speed); + xf86Msg(X_INFO, "trigger_swipe_button: swiping %+f in direction %d (at %d of %d) (speed %f)\n", + dist, dir, gs->move_dist, swipeCfg->dist, gs->move_speed); #endif - } } static void trigger_swipe(struct Gestures* gs, const struct MConfig* cfg, - double dist, int dir, int isfour) + double dist, int dir, int move_type_to_trigger) { - if (gs->move_type == GS_SWIPE || !timercmp(&gs->time, &gs->move_wait, <)) { - struct timeval tv_tmp; + if (gs->move_type == move_type_to_trigger || !timercmp(&gs->time, &gs->move_wait, <)) { trigger_drag_stop(gs, 1); - if (gs->move_type != GS_SWIPE || gs->move_dir != dir) + if (gs->move_type != move_type_to_trigger || gs->move_dir != dir) gs->move_dist = 0; gs->move_dx = 0; gs->move_dy = 0; - gs->move_type = GS_SWIPE; + gs->move_type = move_type_to_trigger; gs->move_dist += (int)ABSVAL(dist); gs->move_dir = dir; gs->move_speed = dist/timertomicro(&gs->dt); timeraddms(&gs->time, cfg->gesture_wait, &gs->move_wait); - timeraddms(&gs->time, cfg->gesture_hold, &tv_tmp); - - if (isfour) { - if (cfg->swipe4_dist > 0 && gs->move_dist >= cfg->swipe4_dist) { - gs->move_dist = MODVAL(gs->move_dist, cfg->swipe4_dist); - if (dir == TR_DIR_UP) - trigger_button_click(gs, cfg->swipe4_up_btn - 1, &tv_tmp); - else if (dir == TR_DIR_DN) - trigger_button_click(gs, cfg->swipe4_dn_btn - 1, &tv_tmp); - else if (dir == TR_DIR_LT) - trigger_button_click(gs, cfg->swipe4_lt_btn - 1, &tv_tmp); - else if (dir == TR_DIR_RT) - trigger_button_click(gs, cfg->swipe4_rt_btn - 1, &tv_tmp); - } -#ifdef DEBUG_GESTURES - xf86Msg(X_INFO, "trigger_swipe4: swiping %+f in direction %d (at %d of %d) (speed %f)\n", - dist, dir, gs->move_dist, cfg->swipe_dist, gs->move_speed); -#endif - } - else { - if (cfg->swipe_dist > 0 && gs->move_dist >= cfg->swipe_dist) { - gs->move_dist = MODVAL(gs->move_dist, cfg->swipe_dist); - if (dir == TR_DIR_UP) - trigger_button_click(gs, cfg->swipe_up_btn - 1, &tv_tmp); - else if (dir == TR_DIR_DN) - trigger_button_click(gs, cfg->swipe_dn_btn - 1, &tv_tmp); - else if (dir == TR_DIR_LT) - trigger_button_click(gs, cfg->swipe_lt_btn - 1, &tv_tmp); - else if (dir == TR_DIR_RT) - trigger_button_click(gs, cfg->swipe_rt_btn - 1, &tv_tmp); - } -#ifdef DEBUG_GESTURES - xf86Msg(X_INFO, "trigger_swipe: swiping %+f in direction %d (at %d of %d)\n", dist, dir, gs->move_dist, cfg->swipe_dist); -#endif + + switch(move_type_to_trigger){ + case GS_SWIPE2: + return trigger_swipe_button(gs, cfg, &cfg->scroll, dir, dist); + case GS_SWIPE3: + return trigger_swipe_button(gs, cfg, &cfg->swipe3, dir, dist); + case GS_SWIPE4: + return trigger_swipe_button(gs, cfg, &cfg->swipe4, dir, dist); } } } @@ -678,7 +652,7 @@ static void moving_update(struct Gestures* gs, dist = hypot( touches[0]->dx + touches[1]->dx, touches[0]->dy + touches[1]->dy); - trigger_scroll(gs, cfg, dist/2, dir); + trigger_swipe(gs, cfg, dist/2.0, dir, GS_SCROLL); } else if ((dir = get_rotate_dir(touches[0], touches[1])) != TR_NONE) { dist = ABSVAL(hypot(touches[0]->dx, touches[0]->dy)) + @@ -696,7 +670,7 @@ static void moving_update(struct Gestures* gs, dist = hypot( touches[0]->dx + touches[1]->dx + touches[2]->dx, touches[0]->dy + touches[1]->dy + touches[2]->dy); - trigger_swipe(gs, cfg, dist/3, dir, 0); + trigger_swipe(gs, cfg, dist/3.0, dir, GS_SWIPE3); } } else if (count == 4 && cfg->trackpad_disable < 1) { @@ -704,7 +678,7 @@ static void moving_update(struct Gestures* gs, dist = hypot( touches[0]->dx + touches[1]->dx + touches[2]->dx + touches[3]->dx, touches[0]->dy + touches[1]->dy + touches[2]->dy + touches[3]->dy); - trigger_swipe(gs, cfg, dist/4, dir, 1); + trigger_swipe(gs, cfg, dist/4.0, dir, GS_SWIPE4); } } } @@ -721,13 +695,11 @@ static void dragging_update(struct Gestures* gs) static void delayed_update(struct Gestures* gs) { - struct timeval epoch; - timerclear(&epoch); - - if (timercmp(&gs->button_delayed_time, &epoch, ==)) + // if there's no delayed button - return + if(isepochtime(&gs->button_delayed_time)) return; - if (!timercmp(&gs->time, &gs->button_delayed_time, <)) { + if (timercmp(&gs->time, &gs->button_delayed_time, >=)) { #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "delayed_update: %d delay expired, triggering up\n", gs->button_delayed); #endif @@ -738,6 +710,9 @@ static void delayed_update(struct Gestures* gs) } else { timersub(&gs->button_delayed_time, &gs->time, &gs->button_delayed_delta); +#ifdef DEBUG_GESTURES + xf86Msg(X_INFO, "delayed_update: %d still waiting, new delta %d ms\n", gs->button_delayed, timertoms(&gs->button_delayed_delta)); +#endif } } @@ -758,39 +733,55 @@ void gestures_extract(struct MTouch* mt) delayed_update(&mt->gs); } -static int gestures_sleep(struct MTouch* mt, const struct timeval* sleep) -{ - if (mtdev_empty(&mt->dev)) { - struct timeval now; - mtdev_idle(&mt->dev, mt->fd, timertoms(sleep)); - microtime(&now); - timersub(&now, &mt->gs.time, &mt->gs.dt); - timercp(&mt->gs.time, &now); - return 1; - } - return 0; -} - +/* + * Executed every input time frame, at least once. First time from 'read_input' to check if + * timer is needed. + * Return value 1 means that next timer should be installed with this function as a + * callabck and gs->button_delayed_delta as delay time. + * + * Return vale meaning: + * - 0 - no delay to handle, don't install timer, do nothing + * - 1 - only install timer + * - 2 - state was changed, so handle it + */ int gestures_delayed(struct MTouch* mt) { struct Gestures* gs = &mt->gs; - struct timeval epoch; + struct timeval now, epoch; timerclear(&epoch); - if (timercmp(&gs->button_delayed_time, &epoch, >)) { - if (gestures_sleep(mt, &gs->button_delayed_delta)) { + // if there's no delayed button - return + if(timercmp(&gs->button_delayed_time, &epoch, ==)) + return 0; + + microtime(&now); + timersub(&now, &mt->gs.time, &mt->gs.dt); + timercp(&mt->gs.time, &now); + + if(timercmp(&gs->button_delayed_time, &now, >)){ + // update delta time + timersub(&gs->button_delayed_time, &now, &gs->button_delayed_delta); + // That second check may seem unnecessary, but it is not. + // Even if button delayed time is > than now time, timertoms may still return 0 + // because it truncates time to miliseconds. It's important because truncated time + // is used to setup timer. + if(timertoms(&gs->button_delayed_delta) > 1){ #ifdef DEBUG_GESTURES - xf86Msg(X_INFO, "gestures_delayed: %d up, timer expired\n", gs->button_delayed); + xf86Msg(X_INFO, "gestures_delayed: %d delayed, new delta: %d ms\n", gs->button_delayed, timertoms(&gs->button_delayed_delta)); #endif - trigger_button_up(gs, gs->button_delayed); - gs->move_dx = 0; - gs->move_dy = 0; - gs->button_delayed = 0; - timerclear(&gs->button_delayed_time); - timerclear(&gs->button_delayed_delta); - return 1; + return 1; // install timer } + // else execute now } - return 0; +#ifdef DEBUG_GESTURES + xf86Msg(X_INFO, "gestures_delayed: %d up, timer expired\n", gs->button_delayed); +#endif + trigger_button_up(gs, gs->button_delayed); + gs->move_dx = 0; + gs->move_dy = 0; + gs->button_delayed = 0; + timerclear(&gs->button_delayed_time); + timerclear(&gs->button_delayed_delta); + return 2; // caller scholud call handle_gestures } diff --git a/src/mconfig.c b/src/mconfig.c index 4ecbd87..c4a8c8f 100644 --- a/src/mconfig.c +++ b/src/mconfig.c @@ -53,21 +53,33 @@ void mconfig_defaults(struct MConfig* cfg) cfg->tap_dist = DEFAULT_TAP_DIST; cfg->gesture_hold = DEFAULT_GESTURE_HOLD; cfg->gesture_wait = DEFAULT_GESTURE_WAIT; - cfg->scroll_dist = DEFAULT_SCROLL_DIST; - cfg->scroll_up_btn = DEFAULT_SCROLL_UP_BTN; - cfg->scroll_dn_btn = DEFAULT_SCROLL_DN_BTN; - cfg->scroll_lt_btn = DEFAULT_SCROLL_LT_BTN; - cfg->scroll_rt_btn = DEFAULT_SCROLL_RT_BTN; - cfg->swipe_dist = DEFAULT_SWIPE_DIST; - cfg->swipe_up_btn = DEFAULT_SWIPE_UP_BTN; - cfg->swipe_dn_btn = DEFAULT_SWIPE_DN_BTN; - cfg->swipe_lt_btn = DEFAULT_SWIPE_LT_BTN; - cfg->swipe_rt_btn = DEFAULT_SWIPE_RT_BTN; - cfg->swipe4_dist = DEFAULT_SWIPE4_DIST; - cfg->swipe4_up_btn = DEFAULT_SWIPE4_UP_BTN; - cfg->swipe4_dn_btn = DEFAULT_SWIPE4_DN_BTN; - cfg->swipe4_lt_btn = DEFAULT_SWIPE4_LT_BTN; - cfg->swipe4_rt_btn = DEFAULT_SWIPE4_RT_BTN; + cfg->scroll.dist = DEFAULT_SCROLL_DIST; + cfg->scroll.up_btn = DEFAULT_SCROLL_UP_BTN; + cfg->scroll.dn_btn = DEFAULT_SCROLL_DN_BTN; + cfg->scroll.lt_btn = DEFAULT_SCROLL_LT_BTN; + cfg->scroll.rt_btn = DEFAULT_SCROLL_RT_BTN; + cfg->scroll.up_hold = DEFAULT_SCROLL_HOLD; + cfg->scroll.dn_hold = DEFAULT_SCROLL_HOLD; + cfg->scroll.lt_hold = DEFAULT_SCROLL_HOLD; + cfg->scroll.rt_hold = DEFAULT_SCROLL_HOLD; + cfg->swipe3.dist = DEFAULT_SWIPE_DIST; + cfg->swipe3.up_btn = DEFAULT_SWIPE_UP_BTN; + cfg->swipe3.dn_btn = DEFAULT_SWIPE_DN_BTN; + cfg->swipe3.lt_btn = DEFAULT_SWIPE_LT_BTN; + cfg->swipe3.rt_btn = DEFAULT_SWIPE_RT_BTN; + cfg->swipe3.up_hold = DEFAULT_SWIPE_HOLD; + cfg->swipe3.dn_hold = DEFAULT_SWIPE_HOLD; + cfg->swipe3.lt_hold = DEFAULT_SWIPE_HOLD; + cfg->swipe3.rt_hold = DEFAULT_SWIPE_HOLD; + cfg->swipe4.dist = DEFAULT_SWIPE4_DIST; + cfg->swipe4.up_btn = DEFAULT_SWIPE4_UP_BTN; + cfg->swipe4.dn_btn = DEFAULT_SWIPE4_DN_BTN; + cfg->swipe4.lt_btn = DEFAULT_SWIPE4_LT_BTN; + cfg->swipe4.rt_btn = DEFAULT_SWIPE4_RT_BTN; + cfg->swipe4.up_hold = DEFAULT_SWIPE_HOLD; + cfg->swipe4.dn_hold = DEFAULT_SWIPE_HOLD; + cfg->swipe4.lt_hold = DEFAULT_SWIPE_HOLD; + cfg->swipe4.rt_hold = DEFAULT_SWIPE_HOLD; cfg->scale_dist = DEFAULT_SCALE_DIST; cfg->scale_up_btn = DEFAULT_SCALE_UP_BTN; cfg->scale_dn_btn = DEFAULT_SCALE_DN_BTN; @@ -85,7 +97,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; @@ -150,21 +162,33 @@ void mconfig_configure(struct MConfig* cfg, cfg->tap_dist = MAXVAL(xf86SetIntOption(opts, "MaxTapMove", DEFAULT_TAP_DIST), 1); cfg->gesture_hold = MAXVAL(xf86SetIntOption(opts, "GestureClickTime", DEFAULT_GESTURE_HOLD), 1); cfg->gesture_wait = MAXVAL(xf86SetIntOption(opts, "GestureWaitTime", DEFAULT_GESTURE_WAIT), 0); - cfg->scroll_dist = MAXVAL(xf86SetIntOption(opts, "ScrollDistance", DEFAULT_SCROLL_DIST), 1); - cfg->scroll_up_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollUpButton", DEFAULT_SCROLL_UP_BTN), 0, 32); - cfg->scroll_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollDownButton", DEFAULT_SCROLL_DN_BTN), 0, 32); - cfg->scroll_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollLeftButton", DEFAULT_SCROLL_LT_BTN), 0, 32); - cfg->scroll_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollRightButton", DEFAULT_SCROLL_RT_BTN), 0, 32); - cfg->swipe_dist = MAXVAL(xf86SetIntOption(opts, "SwipeDistance", DEFAULT_SWIPE_DIST), 1); - cfg->swipe_up_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeUpButton", DEFAULT_SWIPE_UP_BTN), 0, 32); - cfg->swipe_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeDownButton", DEFAULT_SWIPE_DN_BTN), 0, 32); - cfg->swipe_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeLeftButton", DEFAULT_SWIPE_LT_BTN), 0, 32); - cfg->swipe_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeRightButton", DEFAULT_SWIPE_RT_BTN), 0, 32); - cfg->swipe4_dist = MAXVAL(xf86SetIntOption(opts, "Swipe4Distance", DEFAULT_SWIPE4_DIST), 1); - cfg->swipe4_up_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4UpButton", DEFAULT_SWIPE4_UP_BTN), 0, 32); - cfg->swipe4_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4DownButton", DEFAULT_SWIPE4_DN_BTN), 0, 32); - cfg->swipe4_lt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4LeftButton", DEFAULT_SWIPE4_LT_BTN), 0, 32); - cfg->swipe4_rt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4RightButton", DEFAULT_SWIPE4_RT_BTN), 0, 32); + cfg->scroll.dist = MAXVAL(xf86SetIntOption(opts, "ScrollDistance", DEFAULT_SCROLL_DIST), 1); + cfg->scroll.up_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollUpButton", DEFAULT_SCROLL_UP_BTN), 0, 32); + cfg->scroll.dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollDownButton", DEFAULT_SCROLL_DN_BTN), 0, 32); + cfg->scroll.lt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollLeftButton", DEFAULT_SCROLL_LT_BTN), 0, 32); + cfg->scroll.rt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollRightButton", DEFAULT_SCROLL_RT_BTN), 0, 32); + cfg->scroll.up_hold = MAXVAL(xf86SetIntOption(opts, "ScrollUpClickTime", DEFAULT_SCROLL_HOLD), 0); + cfg->scroll.dn_hold = MAXVAL(xf86SetIntOption(opts, "ScrollDownClickTime", DEFAULT_SCROLL_HOLD), 0); + cfg->scroll.lt_hold = MAXVAL(xf86SetIntOption(opts, "ScrollLeftClickTime", DEFAULT_SCROLL_HOLD), 0); + cfg->scroll.rt_hold = MAXVAL(xf86SetIntOption(opts, "ScrollRightClickTime", DEFAULT_SCROLL_HOLD), 0); + cfg->swipe3.dist = MAXVAL(xf86SetIntOption(opts, "SwipeDistance", DEFAULT_SWIPE_DIST), 1); + cfg->swipe3.up_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeUpButton", DEFAULT_SWIPE_UP_BTN), 0, 32); + cfg->swipe3.dn_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeDownButton", DEFAULT_SWIPE_DN_BTN), 0, 32); + cfg->swipe3.lt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeLeftButton", DEFAULT_SWIPE_LT_BTN), 0, 32); + cfg->swipe3.rt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeRightButton", DEFAULT_SWIPE_RT_BTN), 0, 32); + cfg->swipe3.up_hold = MAXVAL(xf86SetIntOption(opts, "SwipeUpClickTime", DEFAULT_SWIPE_HOLD), 0); + cfg->swipe3.dn_hold = MAXVAL(xf86SetIntOption(opts, "SwipeDownClickTime", DEFAULT_SWIPE_HOLD), 0); + cfg->swipe3.lt_hold = MAXVAL(xf86SetIntOption(opts, "SwipeLeftClickTime", DEFAULT_SWIPE_HOLD), 0); + cfg->swipe3.rt_hold = MAXVAL(xf86SetIntOption(opts, "SwipeRightClickTime", DEFAULT_SWIPE_HOLD), 0); + cfg->swipe4.dist = MAXVAL(xf86SetIntOption(opts, "Swipe4Distance", DEFAULT_SWIPE4_DIST), 1); + cfg->swipe4.up_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4UpButton", DEFAULT_SWIPE4_UP_BTN), 0, 32); + cfg->swipe4.dn_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4DownButton", DEFAULT_SWIPE4_DN_BTN), 0, 32); + cfg->swipe4.lt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4LeftButton", DEFAULT_SWIPE4_LT_BTN), 0, 32); + cfg->swipe4.rt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4RightButton", DEFAULT_SWIPE4_RT_BTN), 0, 32); + cfg->swipe4.up_hold = MAXVAL(xf86SetIntOption(opts, "Swipe4UpClickTime", DEFAULT_SWIPE_HOLD), 0); + cfg->swipe4.dn_hold = MAXVAL(xf86SetIntOption(opts, "Swipe4DownClickTime", DEFAULT_SWIPE_HOLD), 0); + cfg->swipe4.lt_hold = MAXVAL(xf86SetIntOption(opts, "Swipe4LeftClickTime", DEFAULT_SWIPE_HOLD), 0); + cfg->swipe4.rt_hold = MAXVAL(xf86SetIntOption(opts, "Swipe4RightClickTime", DEFAULT_SWIPE_HOLD), 0); cfg->scale_dist = MAXVAL(xf86SetIntOption(opts, "ScaleDistance", DEFAULT_SCALE_DIST), 1); cfg->scale_up_btn = CLAMPVAL(xf86SetIntOption(opts, "ScaleUpButton", DEFAULT_SCALE_UP_BTN), 0, 32); cfg->scale_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScaleDownButton", DEFAULT_SCALE_DN_BTN), 0, 32); From fe8c82bf5aae2e6ae638afe9a681263f3e6d4aed Mon Sep 17 00:00:00 2001 From: p2rkw Date: Wed, 15 Jul 2015 14:17:44 +0200 Subject: [PATCH 3/6] Fixed markup for github. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3a31ade..829e630 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ See `configure --help` for options. To build deb package and install in system wide you will usually have to change installation prefix to /usr like so: + ./configure --prefix=/usr dpkg-buildpackage From 36eeed8d5ad4a756a311c0b84a2934a2597c8a3b Mon Sep 17 00:00:00 2001 From: p2rkw Date: Wed, 15 Jul 2015 23:05:06 +0200 Subject: [PATCH 4/6] Merged four directional "click time" properties into one, common for all four directions, but separate for gestures. I guess most users would set all four variables to one value. Also from this point delayed events will be fired early when user finish his gesture before even if it was scheduled for later. So my earlier notes about too high tap click time and tap to drag are no longer valid: button up event will be send right after releasing any of touches. --- README.md | 52 +++++------------------------ driver/mprops.c | 19 ++++------- driver/mtrack.c | 5 ++- include/mconfig.h | 7 ++-- src/gestures.c | 85 +++++++++++++++++++++++++---------------------- src/mconfig.c | 30 ++++------------- 6 files changed, 72 insertions(+), 126 deletions(-) diff --git a/README.md b/README.md index 829e630..28644e8 100644 --- a/README.md +++ b/README.md @@ -161,8 +161,8 @@ disables three-finger tapping. Defaults to 0. **ClickTime** - When tapping, how much time to hold down the emulated button. Integer value -representing milliseconds. Too high value (greater than tap to drag wait time) -may interrupt dragging when tap to drag is enabled. +representing milliseconds. Not very usable because button release event will be +sent immediately after releasing any of fingers (touches). Integer value representing miliseconds. Defaults to 50. **MaxTapTime** - @@ -205,20 +205,8 @@ Integer value. A value of 0 disables scrolling left. Defaults to 6. For two finger scrolling. The button that is triggered by scrolling right. Integer value. A value of 0 disables scrolling right. Defaults to 7. -**ScrollUpClickTime** - -For two finger scrolling. How long button triggered by scrolling right -will be hold down. Integer value representing milliseconds. Defaults to 20. - -**ScrollDownClickTime** - -For two finger scrolling. How long button triggered by scrolling down -will be hold down. Integer value representing milliseconds. Defaults to 20. - -**ScrollLeftClickTime** - -For two finger scrolling. How long button triggered by scrolling left -will be hold down. Integer value representing milliseconds. Defaults to 20. - -**ScrollRightClickTime** - -For two finger scrolling. How long button triggered by scrolling right +**ScrollClickTime** - +For two finger scrolling. How long button triggered by scrolling will be hold down. Integer value representing milliseconds. Defaults to 20. **SwipeDistance** - @@ -241,20 +229,8 @@ value. A value of 0 disables swiping left. Defaults to 10. For three finger swiping. The button that is triggered by swiping right. Integer value. A value of 0 disables swiping right. Defaults to 11. -**SwipeUpClickTime** - -For three finger swiping. How long button triggered by swiping up -will be hold down. Integer value representing milliseconds. Defaults to 300. - -**SwipeDownClickTime** - -For three finger swiping. How long button triggered by swiping down -will be hold down. Integer value representing milliseconds. Defaults to 300. - -**SwipeRightClickTime** - -For three finger swiping. How long button triggered by swiping right -will be hold down. Integer value representing milliseconds. Defaults to 300. - -**SwipeLeftClickTime** - -For three finger swiping. How long button triggered by swiping left +**SwipeClickTime** - +For three finger swiping. How long button triggered by swiping will be hold down. Integer value representing milliseconds. Defaults to 300. **Swipe4Distance** - @@ -277,20 +253,8 @@ value. A value of 0 disables swiping left. Defaults to 10. For four finger swiping. The button that is triggered by swiping right. Integer value. A value of 0 disables swiping right. Defaults to 11. -**Swipe4UpClickTime** - -For four finger swiping. How long button triggered by swiping up -will be hold down. Integer value representing milliseconds. Defaults to 300. - -**Swipe4DownClickTime** - -For four finger swiping. How long button triggered by swiping down -will be hold down. Integer value representing milliseconds. Defaults to 300. - -**Swipe4RightClickTime** - -For four finger swiping. How long button triggered by swiping right -will be hold down. Integer value representing milliseconds. Defaults to 300. - -**Swipe4LeftClickTime** - -For four finger swiping. How long button triggered by swiping left +**Swipe4ClickTime** - +For four finger swiping. How long button triggered by swiping will be hold down. Integer value representing milliseconds. Defaults to 300. **ScaleDistance** - diff --git a/driver/mprops.c b/driver/mprops.c index 902eecf..9866e96 100644 --- a/driver/mprops.c +++ b/driver/mprops.c @@ -88,11 +88,8 @@ static void init_swipe_props(DeviceIntPtr dev, struct MPropsSwipe* propsSwipe, ivals[3] = cfgSwipe->rt_btn; propsSwipe->buttons = atom_init_integer(dev, (char*)buttonsPropName, 4, ivals, 8); - ivals[0] = cfgSwipe->up_hold; - ivals[1] = cfgSwipe->dn_hold; - ivals[2] = cfgSwipe->lt_hold; - ivals[3] = cfgSwipe->rt_hold; - propsSwipe->hold = atom_init_integer(dev, (char*)holdPropName, 4, ivals, 16); + ivals[0] = cfgSwipe->hold; + propsSwipe->hold = atom_init_integer(dev, (char*)holdPropName, 1, ivals, 16); } void mprops_init(struct MConfig* cfg, InputInfoPtr local) { @@ -236,19 +233,15 @@ static int set_swipe_properties(Atom property, BOOL checkonly, XIPropertyValuePt } } else if (property == propsSwipe->hold) { - if (prop->size != 4 || prop->format != 16 || prop->type != XA_INTEGER) + if (prop->size != 1 || prop->format != 16 || prop->type != XA_INTEGER) return BadMatch; ivals16 = (uint16_t*)prop->data; if (!checkonly) { - cfgSwipe->up_hold = ivals16[0]; - cfgSwipe->dn_hold = ivals16[1]; - cfgSwipe->lt_hold = ivals16[2]; - cfgSwipe->rt_hold = ivals16[3]; + cfgSwipe->hold = ivals16[0]; #ifdef DEBUG_PROPS - xf86Msg(X_INFO, "mtrack: set swipe hold to %d %d %d %d\n", - cfgSwipe->up_hold, cfgSwipe->dn_hold, cfgSwipe->lt_hold, cfgSwipe->rt_hold); + xf86Msg(X_INFO, "mtrack: set swipe hold to %d\n", cfgSwipe->hold); #endif } } @@ -491,7 +484,7 @@ int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop #endif } } - else if (set_swipe_properties(property, checkonly, prop, &mprops.scroll, &cfg->scroll)) { + else if (set_swipe_properties(property, checkonly, prop, &mprops.scroll, &cfg->scroll)) { /* nothing to do */ } else if (set_swipe_properties(property, checkonly, prop, &mprops.swipe3, &cfg->swipe3)) { diff --git a/driver/mtrack.c b/driver/mtrack.c index ad53428..d13aeba 100644 --- a/driver/mtrack.c +++ b/driver/mtrack.c @@ -238,7 +238,10 @@ static CARD32 check_resolve_delayed(OsTimerPtr timer, CARD32 time, void *arg){ mt->timer = TimerSet(mt->timer, 0, timertoms(&mt->gs.button_delayed_delta), check_resolve_delayed, local); break; - case 2: handle_gestures(local, &mt->gs); break; + case 2: + TimerCancel(mt->timer); + handle_gestures(local, &mt->gs); + break; case 0: default: break; } diff --git a/include/mconfig.h b/include/mconfig.h index 3cc4bd1..2d9061e 100644 --- a/include/mconfig.h +++ b/include/mconfig.h @@ -140,15 +140,12 @@ struct MConfig { int gesture_hold; // How long to "hold down" the emulated button for gestures. > 0 int gesture_wait; // How long after a gesture to wait before movement is allowed. >= 0 struct MConfigSwipe{ - int dist; // Distance needed to trigger a button. >= 0, 0 disables + int dist; // Distance needed to trigger a button. >= 0, 0 disables int up_btn; // Button to use for swipe up. >= 0, 0 is none int dn_btn; // Button to use for swipe down. >= 0, 0 is none int lt_btn; // Button to use for swipe left. >= 0, 0 is none int rt_btn; // Button to use for swipe right. >= 0, 0 is none - int up_hold; // How long to "hold down" the emulated button for swipe up gesture. > 0 - int dn_hold; // How long to "hold down" the emulated button for swipe down gesture. > 0 - int lt_hold; // How long to "hold down" the emulated button for swipe left gesture. > 0 - int rt_hold; // How long to "hold down" the emulated button for swipe right gesture. > 0 + int hold; // How long to "hold down" the emulated button for swipe up gesture. > 0 } scroll, swipe3, swipe4/*, swipe5*/; int scale_dist; // Distance needed to trigger a button. >= 0, 0 disables int scale_up_btn; // Button to use for scale up. >= 0, 0 is none diff --git a/src/gestures.c b/src/gestures.c index 9b9c05b..a1ed9f4 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -411,28 +411,20 @@ static void trigger_move(struct Gestures* gs, } } -static void trigger_swipe_button(struct Gestures* gs, - const struct MConfig* cfg, - const struct MConfigSwipe* swipeCfg, int dir, double dist){ +static void trigger_swipe_button(struct Gestures* gs, const struct MConfigSwipe* swipeCfg, + int dir, double dist){ struct timeval tv_tmp; if (swipeCfg->dist > 0 && gs->move_dist >= swipeCfg->dist) { + timeraddms(&gs->time, swipeCfg->hold, &tv_tmp); gs->move_dist = MODVAL(gs->move_dist, swipeCfg->dist); - if (dir == TR_DIR_UP){ - timeraddms(&gs->time, swipeCfg->up_hold, &tv_tmp); + if (dir == TR_DIR_UP) trigger_button_click(gs, swipeCfg->up_btn - 1, &tv_tmp); - } - else if (dir == TR_DIR_DN){ - timeraddms(&gs->time, swipeCfg->dn_hold, &tv_tmp); + else if (dir == TR_DIR_DN) trigger_button_click(gs, swipeCfg->dn_btn - 1, &tv_tmp); - } - else if (dir == TR_DIR_LT){ - timeraddms(&gs->time, swipeCfg->lt_hold, &tv_tmp); + else if (dir == TR_DIR_LT) trigger_button_click(gs, swipeCfg->lt_btn - 1, &tv_tmp); - } - else if (dir == TR_DIR_RT){ - timeraddms(&gs->time, swipeCfg->rt_hold, &tv_tmp); + else if (dir == TR_DIR_RT) trigger_button_click(gs, swipeCfg->rt_btn - 1, &tv_tmp); - } } #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "trigger_swipe_button: swiping %+f in direction %d (at %d of %d) (speed %f)\n", @@ -458,11 +450,11 @@ static void trigger_swipe(struct Gestures* gs, switch(move_type_to_trigger){ case GS_SWIPE2: - return trigger_swipe_button(gs, cfg, &cfg->scroll, dir, dist); + return trigger_swipe_button(gs, &cfg->scroll, dir, dist); case GS_SWIPE3: - return trigger_swipe_button(gs, cfg, &cfg->swipe3, dir, dist); + return trigger_swipe_button(gs, &cfg->swipe3, dir, dist); case GS_SWIPE4: - return trigger_swipe_button(gs, cfg, &cfg->swipe4, dir, dist); + return trigger_swipe_button(gs, &cfg->swipe4, dir, dist); } } } @@ -742,37 +734,53 @@ void gestures_extract(struct MTouch* mt) * Return vale meaning: * - 0 - no delay to handle, don't install timer, do nothing * - 1 - only install timer - * - 2 - state was changed, so handle it + * - 2 - state was changed, so caller have to cancel timer and handle state change */ int gestures_delayed(struct MTouch* mt) { struct Gestures* gs = &mt->gs; + struct MTState* ms = &mt->state; struct timeval now, epoch; + int i, taps_released; + timerclear(&epoch); + taps_released = 0; // if there's no delayed button - return if(timercmp(&gs->button_delayed_time, &epoch, ==)) return 0; - microtime(&now); - timersub(&now, &mt->gs.time, &mt->gs.dt); - timercp(&mt->gs.time, &now); - - if(timercmp(&gs->button_delayed_time, &now, >)){ - // update delta time - timersub(&gs->button_delayed_time, &now, &gs->button_delayed_delta); - // That second check may seem unnecessary, but it is not. - // Even if button delayed time is > than now time, timertoms may still return 0 - // because it truncates time to miliseconds. It's important because truncated time - // is used to setup timer. - if(timertoms(&gs->button_delayed_delta) > 1){ -#ifdef DEBUG_GESTURES - xf86Msg(X_INFO, "gestures_delayed: %d delayed, new delta: %d ms\n", gs->button_delayed, timertoms(&gs->button_delayed_delta)); -#endif - return 1; // install timer + // count released fingers + foreach_bit(i, ms->touch_used) { + if (GETBIT(ms->touch[i].state, MT_RELEASED)) + ++taps_released; + } + + // if one of fingers were released it means that gesture was ended so + // send "button up" event immediately without checking for delivery time + if(taps_released == 0){ + microtime(&now); + timersub(&now, &mt->gs.time, &mt->gs.dt); + timercp(&mt->gs.time, &now); + + if(timercmp(&gs->button_delayed_time, &now, >)){ + // update delta time + timersub(&gs->button_delayed_time, &now, &gs->button_delayed_delta); + // That second check may seem unnecessary, but it is not. + // Even if button delayed time is > than now time, timertoms may still return 0 + // because it truncates time to miliseconds. It's important because truncated time + // is used to setup timer. + if(timertoms(&gs->button_delayed_delta) > 1){ + #ifdef DEBUG_GESTURES + xf86Msg(X_INFO, "gestures_delayed: %d delayed, new delta: %d ms\n", gs->button_delayed, timertoms(&gs->button_delayed_delta)); + #endif + return 1; // install timer + } + // else execute now } - // else execute now } + timerclear(&gs->button_delayed_time); + timerclear(&gs->button_delayed_delta); #ifdef DEBUG_GESTURES xf86Msg(X_INFO, "gestures_delayed: %d up, timer expired\n", gs->button_delayed); #endif @@ -780,8 +788,7 @@ int gestures_delayed(struct MTouch* mt) gs->move_dx = 0; gs->move_dy = 0; gs->button_delayed = 0; - timerclear(&gs->button_delayed_time); - timerclear(&gs->button_delayed_delta); - return 2; // caller scholud call handle_gestures + + return 2; // caller scholud call TimerCancel() and handle_gestures() } diff --git a/src/mconfig.c b/src/mconfig.c index c4a8c8f..b417f6e 100644 --- a/src/mconfig.c +++ b/src/mconfig.c @@ -58,28 +58,19 @@ void mconfig_defaults(struct MConfig* cfg) cfg->scroll.dn_btn = DEFAULT_SCROLL_DN_BTN; cfg->scroll.lt_btn = DEFAULT_SCROLL_LT_BTN; cfg->scroll.rt_btn = DEFAULT_SCROLL_RT_BTN; - cfg->scroll.up_hold = DEFAULT_SCROLL_HOLD; - cfg->scroll.dn_hold = DEFAULT_SCROLL_HOLD; - cfg->scroll.lt_hold = DEFAULT_SCROLL_HOLD; - cfg->scroll.rt_hold = DEFAULT_SCROLL_HOLD; + cfg->scroll.hold = DEFAULT_SCROLL_HOLD; cfg->swipe3.dist = DEFAULT_SWIPE_DIST; cfg->swipe3.up_btn = DEFAULT_SWIPE_UP_BTN; cfg->swipe3.dn_btn = DEFAULT_SWIPE_DN_BTN; cfg->swipe3.lt_btn = DEFAULT_SWIPE_LT_BTN; cfg->swipe3.rt_btn = DEFAULT_SWIPE_RT_BTN; - cfg->swipe3.up_hold = DEFAULT_SWIPE_HOLD; - cfg->swipe3.dn_hold = DEFAULT_SWIPE_HOLD; - cfg->swipe3.lt_hold = DEFAULT_SWIPE_HOLD; - cfg->swipe3.rt_hold = DEFAULT_SWIPE_HOLD; + cfg->swipe3.hold = DEFAULT_SWIPE_HOLD; cfg->swipe4.dist = DEFAULT_SWIPE4_DIST; cfg->swipe4.up_btn = DEFAULT_SWIPE4_UP_BTN; cfg->swipe4.dn_btn = DEFAULT_SWIPE4_DN_BTN; cfg->swipe4.lt_btn = DEFAULT_SWIPE4_LT_BTN; cfg->swipe4.rt_btn = DEFAULT_SWIPE4_RT_BTN; - cfg->swipe4.up_hold = DEFAULT_SWIPE_HOLD; - cfg->swipe4.dn_hold = DEFAULT_SWIPE_HOLD; - cfg->swipe4.lt_hold = DEFAULT_SWIPE_HOLD; - cfg->swipe4.rt_hold = DEFAULT_SWIPE_HOLD; + cfg->swipe4.hold = DEFAULT_SWIPE_HOLD; cfg->scale_dist = DEFAULT_SCALE_DIST; cfg->scale_up_btn = DEFAULT_SCALE_UP_BTN; cfg->scale_dn_btn = DEFAULT_SCALE_DN_BTN; @@ -167,28 +158,19 @@ void mconfig_configure(struct MConfig* cfg, cfg->scroll.dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollDownButton", DEFAULT_SCROLL_DN_BTN), 0, 32); cfg->scroll.lt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollLeftButton", DEFAULT_SCROLL_LT_BTN), 0, 32); cfg->scroll.rt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollRightButton", DEFAULT_SCROLL_RT_BTN), 0, 32); - cfg->scroll.up_hold = MAXVAL(xf86SetIntOption(opts, "ScrollUpClickTime", DEFAULT_SCROLL_HOLD), 0); - cfg->scroll.dn_hold = MAXVAL(xf86SetIntOption(opts, "ScrollDownClickTime", DEFAULT_SCROLL_HOLD), 0); - cfg->scroll.lt_hold = MAXVAL(xf86SetIntOption(opts, "ScrollLeftClickTime", DEFAULT_SCROLL_HOLD), 0); - cfg->scroll.rt_hold = MAXVAL(xf86SetIntOption(opts, "ScrollRightClickTime", DEFAULT_SCROLL_HOLD), 0); + cfg->scroll.hold = MAXVAL(xf86SetIntOption(opts, "ScrollClickTime", DEFAULT_SCROLL_HOLD), 0); cfg->swipe3.dist = MAXVAL(xf86SetIntOption(opts, "SwipeDistance", DEFAULT_SWIPE_DIST), 1); cfg->swipe3.up_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeUpButton", DEFAULT_SWIPE_UP_BTN), 0, 32); cfg->swipe3.dn_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeDownButton", DEFAULT_SWIPE_DN_BTN), 0, 32); cfg->swipe3.lt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeLeftButton", DEFAULT_SWIPE_LT_BTN), 0, 32); cfg->swipe3.rt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeRightButton", DEFAULT_SWIPE_RT_BTN), 0, 32); - cfg->swipe3.up_hold = MAXVAL(xf86SetIntOption(opts, "SwipeUpClickTime", DEFAULT_SWIPE_HOLD), 0); - cfg->swipe3.dn_hold = MAXVAL(xf86SetIntOption(opts, "SwipeDownClickTime", DEFAULT_SWIPE_HOLD), 0); - cfg->swipe3.lt_hold = MAXVAL(xf86SetIntOption(opts, "SwipeLeftClickTime", DEFAULT_SWIPE_HOLD), 0); - cfg->swipe3.rt_hold = MAXVAL(xf86SetIntOption(opts, "SwipeRightClickTime", DEFAULT_SWIPE_HOLD), 0); + cfg->swipe3.hold = MAXVAL(xf86SetIntOption(opts, "SwipeClickTime", DEFAULT_SWIPE_HOLD), 0); cfg->swipe4.dist = MAXVAL(xf86SetIntOption(opts, "Swipe4Distance", DEFAULT_SWIPE4_DIST), 1); cfg->swipe4.up_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4UpButton", DEFAULT_SWIPE4_UP_BTN), 0, 32); cfg->swipe4.dn_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4DownButton", DEFAULT_SWIPE4_DN_BTN), 0, 32); cfg->swipe4.lt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4LeftButton", DEFAULT_SWIPE4_LT_BTN), 0, 32); cfg->swipe4.rt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4RightButton", DEFAULT_SWIPE4_RT_BTN), 0, 32); - cfg->swipe4.up_hold = MAXVAL(xf86SetIntOption(opts, "Swipe4UpClickTime", DEFAULT_SWIPE_HOLD), 0); - cfg->swipe4.dn_hold = MAXVAL(xf86SetIntOption(opts, "Swipe4DownClickTime", DEFAULT_SWIPE_HOLD), 0); - cfg->swipe4.lt_hold = MAXVAL(xf86SetIntOption(opts, "Swipe4LeftClickTime", DEFAULT_SWIPE_HOLD), 0); - cfg->swipe4.rt_hold = MAXVAL(xf86SetIntOption(opts, "Swipe4RightClickTime", DEFAULT_SWIPE_HOLD), 0); + cfg->swipe4.hold = MAXVAL(xf86SetIntOption(opts, "Swipe4ClickTime", DEFAULT_SWIPE_HOLD), 0); cfg->scale_dist = MAXVAL(xf86SetIntOption(opts, "ScaleDistance", DEFAULT_SCALE_DIST), 1); cfg->scale_up_btn = CLAMPVAL(xf86SetIntOption(opts, "ScaleUpButton", DEFAULT_SCALE_UP_BTN), 0, 32); cfg->scale_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScaleDownButton", DEFAULT_SCALE_DN_BTN), 0, 32); From cb5c503f20f26c4fbb2041f4f4f155943d991f47 Mon Sep 17 00:00:00 2001 From: p2rkw Date: Thu, 16 Jul 2015 00:04:03 +0200 Subject: [PATCH 5/6] Changed property name to end with _SETTINGS. It will ease further development of swipes. --- driver/mprops.c | 6 +++--- include/mprops.h | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/driver/mprops.c b/driver/mprops.c index 9866e96..61541e1 100644 --- a/driver/mprops.c +++ b/driver/mprops.c @@ -159,11 +159,11 @@ void mprops_init(struct MConfig* cfg, InputInfoPtr local) { ivals[1] = cfg->gesture_wait; mprops.gesture_settings = atom_init_integer(local->dev, MTRACK_PROP_GESTURE_SETTINGS, 2, ivals, 16); - init_swipe_props(local->dev, &mprops.scroll, &cfg->scroll, MTRACK_PROP_SCROLL_DIST, MTRACK_PROP_SCROLL_BUTTONS, MTRACK_PROP_SCROLL_CLICK_TIME); + init_swipe_props(local->dev, &mprops.scroll, &cfg->scroll, MTRACK_PROP_SCROLL_DIST, MTRACK_PROP_SCROLL_BUTTONS, MTRACK_PROP_SCROLL_SETTINGS); - init_swipe_props(local->dev, &mprops.swipe3, &cfg->swipe3, MTRACK_PROP_SWIPE_DIST, MTRACK_PROP_SWIPE_BUTTONS, MTRACK_PROP_SWIPE_CLICK_TIME); + init_swipe_props(local->dev, &mprops.swipe3, &cfg->swipe3, MTRACK_PROP_SWIPE_DIST, MTRACK_PROP_SWIPE_BUTTONS, MTRACK_PROP_SWIPE_SETTINGS); - init_swipe_props(local->dev, &mprops.swipe4, &cfg->swipe4, MTRACK_PROP_SWIPE4_DIST, MTRACK_PROP_SWIPE4_BUTTONS, MTRACK_PROP_SWIPE4_CLICK_TIME); + init_swipe_props(local->dev, &mprops.swipe4, &cfg->swipe4, MTRACK_PROP_SWIPE4_DIST, MTRACK_PROP_SWIPE4_BUTTONS, MTRACK_PROP_SWIPE4_SETTINGS); ivals[0] = cfg->scale_dist; mprops.scale_dist = atom_init_integer(local->dev, MTRACK_PROP_SCALE_DIST, 1, ivals, 32); diff --git a/include/mprops.h b/include/mprops.h index 26a9aa1..7bf2791 100644 --- a/include/mprops.h +++ b/include/mprops.h @@ -66,20 +66,20 @@ #define MTRACK_PROP_SCROLL_DIST "Trackpad Scroll Distance" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SCROLL_BUTTONS "Trackpad Scroll Buttons" -// int, 4 values - how much milliseconds button will be hold after {up,down,left,right} scroll -#define MTRACK_PROP_SCROLL_CLICK_TIME "Trackpad Scroll Click Time" +// int, 1 value - how much milliseconds button will be hold after {up,down,left,right} scroll +#define MTRACK_PROP_SCROLL_SETTINGS "Trackpad Scroll Settings" // int, 1 value - distance before a swipe event is triggered #define MTRACK_PROP_SWIPE_DIST "Trackpad Swipe Distance" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SWIPE_BUTTONS "Trackpad Swipe Buttons" -// int, 4 values - how much milliseconds button will be hold after {up,down,left,right} swipe -#define MTRACK_PROP_SWIPE_CLICK_TIME "Trackpad Swipe Click Time" +// int, 1 value - how much milliseconds button will be hold after {up,down,left,right} swipe +#define MTRACK_PROP_SWIPE_SETTINGS "Trackpad Swipe Settings" // int, 1 value - distance before a swipe event is triggered #define MTRACK_PROP_SWIPE4_DIST "Trackpad Swipe4 Distance" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SWIPE4_BUTTONS "Trackpad Swipe4 Buttons" -// int, 4 values - how much milliseconds button will be hold after {up,down,left,right} swipe4 -#define MTRACK_PROP_SWIPE4_CLICK_TIME "Trackpad Swipe4 Click Time" +// int, 1 value - how much milliseconds button will be hold after {up,down,left,right} swipe4 +#define MTRACK_PROP_SWIPE4_SETTINGS "Trackpad Swipe4 Settings" // int, 1 value - distance before a scale event is triggered #define MTRACK_PROP_SCALE_DIST "Trackpad Scale Distance" // int, 2 values - up button, down button From 01a0f078f6f4a4d79682081e8ec3ceb07e064ea2 Mon Sep 17 00:00:00 2001 From: p2rkw Date: Thu, 16 Jul 2015 13:47:40 +0200 Subject: [PATCH 6/6] Merged swipe properties 'hold' and 'dist' into new one 'settings' known for xserver and user as "Trackpad {Scroll,Swipe,Swipe4} Settings". Fixed bug in set_swipe_properties: now error code is handled correctly. Changed few variable names to follow convention. --- driver/mprops.c | 99 +++++++++++++++++++++++------------------------- include/mprops.h | 27 +++++++------ src/mconfig.c | 6 +-- 3 files changed, 63 insertions(+), 69 deletions(-) diff --git a/driver/mprops.c b/driver/mprops.c index 61541e1..6e2b414 100644 --- a/driver/mprops.c +++ b/driver/mprops.c @@ -75,21 +75,19 @@ Atom atom_init_float(DeviceIntPtr dev, char* name, int nvalues, float* values, A return atom; } -static void init_swipe_props(DeviceIntPtr dev, struct MPropsSwipe* propsSwipe, - struct MConfigSwipe* cfgSwipe, char const* distPropName, - char const* buttonsPropName, char const* holdPropName){ +static void init_swipe_props(DeviceIntPtr dev, struct MPropsSwipe* props_swipe, + struct MConfigSwipe* cfg_swipe, char const* settings_prop_name, + char const* buttons_prop_name){ int ivals[MAX_INT_VALUES]; - ivals[0] = cfgSwipe->dist; - propsSwipe->dist = atom_init_integer(dev, (char*)distPropName, 1, ivals, 32); - - ivals[0] = cfgSwipe->up_btn; - ivals[1] = cfgSwipe->dn_btn; - ivals[2] = cfgSwipe->lt_btn; - ivals[3] = cfgSwipe->rt_btn; - propsSwipe->buttons = atom_init_integer(dev, (char*)buttonsPropName, 4, ivals, 8); - - ivals[0] = cfgSwipe->hold; - propsSwipe->hold = atom_init_integer(dev, (char*)holdPropName, 1, ivals, 16); + ivals[0] = cfg_swipe->dist; + ivals[1] = cfg_swipe->hold; + props_swipe->settings = atom_init_integer(dev, (char*)settings_prop_name, 2, ivals, 32); + + ivals[0] = cfg_swipe->up_btn; + ivals[1] = cfg_swipe->dn_btn; + ivals[2] = cfg_swipe->lt_btn; + ivals[3] = cfg_swipe->rt_btn; + props_swipe->buttons = atom_init_integer(dev, (char*)buttons_prop_name, 4, ivals, 8); } void mprops_init(struct MConfig* cfg, InputInfoPtr local) { @@ -159,11 +157,11 @@ void mprops_init(struct MConfig* cfg, InputInfoPtr local) { ivals[1] = cfg->gesture_wait; mprops.gesture_settings = atom_init_integer(local->dev, MTRACK_PROP_GESTURE_SETTINGS, 2, ivals, 16); - init_swipe_props(local->dev, &mprops.scroll, &cfg->scroll, MTRACK_PROP_SCROLL_DIST, MTRACK_PROP_SCROLL_BUTTONS, MTRACK_PROP_SCROLL_SETTINGS); + init_swipe_props(local->dev, &mprops.scroll, &cfg->scroll, MTRACK_PROP_SCROLL_SETTINGS, MTRACK_PROP_SCROLL_BUTTONS); - init_swipe_props(local->dev, &mprops.swipe3, &cfg->swipe3, MTRACK_PROP_SWIPE_DIST, MTRACK_PROP_SWIPE_BUTTONS, MTRACK_PROP_SWIPE_SETTINGS); + init_swipe_props(local->dev, &mprops.swipe3, &cfg->swipe3, MTRACK_PROP_SWIPE_SETTINGS, MTRACK_PROP_SWIPE_BUTTONS); - init_swipe_props(local->dev, &mprops.swipe4, &cfg->swipe4, MTRACK_PROP_SWIPE4_DIST, MTRACK_PROP_SWIPE4_BUTTONS, MTRACK_PROP_SWIPE4_SETTINGS); + init_swipe_props(local->dev, &mprops.swipe4, &cfg->swipe4, MTRACK_PROP_SWIPE4_SETTINGS, MTRACK_PROP_SWIPE4_BUTTONS); ivals[0] = cfg->scale_dist; mprops.scale_dist = atom_init_integer(local->dev, MTRACK_PROP_SCALE_DIST, 1, ivals, 32); @@ -190,58 +188,53 @@ void mprops_init(struct MConfig* cfg, InputInfoPtr local) { mprops.axis_invert = atom_init_integer(local->dev, MTRACK_PROP_AXIS_INVERT, 2, ivals, 8); } +/* Return: + * 1 - property was recognized and handled with or without error, check error code for details + * 0 - property not recognized, don't trust returned error code - it's invalid + */ static int set_swipe_properties(Atom property, BOOL checkonly, XIPropertyValuePtr prop, - struct MPropsSwipe* propsSwipe, struct MConfigSwipe* cfgSwipe){ + struct MPropsSwipe* props_swipe, + struct MConfigSwipe* cfg_swipe, int* error_code){ uint8_t* ivals8; uint16_t* ivals16; uint32_t* ivals32; - if (property == propsSwipe->dist) { - if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) - return BadMatch; + *error_code = Success; + + if (property == props_swipe->settings) { + if (prop->size != 2 || prop->format != 32 || prop->type != XA_INTEGER) + return *error_code = BadMatch, 1; ivals32 = (uint32_t*)prop->data; if (ivals32[0] < 1) - return BadMatch; + return *error_code = BadMatch, 1; if (!checkonly) { - cfgSwipe->dist = ivals32[0]; + cfg_swipe->dist = ivals32[0]; + cfg_swipe->hold = ivals32[1]; #ifdef DEBUG_PROPS - xf86Msg(X_INFO, "mtrack: set swipe distance to %d\n", - cfgSwipe->dist); + xf86Msg(X_INFO, "mtrack: set swipe settings: dist: %d hold: %d\n", + cfg_swipe->dist, cfg_swipe->hold); #endif } } - else if (property == propsSwipe->buttons) { + else if (property == props_swipe->buttons) { if (prop->size != 4 || prop->format != 8 || prop->type != XA_INTEGER) - return BadMatch; + return *error_code = BadMatch, 1; ivals8 = (uint8_t*)prop->data; if (!VALID_BUTTON(ivals8[0]) || !VALID_BUTTON(ivals8[1]) || !VALID_BUTTON(ivals8[2]) || !VALID_BUTTON(ivals8[3])) - return BadMatch; + return *error_code = BadMatch, 1; if (!checkonly) { - cfgSwipe->up_btn = ivals8[0]; - cfgSwipe->dn_btn = ivals8[1]; - cfgSwipe->lt_btn = ivals8[2]; - cfgSwipe->rt_btn = ivals8[3]; + cfg_swipe->up_btn = ivals8[0]; + cfg_swipe->dn_btn = ivals8[1]; + cfg_swipe->lt_btn = ivals8[2]; + cfg_swipe->rt_btn = ivals8[3]; #ifdef DEBUG_PROPS xf86Msg(X_INFO, "mtrack: set swipe buttons to %d %d %d %d\n", - cfgSwipe->up_btn, cfgSwipe->dn_btn, cfgSwipe->lt_btn, cfgSwipe->rt_btn); -#endif - } - } - else if (property == propsSwipe->hold) { - if (prop->size != 1 || prop->format != 16 || prop->type != XA_INTEGER) - return BadMatch; - - ivals16 = (uint16_t*)prop->data; - - if (!checkonly) { - cfgSwipe->hold = ivals16[0]; -#ifdef DEBUG_PROPS - xf86Msg(X_INFO, "mtrack: set swipe hold to %d\n", cfgSwipe->hold); + cfg_swipe->up_btn, cfg_swipe->dn_btn, cfg_swipe->lt_btn, cfg_swipe->rt_btn); #endif } } @@ -260,6 +253,8 @@ int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop uint32_t* ivals32; float* fvals; + int error_code; + if (property == mprops.trackpad_disable) { if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER) return BadMatch; @@ -484,14 +479,14 @@ int mprops_set_property(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop #endif } } - else if (set_swipe_properties(property, checkonly, prop, &mprops.scroll, &cfg->scroll)) { - /* nothing to do */ + else if (set_swipe_properties(property, checkonly, prop, &mprops.scroll, &cfg->scroll, &error_code)) { + return error_code; } - else if (set_swipe_properties(property, checkonly, prop, &mprops.swipe3, &cfg->swipe3)) { - /* nothing to do */ + else if (set_swipe_properties(property, checkonly, prop, &mprops.swipe3, &cfg->swipe3, &error_code)) { + return error_code; } - else if (set_swipe_properties(property, checkonly, prop, &mprops.swipe4, &cfg->swipe4)) { - /* nothing to do */ + else if (set_swipe_properties(property, checkonly, prop, &mprops.swipe4, &cfg->swipe4, &error_code)) { + return error_code; } else if (property == mprops.scale_dist) { if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) diff --git a/include/mprops.h b/include/mprops.h index 7bf2791..9ca5162 100644 --- a/include/mprops.h +++ b/include/mprops.h @@ -62,24 +62,24 @@ #define MTRACK_PROP_PALM_SIZE "Trackpad Palm Size" // int, 2 value - button hold, wait time #define MTRACK_PROP_GESTURE_SETTINGS "Trackpad Gesture Settings" -// int, 1 value - distance before a scroll event is triggered -#define MTRACK_PROP_SCROLL_DIST "Trackpad Scroll Distance" +// int, 2 values +// first: distance before a scroll event (two finger swipe) is triggered +// second: how much milliseconds button will be hold after {up,down,left,right} scroll +#define MTRACK_PROP_SCROLL_SETTINGS "Trackpad Scroll Settings" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SCROLL_BUTTONS "Trackpad Scroll Buttons" -// int, 1 value - how much milliseconds button will be hold after {up,down,left,right} scroll -#define MTRACK_PROP_SCROLL_SETTINGS "Trackpad Scroll Settings" -// int, 1 value - distance before a swipe event is triggered -#define MTRACK_PROP_SWIPE_DIST "Trackpad Swipe Distance" +// int, 2 values +// first: distance before a three finger swipe event is triggered +// second: how much milliseconds button will be hold after {up,down,left,right} swipe +#define MTRACK_PROP_SWIPE_SETTINGS "Trackpad Swipe Settings" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SWIPE_BUTTONS "Trackpad Swipe Buttons" -// int, 1 value - how much milliseconds button will be hold after {up,down,left,right} swipe -#define MTRACK_PROP_SWIPE_SETTINGS "Trackpad Swipe Settings" -// int, 1 value - distance before a swipe event is triggered -#define MTRACK_PROP_SWIPE4_DIST "Trackpad Swipe4 Distance" +// int, 2 values +// first: distance before a four finger swipe event is triggered +// second: how much milliseconds button will be hold after {up,down,left,right} swipe4 +#define MTRACK_PROP_SWIPE4_SETTINGS "Trackpad Swipe4 Settings" // int, 4 values - up button, down button, left button, right button #define MTRACK_PROP_SWIPE4_BUTTONS "Trackpad Swipe4 Buttons" -// int, 1 value - how much milliseconds button will be hold after {up,down,left,right} swipe4 -#define MTRACK_PROP_SWIPE4_SETTINGS "Trackpad Swipe4 Settings" // int, 1 value - distance before a scale event is triggered #define MTRACK_PROP_SCALE_DIST "Trackpad Scale Distance" // int, 2 values - up button, down button @@ -113,9 +113,8 @@ struct MProps { Atom palm_size; Atom gesture_settings; struct MPropsSwipe{ - Atom dist; + Atom settings; Atom buttons; - Atom hold; } scroll, swipe3, swipe4/*, swipe5*/; Atom scale_dist; Atom scale_buttons; diff --git a/src/mconfig.c b/src/mconfig.c index b417f6e..faca504 100644 --- a/src/mconfig.c +++ b/src/mconfig.c @@ -154,23 +154,23 @@ void mconfig_configure(struct MConfig* cfg, cfg->gesture_hold = MAXVAL(xf86SetIntOption(opts, "GestureClickTime", DEFAULT_GESTURE_HOLD), 1); cfg->gesture_wait = MAXVAL(xf86SetIntOption(opts, "GestureWaitTime", DEFAULT_GESTURE_WAIT), 0); cfg->scroll.dist = MAXVAL(xf86SetIntOption(opts, "ScrollDistance", DEFAULT_SCROLL_DIST), 1); + cfg->scroll.hold = MAXVAL(xf86SetIntOption(opts, "ScrollClickTime", DEFAULT_SCROLL_HOLD), 0); cfg->scroll.up_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollUpButton", DEFAULT_SCROLL_UP_BTN), 0, 32); cfg->scroll.dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollDownButton", DEFAULT_SCROLL_DN_BTN), 0, 32); cfg->scroll.lt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollLeftButton", DEFAULT_SCROLL_LT_BTN), 0, 32); cfg->scroll.rt_btn = CLAMPVAL(xf86SetIntOption(opts, "ScrollRightButton", DEFAULT_SCROLL_RT_BTN), 0, 32); - cfg->scroll.hold = MAXVAL(xf86SetIntOption(opts, "ScrollClickTime", DEFAULT_SCROLL_HOLD), 0); cfg->swipe3.dist = MAXVAL(xf86SetIntOption(opts, "SwipeDistance", DEFAULT_SWIPE_DIST), 1); + cfg->swipe3.hold = MAXVAL(xf86SetIntOption(opts, "SwipeClickTime", DEFAULT_SWIPE_HOLD), 0); cfg->swipe3.up_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeUpButton", DEFAULT_SWIPE_UP_BTN), 0, 32); cfg->swipe3.dn_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeDownButton", DEFAULT_SWIPE_DN_BTN), 0, 32); cfg->swipe3.lt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeLeftButton", DEFAULT_SWIPE_LT_BTN), 0, 32); cfg->swipe3.rt_btn = CLAMPVAL(xf86SetIntOption(opts, "SwipeRightButton", DEFAULT_SWIPE_RT_BTN), 0, 32); - cfg->swipe3.hold = MAXVAL(xf86SetIntOption(opts, "SwipeClickTime", DEFAULT_SWIPE_HOLD), 0); cfg->swipe4.dist = MAXVAL(xf86SetIntOption(opts, "Swipe4Distance", DEFAULT_SWIPE4_DIST), 1); + cfg->swipe4.hold = MAXVAL(xf86SetIntOption(opts, "Swipe4ClickTime", DEFAULT_SWIPE_HOLD), 0); cfg->swipe4.up_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4UpButton", DEFAULT_SWIPE4_UP_BTN), 0, 32); cfg->swipe4.dn_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4DownButton", DEFAULT_SWIPE4_DN_BTN), 0, 32); cfg->swipe4.lt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4LeftButton", DEFAULT_SWIPE4_LT_BTN), 0, 32); cfg->swipe4.rt_btn = CLAMPVAL(xf86SetIntOption(opts, "Swipe4RightButton", DEFAULT_SWIPE4_RT_BTN), 0, 32); - cfg->swipe4.hold = MAXVAL(xf86SetIntOption(opts, "Swipe4ClickTime", DEFAULT_SWIPE_HOLD), 0); cfg->scale_dist = MAXVAL(xf86SetIntOption(opts, "ScaleDistance", DEFAULT_SCALE_DIST), 1); cfg->scale_up_btn = CLAMPVAL(xf86SetIntOption(opts, "ScaleUpButton", DEFAULT_SCALE_UP_BTN), 0, 32); cfg->scale_dn_btn = CLAMPVAL(xf86SetIntOption(opts, "ScaleDownButton", DEFAULT_SCALE_DN_BTN), 0, 32);