diff options
-rw-r--r-- | include/wacom-properties.h | 3 | ||||
-rw-r--r-- | man/xsetwacom.man | 6 | ||||
-rw-r--r-- | src/wcmConfig.c | 2 | ||||
-rw-r--r-- | src/wcmUSB.c | 37 | ||||
-rw-r--r-- | src/wcmXCommand.c | 69 | ||||
-rw-r--r-- | src/xf86Wacom.h | 4 | ||||
-rw-r--r-- | src/xf86WacomDefs.h | 3 | ||||
-rw-r--r-- | tools/xsetwacom.c | 11 |
8 files changed, 134 insertions, 1 deletions
diff --git a/include/wacom-properties.h b/include/wacom-properties.h index dd7e7f3..3201d99 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, read-only */ +#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/wcmConfig.c b/src/wcmConfig.c index f9a593c..a8077f9 100644 --- a/src/wcmConfig.c +++ b/src/wcmConfig.c @@ -103,6 +103,7 @@ static int wcmAllocate(InputInfoPtr pInfo) /* timers */ priv->serial_timer = TimerSet(NULL, 0, 0, NULL, NULL); priv->tap_timer = TimerSet(NULL, 0, 0, NULL, NULL); + priv->touch_timer = TimerSet(NULL, 0, 0, NULL, NULL); return 1; @@ -127,6 +128,7 @@ static void wcmFree(InputInfoPtr pInfo) TimerFree(priv->serial_timer); TimerFree(priv->tap_timer); + TimerFree(priv->touch_timer); free(priv->tool); wcmFreeCommon(&priv->common); free(priv); diff --git a/src/wcmUSB.c b/src/wcmUSB.c index 002c986..7375711 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; @@ -1686,6 +1707,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); +} + /** * 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 882d8cd..bdda3f7 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 @@ -172,6 +175,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); } |