diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2021-11-25 21:03:39 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2021-12-20 15:01:56 +1000 |
commit | d5ca999f35c7de7032a7e2c7df25019a636e59f6 (patch) | |
tree | b8c4619563e6acab23445a2b6d54d396ef0e4234 /src | |
parent | 91cbc367947556420e546a5c48107aa62da6231f (diff) | |
download | xf86-input-wacom-d5ca999f35c7de7032a7e2c7df25019a636e59f6.tar.gz |
Add a helper function to iterate over local devices to the driver layer
wcmForeachDevice() calls a callback on each device that uses the wacom
driver. Switch our loops over to use that instead of iterating manually
- this makes the driver code independent of the X way of iterating
through devices (and finding those using the wacom driver).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/wcmConfig.c | 211 | ||||
-rw-r--r-- | src/wcmValidateDevice.c | 82 | ||||
-rw-r--r-- | src/xf86Wacom.c | 27 | ||||
-rw-r--r-- | src/xf86Wacom.h | 13 |
4 files changed, 186 insertions, 147 deletions
diff --git a/src/wcmConfig.c b/src/wcmConfig.c index 7b85b8f..b637938 100644 --- a/src/wcmConfig.c +++ b/src/wcmConfig.c @@ -258,44 +258,36 @@ void wcmDisableTool(WacomDevicePtr priv) wcmEnableDisableTool(priv, FALSE); } +static int unlinkDevice(WacomDevicePtr tmppriv, /* tmppriv is the iterated device */ + void *data) +{ + WacomDevicePtr priv = data; /* our device is the data argument */ + WacomCommonPtr common = priv->common; + WacomCommonPtr tmpcommon = tmppriv->common; + Bool touch_device = (common->wcmTouchDevice || tmpcommon->wcmTouchDevice); + + if (!touch_device || tmpcommon->tablet_id != common->tablet_id) + return -ENODEV; + + common->wcmTouchDevice = NULL; + tmpcommon->wcmTouchDevice = NULL; + common->tablet_type &= ~WCM_PENTOUCH; + tmpcommon->tablet_type &= ~WCM_PENTOUCH; + return 0; +} + + /** * Unlink the touch tool from the pen of the same device */ void wcmUnlinkTouchAndPen(WacomDevicePtr priv) { WacomCommonPtr common = priv->common; - InputInfoPtr device = xf86FirstLocalDevice(); - WacomCommonPtr tmpcommon = NULL; - WacomDevicePtr tmppriv = NULL; - Bool touch_device = FALSE; if (!TabletHasFeature(common, WCM_PENTOUCH)) return; - /* Lookup to find the associated pen and touch */ - for (; device != NULL; device = device->next) - { - if (!strcmp(device->drv->driverName, "wacom")) - { - tmppriv = (WacomDevicePtr) device->private; - tmpcommon = tmppriv->common; - touch_device = (common->wcmTouchDevice || - tmpcommon->wcmTouchDevice); - - /* skip the same tool or unlinked devices */ - if ((tmppriv == priv) || !touch_device) - continue; - - if (tmpcommon->tablet_id == common->tablet_id) - { - common->wcmTouchDevice = NULL; - tmpcommon->wcmTouchDevice = NULL; - common->tablet_type &= ~WCM_PENTOUCH; - tmpcommon->tablet_type &= ~WCM_PENTOUCH; - return; - } - } - } + wcmForeachDevice(priv, unlinkDevice, priv); } /** @@ -346,14 +338,9 @@ static void wcmSplitName(char* devicename, char *basename, char *subdevice, char * when a tablet reports 'pen' and 'touch' through separate device * nodes. */ -static Bool wcmIsSiblingDevice(InputInfoPtr a, InputInfoPtr b, Bool logical_only) +static Bool wcmIsSiblingDevice(WacomDevicePtr privA, + WacomDevicePtr privB, Bool logical_only) { - WacomDevicePtr privA = (WacomDevicePtr)a->private; - WacomDevicePtr privB = (WacomDevicePtr)b->private; - - if (strcmp(a->drv->driverName, "wacom") || strcmp(b->drv->driverName, "wacom")) - return FALSE; - if (privA == privB) return FALSE; @@ -386,6 +373,30 @@ static Bool wcmIsSiblingDevice(InputInfoPtr a, InputInfoPtr b, Bool logical_only return FALSE; } + +static int matchDevice(WacomDevicePtr privMatch, void *data) +{ + WacomDevicePtr priv = data; + + if (!wcmIsSiblingDevice(priv, privMatch, TRUE)) + return -ENODEV; + + DBG(2, priv, "port share between %s and %s\n", + priv->name, privMatch->name); + /* FIXME: we loose the common->wcmTool here but it + * gets re-added during wcmParseOptions. This is + * currently required by the code, adding the tool + * again here means we trigger the duplicate tool + * detection */ + wcmFreeCommon(&priv->common); + priv->common = wcmRefCommon(privMatch->common); + priv->next = priv->common->wcmDevices; + priv->common->wcmDevices = priv; + + return 0; +} + + /* wcmMatchDevice - locate matching device and merge common structure. If an * already initialized device shares the same device file and driver, remove * the new device's "common" struct and point to the one of the already @@ -397,36 +408,16 @@ static Bool wcmIsSiblingDevice(InputInfoPtr a, InputInfoPtr b, Bool logical_only */ static Bool wcmMatchDevice(WacomDevicePtr priv, WacomCommonPtr *common_return) { - InputInfoPtr pLocal = priv->pInfo; WacomCommonPtr common = priv->common; - InputInfoPtr pMatch = xf86FirstLocalDevice(); *common_return = common; if (!common->device_path) return 0; - for (; pMatch != NULL; pMatch = pMatch->next) - { - WacomDevicePtr privMatch = (WacomDevicePtr)pMatch->private; - - if (wcmIsSiblingDevice(pLocal, pMatch, TRUE)) - { - DBG(2, priv, "port share between %s and %s\n", - pLocal->name, pMatch->name); - /* FIXME: we loose the common->wcmTool here but it - * gets re-added during wcmParseOptions. This is - * currently required by the code, adding the tool - * again here means we trigger the duplicate tool - * detection */ - wcmFreeCommon(&priv->common); - priv->common = wcmRefCommon(privMatch->common); - priv->next = priv->common->wcmDevices; - priv->common->wcmDevices = priv; - *common_return = priv->common; - return 1; - } - } + /* If a match is found, priv->common has been replaced */ + if (wcmForeachDevice(priv, matchDevice, priv) == 0) + *common_return = priv->common; return 0; } @@ -467,6 +458,56 @@ wcmInitModel(WacomDevicePtr priv) return TRUE; } +static int linkDevice(WacomDevicePtr tmppriv, /* the device iterated on */ + void *data) /* our device */ +{ + WacomDevicePtr priv = data; + WacomCommonPtr common = priv->common; + WacomCommonPtr tmpcommon = tmppriv->common; + + if (!wcmIsSiblingDevice(priv, tmppriv, FALSE)) + return -ENODEV; + + DBG(4, priv, "Considering link with %s...\n", tmppriv->name); + + /* already linked devices */ + if (tmpcommon->wcmTouchDevice) + { + DBG(4, priv, "A link is already in place. Ignoring.\n"); + return -ENODEV; + } + + if (IsTouch(tmppriv)) + { + common->wcmTouchDevice = tmppriv; + tmpcommon->wcmTouchDevice = tmppriv; + } + else if (IsTouch(priv)) + { + common->wcmTouchDevice = priv; + tmpcommon->wcmTouchDevice = priv; + } + else + { + DBG(4, priv, "A link is not necessary. Ignoring.\n"); + } + + if ((common->wcmTouchDevice && IsTablet(priv)) || + (tmpcommon->wcmTouchDevice && IsTablet(tmppriv))) + { + TabletSetFeature(common, WCM_PENTOUCH); + TabletSetFeature(tmpcommon, WCM_PENTOUCH); + } + + if (common->wcmTouchDevice) + { + DBG(4, priv, "Link created!\n"); + return 0; + } + + return -ENODEV; +} + /** * Lookup to find the associated pen and touch for the same device. * Store touch tool in wcmTouchDevice for pen and touch, respectively, @@ -478,65 +519,15 @@ wcmInitModel(WacomDevicePtr priv) */ static Bool wcmLinkTouchAndPen(WacomDevicePtr priv) { - InputInfoPtr pInfo = priv->pInfo; - WacomCommonPtr common = priv->common; - InputInfoPtr device = xf86FirstLocalDevice(); - WacomCommonPtr tmpcommon = NULL; - WacomDevicePtr tmppriv = NULL; - if (IsPad(priv)) { DBG(4, priv, "No need to link up pad devices.\n"); return FALSE; } - /* Lookup to find the associated pen and touch */ - for (; device != NULL; device = device->next) - { - if (!wcmIsSiblingDevice(pInfo, device, FALSE)) - continue; + if (wcmForeachDevice(priv, linkDevice, priv) <= 0) + DBG(4, priv, "No suitable device to link with found.\n"); - tmppriv = (WacomDevicePtr) device->private; - tmpcommon = tmppriv->common; - - DBG(4, priv, "Considering link with %s...\n", tmppriv->name); - - /* already linked devices */ - if (tmpcommon->wcmTouchDevice) - { - DBG(4, priv, "A link is already in place. Ignoring.\n"); - continue; - } - - if (IsTouch(tmppriv)) - { - common->wcmTouchDevice = tmppriv; - tmpcommon->wcmTouchDevice = tmppriv; - } - else if (IsTouch(priv)) - { - common->wcmTouchDevice = priv; - tmpcommon->wcmTouchDevice = priv; - } - else - { - DBG(4, priv, "A link is not necessary. Ignoring.\n"); - } - - if ((common->wcmTouchDevice && IsTablet(priv)) || - (tmpcommon->wcmTouchDevice && IsTablet(tmppriv))) - { - TabletSetFeature(common, WCM_PENTOUCH); - TabletSetFeature(tmpcommon, WCM_PENTOUCH); - } - - if (common->wcmTouchDevice) - { - DBG(4, priv, "Link created!\n"); - return TRUE; - } - } - DBG(4, priv, "No suitable device to link with found.\n"); return FALSE; } diff --git a/src/wcmValidateDevice.c b/src/wcmValidateDevice.c index 8cd95a0..c30d2ba 100644 --- a/src/wcmValidateDevice.c +++ b/src/wcmValidateDevice.c @@ -24,6 +24,40 @@ #include <fcntl.h> #include <unistd.h> +struct checkData { + dev_t min_maj; + const char *source; +}; + +static int checkSource(WacomDevicePtr other, void *data) +{ + InputInfoPtr pInfo = other->pInfo; + char *device = xf86CheckStrOption(pInfo->options, "Device", NULL); + WacomCommonPtr pCommon; + struct checkData *check = data; + Bool match = FALSE; + + /* device can be NULL on some distros */ + if (!device) + return -ENODEV; + + free(device); + + pCommon = other->common; + if (pCommon->min_maj && pCommon->min_maj == check->min_maj) + { + char* source = xf86CheckStrOption(pInfo->options, "_source", ""); + + /* only add the new tool if the matching major/minor + * was from the same source */ + if (strcmp(check->source, source)) + match = TRUE; + free(source); + } + + return match ? 0 : -ENODEV; +} + /* wcmCheckSource - Check if there is another source defined this device * before or not: don't add the tool by hal/udev if user has defined at least * one tool for the device in xorg.conf. One device can have multiple tools @@ -31,44 +65,18 @@ static Bool wcmCheckSource(WacomDevicePtr priv, dev_t min_maj) { InputInfoPtr pInfo = priv->pInfo; - int match = 0; - InputInfoPtr pDevices = xf86FirstLocalDevice(); - - for (; !match && pDevices != NULL; pDevices = pDevices->next) - { - char *device; - WacomCommonPtr pCommon; - - if (pInfo == pDevices) - continue; - - if (!strstr(pDevices->drv->driverName, "wacom")) - continue; - - device = xf86CheckStrOption(pDevices->options, "Device", NULL); - /* device can be NULL on some distros */ - if (!device) - continue; - free(device); - - pCommon = ((WacomDevicePtr)pDevices->private)->common; - if (pCommon->min_maj && pCommon->min_maj == min_maj) - { - char* fsource = xf86CheckStrOption(pInfo->options, "_source", ""); - char* psource = xf86CheckStrOption(pDevices->options, "_source", ""); - - /* only add the new tool if the matching major/minor - * was from the same source */ - if (strcmp(fsource, psource)) - match = 1; - free(fsource); - free(psource); - } - } - if (match) + int nmatch; + struct checkData check = { + .min_maj = min_maj, + .source = xf86CheckStrOption(pInfo->options, "_source", ""), + }; + + nmatch = wcmForeachDevice(priv, checkSource, &check); + if (nmatch > 0) wcmLog(priv, W_WARNING, - "device file already in use by %s. Ignoring.\n", pDevices->name); - return match; + "device file already in use. Ignoring.\n"); + free((char*)check.source); + return nmatch; } /* check if the device has been added. diff --git a/src/xf86Wacom.c b/src/xf86Wacom.c index 68987ea..e23d95f 100644 --- a/src/xf86Wacom.c +++ b/src/xf86Wacom.c @@ -284,6 +284,33 @@ Bool wcmInitTouch(WacomDevicePtr priv, int ntouches, Bool is_direct_touch) 2); } +int wcmForeachDevice(WacomDevicePtr priv, WacomDeviceCallback func, void *data) +{ + InputInfoPtr pInfo = priv->pInfo; + InputInfoPtr pOther; + int nmatch = 0; + + for (pOther = xf86FirstLocalDevice(); pOther; pOther = pOther->next) + { + WacomDevicePtr pPriv; + int rc; + + if (pInfo == pOther || !strstr(pOther->drv->driverName, "wacom")) + continue; + + pPriv = pOther->private; + rc = func(pPriv, data); + if (rc == -ENODEV) + continue; + if (rc < 0) + return -rc; + nmatch += 1; /* zero counts as matched */ + if (rc == 0) + break; + } + + return nmatch; +} /***************************************************************************** * wcmOpen -- diff --git a/src/xf86Wacom.h b/src/xf86Wacom.h index 2603470..391523e 100644 --- a/src/xf86Wacom.h +++ b/src/xf86Wacom.h @@ -125,6 +125,19 @@ void wcmDevClose(WacomDevicePtr priv); Bool wcmDevStart(WacomDevicePtr priv); void wcmDevStop(WacomDevicePtr priv); +/** + * @retval 0 to abort the loop (counts as match) + * @retval -ENOENT if the device is not a match + * @retval 1 for success (counts as match). + * @retval -errno for an error (to abort) + */ +typedef int (*WacomDeviceCallback)(WacomDevicePtr priv, void *data); + +/** + * Returns the number of devices processed or a negative errno + */ +extern int wcmForeachDevice(WacomDevicePtr priv, WacomDeviceCallback func, void *data); + /* Open the device with the right serial parmeters */ extern Bool wcmOpen(WacomDevicePtr priv); |