[PATCH RFC 3/5] kdrive: introduce input hotplugging support (udev backend provided) (#33140)

Laércio de Sousa laerciosousa at sme-mogidascruzes.sp.gov.br
Wed Mar 25 11:31:39 PDT 2015


This patch introduces a command-line option -input-hotplug for kdrive-based
applications, which can be used to enable input hotplugging support, instead
of passing explicit -keybd and/or -mouse options.

It also includes udev backend implementation for input hotplugging support.
Another patches are required for hal or wscons backends.

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=33140

Signed-off-by: Laércio de Sousa <laerciosousa at sme-mogidascruzes.sp.gov.br>
---
 hw/kdrive/src/Makefile.am |  2 ++
 hw/kdrive/src/kdrive.c    | 41 ++++++++++++++++++++++++++
 hw/kdrive/src/kinput.c    | 75 +++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 112 insertions(+), 6 deletions(-)

diff --git a/hw/kdrive/src/Makefile.am b/hw/kdrive/src/Makefile.am
index d69f0dd..f446f1a 100644
--- a/hw/kdrive/src/Makefile.am
+++ b/hw/kdrive/src/Makefile.am
@@ -23,3 +23,5 @@ libkdrive_la_SOURCES =	\
 	kshadow.c	\
 	$(KDRIVE_XV_SOURCES) \
         $(top_srcdir)/mi/miinitext.c
+
+libkdrive_la_LIBADD = $(top_builddir)/config/libconfig.la
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index dddbe6e..1ed5a46 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -44,6 +44,7 @@
 #endif
 
 #include <signal.h>
+#include <hotplug.h>
 
 typedef struct _kdDepths {
     CARD8 depth;
@@ -81,6 +82,7 @@ char *kdSwitchCmd;
 DDXPointRec kdOrigin;
 Bool kdHasPointer = FALSE;
 Bool kdHasKbd = FALSE;
+Bool kdEnableInputHotplugging = FALSE;
 
 static Bool kdCaughtSignal = FALSE;
 
@@ -444,6 +446,8 @@ KdUseMsg(void)
     ErrorF
         ("-rgba rgb/bgr/vrgb/vbgr/none   Specify subpixel ordering for LCD panels\n");
     ErrorF
+        ("-input-hotplug                 Enable input device hotplugging support\n");
+    ErrorF
         ("-mouse driver [,n,,options]    Specify the pointer driver and its options (n is the number of buttons)\n");
     ErrorF
         ("-keybd driver [,,options]      Specify the keyboard driver and its options\n");
@@ -555,6 +559,10 @@ KdProcessArgument(int argc, char **argv, int i)
         sscanf(argv[i], "vt%2d", &kdVirtualTerminal) == 1) {
         return 1;
     }
+    if (!strcmp(argv[i], "-input-hotplug")) {
+        kdEnableInputHotplugging = TRUE;
+        return 1;
+    }
     if (!strcmp(argv[i], "-mouse") || !strcmp(argv[i], "-pointer")) {
         if (i + 1 >= argc)
             UseMsg();
@@ -1125,6 +1133,9 @@ KdInitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
             KdAddScreen(pScreenInfo, screen, argc, argv);
 
     OsRegisterSigWrapper(KdSignalWrapper);
+
+    if (kdEnableInputHotplugging)
+        config_pre_init();
 }
 
 void
@@ -1143,3 +1154,33 @@ DPMSSupported(void)
 {
     return FALSE;
 }
+
+/* These stubs can be safely removed once we can
+ * split input and GPU parts in hotplug.h et al. */
+#ifdef CONFIG_UDEV
+void
+NewGPUDeviceRequest(struct OdevAttributes *attribs)
+{
+}
+
+void
+DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
+{
+}
+#endif
+
+struct xf86_platform_device *
+xf86_find_platform_device_by_devnum(int major, int minor)
+{
+    return NULL;
+}
+
+void
+systemd_logind_release_fd(int _major, int _minor, int fd)
+{
+}
+
+void
+systemd_logind_vtenter(void)
+{
+}
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 057f53b..e2b65df 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -50,6 +50,11 @@
 #include "xserver-properties.h"
 #include "inpututils.h"
 #include "optionstr.h"
+#include <hotplug.h>
+
+#ifdef KDRIVE_EVDEV
+#define DEV_INPUT_EVENT_PREFIX "/dev/input/event"
+#endif
 
 #define AtomFromName(x) MakeAtom(x, strlen(x), 1)
 
@@ -92,6 +97,7 @@ static KdInputFd kdInputFds[KD_MAX_INPUT_FDS];
 static int kdNumInputFds;
 
 extern Bool kdRawPointerCoordinates;
+extern Bool kdEnableInputHotplugging;
 
 static void
 KdSigio(int sig)
@@ -391,7 +397,8 @@ KdPointerProc(DeviceIntPtr pDevice, int onoff)
 #endif
         if (!pi->driver) {
             if (!pi->driverPrivate) {
-                ErrorF("no driver specified for %s\n", pi->name);
+                ErrorF("no driver specified for pointer device \"%s\" (%s)\n",
+                       pi->name ? pi->name : "(unnamed)", pi->path);
                 return BadImplementation;
             }
 
@@ -711,7 +718,8 @@ KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
 #endif
         if (!ki->driver) {
             if (!ki->driverPrivate) {
-                ErrorF("no driver specified!\n");
+                ErrorF("no driver specified for keyboard device \"%s\" (%s)\n",
+                       ki->name ? ki->name : "(unnamed)", ki->path);
                 return BadImplementation;
             }
 
@@ -1280,11 +1288,17 @@ KdInitInput(void)
     }
 
     mieqInit();
+
+    if (kdEnableInputHotplugging)
+        config_init();
 }
 
 void
 KdCloseInput(void)
 {
+    if (kdEnableInputHotplugging)
+        config_fini();
+
     mieqFini();
 }
 
@@ -2181,9 +2195,33 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
 #ifdef CONFIG_UDEV
         else if (strcmp(key, "_source") == 0 &&
                  strcmp(value, "server/udev") == 0) {
-            ErrorF("Ignoring device from udev.\n");
-            return BadValue;
+            if (kdEnableInputHotplugging) {
+                if (attrs->flags & ATTR_POINTER) {
+                    pi = KdNewPointer();
+                    if (!pi)
+                        return BadAlloc;
+                }
+                else if (attrs->flags & ATTR_KEYBOARD) {
+                    ki = KdNewKeyboard();
+                    if (!ki)
+                        return BadAlloc;
+                }
+            }
+            else {
+                ErrorF("Ignoring device from udev.\n");
+                return BadValue;
+            }
         }
+#ifdef KDRIVE_EVDEV
+        else if (strcmp(key, "device") == 0) {
+            if (kdEnableInputHotplugging && value &&
+                strncmp(value,
+                        DEV_INPUT_EVENT_PREFIX,
+                        sizeof(DEV_INPUT_EVENT_PREFIX) - 1) == 0) {
+                options = input_option_new(options, "driver", "evdev");
+            }
+        }
+#endif
 #endif
     }
 
