At Wed, 16 Dec 2009 07:50:54 +0100, I wrote: > > At Tue, 15 Dec 2009 18:59:34 -0800, > Dmitry Torokhov wrote: > > > > On Tue, Dec 15, 2009 at 06:05:06PM -0700, Alex Chiang wrote: > > > * Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>: > > > > > > > > The updated patch is below. > > > > > > > > -- > > > > Dmitry > > > > > > Should I test this one or wait one more iteration to address > > > Takashi's last comments? > > > > > > > Actually I think we took the wrong direction with the original patch and > > we should do what other buttonless devices (bcm5974) do: report touchpad > > click as left button and have Synaptics X driver provide enhanced > > support. This way we can have both modes (ClickZones and ClickButtons) > > and users will get to chose (provided that someone takes time to add > > that support to Synaptics driver of course ;) ). > > My concern is, still, how would you identify this device. Will you > extend also some ioctls to expose caps and extcaps? Otherwise it's > difficult to identify this device automatically from the user-space. > > The user-space can know that it's button-less, yes. But, how can it > know whether the device should be emulated via ClickZone? > We can use a driver option to x11 synaptics driver for that, as I > already sent you another patch. However, the driver option is > nowadays not preferred because xorg.conf is being dead on new > systems... FWIW, the patch below is to add clickpad feature to x11 synaptics driver 1.1.3. It's almost straightforward conversion from my kernel patch. (The vertical coordinate had to be flipped, though.) Takashi --- --- include/synaptics-properties.h | 3 ++ include/synaptics.h | 1 man/synaptics.man | 5 ++++ src/synaptics.c | 42 +++++++++++++++++++++++++++++++++++++++++ src/synapticsstr.h | 1 tools/synclient.c | 2 + 6 files changed, 54 insertions(+) --- a/include/synaptics.h +++ b/include/synaptics.h @@ -134,6 +134,7 @@ double press_motion_min_factor; /* factor applied on speed when finger pressure is at minimum */ 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 clickpad; /* clickpad mode */ } SynapticsSHM; /* --- a/src/synaptics.c +++ b/src/synaptics.c @@ -499,6 +499,7 @@ pars->press_motion_min_factor = xf86SetRealOption(opts, "PressureMotionMinFactor", 1.0); pars->press_motion_max_factor = xf86SetRealOption(opts, "PressureMotionMaxFactor", 1.0); pars->grab_event_device = xf86SetBoolOption(opts, "GrabEventDevice", TRUE); + pars->clickpad = xf86SetBoolOption(opts, "Clickpad", FALSE); /* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */ if (pars->top_edge > pars->bottom_edge) { @@ -1902,6 +1903,44 @@ } } +/* left and right clickpad button ranges; + * the gap between them is interpreted as a middle-button click + */ +#define CLICKPAD_LEFT_BTN_X(p) \ + (((p)->maxx - (p)->minx) * 2 / 5 + (p)->minx) +#define CLICKPAD_RIGHT_BTN_X(p) \ + (((p)->maxx - (p)->minx) * 3 / 5 + (p)->minx) + +static void +MangleClickpad(SynapticsPrivate *priv, struct SynapticsHwState *hw) +{ + SynapticsSHM *para = priv->synpara; + + /* clickpad mode reports Y over YMAX as a button area */ + if (hw->y > priv->maxy) { + /* clickpad reports only the middle button, and we need + * to fake left/right buttons depending on the touch position + */ + if (hw->left || hw->middle || hw->right) { /* clicked? */ + hw->left = hw->middle = hw->right = 0; + if (hw->x < CLICKPAD_LEFT_BTN_X(priv)); + hw->left = 1; + else if (hw->x > CLICKPAD_RIGHT_BTN_X(priv)) + hw->right = 1; + else + hw->middle = 1; + } + /* don't move pointer in the button area */ + hw->x = para->x; + hw->y = para->y; + hw->z = 0; + } else if (hw->left || hw->middle || hw->right) { + /* dragging */ + hw->left = para->left; + hw->right = para->right; + hw->middle = para->middle; + } +} /* * React on changes in the hardware state. This function is called every time @@ -1924,6 +1963,9 @@ int timeleft; int i; + if (para->clickpad) + MangleClickpad(priv, hw); + /* update hardware state in shared memory */ para->x = hw->x; para->y = hw->y; --- a/src/synapticsstr.h +++ b/src/synapticsstr.h @@ -154,6 +154,7 @@ Bool has_pressure; /* device reports pressure */ enum TouchpadModel model; /* The detected model */ + Bool clickpad; /* clickpad mode */ } SynapticsPrivate; #endif /* _SYNAPTICSSTR_H_ */ --- a/man/synaptics.man +++ b/man/synaptics.man @@ -411,6 +411,11 @@ . This can be achieved by switching to a text console and then switching back to X. +.TP 7 +.BI "Option \*qClickpad\*q \*q" boolean \*q +Supports Clickpad. The driver handles a middle-button click in the +special low area as left/right/middle buttons according to the position. +This mode works only with evdev protocol. . . .LP --- a/tools/synclient.c +++ b/tools/synclient.c @@ -209,6 +209,8 @@ SYNAPTICS_PROP_PRESSURE_MOTION_FACTOR, 0 /*float*/, 1), DEFINE_PAR("GrabEventDevice", grab_event_device, PT_BOOL, 0, 1, SYNAPTICS_PROP_GRAB, 8, 0), + DEFINE_PAR("Clickpad", clickpad, PT_BOOL, 0, 1, + SYNAPTICS_PROP_CLICKPAD, 8, 0), { NULL, 0, 0, 0, 0 } }; --- a/include/synaptics-properties.h +++ b/include/synaptics-properties.h @@ -142,4 +142,7 @@ /* 8 bit (BOOL) */ #define SYNAPTICS_PROP_GRAB "Synaptics Grab Event Device" +/* 8 bit (BOOL) */ +#define SYNAPTICS_PROP_CLICKPAD "Synaptics Clickpad Mode" + #endif /* _SYNAPTICS_PROPERTIES_H_ */ -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html