Updates some piece of the dead mouse evdev code under the new hotplug scheme.

I exported the evdev driver to Xephyr server. I'm running it using something
like:
    $ ./hw/kdrive/ephyr/Xephyr :1 -mouse evdev,,device=/dev/input/event4 -keybd \
    evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br

It also closes /#5668.
This commit is contained in:
Tiago Vignatti 2007-08-07 23:17:32 -03:00
parent 7d1a749b21
commit ab3f601149
4 changed files with 274 additions and 42 deletions

View File

@ -57,7 +57,9 @@ InitInput (int argc, char **argv)
KdPointerInfo *pi;
KdAddKeyboardDriver(&EphyrKeyboardDriver);
KdAddKeyboardDriver(&LinuxEvdevKeyboardDriver);
KdAddPointerDriver(&EphyrMouseDriver);
KdAddPointerDriver(&LinuxEvdevMouseDriver);
if (!kdHasKbd) {
ki = KdNewKeyboard();

View File

@ -42,11 +42,8 @@
#define OFF(x) ((x)%BITS_PER_LONG)
#define LONG(x) ((x)/BITS_PER_LONG)
#define BIT(x) (1 << OFF(x))
#define SETBIT(x,y) ((x)[LONG(y)] |= BIT(y))
#define CLRBIT(x,y) ((x)[LONG(y)] &= ~BIT(y))
#define ASSIGNBIT(x,y,z) ((x)[LONG(y)] = ((x)[LONG(y)] & ~BIT(y)) | (z << OFF(y)))
typedef struct _kevdevMouse {
typedef struct _kevdev {
/* current device state */
int rel[REL_MAX + 1];
int abs[ABS_MAX + 1];
@ -65,23 +62,60 @@ typedef struct _kevdevMouse {
} Kevdev;
static void
EvdevMotion (KdPointerInfo *pi)
EvdevPtrBtn (KdPointerInfo *pi, struct input_event *ev)
{
int flags = KD_MOUSE_DELTA | pi->buttonState;
if (ev->code >= BTN_MOUSE && ev->code < BTN_JOYSTICK) {
switch (ev->code) {
case BTN_LEFT:
if (ev->value == 1)
flags |= KD_BUTTON_1;
else
flags &= ~KD_BUTTON_1;
break;
case BTN_MIDDLE:
if (ev->value == 1)
flags |= KD_BUTTON_2;
else
flags &= ~KD_BUTTON_2;
break;
case BTN_RIGHT:
if (ev->value == 1)
flags |= KD_BUTTON_3;
else
flags &= ~KD_BUTTON_3;
break;
default:
/* Unknow button */
break;
}
KdEnqueuePointerEvent (pi, flags, 0, 0, 0);
}
}
static void
EvdevPtrMotion (KdPointerInfo *pi, struct input_event *ev)
{
Kevdev *ke = pi->driverPrivate;
int i;
int i;
int flags = KD_MOUSE_DELTA | pi->buttonState;
for (i = 0; i <= ke->max_rel; i++)
if (ke->rel[i])
{
int a;
ErrorF ("rel");
for (a = 0; a <= ke->max_rel; a++)
{
if (ISBITSET (ke->relbits, a))
ErrorF (" %d=%d", a, ke->rel[a]);
ke->rel[a] = 0;
{
if (a == 0)
KdEnqueuePointerEvent(pi, flags, ke->rel[a], 0, 0);
else if (a == 1)
KdEnqueuePointerEvent(pi, flags, 0, ke->rel[a], 0);
}
ke->rel[a] = 0;
}
ErrorF ("\n");
break;
}
for (i = 0; i < ke->max_abs; i++)
@ -98,10 +132,30 @@ EvdevMotion (KdPointerInfo *pi)
ErrorF ("\n");
break;
}
if (ev->code == REL_WHEEL) {
for (i = 0; i < abs (ev->value); i++)
{
if (ev->value > 0)
flags |= KD_BUTTON_4;
else
flags |= KD_BUTTON_5;
KdEnqueuePointerEvent (pi, flags, 0, 0, 0);
if (ev->value > 0)
flags &= ~KD_BUTTON_4;
else
flags &= ~KD_BUTTON_5;
KdEnqueuePointerEvent (pi, flags, 0, 0, 0);
}
}
}
static void
EvdevRead (int evdevPort, void *closure)
EvdevPtrRead (int evdevPort, void *closure)
{
KdPointerInfo *pi = closure;
Kevdev *ke = pi->driverPrivate;
@ -110,8 +164,12 @@ EvdevRead (int evdevPort, void *closure)
int n;
n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
if (n <= 0)
if (n <= 0) {
if (errno == ENODEV)
DeleteInputDeviceRequest(pi->dixdev);
return;
}
n /= sizeof (struct input_event);
for (i = 0; i < n; i++)
{
@ -119,26 +177,20 @@ EvdevRead (int evdevPort, void *closure)
case EV_SYN:
break;
case EV_KEY:
EvdevMotion (pi);
ASSIGNBIT(ke->key,events[i].code, events[i].value);
if (events[i].code < 0x100)
ErrorF ("key %d %d\n", events[i].code, events[i].value);
else
ErrorF ("key 0x%x %d\n", events[i].code, events[i].value);
EvdevPtrBtn (pi, &events[i]);
break;
case EV_REL:
ke->rel[events[i].code] += events[i].value;
EvdevPtrMotion (pi, &events[i]);
break;
case EV_ABS:
ke->abs[events[i].code] = events[i].value;
EvdevPtrMotion (pi, &events[i]);
break;
}
}
EvdevMotion (pi);
}
int EvdevInputType;
char *kdefaultEvdev[] = {
"/dev/input/event0",
"/dev/input/event1",
@ -149,7 +201,7 @@ char *kdefaultEvdev[] = {
#define NUM_DEFAULT_EVDEV (sizeof (kdefaultEvdev) / sizeof (kdefaultEvdev[0]))
static Status
EvdevInit (KdPointerInfo *pi)
EvdevPtrInit (KdPointerInfo *pi)
{
int i;
int fd;
@ -157,25 +209,29 @@ EvdevInit (KdPointerInfo *pi)
if (!pi->path) {
for (i = 0; i < NUM_DEFAULT_EVDEV; i++) {
fd = open (kdefaultEvdev[i], 2);
if (fd >= 0) {
pi->path = KdSaveString (kdefaultEvdev[i]);
break;
}
if (fd >= 0) {
pi->path = KdSaveString (kdefaultEvdev[i]);
break;
}
}
}
else {
fd = open (pi->path, 2);
fd = open (pi->path, O_RDWR);
if (fd < 0) {
ErrorF("Failed to open evdev device %s\n", pi->path);
return BadMatch;
}
}
close(fd);
pi->name = KdSaveString("Evdev mouse");
return Success;
}
static Status
EvdevEnable (KdPointerInfo *pi)
EvdevPtrEnable (KdPointerInfo *pi)
{
int fd;
@ -259,17 +315,19 @@ EvdevEnable (KdPointerInfo *pi)
return BadValue;
}
}
if (!KdRegisterFd (fd, EvdevRead, pi)) {
if (!KdRegisterFd (fd, EvdevPtrRead, pi)) {
xfree (ke);
close (fd);
return BadAlloc;
}
pi->driverPrivate = ke;
ke->fd = fd;
return Success;
}
static void
EvdevDisable (KdPointerInfo *pi)
EvdevPtrDisable (KdPointerInfo *pi)
{
Kevdev *ke;
@ -284,26 +342,195 @@ EvdevDisable (KdPointerInfo *pi)
}
static void
EvdevFini (KdPointerInfo *pi)
EvdevPtrFini (KdPointerInfo *pi)
{
}
/*
* Evdev keyboard functions
*/
static void
readMapping (KdKeyboardInfo *ki)
{
int minScanCode, maxScanCode;
if (!ki)
return;
minScanCode = 0;
maxScanCode = 193;
ki->keySyms.mapWidth = 2;
ki->minScanCode = minScanCode;
ki->maxScanCode = maxScanCode;
}
static void
EvdevKbdRead (int evdevPort, void *closure)
{
KdKeyboardInfo *ki = closure;
struct input_event events[NUM_EVENTS];
int i, n;
n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
if (n <= 0) {
if (errno == ENODEV)
DeleteInputDeviceRequest(ki->dixdev);
return;
}
n /= sizeof (struct input_event);
for (i = 0; i < n; i++)
{
if (events[i].type == EV_KEY)
KdEnqueueKeyboardEvent (ki, events[i].code, !events[i].value);
/* FIXME: must implement other types of events
else
ErrorF("Event type (%d) not delivered\n", events[i].type);
*/
}
}
static Status
EvdevKbdInit (KdKeyboardInfo *ki)
{
int fd;
if (!ki->path) {
ErrorF("Couldn't find evdev device path\n");
return BadValue;
}
else {
fd = open (ki->path, O_RDWR);
if (fd < 0) {
ErrorF("Failed to open evdev device %s\n", ki->path);
return BadMatch;
}
}
close (fd);
ki->name = KdSaveString("Evdev keyboard");
readMapping(ki);
return Success;
}
static Status
EvdevKbdEnable (KdKeyboardInfo *ki)
{
unsigned long ev[NBITS(EV_MAX)];
Kevdev *ke;
int fd;
if (!ki || !ki->path)
return BadImplementation;
fd = open(ki->path, O_RDWR);
if (fd < 0)
return BadMatch;
if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0) {
perror ("EVIOCGBIT 0");
close (fd);
return BadMatch;
}
ke = xalloc (sizeof (Kevdev));
if (!ke) {
close (fd);
return BadAlloc;
}
memset (ke, '\0', sizeof (Kevdev));
if (!KdRegisterFd (fd, EvdevKbdRead, ki)) {
xfree (ke);
close (fd);
return BadAlloc;
}
ki->driverPrivate = ke;
ke->fd = fd;
return Success;
}
static void
EvdevKbdLeds (KdKeyboardInfo *ki, int leds)
{
/* struct input_event event;
Kevdev *ke;
ki->driverPrivate = ke;
memset(&event, 0, sizeof(event));
event.type = EV_LED;
event.code = LED_CAPSL;
event.value = leds & (1 << 0) ? 1 : 0;
write(ke->fd, (char *) &event, sizeof(event));
event.type = EV_LED;
event.code = LED_NUML;
event.value = leds & (1 << 1) ? 1 : 0;
write(ke->fd, (char *) &event, sizeof(event));
event.type = EV_LED;
event.code = LED_SCROLLL;
event.value = leds & (1 << 2) ? 1 : 0;
write(ke->fd, (char *) &event, sizeof(event));
event.type = EV_LED;
event.code = LED_COMPOSE;
event.value = leds & (1 << 3) ? 1 : 0;
write(ke->fd, (char *) &event, sizeof(event));
*/
}
static void
EvdevKbdBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
{
}
static void
EvdevKbdDisable (KdKeyboardInfo *ki)
{
Kevdev *ke;
ke = ki->driverPrivate;
if (!ki || !ki->driverPrivate)
return;
KdUnregisterFd (ki, ke->fd, TRUE);
xfree (ke);
ki->driverPrivate = 0;
}
static void
EvdevKbdFini (KdKeyboardInfo *ki)
{
}
KdPointerDriver LinuxEvdevMouseDriver = {
"evdev",
EvdevInit,
EvdevEnable,
EvdevDisable,
EvdevFini,
EvdevPtrInit,
EvdevPtrEnable,
EvdevPtrDisable,
EvdevPtrFini,
NULL,
};
#if 0
KdKeyboardFuncs LinuxEvdevKeyboardFuncs = {
EvdevKbdLoad,
KdKeyboardDriver LinuxEvdevKeyboardDriver = {
"evdev",
EvdevKbdInit,
EvdevKbdEnable,
EvdevKbdLeds,
EvdevKbdBell,
EvdevKbdDisable,
EvdevKbdFini,
0,
NULL,
};
#endif

View File

@ -456,7 +456,9 @@ KdOsAddInputDrivers ()
#ifdef TSLIB
KdAddPointerDriver(&TsDriver);
#endif
KdAddPointerDriver(&LinuxEvdevMouseDriver);
KdAddKeyboardDriver(&LinuxKeyboardDriver);
KdAddKeyboardDriver(&LinuxEvdevKeyboardDriver);
}
static void

View File

@ -878,12 +878,13 @@ KdRingBell (KdKeyboardInfo *ki,
int duration);
extern KdPointerDriver LinuxMouseDriver;
extern KdPointerDriver LinuxEvdevDriver;
extern KdPointerDriver LinuxEvdevMouseDriver;
extern KdPointerDriver Ps2MouseDriver;
extern KdPointerDriver BusMouseDriver;
extern KdPointerDriver MsMouseDriver;
extern KdPointerDriver TsDriver;
extern KdKeyboardDriver LinuxKeyboardDriver;
extern KdKeyboardDriver LinuxEvdevKeyboardDriver;
extern KdOsFuncs LinuxFuncs;
extern KdPointerDriver VxWorksMouseDriver;