diff options
Diffstat (limited to 'src/xf86Wacom.c')
-rw-r--r-- | src/xf86Wacom.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/src/xf86Wacom.c b/src/xf86Wacom.c index 41e5995..95c94fd 100644 --- a/src/xf86Wacom.c +++ b/src/xf86Wacom.c @@ -167,6 +167,159 @@ void wcmTimerSet(WacomTimerPtr timer, uint32_t millis, WacomTimerCallback func, TimerSet(timer->timer, flags, millis, xserverTimerFunc, timer); } + +/** + * Duplicate xf86 options, replace the "type" option with the given type + * (and the name with "$name $type" and convert them to InputOption + * + * @param basename Kernel device name for this device + * @param type Tool type (cursor, eraser, etc.) + * @param serial Serial number this device should be bound to (-1 for "any") + */ +static InputOption *wcmOptionDupConvert(WacomDevicePtr priv, const char* basename, const char *type, int serial) +{ + WacomCommonPtr common = priv->common; + InputInfoPtr pInfo = priv->pInfo; + pointer original = pInfo->options; + WacomToolPtr ser = common->serials; + InputOption *iopts = NULL; + char *name; + pointer options, o; + int rc; + + options = xf86OptionListDuplicate(original); + if (serial > -1) + { + while (ser->serial && ser->serial != serial) + ser = ser->next; + + if (strlen(ser->name) > 0) + rc = asprintf(&name, "%s %s %s", basename, ser->name, type); + else + rc = asprintf(&name, "%s %d %s", basename, ser->serial, type); + } + else + rc = asprintf(&name, "%s %s", basename, type); + + if (rc == -1) /* if asprintf fails, strdup will probably too... */ + name = strdup("unknown"); + + options = xf86ReplaceStrOption(options, "Type", type); + options = xf86ReplaceStrOption(options, "Name", name); + + if (serial > -1) + options = xf86ReplaceIntOption(options, "Serial", ser->serial); + + free(name); + + o = options; + while(o) + { + iopts = input_option_new(iopts, + xf86OptionName(o), + xf86OptionValue(o)); + o = xf86NextOption(o); + } + xf86OptionListFree(options); + return iopts; +} + +/** + * Duplicate the attributes of the given device. "product" gets the type + * appended, so a device of product "Wacom" will then have a product "Wacom + * eraser", "Wacom cursor", etc. + */ +static InputAttributes* wcmDuplicateAttributes(WacomDevicePtr priv, + const char *type) +{ + InputInfoPtr pInfo = priv->pInfo; + int rc; + InputAttributes *attr; + char *product; + + attr = DuplicateInputAttributes(pInfo->attrs); + rc = asprintf(&product, "%s %s", attr->product, type); + free(attr->product); + attr->product = (rc != -1) ? product : NULL; + return attr; +} + +/** + * This struct contains the necessary info for hotplugging a device later. + * Memory must be freed after use. + */ +typedef struct { + InputOption *input_options; + InputAttributes *attrs; +} WacomHotplugInfo; + +/** + * Actually hotplug the device. This function is called by the server when + * the WorkProcs are processed. + * + * @param client The server client. unused + * @param closure A pointer to a struct WcmHotplugInfo containing the + * necessary information to create a new device. + * @return TRUE to remove this function from the server's work queue. + */ +static Bool +wcmHotplugDevice(ClientPtr client, pointer closure ) +{ + WacomHotplugInfo *hotplug_info = closure; + DeviceIntPtr dev; /* dummy */ + +#if HAVE_THREADED_INPUT + input_lock(); +#endif + + NewInputDeviceRequest(hotplug_info->input_options, + hotplug_info->attrs, + &dev); +#if HAVE_THREADED_INPUT + input_unlock(); +#endif + + input_option_free_list(&hotplug_info->input_options); + + FreeInputAttributes(hotplug_info->attrs); + free(hotplug_info); + + return TRUE; +} + +/** + * Queue the hotplug for one tool/device of the given type. + * Device has the same options as the "parent" device, type is one of + * erasor, stylus, pad, touch, cursor, etc. + * Name of the new device is set automatically to "<device name> <type>". + * + * Note that we don't actually hotplug the device here. We store the + * information needed to hotplug the device later and then queue the + * hotplug. The server will come back and call the @ref wcmHotplugDevice + * later. + * + * @param priv The parent device + * @param basename The base name for the device (type will be appended) + * @param type Type name for this tool + * @param serial Serial number this device should be bound to (-1 for "any") + */ +void wcmQueueHotplug(WacomDevicePtr priv, const char* basename, const char *type, int serial) +{ + WacomHotplugInfo *hotplug_info; + + hotplug_info = calloc(1, sizeof(WacomHotplugInfo)); + + if (!hotplug_info) + { + wcmLog(priv, W_ERROR, "OOM, cannot hotplug dependent devices\n"); + return; + } + + hotplug_info->input_options = wcmOptionDupConvert(priv, basename, type, serial); + hotplug_info->attrs = wcmDuplicateAttributes(priv, type); + QueueWorkProc(wcmHotplugDevice, serverClient, hotplug_info); +} + /***************************************************************************** * Event helpers ****************************************************************************/ |