Subject: Re: XKB keymap patch.
To: None <port-hpcmips@NetBSD.org, port-hpcsh@NetBSD.org,>
From: UCHIYAMA Yasushi <uch@vnop.net>
List: port-hpcmips
Date: 07/21/2004 04:30:10
I've also added keymap coversion routine. When open wskbd* instead of ttyE*,
use this keymap.

Index: atKeynames.h
===================================================================
RCS file: /cvsroot/xsrc/xfree/xc/programs/Xserver/hw/netbsd/hpc/atKeynames.h,v
retrieving revision 1.1
diff -u -r1.1 atKeynames.h
--- atKeynames.h	3 Jan 2004 01:09:19 -0000	1.1
+++ atKeynames.h	20 Jul 2004 17:42:31 -0000
@@ -1,5 +1,5 @@
-/* $XConsortium: atKeynames.h,v 1.6 95/01/13 19:19:20 kaleb Exp $ */
-/* $XFree86: xc/programs/Xserver/hw/xfree86/common/atKeynames.h,v 3.5 1995/06/24 10:28:16 dawes Exp $ */
+/* $NetBSD$ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/common/atKeynames.h,v 3.22 2004/02/13 23:58:35 dawes Exp $ */
 /*
  * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
  *
@@ -22,19 +22,67 @@
  * PERFORMANCE OF THIS SOFTWARE.
  *
  */
+/*
+ * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ *   1.  Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions, and the following disclaimer.
+ *
+ *   2.  Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer
+ *       in the documentation and/or other materials provided with the
+ *       distribution, and in the same place and form as other copyright,
+ *       license and disclaimer information.
+ *
+ *   3.  The end-user documentation included with the redistribution,
+ *       if any, must include the following acknowledgment: "This product
+ *       includes software developed by The XFree86 Project, Inc
+ *       (http://www.xfree86.org/) and its contributors", in the same
+ *       place and form as other third-party acknowledgments.  Alternately,
+ *       this acknowledgment may appear in the software itself, in the
+ *       same form and location as other such third-party acknowledgments.
+ *
+ *   4.  Except as contained in this notice, the name of The XFree86
+ *       Project, Inc shall not be used in advertising or otherwise to
+ *       promote the sale, use or other dealings in this Software without
+ *       prior written authorization from The XFree86 Project, Inc.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE XFREE86 PROJECT, INC OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* $XConsortium: atKeynames.h /main/11 1996/03/09 11:17:41 kaleb $ */
 
 #ifndef _ATKEYNAMES_H
 #define _ATKEYNAMES_H
 
 #define XK_TECHNICAL
+#define	XK_KATAKANA
 #include "keysym.h"
+#include "XF86keysym.h"
 
 #define GLYPHS_PER_KEY	4
-#define NUM_KEYCODES	150
-#define NUM_STD_KEYCODES 127
+#define NUM_KEYCODES	(255 - MIN_KEYCODE)
 #define MIN_KEYCODE     8
 #define MAX_KEYCODE     (NUM_KEYCODES + MIN_KEYCODE - 1)
-#define MAX_STD_KEYCODE (NUM_STD_KEYCODES + MIN_KEYCODE - 1)
 
 #define AltMask		Mod1Mask
 #define NumLockMask	Mod2Mask
@@ -45,8 +93,6 @@
 #define KeyPressed(k) (keyc->down[k >> 3] & (1 << (k & 7)))
 #define ModifierDown(k) ((keyc->state & (k)) == (k))
 
-#define XF86XK_ModeLock	0x1008FF01                 /* Mode Switch Lock */
-
 /*
  * NOTE: The AT/MF keyboards can generate (via the 8042) two (MF: three)
  *       sets of scancodes. Set3 can only be generated by a MF keyboard.
@@ -70,6 +116,7 @@
  *      Key Name            Main       Also       (hex)    (dec)
  *      ----------------   ---------- -------    ------    ------
  */
+
 #define KEY_Escape       /* Escape                0x01  */    1  
 #define KEY_1            /* 1           !         0x02  */    2 
 #define KEY_2            /* 2           @         0x03  */    3 
@@ -181,7 +228,7 @@
 #define KEY_RCtrl        /* Ctrl(right)           0x65  */  101
 #define KEY_Pause        /* Pause                 0x66  */  102
 #define KEY_Print        /* Print                 0x67  */  103
-#define KEY_KP_Divide    /* Didive                0x68  */  104
+#define KEY_KP_Divide    /* Divide                0x68  */  104
 #define KEY_AltLang      /* AtlLang(right)        0x69  */  105
 #define KEY_Break        /* Break                 0x6a  */  106
 #define KEY_LMeta        /* Left Meta             0x6b  */  107
@@ -190,30 +237,83 @@
 #define KEY_F13          /* F13                   0x6e  */  110
 #define KEY_F14          /* F14                   0x6f  */  111
 #define KEY_F15          /* F15                   0x70  */  112
+#define KEY_HKTG         /* Hirugana/Katakana tog 0x70  */  112
 #define KEY_F16          /* F16                   0x71  */  113
 #define KEY_F17          /* F17                   0x72  */  114
 #define KEY_KP_DEC       /* KP_DEC                0x73  */  115