@@ -2224,13 +2262,35 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
                 ki->options = options;
             }
         }
+#ifdef CONFIG_UDEV
+        else if (strcmp(key, "xkb_rules") == 0) {
+            if (ki && value)
+                ki->xkbRules = strdup(value);
+        }
+        else if (strcmp(key, "xkb_model") == 0) {
+            if (ki && value)
+                ki->xkbModel = strdup(value);
+        }
+        else if (strcmp(key, "xkb_layout") == 0) {
+            if (ki && value)
+                ki->xkbLayout = strdup(value);
+        }
+        else if (strcmp(key, "xkb_variant") == 0) {
+            if (ki && value)
+                ki->xkbVariant = strdup(value);
+        }
+        else if (strcmp(key, "xkb_options") == 0) {
+            if (ki && value)
+                ki->xkbOptions = strdup(value);
+        }
+#endif
     }
 
     if (pi) {
         if (KdAddPointer(pi) != Success ||
             ActivateDevice(pi->dixdev, TRUE) != Success ||
             EnableDevice(pi->dixdev, TRUE) != TRUE) {
-            ErrorF("couldn't add or enable pointer\n");
+            ErrorF("couldn't add or enable pointer %s\n", pi->path);
             return BadImplementation;
         }
     }
@@ -2238,7 +2298,7 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
         if (KdAddKeyboard(ki) != Success ||
             ActivateDevice(ki->dixdev, TRUE) != Success ||
             EnableDevice(ki->dixdev, TRUE) != TRUE) {
-            ErrorF("couldn't add or enable keyboard\n");
+            ErrorF("couldn't add or enable keyboard %s\n", ki->path);
             return BadImplementation;
         }
     }
@@ -2256,5 +2316,8 @@ NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
 void
 DeleteInputDeviceRequest(DeviceIntPtr pDev)
 {
+    /* XXX: fix potential memory leaks when unplugging pointer devices */
+    OsBlockSignals();
     RemoveDevice(pDev, TRUE);
+    OsReleaseSignals();
 }
-- 
2.2.0



More information about the xorg-devel mailing list