diff options
Diffstat (limited to 'hw/kdrive/src/kloadmap.c')
-rw-r--r-- | hw/kdrive/src/kloadmap.c | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/hw/kdrive/src/kloadmap.c b/hw/kdrive/src/kloadmap.c new file mode 100644 index 000000000..bd8e31cbd --- /dev/null +++ b/hw/kdrive/src/kloadmap.c @@ -0,0 +1,200 @@ +/* + * $Id$ + * + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +/* $XFree86: $ */ + +#include "kdrive.h" +#include "kkeymap.h" + +#ifdef WINDOWS +#define KM_BUF 1024 +#define KM_EOF -1 + +typedef struct _km_file { + HANDLE handle; + char buf[KM_BUF]; + char *bufptr; + DWORD remain; +} km_file; + +int +km_fill (km_file *kf) +{ + BOOL r; + + NCD_DEBUG ((DEBUG_INIT, "km_fill")); + r = ReadFile (kf->handle, kf->buf, KM_BUF, + &kf->remain, NULL); + NCD_DEBUG ((DEBUG_INIT, "Got %d", kf->remain)); + if (!r || !kf->remain) + return KM_EOF; + kf->bufptr = kf->buf; + --kf->remain; + return *kf->bufptr++; +} + +#define km_getchar(kf) ((kf)->remain-- ? *kf->bufptr++ : km_fill (kf)) +#else +#define km_getchar(kf) getc(kf) +#endif + +BOOL +km_word (km_file *kf, char *buf, int len) +{ + int c; + + for (;;) + { + switch (c = km_getchar (kf)) { + case KM_EOF: + return FALSE; + case ' ': + case '\t': + case '\n': + case '\r': + continue; + } + break; + } + len--; + while (len--) + { + *buf++ = c; + switch (c = km_getchar (kf)) { + case KM_EOF: + case ' ': + case '\t': + case '\n': + case '\r': + *buf++ = '\0'; + return TRUE; + } + } + return FALSE; +} + +BOOL +km_int (km_file *kf, int *r) +{ + char word[64]; + + if (km_word (kf, word, sizeof (word))) + { + *r = strtol (word, NULL, 0); + return TRUE; + } + return FALSE; +} + +WCHAR *winKbdExtensions[] = { + L".xku", + L".xkb" +}; + +#define NUM_KBD_EXTENSIONS (sizeof (winKbdExtensions) / sizeof (winKbdExtensions[0])) + +BOOL +winLoadKeymap (void) +{ + WCHAR file[32 + KL_NAMELENGTH]; + WCHAR name[KL_NAMELENGTH]; + HKL layout; + km_file kf; + int width; + BOOL ret; + KeySym *m; + int scancode; + int w; + int e; + + layout = GetKeyboardLayout (0); + /* + * Pre-build 46 versions of ThinSTAR software return 0 + * for all layouts + */ + if (!layout) + return FALSE; + NCD_DEBUG ((DEBUG_INIT, "Keyboard layout 0x%x", layout)); + for (e = 0; e < NUM_KBD_EXTENSIONS; e++) + { + wstrcpy (file, L"\\Storage Card\\"); + wsprintf (name, TEXT("%08x"), layout); + wstrcat (file, name); + wstrcat (file, winKbdExtensions[e]); + NCD_DEBUG ((DEBUG_INIT, "Loading keymap from %S", file)); + kf.handle = CreateFile (file, + GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (kf.handle != INVALID_HANDLE_VALUE) + break; + } + if (kf.handle == INVALID_HANDLE_VALUE) + { + NCD_DEBUG ((DEBUG_INIT, "No such file")); + return FALSE; + } + ret = FALSE; + kf.remain = 0; + /* + * Keymap format: + * + * flags (optional) + * width + * keycode -> keysym array (num_keycodes * width) + */ + if (!km_int (&kf, &width)) + goto bail1; + if (width & KEYMAP_FLAGS) + { + CEKeymapFlags = (unsigned long) width; + if (!km_int (&kf, &width)) + goto bail1; + } + else + CEKeymapFlags = 0; + if (width > MAX_WIDTH) + goto bail1; + NCD_DEBUG ((DEBUG_INIT, "Keymap width %d flags 0x%x", + width, CEKeymapFlags)); + m = CEKeymap; + for (scancode = MIN_SCANCODE; scancode <= MAX_SCANCODE; scancode++) + { + for (w = 0; w < width; w++) + { + if (!km_int (&kf, m)) + break; + m++; + } + if (w != width) + break; + } + CEKeySyms.mapWidth = width; + ret = TRUE; +bail1: + CloseHandle (kf.handle); + return ret; +} |