[PATCH] Evdev input on Xglx
Tiago Vignatti
tv02 at c3sl.ufpr.br
Tue Apr 11 11:33:12 PDT 2006
This one adds the evdev input on Xglx. I don't know if it is a "feature
bloat", but it really helps to make nested multiseat systems with 3D and xv
support.
--
Tiago Vignatti
C3SL - Centro de Computação Científica e Software Livre
www.c3sl.ufpr.br
-------------- next part --------------
diff -u --exclude=Makefile --exclude='*.Plo' --exclude='*.in' --recursive --new-file xgl.orig/glx/evdev.c xgl/glx/evdev.c
--- xgl.orig/glx/evdev.c 1969-12-31 21:00:00.000000000 -0300
+++ xgl/glx/evdev.c 2006-04-10 18:26:52.000000000 -0300
@@ -0,0 +1,341 @@
+#include "evdev.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "os.h"
+#include "mipointer.h"
+#include "mi.h"
+
+CARD32 lastEventTime = 0;
+
+extern char *xglKbdEvdevFile;
+extern char *xglPtrEvdevFile;
+
+int kbd_fd,
+ ptr_fd;
+
+int EventToXserver[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 203, 90, 91, 92, 93, 94, 126,
+ 100, 101, 104, 99, 105, 101, 89, 90,
+ 91, 92, 94, 95, 96, 97, 98, 99,
+ 112, 113, 114, 115, 214, 117, 118, 102,
+ 120, 126, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 109, 140, 141, 215, 219,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215,
+ 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247,
+ 248
+};
+
+void
+xglCollectEvdevEvents()
+{
+ xEvent x;
+
+ int i;
+ struct input_event ie;
+
+ while (EvdevCheckIfEvent(&ie)) {
+ switch (ie.type) {
+ case EV_REL:
+ switch (ie.code) {
+ case REL_X:
+ miPointerDeltaCursor(ie.value, 0, lastEventTime =
+ GetTimeInMillis());
+ break;
+
+ case REL_Y:
+ miPointerDeltaCursor(0, ie.value, lastEventTime =
+ GetTimeInMillis());
+ break;
+ case REL_WHEEL:
+ if (ie.value > 0)
+ x.u.u.detail = 4;
+ else {
+ x.u.u.detail = 5;
+ ie.value *= -1;
+ }
+
+ for (i = 0; i < ie.value; i++) {
+ x.u.u.type = ButtonPress;
+ mieqEnqueue(&x);
+ x.u.u.type = ButtonRelease;
+ mieqEnqueue(&x);
+ }
+ break;
+ case REL_HWHEEL:
+ if (ie.value > 0)
+ x.u.u.detail = 6;
+ else {
+ x.u.u.detail = 7;
+ ie.value *= -1;
+ }
+
+ for (i = 0; i < ie.value; i++) {
+ x.u.u.type = ButtonPress;
+ mieqEnqueue(&x);
+ x.u.u.type = ButtonRelease;
+ mieqEnqueue(&x);
+ }
+ break;
+ }
+ break;
+
+ case EV_ABS:
+ break;
+
+ case EV_KEY:
+ if (ie.code >= BTN_MOUSE && ie.type < BTN_JOYSTICK) {
+ x.u.u.type = ie.value ? ButtonPress : ButtonRelease;
+ switch (ie.code) {
+ case BTN_LEFT:
+ x.u.u.detail = 1;
+ break;
+ case BTN_MIDDLE:
+ x.u.u.detail = 2;
+ break;
+ case BTN_RIGHT:
+ x.u.u.detail = 3;
+ break;
+ default:
+ x.u.u.detail = 2;
+ break;
+ }
+ x.u.keyButtonPointer.time = lastEventTime =
+ GetTimeInMillis();
+ mieqEnqueue(&x);
+ break;
+ } else {
+ x.u.u.type = ie.value ? KeyPress : KeyRelease;
+ x.u.u.detail = EventToXserver[ie.code] + 8; /* FIXME:"8"
+ * means
+ * the
+ * MIN_KEYCODE
+ */
+ x.u.keyButtonPointer.time = lastEventTime =
+ GetTimeInMillis();
+ mieqEnqueue(&x);
+ }
+
+ case EV_SYN:
+ break;
+ }
+ }
+}
+
+static int
+xglBlockSIGIO(void)
+{
+ sigset_t set,
+ old;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGIO);
+ sigprocmask(SIG_BLOCK, &set, &old);
+ return sigismember(&old, SIGIO);
+}
+
+static void
+xglUnblockSIGIO(int wasset)
+{
+ sigset_t set;
+
+ if (!wasset) {
+ sigemptyset(&set);
+ sigaddset(&set, SIGIO);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+ }
+}
+
+void
+xglSIGIO(int sig)
+{
+ int wasset = xglBlockSIGIO();
+ xglCollectEvdevEvents();
+ xglUnblockSIGIO(wasset);
+}
+
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define BIT(x) (1UL<<((x)%BITS_PER_LONG))
+
+#define EVIOCGMASK _IOR('E', 0x91, unsigned long *) /* Get our
+ * input
+ * mask */
+#define EVIOCSMASK _IOW('E', 0x92, unsigned long) /* Set our
+ * input
+ * mask */
+#define EVIOCGDMASK _IOR('E', 0x93, unsigned long *) /* Get
+ * device
+ * input
+ * mask */
+#define EVIOCSDMASK _IOW('E', 0x94, unsigned long) /* Set
+ * device
+ * input
+ * mask */
+
+void
+xglOpenEvdevInput()
+{
+ static int already_open = 0;
+ struct sigaction sa;
+ struct sigaction osa;
+
+ if (already_open)
+ return;
+
+ kbd_fd = open(xglKbdEvdevFile, O_RDWR | O_NONBLOCK);
+ if (kbd_fd == -1)
+ FatalError("Unable to open keyboard device %s.\n",
+ xglKbdEvdevFile);
+
+ ptr_fd = open(xglPtrEvdevFile, O_RDONLY | O_NONBLOCK);
+ if (ptr_fd == -1)
+ FatalError("Unable to open pointer device %s.\n", xglPtrEvdevFile);
+
+ /*
+ * Register the fd to receive SIGIO signals
+ */
+ if (fcntl(kbd_fd, F_SETFL, fcntl(kbd_fd, F_GETFL) | O_ASYNC) == -1)
+ fprintf(stderr, "fcntl(%d, O_ASYNC): %s\n", kbd_fd,
+ strerror(errno));
+ if (fcntl(kbd_fd, F_SETOWN, getpid()) == -1)
+ fprintf(stderr, "fcntl(%d, F_SETOWN): %s\n", kbd_fd,
+ strerror(errno));
+
+ /*
+ * Register the fd to receive SIGIO signals
+ */
+ if (fcntl(ptr_fd, F_SETFL, fcntl(ptr_fd, F_GETFL) | O_ASYNC) == -1)
+ fprintf(stderr, "fcntl(%d, O_ASYNC): %s\n", ptr_fd,
+ strerror(errno));
+ if (fcntl(ptr_fd, F_SETOWN, getpid()) == -1)
+ fprintf(stderr, "fcntl(%d, F_SETOWN): %s\n", ptr_fd,
+ strerror(errno));
+
+ sigemptyset(&sa.sa_mask);
+ sigaddset(&sa.sa_mask, SIGIO);
+ sa.sa_flags = 0;
+ sa.sa_handler = xglSIGIO;
+ sigaction(SIGIO, &sa, &osa);
+
+ already_open = 1;
+}
+
+static int grabbed = 0;
+
+void
+xglEvdevGrabKeyboard()
+{
+ unsigned long mask;
+
+ if (grabbed)
+ return;
+
+ if (ioctl(kbd_fd, EVIOCGMASK, &mask) < 0) {
+ ErrorF
+ ("unable to use input device masking '%s', trying grabbing.\n",
+ strerror(errno));
+ if (ioctl(kbd_fd, EVIOCGRAB, 1) < 0) {
+ ErrorF("unable to grab device '%s', you may have problems.\n",
+ strerror(errno));
+ }
+ return;
+ }
+
+ mask |= BIT(2);
+ ioctl(kbd_fd, EVIOCSMASK, mask);
+ ioctl(kbd_fd, EVIOCGDMASK, &mask);
+ mask &= ~BIT(0);
+ mask |= BIT(2);
+ ioctl(kbd_fd, EVIOCSDMASK, mask);
+}
+
+
+void
+xglEvdevUngrabKeyboard()
+{
+ if (!grabbed)
+ return;
+
+ unsigned long mask;
+ if (ioctl(kbd_fd, EVIOCGDMASK, &mask) >= 0) {
+ mask |= BIT(0);
+ ioctl(kbd_fd, EVIOCSDMASK, mask);
+ }
+}
+
+int
+EvdevCheckIfEvent(struct input_event *ie)
+{
+ int result,
+ nread;
+
+ nread = read(kbd_fd, ie, sizeof(struct input_event));
+
+ if (nread <= 0)
+ nread = read(ptr_fd, ie, sizeof(struct input_event));
+
+ if (nread <= 0)
+ result = 0;
+ else
+ result = 1;
+
+ return result;
+}
+
+
+int
+EvdevSetLeds(long int leds)
+{
+ struct input_event event;
+ int i;
+
+ memset(&event, 0, sizeof(event));
+
+ event.type = EV_LED;
+ event.code = LED_CAPSL;
+ event.value = leds & (1 << 0) ? 1 : 0;
+ write(kbd_fd, (char *) &event, sizeof(event));
+
+ event.type = EV_LED;
+ event.code = LED_NUML;
+ event.value = leds & (1 << 1) ? 1 : 0;
+ write(kbd_fd, (char *) &event, sizeof(event));
+
+ event.type = EV_LED;
+ event.code = LED_SCROLLL;
+ event.value = leds & (1 << 2) ? 1 : 0;
+ write(kbd_fd, (char *) &event, sizeof(event));
+
+ event.type = EV_LED;
+ event.code = LED_COMPOSE;
+ event.value = leds & (1 << 3) ? 1 : 0;
+ write(kbd_fd, (char *) &event, sizeof(event));
+}
diff -u --exclude=Makefile --exclude='*.Plo' --exclude='*.in' --recursive --new-file xgl.orig/glx/evdev.h xgl/glx/evdev.h
--- xgl.orig/glx/evdev.h 1969-12-31 21:00:00.000000000 -0300
+++ xgl/glx/evdev.h 2006-04-10 18:25:25.000000000 -0300
@@ -0,0 +1,17 @@
+#ifndef XGLEVDEV_H
+#define XGLEVDEV_H
+
+#include <linux/input.h>
+
+extern void xglOpenEvdevInput();
+
+extern void xglEvdevGrabKeyboard();
+extern void xglEvdevUngrabKeyboard();
+
+extern int EvdevCheckIfEvent(struct input_event *ie);
+
+extern int EvdevSetLeds(long int leds);
+
+extern int EventToXserver[];
+
+#endif /* XGLEVDEV_H */
diff -u --exclude=Makefile --exclude='*.Plo' --exclude='*.in' --recursive --new-file xgl.orig/glx/Makefile.am xgl/glx/Makefile.am
--- xgl.orig/glx/Makefile.am 2006-04-10 17:57:21.000000000 -0300
+++ xgl/glx/Makefile.am 2006-04-10 17:58:56.000000000 -0300
@@ -25,7 +25,9 @@
libxglx_la_SOURCES = \
xglx.h \
xglx.c \
- xglxorg.c
+ xglxorg.c \
+ evdev.h \
+ evdev.c
# Xglx_DEPENDENCIES = @XGLX_LIBS@
# Xglx_LDFLAGS = -export-dynamic
diff -u --exclude=Makefile --exclude='*.Plo' --exclude='*.in' --recursive --new-file xgl.orig/glx/xglx.c xgl/glx/xglx.c
--- xgl.orig/glx/xglx.c 2006-04-10 17:57:21.000000000 -0300
+++ xgl/glx/xglx.c 2006-04-11 15:14:35.000000000 -0300
@@ -55,6 +55,8 @@
#include <X11/extensions/XKBconfig.h>
#include <X11/extensions/XKBrules.h>
+#include "evdev.h"
+
extern Bool
XkbQueryExtension (Display *dpy,
int *opcodeReturn,
@@ -136,12 +138,17 @@
static Bool softCursor = FALSE;
static Bool fullscreen = TRUE;
static Bool xDpms = FALSE;
+static Bool useEvdev = FALSE;
static Bool randrExtension = FALSE;
static int randrEvent, randrError;
static glitz_drawable_format_t *xglxScreenFormat = 0;
+/* evdev default file for keyboard and pointer */
+char *xglKbdEvdevFile = "/dev/input/event0";
+char *xglPtrEvdevFile = "/dev/input/event1";
+
static Bool
xglxAllocatePrivates (ScreenPtr pScreen)
{
@@ -978,6 +985,8 @@
while (XCheckIfEvent (xdisplay, &X, xglxNotExposurePredicate, NULL))
{
+ if (useEvdev) ;
+ else {
switch (X.type) {
case KeyPress:
x.u.u.type = KeyPress;
@@ -1029,6 +1038,7 @@
default:
break;
}
+ } /* useEvdev patch*/
}
}
@@ -1049,6 +1059,11 @@
XKeyboardControl values;
int i;
+ if (useEvdev)
+ /* TODO: handle other control stuff: click, bell, autoRepeat */
+ EvdevSetLeds (ctrl->leds);
+ else {
+
valueMask = KBKeyClickPercent | KBBellPercent | KBBellPitch |
KBBellDuration | KBAutoRepeatMode;
@@ -1071,6 +1086,7 @@
XChangeKeyboardControl (xdisplay, valueMask, &values);
}
+ }
}
static int
@@ -1247,10 +1263,14 @@
} break;
case DEVICE_ON:
+ if (useEvdev)
+ xglEvdevGrabKeyboard ();
pDev->on = TRUE;
break;
case DEVICE_OFF:
case DEVICE_CLOSE:
+ if (useEvdev)
+ xglEvdevUngrabKeyboard ();
pDev->on = FALSE;
break;
}
@@ -1317,6 +1337,9 @@
{
DeviceIntPtr pKeyboard, pPointer;
+ if (useEvdev)
+ xglOpenEvdevInput();
+
pPointer = AddInputDevice (xglxPointerProc, TRUE);
pKeyboard = AddInputDevice (xglxKeybdProc, TRUE);
@@ -1341,6 +1364,10 @@
ErrorF ("-fullscreen run fullscreen\n");
ErrorF ("-display string display name of the real server\n");
ErrorF ("-softcursor force software cursor\n");
+ ErrorF ("-kbd file evdev file to read keyboard events\n");
+ ErrorF ("-ptr file evdev file to read pointer events\n");
+ ErrorF (" (if -kbd or -ptr is not set, Xglx will\n");
+ ErrorF (" read from xorg input)\n");
if (!xDisplayName)
xglxUseXorgMsg ();
@@ -1424,6 +1451,24 @@
return xglxProcessXorgArgument (argc, argv, i);
}
+ if (!strcmp(argv[i], "-kbd"))
+ {
+ if (++i < argc) {
+ xglKbdEvdevFile = argv[i];
+ useEvdev = TRUE;
+ return 2;
+ }
+ return 0;
+ }
+ if (!strcmp(argv[i], "-ptr")) {
+ if (++i < argc) {
+ xglPtrEvdevFile = argv[i];
+ useEvdev = TRUE;
+ return 2;
+ }
+ return 0;
+ }
+
return 0;
}
More information about the xorg
mailing list