This patch rewrites the call chains used for setting the three action properties by introducing a single function to handle the 'Actions' properties, and a single function for 'Action' properties. Functions which were merely helper functions have been inlined if appropriate.
Signed-off-by: Jason Gerecke <killert...@gmail.com> --- src/wcmXCommand.c | 287 +++++++++++++++++++++--------------------------------- 1 file changed, 110 insertions(+), 177 deletions(-) diff --git a/src/wcmXCommand.c b/src/wcmXCommand.c index 1cc7b7e..1190ed6 100644 --- a/src/wcmXCommand.c +++ b/src/wcmXCommand.c @@ -274,11 +274,53 @@ static int wcmFindProp(Atom property, Atom *prop_list, int nprops) return i; } -static int wcmSanityCheckProperty(XIPropertyValuePtr prop) +/** + * Obtain a pointer to the the handler and action list for a given Action + * property. This function searches the button, wheel, and strip property + * handler lists. + * + * @param priv The device whose handler lists should be searched + * @param property The Action property that should be searched for + * @param[out] handler Returns a pointer to the property's handler + * @param[out] action Returns a pointer to the property's action list + */ +static void wcmFindActionHandler(WacomDevicePtr priv, Atom property, Atom **handler, unsigned int (**action)[256]) +{ + int offset; + + offset = wcmFindProp(property, priv->btn_actions, ARRAY_SIZE(priv->btn_actions)); + if (offset >=0) + { + *handler = &priv->btn_actions[offset]; + *action = &priv->keys[offset]; + return; + } + + offset = wcmFindProp(property, priv->wheel_actions, ARRAY_SIZE(priv->wheel_actions)); + if (offset >= 0) + { + *handler = &priv->wheel_actions[offset]; + *action = &priv->wheel_keys[offset]; + return; + } + + offset = wcmFindProp(property, priv->strip_actions, ARRAY_SIZE(priv->strip_actions)); + if (offset < 0) + { + *handler = &priv->strip_actions[offset]; + *action = &priv->strip_keys[offset]; + return; + } +} + +static int wcmCheckActionProperty(Atom property, XIPropertyValuePtr prop) { CARD32 *data; int j; + if (!property) + return Success; + if (prop->size >= 255 || prop->format != 32 || prop->type != XA_INTEGER) return BadMatch; @@ -309,98 +351,53 @@ static int wcmSanityCheckProperty(XIPropertyValuePtr prop) } /** - * Store the new value of the property in one of the driver's internal - * property handler lists. Properties stored there will be checked for value - * changes whenever updated. + * An 'Action' property (such as an element of "Wacom Button Actions") + * defines an action to be performed for some event. The property is + * validated, and then saved for later use. Both the property itself + * (as 'handler') and the data it references (as 'action') are saved. + * + * @param dev The device being modified + * @param property The Action property being set + * @param prop The data contained in 'property' + * @param checkonly 'true' if the property should only be checked for validity + * @param handler Pointer to the handler that must be updated + * @param action Pointer to the action list that must be updated */ -static void wcmUpdateActionPropHandlers(XIPropertyValuePtr prop, Atom *handlers) -{ - int i; - CARD32 *values = (CARD32*)prop->data; - - /* any action property needs to be registered for this handler. */ - for (i = 0; i < prop->size; i++) - handlers[i] = values[i]; -} - -static void wcmUpdateButtonKeyActions(DeviceIntPtr dev, XIPropertyValuePtr prop, - unsigned int (*keys)[256], int skeys) -{ - Atom *values = (Atom*)prop->data; - XIPropertyValuePtr val; - int i, j; - - for (i = 0; i < prop->size; i++) - { - memset(keys[i], 0, sizeof(keys[i])); - - if (!values[i]) - continue; - - XIGetDeviceProperty(dev, values[i], &val); - - for (j = 0; j < val->size; j++) - keys[i][j] = ((unsigned int*)val->data)[j]; - } -} - -/* Change the properties that hold the actual button actions */ -static int wcmSetActionProperties(DeviceIntPtr dev, Atom property, - XIPropertyValuePtr prop, BOOL checkonly) +static int wcmSetActionProperty(DeviceIntPtr dev, Atom property, + XIPropertyValuePtr prop, BOOL checkonly, + Atom *handler, unsigned int (*action)[256]) { InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate; WacomDevicePtr priv = (WacomDevicePtr) pInfo->private; - int i; - int rc; - + int rc, i; DBG(10, priv, "\n"); - rc = wcmSanityCheckProperty(prop); + rc = wcmCheckActionProperty(property, prop); if (rc != Success) return rc; - i = wcmFindProp(property, priv->btn_actions, ARRAY_SIZE(priv->btn_actions)); - if (i >= 0) + if (!checkonly && prop) { - if (!checkonly) - { - XIGetDeviceProperty(dev, prop_btnactions, &prop); - wcmUpdateButtonKeyActions(dev, prop, priv->keys, ARRAY_SIZE(priv->keys)); - } - } else - { - i = wcmFindProp(property, priv->wheel_actions, - ARRAY_SIZE(priv->wheel_actions)); - if (i >= 0) { - if (!checkonly) - { - XIGetDeviceProperty(dev, prop_wheel_buttons, &prop); - wcmUpdateButtonKeyActions(dev, prop, - priv->wheel_keys, - ARRAY_SIZE(priv->wheel_keys)); - } - } else - { - i = wcmFindProp(property, priv->strip_actions, ARRAY_SIZE(priv->strip_actions)); - if (i >= 0 && !checkonly) - { - XIGetDeviceProperty(dev, prop_strip_buttons, &prop); - wcmUpdateButtonKeyActions(dev, prop, priv->strip_keys, ARRAY_SIZE(priv->strip_keys)); - } - } + memset(action, 0, sizeof(action)); + for (i = 0; i < prop->size; i++) + (*action)[i] = ((unsigned int*)prop->data)[i]; + *handler = property; } - return abs(i); + return Success; } -static int wcmCheckActionProp(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop) +static int wcmCheckActionsProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop) { InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate; XIPropertyValuePtr val; Atom *values = (Atom*)prop->data; int i; + if (prop->format != 32 || prop->type != XA_ATOM) + return BadMatch; + for (i = 0; i < prop->size; i++) { if (!values[i]) @@ -416,119 +413,50 @@ static int wcmCheckActionProp(DeviceIntPtr dev, Atom property, XIPropertyValuePt return Success; } -/* Change the property that refers to which properties the actual button - * actions are stored in */ -static int wcmSetPropertyButtonActions(DeviceIntPtr dev, Atom property, - XIPropertyValuePtr prop, BOOL checkonly) +/** + * An 'Actions' property (such as "Wacom Button Actions") stores a list of + * 'Action' properties that define an action to be performed. This function + * goes through the list of actions and saves each one. + * + * @param dev The device being modified + * @param property The Actions property being set + * @param prop The data contained in 'property' + * @param checkonly 'true' if the property should only be checked for validity + * @param size Expected number of elements in 'prop' + * @param handlers List of handlers that must be updated + * @param actions List of actions that must be updated + */ +static int wcmSetActionsProperty(DeviceIntPtr dev, Atom property, + XIPropertyValuePtr prop, BOOL checkonly, + int size, Atom* handlers, unsigned int (*actions)[256]) { InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate; - WacomDevicePtr priv = (WacomDevicePtr) pInfo->private; int rc; - DBG(10, priv, "\n"); - - if (prop->format != 32 || prop->type != XA_ATOM) - return BadMatch; - - /* How this works: - * prop_btnactions has a list of atoms stored. Any atom references - * another property on that device that contains the actual action. - * If this property changes, all action-properties are queried for - * their value and their value is stored in priv->key[button]. - * - * If the button is pressed, the actions are executed. - * - * Any button action property needs to be monitored by this property - * handler too. - */ - - rc = wcmCheckActionProp(dev, property, prop); - if (rc != Success) - return rc; - - if (!checkonly) - { - wcmUpdateActionPropHandlers(prop, priv->btn_actions); - wcmUpdateButtonKeyActions(dev, prop, priv->keys, ARRAY_SIZE(priv->keys)); - - } - return Success; -} - -struct wheel_strip_update_t { - /* for CARD32 values, points to atom array of atoms to be - * monitored.*/ - Atom *handlers; - /* for CARD32 values, points to key array that keeps the actual - actions.*/ - int skeys; /* size of first keys dimensions */ - unsigned int (*keys)[256]; -}; - -static int wcmSetWheelOrStripProperty(DeviceIntPtr dev, Atom property, - XIPropertyValuePtr prop, BOOL checkonly, - struct wheel_strip_update_t *wsup) -{ - int rc; - - if ((property == prop_strip_buttons && prop->size != 4) || - (property == prop_wheel_buttons && prop->size != 6)) + if (prop->size != size) return BadValue; - /* see wcmSetPropertyButtonActions for how this works. */ - switch (prop->format) + rc = wcmCheckActionsProperty(dev, property, prop); + if (rc != Success) + return rc; + + if (!checkonly) { - case 32: - rc = wcmCheckActionProp(dev, property, prop); - if (rc != Success) - return rc; + int i; - if (!checkonly) - { - wcmUpdateActionPropHandlers(prop, wsup->handlers); - wcmUpdateButtonKeyActions(dev, prop, wsup->keys, - wsup->skeys); - } + for (i = 0; i < prop->size; i++) + { + Atom subproperty = ((Atom*)prop->data)[i]; + XIPropertyValuePtr subprop; - break; - default: - return BadMatch; + XIGetDeviceProperty(dev, subproperty, &subprop); + wcmSetActionProperty(dev, subproperty, subprop, checkonly, &handlers[i], &actions[i]); + } } return Success; } - -static int wcmSetWheelProperty(DeviceIntPtr dev, Atom property, - XIPropertyValuePtr prop, BOOL checkonly) -{ - InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate; - WacomDevicePtr priv = (WacomDevicePtr) pInfo->private; - - struct wheel_strip_update_t wsup = { - .handlers = priv->wheel_actions, - .keys = priv->wheel_keys, - .skeys = 6, - }; - - return wcmSetWheelOrStripProperty(dev, property, prop, checkonly, &wsup); -} - -static int wcmSetStripProperty(DeviceIntPtr dev, Atom property, - XIPropertyValuePtr prop, BOOL checkonly) -{ - InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate; - WacomDevicePtr priv = (WacomDevicePtr) pInfo->private; - - struct wheel_strip_update_t wsup = { - .handlers = priv->strip_actions, - .keys = priv->strip_keys, - .skeys = 4, - }; - - return wcmSetWheelOrStripProperty(dev, property, prop, checkonly, &wsup); -} - /** * Update the rotation property for all tools on the same physical tablet as * pInfo. @@ -688,9 +616,9 @@ int wcmSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, wcmBindToSerial(pInfo, serial); } } else if (property == prop_strip_buttons) - return wcmSetStripProperty(dev, property, prop, checkonly); + return wcmSetActionsProperty(dev, property, prop, checkonly, ARRAY_SIZE(priv->strip_actions), priv->strip_actions, priv->strip_keys); else if (property == prop_wheel_buttons) - return wcmSetWheelProperty(dev, property, prop, checkonly); + return wcmSetActionsProperty(dev, property, prop, checkonly, ARRAY_SIZE(priv->wheel_actions), priv->wheel_actions, priv->wheel_keys); else if (property == prop_cursorprox) { CARD32 value; @@ -802,11 +730,16 @@ int wcmSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, } else if (property == prop_btnactions) { int nbuttons = min(max(priv->nbuttons + 4, 7), WCM_MAX_BUTTONS); - if (prop->size != nbuttons) - return BadMatch; - wcmSetPropertyButtonActions(dev, property, prop, checkonly); + return wcmSetActionsProperty(dev, property, prop, checkonly, nbuttons, priv->btn_actions, priv->keys); } else - wcmSetActionProperties(dev, property, prop, checkonly); + { + Atom *handler = NULL; + unsigned int (*action)[256] = NULL; + wcmFindActionHandler(priv, property, &handler, &action); + if (handler != NULL && action != NULL) + wcmSetActionProperty(dev, property, prop, checkonly, handler, action); + /* backwards-compatible behavior silently ignores the not-found case */ + } return Success; } -- 1.7.11.1 ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel