Subject: pccons patch for non-US keyboards.
To: None <current-users@sun-lamp.cs.berkeley.edu>
From: Matthieu Herrb <matthieu@laas.fr>
List: current-users
Date: 08/01/1994 09:21:36
Since I got more than 2 requests for it, here is my patch to
pcccons. 

It's not french specific, but it only has a mapping defined for my
french keyboard. To use it with another keyboard, you'll first have to
add your own table:

1. Choose an option name (for example GERMAN_KBD) 
2. At the beginning of pcccons.c add ''|| defined(GERMAN_KBD)'' after
   #if defined(FRENCH_KBD) to enable NONUS_KBD and DISPLAY_ISO8859
3. Look for 'XXXX Add tables' to see where to add your table. For
   non-us keyboards the struct scan_def as one more field to hold the
   Alt-GR map. Insert you definition of the scan_codes[] array between
   a set of #ifdef GERMAN_KBD .. #endif.
4. Add 'option GERMAN_KBD' to your kernel config file and rebuild your
   kernel. 
5. Reboot.

If you're switch back from pcvt, make sure that the ttyv[0-9] entries
in /etc/ttys are commented out. ttyflags -a causes a kernel crash when
they are there and no kernel support for them is present.

*** /sys/arch/i386/isa/pccons.c.050594	Thu May  5 13:11:11 1994
--- pccons.c	Sun Jul 31 13:20:44 1994
***************
*** 81,86 ****
--- 81,94 ----
  
  #define PCBURST 128
  
+ /*
+  * Non-US keyboards definition
+  */
+ #if defined(FRENCH_KBD)
+ # define NONUS_KBD
+ # define DISPLAY_ISO8859
+ #endif
+ 
  extern u_short *Crtat;			/* pointer to backing store */
  static u_short *crtat;			/* pointer to current char */
  static volatile u_char ack, nak;	/* Don't ask. */
***************
*** 137,142 ****
--- 145,153 ----
  #define	FUNC		0x0100	/* function key */
  #define	KP		0x0200	/* Keypad keys */
  #define	NONE		0x0400	/* no function */
+ #ifdef NONUS_KBD
+ #define ALTGR           0x0040  /* Alt graphic */
+ #endif
  
  static unsigned int addr_6845 = MONO_BASE;
  
***************
*** 726,731 ****
--- 737,764 ----
  	BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
  };
  
+ #ifdef DISPLAY_ISO8859
+ static u_char iso2ibm437[] =
+ {
+            0,     0,     0,     0,     0,     0,     0,     0,
+            0,     0,     0,     0,     0,     0,     0,     0,
+            0,     0,     0,     0,     0,     0,     0,     0,
+            0,     0,     0,     0,     0,     0,     0,     0,
+         0xff,  0xad,  0x9b,  0x9c,     0,  0x9d,     0,  0x40,
+         0x6f,  0x63,  0x61,  0xae,     0,     0,     0,     0,
+         0xf8,  0xf1,  0xfd,  0x33,     0,  0xe6,     0,  0xfa,
+            0,  0x31,  0x6f,  0xaf,  0xac,  0xab,     0,  0xa8,
+         0x41,  0x41,  0x41,  0x41,  0x8e,  0x8f,  0x92,  0x80,
+         0x45,  0x90,  0x45,  0x45,  0x49,  0x49,  0x49,  0x49,
+         0x81,  0xa5,  0x4f,  0x4f,  0x4f,  0x4f,  0x99,  0x4f,
+         0x4f,  0x55,  0x55,  0x55,  0x9a,  0x59,     0,  0xe1,
+         0x85,  0xa0,  0x83,  0x61,  0x84,  0x86,  0x91,  0x87,
+         0x8a,  0x82,  0x88,  0x89,  0x8d,  0xa1,  0x8c,  0x8b,
+            0,  0xa4,  0x95,  0xa2,  0x93,  0x6f,  0x94,  0x6f,
+         0x6f,  0x97,  0xa3,  0x96,  0x81,  0x98,     0,     0
+ };
+ #endif
+ 
  /*
   * `pc3' termcap emulation.
   */
***************
*** 865,870 ****
--- 898,907 ----
  					 * break to do a scroll check.
  					 */
  					for (;;) {
+ #ifdef DISPLAY_ISO8859
+ 				               if (c & 0x80) 
+ 						        c = iso2ibm437[c&0x7f];
+ #endif
  						if (vs.so)
  							wrtchar(c, vs.so_at);
  						else
***************
*** 1179,1184 ****
--- 1216,1222 ----
  }
  
  #define	CODE_SIZE	4		/* Use a max of 4 for now... */