-#define KEY_SN_KP_7      /* ServerNumLock 7       0x80  */  128
-#define KEY_SN_KP_8      /* ServerNumLock 8       0x81  */  129
-#define KEY_SN_KP_9      /* ServerNumLock 9       0x82  */  130
-#define KEY_SN_KP_4      /* ServerNumLock 4       0x83  */  131
-#define KEY_SN_KP_5      /* ServerNumLock 5       0x84  */  132
-#define KEY_SN_KP_6      /* ServerNumLock 6       0x85  */  133
-#define KEY_SN_KP_1      /* ServerNumLock 1       0x86  */  134
-#define KEY_SN_KP_2      /* ServerNumLock 2       0x87  */  135
-#define KEY_SN_KP_3      /* ServerNumLock 4       0x88  */  136
-#define KEY_SN_KP_0      /* ServerNumLock 0       0x89  */  137
-#define KEY_SN_KP_Dec    /* ServerNumLock Decimal 0x8a  */  138
-#define KEY_SN_KP_Home   /* ServerNumLock Home    0x8b  */  139
-#define KEY_SN_KP_Up     /* ServerNumLock Up      0x8c  */  140
-#define KEY_SN_KP_Prior  /* ServerNumLock Prior   0x8d  */  141
-#define KEY_SN_KP_Left   /* ServerNumLock Left    0x8e  */  142
-#define KEY_SN_KP_Begin  /* ServerNumLock Begin   0x8f  */  143
-#define KEY_SN_KP_Right  /* ServerNumLock Right   0x90  */  144
-#define KEY_SN_KP_End    /* ServerNumLock End     0x91  */  145
-#define KEY_SN_KP_Down   /* ServerNumLock Down    0x92  */  146
-#define KEY_SN_KP_Next   /* ServerNumLock Next    0x93  */  147
-#define KEY_SN_KP_Ins    /* ServerNumLock Ins     0x94  */  148
-#define KEY_SN_KP_Del    /* ServerNumLock Del     0x95  */  149
+#define KEY_BSlash2      /* \           _         0x73  */  115
+#define KEY_KP_Equal	 /* Equal (Keypad)        0x76  */  118
+#define KEY_XFER         /* Kanji Transfer        0x79  */  121
+#define KEY_NFER         /* No Kanji Transfer     0x7b  */  123
+#define KEY_Yen          /* Yen                   0x7d  */  125
+
+#define KEY_Power        /* Power Key             0x84  */  132
+#define KEY_Mute         /* Audio Mute            0x85  */  133
+#define KEY_AudioLower   /* Audio Lower           0x86  */  134
+#define KEY_AudioRaise   /* Audio Raise           0x87  */  135
+#define KEY_Help         /* Help                  0x88  */  136
+#define KEY_L1           /* Stop                  0x89  */  137
+#define KEY_L2           /* Again                 0x8a  */  138
+#define KEY_L3           /* Props                 0x8b  */  139
+#define KEY_L4           /* Undo                  0x8c  */  140
+#define KEY_L5           /* Front                 0x8d  */  141
+#define KEY_L6           /* Copy                  0x8e  */  142
+#define KEY_L7           /* Open                  0x8f  */  143
+#define KEY_L8           /* Paste                 0x90  */  144
+#define KEY_L9           /* Find                  0x91  */  145
+#define KEY_L10          /* Cut                   0x92  */  146
+
+/*
+ * Fake 'scancodes' in the following ranges are generated for 2-byte
+ * codes not handled elsewhere.  These correspond to most extended keys
+ * on so-called "Internet" keyboards:
+ *
+ *	0x79-0x93
+ *	0x96-0xa1
+ *	0xa3-0xac
+ *	0xb1-0xb4
+ *	0xba-0xbd
+ *	0xc2
+ *	0xcc-0xd2
+ *	0xd6-0xf7
+ */
+
+/*
+ * Remapped 'scancodes' are generated for single-byte codes in the range
+ * 0x59-0x5f,0x62-0x76.  These are used for some extra keys on some keyboards.
+ */
+
+#define KEY_0x59		0x95
+#define KEY_0x5A		0xA2
+#define KEY_0x5B		0xAD
+#define KEY_0x5C		KEY_KP_EQUAL
+#define KEY_0x5D		0xAE
+#define KEY_0x5E		0xAF
+#define KEY_0x5F		0xB0
+#define KEY_0x62		0xB5
+#define KEY_0x63		0xB6
+#define KEY_0x64		0xB7
+#define KEY_0x65		0xB8
+#define KEY_0x66		0xB9
+#define KEY_0x67		0xBE
+#define KEY_0x68		0xBF
+#define KEY_0x69		0xC0
+#define KEY_0x6A		0xC1
+#define KEY_0x6B		0xC3
+#define KEY_0x6C		0xC4
+#define KEY_0x6D		0xC5
+#define KEY_0x6E		0xC6
+#define KEY_0x6F		0xC7
+#define KEY_0x70		0xC8
+#define KEY_0x71		0xC9
+#define KEY_0x72		0xCA
+#define KEY_0x73		0xCB
+#define KEY_0x74		0xD3
+#define KEY_0x75		0xD4
+#define KEY_0x76		0xD5
+
+/* These are for "notused" and "unknown" entries in translation maps. */
+#define KEY_NOTUSED	  0
+#define KEY_UNKNOWN	255
 
 #endif /* _ATKEYNAMES_H */
Index: hpc.h
===================================================================
RCS file: /cvsroot/xsrc/xfree/xc/programs/Xserver/hw/netbsd/hpc/hpc.h,v
retrieving revision 1.1
diff -u -r1.1 hpc.h
--- hpc.h	3 Jan 2004 01:09:19 -0000	1.1
+++ hpc.h	20 Jul 2004 17:42:31 -0000
@@ -107,6 +107,9 @@
     int			xlatestat;     	/* state machine for key code xlation */
     Leds		leds;		/* last known LED state */
     struct termios	kbdtty;		/* previous tty settings */
+    int			encode;		/* builtin keyboard encoding */
+    Bool		multiplexer;	/* connected to wsmux */
+    char                devname[16];	/* actual device name */
 } hpcKbdPrivRec, *hpcKbdPrivPtr;
 extern hpcKbdPrivRec hpcKbdPriv;
 
@@ -175,6 +178,9 @@
 	FatalError a; \
 }
 
+/* alias for verbose print */
+#define	hpcPrintF(x)	hpcErrorF(x)
+
 /*
  * hpcInit.c
  */
@@ -192,6 +198,7 @@
 int hpcKbdProc __P((DeviceIntPtr pKeyboard, int what));
 hpcEvent* hpcKbdGetEvents __P((hpcKbdPrivPtr, int*, Bool*));
 void hpcKbdEnqueueEvent __P((DeviceIntPtr dev, hpcEvent* fe));
+void hpcKbdGetInfo(hpcKbdPrivPtr);
 
 /*
  * hpcMouse.c
@@ -213,4 +220,9 @@
 Bool hpcFBInit __P((int scrn, ScreenPtr pScrn, int argc, char** argv));
 int hpcSetDisplayMode(int, int, int *);
 
+/*
+ * hpcKeymap.c
+ */
+int hpcKeymapConvertWssymToXsym(int);
+
 #endif
Index: hpcInit.c
===================================================================
RCS file: /cvsroot/xsrc/xfree/xc/programs/Xserver/hw/netbsd/hpc/hpcInit.c,v
retrieving revision 1.3
diff -u -r1.3 hpcInit.c
--- hpcInit.c	25 Jun 2004 20:51:59 -0000	1.3
+++ hpcInit.c	20 Jul 2004 17:42:31 -0000
@@ -31,16 +31,6 @@
     -1,		/* fd */
 };
 
-/*
- * a list of devices to try if there is no environment or command
- * line list of devices
- */
-static char *fallbackList[] = {
-    "/dev/ttyE0", "/dev/ttyE1", "/dev/ttyE2", "/dev/ttyE3",
-    "/dev/ttyE4", "/dev/ttyE5", "/dev/ttyE6", "/dev/ttyE7",
-};
-#define FALLBACK_LIST_LEN sizeof fallbackList / sizeof fallbackList[0]
-
 hpcFbRec hpcFbs[MAXSCREENS];
 
 static PixmapFormatRec	formats[] = {
@@ -175,16 +165,7 @@
 	}
 	deviceList[MAXSCREENS] = NULL;
     }
-#if 0
-    if (!deviceList) {
-	/* no environment and no cmdline, so default */
-	deviceList =
-	    (char **) xalloc ((FALLBACK_LIST_LEN + 1) * sizeof (char *));
-	for (i = 0; i < FALLBACK_LIST_LEN; i++)
-	    deviceList[i] = fallbackList[i];
-	deviceList[FALLBACK_LIST_LEN] = NULL;
-    }
-#endif
+
     return deviceList;
 }
 
