summaryrefslogtreecommitdiff
path: root/src/xf86Wacom.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xf86Wacom.c')
-rw-r--r--src/xf86Wacom.c153
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
****************************************************************************/