Subject: port-hpcmips/28383: hpckbd bare function key support (for Clios)
To: None <port-hpcmips-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: Matthew Orgass <darkstar@city-net.com>
List: netbsd-bugs
Date: 11/21/2004 22:30:00
>Number:         28383
>Category:       port-hpcmips
>Synopsis:       hpckbd bare function key support (for Clios)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    port-hpcmips-maintainer
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Nov 21 22:30:00 +0000 2004
>Originator:     darkstar@city-net.com
>Release:        NetBSD 2.0_RC4
>Organization:
>Description:

  The Clio C-1000 and C-1050 have bare function keys (i.e. there is a Fn key
that is scanned, but F1-F12 are not scanned).  I implemented support for this
in hpckbd.  I also used the function key to cause PgUp/PgDn/Home/End as
printed on the keyboard (used with Alt in CE) and added keymap modification
for the brightness and contrast as printed on the keyboard (with Ctl+Alt, but
they don't actually work yet due to missing graphics chip support).  There is
a problem with vrkiu eliminate_phantom_keys that causes Ctl-Alt-F2/F3 to not
work, but that is a separate issue from this patch.

>Fix:

Index: sys/dev/hpc/hpckbd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/hpc/hpckbd.c,v
retrieving revision 1.11
diff -u -r1.11 hpckbd.c
--- sys/dev/hpc/hpckbd.c	13 Mar 2004 17:31:34 -0000	1.11
+++ sys/dev/hpc/hpckbd.c	21 Nov 2004 22:24:58 -0000
@@ -76,10 +76,11 @@
 };

 struct hpckbd_core {
+	const struct hpckbd_keymap_table *hc_entry;
 	struct hpckbd_if	hc_if;
 	struct hpckbd_ic_if	*hc_ic;
 	const u_int8_t		*hc_keymap;
-	const int		*hc_special;
+	u_int32_t		hc_fndown[3];
 	int			hc_polling;
 	int			hc_console;
 #define NEVENTQ 32
@@ -170,6 +171,9 @@
 		hpckbd_initcore(sc->sc_core, ic, 0 /* not console */);
 	}

+	sc->sc_core->hc_fndown[0] = sc->sc_core->hc_fndown[1] =
+	    sc->sc_core->hc_fndown[2] = 0;
+
 	if (sc->sc_core->hc_keymap == default_keymap)
 		printf(": no keymap.");

@@ -285,35 +289,26 @@
 	const struct hpckbd_keymap_table *tab;
 	platid_mask_t mask;

-	for (tab = hpckbd_keymap_table; tab->ht_platform != NULL; tab++) {
-
+	for (tab = hpckbd_keymap_table; ; tab++) {
 		mask = PLATID_DEREF(tab->ht_platform);
+		if (platid_match(&platid, &mask))
+			break;
+	}

-		if (platid_match(&platid, &mask)) {
-			hc->hc_keymap = tab->ht_keymap;
-			hc->hc_special = tab->ht_special;
+	hc->hc_entry = tab;
+	hc->hc_keymap = tab->ht_keymap;
 #if !defined(PCKBD_LAYOUT)
-			hpckbd_keymapdata.layout = tab->ht_layout;
+	hpckbd_keymapdata.layout = tab->ht_layout;
 #endif
-			if (tab->ht_cmdmap.map) {
-				hpckbd_keymap_setup(hc, tab->ht_cmdmap.map,
-				    tab->ht_cmdmap.size);
+	if (tab->ht_cmdmap.map) {
+		hpckbd_keymap_setup(hc, tab->ht_cmdmap.map,
+		    tab->ht_cmdmap.size);
 #if !defined(PCKBD_LAYOUT)
-				hpckbd_keymapdata.layout |= KB_MACHDEP;
+		hpckbd_keymapdata.layout |= KB_MACHDEP;
 #endif
-			} else {
-				hpckbd_keymapdata.layout &= ~KB_MACHDEP;
-			}
-			return;
-		}
+	} else {
+		hpckbd_keymapdata.layout &= ~KB_MACHDEP;
 	}
-
-	/* no keymap. use default. */
-	hc->hc_keymap = default_keymap;
-	hc->hc_special = default_special_keymap;
-#if !defined(PCKBD_LAYOUT)
-	hpckbd_keymapdata.layout = KB_US;
-#endif
 }

 void
@@ -336,11 +331,20 @@

 	if (flag) {
 		type = WSCONS_EVENT_KEY_DOWN;
+		key = hc->hc_keymap[scancode];
 	} else {
 		type = WSCONS_EVENT_KEY_UP;
+#ifdef DEBUG
+		if (scancode >= 96)
+			panic("hpckbd: scancode out of range!\n");
+#endif
+		if (hc->hc_fndown[scancode/32] & (1 << (scancode%32)))
+			key = hc->hc_entry->ht_fn_keymap[scancode];
+		else
+			key = hc->hc_entry->ht_keymap[scancode];
 	}

