Ok, the code has a few hacks, but it all seems to work. For 2.5.x everything should just work once you put it together, hotplugging included.
For 2.4.x everything /except/ hotplugging works, because 2.4.x does not
generate hotplug events for input devices.
One solution for 2.4.x would be to just restart all evdev devices on
every USB add or remove, however this is rather suboptimal due to the
effect it has on input.
A better solution would be to back port the changes that allow the input
layer to generate hotplug events. <=:]
This is still just mouse only, however most of the hard work is done,
keyboard should be fairly quick and easy.
So what I really need is for people to pound on this and make it break.
Both success and failure reports would be much appreciated.
Now, what all you need to make this WORK.
Attached are two files, the patch to the X sources, and input.agent.
The input.agent from previous patches will /NOT/ work, as much has
changed.
You will need to put the input.agent in /etc/hotplug/, if you already
have an input.agent then you will need to merge this in with the
existing one. (That said, I am not aware of any existing input agents.)
The config section for a mouse should look something like this:
Section "InputDevice"
Identifier "Mouse1"
Driver "mouse"
Option "Protocol" "evdev"
Option "Dev Name" "A4Tech USB Optical Mouse"
Option "Dev Phys" "usb-*/input0"
Option "Buttons" "9"
Option "ZAxisMapping" "6 7 8 9"
EndSection
For Dev Name and Dev Phys the wildcards ? and * work, you MUST have at
least one of the two, if you have both then the device must match on
both, a non-existent entry is the same as one consisting of "*".
I would appreciate comments on the design and code as well.
Thanks.
Zephaniah E. Hull.
--
1024D/E65A7801 Zephaniah E. Hull <[EMAIL PROTECTED]>
92ED 94E4 B1E6 3624 226D 5727 4453 008B E65A 7801
CCs of replies from mailing lists are requested.
Why blow away at a partition when you can chip away at it? I now
present a script I just wrote that writes random bits of, well random
bits, into random places in your favorite partition or file. For best
(meaning most spectacular) results, use while the database or
filesystem is in active use.
Disclaimer: This code is untested, and it may or may not trash your
filesystem and/or database. While at least a half-assed effort has
been made to ensure that it works as designed, there is no guarantee
that its use will result in a loss of important data. I am not liable
for the lack of either direct or incidental damages.
-- Logan Shaw on ASR.
#!/bin/bash
cd /etc/hotplug
. hotplug.functions
#DEBUG=yes export DEBUG
export ARG_SEP='\002'
export VAL_SEP='\003'
for dev in `ls /tmp/.X11-unix/ | grep evdev`; do {
export dev="/tmp/.X11-unix/${dev}"
/bin/sh -c 'echo -e
"2.1${ARG_SEP}NAME${VAL_SEP}${NAME}${ARG_SEP}PHYS${VAL_SEP}${PHYS}${ARG_SEP}ACTION${VAL_SEP}${ACTION}"
>> ${dev}' &
}; done
diff -urN -x '*Makefile' -x '*.def' -x xmakefile
build-tree.orig/xc/programs/Xserver/hw/xfree86/os-support/linux/Imakefile
build-tree.tmp/xc/programs/Xserver/hw/xfree86/os-support/linux/Imakefile
--- build-tree.orig/xc/programs/Xserver/hw/xfree86/os-support/linux/Imakefile
2000-11-16 14:45:03.000000000 -0500
+++ build-tree.tmp/xc/programs/Xserver/hw/xfree86/os-support/linux/Imakefile
+2002-12-07 04:42:49.000000000 -0500
@@ -42,15 +42,16 @@
SRCS = lnx_init.c lnx_video.c lnx_io.c libc_wrapper.c bios_mmap.c \
VTsw_usl.c std_kbdEv.c posix_tty.c $(MOUSESRC) \
lnx_pci.c vidmem.c lnx_apm.c $(JOYSTICK_SRC) $(DRI_SRC) $(RES_SRCS) \
- $(AXP_SRC) lnx_kmod.c lnx_agp.c
+ $(AXP_SRC) lnx_kmod.c lnx_agp.c lnx_evdev.c
OBJS = lnx_init.o lnx_video.o lnx_io.o libc_wrapper.o bios_mmap.o \
VTsw_usl.o std_kbdEv.o posix_tty.o $(MOUSEOBJ) \
lnx_pci.o vidmem.o lnx_apm.o $(JOYSTICK_OBJ) $(DRI_OBJ) $(RES_OBJS) \
- $(AXP_OBJ) lnx_kmod.o lnx_agp.o
+ $(AXP_OBJ) lnx_kmod.o lnx_agp.o lnx_evdev.o
INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
- -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(XF86OSSRC)/shared
+ -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(XF86OSSRC)/shared \
+ -I$(SERVERSRC)/mi
RESDEFINES = -DUSESTDRES
diff -urN -x '*Makefile' -x '*.def' -x xmakefile
build-tree.orig/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_evdev.c
build-tree.tmp/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_evdev.c
--- build-tree.orig/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_evdev.c
1969-12-31 19:00:00.000000000 -0500
+++ build-tree.tmp/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_evdev.c
+2002-12-10 03:50:56.000000000 -0500
@@ -0,0 +1,277 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c,v 1.1
+1999/05/17 13:17:18 dawes Exp $ */
+
+/*
+ * Copyright 1999 by The XFree86 Project, Inc.
+ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+#include "lnx_evdev.h"
+#include "mipointer.h"
+
+static Bool evdev_alive = FALSE;
+static evdevDriverPtr evdev_drivers = NULL;
+static char *evdev_buf;
+static char evdev_device[23];
+
+static int
+glob_match(const char *pattern, const char *matchp)
+{
+ int i, j = 0, ret = 0;
+ if (!(pattern && matchp))
+ return (strlen(pattern) == strlen(matchp));
+
+ for (i = 0; matchp[i]; i++) {
+ if (pattern[j] == '\\')
+ j++;
+ else if (pattern[j] == '*') {
+ if (pattern[j + 1]) {
+ if (!glob_match(pattern+j+1,matchp+i))
+ return 0;
+ } else
+ return 0;
+ continue;
+ } else if (pattern[j] == '?') {
+ j++;
+ continue;
+ }
+
+ if ((ret = (pattern[j] - matchp[i])))
+ return ret;
+
+ j++;
+ }
+ if (!pattern[j] || ((pattern[j] == '*') && !pattern[j + 1]))
+ return 0;
+ else
+ return 1;
+}
+
+
+int
+evdevGetFDForDriver (evdevDriverPtr driver)
+{
+ char dev[20];
+ char tmp[256] = "";
+ int fd, i;
+
+ if (!driver)
+ return -1;
+
+ for (i = 0; i < 32; i++) {
+ snprintf(dev, sizeof(dev), "/dev/input/event%d", i++);
+ SYSCALL(fd = open (dev, O_RDWR | O_NONBLOCK));
+ if (fd == -1)
+ continue;
+
+#define check(name,get) \
+ if (name) { \
+ ioctl(fd, get, tmp); \
+ if (glob_match(name, tmp)) { \
+ close(fd); \
+ continue; \
+ } \
+ }
+
+ check(driver->name, EVIOCGNAME(sizeof(tmp)));
+ check(driver->phys, EVIOCGPHYS(sizeof(tmp)));
+#undef check
+ return fd;
+ }
+ return -1;
+}
+
+static void
+evdevReadInput(InputInfoPtr pInfo)
+{
+ int n;
+ evdevDriverPtr driver;
+ char *cur, *end;
+ char *id, *value, *name, *phys, *action;
+ Bool up;
+
+ do {
+ SYSCALL(n = read(pInfo->fd, evdev_buf, 1022));
+ evdev_buf[n] = '\n'; /* Just to be extra safe. */
+ evdev_buf[n + 1] = '\0';/* Just to be extra safe. */
+
+ cur = evdev_buf;
+ while (cur[0] && (end = strchr(cur, '\n'))) {
+ name = phys = action = NULL;
+ if (!strncmp("2.1", cur, 3)) {
+#define next_sep(sep,end,clr) while (1) { \
+ if ((*cur == '\n') || (*cur == '\0')) { \
+ if (end) { \
+ goto evdevReadInput__finished; \
+ } else if (clr) \
+ *cur = '\0'; \
+ cur++; \
+ break; \
+ } else if (*cur == sep) { \
+ if (clr) \
+ *cur = '\0'; \
+ cur++; \
+ break; \
+ } \
+ cur++; \
+ }
+
+ next_sep('\002', 1, 0);
+loop_start__21:
+ id = cur;
+ next_sep('\003', 1, 1);
+ value = cur;
+ next_sep('\002', 0, 1);
+ if (!strcmp(id, "ACTION"))
+ action = value;
+ else if (!strcmp(id, "NAME"))
+ name = value;
+ else if (!strcmp(id, "PHYS"))
+ phys = value;
+ if (*cur != '\n')
+ goto loop_start__21;
+#undef next_sep
+ }
+evdevReadInput__finished:
+
+ if (!(action && name && phys)) {
+ xf86Msg(X_ERROR,"%s: Incomplete command! -%s-%s-%s-\n",
+ pInfo->name, action, name, phys);
+ } else {
+ if (!strcmp(action, "add"))
+ up = TRUE;
+ else
+ up = FALSE;
+
+ for (driver = evdev_drivers; driver; driver = driver->next) {
+ if (driver->name && glob_match(name, driver->name))
+ continue;
+ if (driver->phys && glob_match(phys, driver->phys))
+ continue;
+ if (up)
+ driver->callback(driver->cb_data, DEVICE_ON);
+ else
+ driver->callback(driver->cb_data, DEVICE_OFF);
+ }
+ }
+ cur = end + 1;
+ }
+ } while (xf86WaitForInput(pInfo->fd, 0));
+ return;
+}
+
+static void
+evdevSigioReadInput (int fd, void *closure)
+{
+ evdevReadInput ((InputInfoPtr) closure);
+}
+
+static int
+evdevGetControlFD (void)
+{
+ int i, ret;
+
+ for (i = 0; i < 100; i++) {
+ snprintf(evdev_device,sizeof(evdev_device),"/tmp/.X11-unix/evdev%d", i);
+ SYSCALL(ret = mkfifo (evdev_device, 0666));
+ if (ret == -1) {
+ if (errno != EEXIST)
+ return -1;
+ continue;
+ }
+ SYSCALL(ret = open (evdev_device, O_RDWR | O_NONBLOCK));
+ return ret;
+ }
+
+ return -1;
+}
+
+static void
+evdevReleaseControlFD (int fd)
+{
+ SYSCALL(close(fd));
+ SYSCALL(unlink(evdev_device));
+}
+
+static int
+evdevControl(DeviceIntPtr pPointer, int what)
+{
+ InputInfoPtr pInfo;
+
+ pInfo = pPointer->public.devicePrivate;
+
+ switch (what) {
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+ break;
+
+ case DEVICE_ON:
+ pInfo->fd = evdevGetControlFD ();
+ if (pInfo->fd == -1) {
+ xf86Msg(X_ERROR, "%s: cannot open control FIFO.\n", pInfo->name);
+ return BadRequest;
+ }
+ xf86FlushInput(pInfo->fd);
+ if (!xf86InstallSIGIOHandler (pInfo->fd, evdevSigioReadInput, pInfo))
+ AddEnabledDevice(pInfo->fd);
+ pPointer->public.on = TRUE;
+ break;
+
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if (pInfo->fd != -1) {
+ RemoveEnabledDevice(pInfo->fd);
+ xf86RemoveSIGIOHandler(pInfo->fd);
+ evdevReleaseControlFD (pInfo->fd);
+ pInfo->fd = -1;
+ }
+ pPointer->public.on = FALSE;
+ usleep(300000);
+ break;
+ }
+ return Success;
+}
+
+Bool
+evdevStart (InputDriverPtr drv)
+{
+ InputInfoPtr pInfo;
+
+ if (evdev_alive)
+ return TRUE;
+
+ if (!(evdev_buf = xcalloc(1024, 1)))
+ return FALSE;
+
+ if (!(pInfo = xf86AllocateInput(drv, 0)))
+ return FALSE;
+
+
+ pInfo->name = "evdev brain";
+ pInfo->type_name = "evdev brain";
+ pInfo->device_control = evdevControl;
+ pInfo->read_input = evdevReadInput;
+ pInfo->fd = -1;
+ evdev_alive = TRUE;
+ pInfo->flags = XI86_CONFIGURED | XI86_OPEN_ON_INIT;
+ return TRUE;
+}
+
+Bool
+evdevNewDriver (evdevDriverPtr driver)
+{
+ if (!evdev_alive)
+ return FALSE;
+ if (!(driver->name || driver->phys))
+ return FALSE;
+ if (!driver->callback)
+ return FALSE;
+
+ driver->next = evdev_drivers;
+ evdev_drivers = driver;
+ return TRUE;
+}
diff -urN -x '*Makefile' -x '*.def' -x xmakefile
build-tree.orig/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_evdev.h
build-tree.tmp/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_evdev.h
--- build-tree.orig/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_evdev.h
1969-12-31 19:00:00.000000000 -0500
+++ build-tree.tmp/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_evdev.h
+2002-12-08 09:22:48.000000000 -0500
@@ -0,0 +1,42 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx.h,v 3.2 2000/02/15
+02:00:14 eich Exp $ */
+
+#ifndef LNX_EVDEV_H_
+
+#include <linux/input.h>
+
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define OFF(x) ((x)%BITS_PER_LONG)
+#define LONG(x) ((x)/BITS_PER_LONG)
+#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
+
+#ifndef EVIOCGPHYS
+#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical
+location */
+#endif
+
+/*
+ * Synchronization events.
+ */
+#ifndef EV_SYN
+#define EV_SYN 0x00
+
+#define SYN_REPORT 0
+#define SYN_CONFIG 1
+#endif
+
+
+typedef struct _evdevDriver {
+ const char *name;
+ const char *phys;
+ void *cb_data;
+ void (*callback)(void *cb_data, int what);
+ struct _evdevDriver *next;
+} evdevDriver, *evdevDriverPtr;
+
+int evdevGetFDForDriver (evdevDriverPtr driver);
+Bool evdevStart (InputDriverPtr drv);
+Bool evdevNewDriver (evdevDriverPtr driver);
+
+#define LNX_EVDEV_H_
+
+#endif
diff -urN -x '*Makefile' -x '*.def' -x xmakefile
build-tree.orig/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c
build-tree.tmp/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c
--- build-tree.orig/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c
1999-05-17 09:17:18.000000000 -0400
+++ build-tree.tmp/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c
+2002-12-09 02:48:44.000000000 -0500
@@ -6,8 +6,18 @@
#include "X.h"
#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
#include "xf86Xinput.h"
#include "xf86OSmouse.h"
+#include "mipointer.h"
+#include "lnx_evdev.h"
+
+/* Names of protocols that are handled internally here. */
+static const char *internalNames[] = {
+ "evdev",
+ NULL
+};
static int
SupportedInterfaces(void)
@@ -15,6 +25,272 @@
return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO;
}
+static const char **
+BuiltinNames(void)
+{
+ return internalNames;
+}
+
+static Bool
+CheckProtocol(const char *protocol)
+{
+ int i;
+
+ for (i = 0; internalNames[i]; i++)
+ if (xf86NameCmp(protocol, internalNames[i]) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+typedef struct _evdevMseRec {
+ int packetSize;
+ int buttons;
+ Bool sync;
+ evdevDriver evdev;
+} evdevMseRec, *evdevMsePtr;
+
+static void
+evdevMouseReadInput(InputInfoPtr pInfo)
+{
+ MouseDevPtr pMse;
+ evdevMsePtr evdevMse;
+ struct input_event *ev;
+ int n, bit;
+ int dx = 0, dy = 0, dz = 0, dw = 0;
+
+ pMse = pInfo->private;
+ ev = (struct input_event *) pMse->buffer;
+ evdevMse = pMse->mousePriv;
+
+ if (pInfo->fd == -1)
+ return;
+
+ do {
+ n = read(pInfo->fd, pMse->buffer, sizeof(struct input_event));
+ if (n == -1) {
+ xf86Msg(X_ERROR, "%s: Error in reading! (%s) Disabiling.\n",
+ pInfo->name, strerror(errno));
+ RemoveEnabledDevice(pInfo->fd);
+ xf86RemoveSIGIOHandler(pInfo->fd);
+ close (pInfo->fd);
+ pMse->device->public.on = FALSE;
+ pInfo->fd = -1;
+ pMse->PostEvent(pInfo, evdevMse->buttons, dx, dy, dz, dw);
+ return;
+ }
+ if (n != sizeof(struct input_event)) {
+ xf86Msg(X_WARNING, "%s: incomplete packet, size %d\n", pInfo->name, n);
+ pMse->PostEvent(pInfo, evdevMse->buttons, dx, dy, dz, dw);
+ return;
+ }
+
+ switch (ev->type) {
+ case EV_REL:
+ switch (ev->code) {
+ case REL_X:
+ dx += ev->value;
+ break;
+ case REL_Y:
+ dy += ev->value;
+ break;
+ case REL_Z:
+ case REL_WHEEL:
+ dz -= ev->value;
+ break;
+ case REL_HWHEEL:
+ dw -= ev->value;
+ break;
+ }
+ break;
+ case EV_KEY:
+ if ((ev->code < BTN_MOUSE) || (ev->code >= BTN_JOYSTICK))
+ break;
+ switch (ev->code) {
+ case BTN_RIGHT: bit = 1 << 0; break; /* 1 */
+ case BTN_MIDDLE: bit = 1 << 1; break; /* 2 */
+ case BTN_LEFT: bit = 1 << 2; break; /* 3 */
+ default: bit = 1 << (ev->code - BTN_MOUSE); break;
+ }
+ evdevMse->buttons &= ~bit;
+ if (ev->value)
+ evdevMse->buttons |= bit;
+ break;
+ case EV_SYN:
+ switch (ev->code) {
+ case SYN_REPORT:
+ pMse->PostEvent(pInfo,evdevMse->buttons,dx, dy, dz, dw);
+ dx = dy = dz = dw = 0;
+ break;
+ }
+ break;
+ }
+ if (!evdevMse->sync) {
+ pMse->PostEvent(pInfo,evdevMse->buttons,dx, dy, dz, dw);
+ dx = dy = dz = dw = 0;
+ }
+ } while (xf86WaitForInput(pInfo->fd, 0));
+
+ pMse->PostEvent(pInfo, evdevMse->buttons, dx, dy, dz, dw);
+
+ return;
+}
+
+static void
+evdevMouseSigioReadInput (int fd, void *closure)
+{
+ evdevMouseReadInput ((InputInfoPtr) closure);
+}
+
+static int
+evdevMouseProc(DeviceIntPtr pPointer, int what)
+{
+ InputInfoPtr pInfo;
+ MouseDevPtr pMse;
+ evdevMsePtr evdevMse;
+ unsigned char map[MSE_MAXBUTTONS + 1];
+ int i, j, blocked;
+ unsigned long evtype_bits[NBITS(EV_MAX)];
+ unsigned long evkey_bits[NBITS(KEY_MAX)];
+
+ pInfo = pPointer->public.devicePrivate;
+ pMse = pInfo->private;
+ pMse->device = pPointer;
+ evdevMse = pMse->mousePriv;
+
+ switch (what) {
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+
+ evdevMse->evdev.name = xf86SetStrOption(pInfo->options,"Dev Name",NULL);
+ evdevMse->evdev.phys = xf86SetStrOption(pInfo->options,"Dev Phys",NULL);
+ evdevMse->evdev.cb_data = pInfo->dev;
+ evdevMse->evdev.callback = evdevMouseProc;
+ if (!evdevNewDriver (&evdevMse->evdev)) {
+ xf86Msg(X_ERROR, "%s: cannot register with evdev brain\n", pInfo->name);
+ return BadRequest;
+ }
+ if ((pInfo->fd = evdevGetFDForDriver (&evdevMse->evdev)) == -1) {
+ xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
+ return BadRequest;
+ }
+
+ ioctl(pInfo->fd, EVIOCGBIT(0, EV_MAX), evtype_bits);
+ if (test_bit(EV_SYN, evtype_bits))
+ evdevMse->sync = TRUE;
+ else
+ evdevMse->sync = FALSE;
+
+ if (test_bit(EV_KEY, evtype_bits)) {
+ ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, KEY_MAX), evkey_bits);
+ i = BTN_LEFT;
+ pMse->buttons = 0;
+ for (i = BTN_LEFT, j = 0; i <= BTN_BACK; i++)
+ if (test_bit(i, evkey_bits))
+ pMse->buttons++;
+ }
+
+ close(pInfo->fd);
+ pInfo->fd = -1;
+
+ for (i = 0; i < MSE_MAXBUTTONS; ++i)
+ map[i + 1] = i + 1;
+
+ InitPointerDeviceStruct((DevicePtr)pPointer, map,
+ min(pMse->buttons, MSE_MAXBUTTONS),
+ miPointerGetMotionEvents, pMse->Ctrl,
+ miPointerGetMotionBufferSize());
+
+ /* X valuator */
+ xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(pPointer, 0);
+ /* Y valuator */
+ xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(pPointer, 1);
+ xf86MotionHistoryAllocate(pInfo);
+ break;
+
+ case DEVICE_ON:
+ if (pPointer->public.on)
+ break;
+ if ((pInfo->fd = evdevGetFDForDriver (&evdevMse->evdev)) == -1) {
+ xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
+ return BadRequest;
+ }
+
+ xf86FlushInput(pInfo->fd);
+ if (!xf86InstallSIGIOHandler (pInfo->fd, evdevMouseSigioReadInput, pInfo))
+ AddEnabledDevice(pInfo->fd);
+ pMse->lastButtons = 0;
+ pMse->emulateState = 0;
+ evdevMse->buttons = 0;
+ pPointer->public.on = TRUE;
+ /*
+ * send button up events for sanity. If no button down is pending
+ * xf86PostButtonEvent() will discard them. So we are on the safe side.
+ */
+ blocked = xf86BlockSIGIO ();
+ for (i = 1; i <= 5; i++)
+ xf86PostButtonEvent(pPointer,0,i,0,0,0);
+ xf86UnblockSIGIO (blocked);
+ break;
+
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if (pInfo->fd != -1) {
+ RemoveEnabledDevice(pInfo->fd);
+ xf86RemoveSIGIOHandler(pInfo->fd);
+ close (pInfo->fd);
+ pInfo->fd = -1;
+ }
+ pPointer->public.on = FALSE;
+ usleep(300000);
+ break;
+ }
+ return Success;
+}
+
+
+/* This function is called when the protocol is "evdev". */
+static Bool
+evdevMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags)
+{
+ MouseDevPtr pMse = pInfo->private;
+ evdevMsePtr evdevMse;
+
+ pMse->protocol = protocol;
+ xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
+
+ /* Collect the options, and process the common options. */
+ xf86CollectInputOptions(pInfo, NULL, NULL);
+ xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+ if (sizeof(struct input_event) <= sizeof(pMse->protoBuf))
+ pMse->buffer = pMse->protoBuf;
+ else
+ pMse->buffer = xcalloc(sizeof(struct input_event),1);
+ pMse->mousePriv = evdevMse = xcalloc(sizeof(evdevMseRec), 1);
+ if ((pMse->buffer == NULL) || (pMse->mousePriv == NULL)) {
+ xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name);
+ xfree(pMse);
+ return FALSE;
+ }
+
+ if (!evdevStart (pInfo->drv)) {
+ xf86Msg(X_ERROR, "%s: cannot start evdev brain\n", pInfo->name);
+ return FALSE;
+ }
+
+ pMse->CommonOptions(pInfo);
+
+ /* Setup the local procs. */
+ pInfo->device_control = evdevMouseProc;
+ pInfo->read_input = evdevMouseReadInput;
+
+ pInfo->flags |= XI86_CONFIGURED;
+
+ return TRUE;
+}
+
OSMouseInfoPtr
xf86OSMouseInit(int flags)
{
@@ -24,6 +300,8 @@
if (!p)
return NULL;
p->SupportedInterfaces = SupportedInterfaces;
+ p->CheckProtocol = CheckProtocol;
+ p->BuiltinNames = BuiltinNames;
+ p->PreInit = evdevMousePreInit;
return p;
}
-
msg11518/pgp00000.pgp
Description: PGP signature