@@ -199,11 +180,12 @@
     char    	  **argv;
 {
 	struct rlimit rl;
-	int maxfds, kbdtype;
-	int i;
+	int maxfds;
+	int i, fd;
 	char **devList;
-
+	Bool kbdFound;
 	static int inited;
+	char mousedevname[16];
 
 	if (inited)
 	    return;
@@ -219,73 +201,103 @@
 	    (void) setrlimit (RLIMIT_NOFILE, &rl);
 	}
 
-	hpcKbdPriv.fd = hpcPtrPriv.fd = -1;
+	hpcPtrPriv.fd = -1;
+	kbdFound = FALSE;
 
 	/*
 	 * use mouse multiplexer if it's available.
 	 */
-	hpcPtrPriv.fd = open("/dev/wsmux0", O_RDWR);
+	if ((hpcPtrPriv.fd = open("/dev/wsmouse", O_RDWR)) != -1) {
+		hpcPrintF(("mouse: /dev/wsmouse (multiplexer)\n"));
+	} else {
+		for (i = 0; i < 8; i++) {
+			sprintf(mousedevname, "/dev/wsmouse%d", i);
+			if ((hpcPtrPriv.fd = open(mousedevname, O_RDWR)) != -1) {
+				hpcPrintF(("mouse: %s\n", mousedevname));
+				break;
+			} else {
+				hpcError(mousedevname);
+			}
+		}
+	}
 
+#ifndef __arm__
 	/*
-	 * try each mouse device
+	 * 1. use keyboards which are connected wsdisplay(ttyE*).
+	 * hpcarm's Xhpc can't use ttyE* even if WSDISPLAY_COMPAT_RAWKBD
+	 * is setted. because keyboard scancode is not compatible with
+	 * hpcsh/hpcmips. -uch
 	 */