-	if ((key = hc->hc_keymap[scancode]) == UNK) {
+	if (key == UNK) {
 #ifdef DEBUG
 		printf("hpckbd: unknown scan code %#x (%d, %d)\n",
 		    scancode, scancode >> 3,
@@ -353,15 +357,26 @@
 		return (0);
 	}

+	if (key == FUN) {
+		if (flag)
+			hc->hc_keymap = hc->hc_entry->ht_fn_keymap;
+		else
+			hc->hc_keymap = hc->hc_entry->ht_keymap;
+
+		return (0);
+	}
+
 	if (key == SPL) {
+		const int *special = hc->hc_entry->ht_special;
+
 		if (!flag)
 			return (0);

-		if (scancode == hc->hc_special[KEY_SPECIAL_OFF]) {
+		if (scancode == special[KEY_SPECIAL_OFF]) {
 #ifdef DEBUG
 			printf("off button\n"); // XXX notyet -uch
 #endif
-		} else if (scancode == hc->hc_special[KEY_SPECIAL_LIGHT]) {
+		} else if (scancode == special[KEY_SPECIAL_LIGHT]) {
 			static int onoff; /* XXX -uch */
 			config_hook_call(CONFIG_HOOK_BUTTONEVENT,
 			    CONFIG_HOOK_BUTTONEVENT_LIGHT,
@@ -376,18 +391,18 @@
 	}

 	if (hc->hc_polling) {
-		if (hpckbd_putevent(hc, type, hc->hc_keymap[scancode]) == 0)
+		if (hpckbd_putevent(hc, type, key) == 0)
 			printf("hpckbd: queue over flow");
 	} else {
 #ifdef WSDISPLAY_COMPAT_RAWKBD
 		if (hc->hc_rawkbd) {
 			int n;
 			u_char data[16];
-			n = pckbd_encode(type, hc->hc_keymap[scancode], data);
+			n = pckbd_encode(type, key, data);
 			wskbd_rawinput(hc->hc_wskbddev, data, n);
 		} else
 #endif
-			wskbd_input(hc->hc_wskbddev, type, hc->hc_keymap[scancode]);
+			wskbd_input(hc->hc_wskbddev, type, key);
 	}

 	return (0);
Index: sys/dev/hpc/hpckbdkeymap.h
===================================================================
RCS file: /cvsroot/src/sys/dev/hpc/hpckbdkeymap.h,v
retrieving revision 1.26.2.1
diff -u -r1.26.2.1 hpckbdkeymap.h
--- sys/dev/hpc/hpckbdkeymap.h	7 Apr 2004 04:38:42 -0000	1.26.2.1
+++ sys/dev/hpc/hpckbdkeymap.h	21 Nov 2004 22:25:01 -0000
@@ -36,6 +36,7 @@
 #define UNK		255	/* unknown */
 #define IGN		254	/* ignore */
 #define SPL		253	/* special key */
+#define FUN		252	/* bare function key */
 #define KC(n)		KS_KEYCODE(n)
 #define CMDMAP(map)	{ map, (sizeof(map)/sizeof(keysym_t)) }
 #define NULLCMDMAP	{ NULL, 0 }
@@ -247,7 +248,7 @@
 /*10*/	 56,	 57,	 46,	 47,	 32,	 33,	 19,	  4,
 /*18*/	 48,	 49,	 34,	 35,	 20,	 21,	  5,	  6,
 /*20*/	 50,	 51,	 36,	 37,	 22,	 23,	  7,	  8,
-/*28*/	105,	 58,	 38,	 24,	 25,	  9,	 10,	 11,
+/*28*/	FUN,	 58,	 38,	 24,	 25,	  9,	 10,	 11,
 /*30*/	 26,	 27,	203,	 52,	 53,	 39,	 12,	 13,
 /*38*/	 54,	205,	200,	208,	 40,	 28,	 43,	 14,
 /*40*/	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,
@@ -256,6 +257,43 @@
 /*58*/	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,
 };

+static const keysym_t tripad_cmdmap[] = {
+/*	pos      command		normal		shifted		*/
+	KC(13),  KS_Cmd_BrightnessUp,	KS_equal,	KS_plus,
+	KC(12),  KS_Cmd_BrightnessDown,	KS_minus,	KS_underscore,
+	KC(51),  KS_Cmd_ContrastDown,	KS_comma,	KS_less,
+	KC(52),  KS_Cmd_ContrastUp,	KS_period,	KS_greater,
+};
+
+/* Sharp Tripad PV6000 and VADEM CLIO */
+static u_int8_t tripad_fn_keytrans[] = {
+/*00	lsh	tab	-	-	esc	F1	WIN	-	*/
+/*08	ctrl	-	-	-	-	-	-	F2	*/
+/*10	lalt	-	-	-	-	-	-	F3	*/
+/*18	-	-	-	-	-	-	F4	F5	*/
+/*20	-	-	-	-	-	-	F6	F7	*/
+/*28	-	-	-	-	-	F8	F9	F10	*/
+/*30	-	-	Home	-	-	-	F11	F12	*/
+/*38	rsh	End	PgUp	PgDn	-	ent	-	BkSp	*/
+/*40	-	-	-	-	-	-	-	-	*/
+/*48	-	-	-	-	-	-	-	-	*/
+/*50	-	-	-	-	-	-	-	-	*/
+/*58	-	-	-	-	-	-	-	-	*/
+/*----------------------------------------------------------------------*/
+/*00*/	 42,	 15,	IGN,	IGN,	  1,	 59,	104,	IGN,
+/*08*/	 29,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	 60,
+/*10*/	 56,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	 61,
+/*18*/	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	 62,	 63,
+/*20*/	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	 64,	 65,
+/*28*/	IGN,	IGN,	IGN,	IGN,	IGN,	 66,	 67,	 68,
+/*30*/	IGN,	IGN,	199,	IGN,	IGN,	IGN,	 87,	 88,
+/*38*/	 54,	207,	201,	209,	IGN,	 28,	IGN,	211,
+/*40*/	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,
+/*48*/	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,
+/*50*/	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,
+/*58*/	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,	IGN,
+};
+
 /* NEC Mobile Gear MCCS series */
 static u_int8_t mccs_keytrans[] = {
 /*00	caps	cr	rar	p	.	y	b	z	*/
@@ -810,6 +848,7 @@
 const struct hpckbd_keymap_table {
 	platid_t	*ht_platform;
 	const u_int8_t	*ht_keymap;
+	const u_int8_t	*ht_fn_keymap;
 	const int	*ht_special;
 	struct {
 		const keysym_t	*map;
@@ -820,97 +859,116 @@
 #ifdef hpcmips
 	{	&platid_mask_MACH_COMPAQ_C,
 		tc5165_compaq_c_jp_keymap,
+		NULL,
 		tc5165_compaq_c_jp_special_keymap,
 		NULLCMDMAP,
 		KB_JP },
 	{	&platid_mask_MACH_VICTOR_INTERLINK,
 		m38813c_keymap,
+		NULL,
 		default_special_keymap,
 		NULLCMDMAP,
 		KB_JP },
 	{	&platid_mask_MACH_SHARP_TELIOS,
 		tc5165_telios_jp_keymap,
+		NULL,
 		default_special_keymap,
 		NULLCMDMAP,
 		KB_JP },
 	{	&platid_mask_MACH_SHARP_MOBILON,
 		tc5165_mobilon_keymap,
+		NULL,
 		tc5165_mobilon_special_keymap,
 		NULLCMDMAP,
 		KB_US },
 	{	&platid_mask_MACH_NEC_MCR_500A,
 		mobilepro750c_keytrans,
 		NULL,
+		NULL,
 		NULLCMDMAP,
 		KB_US },
 	{	&platid_mask_MACH_NEC_MCR_520A,
 		mobilepro_keytrans,
 		NULL,
+		NULL,
 		CMDMAP(mobilepro_cmdmap),
 		KB_US },
 	{	&platid_mask_MACH_NEC_MCR_530A,
 		mobilepro780_keytrans,
 		NULL,
+		NULL,
 		NULLCMDMAP,
 		KB_US },
 	{	&platid_mask_MACH_NEC_MCR_700A,
 		mobilepro8x0_keytrans,
 		NULL,
+		NULL,
 		CMDMAP(mobilepro8x0_cmdmap),
 		KB_US },
 	{	&platid_mask_MACH_NEC_MCR_730A,
 		mobilepro8x0_keytrans,
 		NULL,
+		NULL,
 		CMDMAP(mobilepro8x0_cmdmap),
 		KB_US },
 	{	&platid_mask_MACH_NEC_MCR_MPRO700,
 		mobilepro_keytrans,
 		NULL,
+		NULL,
 		NULLCMDMAP,
 		KB_US },
 	{	&platid_mask_MACH_NEC_MCR_SIGMARION,
 		sigmarion_jp_keytrans,
 		NULL,
+		NULL,
 		CMDMAP(sigmarion_cmdmap),
 		KB_JP },
 	{	&platid_mask_MACH_NEC_MCR_SIGMARION2,
 		sigmarion_jp_keytrans,
 		NULL,
+		NULL,
 		CMDMAP(sigmarion_cmdmap),
 		KB_JP },
 	{	&platid_mask_MACH_NEC_MCR,
 		mcr_jp_keytrans,
 		NULL,
+		NULL,
 		CMDMAP(mcr_jp_cmdmap),
 		KB_JP },
 	{	&platid_mask_MACH_IBM_WORKPAD_Z50,
 		z50_keytrans,
 		NULL,
+		NULL,
 		NULLCMDMAP,
 		KB_US },
 	{	&platid_mask_MACH_SHARP_TRIPAD,
 		tripad_keytrans,
+		tripad_fn_keytrans,
 		NULL,
-		NULLCMDMAP,
+		CMDMAP(tripad_cmdmap),
 		KB_US },
 	{	&platid_mask_MACH_VADEM_CLIO_C,
 		tripad_keytrans,
+		tripad_fn_keytrans,
 		NULL,
-		NULLCMDMAP,
+		CMDMAP(tripad_cmdmap),
 		KB_US },
 	{	&platid_mask_MACH_NEC_MCCS,
 		mccs_keytrans,
 		NULL,
+		NULL,
 		CMDMAP(mccs_cmdmap),
 		KB_JP },
 	{	&platid_mask_MACH_FUJITSU_INTERTOP,
 		intertop_keytrans,
 		NULL,
+		NULL,
 		NULLCMDMAP,
 		KB_JP },
 	{	&platid_mask_MACH_CASIO_POCKETPOSTPET,
 		pocketpostpet_keytrans,
 		NULL,
+		NULL,
 		NULLCMDMAP,
 		KB_JP },
 #endif /* hpcmips */
@@ -921,66 +979,78 @@
 	/* Japanese */
 	{	&platid_mask_MACH_HP_JORNADA_680JP,
 		jornada6x0_jp_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
 		NULLCMDMAP,
 		KB_JP },
 	{	&platid_mask_MACH_HP_JORNADA_690JP,
 		jornada6x0_jp_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
 		NULLCMDMAP,
 		KB_JP },
 	/* US (ABA), UK (ABU) */
 	{	&platid_mask_MACH_HP_JORNADA_680,
 		jornada6x0_us_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
 		CMDMAP(jornada6x0_us_keydesc),
 		KB_US },
 	{	&platid_mask_MACH_HP_JORNADA_690,
 		jornada6x0_us_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
 		CMDMAP(jornada6x0_us_keydesc),
 		KB_US },
 	/* European English (ABB) */
 	{	&platid_mask_MACH_HP_JORNADA_680EU,
 		jornada6x0_intl_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
 		CMDMAP(jornada6x0_intl_keydesc),
 		KB_US },
 	{	&platid_mask_MACH_HP_JORNADA_690EU,
 		jornada6x0_intl_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
 		CMDMAP(jornada6x0_intl_keydesc),
 		KB_US },
 	/* German (ABD) */
 	{	&platid_mask_MACH_HP_JORNADA_680DE,
 		jornada6x0_intl_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
 		CMDMAP(jornada6x0_de_keydesc),
 		KB_DE },
 	{	&platid_mask_MACH_HP_JORNADA_690DE,
 		jornada6x0_intl_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
  		CMDMAP(jornada6x0_de_keydesc),
 		KB_DE },
 	/* French (ABF) */
 	{	&platid_mask_MACH_HP_JORNADA_680FR,
 		jornada6x0_intl_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
 		CMDMAP(jornada6x0_fr_keydesc),
 		KB_FR },
 	{	&platid_mask_MACH_HP_JORNADA_690FR,
 		jornada6x0_intl_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
  		CMDMAP(jornada6x0_fr_keydesc),
 		KB_FR },
 	/* Scandinavian */
 	{	&platid_mask_MACH_HP_JORNADA_680SV,
 		jornada6x0_intl_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
 		CMDMAP(jornada6x0_scnv_keydesc),
 		KB_US },
 	{	&platid_mask_MACH_HP_JORNADA_690SV,
 		jornada6x0_intl_keytrans,
+		NULL,
 		jornada6x0_special_keymap,
  		CMDMAP(jornada6x0_scnv_keydesc),
 		KB_US },
@@ -990,6 +1060,7 @@
 	/* Japanese */
 	{	&platid_mask_MACH_HP_LX_620JP,
 		hp620lx_jp_keytrans,
+		NULL,
 		hp620lx_special_keymap,
 		NULLCMDMAP,
 		KB_JP },
@@ -999,9 +1070,15 @@
 	/* Japanese */
 	{ 	&platid_mask_MACH_HITACHI_PERSONA_HPW50PAD,
 		persona_hpw50pad_jp_keytrans,
+		NULL,
 		persona_hpw50pad_special_keymap,
 		NULLCMDMAP,
 		KB_JP },
 #endif /* hpcsh */
-	{ NULL } /* end mark */
+	{	&platid_wild,
+		default_keymap,
+		NULL,
+		default_special_keymap,
+		NULLCMDMAP,
+		KB_US },
 };

>Unformatted: