At Thu, 29 Apr 2010 17:03:59 +1000, Peter Hutterer wrote: > > On Fri, Apr 23, 2010 at 05:39:04PM +0200, Takashi Iwai wrote: > > This patch adds the support for Synaptics Clickpad devices. > > It requires the change in Linux kernel synaptics input driver, found in > > https://patchwork.kernel.org/patch/92435/ > > The kernel patch is already included in linux-input GIT tree, which > > will hit Linus tree sooner or later. > > > > When the kernel driver sets only the left-button bit evbit and no > > multi-finger is possible, Clickpad mode is activated. In this mode, > > the bottom touch area is used as button emulations. Clicking at the > > bottom-left, bottom-center and bottom-right zone corresponds to a left, > > center and right click. > > > > Signed-off-by: Takashi Iwai <[email protected]> > > --- > > > > v2->v3: Fix the mis-detection of Clickpad device with double-tap feature > > (e.g. MacBook) > > Fix one forgotten spacing issue Peter suggested > > > > src/eventcomm.c | 6 ++++ > > src/synaptics.c | 72 > > +++++++++++++++++++++++++++++++++++++++++++++++++++- > > src/synapticsstr.h | 2 + > > 3 files changed, 79 insertions(+), 1 deletions(-) > > > > diff --git a/src/eventcomm.c b/src/eventcomm.c > > index d00d810..6b44778 100644 > > --- a/src/eventcomm.c > > +++ b/src/eventcomm.c > > @@ -252,6 +252,12 @@ event_query_axis_ranges(LocalDevicePtr local) > > if ((priv->has_triple = (TEST_BIT(BTN_TOOL_TRIPLETAP, keybits) != 0))) > > strcat(buf, " triple"); > > xf86Msg(X_INFO, "%s: buttons:%s\n", local->name, buf); > > + > > + /* clickpad device reports only the single left button mask */ > > + if (priv->has_left && !priv->has_right && !priv->has_middle && > > !priv->has_double) { > > + priv->is_clickpad = TRUE; > > + xf86Msg(X_INFO, "%s: is Clickpad device\n", local->name); > > + } > > } > > } > > > > diff --git a/src/synaptics.c b/src/synaptics.c > > index 091dbe1..554f7a3 100644 > > --- a/src/synaptics.c > > +++ b/src/synaptics.c > > @@ -457,6 +457,18 @@ static void set_default_parameters(LocalDevicePtr > > local) > > vertResolution = priv->resy; > > } > > > > + /* Clickpad mode -- bottom area is used as buttons */ > > + if (priv->is_clickpad) { > > + int button_bottom; > > + /* Clickpad devices usually the button area at the bottom, and > > + * its size seems ca. 20% of the touchpad height no matter how > > + * large the pad is. > > + */ > > + button_bottom = priv->maxy - (abs(priv->maxy - priv->miny) * 20) / 100; > > + if (button_bottom < b && button_bottom >= t) > > + b = button_bottom; > > + } > > + > > /* set the parameters */ > > pars->left_edge = xf86SetIntOption(opts, "LeftEdge", l); > > pars->right_edge = xf86SetIntOption(opts, "RightEdge", r); > > @@ -2052,6 +2064,59 @@ HandleClickWithFingers(SynapticsParameters *para, > > struct SynapticsHwState *hw) > > } > > } > > > > +/* clickpad event handling */ > > +static void > > +HandleClickpad(LocalDevicePtr local, struct SynapticsHwState *hw, > > edge_type edge) > > +{ > > + SynapticsPrivate *priv = (SynapticsPrivate *) (local->private); > > + SynapticsParameters *para = &priv->synpara; > > + > > + if (edge & BOTTOM_EDGE) { > > + /* button area */ > > + int width = priv->maxx - priv->minx; > > + int left_button_x, right_button_x; > > + > > + /* left and right clickpad button ranges; > > + * the gap between them is interpreted as a middle-button click > > + */ > > + left_button_x = width * 2 / 5 + priv->minx; > > + right_button_x = width * 3 / 5 + priv->minx; > > + > > + /* clickpad reports only one button, and we need > > + * to fake left/right buttons depending on the touch position > > + */ > > + if (hw->left) { /* clicked? */ > > + hw->left = 0; > > + if (hw->x < left_button_x) > > + hw->left = 1; > > + else if (hw->x > right_button_x) > > + hw->right = 1; > > + else > > + hw->middle = 1; > > + } > > + > > + /* Don't move pointer position in the button area during clicked, > > + * except for horiz/vert scrolling is enabled. > > + * > > + * The synaptics driver tends to be pretty sensitive. This hack > > + * is to avoid that the pointer moves slightly and misses the > > + * poistion you aimed to click. > > + * > > + * Also, when the pointer movement is reported, the dragging > > + * (with a sort of multi-touching) doesn't work well, too. > > + */ > > + if (hw->left || !(para->scroll_edge_horiz || > > + ((edge & RIGHT_EDGE) && para->scroll_edge_vert))) > > + hw->z = 0; /* don't move pointer */ > > + > > + } else if (hw->left) { > > + /* dragging */ > > + hw->left = priv->prev_hw.left; > > + hw->right = priv->prev_hw.right; > > + hw->middle = priv->prev_hw.middle; > > + } > > + priv->prev_hw = *hw; > > +} > > > > /* > > * React on changes in the hardware state. This function is called every > > time > > @@ -2102,6 +2167,12 @@ HandleState(LocalDevicePtr local, struct > > SynapticsHwState *hw) > > if (para->touchpad_off == 1) > > return delay; > > > > + edge = edge_detection(priv, hw->x, hw->y); > > + > > + /* Clickpad handling for button area */ > > + if (priv->is_clickpad) > > + HandleClickpad(local, hw, edge); > > + > > /* Treat the first two multi buttons as up/down for now. */ > > hw->up |= hw->multi[0]; > > hw->down |= hw->multi[1]; > > @@ -2152,7 +2223,6 @@ HandleState(LocalDevicePtr local, struct > > SynapticsHwState *hw) > > hw->multi[2] = hw->multi[3] = FALSE; > > } > > > > - edge = edge_detection(priv, hw->x, hw->y); > > inside_active_area = is_inside_active_area(priv, hw->x, hw->y); > > > > finger = SynapticsDetectFinger(priv, hw); > > diff --git a/src/synapticsstr.h b/src/synapticsstr.h > > index bd19c79..05e43d3 100644 > > --- a/src/synapticsstr.h > > +++ b/src/synapticsstr.h > > @@ -232,6 +232,8 @@ typedef struct _SynapticsPrivateRec > > Bool has_double; /* double click detected for > > this device */ > > Bool has_triple; /* triple click detected for > > this device */ > > Bool has_pressure; /* device reports pressure */ > > + Bool is_clickpad; /* is Clickpad device > > (one-button) */ > > + struct SynapticsHwState prev_hw; /* previous h/w state (for > > clickpad) */ > > > > enum TouchpadModel model; /* The detected model */ > > } SynapticsPrivate; > > -- > > 1.7.0.4 > > can you send me a man page update for this change as well? Just so something > is in the man page informing the user what ClickPad in the log means. I'll > squash it on top of this one then.
OK, I'll update in the next week after I back from my vacation. thanks, Takashi _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
