summaryrefslogtreecommitdiff
path: root/hw/kdrive
diff options
context:
space:
mode:
Diffstat (limited to 'hw/kdrive')
-rw-r--r--hw/kdrive/ephyr/ephyrinit.c35
-rw-r--r--hw/kdrive/linux/evdev.c309
-rw-r--r--hw/kdrive/linux/linux.c2
-rw-r--r--hw/kdrive/linux/tslib.c2
-rw-r--r--hw/kdrive/src/kasync.c27
-rw-r--r--hw/kdrive/src/kdrive.c37
-rw-r--r--hw/kdrive/src/kdrive.h22
-rw-r--r--hw/kdrive/src/kinput.c161
8 files changed, 439 insertions, 156 deletions
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index 45e2d3067..a76da03b4 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -30,6 +30,8 @@
extern Window EphyrPreExistingHostWin;
extern Bool EphyrWantGrayScale;
+extern Bool kdHasPointer;
+extern Bool kdHasKbd;
void
InitCard (char *name)
@@ -54,19 +56,30 @@ InitInput (int argc, char **argv)
KdKeyboardInfo *ki;
KdPointerInfo *pi;
- ki = KdNewKeyboard();
- if (!ki)
- FatalError("Couldn't create Xephyr keyboard\n");
- ki->driver = &EphyrKeyboardDriver;
KdAddKeyboardDriver(&EphyrKeyboardDriver);
- KdAddKeyboard(ki);
-
- pi = KdNewPointer();
- if (!pi)
- FatalError("Couldn't create Xephyr pointer\n");
- pi->driver = &EphyrMouseDriver;
+#ifdef linux
+ KdAddKeyboardDriver(&LinuxEvdevKeyboardDriver);
+#endif
KdAddPointerDriver(&EphyrMouseDriver);
- KdAddPointer(pi);
+#ifdef linux
+ KdAddPointerDriver(&LinuxEvdevMouseDriver);
+#endif
+
+ if (!kdHasKbd) {
+ ki = KdNewKeyboard();
+ if (!ki)
+ FatalError("Couldn't create Xephyr keyboard\n");
+ ki->driver = &EphyrKeyboardDriver;
+ KdAddKeyboard(ki);
+ }
+
+ if (!kdHasPointer) {
+ pi = KdNewPointer();
+ if (!pi)
+ FatalError("Couldn't create Xephyr pointer\n");
+ pi->driver = &EphyrMouseDriver;
+ KdAddPointer(pi);
+ }
KdInitInput();
}
diff --git a/hw/kdrive/linux/evdev.c b/hw/kdrive/linux/evdev.c
index 79527c70d..2eaa1e332 100644
--- a/hw/kdrive/linux/evdev.c
+++ b/hw/kdrive/linux/evdev.c
@@ -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 (ISBITSET (ke->relbits, a))
+ {
+ 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
diff --git a/hw/kdrive/linux/linux.c b/hw/kdrive/linux/linux.c
index 0e4a77cdf..23cd8f59f 100644
--- a/hw/kdrive/linux/linux.c
+++ b/hw/kdrive/linux/linux.c
@@ -456,7 +456,9 @@ KdOsAddInputDrivers ()
#ifdef TSLIB
KdAddPointerDriver(&TsDriver);
#endif
+ KdAddPointerDriver(&LinuxEvdevMouseDriver);
KdAddKeyboardDriver(&LinuxKeyboardDriver);
+ KdAddKeyboardDriver(&LinuxEvdevKeyboardDriver);
}
static void
diff --git a/hw/kdrive/linux/tslib.c b/hw/kdrive/linux/tslib.c
index 41b74fabd..371aeced9 100644
--- a/hw/kdrive/linux/tslib.c
+++ b/hw/kdrive/linux/tslib.c
@@ -118,7 +118,7 @@ TslibEnable (KdPointerInfo *pi)
private->fd = ts_fd(private->tsDev);
if (!private->tsDev || ts_config(private->tsDev) || private->fd < 0) {
ErrorF("[tslib/TslibEnable] failed to open %s\n", pi->path);
- if (private->fd > 0);
+ if (private->fd >= 0)
close(private->fd);
return BadAlloc;
}
diff --git a/hw/kdrive/src/kasync.c b/hw/kdrive/src/kasync.c
index cc751112c..51909630e 100644
--- a/hw/kdrive/src/kasync.c
+++ b/hw/kdrive/src/kasync.c
@@ -224,30 +224,6 @@ KdCheckGetSpans (DrawablePtr pDrawable,
}
void
-KdCheckSaveAreas (PixmapPtr pPixmap,
- RegionPtr prgnSave,
- int xorg,
- int yorg,
- WindowPtr pWin)
-{
- kaaWaitSync(pWin->drawable.pScreen);
- kaaDrawableDirty (&pPixmap->drawable);
- fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
-}
-
-void
-KdCheckRestoreAreas (PixmapPtr pPixmap,
- RegionPtr prgnSave,
- int xorg,
- int yorg,
- WindowPtr pWin)
-{
- kaaWaitSync(pWin->drawable.pScreen);
- kaaDrawableDirty ((DrawablePtr)pWin);
- fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
-}
-
-void
KdCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
{
kaaWaitSync (pWin->drawable.pScreen);
@@ -292,9 +268,6 @@ KdScreenInitAsync (ScreenPtr pScreen)
pScreen->PaintWindowBackground = KdCheckPaintWindow;
pScreen->PaintWindowBorder = KdCheckPaintWindow;
pScreen->CopyWindow = KdCheckCopyWindow;
-
- pScreen->BackingStoreFuncs.SaveAreas = KdCheckSaveAreas;
- pScreen->BackingStoreFuncs.RestoreAreas = KdCheckRestoreAreas;
#ifdef RENDER
KdPictureInitAsync (pScreen);
#endif
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index 8653d72a2..8c4342eaa 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -81,6 +81,8 @@ int kdVirtualTerminal = -1;
Bool kdSwitchPending;
char *kdSwitchCmd;
DDXPointRec kdOrigin;
+Bool kdHasPointer = FALSE;
+Bool kdHasKbd = FALSE;
static Bool kdCaughtSignal = FALSE;
@@ -99,7 +101,7 @@ KdSetRootClip (ScreenPtr pScreen, BOOL enable)
WindowPtr pChild;
Bool WasViewable;
Bool anyMarked = FALSE;
- RegionPtr pOldClip = 0, bsExposed;
+ RegionPtr pOldClip = 0;
#ifdef DO_SAVE_UNDERS
Bool dosave = FALSE;
#endif
@@ -157,12 +159,6 @@ KdSetRootClip (ScreenPtr pScreen, BOOL enable)
if (WasViewable)
{
- if (pWin->backStorage)
- {
- pOldClip = REGION_CREATE(pScreen, NullBox, 1);
- REGION_COPY(pScreen, pOldClip, &pWin->clipList);
- }
-
if (pWin->firstChild)
{
anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
@@ -186,28 +182,6 @@ KdSetRootClip (ScreenPtr pScreen, BOOL enable)
(*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
}
- if (pWin->backStorage &&
- ((pWin->backingStore == Always) || WasViewable))
- {
- if (!WasViewable)
- pOldClip = &pWin->clipList; /* a convenient empty region */
- bsExposed = (*pScreen->TranslateBackingStore)
- (pWin, 0, 0, pOldClip,
- pWin->drawable.x, pWin->drawable.y);
- if (WasViewable)
- REGION_DESTROY(pScreen, pOldClip);
- if (bsExposed)
- {
- RegionPtr valExposed = NullRegion;
-
- if (pWin->valdata)
- valExposed = &pWin->valdata->after.exposed;
- (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
- if (valExposed)
- REGION_EMPTY(pScreen, valExposed);
- REGION_DESTROY(pScreen, bsExposed);
- }
- }
if (WasViewable)
{
if (anyMarked)
@@ -596,6 +570,8 @@ KdUseMsg (void)
ErrorF("-card pcmcia Use PCMCIA card as additional screen\n");
ErrorF("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM][@ROTATION][X][Y][xDEPTH/BPP{,DEPTH/BPP}[xFREQ]] Specify screen characteristics\n");
ErrorF("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\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");
ErrorF("-zaphod Disable cursor screen switching\n");
ErrorF("-2button Emulate 3 button mouse\n");
ErrorF("-3button Disable 3 button mouse emulation\n");
@@ -604,7 +580,6 @@ KdUseMsg (void)
ErrorF("-softCursor Force software cursor\n");
ErrorF("-videoTest Start the server, pause momentarily and exit\n");
ErrorF("-origin X,Y Locates the next screen in the the virtual screen (Xinerama)\n");
- ErrorF("-mouse path[,n] Filename of mouse device, n is number of buttons\n");
ErrorF("-switchCmd Command to execute on vt switch\n");
ErrorF("-nozap Don't terminate server on Ctrl+Alt+Backspace\n");
ErrorF("vtxx Use virtual terminal xx instead of the next available\n");
@@ -737,12 +712,14 @@ KdProcessArgument (int argc, char **argv, int i)
if (i + 1 >= argc)
UseMsg();
KdAddConfigPointer(argv[i + 1]);
+ kdHasPointer = TRUE;
return 2;
}
if (!strcmp (argv[i], "-keybd")) {
if (i + 1 >= argc)
UseMsg();
KdAddConfigKeyboard(argv[i + 1]);
+ kdHasKbd = TRUE;
return 2;
}
diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h
index 2ebde2203..2da008df9 100644
--- a/hw/kdrive/src/kdrive.h
+++ b/hw/kdrive/src/kdrive.h
@@ -330,6 +330,11 @@ struct _KdKeyboardInfo {
int inputClass;
#ifdef XKB
XkbDescPtr xkb;
+ char *xkbRules;
+ char *xkbModel;
+ char *xkbLayout;
+ char *xkbVariant;
+ char *xkbOptions;
#endif
int LockLed;
@@ -607,20 +612,6 @@ KdCheckGetSpans (DrawablePtr pDrawable,
char *pdstStart);
void
-KdCheckSaveAreas (PixmapPtr pPixmap,
- RegionPtr prgnSave,
- int xorg,
- int yorg,
- WindowPtr pWin);
-
-void
-KdCheckRestoreAreas (PixmapPtr pPixmap,
- RegionPtr prgnSave,
- int xorg,
- int yorg,
- WindowPtr pWin);
-
-void
KdCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what);
void
@@ -873,12 +864,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;
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index cfd162f57..6c247c185 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -792,7 +792,9 @@ KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
if (!noXkbExtension) {
memset(&names, 0, sizeof(XkbComponentNamesRec));
- XkbSetRulesDflts ("base", "pc105", "us", NULL, NULL);
+ XkbSetRulesDflts (ki->xkbRules, ki->xkbModel, ki->xkbLayout,
+ ki->xkbVariant, ki->xkbOptions);
+
ret = XkbInitKeyboardDeviceStruct (pDevice,
&names,
&ki->keySyms,
@@ -961,6 +963,13 @@ KdNewKeyboard (void)
ki->bellDuration = 200;
ki->next = NULL;
ki->options = NULL;
+#ifdef XKB
+ ki->xkbRules = KdSaveString("base");
+ ki->xkbModel = KdSaveString("pc105");
+ ki->xkbLayout = KdSaveString("us");
+ ki->xkbVariant = NULL;
+ ki->xkbOptions = NULL;
+#endif
return ki;
}
@@ -1096,11 +1105,78 @@ KdRemovePointer (KdPointerInfo *pi)
KdFreePointer(pi);
}
+/*
+ * You can call your kdriver server with something like:
+ * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd
+ * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br
+ */
+static Bool
+KdGetOptions (InputOption **options, char *string)
+{
+ InputOption *newopt = NULL, **tmpo = NULL;
+ int tam_key = 0;
+
+ newopt = (InputOption *) xalloc(sizeof (InputOption));
+ if (!newopt)
+ return FALSE;
+
+ bzero(newopt, sizeof (InputOption));
+
+ for (tmpo = options; *tmpo; tmpo = &(*tmpo)->next)
+ ; /* Hello, I'm here */
+ *tmpo = newopt;
+
+ if (strchr(string, '='))
+ {
+ tam_key = (strchr(string, '=') - string);
+ newopt->key = (char *)xalloc(tam_key);
+ strncpy(newopt->key, string, tam_key);
+ newopt->key[tam_key] = '\0';
+ newopt->value = xstrdup(strchr(string, '=') + 1);
+ }
+ else
+ {
+ newopt->key = xstrdup(string);
+ newopt->value = NULL;
+ }
+ newopt->next = NULL;
+
+ return TRUE;
+}
+
+static void
+KdParseKbdOptions (KdKeyboardInfo *ki)
+{
+ InputOption *option = NULL;
+
+ for (option = ki->options; option; option = option->next)
+ {
+#ifdef XKB
+ if (strcasecmp(option->key, "XkbRules") == 0)
+ ki->xkbRules = option->value;
+ else if (strcasecmp(option->key, "XkbModel") == 0)
+ ki->xkbModel = option->value;
+ else if (strcasecmp(option->key, "XkbLayout") == 0)
+ ki->xkbLayout = option->value;
+ else if (strcasecmp(option->key, "XkbVariant") == 0)
+ ki->xkbVariant = option->value;
+ else if (strcasecmp(option->key, "XkbOptions") == 0)
+ ki->xkbOptions = option->value;
+ else if (!strcasecmp (option->key, "device"))
+ ki->path = KdSaveString(option->value);
+ else
+#endif
+ ErrorF("Kbd option key (%s) of value (%s) not assigned!\n",
+ option->key, option->value);
+ }
+}
+
KdKeyboardInfo *
KdParseKeyboard (char *arg)
{
char save[1024];
char delim;
+ InputOption *options = NULL;
KdKeyboardInfo *ki = NULL;
ki = KdNewKeyboard();
@@ -1143,18 +1219,63 @@ KdParseKeyboard (char *arg)
else
ki->driverPrivate = xstrdup(save);
- /* FIXME actually implement options */
+ if (delim != ',')
+ {
+ return ki;
+ }
+
+ arg = KdParseFindNext (arg, ",", save, &delim);
+
+ while (delim == ',')
+ {
+ arg = KdParseFindNext (arg, ",", save, &delim);
+
+ if (!KdGetOptions(&options, save))
+ {
+ KdFreeKeyboard(ki);
+ return NULL;
+ }
+ }
+
+ if (options)
+ {
+ ki->options = options;
+ KdParseKbdOptions(ki);
+ }
return ki;
}
+static void
+KdParsePointerOptions (KdPointerInfo *pi)
+{
+ InputOption *option = NULL;
+
+ for (option = pi->options; option; option = option->next)
+ {
+ if (!strcmp (option->key, "emulatemiddle"))
+ pi->emulateMiddleButton = TRUE;
+ else if (!strcmp (option->key, "noemulatemiddle"))
+ pi->emulateMiddleButton = FALSE;
+ else if (!strcmp (option->key, "transformcoord"))
+ pi->transformCoordinates = TRUE;
+ else if (!strcmp (option->key, "rawcoord"))
+ pi->transformCoordinates = FALSE;
+ else if (!strcasecmp (option->key, "device"))
+ pi->path = KdSaveString(option->value);
+ else
+ ErrorF("Pointer option key (%s) of value (%s) not assigned!\n",
+ option->key, option->value);
+ }
+}
+
KdPointerInfo *
KdParsePointer (char *arg)
{
char save[1024];
char delim;
KdPointerInfo *pi = NULL;
- InputOption *options = NULL, *newopt = NULL, **tmpo = NULL;
+ InputOption *options = NULL;
int i = 0;
pi = KdNewPointer();
@@ -1214,45 +1335,21 @@ KdParsePointer (char *arg)
s++;
}
}
- else if (!strcmp (save, "emulatemiddle"))
- pi->emulateMiddleButton = TRUE;
- else if (!strcmp (save, "noemulatemiddle"))
- pi->emulateMiddleButton = FALSE;
- else if (!strcmp (save, "transformcoord"))
- pi->transformCoordinates = TRUE;
- else if (!strcmp (save, "rawcoord"))
- pi->transformCoordinates = FALSE;
else
{
- newopt = (InputOption *) xalloc(sizeof (InputOption));
- if (!newopt)
+ if (!KdGetOptions(&options, save))
{
KdFreePointer(pi);
return NULL;
}
- bzero(newopt, sizeof (InputOption));
-
- for (tmpo = &options; *tmpo; tmpo = &(*tmpo)->next)
- *tmpo = newopt;
-
- if (strchr(arg, '='))
- {
- i = (strchr(arg, '=') - arg);
- newopt->key = (char *)xalloc(i+1);
- strncpy(newopt->key, arg, i+1);
- newopt->value = xstrdup(strchr(arg, '=') + 1);
- }
- else
- {
- newopt->key = xstrdup(save);
- newopt->value = NULL;
- }
- newopt->next = NULL;
}
}
if (options)
+ {
pi->options = options;
+ KdParsePointerOptions(pi);
+ }
return pi;
}
@@ -2336,6 +2433,8 @@ NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev)
return BadValue;
}
+ /* FIXME: change this code below to use KdParseKbdOptions and
+ * KdParsePointerOptions */
for (option = options; option; option = option->next) {
if (strcmp(option->key, "device") == 0) {
if (pi && option->value)