Subject: Re: Anyone got a type-4 keyboard?
To: NetBSD port-sparc mailing list <port-sparc@netbsd.org>
From: Greg A. Woods <woods@weird.com>
List: port-sparc
Date: 10/08/2002 22:48:52
[ On Tuesday, October 8, 2002 at 19:23:30 (+0100), Julian Coleman wrote: ]
> Subject: Re: Anyone got a type-4 keyboard?
>
> Running vi under 1.5 on the console of a 4/330 with a type 4 keyboard, the
> keypad keys don't work (never noticed before - I always use 'h', 'j', 'k'
> and 'l' ;-). Adding the following as ~/.termcap and setting $TERM to
> "sun-type4" fixes that :
>
> sun-type4:\
> :kd=\E[221z:kl=\E[217z:kr=\E[219z:ku=\E[215z:tc=sun-il:
>
> It also makes the cursor keys work with `set -E` in /bin/sh.
Hmmm... that made me think about something I'd seen a while ago, and
since I had come to a clean juncture where shutting down my desktop
wouldn't matter I logged out and sure enough the keypad cursor keys
generate the above sequences on this SS20 with type-4 keyboard!
This confused me enormously since I'm pretty sure that's not what
happens under SunOS-5, and indeed on all versions of SunOS-5 that I've
looked on the headless machines I now have access to at you'll find that
both their termcap file, and the default terminfo files, for both 'sun'
and 'sun1' say:
ku=\E[A:kd=\E[B:kr=\E[C:kl=\E[D
and
kcub1=\E[D, kcud1=\E[B, kcuf1=\E[C, kcuu1=\E[A,
respectively.
I also noted that in NetBSD's sys/dev/sun/kbd_tables.c there are special
string definitions for the arrow and home keys which suggest the driver
should be translating those keys into the "standard" ANSI X3.64
sequences as defined in our own termcap.src too.
There is some confusion though because the kb(7m) manual page for the
console keyboard driver STREAMS module says:
In TR_ASCII mode, when a function key is pressed, the fol-
lowing escape sequence is sent:
ESC[0....9z
where ESC is a single escape character and "0...9" indicates
the decimal representation of the function-key value. For
example, function key R1 sends the sequence:
ESC[208z
because the decimal value of RF(1) is 208.
Later it says:
FUNCKEYS 0x600 Function keys. The next-to-lowest 4
bits indicate the group of function
keys:
LEFTFUNC 0x600
RIGHTFUNC 0x610
TOPFUNC 0x620
BOTTOMFUNC 0x630
The low 4 bits indicate the function key number within the
group:
LF(n) (LEFTFUNC+(n)-1)
RF(n) (RIGHTFUNC+(n)-1)
TF(n) (TOPFUNC+(n)-1)
BF(n) (BOTTOMFUNC+(n)-1)
and according to keytables(4), which gives the default standard
translation table for a U.S. Type 4 keyboard:
key 21 all rf(1)
key 22 all rf(2)
key 23 all rf(3)
key 45 all rf(4) numl padequal
key 46 all rf(5) numl padslash
key 47 all rf(6) numl padstar
key 50 all bf(10) numl padequal
key 68 all rf(7) numl pad7
key 69 all rf(8) numl pad8
key 70 all rf(9) numl pad9
key 71 all bf(15) numl padminus
key 90 all bf(11) numl padenter
key 91 all rf(10) numl pad4
key 92 all rf(11) numl pad5
key 93 all rf(12) numl pad6
key 94 all bf(8) numl pad0
key 112 all rf(13) numl pad1
key 113 all rf(14) numl pad2
key 114 all rf(15) numl pad3
key 125 all bf(14) numl padplus
Now here's where it gets a wee bit confusing. kb(7m) also says:
STRING 0x500 The low-order bits index a table of
strings. When a key with a STRING entry
is depressed, the characters in the
null-terminated string for that key are
sent, character by character. The max-
imum length is defined as:
KTAB_STRLEN 10
Individual string numbers are defined
as:
HOMEARROW 0x00
UPARROW 0x01
DOWNARROW 0x02
LEFTARROW 0x03
RIGHTARROW 0x04
String numbers 0x05 - 0x0F are available
for custom entries.
and keytables(4) says keys can be mapped using these expressions:
string+uparrow
the key is to be the "up arrow" key
string+downarrow
the key is to be the "down arrow" key
string+leftarrow
the key is to be the "left arrow" key
string+rightarrow
the key is to be the "right arrow" key
string+homearrow
the key is to be the "home" key
However in the default mapping table for the US type-4 as given in the
manual page none of the above expressions are used.
Of course that's still not the full story (this is Solaris, after all!).
According to loadkeys(1):
By default, loadkeys loads the file:
/usr/share/lib/keytables/type_tt/layout_dd, where tt is the
value returned by the KIOCTYPE ioctl, and dd is the value
returned by the KIOCLAYOUT ioctl (see kb(7M)). On self-
identifying keyboards, the value returned by the KIOCLAYOUT
ioctl is set from the DIP switches. These files specify only
the entries that change between the different Type-4 key-
board layouts.
and 'loadkeys is indeed run on boot by /etc/rcS.d/S33keymap.sh (with an
undocumented '-e' on SunOS-5.6).
Interestingly type_4/us is one of the few translation tables that indeed
does not define any keys with the 'string+' expressions. Only these
matching 'us*' do:
$ fgrep string /usr/share/lib/keytables/type_4/us*
/usr/share/lib/keytables/type_4/us101a_pc:key 20 all string+uparrow
/usr/share/lib/keytables/type_4/us101a_pc:key 24 all string+leftarrow
/usr/share/lib/keytables/type_4/us101a_pc:key 27 all string+downarrow
/usr/share/lib/keytables/type_4/us101a_pc:key 28 all string+rightarrow
/usr/share/lib/keytables/type_4/us_5:key 20 all string+uparrow
/usr/share/lib/keytables/type_4/us_5:key 24 all string+leftarrow
/usr/share/lib/keytables/type_4/us_5:key 27 all string+downarrow
/usr/share/lib/keytables/type_4/us_5:key 28 all string+rightarrow
/usr/share/lib/keytables/type_4/us_hobo:key 20 all string+uparrow
/usr/share/lib/keytables/type_4/us_hobo:key 24 all string+leftarrow
/usr/share/lib/keytables/type_4/us_hobo:key 27 all string+downarrow
/usr/share/lib/keytables/type_4/us_hobo:key 28 all string+rightarrow
and those are all type-5 key codes despite the directory name, though
there is a note in kb(7m)
Many of the keyboards released after Sun Type 4 keyboard
also report themselves as Sun Type 4 keyboard.
Yuck.
Now back to NetBSD.
In sys/dev/sun/kbd_tables.h we see:
/*
* The string entry class.
* The low 4 bits select one of the entries from
* the string table. (see kbd_stringtab[])
* By default, the string table has ANSI movement
* sequences for the arrow keys.
*/
#define KEYSYM_STRING 0x0500
and in sys/dev/sun/kbd_tables.c we see:
/*
* Strings indexed by: (KEYSYM_STRING | idx)
*/
char kbd_stringtab[16][10] = {
{ 0x1b, '[', 'H', 0 }, /* 0: Home */
{ 0x1b, '[', 'A', 0 }, /* 1: Up */
{ 0x1b, '[', 'B', 0 }, /* 2: Down */
{ 0x1b, '[', 'D', 0 }, /* 3: Left */
{ 0x1b, '[', 'C', 0 }, /* 4: Right */
};
and still in sys/dev/sun/kbd_tables.c we also see:
/*
* Keymaps for the "type 4" keyboard.
* (lower-case, upper-case)
*/
u_short keymap_s4_lc[KEYMAP_SIZE] = {
(it's the same in keymap_s4_uc too)
/* 24: T5_Left */ KEYSYM_STRING | 3,
/* 20: T5_Up */ KEYSYM_STRING | 1,
/* 27: T5_Down */ KEYSYM_STRING | 2,
/* 28: T5_Right */ KEYSYM_STRING | 4,
/* 52: T5_Home */ KEYSYM_FUNC_R(7),
but for the type-4 keypad we only have:
/* 68: R7/Home */ KEYSYM_FUNC_R(7),
/* 69: R8/Up */ KEYSYM_FUNC_R(8),
/* 70: R9/PgUp */ KEYSYM_FUNC_R(9),
/* 71: KP_Minus */ KEYSYM_FUNC_N(15),
/* 90: KP_Enter */ KEYSYM_FUNC_N(11),
/* 91: R10/Left */ KEYSYM_FUNC_R(10),
/* 92: R11/KP_5 */ KEYSYM_FUNC_R(11),
/* 93: R12/Right */ KEYSYM_FUNC_R(12),
/* 94: KP_Insert */ KEYSYM_FUNC_N(8),
/* 96: T5_PgUp */ KEYSYM_FUNC_R(9),
/* 112: R13/End */ KEYSYM_FUNC_R(13),
/* 113: R14/Down */ KEYSYM_FUNC_R(14),
/* 114: R15/PgDn */ KEYSYM_FUNC_R(15),
In the CVS history for sys/dev/sun/kbd_tables.c we find:
----------------------------
revision 1.7
date: 2002/04/12 14:27:29; author: pk; state: Exp; lines: +22 -22
Add entries for Type5 keys T5_Insert, T5_Home, T5_End, T5_PgUp and T5_PgDn
as suggested by uwe@netbsd.org.
----------------------------
which is where the Up, Down, Right, and Left keys were fixed for type-5
(though oddly Home was not).
Ultimately we find the cause of my confusion:
----------------------------
revision 1.5
date: 1997/10/28 06:18:36; author: gwr; state: Exp; lines: +38 -38
branches: 1.5.26; 1.5.28;
The release and control maps are shared by all keyboard types, so
change KEYSYM_HOLE to KEYSYM_NOP most places in those tables.
Map the `R' function keys with KEYSYM_FUNC_R instead of the
arrow key strings so that numlock indirection works.
----------------------------
and indeed the delta includes these changes:
***************
*** 394 ****
! /* 69: R8/Up */ KEYSYM_STRING | 1,
--- 394 ----
! /* 69: R8/Up */ KEYSYM_FUNC_R(8),
***************
*** 416 ****
! /* 91: R10/Left */ KEYSYM_STRING | 3,
--- 416 ----
! /* 91: R10/Left */ KEYSYM_FUNC_R(10),
***************
*** 418 ****
! /* 93: R12/Right */ KEYSYM_STRING | 4,
--- 418 ----
! /* 93: R12/Right */ KEYSYM_FUNC_R(12),
***************
*** 438 ****
! /* 113: R14/Down */ KEYSYM_STRING | 2,
--- 438 ----
! /* 113: R14/Down */ KEYSYM_FUNC_R(14),
In this change the type-4 keypad mappings to KEYSYM_STRING entries was
removed. That's why way back when an SS-1 was my desktop, and it was
running a really old kernel, it worked fine, but now the same keyboard
running a 1.6-branch kernel (now on an SS-20, though that doesn't
matter), does not have working console cursor keys.
I see that a "sun-type4" entry has been added to termcap.src. This is a
work-around had, I'm guessing/hoping. The correct fix is to find out
what that rev.1.5 comment above really means and then to fix the tables
properly again so that the arrow keys are by default mapped to their
proper KEYSYM_STRING values. What does "numlock indirection" mean, and
how did it not work with the proper KEYSYM_STRING mappings in place?
Though I didn't use my console much (except under X11) when running the
old kernel, I don't remember having any problems with numlock either.
(another work-around hack would be to write a small program which does
the right ioctl(KIOCSKEY) on the console keyboard to undo the above
rev.1.5 changes and also to fix key 68 to be KEYSYM_STRING|0 too.....)
--
Greg A. Woods
+1 416 218-0098; <g.a.woods@ieee.org>; <woods@robohack.ca>
Planix, Inc. <woods@planix.com>; VE3TCP; Secrets of the Weird <woods@weird.com>