diff -Nur xfree86-driver-synaptics-0.99.3.orig/include/synaptics.h xfree86-driver-synaptics-0.99.3/include/synaptics.h --- xfree86-driver-synaptics-0.99.3.orig/include/synaptics.h 2008-11-13 05:57:45.000000000 +0100 +++ xfree86-driver-synaptics-0.99.3/include/synaptics.h 2009-04-21 10:35:03.000000000 +0200 @@ -78,6 +78,7 @@ /* Parameter data */ int left_edge, right_edge, top_edge, bottom_edge; /* edge coordinates absolute */ + int movement_bottom_edge; /* edge coordinates to limit movements */ int finger_low, finger_high, finger_press; /* finger detection values in Z-values */ int tap_time; int tap_move; /* max. tapping time and movement in packets and coord. */ diff -Nur xfree86-driver-synaptics-0.99.3.orig/include/synaptics-properties.h xfree86-driver-synaptics-0.99.3/include/synaptics-properties.h --- xfree86-driver-synaptics-0.99.3.orig/include/synaptics-properties.h 2008-10-03 10:20:48.000000000 +0200 +++ xfree86-driver-synaptics-0.99.3/include/synaptics-properties.h 2009-04-21 10:54:23.000000000 +0200 @@ -139,4 +139,7 @@ /* 8 bit (BOOL) */ #define SYNAPTICS_PROP_GRAB "Synaptics Grab Event Device" +/* 32 bit . Valid values are the same as Synaptics Edges bottom */ +#define SYNAPTICS_PROP_MOVEMENT_BOTTOM_EDGE "Synaptics Movement Bottom Edge" + #endif /* _SYNAPTICS_PROPERTIES_H_ */ diff -Nur xfree86-driver-synaptics-0.99.3.orig/src/eventcomm.c xfree86-driver-synaptics-0.99.3/src/eventcomm.c --- xfree86-driver-synaptics-0.99.3.orig/src/eventcomm.c 2008-11-13 02:09:52.000000000 +0100 +++ xfree86-driver-synaptics-0.99.3/src/eventcomm.c 2009-04-21 16:28:46.000000000 +0200 @@ -143,6 +143,16 @@ abs.minimum, abs.maximum); priv->miny = abs.minimum; priv->maxy = abs.maximum; + + Bool has_movement_bottom_edge = (! priv->synpara) ? FALSE : (priv->synpara->movement_bottom_edge > 0); + /* This is necessary because priv->synpara might have not been initialised yet */ + if (has_movement_bottom_edge) { + priv->maxy = (priv->synpara->movement_bottom_edge > 0) ? priv->synpara->movement_bottom_edge : abs.maximum; + } + else { + priv->maxy = abs.maximum; + xf86Msg(X_WARNING, "%s: priv->synpara->movement_bottom_edge NOT AVAILABLE.\n", local->name); + } } else xf86Msg(X_ERROR, "%s: failed to query axis range (%s)\n", local->name, strerror(errno)); @@ -234,6 +244,8 @@ struct SynapticsHwState *hw = &(comm->hwState); SynapticsPrivate *priv = (SynapticsPrivate *)local->private; SynapticsSHM *para = priv->synpara; + /* See if movement_bottom_edge is enabled */ + Bool has_movement_bottom_edge = (! priv->synpara) ? FALSE : (priv->synpara->movement_bottom_edge > 0); while (SynapticsReadEvent(comm, &ev)) { switch (ev.type) { @@ -318,10 +330,41 @@ case EV_ABS: switch (ev.code) { case ABS_X: - hw->x = ev.value; + if (has_movement_bottom_edge) { + /* Update hw->x only if the y event didn't take place + * in the blacklisted area. + */ + if (hw->y < priv->synpara->movement_bottom_edge) { + hw->x = ev.value; + } + } + else { + hw->x = ev.value; + } break; case ABS_Y: - hw->y = ev.value; + if (has_movement_bottom_edge) { + /* Update hw->y to its real value only if the event + * didn't take place in the blacklisted area. + */ + + /* Valid value within the limits */ + if (ev.value <= priv->synpara->movement_bottom_edge) { + hw->y = ev.value; + } + /* Valid value: <= maxy + * Let's set it to the maximum allowed + */ + else if (ev.value <= priv->maxy) { + hw->y = priv->synpara->movement_bottom_edge; + } + /* Else - Invalid value: bigger than maxy + * Let's ignore the event + */ + } + else { + hw->y = ev.value; + } break; case ABS_PRESSURE: hw->z = ev.value; diff -Nur xfree86-driver-synaptics-0.99.3.orig/src/properties.c xfree86-driver-synaptics-0.99.3/src/properties.c --- xfree86-driver-synaptics-0.99.3.orig/src/properties.c 2008-10-28 07:59:36.000000000 +0100 +++ xfree86-driver-synaptics-0.99.3/src/properties.c 2009-04-21 11:14:10.000000000 +0200 @@ -71,6 +71,7 @@ Atom prop_coastspeed = 0; Atom prop_pressuremotion = 0; Atom prop_grab = 0; +Atom prop_movement_bottom_edge = 0; static Atom InitAtom(DeviceIntPtr dev, char *name, int format, int nvalues, int *values) @@ -205,6 +206,8 @@ prop_grab = InitAtom(local->dev, SYNAPTICS_PROP_GRAB, 8, 1, ¶->grab_event_device); + prop_movement_bottom_edge = InitAtom(local->dev, SYNAPTICS_PROP_MOVEMENT_BOTTOM_EDGE, 32, 1, ¶->movement_bottom_edge); + } int @@ -513,6 +516,12 @@ return BadMatch; para->grab_event_device = *(BOOL*)prop->data; + } else if (property == prop_movement_bottom_edge) + { + if (prop->size != 1 || prop->format != 32 || prop->type != XA_INTEGER) + return BadMatch; + + para->movement_bottom_edge = *(INT32*)prop->data; } return Success; diff -Nur xfree86-driver-synaptics-0.99.3.orig/src/synaptics.c xfree86-driver-synaptics-0.99.3/src/synaptics.c --- xfree86-driver-synaptics-0.99.3.orig/src/synaptics.c 2008-12-15 00:33:15.000000000 +0100 +++ xfree86-driver-synaptics-0.99.3/src/synaptics.c 2009-04-21 11:01:59.000000000 +0200 @@ -494,6 +494,9 @@ pars->press_motion_max_factor = synSetFloatOption(opts, "PressureMotionMaxFactor", 1.0); pars->grab_event_device = xf86SetBoolOption(opts, "GrabEventDevice", TRUE); + /* Set "MovementBottomEdge" to 0 as most touchpads don't need it */ + pars->movement_bottom_edge = xf86SetIntOption(opts, "MovementBottomEdge", 0); + /* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */ if (pars->top_edge > pars->bottom_edge) { int tmp = pars->top_edge; diff -Nur xfree86-driver-synaptics-0.99.3.orig/tools/synclient.c xfree86-driver-synaptics-0.99.3/tools/synclient.c --- xfree86-driver-synaptics-0.99.3.orig/tools/synclient.c 2008-11-13 05:57:45.000000000 +0100 +++ xfree86-driver-synaptics-0.99.3/tools/synclient.c 2009-04-21 10:36:28.000000000 +0200 @@ -64,6 +64,7 @@ DEFINE_PAR("RightEdge", right_edge, PT_INT, 0, 10000), DEFINE_PAR("TopEdge", top_edge, PT_INT, 0, 10000), DEFINE_PAR("BottomEdge", bottom_edge, PT_INT, 0, 10000), + DEFINE_PAR("MovementBottomEdge", movement_bottom_edge, PT_INT, 0, 10000), DEFINE_PAR("FingerLow", finger_low, PT_INT, 0, 255), DEFINE_PAR("FingerHigh", finger_high, PT_INT, 0, 255), DEFINE_PAR("FingerPress", finger_press, PT_INT, 0, 256),