On Mon, Feb 24, 2014 at 01:31:57PM -0800, Jason Gerecke wrote:
> New Intuos series introduced a hardware switch to turn touch
> events on/off. This patch retrieves its state from kernel by
> checking if SW_MUTE_DEVICE is declared.
>
> A new input property, WACOM_PROP_HARDWARE_TOUCH, is intoduced
> to report touch status changed by end user through touch switch.
>
> HardwareTouch, a new xsetwacom option, is added. This option
> is read-only since the state can only be changed by end users.
> This option is independent from the existing Touch option,
> which can be considered as a software touch switch.
>
> Signed-off-by: Ping Cheng <[email protected]>
> Signed-off-by: Jason Gerecke <[email protected]>
> ---
> Changes from v4:
> * Added PROP_FLAG_BOOLEAN to HWTouchSwitchState (will cause
> xsetwacom to display on/off instead of 1/0)
>
> include/wacom-properties.h | 3 ++
> man/xsetwacom.man | 6 ++++
> src/wcmUSB.c | 37 +++++++++++++++++++++++++
> src/wcmXCommand.c | 69
> ++++++++++++++++++++++++++++++++++++++++++++++
> src/xf86Wacom.h | 4 +++
> src/xf86WacomDefs.h | 3 ++
> tools/xsetwacom.c | 11 +++++++-
> 7 files changed, 132 insertions(+), 1 deletion(-)
>
> diff --git a/include/wacom-properties.h b/include/wacom-properties.h
> index dd7e7f3..419251a 100644
> --- a/include/wacom-properties.h
> +++ b/include/wacom-properties.h
> @@ -78,6 +78,9 @@
> /* BOOL, 1 value */
> #define WACOM_PROP_TOUCH "Wacom Enable Touch"
>
> +/* BOOL, 1 value */
add "read-only" here please
> +#define WACOM_PROP_HARDWARE_TOUCH "Wacom Hardware Touch Switch"
> +
> /* 8 bit, 1 values */
> #define WACOM_PROP_ENABLE_GESTURE "Wacom Enable Touch Gesture"
>
> diff --git a/man/xsetwacom.man b/man/xsetwacom.man
> index 978b104..a976f58 100644
> --- a/man/xsetwacom.man
> +++ b/man/xsetwacom.man
> @@ -209,6 +209,12 @@ If on, touch events are reported to userland, i.e.,
> system cursor moves when
> user touches the tablet. If off, touch events are ignored. Default: on for
> devices that support touch; off for all other models.
> .TP
> +\fBHWTouchSwitchState\fR on|off
> +If on, it means touch switch is turned off. That is, touch events are
> reported
> +to userland. If off, touch switch is turned on, i.e., touch events are
> ignored.
> +This is a read-only parameter. Initial touch switch state is retrieved from
> the
> +kernel when X driver starts.
> +.TP
> \fBCursorProximity\fR distance
> sets the max distance from tablet to stop reporting movement for cursor in
> relative mode. Default for Intuos series is 10, for Graphire series
> (including
> diff --git a/src/wcmUSB.c b/src/wcmUSB.c
> index e22cd5e..78e559d 100644
> --- a/src/wcmUSB.c
> +++ b/src/wcmUSB.c
> @@ -518,6 +518,7 @@ int usbWcmGetRanges(InputInfoPtr pInfo)
> struct input_absinfo absinfo;
> unsigned long ev[NBITS(EV_MAX)] = {0};
> unsigned long abs[NBITS(ABS_MAX)] = {0};
> + unsigned long sw[NBITS(SW_MAX)] = {0};
> WacomDevicePtr priv = (WacomDevicePtr)pInfo->private;
> WacomCommonPtr common = priv->common;
> wcmUSBData* private = common->private;
> @@ -744,6 +745,26 @@ int usbWcmGetRanges(InputInfoPtr pInfo)
> if (!ISBITSET(abs, ABS_MISC))
> common->wcmProtocolLevel = WCM_PROTOCOL_GENERIC;
>
> + if (ioctl(pInfo->fd, EVIOCGBIT(EV_SW, sizeof(sw)), sw) < 0)
> + {
> + xf86Msg(X_ERROR, "%s: usbProbeKeys unable to ioctl "
> + "sw bits.\n", pInfo->name);
> + return 0;
> + }
> + else if (ISBITSET(sw, SW_MUTE_DEVICE))
> + {
> + common->wcmHasHWTouchSwitch = TRUE;
> +
> + memset(sw, 0, sizeof(sw));
> +
> + ioctl(pInfo->fd, EVIOCGSW(sizeof(sw)), sw);
> +
> + if (ISBITSET(sw, SW_MUTE_DEVICE))
> + common->wcmHWTouchSwitchState = 0;
> + else
> + common->wcmHWTouchSwitchState = 1;
> + }
> +
> usbWcmInitPadState(pInfo);
>
> return Success;
> @@ -1685,6 +1706,22 @@ static void usbDispatchEvents(InputInfoPtr pInfo)
> if (usbFilterEvent(common, event))
> continue;
>
> + if (common->wcmHasHWTouchSwitch)
> + {
> + if ((event->type == EV_SW) &&
> + (event->code == SW_MUTE_DEVICE))
> + {
> + /* touch is disabled when SW_MUTE_DEVICE is set
> */
> + int touch_enabled = (event->value == 0);
> +
> + if (touch_enabled !=
> common->wcmHWTouchSwitchState)
> + /* this property is only set for touch device */
> + wcmUpdateHWTouchProperty(
> + common->wcmTouchDevice,
> + touch_enabled);
> + }
> + }
> +
> /* absolute events */
> if (event->type == EV_ABS)
> {
> diff --git a/src/wcmXCommand.c b/src/wcmXCommand.c
> index b2ba5a5..8a8fa97 100644
> --- a/src/wcmXCommand.c
> +++ b/src/wcmXCommand.c
> @@ -92,6 +92,7 @@ Atom prop_cursorprox;
> Atom prop_threshold;
> Atom prop_suppress;
> Atom prop_touch;
> +Atom prop_hardware_touch;
> Atom prop_gesture;
> Atom prop_gesture_param;
> Atom prop_hover;
> @@ -264,6 +265,11 @@ void InitWcmDeviceProperties(InputInfoPtr pInfo)
> values[0] = common->wcmTouch;
> prop_touch = InitWcmAtom(pInfo->dev, WACOM_PROP_TOUCH, XA_INTEGER, 8,
> 1, values);
>
> + if (common->wcmHasHWTouchSwitch && IsTouch(priv)) {
> + values[0] = common->wcmHWTouchSwitchState;
> + prop_hardware_touch = InitWcmAtom(pInfo->dev,
> WACOM_PROP_HARDWARE_TOUCH, XA_INTEGER, 8, 1, values);
> + }
> +
> if (IsStylus(priv)) {
> values[0] = !common->wcmTPCButton;
> prop_hover = InitWcmAtom(pInfo->dev, WACOM_PROP_HOVER,
> XA_INTEGER, 8, 1, values);
> @@ -601,6 +607,56 @@ void wcmUpdateRotationProperty(WacomDevicePtr priv)
> }
> }
>
> +static CARD32
> +touchTimerFunc(OsTimerPtr timer, CARD32 now, pointer arg)
> +{
> + InputInfoPtr pInfo = arg;
> + WacomDevicePtr priv = pInfo->private;
> + WacomCommonPtr common = priv->common;
> + XIPropertyValuePtr prop;
> + CARD8 prop_value;
> + int sigstate;
> + int rc;
> +
> + sigstate = xf86BlockSIGIO();
> +
> + rc = XIGetDeviceProperty(pInfo->dev, prop_hardware_touch, &prop);
> + if (rc != Success || prop->format != 8 || prop->size != 1)
> + {
> + xf86Msg(X_ERROR, "%s: Failed to update hardware touch state.\n",
> + pInfo->name);
> + return 0;
> + }
> +
> + prop_value = common->wcmHWTouchSwitchState;
> + XIChangeDeviceProperty(pInfo->dev, prop_hardware_touch, XA_INTEGER,
> + prop->format, PropModeReplace,
> + prop->size, &prop_value, TRUE);
> +
> + xf86UnblockSIGIO(sigstate);
> +
> + return 0;
> +}
> +
> +/**
> + * Update HW touch property when its state is changed by touch switch
> + */
> +void
> +wcmUpdateHWTouchProperty(WacomDevicePtr priv, int hw_touch)
> +{
> + WacomCommonPtr common = priv->common;
> +
> + if (hw_touch == common->wcmHWTouchSwitchState)
> + return;
> +
> + common->wcmHWTouchSwitchState = hw_touch;
> +
> + /* This function is called during SIGIO. Schedule timer for property
> + * event delivery outside of signal handler. */
> + priv->touch_timer = TimerSet(priv->touch_timer, 0 /* reltime */,
> + 1, touchTimerFunc, priv->pInfo);
hmm, I didn't spot this in the previous revisions but this won't work. the
first time this is called priv->touch_timer is NULL, so it'll allocate a
timer. That looks good at first but this code called in the signal handler
so we may deadlock. Look at the code for tap_timer, it's allocated in
wcmAllocate, all you need to do is add another line for touch_timer there
too.
With that, Reviewed-by: Peter Hutterer <[email protected]>
Cheers,
Peter
> +}
> +
> /**
> * Only allow deletion of a property if it is not being used by any of the
> * button actions.
> @@ -781,6 +837,19 @@ int wcmSetProperty(DeviceIntPtr dev, Atom property,
> XIPropertyValuePtr prop,
>
> if (!checkonly && common->wcmTouch != values[0])
> common->wcmTouch = values[0];
> + } else if (property == prop_hardware_touch)
> + {
> + if (common->wcmHasHWTouchSwitch)
> + {
> + /* If we get here from wcmUpdateHWTouchProperty, we know
> + * the wcmHWTouchSwitchState has been set internally
> + * already, so we can reply with success. */
> + if (prop->size == 1 && prop->format == 8)
> + if (((CARD8*)prop->data)[0] ==
> common->wcmHWTouchSwitchState)
> + return Success;
> + }
> +
> + return BadValue; /* read-only */
> } else if (property == prop_gesture)
> {
> CARD8 *values = (CARD8*)prop->data;
> diff --git a/src/xf86Wacom.h b/src/xf86Wacom.h
> index c0448f2..f3feea4 100644
> --- a/src/xf86Wacom.h
> +++ b/src/xf86Wacom.h
> @@ -43,6 +43,9 @@
> #define LogMessageVerbSigSafe xf86MsgVerb
> #endif
>
> +#ifndef SW_MUTE_DEVICE
> +#define SW_MUTE_DEVICE 0x0e
> +#endif
>
>
> /******************************************************************************
> * Debugging support
> @@ -169,6 +172,7 @@ extern int wcmDeleteProperty(DeviceIntPtr dev, Atom
> property);
> extern void InitWcmDeviceProperties(InputInfoPtr pInfo);
> extern void wcmUpdateRotationProperty(WacomDevicePtr priv);
> extern void wcmUpdateSerial(InputInfoPtr pInfo, unsigned int serial, int id);
> +extern void wcmUpdateHWTouchProperty(WacomDevicePtr priv, int touch);
>
> /* Utility functions */
> extern Bool is_absolute(InputInfoPtr pInfo);
> diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
> index afe6543..67e87c3 100644
> --- a/src/xf86WacomDefs.h
> +++ b/src/xf86WacomDefs.h
> @@ -311,6 +311,7 @@ struct _WacomDeviceRec
>
> OsTimerPtr serial_timer; /* timer used for serial number property
> update */
> OsTimerPtr tap_timer; /* timer used for tap timing */
> + OsTimerPtr touch_timer; /* timer used for touch switch property update
> */
> };
>
>
> /******************************************************************************
> @@ -432,6 +433,8 @@ struct _WacomCommonRec
> WacomDevicePtr wcmTouchDevice; /* The pointer for pen to access the
> touch tool of the same device id */
> Bool wcmPenInProx; /* Keep pen in-prox state for touch tool */
> + Bool wcmHasHWTouchSwitch; /* Tablet has a touch on/off switch */
> + int wcmHWTouchSwitchState; /* touch event disable/enabled by hardware
> switch */
>
> /* These values are in tablet coordinates */
> int wcmMaxX; /* tablet max X value */
> diff --git a/tools/xsetwacom.c b/tools/xsetwacom.c
> index bbe25ea..96f0f8d 100644
> --- a/tools/xsetwacom.c
> +++ b/tools/xsetwacom.c
> @@ -204,6 +204,15 @@ static param_t parameters[] =
> .prop_flags = PROP_FLAG_BOOLEAN
> },
> {
> + .name = "HWTouchSwitchState",
> + .desc = "Touch events turned on/off by hardware switch. ",
> + .prop_name = WACOM_PROP_HARDWARE_TOUCH,
> + .prop_format = 8,
> + .prop_offset = 0,
> + .arg_count = 1,
> + .prop_flags = PROP_FLAG_READONLY | PROP_FLAG_BOOLEAN
> + },
> + {
> .name = "Gesture",
> .desc = "Turns on/off multi-touch gesture events "
> "(default is on). ",
> @@ -2791,7 +2800,7 @@ static void test_parameter_number(void)
> * deprecated them.
> * Numbers include trailing NULL entry.
> */
> - assert(ARRAY_SIZE(parameters) == 37);
> + assert(ARRAY_SIZE(parameters) == 38);
> assert(ARRAY_SIZE(deprecated_parameters) == 17);
> }
>
> --
> 1.9.0
>
>
> ------------------------------------------------------------------------------
> Flow-based real-time traffic analytics software. Cisco certified tool.
> Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer
> Customize your own dashboards, set traffic alerts and generate reports.
> Network behavioral analysis & security monitoring. All-in-one tool.
> http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
> _______________________________________________
> Linuxwacom-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel
>
------------------------------------------------------------------------------
Subversion Kills Productivity. Get off Subversion & Make the Move to Perforce.
With Perforce, you get hassle-free workflows. Merge that actually works.
Faster operations. Version large binaries. Built-in WAN optimization and the
freedom to use Git, Perforce or both. Make the move to Perforce.
http://pubads.g.doubleclick.net/gampad/clk?id=122218951&iu=/4140/ostg.clktrk
_______________________________________________
Linuxwacom-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel