diff options
Diffstat (limited to 'hw/kdrive')
-rw-r--r-- | hw/kdrive/ephyr/ephyrinit.c | 35 | ||||
-rw-r--r-- | hw/kdrive/linux/evdev.c | 309 | ||||
-rw-r--r-- | hw/kdrive/linux/linux.c | 2 | ||||
-rw-r--r-- | hw/kdrive/linux/tslib.c | 2 | ||||
-rw-r--r-- | hw/kdrive/src/kasync.c | 27 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.c | 37 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.h | 22 | ||||
-rw-r--r-- | hw/kdrive/src/kinput.c | 161 |
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) |