summaryrefslogtreecommitdiff
path: root/xserver/hw/xfree86/common/xf86Xinput.c
diff options
context:
space:
mode:
Diffstat (limited to 'xserver/hw/xfree86/common/xf86Xinput.c')
-rw-r--r--xserver/hw/xfree86/common/xf86Xinput.c110
1 files changed, 97 insertions, 13 deletions
diff --git a/xserver/hw/xfree86/common/xf86Xinput.c b/xserver/hw/xfree86/common/xf86Xinput.c
index 4b588a741..4e8060b0f 100644
--- a/xserver/hw/xfree86/common/xf86Xinput.c
+++ b/xserver/hw/xfree86/common/xf86Xinput.c
@@ -1,6 +1,6 @@
/*
* Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
- *
+ *
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
@@ -9,8 +9,8 @@
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Frederic Lepied makes no
* representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
+ * is provided "as is" without express or implied warranty.
+ *
* FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -63,6 +63,7 @@
#include "mipointer.h"
#include "extinit.h"
#include "loaderProcs.h"
+#include "systemd-logind.h"
#include "exevents.h" /* AddInputDevice */
#include "exglobals.h"
@@ -80,6 +81,12 @@
#include <stdarg.h>
#include <stdint.h> /* for int64_t */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_MKDEV_H
+#include <sys/mkdev.h> /* for major() & minor() on Solaris */
+#endif
#include "mi.h"
@@ -103,11 +110,14 @@
static int
xf86InputDevicePostInit(DeviceIntPtr dev);
+static InputInfoPtr *new_input_devices;
+static int new_input_devices_count;
+
/**
* Eval config and modify DeviceVelocityRec accordingly
*/
static void
-ProcessVelocityConfiguration(DeviceIntPtr pDev, char *devname, pointer list,
+ProcessVelocityConfiguration(DeviceIntPtr pDev, const char *devname, void *list,
DeviceVelocityPtr s)
{
int tempi;
@@ -305,7 +315,7 @@ ApplyTransformationMatrix(DeviceIntPtr dev)
/***********************************************************************
*
* xf86ProcessCommonOptions --
- *
+ *
* Process global options.
*
***********************************************************************
@@ -661,7 +671,7 @@ MergeInputClasses(const InputInfoPtr idev, const InputAttributes * attrs)
/* Collect class options and driver settings */
classopts = xf86optionListDup(cl->option_lst);
if (cl->driver) {
- free(idev->driver);
+ free((void *) idev->driver);
idev->driver = xstrdup(cl->driver);
if (!idev->driver) {
xf86Msg(X_ERROR, "Failed to allocate memory while merging "
@@ -760,6 +770,9 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
FreeInputAttributes(pInp->attrs);
+ if (pInp->flags & XI86_SERVER_FD)
+ systemd_logind_release_fd(pInp->major, pInp->minor, pInp->fd);
+
/* Remove the entry from the list. */
if (pInp == xf86InputDevs)
xf86InputDevs = pInp->next;
@@ -773,8 +786,8 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
/* Else the entry wasn't in the xf86InputDevs list (ignore this). */
}
- free(pInp->driver);
- free(pInp->name);
+ free((void *) pInp->driver);
+ free((void *) pInp->name);
xf86optionListFree(pInp->options);
free(pInp);
}
@@ -794,6 +807,18 @@ xf86InputDevicePostInit(DeviceIntPtr dev)
return Success;
}
+static void
+xf86stat(const char *path, int *maj, int *min)
+{
+ struct stat st;
+
+ if (stat(path, &st) == -1)
+ return;
+
+ *maj = major(st.st_rdev);
+ *min = minor(st.st_rdev);
+}
+
/**
* Create a new input device, activate and enable it.
*
@@ -816,7 +841,9 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
{
InputDriverPtr drv = NULL;
DeviceIntPtr dev = NULL;
+ Bool paused;
int rval;
+ const char *path;
/* Memory leak for every attached device if we don't
* test if the module is already loaded first */
@@ -830,6 +857,29 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
goto unwind;
}
+ path = xf86CheckStrOption(pInfo->options, "Device", NULL);
+ if (path && pInfo->major == 0 && pInfo->minor == 0)
+ xf86stat(path, &pInfo->major, &pInfo->minor);
+
+ if (path && (drv->capabilities & XI86_DRV_CAP_SERVER_FD)){
+ int fd = systemd_logind_take_fd(pInfo->major, pInfo->minor,
+ path, &paused);
+ if (fd != -1) {
+ if (paused) {
+ /* Put on new_input_devices list for delayed probe */
+ new_input_devices = xnfrealloc(new_input_devices,
+ sizeof(pInfo) * (new_input_devices_count + 1));
+ new_input_devices[new_input_devices_count] = pInfo;
+ new_input_devices_count++;
+ systemd_logind_release_fd(pInfo->major, pInfo->minor, fd);
+ return BadMatch;
+ }
+ pInfo->fd = fd;
+ pInfo->flags |= XI86_SERVER_FD;
+ pInfo->options = xf86ReplaceIntOption(pInfo->options, "fd", fd);
+ }
+ }
+
xf86Msg(X_INFO, "Using input driver '%s' for '%s'\n", drv->driverName,
pInfo->name);
@@ -949,6 +999,12 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
goto unwind;
}
}
+
+ if (strcmp(key, "major") == 0)
+ pInfo->major = atoi(value);
+
+ if (strcmp(key, "minor") == 0)
+ pInfo->minor = atoi(value);
}
nt_list_for_each_entry(option, options, list.next) {
@@ -1021,7 +1077,7 @@ DeleteInputDeviceRequest(DeviceIntPtr pDev)
OsReleaseSignals();
}
-/*
+/*
* convenient functions to post events
*/
@@ -1067,7 +1123,7 @@ xf86CheckMotionEvent4DGA(DeviceIntPtr device, int is_absolute,
#if XFreeXDGA
ScreenPtr scr = NULL;
- int idx, i;
+ int idx = 0, i;
/* The evdev driver may not always send all axes across. */
if (valuator_mask_isset(mask, 0) || valuator_mask_isset(mask, 1)) {
@@ -1345,7 +1401,7 @@ xf86FirstLocalDevice(void)
return xf86InputDevs;
}
-/*
+/*
* Cx - raw data from touch screen
* to_max - scaled highest dimension
* (remember, this is of rows - 1 because of 0 origin)
@@ -1419,7 +1475,7 @@ xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
* Device will be moved to the off_devices list, but it will still be there
* until you really clean up after it.
* Notifies the client about an inactive device.
- *
+ *
* @param panic True if device is unrecoverable and needs to be removed.
*/
void
@@ -1437,7 +1493,7 @@ xf86DisableDevice(DeviceIntPtr dev, Bool panic)
/**
* Reactivate a device. Call this function from the driver if you just found
* out that the read error wasn't quite that bad after all.
- * Device will be re-activated, and an event sent to the client.
+ * Device will be re-activated, and an event sent to the client.
*/
void
xf86EnableDevice(DeviceIntPtr dev)
@@ -1469,4 +1525,32 @@ xf86PostTouchEvent(DeviceIntPtr dev, uint32_t touchid, uint16_t type,
QueueTouchEvents(dev, type, touchid, flags, mask);
}
+void
+xf86InputEnableVTProbe(void)
+{
+ int i, is_auto = 0;
+ InputOption *option = NULL;
+ DeviceIntPtr pdev;
+
+ for (i = 0; i < new_input_devices_count; i++) {
+ InputInfoPtr pInfo = new_input_devices[i];
+
+ is_auto = 0;
+ nt_list_for_each_entry(option, pInfo->options, list.next) {
+ const char *key = input_option_get_key(option);
+ const char *value = input_option_get_value(option);
+
+ if (strcmp(key, "_source") == 0 &&
+ (strcmp(value, "server/hal") == 0 ||
+ strcmp(value, "server/udev") == 0 ||
+ strcmp(value, "server/wscons") == 0))
+ is_auto = 1;
+ }
+ xf86NewInputDevice(pInfo, &pdev,
+ (!is_auto ||
+ (is_auto && xf86Info.autoEnableDevices)));
+ }
+ new_input_devices_count = 0;
+}
+
/* end of xf86Xinput.c */