summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wacom-properties.h3
-rw-r--r--man/xsetwacom.man6
-rw-r--r--src/wcmConfig.c2
-rw-r--r--src/wcmUSB.c37
-rw-r--r--src/wcmXCommand.c69
-rw-r--r--src/xf86Wacom.h4
-rw-r--r--src/xf86WacomDefs.h3
-rw-r--r--tools/xsetwacom.c11
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);
}