+ #ifndef NONUS_KBD
  typedef struct {
  	u_short	type;
  	char unshift[CODE_SIZE];
***************
*** 1317,1322 ****
--- 1355,1511 ----
  	NONE,	"",		"",		"",		/* 127 */
  };
  
+ #else /* NONUS_KBD */
+ 
+ typedef struct {
+ 	u_short type;
+ 	char unshift[CODE_SIZE];
+ 	char shift[CODE_SIZE];
+ 	char ctl[CODE_SIZE];
+ 	char altgr[CODE_SIZE];
+ } Scan_def;
+ 
+ #ifdef FRENCH_KBD
+ 
+ static Scan_def	scan_codes[] = {
+ 	NONE,	"",	"",	"",	"",	/* 0 unused */
+ 	ASCII,	"\033",	"\033",	"\033", "\033", /* 1 ESCape */
+ 	ASCII,	"&",	"1",	"&",	"",	/* 2 1 */
+ 	ASCII,	"e'",	"2",	"\211",	"~",	/* 3 2 */
+ 	ASCII,	"\"",	"3",	"\"",	"#",	/* 4 3 */
+ 	ASCII,	"'",	"4",	"'",	"{",	/* 5 4 */
+ 	ASCII,	"(",	"5",	"(",	"[",	/* 6 5 */
+ 	ASCII,	"-",	"6",	"-",	"|",	/* 7 6 */
+ 	ASCII,	"e!",	"7",	"\210", "`",	/* 8 7 */
+ 	ASCII,	"_",	"8",	"\037",	"\\",	/* 9 8 */
+ 	ASCII,	"c,",	"9",	"\207",	"^",	/* 10 9 */
+ 	ASCII,	"a!",	"0",	"a!",	"@",	/* 11 0 */
+ 	ASCII,	")",	"DG",	")",	"]",	/* 12 - */
+ 	ASCII,	"=",	"+",	"+",	"}",	/* 13 = */
+ 	ASCII,	"\177",	"\177",	"\010",	"\177",	/* 14 backspace */
+ 	ASCII,	"\t",	"\177\t", "\t",	"\t",	/* 15 tab */
+ 	ASCII,	"a",	"A",	"\001",	"a",	/* 16 q */
+ 	ASCII,	"z",	"Z",	"\032", "z",	/* 17 w */
+ 	ASCII,	"e",	"E",	"\005", "e",	/* 18 e */
+ 	ASCII,	"r",	"R",	"\022", "r",	/* 19 r */
+ 	ASCII,	"t",	"T",	"\024",	"t",	/* 20 t */
+ 	ASCII,	"y",	"Y",	"\031",	"y",	/* 21 y */
+ 	ASCII,	"u",	"U",	"\025", "u",	/* 22 u */
+ 	ASCII,	"i",	"I",	"\011",	"i",	/* 23 i */
+ 	ASCII,	"o",	"O",	"\017", "o",	/* 24 o */
+ 	ASCII,	"p",	"P",	"\020",	"p",	/* 25 p */
+ 	NONE,	"",	"",	"",	"",	/* 26 [ */
+ 	ASCII,	"$",	"Pd",	"$",	"$",	/* 27 ] */
+ 	ASCII,	"\r",	"\r",	"\n",	"\r",	/* 28 return */
+ 	CTL,	"",	"",	"",	"",	/* 29 control */
+ 	ASCII,	"q",	"Q",	"\021",	"q",	/* 30 a */
+ 	ASCII,	"s",	"S",	"\023",	"s",	/* 31 s */
+ 	ASCII,	"d",	"D",	"\004",	"d",	/* 32 d */
+ 	ASCII,	"f",	"F",	"\006",	"f",	/* 33 f */
+ 	ASCII,	"g",	"G",	"\007",	"g",	/* 34 g */
+ 	ASCII,	"h",	"H",	"\010",	"h",	/* 35 h */
+ 	ASCII,	"j",	"J",	"\n",	"j",	/* 36 j */
+ 	ASCII,	"k",	"K",	"\013",	"k",	/* 37 k */
+ 	ASCII,	"l",	"L",	"\014",	"l",	/* 38 l */
+ 	ASCII,	"m",	"M",	"\r",	"m",	/* 39 ; */
+ 	ASCII,	"u!",	"%",	"\231",	"u!",	/* 40 ' */
+ 	ASCII,	"2S",	"",	"2S",	"2S",	/* 41 ` */
+ 	SHIFT,	"",	"",	"",	"",	/* 42 shift */
+ 	ASCII,	"*",	"My",	"*",	"*",	/* 43 \ */
+ 	ASCII,	"w",	"W",	"\027",	"w",	/* 44 z */
+ 	ASCII,	"x",	"X",	"\030",	"x",	/* 45 x */
+ 	ASCII,	"c",	"C",	"\003",	"c",	/* 46 c */
+ 	ASCII,	"v",	"V",	"\026",	"v",	/* 47 v */
+ 	ASCII,	"b",	"B",	"\002",	"b",	/* 48 b */
+ 	ASCII,	"n",	"N",	"\016",	"n",	/* 49 n */
+ 	ASCII,	",",	"?",	",",	",",	/* 50 m */
+ 	ASCII,	";",	".",	";",	";",	/* 51 , */
+ 	ASCII,	":",	"/",	"\037",	":",	/* 52 . */
+ 	ASCII,	"!",	"PI",	"!",	"!",	/* 53 / */
+ 	SHIFT,	"",	"",	"",	"",	/* 54 shift */
+ 	KP,	"*",	"*",	"*",	"*",	/* 55 kp * */
+ 	ALT,	"",	"",	"",	"",	/* 56 alt */
+ 	ASCII,	" ",	" ",	"\000",	" ",	/* 57 space */
+ 	CAPS,	"",	"",	"",	"",	/* 58 caps */
+ 	FUNC,	"\033[M",	"\033[Y",	"\033[k",	"", /* 59 f1 */
+ 	FUNC,	"\033[N",	"\033[Z",	"\033[l",	"", /* 60 f2 */
+ 	FUNC,	"\033[O",	"\033[a",	"\033[m",	"", /* 61 f3 */
+ 	FUNC,	"\033[P",	"\033[b",	"\033[n",	"", /* 62 f4 */
+ 	FUNC,	"\033[Q",	"\033[c",	"\033[o",	"", /* 63 f5 */
+ 	FUNC,	"\033[R",	"\033[d",	"\033[p",	"", /* 64 f6 */
+ 	FUNC,	"\033[S",	"\033[e",	"\033[q",	"", /* 65 f7 */
+ 	FUNC,	"\033[T",	"\033[f",	"\033[r",	"", /* 66 f8 */
+ 	FUNC,	"\033[U",	"\033[g",	"\033[s",	"", /* 67 f9 */
+ 	FUNC,	"\033[V",	"\033[h",	"\033[t",	"", /* 68 f10 */
+ 	NUM,	"",		"",		"",		"", /* 69 num lock */
+ 	SCROLL,	"",		"",		"",		"", /* 70 scroll lock */
+ 	KP,	"7",		"\033[H",	"7",	"",	/* 71 kp 7 */
+ 	KP,	"8",		"\033[A",	"8",	"",	/* 72 kp 8 */
+ 	KP,	"9",		"\033[I",	"9",	"",	/* 73 kp 9 */
+ 	KP,	"-",		"-",		"-",	"",	/* 74 kp - */
+ 	KP,	"4",		"\033[D",	"4",	"",	/* 75 kp 4 */
+ 	KP,	"5",		"\033[E",	"5",	"",	/* 76 kp 5 */
+ 	KP,	"6",		"\033[C",	"6",	"",	/* 77 kp 6 */
+ 	KP,	"+",		"+",		"+",	"",	/* 78 kp + */
+ 	KP,	"1",		"\033[F",	"1",	"",	/* 79 kp 1 */
+ 	KP,	"2",		"\033[B",	"2",	"",	/* 80 kp 2 */
+ 	KP,	"3",		"\033[G",	"3",	"",	/* 81 kp 3 */
+ 	KP,	"0",		"\033[L",	"0",	"",	/* 82 kp 0 */
+ 	KP,	".",		"\177",		".",	"",	/* 83 kp . */
+ 	NONE,	"",		"",		"",	"",	/* 84 0 */
+ 	NONE,	"100",		"",		"",	"",	/* 85 0 */
+ 	ASCII,	"<",		">",		"<",	"<",	/* 86 < > */
+ 	FUNC,	"\033[W",	"\033[i",	"\033[u","",	/* 87 f11 */
+ 	FUNC,	"\033[X",	"\033[j",	"\033[v","",	/* 88 f12 */
+ 	NONE,	"102",		"",		"",	"",	/* 89 0 */
+ 	NONE,	"103",		"",		"",	"",	/* 90 0 */
+ 	NONE,	"",		"",		"",	"",	/* 91 0 */
+ 	NONE,	"",		"",		"",	"",	/* 92 0 */
+ 	NONE,	"",		"",		"",	"",	/* 93 0 */
+ 	NONE,	"",		"",		"",	"",	/* 94 0 */
+ 	NONE,	"",		"",		"",	"",	/* 95 0 */
+ 	NONE,	"",		"",		"",	"",	/* 96 0 */
+ 	NONE,	"",		"",		"",	"",	/* 97 0 */
+ 	NONE,	"",		"",		"",	"",	/* 98 0 */
+ 	NONE,	"",		"",		"",	"",	/* 99 0 */
+ 	NONE,	"",		"",		"",	"",	/* 100 */
+ 	NONE,	"",		"",		"",	"",	/* 101 */
+ 	NONE,	"",		"",		"",	"",	/* 102 */
+ 	NONE,	"",		"",		"",	"",	/* 103 */
+ 	NONE,	"",		"",		"",	"",	/* 104 */
+ 	NONE,	"",		"",		"",	"",	/* 105 */
+ 	NONE,	"",		"",		"",	"",	/* 106 */
+ 	NONE,	"",		"",		"",	"",	/* 107 */
+ 	NONE,	"",		"",		"",	"",	/* 108 */
+ 	NONE,	"",		"",		"",	"",	/* 109 */
+ 	NONE,	"",		"",		"",	"",	/* 110 */
+ 	NONE,	"",		"",		"",	"",	/* 111 */
+ 	NONE,	"",		"",		"",	"",	/* 112 */
+ 	NONE,	"",		"",		"",	"",	/* 113 */
+ 	NONE,	"",		"",		"",	"",	/* 114 */
+ 	NONE,	"",		"",		"",	"",	/* 115 */
+ 	NONE,	"",		"",		"",	"",	/* 116 */
+ 	NONE,	"",		"",		"",	"",	/* 117 */
+ 	NONE,	"",		"",		"",	"",	/* 118 */
+ 	NONE,	"",		"",		"",	"",	/* 119 */
+ 	NONE,	"",		"",		"",	"",	/* 120 */
+ 	NONE,	"",		"",		"",	"",	/* 121 */
+ 	NONE,	"",		"",		"",	"",	/* 122 */
+ 	NONE,	"",		"",		"",	"",	/* 123 */
+ 	NONE,	"",		"",		"",	"",	/* 124 */
+ 	NONE,	"",		"",		"",	"",	/* 125 */
+ 	NONE,	"",		"",		"",	"",	/* 126 */
+ 	NONE,	"",		"",		"",	"",	/* 127 */
+ };
+ 
+ #endif /* FRENCH_KBD */
+ 
+ /*
+  * XXXX Add tables for other keyboards here
+  */
+ 
+ #endif
+ 
  /*
   * Get characters from the keyboard.  If none are present, return NULL.
   */
