kbdcontrol.c revision 46761
12088Ssos/*- 25536Ssos * Copyright (c) 1994-1995 S�ren Schmidt 32088Ssos * All rights reserved. 42088Ssos * 52088Ssos * Redistribution and use in source and binary forms, with or without 62088Ssos * modification, are permitted provided that the following conditions 72088Ssos * are met: 82088Ssos * 1. Redistributions of source code must retain the above copyright 95994Ssos * notice, this list of conditions and the following disclaimer, 105994Ssos * in this position and unchanged. 112088Ssos * 2. Redistributions in binary form must reproduce the above copyright 122088Ssos * notice, this list of conditions and the following disclaimer in the 132088Ssos * documentation and/or other materials provided with the distribution. 142088Ssos * 3. The name of the author may not be used to endorse or promote products 152088Ssos * derived from this software withough specific prior written permission 162088Ssos * 172088Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 182088Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 192088Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 202088Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 212088Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 222088Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232088Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242088Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252088Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 262088Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272088Ssos */ 282088Ssos 2929603Scharnier#ifndef lint 3029603Scharnierstatic const char rcsid[] = 3146761Syokota "$Id: kbdcontrol.c,v 1.24 1999/03/17 11:42:18 gpalmer Exp $"; 3229603Scharnier#endif /* not lint */ 3329603Scharnier 342088Ssos#include <ctype.h> 3529603Scharnier#include <err.h> 362088Ssos#include <stdio.h> 3729603Scharnier#include <stdlib.h> 383864Sswallace#include <string.h> 3929603Scharnier#include <unistd.h> 4042505Syokota#include <fcntl.h> 412088Ssos#include <machine/console.h> 422088Ssos#include "path.h" 432088Ssos#include "lex.h" 442088Ssos 452088Ssoschar ctrl_names[32][4] = { 468857Srgrimes "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 472088Ssos "bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ", 482088Ssos "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 4938139Syokota "can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "us " 502088Ssos }; 512088Ssos 5232316Syokotachar acc_names[15][5] = { 5332316Syokota "dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot", 5432316Syokota "duml", "dsla", "drin", "dced", "dapo", "ddac", "dogo", 5532316Syokota "dcar", 5632316Syokota }; 5732316Syokota 5832316Syokotachar acc_names_u[15][5] = { 5932316Syokota "DGRA", "DACU", "DCIR", "DTIL", "DMAC", "DBRE", "DDOT", 6032316Syokota "DUML", "DSLA", "DRIN", "DCED", "DAPO", "DDAC", "DOGO", 6132316Syokota "DCAR", 6232316Syokota }; 6332316Syokota 645994Ssoschar fkey_table[96][MAXFK] = { 655994Ssos/* 01-04 */ "\033[M", "\033[N", "\033[O", "\033[P", 665994Ssos/* 05-08 */ "\033[Q", "\033[R", "\033[S", "\033[T", 675994Ssos/* 09-12 */ "\033[U", "\033[V", "\033[W", "\033[X", 685994Ssos/* 13-16 */ "\033[Y", "\033[Z", "\033[a", "\033[b", 695994Ssos/* 17-20 */ "\033[c", "\033[d", "\033[e", "\033[f", 705994Ssos/* 21-24 */ "\033[g", "\033[h", "\033[i", "\033[j", 715994Ssos/* 25-28 */ "\033[k", "\033[l", "\033[m", "\033[n", 725994Ssos/* 29-32 */ "\033[o", "\033[p", "\033[q", "\033[r", 735994Ssos/* 33-36 */ "\033[s", "\033[t", "\033[u", "\033[v", 745994Ssos/* 37-40 */ "\033[w", "\033[x", "\033[y", "\033[z", 755994Ssos/* 41-44 */ "\033[@", "\033[[", "\033[\\","\033[]", 769202Srgrimes/* 45-48 */ "\033[^", "\033[_", "\033[`", "\033[{", 775994Ssos/* 49-52 */ "\033[H", "\033[A", "\033[I", "-" , 785994Ssos/* 53-56 */ "\033[D", "\033[E", "\033[C", "+" , 795994Ssos/* 57-60 */ "\033[F", "\033[B", "\033[G", "\033[L", 809202Srgrimes/* 61-64 */ "\177", "\033[J", "\033[~", "\033[}", 815994Ssos/* 65-68 */ "" , "" , "" , "" , 825994Ssos/* 69-72 */ "" , "" , "" , "" , 835994Ssos/* 73-76 */ "" , "" , "" , "" , 845994Ssos/* 77-80 */ "" , "" , "" , "" , 855994Ssos/* 81-84 */ "" , "" , "" , "" , 865994Ssos/* 85-88 */ "" , "" , "" , "" , 875994Ssos/* 89-92 */ "" , "" , "" , "" , 885994Ssos/* 93-96 */ "" , "" , "" , "" , 892088Ssos }; 902088Ssos 9146761Syokotaconst int delays[] = {250, 500, 750, 1000}; 9246761Syokotaconst int repeats[] = { 34, 38, 42, 46, 50, 55, 59, 63, 9346761Syokota 68, 76, 84, 92, 100, 110, 118, 126, 9446761Syokota 136, 152, 168, 184, 200, 220, 236, 252, 9546761Syokota 272, 304, 336, 368, 400, 440, 472, 504}; 9646761Syokotaconst int ndelays = (sizeof(delays) / sizeof(int)); 9746761Syokotaconst int nrepeats = (sizeof(repeats) / sizeof(int)); 982088Ssosint hex = 0; 996046Ssosint number; 1002088Ssoschar letter; 10132316Syokotaint token; 1022088Ssos 10329603Scharnierstatic void usage __P((void)); 1042088Ssos 1052088Ssoschar * 1062088Ssosnextarg(int ac, char **av, int *indp, int oc) 1072088Ssos{ 1082088Ssos if (*indp < ac) 1092088Ssos return(av[(*indp)++]); 11029603Scharnier warnx("option requires two arguments -- %c", oc); 1112088Ssos usage(); 1122088Ssos return(""); 1132088Ssos} 1142088Ssos 1152088Ssos 1162088Ssoschar * 1172088Ssosmkfullname(const char *s1, const char *s2, const char *s3) 1182088Ssos{ 1195536Ssos static char *buf = NULL; 1205536Ssos static int bufl = 0; 1215536Ssos int f; 1222088Ssos 1232088Ssos f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 1242088Ssos if (f > bufl) 1252088Ssos if (buf) 1262088Ssos buf = (char *)realloc(buf, f); 1272088Ssos else 1282088Ssos buf = (char *)malloc(f); 1292088Ssos if (!buf) { 1302088Ssos bufl = 0; 1312088Ssos return(NULL); 1322088Ssos } 1332088Ssos 1342088Ssos bufl = f; 1352088Ssos strcpy(buf, s1); 1362088Ssos strcat(buf, s2); 1372088Ssos strcat(buf, s3); 1382088Ssos return(buf); 1392088Ssos} 1402088Ssos 1412088Ssos 1422088Ssosint 1432088Ssosget_entry() 1442088Ssos{ 14532316Syokota switch ((token = yylex())) { 1462088Ssos case TNOP: 1472088Ssos return NOP | 0x100; 1482088Ssos case TLSH: 1492088Ssos return LSH | 0x100; 1502088Ssos case TRSH: 1512088Ssos return RSH | 0x100; 1522088Ssos case TCLK: 1532088Ssos return CLK | 0x100; 1542088Ssos case TNLK: 1552088Ssos return NLK | 0x100; 1562088Ssos case TSLK: 1572088Ssos return SLK | 0x100; 1582088Ssos case TBTAB: 1592088Ssos return BTAB | 0x100; 1602088Ssos case TLALT: 1612088Ssos return LALT | 0x100; 1622088Ssos case TLCTR: 1632088Ssos return LCTR | 0x100; 1642088Ssos case TNEXT: 1652088Ssos return NEXT | 0x100; 1662088Ssos case TRCTR: 1672088Ssos return RCTR | 0x100; 1682088Ssos case TRALT: 1692088Ssos return RALT | 0x100; 1702088Ssos case TALK: 1712088Ssos return ALK | 0x100; 1722088Ssos case TASH: 1732088Ssos return ASH | 0x100; 1742088Ssos case TMETA: 1752088Ssos return META | 0x100; 1762088Ssos case TRBT: 1772088Ssos return RBT | 0x100; 1782088Ssos case TDBG: 1792088Ssos return DBG | 0x100; 1805994Ssos case TSUSP: 1815994Ssos return SUSP | 0x100; 18238053Syokota case TSPSC: 18338053Syokota return SPSC | 0x100; 18432316Syokota case TACC: 18532316Syokota if (ACC(number) > L_ACC) 18632316Syokota return -1; 18732316Syokota return ACC(number) | 0x100; 1882088Ssos case TFUNC: 1892088Ssos if (F(number) > L_FN) 1902088Ssos return -1; 1912088Ssos return F(number) | 0x100; 1922088Ssos case TSCRN: 1932088Ssos if (S(number) > L_SCR) 1942088Ssos return -1; 1952088Ssos return S(number) | 0x100; 1962088Ssos case TLET: 1972088Ssos return (unsigned char)letter; 1982088Ssos case TNUM: 1992088Ssos if (number < 0 || number > 255) 2002088Ssos return -1; 2012088Ssos return number; 2022088Ssos default: 2032088Ssos return -1; 2042088Ssos } 2052088Ssos} 2062088Ssos 2072088Ssosint 20832316Syokotaget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap) 2092088Ssos{ 21032316Syokota int c; 2112088Ssos 2122088Ssos yyin = fd; 2132088Ssos 21432316Syokota if (token < 0) 21532316Syokota token = yylex(); 21632316Syokota switch (token) { 21732316Syokota case TNUM: 21832316Syokota c = get_key_definition_line(keymap); 21932316Syokota if (c < 0) 22032316Syokota errx(1, "invalid key definition"); 22132316Syokota if (c > keymap->n_keys) 22232316Syokota keymap->n_keys = c; 22332316Syokota break; 22432316Syokota case TACC: 22532316Syokota c = get_accent_definition_line(accentmap); 22632316Syokota if (c < 0) 22732316Syokota errx(1, "invalid accent key definition"); 22832316Syokota if (c > accentmap->n_accs) 22932316Syokota accentmap->n_accs = c; 23032316Syokota break; 23132316Syokota case 0: 23232316Syokota /* EOF */ 2332088Ssos return -1; 23432316Syokota default: 23532316Syokota errx(1, "illegal definition line"); 23632316Syokota } 23732316Syokota return c; 23832316Syokota} 23932316Syokota 24032316Syokotaint 24132316Syokotaget_key_definition_line(keymap_t *map) 24232316Syokota{ 24332316Syokota int i, def, scancode; 24432316Syokota 24532316Syokota /* check scancode number */ 2462088Ssos if (number < 0 || number >= NUM_KEYS) 2472088Ssos return -1; 2482088Ssos scancode = number; 2492088Ssos 2502088Ssos /* get key definitions */ 2512088Ssos map->key[scancode].spcl = 0; 2522088Ssos for (i=0; i<NUM_STATES; i++) { 2532088Ssos if ((def = get_entry()) == -1) 2542088Ssos return -1; 2552088Ssos if (def & 0x100) 2562088Ssos map->key[scancode].spcl |= (0x80 >> i); 2572088Ssos map->key[scancode].map[i] = def & 0xFF; 2582088Ssos } 2592088Ssos /* get lock state key def */ 26032316Syokota if ((token = yylex()) != TFLAG) 2612088Ssos return -1; 2622088Ssos map->key[scancode].flgs = number; 26332316Syokota token = yylex(); 26432316Syokota return (scancode + 1); 2652088Ssos} 2662088Ssos 26732316Syokotaint 26832316Syokotaget_accent_definition_line(accentmap_t *map) 26932316Syokota{ 27032316Syokota int accent; 27132316Syokota int c1, c2; 27232316Syokota int i; 2732088Ssos 27432316Syokota if (ACC(number) < F_ACC || ACC(number) > L_ACC) 27532316Syokota /* number out of range */ 27632316Syokota return -1; 27732316Syokota accent = number; 27832316Syokota if (map->acc[accent].accchar != 0) { 27932316Syokota /* this entry has already been defined before! */ 28032316Syokota errx(1, "duplicated accent key definition"); 28132316Syokota } 28232316Syokota 28332316Syokota switch ((token = yylex())) { 28432316Syokota case TLET: 28532316Syokota map->acc[accent].accchar = letter; 28632316Syokota break; 28732316Syokota case TNUM: 28832316Syokota map->acc[accent].accchar = number; 28932316Syokota break; 29032316Syokota default: 29132316Syokota return -1; 29232316Syokota } 29332316Syokota 29432316Syokota for (i = 0; (token = yylex()) == '(';) { 29532316Syokota switch ((token = yylex())) { 29632316Syokota case TLET: 29732316Syokota c1 = letter; 29832316Syokota break; 29932316Syokota case TNUM: 30032316Syokota c1 = number; 30132316Syokota break; 30232316Syokota default: 30332316Syokota return -1; 30432316Syokota } 30532316Syokota switch ((token = yylex())) { 30632316Syokota case TLET: 30732316Syokota c2 = letter; 30832316Syokota break; 30932316Syokota case TNUM: 31032316Syokota c2 = number; 31132316Syokota break; 31232316Syokota default: 31332316Syokota return -1; 31432316Syokota } 31532316Syokota if ((token = yylex()) != ')') 31632316Syokota return -1; 31732316Syokota if (i >= NUM_ACCENTCHARS) { 31832316Syokota warnx("too many accented characters, ignored"); 31932316Syokota continue; 32032316Syokota } 32132316Syokota map->acc[accent].map[i][0] = c1; 32232316Syokota map->acc[accent].map[i][1] = c2; 32332316Syokota ++i; 32432316Syokota } 32532316Syokota return (accent + 1); 32632316Syokota} 32732316Syokota 32829603Scharniervoid 3292088Ssosprint_entry(FILE *fp, int value) 3302088Ssos{ 3312088Ssos int val = value & 0xFF; 3322088Ssos 3332088Ssos switch (value) { 3342088Ssos case NOP | 0x100: 3358857Srgrimes fprintf(fp, " nop "); 3362088Ssos break; 3372088Ssos case LSH | 0x100: 3382088Ssos fprintf(fp, " lshift"); 3392088Ssos break; 3402088Ssos case RSH | 0x100: 3412088Ssos fprintf(fp, " rshift"); 3422088Ssos break; 3432088Ssos case CLK | 0x100: 3442088Ssos fprintf(fp, " clock "); 3452088Ssos break; 3462088Ssos case NLK | 0x100: 3472088Ssos fprintf(fp, " nlock "); 3482088Ssos break; 3492088Ssos case SLK | 0x100: 3502088Ssos fprintf(fp, " slock "); 3512088Ssos break; 3522088Ssos case BTAB | 0x100: 3532088Ssos fprintf(fp, " btab "); 3542088Ssos break; 3552088Ssos case LALT | 0x100: 3562088Ssos fprintf(fp, " lalt "); 3572088Ssos break; 3582088Ssos case LCTR | 0x100: 3592088Ssos fprintf(fp, " lctrl "); 3602088Ssos break; 3612088Ssos case NEXT | 0x100: 3622088Ssos fprintf(fp, " nscr "); 3632088Ssos break; 3642088Ssos case RCTR | 0x100: 3652088Ssos fprintf(fp, " rctrl "); 3662088Ssos break; 3672088Ssos case RALT | 0x100: 3682088Ssos fprintf(fp, " ralt "); 3692088Ssos break; 3702088Ssos case ALK | 0x100: 3712088Ssos fprintf(fp, " alock "); 3722088Ssos break; 3732088Ssos case ASH | 0x100: 3742088Ssos fprintf(fp, " ashift"); 3752088Ssos break; 3762088Ssos case META | 0x100: 3772088Ssos fprintf(fp, " meta "); 3782088Ssos break; 3792088Ssos case RBT | 0x100: 3802088Ssos fprintf(fp, " boot "); 3812088Ssos break; 3822088Ssos case DBG | 0x100: 3832088Ssos fprintf(fp, " debug "); 3842088Ssos break; 38532316Syokota case SUSP | 0x100: 38632316Syokota fprintf(fp, " susp "); 38732316Syokota break; 38838053Syokota case SPSC | 0x100: 38938053Syokota fprintf(fp, " saver "); 39038053Syokota break; 3912088Ssos default: 3922088Ssos if (value & 0x100) { 3938857Srgrimes if (val >= F_FN && val <= L_FN) 3942088Ssos fprintf(fp, " fkey%02d", val - F_FN + 1); 3958857Srgrimes else if (val >= F_SCR && val <= L_SCR) 3962088Ssos fprintf(fp, " scr%02d ", val - F_SCR + 1); 39732316Syokota else if (val >= F_ACC && val <= L_ACC) 39832316Syokota fprintf(fp, " %-6s", acc_names[val - F_ACC]); 3992088Ssos else if (hex) 4008857Srgrimes fprintf(fp, " 0x%02x ", val); 4012088Ssos else 40232316Syokota fprintf(fp, " %3d ", val); 4032088Ssos } 4042088Ssos else { 4052088Ssos if (val < ' ') 4068857Srgrimes fprintf(fp, " %s ", ctrl_names[val]); 4072088Ssos else if (val == 127) 4088857Srgrimes fprintf(fp, " del "); 4099202Srgrimes else if (isascii(val) && isprint(val)) 4108857Srgrimes fprintf(fp, " '%c' ", val); 4112088Ssos else if (hex) 4128857Srgrimes fprintf(fp, " 0x%02x ", val); 4132088Ssos else 4148857Srgrimes fprintf(fp, " %3d ", val); 4152088Ssos } 4162088Ssos } 4172088Ssos} 4182088Ssos 4192088Ssos 4202088Ssosvoid 42142505Syokotaprint_key_definition_line(FILE *fp, int scancode, struct keyent_t *key) 4222088Ssos{ 42329603Scharnier int i; 4242088Ssos 4252088Ssos /* print scancode number */ 4262088Ssos if (hex) 4272088Ssos fprintf(fp, " 0x%02x ", scancode); 4282088Ssos else 4292088Ssos fprintf(fp, " %03d ", scancode); 4302088Ssos 4312088Ssos /* print key definitions */ 4322088Ssos for (i=0; i<NUM_STATES; i++) { 4332088Ssos if (key->spcl & (0x80 >> i)) 4342088Ssos print_entry(fp, key->map[i] | 0x100); 4352088Ssos else 4368857Srgrimes print_entry(fp, key->map[i]); 4372088Ssos } 4382088Ssos 4392088Ssos /* print lock state key def */ 4402088Ssos switch (key->flgs) { 4412088Ssos case 0: 4422088Ssos fprintf(fp, " O\n"); 4432088Ssos break; 4442088Ssos case 1: 4452088Ssos fprintf(fp, " C\n"); 4462088Ssos break; 4472088Ssos case 2: 4482088Ssos fprintf(fp, " N\n"); 4492088Ssos break; 4506046Ssos case 3: 4516046Ssos fprintf(fp, " B\n"); 4526046Ssos break; 4538857Srgrimes } 4542088Ssos} 4552088Ssos 45632316Syokotavoid 45732316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key) 45832316Syokota{ 45932316Syokota int c; 46032316Syokota int i; 4612088Ssos 46232316Syokota if (key->accchar == 0) 46332316Syokota return; 46432316Syokota 46532316Syokota /* print accent number */ 46632316Syokota fprintf(fp, " %-6s", acc_names[accent]); 46732316Syokota if (isascii(key->accchar) && isprint(key->accchar)) 46832316Syokota fprintf(fp, "'%c' ", key->accchar); 46932316Syokota else if (hex) 47032316Syokota fprintf(fp, "0x%02x ", key->accchar); 47132316Syokota else 47232316Syokota fprintf(fp, "%03d ", key->accchar); 47332316Syokota 47432316Syokota for (i = 0; i < NUM_ACCENTCHARS; ++i) { 47532316Syokota c = key->map[i][0]; 47632316Syokota if (c == 0) 47732316Syokota break; 47832316Syokota if ((i > 0) && ((i % 4) == 0)) 47932316Syokota fprintf(fp, "\n "); 48032316Syokota if (isascii(c) && isprint(c)) 48132316Syokota fprintf(fp, "( '%c' ", c); 48232316Syokota else if (hex) 48332316Syokota fprintf(fp, "(0x%02x ", c); 48432316Syokota else 48532316Syokota fprintf(fp, "( %03d ", c); 48632316Syokota c = key->map[i][1]; 48732316Syokota if (isascii(c) && isprint(c)) 48832316Syokota fprintf(fp, "'%c' ) ", c); 48932316Syokota else if (hex) 49032316Syokota fprintf(fp, "0x%02x) ", c); 49132316Syokota else 49232316Syokota fprintf(fp, "%03d ) ", c); 49332316Syokota } 49432316Syokota fprintf(fp, "\n"); 49532316Syokota} 49632316Syokota 4972088Ssosvoid 49832316Syokotadump_entry(int value) 49932316Syokota{ 50032316Syokota if (value & 0x100) { 50132316Syokota value &= 0x00ff; 50232316Syokota switch (value) { 50332316Syokota case NOP: 50432316Syokota printf(" NOP, "); 50532316Syokota break; 50632316Syokota case LSH: 50732316Syokota printf(" LSH, "); 50832316Syokota break; 50932316Syokota case RSH: 51032316Syokota printf(" RSH, "); 51132316Syokota break; 51232316Syokota case CLK: 51332316Syokota printf(" CLK, "); 51432316Syokota break; 51532316Syokota case NLK: 51632316Syokota printf(" NLK, "); 51732316Syokota break; 51832316Syokota case SLK: 51932316Syokota printf(" SLK, "); 52032316Syokota break; 52132316Syokota case BTAB: 52232316Syokota printf(" BTAB, "); 52332316Syokota break; 52432316Syokota case LALT: 52532316Syokota printf(" LALT, "); 52632316Syokota break; 52732316Syokota case LCTR: 52832316Syokota printf(" LCTR, "); 52932316Syokota break; 53032316Syokota case NEXT: 53132316Syokota printf(" NEXT, "); 53232316Syokota break; 53332316Syokota case RCTR: 53432316Syokota printf(" RCTR, "); 53532316Syokota break; 53632316Syokota case RALT: 53732316Syokota printf(" RALT, "); 53832316Syokota break; 53932316Syokota case ALK: 54032316Syokota printf(" ALK, "); 54132316Syokota break; 54232316Syokota case ASH: 54332316Syokota printf(" ASH, "); 54432316Syokota break; 54532316Syokota case META: 54632316Syokota printf(" META, "); 54732316Syokota break; 54832316Syokota case RBT: 54932316Syokota printf(" RBT, "); 55032316Syokota break; 55132316Syokota case DBG: 55232316Syokota printf(" DBG, "); 55332316Syokota break; 55432316Syokota case SUSP: 55532316Syokota printf(" SUSP, "); 55632316Syokota break; 55738053Syokota case SPSC: 55838053Syokota printf(" SPSC, "); 55938053Syokota break; 56032316Syokota default: 56132316Syokota if (value >= F_FN && value <= L_FN) 56232316Syokota printf(" F(%2d),", value - F_FN + 1); 56332316Syokota else if (value >= F_SCR && value <= L_SCR) 56432486Syokota printf(" S(%2d),", value - F_SCR + 1); 56532316Syokota else if (value >= F_ACC && value <= L_ACC) 56632316Syokota printf(" %-4s, ", acc_names_u[value - F_ACC]); 56732316Syokota else 56832316Syokota printf(" 0x%02X, ", value); 56932316Syokota break; 57032316Syokota } 57132316Syokota } else if (value == '\'') { 57232316Syokota printf(" '\\'', "); 57332316Syokota } else if (value == '\\') { 57432316Syokota printf(" '\\\\', "); 57532316Syokota } else if (isascii(value) && isprint(value)) { 57632316Syokota printf(" '%c', ", value); 57732316Syokota } else { 57832316Syokota printf(" 0x%02X, ", value); 57932316Syokota } 58032316Syokota} 58132316Syokota 58232316Syokotavoid 58332316Syokotadump_key_definition(char *name, keymap_t *keymap) 58432316Syokota{ 58532316Syokota int i, j; 58632316Syokota 58732486Syokota printf("static keymap_t keymap_%s = { 0x%02x, {\n", 58832316Syokota name, (unsigned)keymap->n_keys); 58932316Syokota printf( 59032486Syokota"/* alt\n" 59132486Syokota" * scan cntrl alt alt cntrl\n" 59232486Syokota" * code base shift cntrl shift alt shift cntrl shift spcl flgs\n" 59332316Syokota" * ---------------------------------------------------------------------------\n" 59432316Syokota" */\n"); 59532316Syokota for (i = 0; i < keymap->n_keys; i++) { 59632486Syokota printf("/*%02x*/{{", i); 59732316Syokota for (j = 0; j < NUM_STATES; j++) { 59832316Syokota if (keymap->key[i].spcl & (0x80 >> j)) 59932316Syokota dump_entry(keymap->key[i].map[j] | 0x100); 60032316Syokota else 60132316Syokota dump_entry(keymap->key[i].map[j]); 60232316Syokota } 60332486Syokota printf("}, 0x%02X,0x%02X },\n", 60432316Syokota (unsigned)keymap->key[i].spcl, 60532316Syokota (unsigned)keymap->key[i].flgs); 60632316Syokota } 60732486Syokota printf("} };\n\n"); 60832316Syokota} 60932316Syokota 61032316Syokotavoid 61132316Syokotadump_accent_definition(char *name, accentmap_t *accentmap) 61232316Syokota{ 61332316Syokota int i, j; 61432316Syokota int c; 61532316Syokota 61632486Syokota printf("static accentmap_t accentmap_%s = { %d", 61732316Syokota name, accentmap->n_accs); 61832486Syokota if (accentmap->n_accs <= 0) { 61932486Syokota printf(" };\n\n"); 62032486Syokota return; 62132486Syokota } 62232486Syokota printf(", {\n"); 62332316Syokota for (i = 0; i < NUM_DEADKEYS; i++) { 62432316Syokota printf(" /* %s=%d */\n {", acc_names[i], i); 62532316Syokota c = accentmap->acc[i].accchar; 62632316Syokota if (c == '\'') 62732316Syokota printf(" '\\'', {"); 62832316Syokota else if (c == '\\') 62932316Syokota printf(" '\\\\', {"); 63032316Syokota else if (isascii(c) && isprint(c)) 63132316Syokota printf(" '%c', {", c); 63232316Syokota else if (c == 0) { 63332316Syokota printf(" 0x00 }, \n"); 63432316Syokota continue; 63532316Syokota } else 63632316Syokota printf(" 0x%02x, {", c); 63732316Syokota for (j = 0; j < NUM_ACCENTCHARS; j++) { 63832316Syokota c = accentmap->acc[i].map[j][0]; 63932316Syokota if (c == 0) 64032316Syokota break; 64132316Syokota if ((j > 0) && ((j % 4) == 0)) 64232316Syokota printf("\n\t "); 64332316Syokota if (isascii(c) && isprint(c)) 64432316Syokota printf(" { '%c',", c); 64532316Syokota else 64632316Syokota printf(" { 0x%02x,", c); 64732316Syokota printf("0x%02x },", accentmap->acc[i].map[j][1]); 64832316Syokota } 64932316Syokota printf(" }, },\n"); 65032316Syokota } 65132486Syokota printf("} };\n\n"); 65232316Syokota} 65332316Syokota 65432316Syokotavoid 65519569Sjoergload_keymap(char *opt, int dumponly) 6562088Ssos{ 65732316Syokota keymap_t keymap; 65832316Syokota accentmap_t accentmap; 6592088Ssos FILE *fd; 66032316Syokota int i; 66119569Sjoerg char *name, *cp; 66235750Sdes char *prefix[] = {"", "", KEYMAP_PATH, KEYMAP_PATH, NULL}; 66335750Sdes char *postfix[] = {"", ".kbd", "", ".kbd"}; 6642088Ssos 6652088Ssos for (i=0; prefix[i]; i++) { 6662088Ssos name = mkfullname(prefix[i], opt, postfix[i]); 66729603Scharnier if ((fd = fopen(name, "r"))) 6682088Ssos break; 6692088Ssos } 6702088Ssos if (fd == NULL) { 67129603Scharnier warn("keymap file not found"); 6722088Ssos return; 6732088Ssos } 67432316Syokota memset(&keymap, 0, sizeof(keymap)); 67532316Syokota memset(&accentmap, 0, sizeof(accentmap)); 67632316Syokota token = -1; 6772088Ssos while (1) { 67832316Syokota if (get_definition_line(fd, &keymap, &accentmap) < 0) 6792088Ssos break; 6802088Ssos } 68119569Sjoerg if (dumponly) { 68219569Sjoerg /* fix up the filename to make it a valid C identifier */ 68319569Sjoerg for (cp = opt; *cp; cp++) 68419569Sjoerg if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_'; 68532316Syokota printf("/*\n" 68632316Syokota " * Automatically generated from %s.\n" 68732316Syokota " * DO NOT EDIT!\n" 68832316Syokota " */\n", name); 68932316Syokota dump_key_definition(opt, &keymap); 69032316Syokota dump_accent_definition(opt, &accentmap); 69119569Sjoerg return; 69219569Sjoerg } 69332316Syokota if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) { 69429603Scharnier warn("setting keymap"); 6952088Ssos fclose(fd); 6962088Ssos return; 6972088Ssos } 69832316Syokota if ((accentmap.n_accs > 0) 69932316Syokota && (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) { 70032316Syokota warn("setting accentmap"); 70132316Syokota fclose(fd); 70232316Syokota return; 70332316Syokota } 7042088Ssos} 7052088Ssos 7062088Ssosvoid 7072088Ssosprint_keymap() 7082088Ssos{ 70932316Syokota keymap_t keymap; 71032316Syokota accentmap_t accentmap; 7112088Ssos int i; 7122088Ssos 71332316Syokota if (ioctl(0, GIO_KEYMAP, &keymap) < 0) 71429603Scharnier err(1, "getting keymap"); 71532316Syokota if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0) 71632316Syokota memset(&accentmap, 0, sizeof(accentmap)); 7172088Ssos printf( 7182088Ssos"# alt\n" 7192088Ssos"# scan cntrl alt alt cntrl lock\n" 7202088Ssos"# code base shift cntrl shift alt shift cntrl shift state\n" 7212088Ssos"# ------------------------------------------------------------------\n" 7222088Ssos ); 72332316Syokota for (i=0; i<keymap.n_keys; i++) 72432316Syokota print_key_definition_line(stdout, i, &keymap.key[i]); 72532316Syokota 72632316Syokota printf("\n"); 72732316Syokota for (i = 0; i < NUM_DEADKEYS; i++) 72832316Syokota print_accent_definition_line(stdout, i, &accentmap.acc[i]); 72932316Syokota 7302088Ssos} 7312088Ssos 7322088Ssos 7332088Ssosvoid 7342088Ssosload_default_functionkeys() 7352088Ssos{ 7362088Ssos fkeyarg_t fkey; 7372088Ssos int i; 7382088Ssos 7392088Ssos for (i=0; i<NUM_FKEYS; i++) { 7402088Ssos fkey.keynum = i; 7412088Ssos strcpy(fkey.keydef, fkey_table[i]); 7422088Ssos fkey.flen = strlen(fkey_table[i]); 7432088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 74429603Scharnier warn("setting function key"); 7452088Ssos } 7462088Ssos} 7472088Ssos 7482088Ssosvoid 7492088Ssosset_functionkey(char *keynumstr, char *string) 7502088Ssos{ 7512088Ssos fkeyarg_t fkey; 7522088Ssos 7532088Ssos if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) { 7542088Ssos load_default_functionkeys(); 7552088Ssos return; 7562088Ssos } 7572088Ssos fkey.keynum = atoi(keynumstr); 7582088Ssos if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) { 75929603Scharnier warnx("function key number must be between 1 and %d", 7602088Ssos NUM_FKEYS); 7612088Ssos return; 7622088Ssos } 7632088Ssos if ((fkey.flen = strlen(string)) > MAXFK) { 76429603Scharnier warnx("function key string too long (%d > %d)", 7652088Ssos fkey.flen, MAXFK); 7662088Ssos return; 7672088Ssos } 7682088Ssos strcpy(fkey.keydef, string); 7692088Ssos fkey.keynum -= 1; 7702088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 77129603Scharnier warn("setting function key"); 7722088Ssos} 7732088Ssos 7742088Ssos 7752088Ssosvoid 7762088Ssosset_bell_values(char *opt) 7772088Ssos{ 7785536Ssos int bell, duration, pitch; 7792088Ssos 78038044Syokota bell = 0; 78138044Syokota if (!strncmp(opt, "quiet.", 6)) { 78238044Syokota bell = 2; 78338044Syokota opt += 6; 78438044Syokota } 7858857Srgrimes if (!strcmp(opt, "visual")) 78638044Syokota bell |= 1; 7875536Ssos else if (!strcmp(opt, "normal")) 78838044Syokota duration = 5, pitch = 800; 7892088Ssos else { 7902088Ssos char *v1; 7918857Srgrimes 7925536Ssos bell = 0; 7932088Ssos duration = strtol(opt, &v1, 0); 7942088Ssos if ((duration < 0) || (*v1 != '.')) 7952088Ssos goto badopt; 7962088Ssos opt = ++v1; 7972088Ssos pitch = strtol(opt, &v1, 0); 7982088Ssos if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) { 7992088Ssosbadopt: 80029603Scharnier warnx("argument to -b must be DURATION.PITCH"); 8012088Ssos return; 8022088Ssos } 80338044Syokota if (pitch != 0) 80438044Syokota pitch = 1193182 / pitch; /* in Hz */ 80538044Syokota duration /= 10; /* in 10 m sec */ 8062088Ssos } 8072088Ssos 8085536Ssos ioctl(0, CONS_BELLTYPE, &bell); 80938044Syokota if ((bell & ~2) == 0) 8105536Ssos fprintf(stderr, "[=%d;%dB", pitch, duration); 8112088Ssos} 8122088Ssos 8132088Ssos 8142088Ssosvoid 8152088Ssosset_keyrates(char *opt) 8162088Ssos{ 81744628Syokota int arg[2]; 81839047Syokota int repeat; 81939047Syokota int delay; 82046761Syokota int r, d; 8212088Ssos 82246761Syokota if (!strcmp(opt, "slow")) { 82344628Syokota delay = 1000, repeat = 500; 82446761Syokota d = 3, r = 31; 82546761Syokota } else if (!strcmp(opt, "normal")) { 82644628Syokota delay = 500, repeat = 125; 82746761Syokota d = 1, r = 15; 82846761Syokota } else if (!strcmp(opt, "fast")) { 82939047Syokota delay = repeat = 0; 83046761Syokota d = r = 0; 83146761Syokota } else { 8322088Ssos int n; 8332088Ssos char *v1; 8342088Ssos 8352088Ssos delay = strtol(opt, &v1, 0); 8362088Ssos if ((delay < 0) || (*v1 != '.')) 8372088Ssos goto badopt; 8382088Ssos opt = ++v1; 8392088Ssos repeat = strtol(opt, &v1, 0); 8402088Ssos if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) { 8412088Ssosbadopt: 84229603Scharnier warnx("argument to -r must be delay.repeat"); 8432088Ssos return; 8442088Ssos } 84546761Syokota for (n = 0; n < ndelays - 1; n++) 84646761Syokota if (delay <= delays[n]) 84746761Syokota break; 84846761Syokota d = n; 84946761Syokota for (n = 0; n < nrepeats - 1; n++) 85046761Syokota if (repeat <= repeats[n]) 85146761Syokota break; 85246761Syokota r = n; 8532088Ssos } 8542088Ssos 85544628Syokota arg[0] = delay; 85644628Syokota arg[1] = repeat; 85746761Syokota if (ioctl(0, KDSETREPEAT, arg)) { 85846761Syokota if (ioctl(0, KDSETRAD, (d << 5) | r)) 85946761Syokota warn("setting keyboard rate"); 86046761Syokota } 8612088Ssos} 8622088Ssos 8632088Ssos 8646046Ssosvoid 8656046Ssosset_history(char *opt) 8666046Ssos{ 8676046Ssos int size; 8686046Ssos 8696046Ssos size = atoi(opt); 8706046Ssos if ((*opt == '\0') || size < 0) { 87129603Scharnier warnx("argument must be a positive number"); 8726046Ssos return; 8736046Ssos } 8746046Ssos if (ioctl(0, CONS_HISTORY, &size) == -1) 87529603Scharnier warn("setting history buffer size"); 8766046Ssos} 8776046Ssos 87842505Syokotastatic char 87942505Syokota*get_kbd_type_name(int type) 88042505Syokota{ 88142505Syokota static struct { 88242505Syokota int type; 88342505Syokota char *name; 88442505Syokota } name_table[] = { 88542505Syokota { KB_84, "AT 84" }, 88642505Syokota { KB_101, "AT 101/102" }, 88742505Syokota { KB_OTHER, "generic" }, 88842505Syokota }; 88942505Syokota int i; 8906046Ssos 89142505Syokota for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) { 89242505Syokota if (type == name_table[i].type) 89342505Syokota return name_table[i].name; 89442505Syokota } 89542505Syokota return "unknown"; 89642505Syokota} 89742505Syokota 89842505Syokotavoid 89942505Syokotashow_kbd_info(void) 90042505Syokota{ 90142505Syokota keyboard_info_t info; 90242505Syokota 90342505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 90442505Syokota warn("unable to obtain keyboard information"); 90542505Syokota return; 90642505Syokota } 90742505Syokota printf("kbd%d:\n", info.kb_index); 90842505Syokota printf(" %.*s%d, type:%s (%d)\n", 90942505Syokota sizeof(info.kb_name), info.kb_name, info.kb_unit, 91042505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 91142505Syokota} 91242505Syokota 91342505Syokota 91442505Syokotavoid 91542505Syokotaset_keyboard(char *device) 91642505Syokota{ 91742505Syokota keyboard_info_t info; 91842505Syokota int fd; 91942505Syokota 92042505Syokota fd = open(device, O_RDONLY); 92142505Syokota if (fd < 0) { 92242505Syokota warn("cannot open %s", device); 92342505Syokota return; 92442505Syokota } 92542505Syokota if (ioctl(fd, KDGKBINFO, &info) == -1) { 92642505Syokota warn("unable to obtain keyboard information"); 92742505Syokota close(fd); 92842505Syokota return; 92942505Syokota } 93042505Syokota /* 93142505Syokota * The keyboard device driver won't release the keyboard by 93242505Syokota * the following ioctl, but it automatically will, when the device 93342505Syokota * is closed. So, we don't check error here. 93442505Syokota */ 93542505Syokota ioctl(fd, CONS_RELKBD, 0); 93642505Syokota close(fd); 93742505Syokota#if 1 93842505Syokota printf("kbd%d\n", info.kb_index); 93942505Syokota printf(" %.*s%d, type:%s (%d)\n", 94042505Syokota sizeof(info.kb_name), info.kb_name, info.kb_unit, 94142505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 94242505Syokota#endif 94342505Syokota 94442505Syokota if (ioctl(0, CONS_SETKBD, info.kb_index) == -1) 94542505Syokota warn("unable to set keyboard"); 94642505Syokota} 94742505Syokota 94842505Syokota 94942505Syokotavoid 95042505Syokotarelease_keyboard(void) 95142505Syokota{ 95242505Syokota keyboard_info_t info; 95342505Syokota 95442505Syokota /* 95542505Syokota * If stdin is not associated with a keyboard, the following ioctl 95642505Syokota * will fail. 95742505Syokota */ 95842505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 95942505Syokota warn("unable to obtain keyboard information"); 96042505Syokota return; 96142505Syokota } 96242505Syokota#if 1 96342505Syokota printf("kbd%d\n", info.kb_index); 96442505Syokota printf(" %.*s%d, type:%s (%d)\n", 96542505Syokota sizeof(info.kb_name), info.kb_name, info.kb_unit, 96642505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 96742505Syokota#endif 96842505Syokota if (ioctl(0, CONS_RELKBD, 0) == -1) 96942505Syokota warn("unable to release the keyboard"); 97042505Syokota} 97142505Syokota 97242505Syokota 97329603Scharnierstatic void 9742088Ssosusage() 9752088Ssos{ 97629603Scharnier fprintf(stderr, "%s\n%s\n%s\n", 97742505Syokota"usage: kbdcontrol [-dFKix] [-b duration.pitch | [quiet.]belltype]", 97829603Scharnier" [-r delay.repeat | speed] [-l mapfile] [-f # string]", 97942505Syokota" [-h size] [-k device] [-L mapfile]"); 98029603Scharnier exit(1); 9812088Ssos} 9822088Ssos 9832088Ssos 9842088Ssosvoid 9852088Ssosmain(int argc, char **argv) 9862088Ssos{ 9872088Ssos int opt; 9882088Ssos 98942505Syokota while((opt = getopt(argc, argv, "b:df:h:iKk:Fl:L:r:x")) != -1) 9902088Ssos switch(opt) { 9912088Ssos case 'b': 9922088Ssos set_bell_values(optarg); 9932088Ssos break; 9942088Ssos case 'd': 9952088Ssos print_keymap(); 9962088Ssos break; 9972088Ssos case 'l': 99819569Sjoerg load_keymap(optarg, 0); 9992088Ssos break; 100019569Sjoerg case 'L': 100119569Sjoerg load_keymap(optarg, 1); 100219569Sjoerg break; 10032088Ssos case 'f': 10048857Srgrimes set_functionkey(optarg, 10052088Ssos nextarg(argc, argv, &optind, 'f')); 10062088Ssos break; 10072088Ssos case 'F': 10082088Ssos load_default_functionkeys(); 10092088Ssos break; 10106046Ssos case 'h': 10116046Ssos set_history(optarg); 10126046Ssos break; 101342505Syokota case 'i': 101442505Syokota show_kbd_info(); 101542505Syokota break; 101642505Syokota case 'K': 101742505Syokota release_keyboard(); 101842505Syokota break; 101942505Syokota case 'k': 102042505Syokota set_keyboard(optarg); 102142505Syokota break; 10222088Ssos case 'r': 10232088Ssos set_keyrates(optarg); 10242088Ssos break; 10252088Ssos case 'x': 10262088Ssos hex = 1; 10272088Ssos break; 10282088Ssos default: 10292088Ssos usage(); 10302088Ssos } 103129603Scharnier if ((optind != argc) || (argc == 1)) 10322088Ssos usage(); 10332088Ssos exit(0); 10342088Ssos} 10352088Ssos 10362088Ssos 1037