diff --git a/man/synaptics.man b/man/synaptics.man index 5b98082..8f7812c 100644 --- a/man/synaptics.man +++ b/man/synaptics.man @@ -99,7 +99,9 @@ option is not needed with synaptics 1.0 or later. See section X coordinate for left edge. Property: "Synaptics Edges" .TP 7 .BI "Option \*qRightEdge\*q \*q" integer \*q -X coordinate for right edge. Property: "Synaptics Edges" +X coordinate for right edge. If this option is set, +.BI SpecialScrollAreaRight +is ignored. Property: "Synaptics Edges" .TP 7 .BI "Option \*qTopEdge\*q \*q" integer \*q Y coordinate for top edge. Property: "Synaptics Edges" @@ -107,6 +109,10 @@ Y coordinate for top edge. Property: "Synaptics Edges" .BI "Option \*qBottomEdge\*q \*q" integer \*q Y coordinate for bottom edge. Property: "Synaptics Edges" .TP 7 +.BI "Option \*qSpecialScrollAreaRight\*q \*q" boolean \*q +Some touchpads have a scroll region on the right edge. Disable this option if +you have one but don't want use it as scroll wheel region. +.TP 7 .BI "Option \*qFingerLow\*q \*q" integer \*q When finger pressure drops below this value, the driver counts it as a release. Property: "Synaptics Finger" @@ -836,11 +842,6 @@ Tapping is disabled by default for touchpads with one or more physical buttons. To enable it you need to map tap actions to buttons. See the "TapButton1", "TapButton2" and "TapButton3" options. .LP -Some devices report min/max values but provide values outside this range. -In this case, the driver auto-adjusts the edge values. Acceleration and -speed values are not affected. User-specified edges are not -auto-adjusted. -.LP Button mapping for physical buttons is handled in the server. If the device is switched to left-handed (an in-server mapping of physical buttons 1, 2, 3 to the logical buttons 3, 2, 1, respectively), both physical @@ -853,10 +854,6 @@ The following options are no longer part of the driver configuration: .BI "Option \*qRepeater\*q \*q" string \*q .TP .BI "Option \*qHistorySize\*q \*q" integer \*q -.TP 7 -.BI "Option \*qSpecialScrollAreaRight\*q \*q" boolean \*q -Some touchpads have a scroll region on the right edge. Disable this option if -you have one but don't want use it as scroll wheel region. .SH "AUTHORS" .LP diff --git a/src/properties.c b/src/properties.c index c571c34..70b59e0 100644 --- a/src/properties.c +++ b/src/properties.c @@ -151,10 +151,10 @@ InitDeviceProperties(LocalDevicePtr local) } } - values[0] = para->edges[LEFT_EDGE]; - values[1] = para->edges[RIGHT_EDGE]; - values[2] = para->edges[TOP_EDGE]; - values[3] = para->edges[BOTTOM_EDGE]; + values[0] = para->left_edge; + values[1] = para->right_edge; + values[2] = para->top_edge; + values[3] = para->bottom_edge; prop_edges = InitAtom(local->dev, SYNAPTICS_PROP_EDGES, 32, 4, values); @@ -291,10 +291,10 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, if (edges[0] > edges[1] || edges[2] > edges[3]) return BadValue; - para->edges[LEFT_EDGE] = edges[0]; - para->edges[RIGHT_EDGE] = edges[1]; - para->edges[TOP_EDGE] = edges[2]; - para->edges[BOTTOM_EDGE] = edges[3]; + para->left_edge = edges[0]; + para->right_edge = edges[1]; + para->top_edge = edges[2]; + para->bottom_edge = edges[3]; } else if (property == prop_finger) { diff --git a/src/synaptics.c b/src/synaptics.c index 5f800a1..e1e3646 100644 --- a/src/synaptics.c +++ b/src/synaptics.c @@ -82,6 +82,17 @@ #include #endif +typedef enum { + BOTTOM_EDGE = 1, + TOP_EDGE = 2, + LEFT_EDGE = 4, + RIGHT_EDGE = 8, + LEFT_BOTTOM_EDGE = BOTTOM_EDGE | LEFT_EDGE, + RIGHT_BOTTOM_EDGE = BOTTOM_EDGE | RIGHT_EDGE, + RIGHT_TOP_EDGE = TOP_EDGE | RIGHT_EDGE, + LEFT_TOP_EDGE = TOP_EDGE | LEFT_EDGE +} edge_type; + #define MAX(a, b) (((a)>(b))?(a):(b)) #define MIN(a, b) (((a)<(b))?(a):(b)) #define TIME_DIFF(a, b) ((int)((a)-(b))) @@ -282,40 +293,6 @@ free_param_data(SynapticsPrivate *priv) priv->synshm = NULL; } -static void -calculate_edge_widths(SynapticsPrivate *priv, int *l, int *r, int *t, int *b) -{ - int width, height; - int ewidth, eheight; /* edge width/height */ - - width = abs(priv->maxx - priv->minx); - height = abs(priv->maxy - priv->miny); - - if (priv->model == MODEL_SYNAPTICS) - { - ewidth = width * .07; - eheight = height * .07; - } else if (priv->model == MODEL_ALPS) - { - ewidth = width * .15; - eheight = height * .15; - } else if (priv->model == MODEL_APPLETOUCH) - { - ewidth = width * .085; - eheight = height * .085; - } else - { - ewidth = width * .04; - eheight = height * .054; - } - - *l = priv->minx + ewidth; - *r = priv->maxx - ewidth; - *t = priv->miny + eheight; - *b = priv->maxy - eheight; -} - - static void set_default_parameters(LocalDevicePtr local) { SynapticsPrivate *priv = local->private; /* read-only */ @@ -355,12 +332,33 @@ static void set_default_parameters(LocalDevicePtr local) if (priv->minx < priv->maxx && priv->miny < priv->maxy) { int width, height, diag; + int ewidth, eheight; /* edge width/height */ width = abs(priv->maxx - priv->minx); height = abs(priv->maxy - priv->miny); diag = sqrt(width * width + height * height); + if (priv->model == MODEL_SYNAPTICS) + { + ewidth = width * .07; + eheight = height * .07; + } else if (priv->model == MODEL_ALPS) + { + ewidth = width * .15; + eheight = height * .15; + } else if (priv->model == MODEL_APPLETOUCH) + { + ewidth = width * .085; + eheight = height * .085; + } else + { + ewidth = width * .04; + eheight = height * .054; + } - calculate_edge_widths(priv, &l, &r, &t, &b); + l = priv->minx + ewidth; + r = priv->maxx - ewidth; + t = priv->miny + eheight; + b = priv->maxy - eheight; /* Again, based on typical x/y range and defaults */ horizScrollDelta = diag * .020; @@ -439,14 +437,10 @@ static void set_default_parameters(LocalDevicePtr local) horizTwoFingerScroll = FALSE; /* set the parameters */ - pars->edges_forced[LEFT_EDGE] = xf86CheckIfOptionUsedByName(opts, "LeftEdge"); - pars->edges_forced[RIGHT_EDGE] = xf86CheckIfOptionUsedByName(opts, "RightEdge"); - pars->edges_forced[TOP_EDGE] = xf86CheckIfOptionUsedByName(opts, "TopEdge"); - pars->edges_forced[BOTTOM_EDGE] = xf86CheckIfOptionUsedByName(opts, "BottomEdge"); - pars->edges[LEFT_EDGE] = xf86SetIntOption(opts, "LeftEdge", l); - pars->edges[RIGHT_EDGE] = xf86SetIntOption(opts, "RightEdge", r); - pars->edges[TOP_EDGE] = xf86SetIntOption(opts, "TopEdge", t); - pars->edges[BOTTOM_EDGE] = xf86SetIntOption(opts, "BottomEdge", b); + pars->left_edge = xf86SetIntOption(opts, "LeftEdge", l); + pars->right_edge = xf86SetIntOption(opts, "RightEdge", r); + pars->top_edge = xf86SetIntOption(opts, "TopEdge", t); + pars->bottom_edge = xf86SetIntOption(opts, "BottomEdge", b); pars->finger_low = xf86SetIntOption(opts, "FingerLow", fingerLow); pars->finger_high = xf86SetIntOption(opts, "FingerHigh", fingerHigh); @@ -462,6 +456,11 @@ static void set_default_parameters(LocalDevicePtr local) pars->scroll_dist_vert = xf86SetIntOption(opts, "VertScrollDelta", horizScrollDelta); pars->scroll_dist_horiz = xf86SetIntOption(opts, "HorizScrollDelta", vertScrollDelta); pars->scroll_edge_vert = xf86SetBoolOption(opts, "VertEdgeScroll", vertEdgeScroll); + if (xf86CheckIfOptionUsedByName(opts, "RightEdge")) { + pars->special_scroll_area_right = FALSE; + } else { + pars->special_scroll_area_right = xf86SetBoolOption(opts, "SpecialScrollAreaRight", TRUE); + } pars->scroll_edge_horiz = xf86SetBoolOption(opts, "HorizEdgeScroll", horizEdgeScroll); pars->scroll_edge_corner = xf86SetBoolOption(opts, "CornerCoasting", FALSE); pars->scroll_twofinger_vert = xf86SetBoolOption(opts, "VertTwoFingerScroll", vertTwoFingerScroll); @@ -512,10 +511,10 @@ static void set_default_parameters(LocalDevicePtr local) pars->tap_and_drag_gesture = xf86SetBoolOption(opts, "TapAndDragGesture", TRUE); /* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */ - if (pars->edges[TOP_EDGE] > pars->edges[BOTTOM_EDGE]) { - int tmp = pars->edges[TOP_EDGE]; - pars->edges[TOP_EDGE]= pars->edges[BOTTOM_EDGE]; - pars->edges[BOTTOM_EDGE] = tmp; + if (pars->top_edge > pars->bottom_edge) { + int tmp = pars->top_edge; + pars->top_edge = pars->bottom_edge; + pars->bottom_edge = tmp; xf86Msg(X_WARNING, "%s: TopEdge is bigger than BottomEdge. Fixing.\n", local->name); } @@ -606,7 +605,7 @@ SynapticsPreInit(InputDriverPtr drv, IDevPtr dev, int flags) set_default_parameters(local); - priv->largest_valid_x = MIN(priv->synpara.edges[RIGHT_EDGE], XMAX_NOMINAL); + priv->largest_valid_x = MIN(priv->synpara.right_edge, XMAX_NOMINAL); if (!alloc_param_data(local)) goto SetupProc_fail; @@ -943,10 +942,10 @@ static void relative_coords(SynapticsPrivate *priv, int x, int y, double *relX, double *relY) { - int minX = priv->synpara.edges[LEFT_EDGE]; - int maxX = priv->synpara.edges[RIGHT_EDGE]; - int minY = priv->synpara.edges[TOP_EDGE]; - int maxY = priv->synpara.edges[BOTTOM_EDGE]; + int minX = priv->synpara.left_edge; + int maxX = priv->synpara.right_edge; + int minY = priv->synpara.top_edge; + int maxY = priv->synpara.bottom_edge; double xCenter = (minX + maxX) / 2.0; double yCenter = (minY + maxY) / 2.0; @@ -963,8 +962,8 @@ relative_coords(SynapticsPrivate *priv, int x, int y, static double angle(SynapticsPrivate *priv, int x, int y) { - double xCenter = (priv->synpara.edges[LEFT_EDGE] + priv->synpara.edges[RIGHT_EDGE]) / 2.0; - double yCenter = (priv->synpara.edges[TOP_EDGE] + priv->synpara.edges[BOTTOM_EDGE]) / 2.0; + double xCenter = (priv->synpara.left_edge + priv->synpara.right_edge) / 2.0; + double yCenter = (priv->synpara.top_edge + priv->synpara.bottom_edge) / 2.0; return atan2(-(y - yCenter), x - xCenter); } @@ -1014,14 +1013,14 @@ edge_detection(SynapticsPrivate *priv, int x, int y) if (priv->synpara.circular_pad) return circular_edge_detection(priv, x, y); - if (x > priv->synpara.edges[RIGHT_EDGE]) + if (x > priv->synpara.right_edge) edge |= RIGHT_EDGE; - else if (x < priv->synpara.edges[LEFT_EDGE]) + else if (x < priv->synpara.left_edge) edge |= LEFT_EDGE; - if (y < priv->synpara.edges[TOP_EDGE]) + if (y < priv->synpara.top_edge) edge |= TOP_EDGE; - else if (y > priv->synpara.edges[BOTTOM_EDGE]) + else if (y > priv->synpara.bottom_edge) edge |= BOTTOM_EDGE; return edge; @@ -2107,48 +2106,22 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState *hw) hw->multi[2] = hw->multi[3] = FALSE; } - /* The kernel doesn't clip into min/max, so auto-adjust the edges if we - * go beyond min/max */ - if (hw->x > priv->maxx || hw->x < priv->minx || - hw->y > priv->maxy || hw->y < priv->miny) - { - int l, r, t, b; - Bool changed = FALSE; - - if (hw->x > priv->maxx && !para->edges_forced[RIGHT_EDGE]) - { - priv->maxx = hw->x; - changed = TRUE; - } else if (hw->x < priv->minx && !para->edges_forced[LEFT_EDGE]) - { - priv->minx = hw->x; - changed = TRUE; - } - - if (hw->y >= priv->maxy && !para->edges_forced[BOTTOM_EDGE]) - { - priv->maxy = hw->y; - changed = TRUE; - } else if (hw->y >= priv->miny && !para->edges_forced[TOP_EDGE]) - { - priv->miny = hw->y; - changed = TRUE; - } - - if (changed) - { - calculate_edge_widths(priv, &l, &r, &t, &b); - if (!para->edges_forced[LEFT_EDGE]) - para->edges[LEFT_EDGE] = l; - if (!para->edges_forced[RIGHT_EDGE]) - para->edges[RIGHT_EDGE] = r; - if (!para->edges_forced[TOP_EDGE]) - para->edges[TOP_EDGE] = t; - if (!para->edges_forced[BOTTOM_EDGE]) - para->edges[BOTTOM_EDGE] = b; - - /* FIXME: property notify */ - } + /* + * Some touchpads have a scroll wheel region where a very large X + * coordinate is reported. In this case for eliminate discontinuity, + * we adjust X and simulate new zone which adjacent to right edge. + */ + if (hw->x <= XMAX_VALID) { + if (priv->largest_valid_x < hw->x) + priv->largest_valid_x = hw->x; + } else { + hw->x = priv->largest_valid_x + 1; + /* + * If user didn't set right_edge manualy, auto-adjust to bounds of + * hardware scroll area. + */ + if (para->special_scroll_area_right) + priv->synpara.right_edge = priv->largest_valid_x; } edge = edge_detection(priv, hw->x, hw->y); diff --git a/src/synapticsstr.h b/src/synapticsstr.h index 7da6c5e..d2ff57c 100644 --- a/src/synapticsstr.h +++ b/src/synapticsstr.h @@ -86,23 +86,10 @@ enum TouchpadModel { MODEL_APPLETOUCH }; -typedef enum { - BOTTOM_EDGE = 1, - TOP_EDGE = 2, - LEFT_EDGE = 4, - RIGHT_EDGE = 8, - LEFT_BOTTOM_EDGE = BOTTOM_EDGE | LEFT_EDGE, - RIGHT_BOTTOM_EDGE = BOTTOM_EDGE | RIGHT_EDGE, - RIGHT_TOP_EDGE = TOP_EDGE | RIGHT_EDGE, - LEFT_TOP_EDGE = TOP_EDGE | LEFT_EDGE -} edge_type; - - typedef struct _SynapticsParameters { /* Parameter data */ - int edges[RIGHT_EDGE]; /* edge coordinates absolute */ - Bool edges_forced[RIGHT_EDGE]; /* edges set manually? */ + int left_edge, right_edge, top_edge, bottom_edge; /* edge coordinates absolute */ 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. */