***************
*** 1431,1436 ****
--- 1620,1630 ----
  			shift_state &= ~SHIFT;
  			break;
  		case ALT:
+ #ifdef NONUS_KBD
+ 			if (extended) 
+ 			        shift_state &= ~ALTGR;
+ 			else
+ #endif		     
  			shift_state &= ~ALT;
  			break;
  		case CTL:
***************
*** 1475,1486 ****
--- 1669,1692 ----
  			shift_state |= SHIFT;
  			break;
  		case ALT:
+ #ifdef NONUS_KBD
+ 			if (extended)  
+ 			        shift_state |= ALTGR;
+ 			else
+ #endif
  			shift_state |= ALT;
  			break;
  		case CTL:
  			shift_state |= CTL;
  			break;
  		case ASCII:
+ #ifdef NONUS_KBD
+ 			if (shift_state & ALTGR) {
+ 			        capchar[0] = scan_codes[dt].altgr[0];
+ 				if (shift_state & CTL) 
+ 				        capchar[0] &= 0x1f;
+ 			} else
+ #endif
  			/* control has highest priority */
  			if (shift_state & CTL)
  				capchar[0] = scan_codes[dt].ctl[0];
***************
*** 1493,1498 ****
--- 1699,1705 ----
  				capchar[0] -= ('a' - 'A');
  			}
  			capchar[0] |= (shift_state & ALT);
+ 
  			extended = 0;
  			return capchar;
  		case NONE:



					Matthieu

------------------------------------------------------------------------------