-	for (i = 0; i < 8; i++) {
-	    char devname[16];
-
-#ifdef __arm__
-	    /*
-	     * We can't use wskbd for now, because primary keyboard(wskbd0)
-             * is already connected with console(/dev/ttyE0).
-	     */
-	    if (hpcKbdPriv.fd == -1) {
-		sprintf(devname, "/dev/wskbd%d", i);
-		hpcKbdPriv.fd = open(devname, O_RDWR);
-	    }
-#endif
+	if (!kbdFound) {
+		devList = GetDeviceList (argc, argv);
+		for (i = 0; devList[i] != NULL; i++) {
+			int mode;
+			strcpy(hpcKbdPriv.devname, devList[i]);
+			if ((fd = open(hpcKbdPriv.devname, O_RDWR)) == -1)
+				continue;
+			/* check raw keyboard scan code support */
+			if (ioctl(fd, WSKBDIO_GETMODE, &mode) != -1) {
+				hpcPrintF(("keyboard: %s (RAW XT keyboard)\n",
+				    devList[i]));
+				hpcKbdPriv.devtype = HPC_KBDDEV_RAW;
+				kbdFound = TRUE;
+				close(fd);
+				break;
+			}
+			close(fd);
+		}
+	}
+#endif /* __arm__ */
 
-	    if (hpcPtrPriv.fd == -1) {
-		sprintf(devname, "/dev/wsmouse%d", i);
-		if ((hpcPtrPriv.fd = open(devname, O_RDWR)) < 0)
-		    hpcError(devname);
-	    }
+	/*
+	 * 2. use wskbd (multiplexer)
+	 */
+	if (!kbdFound) {
+		strcpy(hpcKbdPriv.devname, "/dev/wskbd");
+		if ((fd = open(hpcKbdPriv.devname, O_RDWR)) != -1) {
+			hpcKbdPriv.devtype = HPC_KBDDEV_WSMUX;
+			kbdFound = TRUE;
+			hpcPrintF(("keyboard: /dev/wskbd (multiplexer)\n"));
+			close(fd);
+		}
 	}
 
-	if (hpcKbdPriv.fd != -1) {
-	    hpcKbdPriv.devtype = HPC_KBDDEV_WSKBD;
-	} else {
-	    /*
-	     * use keyboards which are connected wsdisplay(ttyE*).
-	     */
-	    devList = GetDeviceList (argc, argv);
-	    for (i = 0; devList[i] != NULL; i++) {
-		if (0 <= (hpcKbdPriv.fd = open(devList[i], O_RDWR))) {
-		    /* this isn't error */
-		    hpcErrorF(("use RAW XT keyboard, %s\n", devList[i]));
-		    hpcKbdPriv.devtype = HPC_KBDDEV_RAW;
-		    break;
+	/*
+	 * 3. use wskbd*
+	 */
+	if (!kbdFound) {
+		for (i = 0; i < 8; i++) {
+			sprintf(hpcKbdPriv.devname, "/dev/wskbd%d", i);
+			if ((fd = open(hpcKbdPriv.devname, O_RDWR)) != -1) {
+				hpcKbdPriv.devtype = HPC_KBDDEV_WSKBD;
+				kbdFound = TRUE;
+				hpcPrintF(("keyboard: %s\n", hpcKbdPriv.devname));
+				close(fd);
+				break;
+			}
 		}
-	    }
 	}
 
-	if (hpcKbdPriv.fd == -1)
-	    hpcFatalError(("Can't open keyboard device\n"));
+	if (!kbdFound)
+		hpcFatalError(("Can't open keyboard device\n"));
 	if (hpcPtrPriv.fd == -1)
-	    hpcFatalError(("Can't open pointer device\n"));
+		hpcFatalError(("Can't open pointer device\n"));
+
 	noXkbExtension = FALSE;		/* XXX for now */
-	inited = 1;
 
-	if (ioctl(hpcKbdPriv.fd, WSKBDIO_GTYPE, &kbdtype) == -1) {
-	    hpcError("cannot get keyboard type\n");
-	    kbdtype = 0;
-	}
+	/*
+	 * Try to inquire keyboard encoding type. If using wskbd,
+	 * generating keymap.
+	 */
+	hpcKbdGetInfo(&hpcKbdPriv);
+	/*
+	 * Index of hpcKeySyms[]. Xhpc use only one keymap table.
+	 */
+	hpcKbdPriv.type = 0;
 
-	switch (kbdtype) {
-	case WSKBD_TYPE_USB:
-		break;
-	}
+	hpcKbdPriv.fd = open(hpcKbdPriv.devname, O_RDWR);
+	inited = 1;
 
-	/* XXX, What does this mean ??? */
-	hpcKbdPriv.type = 0;
 }
 
 /*
@@ -434,3 +446,4 @@
     return FALSE;
 }
 #endif
+
Index: hpcKbd.c
===================================================================
RCS file: /cvsroot/xsrc/xfree/xc/programs/Xserver/hw/netbsd/hpc/hpcKbd.c,v
retrieving revision 1.2
diff -u -r1.2 hpcKbd.c
--- hpcKbd.c	3 Jan 2004 01:23:02 -0000	1.2
+++ hpcKbd.c	20 Jul 2004 17:42:31 -0000
@@ -47,14 +47,26 @@
 #include <stdio.h>
 #include <sys/time.h>
 #include <dev/pckbc/pckbdreg.h>
+#include <dev/wscons/wsksymdef.h>
 #include "atKeynames.h"
 
+#ifdef XKB
+#include <X11/extensions/XKB.h>
+#include <X11/extensions/XKBstr.h>
+#include <X11/extensions/XKBsrv.h>
+#endif
+
 #define MOUSE_EMUL_KEY	(KEY_Menu + MIN_KEYCODE)	/* menu key on windows keyboard */
 #define MOUSE_EMUL_KEY1	(KEY_1 + MIN_KEYCODE)
 #define MOUSE_EMUL_KEY5	(KEY_5 + MIN_KEYCODE)
 
 extern KeySymsRec hpcKeySyms[];
 extern hpcModmapRec *hpcModMaps[];
+static void hpcInitKbdNames(XkbComponentNamesRec *, hpcKbdPrivPtr);
+static int hpcKbdMuxSaveDevices(struct wsmux_device_list *);
+static int hpcKbdMuxRestoreDevices(struct wsmux_device_list *);
+static int hpcKbdMainKeyboardIoctl(hpcKbdPrivPtr);
+static int hpcKbdMainKeyboardDoIoctl(hpcKbdPrivPtr, const char *);
 
 /*
  * hpcBell --
@@ -131,7 +143,7 @@
 {
     int i;
     DevicePtr pKeyboard = (DevicePtr) device;
-    hpcKbdPrivPtr pPriv;
+    hpcKbdPrivPtr pPriv = &hpcKbdPriv;
     KeybdCtrl*	ctrl = &device->kbdfeed->ctrl;
     extern int XkbDfltRepeatDelay, XkbDfltRepeatInterval;
     struct termios tkbdtty;
@@ -184,9 +196,25 @@
 	pKeyboard->devicePrivate = (pointer)&hpcKbdPriv;
 	pKeyboard->on = FALSE;
 
-	InitKeyboardDeviceStruct(pKeyboard,
-				 workingKeySyms, workingModMap,
-				 hpcBell, hpcKbdCtrl);
+#ifndef XKB
+	InitKeyboardDeviceStruct(pKeyboard, workingKeySyms,
+	    workingModMap, hpcBell, hpcKbdCtrl);
+#else
+	if (noXkbExtension || pPriv->devtype == HPC_KBDDEV_WSMUX ||
+	    pPriv->devtype == HPC_KBDDEV_WSKBD) {
+		/*
+		 * When using wskbd and its multiplexer, keysyms are
+		 * already converted from WSKBDIO_GETMAP ioctl.
+		 */
+		InitKeyboardDeviceStruct(pKeyboard, workingKeySyms,
+		    workingModMap, hpcBell, hpcKbdCtrl);
+	} else {
+		XkbComponentNamesRec names;
+		hpcInitKbdNames(&names, &hpcKbdPriv);
+		XkbInitKeyboardDeviceStruct((DeviceIntPtr)pKeyboard, &names,
+		    workingKeySyms, workingModMap, hpcBell, hpcKbdCtrl);
+	}
+#endif
 	break;
 
     case DEVICE_ON:
@@ -201,7 +229,6 @@
 	hpcKbdPriv.bkeymask = 0;
 	hpcKbdPriv.bkeynrmask = 0;
 
-	pPriv = (hpcKbdPrivPtr)pKeyboard->devicePrivate;
 	switch (pPriv->devtype) {
 	case HPC_KBDDEV_RAW:
 	    pPriv->xlatestat = HPC_KBDXSTAT_INIT;
@@ -231,7 +258,6 @@
 
     case DEVICE_CLOSE:
     case DEVICE_OFF:
-	pPriv = (hpcKbdPrivPtr)pKeyboard->devicePrivate;
 	RemoveEnabledDevice(pPriv->fd);
 	pKeyboard->on = FALSE;
 	switch (pPriv->devtype) {
@@ -272,6 +298,7 @@
 {
     int fd;
     int	nBytes;	    /* number of bytes of events available. */
+    struct timeval tv;
     u_char c, c2;
     static hpcEvent evBuf[MAXEVENTS];   /* Buffer for hpcEvents */
 
@@ -300,8 +327,43 @@
 			pPriv->xlatestat = HPC_KBDXSTAT_EXT1;
 			goto AGAIN;
 		    } else {
-			*pNumEvents = 1;
-			evBuf[0].value = (c & 0x7f);
+			    switch (c & 0x7f) {
+			    case 0x59:        c2 = KEY_0x59; break;
+			    case 0x5a:        c2 = KEY_0x5A; break;
+			    case 0x5b:        c2 = KEY_0x5B; break;
+			    case 0x5c:        c2 = KEY_KP_Equal; break; /* Keypad Equal */
+			    case 0x5d:        c2 = KEY_0x5D; break;
+			    case 0x5e:        c2 = KEY_0x5E; break;
+			    case 0x5f:        c2 = KEY_0x5F; break;
+			    case 0x62:        c2 = KEY_0x62; break;
+			    case 0x63:        c2 = KEY_0x63; break;
+			    case 0x64:        c2 = KEY_0x64; break;
+			    case 0x65:        c2 = KEY_0x65; break;
+			    case 0x66:        c2 = KEY_0x66; break;
+			    case 0x67:        c2 = KEY_0x67; break;
+			    case 0x68:        c2 = KEY_0x68; break;
+			    case 0x69:        c2 = KEY_0x69; break;
+			    case 0x6a:        c2 = KEY_0x6A; break;
+			    case 0x6b:        c2 = KEY_0x6B; break;
+			    case 0x6c:        c2 = KEY_0x6C; break;
+			    case 0x6d:        c2 = KEY_0x6D; break;
+			    case 0x6e:        c2 = KEY_0x6E; break;
+			    case 0x6f:        c2 = KEY_0x6F; break;
+			    case 0x70:        c2 = KEY_0x70; break;
+			    case 0x71:        c2 = KEY_0x71; break;
+			    case 0x72:        c2 = KEY_0x72; break;
+			    case 0x73:        c2 = KEY_0x73; break;
+			    case 0x74:        c2 = KEY_0x74; break;
+			    case 0x75:        c2 = KEY_0x75; break;
+			    case 0x76:        c2 = KEY_0x76; break;
+			    default:	      c2 = c & 0x7f; break;
+			    }
+			    *pNumEvents = 1;
+			    evBuf[0].value = c2;
+			    evBuf[0].type = (c & 0x80) ?
+				WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
+			    TIMEVAL_TO_TIMESPEC(&tv, &evBuf[0].time);
+			    return evBuf;
 		    }
 		    break;
 		case HPC_KBDXSTAT_EXT0:
@@ -380,8 +442,8 @@
 		    hpcFatalError(("hpcKbdGetEvents: invalid xlate status"));
 		    break;
 		}
+
 		if (*pNumEvents != 0) {
-		    struct timeval tv;
 		    gettimeofday(&tv, NULL);
 		    evBuf[0].type = (c & 0x80) ?
 				WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
@@ -556,3 +618,202 @@
 {
     return TRUE;
 }
+
+/*-
+ *-----------------------------------------------------------------------
+ * hpcInitKbdNames --
+ *	Handle the XKB initialization
+ *
+ * Results:
+ *	None.
+ *
+ * Comments:
+ *-----------------------------------------------------------------------
+ */
+#ifdef XKB
+static void hpcInitKbdNames (XkbComponentNamesRec* names, hpcKbdPrivPtr pKbd)
+{
+#ifndef XKBBUFSIZE
+#define	XKBBUFSIZE 64
+#endif
+    static char keycodesbuf[XKBBUFSIZE];
+    static char geometrybuf[XKBBUFSIZE];
+    static char symbolsbuf[XKBBUFSIZE];
+
+    names->keymap = NULL;
+    names->compat = "compat/complete";
+    names->types  = "types/complete";
+    names->keycodes = keycodesbuf;
+    names->geometry = geometrybuf;
+    names->symbols = symbolsbuf;
+    strcpy(keycodesbuf, "keycodes/");
+    strcpy(geometrybuf, "geometry/");
+    strcpy(symbolsbuf, "symbols/");
+
+    /* keycodes & geometry */
+    switch (pKbd->encode) {
+    case KB_DE:
+	    strcat(names->keycodes, "xfree86");
+	    strcat(names->geometry, "pc(jp102)");
+	    strcat(names->symbols, "en_US(pc105)+de");
+	    hpcPrintF(("keymap: en_US(pc105)+de\n"));
+	    break;
+    case KB_FR:
+	    strcat(names->keycodes, "xfree86");
+	    strcat(names->geometry, "pc(pc102)");
+	    strcat(names->symbols, "en_US(pc105)+fr");
+	    hpcPrintF(("keymap: en_US(pc105)+fr\n"));
+	    break;
+    case KB_JP:
+	    strcat(names->keycodes, "xfree86(jp106)");
+	    strcat(names->geometry, "pc(jp106)");
+	    strcat(names->symbols, "jp(jp106)");
+	    hpcPrintF(("keymap: jp(jp106)\n"));
+	    break;
+    case KB_PT:
+	    strcat(names->keycodes, "xfree86");
+	    strcat(names->geometry, "pc(pc102)");
+	    strcat(names->symbols, "en_US(pc105)+pt");
+	    hpcPrintF(("keymap: en_US(jp105)+pt\n"));
+	    break;
+    case KB_US:
+    default:
+	    strcat(names->keycodes, "xfree86");
+	    strcat(names->geometry, "pc");
+	    strcat(names->symbols, "us(pc105)");
+	    hpcPrintF(("keymap: us(pc105)\n"));
+	    break;
+    }
+}
+#endif /* XKB */
+
+/*
+ * Inquire built-in keyboard encoding type and keymap.
+ */
+void
+hpcKbdGetInfo(hpcKbdPrivPtr pPriv)
+{
+	struct wsmux_device_list devlist;
+
+	/* try to open multiplexer */
+	if (hpcKbdMuxSaveDevices(&devlist) == 0) {
+		pPriv->multiplexer = TRUE;
+		hpcKbdMainKeyboardIoctl(pPriv);
+		hpcKbdMuxRestoreDevices(&devlist);
+	} else {
+		pPriv->multiplexer = FALSE;
+		hpcKbdMainKeyboardIoctl(pPriv);
+	}
+}
+
+/*
+ * Save attached device of mulitiplexer to devlist.
+ */
+int
+hpcKbdMuxSaveDevices(struct wsmux_device_list *devlist)
+{
+	struct wsmux_device *dev;
+	int i, fd;
+
+	if ((fd = open("/dev/wskbd", O_RDWR)) == -1) {
+		hpcPrintF(("can't open /dev/wskbd multiplexer (not fatal)"));
+		return 1;
+	}
+
+	if (ioctl(fd, WSMUXIO_LIST_DEVICES, devlist) == -1) {
+		hpcPrintF(("can't WSMUXIO_LIST_DEVICES (not fatal)"));
+		close(fd);
+		return 1;
+	}
+	close(fd);
+
+	return 0;
+}
+
+int
+hpcKbdMuxRestoreDevices(struct wsmux_device_list *odevlist)
+{
+	struct wsmux_device_list devlist;
+	struct wsmux_device *odev, *dev;
+	int fd, i, j, n;
+
+	/* Get current list */
+	if (hpcKbdMuxSaveDevices(&devlist) != 0)
+		return 1;
+
+	fd = open("/dev/wskbd", O_RDWR);
+
+	/* Compare old list, if find detatched device, reconnect again. */
+	n = devlist.ndevices;
+	for (odev = odevlist->devices,
+	    i = 0; i < odevlist->ndevices; i++, odev++) {
+		for (dev = devlist.devices, j = 0; j < n; j++, dev++)
+			if (dev->type == odev->type && dev->idx == odev->idx)
+				break;
+		if (j != n)
+			continue;
+
+		if (ioctl(fd, WSMUXIO_ADD_DEVICE, odev) == -1) {
+			hpcPrintF(("failed to add type %d idx %d\n",
+			    odev->type, odev->idx));
+		}
+	}
+	close(fd);
+}
+
+int
+hpcKbdMainKeyboardIoctl(hpcKbdPrivPtr pPriv)
+{
+	char device[16];
+	int i;
+
+	if (pPriv->multiplexer) {
+		/* find builtin-keyboard */
+		for (i = 0; i < 8; i++) {
+			sprintf(device, "/dev/wskbd%d", i);
+			if (hpcKbdMainKeyboardDoIoctl(pPriv, device) == 0)
+				break;
+		}
+	} else {
+		hpcKbdMainKeyboardDoIoctl(pPriv, pPriv->devname);
+	}
+
+	if (pPriv->encode == 0)
+		pPriv->encode = KB_USER;
+}
+
+int
+hpcKbdMainKeyboardDoIoctl(hpcKbdPrivPtr pPriv, const char *device)
+{
+	int fd;
+	kbd_t kbdencoding = 0;
+	u_int kbdtype;
+
+	if ((fd = open(device, O_RDWR)) == -1)
+		return 1;
+
+	if (ioctl(fd, WSKBDIO_GTYPE, &kbdtype) == -1) {
+		close(fd);
+		return 1;
+	}
+
+	if (ioctl(fd, WSKBDIO_GETENCODING, &kbdencoding) != -1) {
+		pPriv->encode = kbdencoding;
+	} else {
+		hpcErrorF(("can't get keyboard encoding. (not fatal)\n"));
+	}
+
+	switch (kbdtype) {
+	default:
+	case WSKBD_TYPE_USB:
+		hpcErrorF(("USB keyboard.\n"));
+		/* FALLTHROUGH */
+	case WSKBD_TYPE_HPC_KBD:
+		if (pPriv->devtype == HPC_KBDDEV_WSMUX ||
+		    pPriv->devtype == HPC_KBDDEV_WSKBD)
+			hpcKeymapConvertWssymToXsym(fd);
+	}
+	close(fd);
+
+	return 0;
+}
Index: hpcKeymap.c
===================================================================
RCS file: /cvsroot/xsrc/xfree/xc/programs/Xserver/hw/netbsd/hpc/hpcKeymap.c,v
retrieving revision 1.1
diff -u -r1.1 hpcKeymap.c
--- hpcKeymap.c	3 Jan 2004 01:09:19 -0000	1.1
+++ hpcKeymap.c	20 Jul 2004 17:42:31 -0000
@@ -34,10 +34,13 @@
 
 #include	"atKeynames.h"
 #include	"xf86Keymap.h"
+#include <dev/wscons/wsksymdef.h>
+
+static void hpcKeymapSetSymbol(KeySym *, u_int16_t, int);
 
 KeySymsRec hpcKeySyms[] = {
     /*	map	   minKeyCode	maxKC	width */
-    map,		0,	MAX_STD_KEYCODE,	4,
+    map,		0,	NUM_KEYCODES,	4,
 };
 
 static hpcModmapRec modmap[] = {
@@ -54,3 +57,408 @@
 hpcModmapRec *hpcModMaps[] = {
     modmap,
 };
+
+KeySym wssym_to_xkeysym[] = {
+	[KS_BackSpace] = XK_BackSpace,
+	[KS_Tab] = XK_Tab,
+	[KS_Linefeed] = XK_Linefeed,
+	[KS_Clear] = XK_Clear,
+	[KS_Return] = XK_Return,
+	[KS_Escape] = XK_Escape,
+	[KS_space] = XK_space,
+	[KS_exclam] = XK_exclam,
+	[KS_quotedbl] = XK_quotedbl,
+	[KS_numbersign] = XK_numbersign,
+	[KS_dollar] = XK_dollar,
+	[KS_percent] = XK_percent,
+	[KS_ampersand] = XK_ampersand,
+	[KS_apostrophe] = XK_apostrophe,
+	[KS_parenleft] = XK_parenleft,
+	[KS_parenright] = XK_parenright,
+	[KS_asterisk] = XK_asterisk,
+	[KS_plus] = XK_plus,
+	[KS_comma] = XK_comma,
+	[KS_minus] = XK_minus,
+	[KS_period] = XK_period,
+	[KS_slash] = XK_slash,
+	[KS_0] = XK_0,
+	[KS_1] = XK_1,
+	[KS_2] = XK_2,
+	[KS_3] = XK_3,
+	[KS_4] = XK_4,
+	[KS_5] = XK_5,
+	[KS_6] = XK_6,
+	[KS_7] = XK_7,
+	[KS_8] = XK_8,
+	[KS_9] = XK_9,
+	[KS_colon] = XK_colon,
+	[KS_semicolon] = XK_semicolon,
+	[KS_less] = XK_less,
+	[KS_equal] = XK_equal,
+	[KS_greater] = XK_greater,
+	[KS_question] = XK_question,
+	[KS_at] = XK_at,
+	[KS_A] = XK_A,
+	[KS_B] = XK_B,
+	[KS_C] = XK_C,
+	[KS_D] = XK_D,
+	[KS_E] = XK_E,
+	[KS_F] = XK_F,
+	[KS_G] = XK_G,
+	[KS_H] = XK_H,
+	[KS_I] = XK_I,
+	[KS_J] = XK_J,
+	[KS_K] = XK_K,
+	[KS_L] = XK_L,
+	[KS_M] = XK_M,
+	[KS_N] = XK_N,
+	[KS_O] = XK_O,
+	[KS_P] = XK_P,
+	[KS_Q] = XK_Q,
+	[KS_R] = XK_R,
+	[KS_S] = XK_S,
+	[KS_T] = XK_T,
+	[KS_U] = XK_U,
+	[KS_V] = XK_V,
+	[KS_W] = XK_W,
+	[KS_X] = XK_X,
+	[KS_Y] = XK_Y,
+	[KS_Z] = XK_Z,
+	[KS_bracketleft] = XK_bracketleft,
+	[KS_backslash] = XK_backslash,
+	[KS_bracketright] = XK_bracketright,
+	[KS_asciicircum] = XK_asciicircum,
+	[KS_underscore] = XK_underscore,
+	[KS_grave] = XK_grave,
+	[KS_a] = XK_a,
+	[KS_b] = XK_b,
+	[KS_c] = XK_c,
+	[KS_d] = XK_d,
+	[KS_e] = XK_e,
+	[KS_f] = XK_f,
+	[KS_g] = XK_g,
+	[KS_h] = XK_h,
+	[KS_i] = XK_i,
+	[KS_j] = XK_j,
+	[KS_k] = XK_k,
+	[KS_l] = XK_l,
+	[KS_m] = XK_m,
+	[KS_n] = XK_n,
+	[KS_o] = XK_o,
+	[KS_p] = XK_p,
+	[KS_q] = XK_q,
+	[KS_r] = XK_r,
+	[KS_s] = XK_s,
+	[KS_t] = XK_t,
+	[KS_u] = XK_u,
+	[KS_v] = XK_v,
+	[KS_w] = XK_w,
+	[KS_x] = XK_x,
+	[KS_y] = XK_y,
+	[KS_z] = XK_z,
+	[KS_braceleft] = XK_braceleft,
+	[KS_bar] = XK_bar,
+	[KS_braceright] = XK_braceright,
+	[KS_asciitilde] = XK_asciitilde,
+	[KS_Delete] = XK_Delete,
+	[KS_nobreakspace] = XK_nobreakspace,
+	[KS_exclamdown] = XK_exclamdown,
+	[KS_cent] = XK_cent,
+	[KS_sterling] = XK_sterling,
+	[KS_currency] = XK_currency,
+	[KS_yen] = XK_yen,
+	[KS_brokenbar] = XK_brokenbar,
+	[KS_section] = XK_section,
+	[KS_diaeresis] = XK_diaeresis,
+	[KS_copyright] = XK_copyright,
+	[KS_ordfeminine] = XK_ordfeminine,
+	[KS_guillemotleft] = XK_guillemotleft,
+	[KS_notsign] = XK_notsign,
+	[KS_hyphen] = XK_hyphen,
+	[KS_registered] = XK_registered,
+	[KS_macron] = XK_macron,
+	[KS_degree] = XK_degree,
+	[KS_plusminus] = XK_plusminus,
+	[KS_twosuperior] = XK_twosuperior,
+	[KS_threesuperior] = XK_threesuperior,
+	[KS_acute] = XK_acute,
+	[KS_mu] = XK_mu,
+	[KS_paragraph] = XK_paragraph,
+	[KS_periodcentered] = XK_periodcentered,
+	[KS_cedilla] = XK_cedilla,
+	[KS_onesuperior] = XK_onesuperior,
+	[KS_masculine] = XK_masculine,
+	[KS_guillemotright] = XK_guillemotright,
+	[KS_onequarter] = XK_onequarter,
+	[KS_onehalf] = XK_onehalf,
+	[KS_threequarters] = XK_threequarters,
+	[KS_questiondown] = XK_questiondown,
+	[KS_Agrave] = XK_Agrave,
+	[KS_Aacute] = XK_Aacute,
+	[KS_Acircumflex] = XK_Acircumflex,
+	[KS_Atilde] = XK_Atilde,
+	[KS_Adiaeresis] = XK_Adiaeresis,
+	[KS_Aring] = XK_Aring,
+	[KS_AE] = XK_AE,
+	[KS_Ccedilla] = XK_Ccedilla,
+	[KS_Egrave] = XK_Egrave,
+	[KS_Eacute] = XK_Eacute,
+	[KS_Ecircumflex] = XK_Ecircumflex,
+	[KS_Ediaeresis] = XK_Ediaeresis,
+	[KS_Igrave] = XK_Igrave,
+	[KS_Iacute] = XK_Iacute,
+	[KS_Icircumflex] = XK_Icircumflex,
+	[KS_Idiaeresis] = XK_Idiaeresis,
+	[KS_ETH] = XK_ETH,
+	[KS_Ntilde] = XK_Ntilde,
+	[KS_Ograve] = XK_Ograve,
+	[KS_Oacute] = XK_Oacute,
+	[KS_Ocircumflex] = XK_Ocircumflex,
+	[KS_Otilde] = XK_Otilde,
+	[KS_Odiaeresis] = XK_Odiaeresis,
+	[KS_multiply] = XK_multiply,
+	[KS_Ooblique] = XK_Ooblique,
+	[KS_Ugrave] = XK_Ugrave,
+	[KS_Uacute] = XK_Uacute,
+	[KS_Ucircumflex] = XK_Ucircumflex,
+	[KS_Udiaeresis] = XK_Udiaeresis,
+	[KS_Yacute] = XK_Yacute,
+	[KS_THORN] = XK_THORN,
+	[KS_ssharp] = XK_ssharp,
+	[KS_agrave] = XK_agrave,
+	[KS_aacute] = XK_aacute,
+	[KS_acircumflex] = XK_acircumflex,
+	[KS_atilde] = XK_atilde,
+	[KS_adiaeresis] = XK_adiaeresis,
+	[KS_aring] = XK_aring,
+	[KS_ae] = XK_ae,
+	[KS_ccedilla] = XK_ccedilla,
+	[KS_egrave] = XK_egrave,
+	[KS_eacute] = XK_eacute,
+	[KS_ecircumflex] = XK_ecircumflex,
+	[KS_ediaeresis] = XK_ediaeresis,
+	[KS_igrave] = XK_igrave,
+	[KS_iacute] = XK_iacute,
+	[KS_icircumflex] = XK_icircumflex,
+	[KS_idiaeresis] = XK_idiaeresis,
+	[KS_eth] = XK_eth,
+	[KS_ntilde] = XK_ntilde,
+	[KS_ograve] = XK_ograve,
+	[KS_oacute] = XK_oacute,
+	[KS_ocircumflex] = XK_ocircumflex,
+	[KS_otilde] = XK_otilde,
+	[KS_odiaeresis] = XK_odiaeresis,
+	[KS_division] = XK_division,
+	[KS_oslash] = XK_oslash,
+	[KS_ugrave] = XK_ugrave,
+	[KS_uacute] = XK_uacute,
+	[KS_ucircumflex] = XK_ucircumflex,
+	[KS_udiaeresis] = XK_udiaeresis,
+	[KS_yacute] = XK_yacute,
+	[KS_thorn] = XK_thorn,
+	[KS_ydiaeresis] = XK_ydiaeresis,
+	[KS_Odoubleacute] = XK_Odoubleacute,
+	[KS_odoubleacute] = XK_odoubleacute,
+	[KS_Udoubleacute] = XK_Udoubleacute,
+	[KS_udoubleacute] = XK_udoubleacute,
+	[KS_dead_grave] = XK_dead_grave,
+	[KS_dead_acute] = XK_dead_acute,
+	[KS_dead_circumflex] = XK_dead_circumflex,
+	[KS_dead_tilde] = XK_dead_tilde,
+	[KS_dead_diaeresis] = XK_dead_diaeresis,
+	[KS_dead_abovering] = XK_dead_abovering,
+	[KS_dead_cedilla] = XK_dead_cedilla,
+	[KS_Shift_L] = XK_Shift_L,
+	[KS_Shift_R] = XK_Shift_R,
+	[KS_Control_L] = XK_Control_L,
+	[KS_Control_R] = XK_Control_R,
+	[KS_Caps_Lock] = XK_Caps_Lock,
+	[KS_Shift_Lock] = XK_Shift_Lock,
+	[KS_Alt_L] = XK_Alt_L,
+	[KS_Alt_R] = XK_Alt_R,
+	[KS_Multi_key] = XK_Multi_key,
+	[KS_Mode_switch] = XK_Mode_switch,
+	[KS_Num_Lock] = XK_Num_Lock,
+	[KS_Meta_L] = XK_Meta_L,
+	[KS_Meta_R] = XK_Meta_R,
+	[KS_Zenkaku_Hankaku] = XK_Zenkaku_Hankaku,
+	[KS_Hiragana_Katakana] = XK_Hiragana_Katakana,
+	[KS_Henkan_Mode] = XK_Henkan_Mode,
+	[KS_Henkan] = XK_Henkan,
+	[KS_Muhenkan] = XK_Muhenkan,
+	[KS_KP_F1] = XK_KP_F1,
+	[KS_KP_F2] = XK_KP_F2,
+	[KS_KP_F3] = XK_KP_F3,
+	[KS_KP_F4] = XK_KP_F4,
+	[KS_KP_Home] = XK_KP_Home,
+	[KS_KP_Left] = XK_KP_Left,
+	[KS_KP_Up] = XK_KP_Up,
+	[KS_KP_Right] = XK_KP_Right,
+	[KS_KP_Down] = XK_KP_Down,
+	[KS_KP_Prior] = XK_KP_Prior,
+	[KS_KP_Next] = XK_KP_Next,
+	[KS_KP_End] = XK_KP_End,
+	[KS_KP_Begin] = XK_KP_Begin,
+	[KS_KP_Insert] = XK_KP_Insert,
+	[KS_KP_Delete] = XK_KP_Delete,
+	[KS_KP_Space] = XK_KP_Space,
+	[KS_KP_Tab] = XK_KP_Tab,
+	[KS_KP_Enter] = XK_KP_Enter,
+	[KS_KP_Equal] = XK_KP_Equal,
+	[KS_KP_Numbersign] = XK_numbersign,
+	[KS_KP_Multiply] = XK_KP_Multiply,
+	[KS_KP_Add] = XK_KP_Add,
+	[KS_KP_Separator] = XK_KP_Separator,
+	[KS_KP_Subtract] = XK_KP_Subtract,
+	[KS_KP_Decimal] = XK_KP_Decimal,
+	[KS_KP_Divide] = XK_KP_Divide,
+	[KS_KP_0] = XK_KP_0,
+	[KS_KP_1] = XK_KP_1,
+	[KS_KP_2] = XK_KP_2,
+	[KS_KP_3] = XK_KP_3,
+	[KS_KP_4] = XK_KP_4,
+	[KS_KP_5] = XK_KP_5,
+	[KS_KP_6] = XK_KP_6,
+	[KS_KP_7] = XK_KP_7,
+	[KS_KP_8] = XK_KP_8,
+	[KS_KP_9] = XK_KP_9,
+	[KS_f1] = XK_F1,
+	[KS_f2] = XK_F2,
+	[KS_f3] = XK_F3,
+	[KS_f4] = XK_F4,
+	[KS_f5] = XK_F5,
+	[KS_f6] = XK_F6,
+	[KS_f7] = XK_F7,
+	[KS_f8] = XK_F8,
+	[KS_f9] = XK_F9,
+	[KS_f10] = XK_F10,
+	[KS_f11] = XK_F11,
+	[KS_f12] = XK_F12,
+	[KS_f13] = XK_F13,
+	[KS_f14] = XK_F14,
+	[KS_f15] = XK_F15,
+	[KS_f16] = XK_F16,
+	[KS_f17] = XK_F17,
+	[KS_f18] = XK_F18,
+	[KS_f19] = XK_F19,
+	[KS_f20] = XK_F20,
+	[KS_F1] = XK_F1,
+	[KS_F2] = XK_F2,
+	[KS_F3] = XK_F3,
+	[KS_F4] = XK_F4,
+	[KS_F5] = XK_F5,
+	[KS_F6] = XK_F6,
+	[KS_F7] = XK_F7,
+	[KS_F8] = XK_F8,
+	[KS_F9] = XK_F9,
+	[KS_F10] = XK_F10,
+	[KS_F11] = XK_F11,
+	[KS_F12] = XK_F12,
+	[KS_F13] = XK_F13,
+	[KS_F14] = XK_F14,
+	[KS_F15] = XK_F15,
+	[KS_F16] = XK_F16,
+	[KS_F17] = XK_F17,
+	[KS_F18] = XK_F18,
+	[KS_F19] = XK_F19,
+	[KS_F20] = XK_F20,
+	[KS_Home] = XK_Home,
+	[KS_Prior] = XK_Prior,
+	[KS_Next] = XK_Next,
+	[KS_Up] = XK_Up,
+	[KS_Down] = XK_Down,
+	[KS_Left] = XK_Left,
+	[KS_Right] = XK_Right,
+	[KS_End] = XK_End,
+	[KS_Insert] = XK_Insert,
+	[KS_Help] = XK_Help,
+	[KS_Execute] = XK_Execute,
+	[KS_Find] = XK_Find,
+	[KS_Select] = XK_Select,
+	[KS_Undo] = XK_Undo,
+	[KS_Menu] = XK_Menu,
+	[KS_Pause] = XK_Pause,
+	[0xffff] = NoSymbol,
+};
+
+int
+hpcKeymapConvertWssymToXsym(int fd)
+{
+	struct wskbd_map_data map_data;
+	struct wscons_keymap wscons_keymap[WSKBDIO_MAXMAPLEN], *wscons_key;
+	KeySym *x_key;
+	int i;
+
+	memset(wscons_keymap, 0, sizeof wscons_keymap);
+	map_data.maplen = WSKBDIO_MAXMAPLEN;
+	map_data.map = wscons_keymap;
+
+	/* Get console keymap */
+	if (ioctl(fd, WSKBDIO_GETMAP, &map_data) == -1) {
+		hpcErrorF(("can't WSKBDIO_GETMAP"));
+		return 1;
+	}
+
+	for (i = 0;
+	    i < sizeof wssym_to_xkeysym / sizeof(wssym_to_xkeysym[0]); i++)
+		if (wssym_to_xkeysym[i] == 0)
+			wssym_to_xkeysym[i] = NoSymbol;
+
+	/* Reconstruct keymap */
+	wscons_key = wscons_keymap;
+	x_key = map;
+	memset(modmap, 0, sizeof modmap);
+	for (i = 0; i < map_data.maplen; i++, wscons_key++) {
+		/* assume GLYPHS_PER_KEY is 4 */
+		if (i == NUM_KEYCODES) {
+			hpcErrorF(("Xkeysym overflow.\n"));
+			break;
+		}
+		hpcKeymapSetSymbol(x_key++, wscons_key->group1[0], i);
+		hpcKeymapSetSymbol(x_key++, wscons_key->group1[1], i);
+		hpcKeymapSetSymbol(x_key++, wscons_key->group2[0], i);
+		hpcKeymapSetSymbol(x_key++, wscons_key->group2[1], i);
+	}
+	hpcKeySyms[0].maxKeyCode = map_data.maplen - 1;
+	hpcPrintF(("wssym converted xkeysym.\n"));
+
+	return 0;
+}
+
+void
+hpcKeymapSetSymbol(KeySym *dst, u_int16_t wssym, int keyscan)
+{
+
+	*dst = wssym_to_xkeysym[wssym];
+
+	switch (*dst) {
+	case XK_Shift_L:
+		modmap[0].key = keyscan;
+		modmap[0].modifiers = ShiftMask;
+		break;
+	case XK_Shift_R:
+		modmap[1].key = keyscan;
+		modmap[1].modifiers = ShiftMask;
+		break;
+	case XK_Caps_Lock:
+		modmap[2].key = keyscan;
+		modmap[2].modifiers = LockMask;
+		break;
+	case XK_Control_L:
+		modmap[3].key = keyscan;
+		modmap[3].modifiers = ControlMask;
+		break;
+	case XK_Control_R:
+		modmap[4].key = keyscan;
+		modmap[4].modifiers = ControlMask;
+		break;
+	case XK_Alt_L:
+		modmap[5].key = keyscan;
+		modmap[5].modifiers = AltMask;
+		break;
+	case XK_Mode_switch:	// ok? -uch
+		modmap[6].key = keyscan;
+		modmap[6].modifiers = AltLangMask;
+		break;
+	}
+}
Index: xf86Keymap.h
===================================================================
RCS file: /cvsroot/xsrc/xfree/xc/programs/Xserver/hw/netbsd/hpc/xf86Keymap.h,v
retrieving revision 1.1
diff -u -r1.1 xf86Keymap.h
--- xf86Keymap.h	3 Jan 2004 01:09:19 -0000	1.1
+++ xf86Keymap.h	20 Jul 2004 17:42:31 -0000
@@ -1,3 +1,4 @@
+/* $NetBSD$
 /* $XConsortium: xf86Keymap.h,v 1.8 95/01/23 15:34:05 kaleb Exp $ */
 /* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Keymap.h,v 3.5 1995/01/28 17:03:33 dawes Exp $ */
 /*