[PATCH evdev 5/7] Handling the creation / destruction of mt subdevices by the property "Evdev MultiTouch"
Benjamin Tissoires
tissoire at cena.fr
Sat Dec 19 03:34:48 PST 2009
Signed-off-by: Benjamin Tissoires <tissoire at cena.fr>
---
src/evdev.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 167 insertions(+), 2 deletions(-)
diff --git a/src/evdev.c b/src/evdev.c
index fb5c5c9..3722a1c 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -118,6 +118,7 @@ static const char *evdevDefaults[] = {
static int EvdevOn(DeviceIntPtr);
static int EvdevCacheCompare(InputInfoPtr pInfo, BOOL compare);
static void EvdevKbdCtrl(DeviceIntPtr device, KeybdCtrl *ctrl);
+static void EvdevSetMultitouch(InputInfoPtr pInfo, int num_multitouch);
#ifdef HAVE_PROPERTIES
static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms);
@@ -131,8 +132,11 @@ static Atom prop_swap = 0;
static Atom prop_axis_label = 0;
static Atom prop_btn_label = 0;
static Atom prop_tracking_id = 0;
+static Atom prop_multitouch = 0;
#endif
+static InputInfoPtr pCreatorInfo = NULL;
+
/* All devices the evdev driver has allocated and knows about.
* MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK)
* cannot be used by evdev, leaving us with a space of 2 at the end. */
@@ -1583,6 +1587,7 @@ EvdevOn(DeviceIntPtr device)
}
xf86FlushInput(pInfo->fd);
+ EvdevSetMultitouch(pInfo, pEvdev->num_multitouch);
xf86AddEnabledDevice(pInfo);
EvdevMBEmuOn(pInfo);
pEvdev->flags |= EVDEV_INITIALIZED;
@@ -1616,6 +1621,7 @@ EvdevProc(DeviceIntPtr device, int what)
if (pEvdev->flags & EVDEV_INITIALIZED)
EvdevMBEmuFinalize(pInfo);
if (EvdevIsCoreDevice(pInfo)){
+ EvdevSetMultitouch(pInfo, 0);
if (pInfo->fd != -1)
{
if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
@@ -2045,6 +2051,7 @@ static InputInfoPtr
EvdevSubdevPreInit(InputInfoPtr pInfo, InputDriverPtr drv, IDevPtr dev, int flags)
{
EvdevPtr pEvdev;
+ EvdevPtr pCreatorEvdev;
/* Initialise the InputInfoRec. */
pInfo->name = dev->identifier;
@@ -2072,9 +2079,14 @@ EvdevSubdevPreInit(InputInfoPtr pInfo, InputDriverPtr drv, IDevPtr dev, int flag
xf86ProcessCommonOptions(pInfo, pInfo->options);
pEvdev->id = -1;
+ if (!pCreatorInfo){
+ return pInfo;
+ }
+ pCreatorEvdev = pCreatorInfo->private;
+ memcpy(pEvdev, pCreatorEvdev, sizeof(EvdevRec));
+ pInfo->type_name = pCreatorInfo->type_name;
xf86Msg(X_INFO, "%s: Evdev subdevice found\n", dev->identifier);
- // FIXME: need to duplicate the parent device
-
+
pInfo->flags |= XI86_CONFIGURED;
pEvdev->num_multitouch = 1;
@@ -2624,6 +2636,17 @@ EvdevInitProperty(DeviceIntPtr dev)
return;
XISetDevicePropertyDeletable(dev, prop_tracking_id, FALSE);
+
+ /* The number of multitouch subdevices.
+ * If 0, we emulate a touchscreen. */
+ prop_multitouch = MakeAtom(EVDEV_PROP_MULTITOUCH_SUBDEVICES,
+ strlen(EVDEV_PROP_MULTITOUCH_SUBDEVICES), TRUE);
+ rc = XIChangeDeviceProperty(dev, prop_multitouch, XA_INTEGER, 8,
+ PropModeReplace, 1, &pEvdev->num_multitouch, FALSE);
+ if (rc != Success)
+ return;
+
+ XISetDevicePropertyDeletable(dev, prop_multitouch, FALSE);
}
#ifdef HAVE_LABELS
@@ -2694,8 +2717,150 @@ EvdevSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
if (!checkonly)
pEvdev->id = *((int*)val->data);
+ } else if (atom == prop_multitouch)
+ {
+ BOOL data;
+ if (val->format != 8 || val->type != XA_INTEGER || val->size != 1)
+ return BadMatch;
+ if (!checkonly) {
+ data = *((BOOL*)val->data);
+ if (pEvdev->num_multitouch != data)
+ EvdevSetMultitouch(pInfo,data);
+ }
}
return Success;
}
#endif
+
+/* Duplicate xf86 options and convert them to InputOption */
+static InputOption *EvdevOptionDupConvert(pointer original)
+{
+ InputOption *iopts = NULL, *new;
+ InputInfoRec dummy;
+
+
+ memset(&dummy, 0, sizeof(dummy));
+ xf86CollectInputOptions(&dummy, NULL, original);
+
+ while(dummy.options)
+ {
+ new = xcalloc(1, sizeof(InputOption));
+
+ new->key = xf86OptionName(dummy.options);
+ new->value = xf86OptionValue(dummy.options);
+
+ new->next = iopts;
+ iopts = new;
+ dummy.options = xf86NextOption(dummy.options);
+ }
+ return iopts;
+}
+static void EvdevFreeInputOpts(InputOption* opts)
+{
+ InputOption *tmp = opts;
+
+ while(opts)
+ {
+ tmp = opts->next;
+ xfree(opts->key);
+ xfree(opts->value);
+ xfree(opts);
+ opts = tmp;
+ }
+}
+static void EvdevReplaceOption(InputOption *opts,const char* key, char * value)
+{
+
+ while(opts)
+ {
+ if (xf86NameCmp(opts->key, key) == 0)
+ {
+
+ xfree(opts->value);
+ opts->value = strdup(value);
+ }
+ opts = opts->next;
+ }
+}
+
+/**
+ * New device creation through xorg/input
+ *
+ * @return 0 if successful, 1 if failure
+ */
+static InputInfoPtr
+EvdevCreateSubDevice(InputInfoPtr pInfo, int id) {
+ InputInfoPtr pSubdev;
+
+ DeviceIntPtr dev; /* dummy */
+ InputOption *input_options = NULL;
+ char* name;
+
+
+ pInfo->options = xf86AddNewOption(pInfo->options, "Type", "core");
+ pInfo->options = xf86AddNewOption(pInfo->options, "SendCoreEvents", "on");
+
+ /* Create new device */
+
+ input_options = EvdevOptionDupConvert(pInfo->options);
+
+ EvdevReplaceOption(input_options, "type","Object");
+
+ //EvdevReplaceOption(input_options, "SendCoreEvents","off"); //FIXME: bug in xserver
+ name = xalloc( (strlen(pInfo->name) + strlen(" subdev ") + 20 )*sizeof(char)); // 20 for adding the id
+ sprintf(name, "%s subdev %i", pInfo->name, id);
+ EvdevReplaceOption(input_options, "name",name);
+
+ pCreatorInfo = pInfo;
+ NewInputDeviceRequest(input_options, &dev);
+ pSubdev = dev->public.devicePrivate;
+ pCreatorInfo = NULL;
+
+ EvdevFreeInputOpts(input_options);
+
+ xfree(name);
+ return pSubdev;
+}
+static void
+EvdevDeleteSubDevice(InputInfoPtr pInfo, InputInfoPtr subdev) {
+ /* We need to explicitely flush the events so as not deleting
+ * a device that still has events in queue
+ */
+ ProcessInputEvents();
+ xf86Msg(X_INFO, "%s: Removing subdevice %s\n", pInfo->name,subdev->name);
+ DeleteInputDeviceRequest(subdev->dev);
+}
+
+/*
+ * Handle the creation/destruction of subdevices
+ * according to pEvdev->num_multitouch.
+ */
+static void
+EvdevSetMultitouch(InputInfoPtr pInfo, int num_multitouch) {
+ EvdevPtr pEvdev = pInfo->private;
+ int i;
+
+ if (num_multitouch > MAX_VALUATORS_MT)
+ num_multitouch = MAX_VALUATORS_MT;
+ if (num_multitouch < 0)
+ num_multitouch = 0;
+
+ for (i=0;i<num_multitouch;++i) {
+ if (pEvdev->vals_mt[i].pInfo == NULL){
+ pEvdev->vals_mt[i].containsValues = FALSE;
+ pEvdev->vals_mt[i].id = -1;
+ pEvdev->vals_mt[i].pInfo = EvdevCreateSubDevice(pInfo, i);
+ }
+ }
+ for (i=num_multitouch;i<MAX_VALUATORS_MT;++i) {
+ pEvdev->vals_mt[i].containsValues = FALSE;
+ pEvdev->vals_mt[i].id = -1;
+ if (pEvdev->vals_mt[i].pInfo) {
+ EvdevDeleteSubDevice(pInfo, pEvdev->vals_mt[i].pInfo);
+ pEvdev->vals_mt[i].pInfo = NULL;
+ }
+ }
+
+ pEvdev->num_multitouch = num_multitouch;
+}
--
1.6.5.2
--------------090208080606020807080800
Content-Type: text/x-patch;
name="0006-Process-of-MT-events.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="0006-Process-of-MT-events.patch"
More information about the xorg-devel
mailing list