1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright (c) 1999 by Sun Microsystems, Inc.
  24  * All rights reserved.
  25  */
  26 
  27 /*
  28  * This file contains generic keytable information across all
  29  * keyboard hardware.
  30  */
  31 
  32 #include <sys/param.h>
  33 #include <sys/kbd.h>
  34 
  35 /*
  36  * Keyboard String Table
  37  *
  38  * This defines the strings sent by various keys (as selected in the
  39  * tables above).
  40  * The first byte of each string is its length, the rest is data.
  41  */
  42 
  43 #ifdef  __STDC__
  44 #define kstescinit(c)   "\033[" #c
  45 #else   /* __STDC__ */
  46 #define kstescinit(c)   {'\033', '[', 'c', '\0'}
  47 #endif  /* __STDC__ */
  48 char keystringtab[16][KTAB_STRLEN] = {
  49         kstescinit(H) /* home */,
  50         kstescinit(A) /* up */,
  51         kstescinit(B) /* down */,
  52         kstescinit(D) /* left */,
  53         kstescinit(C) /* right */,
  54 };
  55 
  56 
  57 /*
  58  * Compose Key Sequence Table
  59  *
  60  * Taken from Suncompose.h of openwindows.
  61  *
  62  * The idea here is to create a simple index into a table of
  63  * compose key sequences.  The purpose is to provide a fast
  64  * lookup mechanism using as little space as possible (while
  65  * still using a table of triplets).
  66  *
  67  * For reference, here is the set of all composable characters:
  68  * SP !\"\'*+,-./01234:<>?ACDEHILNOPRSTUXY\\^_`acdehilnoprstuxy|~
  69  *
  70  * if ascii_char[i] is not composable,
  71  *      kb_compose_map[i] is -1
  72  * else
  73  *      if ascii_char[i] appears as a first char in compose_table,
  74  *              kb_compose_map[i] is the index of it's first appearance
  75  *      else
  76  *              kb_compose_map[i] is 112        (end of table)
  77  */
  78 
  79 signed char kb_compose_map[ASCII_SET_SIZE] = {
  80         -1,     /* 000 (^@) */
  81         -1,     /* 001 (^A) */
  82         -1,     /* 002 (^B) */
  83         -1,     /* 003 (^C) */
  84         -1,     /* 004 (^D) */
  85         -1,     /* 005 (^E) */
  86         -1,     /* 006 (^F) */
  87         -1,     /* 007 (^G) */
  88         -1,     /* 008 (^H) */
  89         -1,     /* 009 (^I) */
  90         -1,     /* 010 (^J) */
  91         -1,     /* 011 (^K) */
  92         -1,     /* 012 (^L) */
  93         -1,     /* 013 (^M) */
  94         -1,     /* 014 (^N) */
  95         -1,     /* 015 (^O) */
  96         -1,     /* 016 (^P) */
  97         -1,     /* 017 (^Q) */
  98         -1,     /* 018 (^R) */
  99         -1,     /* 019 (^S) */
 100         -1,     /* 020 (^T) */
 101         -1,     /* 021 (^U) */
 102         -1,     /* 022 (^V) */
 103         -1,     /* 023 (^W) */
 104         -1,     /* 024 (^X) */
 105         -1,     /* 025 (^Y) */
 106         -1,     /* 026 (^Z) */
 107         -1,     /* 027 (^[) */
 108         -1,     /* 028 (^\) */
 109         -1,     /* 029 (^]) */
 110         -1,     /* 030 (^^) */
 111         -1,     /* 031 (^_) */
 112         0,      /* 032 (SP) */
 113         1,      /* 033 (!) */
 114         4,      /* 034 (") */
 115         -1,     /* 035 (#) */
 116         -1,     /* 036 ($) */
 117         -1,     /* 037 (%) */
 118         -1,     /* 038 (&) */
 119         16,     /* 039 (') */
 120         -1,     /* 040 (() */
 121         -1,     /* 041 ()) */
 122         28,     /* 042 (*) */
 123         31,     /* 043 (+) */
 124         32,     /* 044 (,) */
 125         36,     /* 045 (-) */
 126         48,     /* 046 (.) */
 127         49,     /* 047 (/) */
 128         54,     /* 048 (0) */
 129         57,     /* 049 (1) */
 130         60,     /* 050 (2) */
 131         61,     /* 051 (3) */
 132         112,    /* 052 (4) */
 133         -1,     /* 053 (5) */
 134         -1,     /* 054 (6) */
 135         -1,     /* 055 (7) */
 136         -1,     /* 056 (8) */
 137         -1,     /* 057 (9) */
 138         112,    /* 058 (:) */
 139         -1,     /* 059 (;) */
 140         63,     /* 060 (<) */
 141         -1,     /* 061 (=) */
 142         64,     /* 062 (>) */
 143         65,     /* 063 (?) */
 144         -1,     /* 064 (@) */
 145         66,     /* 065 (A) */
 146         -1,     /* 066 (B) */
 147         70,     /* 067 (C) */
 148         112,    /* 068 (D) */
 149         71,     /* 069 (E) */
 150         -1,     /* 070 (F) */
 151         -1,     /* 071 (G) */
 152         73,     /* 072 (H) */
 153         74,     /* 073 (I) */
 154         -1,     /* 074 (J) */
 155         -1,     /* 075 (K) */
 156         112,    /* 076 (L) */
 157         -1,     /* 077 (M) */
 158         76,     /* 078 (N) */
 159         77,     /* 079 (O) */
 160         84,     /* 080 (P) */
 161         -1,     /* 081 (Q) */
 162         112,    /* 082 (R) */
 163         112,    /* 083 (S) */
 164         112,    /* 084 (T) */
 165         85,     /* 085 (U) */
 166         -1,     /* 086 (V) */
 167         -1,     /* 087 (W) */
 168         112,    /* 088 (X) */
 169         112,    /* 089 (Y) */
 170         -1,     /* 090 (Z) */
 171         -1,     /* 091 ([) */
 172         87,     /* 092 (\) */
 173         -1,     /* 093 (]) */
 174         88,     /* 094 (^) */
 175         93,     /* 095 (_) */
 176         94,     /* 096 (`) */
 177         99,     /* 097 (a) */
 178         -1,     /* 098 (b) */
 179         101,    /* 099 (c) */
 180         112,    /* 100 (d) */
 181         112,    /* 101 (e) */
 182         -1,     /* 102 (f) */
 183         -1,     /* 103 (g) */
 184         102,    /* 104 (h) */
 185         112,    /* 105 (i) */
 186         -1,     /* 106 (j) */
 187         -1,     /* 107 (k) */
 188         112,    /* 108 (l) */
 189         -1,     /* 109 (m) */
 190         103,    /* 110 (n) */
 191         104,    /* 111 (o) */
 192         108,    /* 112 (p) */
 193         -1,     /* 113 (q) */
 194         112,    /* 114 (r) */
 195         109,    /* 115 (s) */
 196         112,    /* 116 (t) */
 197         112,    /* 117 (u) */
 198         -1,     /* 118 (v) */
 199         -1,     /* 119 (w) */
 200         110,    /* 120 (x) */
 201         112,    /* 121 (y) */
 202         -1,     /* 122 (z) */
 203         -1,     /* 123 ({) */
 204         111,    /* 124 (|) */
 205         -1,     /* 125 (}) */
 206         112,    /* 126 (~) */
 207         -1,     /* 127 (DEL) */
 208 };
 209 
 210 /*
 211  * IMPORTANT NOTE:  This table MUST be kept in proper sorted order:
 212  *      The first and second characters in each entry must be in ASCII
 213  *          collating sequence (left to right).
 214  *      The table must be in ASCII collating sequence by first character
 215  *          (top to bottom).
 216  */
 217 
 218 /* COMPOSE + first character + second character => UTF-8 character */
 219 
 220 struct compose_sequence_t kb_compose_table[] = {
 221 
 222         {' ', ' ', 0xA0},       /* 000 */       /* NBSP (non-breaking space) */
 223         {'!', '!', 0xA1},       /* 001 */       /* inverted ! */
 224         {'!', 'P', 0xB6},       /* 002 */       /* paragraph mark */
 225         {'!', 'p', 0xB6},       /* 003 */       /* paragraph mark */
 226         {'"', '"', 0xA8},       /* 004 */       /* diaresis */
 227         {'"', 'A', 0xC4},       /* 005 */       /* A with diaresis */
 228         {'"', 'E', 0xCB},       /* 006 */       /* E with diaresis */
 229         {'"', 'I', 0xCF},       /* 007 */       /* I with diaresis */
 230         {'"', 'O', 0xD6},       /* 008 */       /* O with diaresis */
 231         {'"', 'U', 0xDC},       /* 009 */       /* U with diaresis */
 232         {'"', 'a', 0xE4},       /* 010 */       /* a with diaresis */
 233         {'"', 'e', 0xEB},       /* 011 */       /* e with diaresis */
 234         {'"', 'i', 0xEF},       /* 012 */       /* i with diaresis */
 235         {'"', 'o', 0xF6},       /* 013 */       /* o with diaresis */
 236         {'"', 'u', 0xFC},       /* 014 */       /* u with diaresis */
 237         {'"', 'y', 0xFF},       /* 015 */       /* y with diaresis */
 238         {'\'', 'A', 0xC1},      /* 016 */       /* A with acute accent */
 239         {'\'', 'E', 0xC9},      /* 017 */       /* E with acute accent */
 240         {'\'', 'I', 0xCD},      /* 018 */       /* I with acute accent */
 241         {'\'', 'O', 0xD3},      /* 019 */       /* O with acute accent */
 242         {'\'', 'U', 0xDA},      /* 020 */       /* U with acute accent */
 243         {'\'', 'Y', 0xDD},      /* 021 */       /* Y with acute accent */
 244         {'\'', 'a', 0xE1},      /* 022 */       /* a with acute accent */
 245         {'\'', 'e', 0xE9},      /* 023 */       /* e with acute accent */
 246         {'\'', 'i', 0xED},      /* 024 */       /* i with acute accent */
 247         {'\'', 'o', 0xF3},      /* 025 */       /* o with acute accent */
 248         {'\'', 'u', 0xFA},      /* 026 */       /* u with acute accent */
 249         {'\'', 'y', 0xFD},      /* 027 */       /* y with acute accent */
 250         {'*', 'A', 0xC5},       /* 028 */       /* A with ring */
 251         {'*', '^', 0xB0},       /* 029 */       /* degree */
 252         {'*', 'a', 0xE5},       /* 030 */       /* a with ring */
 253         {'+', '-', 0xB1},       /* 031 */       /* plus/minus */
 254         {',', ',', 0xB8},       /* 032 */       /* cedilla */
 255         {',', '-', 0xAC},       /* 033 */       /* not sign */
 256         {',', 'C', 0xC7},       /* 034 */       /* C with cedilla */
 257         {',', 'c', 0xE7},       /* 035 */       /* c with cedilla */
 258         {'-', '-', 0xAD},       /* 036 */       /* soft hyphen */
 259         {'-', ':', 0xF7},       /* 037 */       /* division sign */
 260         {'-', 'A', 0xAA},       /* 038 */       /* feminine superior numeral */
 261         {'-', 'D', 0xD0},       /* 039 */       /* Upper-case eth */
 262         {'-', 'L', 0xA3},       /* 040 */       /* pounds sterling */
 263         {'-', 'Y', 0xA5},       /* 041 */       /* yen */
 264         {'-', '^', 0xAF},       /* 042 */       /* macron */
 265         {'-', 'a', 0xAA},       /* 043 */       /* feminine superior numeral */
 266         {'-', 'd', 0xF0},       /* 044 */       /* Lower-case eth */
 267         {'-', 'l', 0xA3},       /* 045 */       /* pounds sterling */
 268         {'-', 'y', 0xA5},       /* 046 */       /* yen */
 269         {'-', '|', 0xAC},       /* 047 */       /* not sign */
 270         {'.', '^', 0xB7},       /* 048 */       /* centered dot */
 271         {'/', 'C', 0xA2},       /* 049 */       /* cent sign */
 272         {'/', 'O', 0xD8},       /* 050 */       /* O with slash */
 273         {'/', 'c', 0xA2},       /* 051 */       /* cent sign */
 274         {'/', 'o', 0xF8},       /* 052 */       /* o with slash */
 275         {'/', 'u', 0xB5},       /* 053 */       /* mu */
 276         {'0', 'X', 0xA4},       /* 054 */       /* currency symbol */
 277         {'0', '^', 0xB0},       /* 055 */       /* degree */
 278         {'0', 'x', 0xA4},       /* 056 */       /* currency symbol */
 279         {'1', '2', 0xBD},       /* 057 */       /* 1/2 */
 280         {'1', '4', 0xBC},       /* 058 */       /* 1/4 */
 281         {'1', '^', 0xB9},       /* 059 */       /* superior '1' */
 282         {'2', '^', 0xB2},       /* 060 */       /* superior '2' */
 283         {'3', '4', 0xBE},       /* 061 */       /* 3/4 */
 284         {'3', '^', 0xB3},       /* 062 */       /* superior '3' */
 285         {'<', '<', 0xAB}, /* 063 */       /* left guillemot */
 286         {'>', '>', 0xBB}, /* 064 */       /* right guillemot */
 287         {'?', '?', 0xBF},       /* 065 */       /* inverted ? */
 288         {'A', 'E', 0xC6},       /* 066 */       /* AE dipthong */
 289         {'A', '^', 0xC2},       /* 067 */       /* A with circumflex accent */
 290         {'A', '`', 0xC0},       /* 068 */       /* A with grave accent */
 291         {'A', '~', 0xC3},       /* 069 */       /* A with tilde */
 292         {'C', 'O', 0xA9},       /* 060 */       /* copyright */
 293         {'E', '^', 0xCA},       /* 071 */       /* E with circumflex accent */
 294         {'E', '`', 0xC8},       /* 072 */       /* E with grave accent */
 295         {'H', 'T', 0xDE},       /* 073 */       /* Upper-case thorn */
 296         {'I', '^', 0xCE},       /* 074 */       /* I with circumflex accent */
 297         {'I', '`', 0xCC},       /* 075 */       /* I with grave accent */
 298         {'N', '~', 0xD1},       /* 076 */       /* N with tilde */
 299         {'O', 'R', 0xAE},       /* 077 */       /* registered */
 300         {'O', 'S', 0xA7},       /* 078 */       /* section mark */
 301         {'O', 'X', 0xA4},       /* 079 */       /* currency symbol */
 302         {'O', '^', 0xD4},       /* 080 */       /* O with circumflex accent */
 303         {'O', '_', 0xBA},       /* 081 */       /* masculine superior numeral */
 304         {'O', '`', 0xD2},       /* 082 */       /* O with grave accent */
 305         {'O', '~', 0xD5},       /* 083 */       /* O with tilde */
 306         {'P', '|', 0xDE},       /* 084 */       /* Upper-case thorn */
 307         {'U', '^', 0xDB},       /* 085 */       /* U with circumflex accent */
 308         {'U', '`', 0xD9},       /* 086 */       /* U with grave accent */
 309         {'\\', '\\', 0xB4},     /* 087 */       /* acute accent */
 310         {'^', 'a', 0xE2},       /* 088 */       /* a with circumflex accent */
 311         {'^', 'e', 0xEA},       /* 089 */       /* e with circumflex accent */
 312         {'^', 'i', 0xEE},       /* 090 */       /* i with circumflex accent */
 313         {'^', 'o', 0xF4},       /* 091 */       /* o with circumflex accent */
 314         {'^', 'u', 0xFB},       /* 092 */       /* u with circumflex accent */
 315         {'_', 'o', 0xBA},       /* 093 */       /* masculine superior numeral */
 316         {'`', 'a', 0xE0},       /* 094 */       /* a with grave accent */
 317         {'`', 'e', 0xE8},       /* 095 */       /* e with grave accent */
 318         {'`', 'i', 0xEC},       /* 096 */       /* i with grave accent */
 319         {'`', 'o', 0xF2},       /* 097 */       /* o with grave accent */
 320         {'`', 'u', 0xF9},       /* 098 */       /* u with grave accent */
 321         {'a', 'e', 0xE6},       /* 099 */       /* ae dipthong */
 322         {'a', '~', 0xE3},       /* 100 */       /* a with tilde */
 323         {'c', 'o', 0xA9},       /* 101 */       /* copyright */
 324         {'h', 't', 0xFE},       /* 102 */       /* Lower-case thorn */
 325         {'n', '~', 0xF1},       /* 103 */       /* n with tilde */
 326         {'o', 'r', 0xAE},       /* 104 */       /* registered */
 327         {'o', 's', 0xA7},       /* 105 */       /* section mark */
 328         {'o', 'x', 0xA4},       /* 106 */       /* currency symbol */
 329         {'o', '~', 0xF5},       /* 107 */       /* o with tilde */
 330         {'p', '|', 0xFE},       /* 108 */       /* Lower-case thorn */
 331         {'s', 's', 0xDF},       /* 109 */       /* German double-s */
 332         {'x', 'x', 0xD7},       /* 110 */       /* multiplication sign */
 333         {'|', '|', 0xA6},       /* 111 */       /* broken bar */
 334 
 335         {0, 0, 0},                      /* end of table */
 336 };
 337 
 338 /*
 339  * Floating Accent Sequence Table
 340  */
 341 
 342 /* FA + ASCII character => UTF-8 character */
 343 struct fltaccent_sequence_t kb_fltaccent_table[] = {
 344 
 345         {FA_UMLAUT, ' ', 0xA8},         /* umlaut/diaresis */
 346         {FA_UMLAUT, 'A', 0xC4},         /* A with umlaut */
 347         {FA_UMLAUT, 'E', 0xCB},         /* E with umlaut */
 348         {FA_UMLAUT, 'I', 0xCF},         /* I with umlaut */
 349         {FA_UMLAUT, 'O', 0xD6},         /* O with umlaut */
 350         {FA_UMLAUT, 'U', 0xDC},         /* U with umlaut */
 351         {FA_UMLAUT, 'a', 0xE4},         /* a with umlaut */
 352         {FA_UMLAUT, 'e', 0xEB},         /* e with umlaut */
 353         {FA_UMLAUT, 'i', 0xEF},         /* i with umlaut */
 354         {FA_UMLAUT, 'o', 0xF6},         /* o with umlaut */
 355         {FA_UMLAUT, 'u', 0xFC},         /* u with umlaut */
 356         {FA_UMLAUT, 'y', 0xFF},         /* y with umlaut */
 357 
 358         {FA_CFLEX, 'A', 0xC2},          /* A with circumflex */
 359         {FA_CFLEX, 'E', 0xCA},          /* E with circumflex */
 360         {FA_CFLEX, 'I', 0xCE},          /* I with circumflex */
 361         {FA_CFLEX, 'O', 0xD4},          /* O with circumflex */
 362         {FA_CFLEX, 'U', 0xDB},          /* U with circumflex */
 363         {FA_CFLEX, 'a', 0xE2},          /* a with circumflex */
 364         {FA_CFLEX, 'e', 0xEA},          /* e with circumflex */
 365         {FA_CFLEX, 'i', 0xEE},          /* i with circumflex */
 366         {FA_CFLEX, 'o', 0xF4},          /* o with circumflex */
 367         {FA_CFLEX, 'u', 0xFB},          /* u with circumflex */
 368 
 369         {FA_TILDE, ' ', '~'},           /* tilde */
 370         {FA_TILDE, 'A', 0xC3},          /* A with tilde */
 371         {FA_TILDE, 'N', 0xD1},          /* N with tilde */
 372         {FA_TILDE, 'O', 0xD5},          /* O with tilde */
 373         {FA_TILDE, 'a', 0xE3},          /* a with tilde */
 374         {FA_TILDE, 'n', 0xF1},          /* n with tilde */
 375         {FA_TILDE, 'o', 0xF5},          /* o with tilde */
 376 
 377         {FA_CEDILLA, ' ', 0xB8},        /* cedilla */
 378         {FA_CEDILLA, 'C', 0xC7},        /* C with cedilla */
 379         {FA_CEDILLA, 'c', 0xE7},        /* c with cedilla */
 380 
 381         {FA_ACUTE, ' ', '\''},          /* apostrophe */
 382         {FA_ACUTE, 'A', 0xC1},          /* A with acute accent */
 383         {FA_ACUTE, 'E', 0xC9},          /* E with acute accent */
 384         {FA_ACUTE, 'I', 0xCD},          /* I with acute accent */
 385         {FA_ACUTE, 'O', 0xD3},          /* O with acute accent */
 386         {FA_ACUTE, 'U', 0xDA},          /* U with acute accent */
 387         {FA_ACUTE, 'a', 0xE1},          /* a with acute accent */
 388         {FA_ACUTE, 'e', 0xE9},          /* e with acute accent */
 389         {FA_ACUTE, 'i', 0xED},          /* i with acute accent */
 390         {FA_ACUTE, 'o', 0xF3},          /* o with acute accent */
 391         {FA_ACUTE, 'u', 0xFA},          /* u with acute accent */
 392         {FA_ACUTE, 'y', 0xFD},          /* y with acute accent */
 393 
 394         {FA_GRAVE, ' ', '`'},           /* grave accent */
 395         {FA_GRAVE, 'A', 0xC0},          /* A with grave accent */
 396         {FA_GRAVE, 'E', 0xC8},          /* E with grave accent */
 397         {FA_GRAVE, 'I', 0xCC},          /* I with grave accent */
 398         {FA_GRAVE, 'O', 0xD2},          /* O with grave accent */
 399         {FA_GRAVE, 'U', 0xD9},          /* U with grave accent */
 400         {FA_GRAVE, 'a', 0xE0},          /* a with grave accent */
 401         {FA_GRAVE, 'e', 0xE8},          /* e with grave accent */
 402         {FA_GRAVE, 'i', 0xEC},          /* i with grave accent */
 403         {FA_GRAVE, 'o', 0xF2},          /* o with grave accent */
 404         {FA_GRAVE, 'u', 0xF9},          /* u with grave accent */
 405 
 406         {FA_MACRON, ' ', 0xAF},         /* macron */
 407 
 408         {FA_BREVE, ' ', 0x306},         /* combining breve */
 409 
 410         {FA_DOT, ' ', 0x307},           /* combining dot above */
 411 
 412         {FA_SLASH, 0, 0},               /* slash, invalid entry */
 413 
 414         {FA_RING, ' ', 0x30A},          /* combining ring above */
 415 
 416         {FA_APOSTROPHE, ' ', '\''},     /* apostrophe */
 417 
 418         {FA_DACUTE, ' ', 0x30B},        /* combining double acute */
 419 
 420         {FA_OGONEK, ' ', 0x328},        /* combining ogonek */
 421 
 422         {FA_CARON, ' ', 0x2C7},         /* caron */
 423         {FA_CARON, 'C', 0x10C},         /* C with caron */
 424         {FA_CARON, 'S', 0x160},         /* S with caron */
 425         {FA_CARON, 'Z', 0x17D},         /* Z with caron */
 426         {FA_CARON, 'c', 0x10D},         /* c with caron */
 427         {FA_CARON, 's', 0x161},         /* s with caron */
 428         {FA_CARON, 'z', 0x17E},         /* z with caron */
 429 
 430         {0, 0, 0},                      /* end of table */
 431 };
 432 
 433 /*
 434  * Num Lock Table
 435  */
 436 
 437 /* Num Lock:  pad key entry & 0x1F => ASCII character */
 438 uchar_t kb_numlock_table[] = {
 439         '=',
 440         '/',
 441         '*',
 442         '-',
 443         ',',
 444 
 445         '7',
 446         '8',
 447         '9',
 448         '+',
 449 
 450         '4',
 451         '5',
 452         '6',
 453 
 454         '1',
 455         '2',
 456         '3',
 457 
 458         '0',
 459         '.',
 460         '\n',   /* Enter */
 461 };