If a tool is on an USB tablet before the driver is loaded, the driver loses the initial state of the tool since kernel input device driver filters repeated events. To initialize the tool with the proper device type, we call EVIOCGKEY to retrieve it from the kernel.
Signed-off-by: Ping Cheng <[email protected]> --- src/wcmCommon.c | 7 ++++--- src/wcmUSB.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/wcmCommon.c b/src/wcmCommon.c index eb985e4..96bd48c 100644 --- a/src/wcmCommon.c +++ b/src/wcmCommon.c @@ -1297,9 +1297,7 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel, if (!ds->device_type && ds->proximity) { - /* Tool may be on the tablet when X starts. - * Figure out device type by device id - */ + /* something went wrong. Figure out device type by device id */ switch (ds->device_id) { case STYLUS_DEVICE_ID: @@ -1314,6 +1312,9 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel, case TOUCH_DEVICE_ID: ds->device_type = TOUCH_ID; break; + case PAD_DEVICE_ID: + ds->device_type = PAD_ID; + break; default: ds->device_type = idtotype(ds->device_id); } diff --git a/src/wcmUSB.c b/src/wcmUSB.c index 249a7bf..7128fae 100644 --- a/src/wcmUSB.c +++ b/src/wcmUSB.c @@ -869,6 +869,24 @@ skipEvent: common->wcmEventCnt = 0; } +static struct +{ + __u16 device_type; + __u16 tool_key; +} wcmTypeToKey [] = +{ + { STYLUS_ID, BTN_TOOL_PEN }, + { STYLUS_ID, BTN_TOOL_PENCIL }, + { STYLUS_ID, BTN_TOOL_BRUSH }, + { STYLUS_ID, BTN_TOOL_AIRBRUSH }, + { ERASER_ID, BTN_TOOL_RUBBER }, + { CURSOR_ID, BTN_TOOL_MOUSE }, + { CURSOR_ID, BTN_TOOL_LENS }, + { TOUCH_ID, BTN_TOOL_DOUBLETAP }, + { TOUCH_ID, BTN_TOOL_TRIPLETAP }, + { PAD_ID, BTN_TOOL_FINGER } +}; + static void usbParseChannel(LocalDevicePtr local, int channel) { int i, shift, nkeys; @@ -876,6 +894,8 @@ static void usbParseChannel(LocalDevicePtr local, int channel) struct input_event* event; WacomDevicePtr priv = (WacomDevicePtr)local->private; WacomCommonPtr common = priv->common; + WacomChannelPtr pChannel = common->wcmChannel + channel; + WacomDeviceState dslast = pChannel->valid.state; DBG(6, common, "%d events received\n", common->wcmEventCnt); #define MOD_BUTTONS(bit, value) do { \ @@ -996,8 +1016,6 @@ static void usbParseChannel(LocalDevicePtr local, int channel) } else if (event->code == BTN_TOOL_DOUBLETAP) { - WacomChannelPtr pChannel = common->wcmChannel + channel; - WacomDeviceState dslast = pChannel->valid.state; DBG(6, common, "USB Touch detected %x (value=%d)\n", event->code, event->value); @@ -1023,8 +1041,6 @@ static void usbParseChannel(LocalDevicePtr local, int channel) } else if (event->code == BTN_TOOL_TRIPLETAP) { - WacomChannelPtr pChannel = common->wcmChannel + channel; - WacomDeviceState dslast = pChannel->valid.state; DBG(6, common, "USB Touch second finger detected %x (value=%d)\n", event->code, event->value); @@ -1066,6 +1082,27 @@ static void usbParseChannel(LocalDevicePtr local, int channel) } } /* next event */ + /* device type unknown? Tool may be on the tablet when X starts. */ + if (!ds->device_type && !dslast.proximity) + { + __u16 keys[NBITS(KEY_MAX)]; + int i; + + memset(keys, 0, sizeof(keys)); + + /* Retrieve the type by asking a resend from the kernel */ + ioctl(common->fd, EVIOCGKEY(sizeof(keys)), keys); + + for (i=0; i<sizeof(wcmTypeToKey) / sizeof(wcmTypeToKey[0]); i++) + { + if (ISBITSET(keys, wcmTypeToKey[i].tool_key)) + { + ds->device_type = wcmTypeToKey[i].device_type; + break; + } + } + } + /* don't send touch event when touch isn't enabled */ if ((ds->device_type == TOUCH_ID) && !common->wcmTouch) return; -- 1.6.6.1 ------------------------------------------------------------------------------ ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo _______________________________________________ Linuxwacom-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel
