new KDrive input world order
Convert KDrive to GPE/GKE interface. Add first-class drivers and enumerate every device separately through Xi, instead of lamely attempting to aggregate them. Add XKB support to the Linux keyboard driver. Add 'thumb button' support to the tslib driver. Rejig InitInput, so each DDX has to add a list of drivers it supports. Support NewInputDeviceRequest, et al.
This commit is contained in:
committed by
Daniel Stone
parent
a274e7296b
commit
02d0910511
@@ -43,98 +43,100 @@
|
||||
#define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y))
|
||||
#define OFF(x) ((x)%BITS_PER_LONG)
|
||||
#define LONG(x) ((x)/BITS_PER_LONG)
|
||||
#define BIT(x) (1 << OFF(x))
|
||||
#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 {
|
||||
/* current device state */
|
||||
int rel[REL_MAX + 1];
|
||||
int abs[ABS_MAX + 1];
|
||||
int prevabs[ABS_MAX + 1];
|
||||
long key[NBITS(KEY_MAX + 1)];
|
||||
int rel[REL_MAX + 1];
|
||||
int abs[ABS_MAX + 1];
|
||||
int prevabs[ABS_MAX + 1];
|
||||
long key[NBITS(KEY_MAX + 1)];
|
||||
|
||||
/* supported device info */
|
||||
long relbits[NBITS(REL_MAX + 1)];
|
||||
long absbits[NBITS(ABS_MAX + 1)];
|
||||
long keybits[NBITS(KEY_MAX + 1)];
|
||||
long relbits[NBITS(REL_MAX + 1)];
|
||||
long absbits[NBITS(ABS_MAX + 1)];
|
||||
long keybits[NBITS(KEY_MAX + 1)];
|
||||
struct input_absinfo absinfo[ABS_MAX + 1];
|
||||
int max_rel;
|
||||
int max_abs;
|
||||
int max_rel;
|
||||
int max_abs;
|
||||
|
||||
int fd;
|
||||
} Kevdev;
|
||||
|
||||
static void
|
||||
EvdevMotion (KdMouseInfo *mi)
|
||||
EvdevMotion (KdPointerInfo *pi)
|
||||
{
|
||||
Kevdev *ke = mi->driver;
|
||||
int i;
|
||||
Kevdev *ke = pi->driverPrivate;
|
||||
int i;
|
||||
|
||||
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;
|
||||
}
|
||||
ErrorF ("\n");
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
ErrorF ("\n");
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < ke->max_abs; i++)
|
||||
if (ke->abs[i] != ke->prevabs[i])
|
||||
{
|
||||
int a;
|
||||
ErrorF ("abs");
|
||||
for (a = 0; a <= ke->max_abs; a++)
|
||||
{
|
||||
if (ISBITSET (ke->absbits, a))
|
||||
ErrorF (" %d=%d", a, ke->abs[a]);
|
||||
ke->prevabs[a] = ke->abs[a];
|
||||
}
|
||||
ErrorF ("\n");
|
||||
break;
|
||||
}
|
||||
if (ke->abs[i] != ke->prevabs[i])
|
||||
{
|
||||
int a;
|
||||
ErrorF ("abs");
|
||||
for (a = 0; a <= ke->max_abs; a++)
|
||||
{
|
||||
if (ISBITSET (ke->absbits, a))
|
||||
ErrorF (" %d=%d", a, ke->abs[a]);
|
||||
ke->prevabs[a] = ke->abs[a];
|
||||
}
|
||||
ErrorF ("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
EvdevRead (int evdevPort, void *closure)
|
||||
{
|
||||
KdMouseInfo *mi = closure;
|
||||
Kevdev *ke = mi->driver;
|
||||
int i;
|
||||
struct input_event events[NUM_EVENTS];
|
||||
int n;
|
||||
KdPointerInfo *pi = closure;
|
||||
Kevdev *ke = pi->driverPrivate;
|
||||
int i;
|
||||
struct input_event events[NUM_EVENTS];
|
||||
int n;
|
||||
|
||||
n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
|
||||
if (n <= 0)
|
||||
return;
|
||||
return;
|
||||
n /= sizeof (struct input_event);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
switch (events[i].type) {
|
||||
case EV_SYN:
|
||||
break;
|
||||
case EV_KEY:
|
||||
EvdevMotion (mi);
|
||||
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);
|
||||
break;
|
||||
case EV_REL:
|
||||
ke->rel[events[i].code] += events[i].value;
|
||||
break;
|
||||
case EV_ABS:
|
||||
ke->abs[events[i].code] = events[i].value;
|
||||
break;
|
||||
}
|
||||
switch (events[i].type) {
|
||||
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);
|
||||
break;
|
||||
case EV_REL:
|
||||
ke->rel[events[i].code] += events[i].value;
|
||||
break;
|
||||
case EV_ABS:
|
||||
ke->abs[events[i].code] = events[i].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EvdevMotion (mi);
|
||||
EvdevMotion (pi);
|
||||
}
|
||||
|
||||
int EvdevInputType;
|
||||
@@ -148,143 +150,153 @@ char *kdefaultEvdev[] = {
|
||||
|
||||
#define NUM_DEFAULT_EVDEV (sizeof (kdefaultEvdev) / sizeof (kdefaultEvdev[0]))
|
||||
|
||||
static Bool
|
||||
EvdevInit (void)
|
||||
static Status
|
||||
EvdevInit (KdPointerInfo *pi)
|
||||
{
|
||||
int i;
|
||||
int fd;
|
||||
KdMouseInfo *mi, *next;
|
||||
int n = 0;
|
||||
char *prot;
|
||||
int i;
|
||||
int fd;
|
||||
int n = 0;
|
||||
char *prot;
|
||||
|
||||
if (!EvdevInputType)
|
||||
EvdevInputType = KdAllocInputType ();
|
||||
|
||||
for (mi = kdMouseInfo; mi; mi = next)
|
||||
{
|
||||
next = mi->next;
|
||||
prot = mi->prot;
|
||||
if (mi->inputType)
|
||||
continue;
|
||||
if (!mi->name)
|
||||
{
|
||||
for (i = 0; i < NUM_DEFAULT_EVDEV; i++)
|
||||
{
|
||||
fd = open (kdefaultEvdev[i], 2);
|
||||
if (fd >= 0)
|
||||
{
|
||||
mi->name = KdSaveString (kdefaultEvdev[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
fd = open (mi->name, 2);
|
||||
|
||||
if (fd >= 0)
|
||||
{
|
||||
unsigned long ev[NBITS(EV_MAX)];
|
||||
Kevdev *ke;
|
||||
|
||||
if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0)
|
||||
{
|
||||
perror ("EVIOCGBIT 0");
|
||||
close (fd);
|
||||
continue;
|
||||
}
|
||||
ke = xalloc (sizeof (Kevdev));
|
||||
if (!ke)
|
||||
{
|
||||
close (fd);
|
||||
continue;
|
||||
}
|
||||
memset (ke, '\0', sizeof (Kevdev));
|
||||
if (ISBITSET (ev, EV_KEY))
|
||||
{
|
||||
if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)),
|
||||
ke->keybits) < 0)
|
||||
{
|
||||
perror ("EVIOCGBIT EV_KEY");
|
||||
xfree (ke);
|
||||
close (fd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (ISBITSET (ev, EV_REL))
|
||||
{
|
||||
if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)),
|
||||
ke->relbits) < 0)
|
||||
{
|
||||
perror ("EVIOCGBIT EV_REL");
|
||||
xfree (ke);
|
||||
close (fd);
|
||||
continue;
|
||||
}
|
||||
for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--)
|
||||
if (ISBITSET(ke->relbits, ke->max_rel))
|
||||
break;
|
||||
}
|
||||
if (ISBITSET (ev, EV_ABS))
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)),
|
||||
ke->absbits) < 0)
|
||||
{
|
||||
perror ("EVIOCGBIT EV_ABS");
|
||||
xfree (ke);
|
||||
close (fd);
|
||||
continue;
|
||||
}
|
||||
for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--)
|
||||
if (ISBITSET(ke->absbits, ke->max_abs))
|
||||
break;
|
||||
for (i = 0; i <= ke->max_abs; i++)
|
||||
{
|
||||
if (ISBITSET (ke->absbits, i))
|
||||
if (ioctl (fd, EVIOCGABS(i), &ke->absinfo[i]) < 0)
|
||||
{
|
||||
perror ("EVIOCGABS");
|
||||
break;
|
||||
}
|
||||
ke->prevabs[i] = ABS_UNSET;
|
||||
}
|
||||
if (i <= ke->max_abs)
|
||||
{
|
||||
xfree (ke);
|
||||
close (fd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
mi->driver = ke;
|
||||
mi->inputType = EvdevInputType;
|
||||
if (KdRegisterFd (EvdevInputType, fd, EvdevRead, (void *) mi))
|
||||
n++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
else {
|
||||
fd = open (pi->path, 2);
|
||||
if (fd < 0) {
|
||||
ErrorF("Failed to open evdev device %s\n", pi->path);
|
||||
return BadMatch;
|
||||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static Status
|
||||
EvdevEnable (KdPointerInfo *pi)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (!pi || !pi->path)
|
||||
return BadImplementation;
|
||||
|
||||
fd = open(pi->path, 2);
|
||||
if (fd < 0)
|
||||
return BadMatch;
|
||||
|
||||
unsigned long ev[NBITS(EV_MAX)];
|
||||
Kevdev *ke;
|
||||
|
||||
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 (ISBITSET (ev, EV_KEY))
|
||||
{
|
||||
if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)),
|
||||
ke->keybits) < 0)
|
||||
{
|
||||
perror ("EVIOCGBIT EV_KEY");
|
||||
xfree (ke);
|
||||
close (fd);
|
||||
return BadMatch;
|
||||
}
|
||||
}
|
||||
if (ISBITSET (ev, EV_REL))
|
||||
{
|
||||
if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)),
|
||||
ke->relbits) < 0)
|
||||
{
|
||||
perror ("EVIOCGBIT EV_REL");
|
||||
xfree (ke);
|
||||
close (fd);
|
||||
return BadMatch;
|
||||
}
|
||||
for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--)
|
||||
if (ISBITSET(ke->relbits, ke->max_rel))
|
||||
break;
|
||||
}
|
||||
if (ISBITSET (ev, EV_ABS))
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)),
|
||||
ke->absbits) < 0)
|
||||
{
|
||||
perror ("EVIOCGBIT EV_ABS");
|
||||
xfree (ke);
|
||||
close (fd);
|
||||
return BadMatch;
|
||||
}
|
||||
for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--)
|
||||
if (ISBITSET(ke->absbits, ke->max_abs))
|
||||
break;
|
||||
for (i = 0; i <= ke->max_abs; i++)
|
||||
{
|
||||
if (ISBITSET (ke->absbits, i))
|
||||
if (ioctl (fd, EVIOCGABS(i), &ke->absinfo[i]) < 0)
|
||||
{
|
||||
perror ("EVIOCGABS");
|
||||
break;
|
||||
}
|
||||
ke->prevabs[i] = ABS_UNSET;
|
||||
}
|
||||
if (i <= ke->max_abs)
|
||||
{
|
||||
xfree (ke);
|
||||
close (fd);
|
||||
return BadValue;
|
||||
}
|
||||
}
|
||||
if (!KdRegisterFd (fd, EvdevRead, pi)) {
|
||||
xfree (ke);
|
||||
close (fd);
|
||||
return BadAlloc;
|
||||
}
|
||||
pi->driverPrivate = ke;
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
EvdevFini (void)
|
||||
EvdevDisable (KdPointerInfo *pi)
|
||||
{
|
||||
KdMouseInfo *mi;
|
||||
Kevdev *ke;
|
||||
|
||||
KdUnregisterFds (EvdevInputType, TRUE);
|
||||
for (mi = kdMouseInfo; mi; mi = mi->next)
|
||||
{
|
||||
if (mi->inputType == EvdevInputType)
|
||||
{
|
||||
xfree (mi->driver);
|
||||
mi->driver = 0;
|
||||
mi->inputType = 0;
|
||||
}
|
||||
}
|
||||
if (!pi || !pi->driverPrivate)
|
||||
return;
|
||||
|
||||
KdUnregisterFd (pi, ke->fd, TRUE);
|
||||
xfree (ke);
|
||||
pi->driverPrivate = 0;
|
||||
}
|
||||
|
||||
KdMouseFuncs LinuxEvdevMouseFuncs = {
|
||||
static void
|
||||
EvdevFini (KdPointerInfo *pi)
|
||||
{
|
||||
}
|
||||
|
||||
KdPointerDriver LinuxEvdevMouseDriver = {
|
||||
"evdev",
|
||||
EvdevInit,
|
||||
EvdevEnable,
|
||||
EvdevDisable,
|
||||
EvdevFini,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
Reference in New Issue
Block a user