diff -Nurp xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1.orig/include/synaptics-properties.h xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1/include/synaptics-properties.h --- xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1.orig/include/synaptics-properties.h 2009-06-28 03:04:33.000000000 +0200 +++ xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1/include/synaptics-properties.h 2009-07-06 12:29:13.000000000 +0200 @@ -149,4 +149,7 @@ * has_double, has_triple */ #define SYNAPTICS_PROP_CAPABILITIES "Synaptics Capabilities" +/* 32 bit, 4 values, left, right, top, bottom */ +#define SYNAPTICS_PROP_AREA "Synaptics Area" + #endif /* _SYNAPTICS_PROPERTIES_H_ */ diff -Nurp xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1.orig/src/eventcomm.c xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1/src/eventcomm.c --- xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1.orig/src/eventcomm.c 2009-06-28 03:04:33.000000000 +0200 +++ xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1/src/eventcomm.c 2009-07-06 12:47:43.000000000 +0200 @@ -182,8 +182,8 @@ event_query_axis_ranges(LocalDevicePtr l { xf86Msg(X_INFO, "%s: x-axis range %d - %d\n", local->name, abs.minimum, abs.maximum); - priv->minx = abs.minimum; - priv->maxx = abs.maximum; + priv->minx = (priv->synpara.area_left_edge > 0) ? priv->synpara.area_left_edge : abs.minimum; + priv->maxx = (priv->synpara.area_right_edge > 0) ? priv->synpara.area_right_edge : abs.maximum; } else xf86Msg(X_ERROR, "%s: failed to query axis range (%s)\n", local->name, strerror(errno)); @@ -193,8 +193,8 @@ event_query_axis_ranges(LocalDevicePtr l { xf86Msg(X_INFO, "%s: y-axis range %d - %d\n", local->name, abs.minimum, abs.maximum); - priv->miny = abs.minimum; - priv->maxy = abs.maximum; + priv->maxy = (priv->synpara.area_top_edge > 0) ? priv->synpara.area_top_edge : abs.maximum; + priv->miny = (priv->synpara.area_bottom_edge > 0) ? priv->synpara.area_bottom_edge : abs.minimum; } else xf86Msg(X_ERROR, "%s: failed to query axis range (%s)\n", local->name, strerror(errno)); diff -Nurp xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1.orig/src/properties.c xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1/src/properties.c --- xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1.orig/src/properties.c 2009-06-28 03:04:33.000000000 +0200 +++ xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1/src/properties.c 2009-07-06 12:29:13.000000000 +0200 @@ -82,6 +82,7 @@ Atom prop_pressuremotion_factor = 0; Atom prop_grab = 0; Atom prop_gestures = 0; Atom prop_capabilities = 0; +Atom prop_area = 0; static Atom InitAtom(DeviceIntPtr dev, char *name, int format, int nvalues, int *values) @@ -262,6 +263,12 @@ InitDeviceProperties(LocalDevicePtr loca values[3] = priv->has_double; values[4] = priv->has_triple; prop_capabilities = InitAtom(local->dev, SYNAPTICS_PROP_CAPABILITIES, 8, 5, values); + + values[0] = para->area_left_edge; + values[1] = para->area_right_edge; + values[2] = para->area_top_edge; + values[3] = para->area_bottom_edge; + prop_area = InitAtom(local->dev, SYNAPTICS_PROP_AREA, 32, 4, values); } int @@ -612,6 +619,21 @@ SetProperty(DeviceIntPtr dev, Atom prope { /* read-only */ return BadValue; + } else if (property == prop_area) + { + INT32 *area; + if (prop->size != 4 || prop->format != 32 || prop->type != XA_INTEGER) + return BadMatch; + + area = (INT32*)prop->data; + if ((((area[0] > 0) && (area[1] > 0)) && (area[0] > area[1]) ) || (((area[2] > 0) && (area[3] > 0)) && (area[2] > area[3]))) + return BadValue; + + para->area_left_edge = area[0]; + para->area_right_edge = area[1]; + para->area_top_edge = area[2]; + para->area_bottom_edge = area[3]; + } return Success; diff -Nurp xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1.orig/src/synaptics.c xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1/src/synaptics.c --- xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1.orig/src/synaptics.c 2009-06-28 03:06:17.000000000 +0200 +++ xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1/src/synaptics.c 2009-07-06 12:31:59.000000000 +0200 @@ -1026,6 +1026,28 @@ edge_detection(SynapticsPrivate *priv, i return edge; } +/* Checks whether coordinates are in the Synaptics Area + * or not. If no Synaptics Area is defined, the function + * returns TRUE. + */ +static Bool +is_inside_active_area(SynapticsPrivate *priv, int x, int y) +{ + Bool inside_area = TRUE; + + if ((priv->synpara.area_left_edge > 0) && (x < priv->synpara.area_left_edge)) + inside_area = FALSE; + else if ((priv->synpara.area_right_edge > 0) && (x > priv->synpara.area_right_edge)) + inside_area = FALSE; + + if ((priv->synpara.area_top_edge > 0) && (y < priv->synpara.area_top_edge)) + inside_area = FALSE; + else if ((priv->synpara.area_bottom_edge > 0) && (y > priv->synpara.area_bottom_edge)) + inside_area = FALSE; + + return inside_area; +} + static CARD32 timerFunc(OsTimerPtr timer, CARD32 now, pointer arg) { @@ -1364,7 +1386,7 @@ GetTimeOut(SynapticsPrivate *priv) static int HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw, - edge_type edge, enum FingerState finger) + edge_type edge, enum FingerState finger, Bool inside_active_area) { SynapticsParameters *para = &priv->synpara; Bool touch, release, is_timeout, move; @@ -1380,6 +1402,11 @@ HandleTapProcessing(SynapticsPrivate *pr ((abs(hw->x - priv->touch_on.x) >= para->tap_move) || (abs(hw->y - priv->touch_on.y) >= para->tap_move)) && finger); + if (! inside_active_area) { + touch = release = FALSE; + move = TRUE; + } + if (touch) { priv->touch_on.x = hw->x; priv->touch_on.y = hw->y; @@ -2029,6 +2056,7 @@ HandleState(LocalDevicePtr local, struct int delay = 1000000000; int timeleft; int i; + Bool inside_active_area; /* update hardware state in shared memory */ if (shm) @@ -2125,11 +2153,12 @@ HandleState(LocalDevicePtr local, struct } edge = edge_detection(priv, hw->x, hw->y); + inside_active_area = is_inside_active_area(priv, hw->x, hw->y); finger = SynapticsDetectFinger(priv, hw); /* tap and drag detection */ - timeleft = HandleTapProcessing(priv, hw, edge, finger); + timeleft = HandleTapProcessing(priv, hw, edge, finger, inside_active_area); if (timeleft > 0) delay = MIN(delay, timeleft); @@ -2165,7 +2194,23 @@ HandleState(LocalDevicePtr local, struct } /* Post events */ - if (dx || dy) + + /* Process movements only if coordinates are + * in the Synaptics Area + */ + if (! inside_active_area) + dx = dy = 0; + + /* Process movements only if previous coordinates were + * in the Synaptics Area otherwise the cursor will jump + * after moving from the inactive area to the active area. + * This happens because we are ignoring taps which take + * place outside of the active area. + */ + if ((dx || dy) && (is_inside_active_area(priv, HIST(0).x, HIST(0).y) && + is_inside_active_area(priv, HIST(1).x, HIST(1).y) && + is_inside_active_area(priv, HIST(2).x, HIST(2).y) && + is_inside_active_area(priv, HIST(3).x, HIST(3).y) )) xf86PostMotionEvent(local->dev, 0, 0, 2, dx, dy); if (priv->mid_emu_state == MBE_LEFT_CLICK) @@ -2187,6 +2232,10 @@ HandleState(LocalDevicePtr local, struct xf86PostButtonEvent(local->dev, FALSE, id, (buttons & (1 << (id - 1))), 0, 0); } + /* Process scroll events only if coordinates are + * in the Synaptics Area + */ + if (inside_active_area) { while (scroll.up-- > 0) { xf86PostButtonEvent(local->dev, FALSE, 4, !hw->up, 0, 0); xf86PostButtonEvent(local->dev, FALSE, 4, hw->up, 0, 0); @@ -2203,6 +2252,8 @@ HandleState(LocalDevicePtr local, struct xf86PostButtonEvent(local->dev, FALSE, 7, TRUE, 0, 0); xf86PostButtonEvent(local->dev, FALSE, 7, FALSE, 0, 0); } + } + if (double_click) { int i; for (i = 0; i < 2; i++) { diff -Nurp xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1.orig/src/synapticsstr.h xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1/src/synapticsstr.h --- xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1.orig/src/synapticsstr.h 2009-06-28 03:04:33.000000000 +0200 +++ xserver-xorg-input-synaptics-1.1.99+git20090627.bb74e1a1/src/synapticsstr.h 2009-07-06 12:29:13.000000000 +0200 @@ -147,6 +147,7 @@ typedef struct _SynapticsParameters double press_motion_max_factor; /* factor applied on speed when finger pressure is at minimum */ Bool grab_event_device; /* grab event device for exclusive use? */ Bool tap_and_drag_gesture; /* Switches the tap-and-drag gesture on/off */ + int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* area coordinates absolute */ } SynapticsParameters;