kbdcontrol.c revision 32486
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[] = 3132486Syokota "$Id: kbdcontrol.c,v 1.12 1998/01/07 08:43:27 yokota 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> 402088Ssos#include <machine/console.h> 412088Ssos#include "path.h" 422088Ssos#include "lex.h" 432088Ssos 442088Ssoschar ctrl_names[32][4] = { 458857Srgrimes "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 462088Ssos "bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ", 472088Ssos "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 482088Ssos "can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "ns " 492088Ssos }; 502088Ssos 5132316Syokotachar acc_names[15][5] = { 5232316Syokota "dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot", 5332316Syokota "duml", "dsla", "drin", "dced", "dapo", "ddac", "dogo", 5432316Syokota "dcar", 5532316Syokota }; 5632316Syokota 5732316Syokotachar acc_names_u[15][5] = { 5832316Syokota "DGRA", "DACU", "DCIR", "DTIL", "DMAC", "DBRE", "DDOT", 5932316Syokota "DUML", "DSLA", "DRIN", "DCED", "DAPO", "DDAC", "DOGO", 6032316Syokota "DCAR", 6132316Syokota }; 6232316Syokota 635994Ssoschar fkey_table[96][MAXFK] = { 645994Ssos/* 01-04 */ "\033[M", "\033[N", "\033[O", "\033[P", 655994Ssos/* 05-08 */ "\033[Q", "\033[R", "\033[S", "\033[T", 665994Ssos/* 09-12 */ "\033[U", "\033[V", "\033[W", "\033[X", 675994Ssos/* 13-16 */ "\033[Y", "\033[Z", "\033[a", "\033[b", 685994Ssos/* 17-20 */ "\033[c", "\033[d", "\033[e", "\033[f", 695994Ssos/* 21-24 */ "\033[g", "\033[h", "\033[i", "\033[j", 705994Ssos/* 25-28 */ "\033[k", "\033[l", "\033[m", "\033[n", 715994Ssos/* 29-32 */ "\033[o", "\033[p", "\033[q", "\033[r", 725994Ssos/* 33-36 */ "\033[s", "\033[t", "\033[u", "\033[v", 735994Ssos/* 37-40 */ "\033[w", "\033[x", "\033[y", "\033[z", 745994Ssos/* 41-44 */ "\033[@", "\033[[", "\033[\\","\033[]", 759202Srgrimes/* 45-48 */ "\033[^", "\033[_", "\033[`", "\033[{", 765994Ssos/* 49-52 */ "\033[H", "\033[A", "\033[I", "-" , 775994Ssos/* 53-56 */ "\033[D", "\033[E", "\033[C", "+" , 785994Ssos/* 57-60 */ "\033[F", "\033[B", "\033[G", "\033[L", 799202Srgrimes/* 61-64 */ "\177", "\033[J", "\033[~", "\033[}", 805994Ssos/* 65-68 */ "" , "" , "" , "" , 815994Ssos/* 69-72 */ "" , "" , "" , "" , 825994Ssos/* 73-76 */ "" , "" , "" , "" , 835994Ssos/* 77-80 */ "" , "" , "" , "" , 845994Ssos/* 81-84 */ "" , "" , "" , "" , 855994Ssos/* 85-88 */ "" , "" , "" , "" , 865994Ssos/* 89-92 */ "" , "" , "" , "" , 875994Ssos/* 93-96 */ "" , "" , "" , "" , 882088Ssos }; 892088Ssos 902088Ssosconst int delays[] = {250, 500, 750, 1000}; 912088Ssosconst int repeats[] = { 34, 38, 42, 46, 50, 55, 59, 63, 922088Ssos 68, 76, 84, 92, 100, 110, 118, 126, 932088Ssos 136, 152, 168, 184, 200, 220, 236, 252, 942088Ssos 272, 304, 336, 368, 400, 440, 472, 504}; 952088Ssosconst int ndelays = (sizeof(delays) / sizeof(int)); 962088Ssosconst int nrepeats = (sizeof(repeats) / sizeof(int)); 972088Ssosint hex = 0; 986046Ssosint number; 992088Ssoschar letter; 10032316Syokotaint token; 1012088Ssos 10229603Scharnierstatic void usage __P((void)); 1032088Ssos 1042088Ssoschar * 1052088Ssosnextarg(int ac, char **av, int *indp, int oc) 1062088Ssos{ 1072088Ssos if (*indp < ac) 1082088Ssos return(av[(*indp)++]); 10929603Scharnier warnx("option requires two arguments -- %c", oc); 1102088Ssos usage(); 1112088Ssos return(""); 1122088Ssos} 1132088Ssos 1142088Ssos 1152088Ssoschar * 1162088Ssosmkfullname(const char *s1, const char *s2, const char *s3) 1172088Ssos{ 1185536Ssos static char *buf = NULL; 1195536Ssos static int bufl = 0; 1205536Ssos int f; 1212088Ssos 1222088Ssos f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 1232088Ssos if (f > bufl) 1242088Ssos if (buf) 1252088Ssos buf = (char *)realloc(buf, f); 1262088Ssos else 1272088Ssos buf = (char *)malloc(f); 1282088Ssos if (!buf) { 1292088Ssos bufl = 0; 1302088Ssos return(NULL); 1312088Ssos } 1322088Ssos 1332088Ssos bufl = f; 1342088Ssos strcpy(buf, s1); 1352088Ssos strcat(buf, s2); 1362088Ssos strcat(buf, s3); 1372088Ssos return(buf); 1382088Ssos} 1392088Ssos 1402088Ssos 1412088Ssosint 1422088Ssosget_entry() 1432088Ssos{ 14432316Syokota switch ((token = yylex())) { 1452088Ssos case TNOP: 1462088Ssos return NOP | 0x100; 1472088Ssos case TLSH: 1482088Ssos return LSH | 0x100; 1492088Ssos case TRSH: 1502088Ssos return RSH | 0x100; 1512088Ssos case TCLK: 1522088Ssos return CLK | 0x100; 1532088Ssos case TNLK: 1542088Ssos return NLK | 0x100; 1552088Ssos case TSLK: 1562088Ssos return SLK | 0x100; 1572088Ssos case TBTAB: 1582088Ssos return BTAB | 0x100; 1592088Ssos case TLALT: 1602088Ssos return LALT | 0x100; 1612088Ssos case TLCTR: 1622088Ssos return LCTR | 0x100; 1632088Ssos case TNEXT: 1642088Ssos return NEXT | 0x100; 1652088Ssos case TRCTR: 1662088Ssos return RCTR | 0x100; 1672088Ssos case TRALT: 1682088Ssos return RALT | 0x100; 1692088Ssos case TALK: 1702088Ssos return ALK | 0x100; 1712088Ssos case TASH: 1722088Ssos return ASH | 0x100; 1732088Ssos case TMETA: 1742088Ssos return META | 0x100; 1752088Ssos case TRBT: 1762088Ssos return RBT | 0x100; 1772088Ssos case TDBG: 1782088Ssos return DBG | 0x100; 1795994Ssos case TSUSP: 1805994Ssos return SUSP | 0x100; 18132316Syokota case TACC: 18232316Syokota if (ACC(number) > L_ACC) 18332316Syokota return -1; 18432316Syokota return ACC(number) | 0x100; 1852088Ssos case TFUNC: 1862088Ssos if (F(number) > L_FN) 1872088Ssos return -1; 1882088Ssos return F(number) | 0x100; 1892088Ssos case TSCRN: 1902088Ssos if (S(number) > L_SCR) 1912088Ssos return -1; 1922088Ssos return S(number) | 0x100; 1932088Ssos case TLET: 1942088Ssos return (unsigned char)letter; 1952088Ssos case TNUM: 1962088Ssos if (number < 0 || number > 255) 1972088Ssos return -1; 1982088Ssos return number; 1992088Ssos default: 2002088Ssos return -1; 2012088Ssos } 2022088Ssos} 2032088Ssos 2042088Ssosint 20532316Syokotaget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap) 2062088Ssos{ 20732316Syokota int c; 2082088Ssos 2092088Ssos yyin = fd; 2102088Ssos 21132316Syokota if (token < 0) 21232316Syokota token = yylex(); 21332316Syokota switch (token) { 21432316Syokota case TNUM: 21532316Syokota c = get_key_definition_line(keymap); 21632316Syokota if (c < 0) 21732316Syokota errx(1, "invalid key definition"); 21832316Syokota if (c > keymap->n_keys) 21932316Syokota keymap->n_keys = c; 22032316Syokota break; 22132316Syokota case TACC: 22232316Syokota c = get_accent_definition_line(accentmap); 22332316Syokota if (c < 0) 22432316Syokota errx(1, "invalid accent key definition"); 22532316Syokota if (c > accentmap->n_accs) 22632316Syokota accentmap->n_accs = c; 22732316Syokota break; 22832316Syokota case 0: 22932316Syokota /* EOF */ 2302088Ssos return -1; 23132316Syokota default: 23232316Syokota errx(1, "illegal definition line"); 23332316Syokota } 23432316Syokota return c; 23532316Syokota} 23632316Syokota 23732316Syokotaint 23832316Syokotaget_key_definition_line(keymap_t *map) 23932316Syokota{ 24032316Syokota int i, def, scancode; 24132316Syokota 24232316Syokota /* check scancode number */ 2432088Ssos if (number < 0 || number >= NUM_KEYS) 2442088Ssos return -1; 2452088Ssos scancode = number; 2462088Ssos 2472088Ssos /* get key definitions */ 2482088Ssos map->key[scancode].spcl = 0; 2492088Ssos for (i=0; i<NUM_STATES; i++) { 2502088Ssos if ((def = get_entry()) == -1) 2512088Ssos return -1; 2522088Ssos if (def & 0x100) 2532088Ssos map->key[scancode].spcl |= (0x80 >> i); 2542088Ssos map->key[scancode].map[i] = def & 0xFF; 2552088Ssos } 2562088Ssos /* get lock state key def */ 25732316Syokota if ((token = yylex()) != TFLAG) 2582088Ssos return -1; 2592088Ssos map->key[scancode].flgs = number; 26032316Syokota token = yylex(); 26132316Syokota return (scancode + 1); 2622088Ssos} 2632088Ssos 26432316Syokotaint 26532316Syokotaget_accent_definition_line(accentmap_t *map) 26632316Syokota{ 26732316Syokota int accent; 26832316Syokota int c1, c2; 26932316Syokota int i; 2702088Ssos 27132316Syokota if (ACC(number) < F_ACC || ACC(number) > L_ACC) 27232316Syokota /* number out of range */ 27332316Syokota return -1; 27432316Syokota accent = number; 27532316Syokota if (map->acc[accent].accchar != 0) { 27632316Syokota /* this entry has already been defined before! */ 27732316Syokota errx(1, "duplicated accent key definition"); 27832316Syokota } 27932316Syokota 28032316Syokota switch ((token = yylex())) { 28132316Syokota case TLET: 28232316Syokota map->acc[accent].accchar = letter; 28332316Syokota break; 28432316Syokota case TNUM: 28532316Syokota map->acc[accent].accchar = number; 28632316Syokota break; 28732316Syokota default: 28832316Syokota return -1; 28932316Syokota } 29032316Syokota 29132316Syokota for (i = 0; (token = yylex()) == '(';) { 29232316Syokota switch ((token = yylex())) { 29332316Syokota case TLET: 29432316Syokota c1 = letter; 29532316Syokota break; 29632316Syokota case TNUM: 29732316Syokota c1 = number; 29832316Syokota break; 29932316Syokota default: 30032316Syokota return -1; 30132316Syokota } 30232316Syokota switch ((token = yylex())) { 30332316Syokota case TLET: 30432316Syokota c2 = letter; 30532316Syokota break; 30632316Syokota case TNUM: 30732316Syokota c2 = number; 30832316Syokota break; 30932316Syokota default: 31032316Syokota return -1; 31132316Syokota } 31232316Syokota if ((token = yylex()) != ')') 31332316Syokota return -1; 31432316Syokota if (i >= NUM_ACCENTCHARS) { 31532316Syokota warnx("too many accented characters, ignored"); 31632316Syokota continue; 31732316Syokota } 31832316Syokota map->acc[accent].map[i][0] = c1; 31932316Syokota map->acc[accent].map[i][1] = c2; 32032316Syokota ++i; 32132316Syokota } 32232316Syokota return (accent + 1); 32332316Syokota} 32432316Syokota 32529603Scharniervoid 3262088Ssosprint_entry(FILE *fp, int value) 3272088Ssos{ 3282088Ssos int val = value & 0xFF; 3292088Ssos 3302088Ssos switch (value) { 3312088Ssos case NOP | 0x100: 3328857Srgrimes fprintf(fp, " nop "); 3332088Ssos break; 3342088Ssos case LSH | 0x100: 3352088Ssos fprintf(fp, " lshift"); 3362088Ssos break; 3372088Ssos case RSH | 0x100: 3382088Ssos fprintf(fp, " rshift"); 3392088Ssos break; 3402088Ssos case CLK | 0x100: 3412088Ssos fprintf(fp, " clock "); 3422088Ssos break; 3432088Ssos case NLK | 0x100: 3442088Ssos fprintf(fp, " nlock "); 3452088Ssos break; 3462088Ssos case SLK | 0x100: 3472088Ssos fprintf(fp, " slock "); 3482088Ssos break; 3492088Ssos case BTAB | 0x100: 3502088Ssos fprintf(fp, " btab "); 3512088Ssos break; 3522088Ssos case LALT | 0x100: 3532088Ssos fprintf(fp, " lalt "); 3542088Ssos break; 3552088Ssos case LCTR | 0x100: 3562088Ssos fprintf(fp, " lctrl "); 3572088Ssos break; 3582088Ssos case NEXT | 0x100: 3592088Ssos fprintf(fp, " nscr "); 3602088Ssos break; 3612088Ssos case RCTR | 0x100: 3622088Ssos fprintf(fp, " rctrl "); 3632088Ssos break; 3642088Ssos case RALT | 0x100: 3652088Ssos fprintf(fp, " ralt "); 3662088Ssos break; 3672088Ssos case ALK | 0x100: 3682088Ssos fprintf(fp, " alock "); 3692088Ssos break; 3702088Ssos case ASH | 0x100: 3712088Ssos fprintf(fp, " ashift"); 3722088Ssos break; 3732088Ssos case META | 0x100: 3742088Ssos fprintf(fp, " meta "); 3752088Ssos break; 3762088Ssos case RBT | 0x100: 3772088Ssos fprintf(fp, " boot "); 3782088Ssos break; 3792088Ssos case DBG | 0x100: 3802088Ssos fprintf(fp, " debug "); 3812088Ssos break; 38232316Syokota case SUSP | 0x100: 38332316Syokota fprintf(fp, " susp "); 38432316Syokota break; 3852088Ssos default: 3862088Ssos if (value & 0x100) { 3878857Srgrimes if (val >= F_FN && val <= L_FN) 3882088Ssos fprintf(fp, " fkey%02d", val - F_FN + 1); 3898857Srgrimes else if (val >= F_SCR && val <= L_SCR) 3902088Ssos fprintf(fp, " scr%02d ", val - F_SCR + 1); 39132316Syokota else if (val >= F_ACC && val <= L_ACC) 39232316Syokota fprintf(fp, " %-6s", acc_names[val - F_ACC]); 3932088Ssos else if (hex) 3948857Srgrimes fprintf(fp, " 0x%02x ", val); 3952088Ssos else 39632316Syokota fprintf(fp, " %3d ", val); 3972088Ssos } 3982088Ssos else { 3992088Ssos if (val < ' ') 4008857Srgrimes fprintf(fp, " %s ", ctrl_names[val]); 4012088Ssos else if (val == 127) 4028857Srgrimes fprintf(fp, " del "); 4039202Srgrimes else if (isascii(val) && isprint(val)) 4048857Srgrimes fprintf(fp, " '%c' ", val); 4052088Ssos else if (hex) 4068857Srgrimes fprintf(fp, " 0x%02x ", val); 4072088Ssos else 4088857Srgrimes fprintf(fp, " %3d ", val); 4092088Ssos } 4102088Ssos } 4112088Ssos} 4122088Ssos 4132088Ssos 4142088Ssosvoid 4152088Ssosprint_key_definition_line(FILE *fp, int scancode, struct key_t *key) 4162088Ssos{ 41729603Scharnier int i; 4182088Ssos 4192088Ssos /* print scancode number */ 4202088Ssos if (hex) 4212088Ssos fprintf(fp, " 0x%02x ", scancode); 4222088Ssos else 4232088Ssos fprintf(fp, " %03d ", scancode); 4242088Ssos 4252088Ssos /* print key definitions */ 4262088Ssos for (i=0; i<NUM_STATES; i++) { 4272088Ssos if (key->spcl & (0x80 >> i)) 4282088Ssos print_entry(fp, key->map[i] | 0x100); 4292088Ssos else 4308857Srgrimes print_entry(fp, key->map[i]); 4312088Ssos } 4322088Ssos 4332088Ssos /* print lock state key def */ 4342088Ssos switch (key->flgs) { 4352088Ssos case 0: 4362088Ssos fprintf(fp, " O\n"); 4372088Ssos break; 4382088Ssos case 1: 4392088Ssos fprintf(fp, " C\n"); 4402088Ssos break; 4412088Ssos case 2: 4422088Ssos fprintf(fp, " N\n"); 4432088Ssos break; 4446046Ssos case 3: 4456046Ssos fprintf(fp, " B\n"); 4466046Ssos break; 4478857Srgrimes } 4482088Ssos} 4492088Ssos 45032316Syokotavoid 45132316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key) 45232316Syokota{ 45332316Syokota int c; 45432316Syokota int i; 4552088Ssos 45632316Syokota if (key->accchar == 0) 45732316Syokota return; 45832316Syokota 45932316Syokota /* print accent number */ 46032316Syokota fprintf(fp, " %-6s", acc_names[accent]); 46132316Syokota if (isascii(key->accchar) && isprint(key->accchar)) 46232316Syokota fprintf(fp, "'%c' ", key->accchar); 46332316Syokota else if (hex) 46432316Syokota fprintf(fp, "0x%02x ", key->accchar); 46532316Syokota else 46632316Syokota fprintf(fp, "%03d ", key->accchar); 46732316Syokota 46832316Syokota for (i = 0; i < NUM_ACCENTCHARS; ++i) { 46932316Syokota c = key->map[i][0]; 47032316Syokota if (c == 0) 47132316Syokota break; 47232316Syokota if ((i > 0) && ((i % 4) == 0)) 47332316Syokota fprintf(fp, "\n "); 47432316Syokota if (isascii(c) && isprint(c)) 47532316Syokota fprintf(fp, "( '%c' ", c); 47632316Syokota else if (hex) 47732316Syokota fprintf(fp, "(0x%02x ", c); 47832316Syokota else 47932316Syokota fprintf(fp, "( %03d ", c); 48032316Syokota c = key->map[i][1]; 48132316Syokota if (isascii(c) && isprint(c)) 48232316Syokota fprintf(fp, "'%c' ) ", c); 48332316Syokota else if (hex) 48432316Syokota fprintf(fp, "0x%02x) ", c); 48532316Syokota else 48632316Syokota fprintf(fp, "%03d ) ", c); 48732316Syokota } 48832316Syokota fprintf(fp, "\n"); 48932316Syokota} 49032316Syokota 4912088Ssosvoid 49232316Syokotadump_entry(int value) 49332316Syokota{ 49432316Syokota if (value & 0x100) { 49532316Syokota value &= 0x00ff; 49632316Syokota switch (value) { 49732316Syokota case NOP: 49832316Syokota printf(" NOP, "); 49932316Syokota break; 50032316Syokota case LSH: 50132316Syokota printf(" LSH, "); 50232316Syokota break; 50332316Syokota case RSH: 50432316Syokota printf(" RSH, "); 50532316Syokota break; 50632316Syokota case CLK: 50732316Syokota printf(" CLK, "); 50832316Syokota break; 50932316Syokota case NLK: 51032316Syokota printf(" NLK, "); 51132316Syokota break; 51232316Syokota case SLK: 51332316Syokota printf(" SLK, "); 51432316Syokota break; 51532316Syokota case BTAB: 51632316Syokota printf(" BTAB, "); 51732316Syokota break; 51832316Syokota case LALT: 51932316Syokota printf(" LALT, "); 52032316Syokota break; 52132316Syokota case LCTR: 52232316Syokota printf(" LCTR, "); 52332316Syokota break; 52432316Syokota case NEXT: 52532316Syokota printf(" NEXT, "); 52632316Syokota break; 52732316Syokota case RCTR: 52832316Syokota printf(" RCTR, "); 52932316Syokota break; 53032316Syokota case RALT: 53132316Syokota printf(" RALT, "); 53232316Syokota break; 53332316Syokota case ALK: 53432316Syokota printf(" ALK, "); 53532316Syokota break; 53632316Syokota case ASH: 53732316Syokota printf(" ASH, "); 53832316Syokota break; 53932316Syokota case META: 54032316Syokota printf(" META, "); 54132316Syokota break; 54232316Syokota case RBT: 54332316Syokota printf(" RBT, "); 54432316Syokota break; 54532316Syokota case DBG: 54632316Syokota printf(" DBG, "); 54732316Syokota break; 54832316Syokota case SUSP: 54932316Syokota printf(" SUSP, "); 55032316Syokota break; 55132316Syokota default: 55232316Syokota if (value >= F_FN && value <= L_FN) 55332316Syokota printf(" F(%2d),", value - F_FN + 1); 55432316Syokota else if (value >= F_SCR && value <= L_SCR) 55532486Syokota printf(" S(%2d),", value - F_SCR + 1); 55632316Syokota else if (value >= F_ACC && value <= L_ACC) 55732316Syokota printf(" %-4s, ", acc_names_u[value - F_ACC]); 55832316Syokota else 55932316Syokota printf(" 0x%02X, ", value); 56032316Syokota break; 56132316Syokota } 56232316Syokota } else if (value == '\'') { 56332316Syokota printf(" '\\'', "); 56432316Syokota } else if (value == '\\') { 56532316Syokota printf(" '\\\\', "); 56632316Syokota } else if (isascii(value) && isprint(value)) { 56732316Syokota printf(" '%c', ", value); 56832316Syokota } else { 56932316Syokota printf(" 0x%02X, ", value); 57032316Syokota } 57132316Syokota} 57232316Syokota 57332316Syokotavoid 57432316Syokotadump_key_definition(char *name, keymap_t *keymap) 57532316Syokota{ 57632316Syokota int i, j; 57732316Syokota 57832486Syokota printf("static keymap_t keymap_%s = { 0x%02x, {\n", 57932316Syokota name, (unsigned)keymap->n_keys); 58032316Syokota printf( 58132486Syokota"/* alt\n" 58232486Syokota" * scan cntrl alt alt cntrl\n" 58332486Syokota" * code base shift cntrl shift alt shift cntrl shift spcl flgs\n" 58432316Syokota" * ---------------------------------------------------------------------------\n" 58532316Syokota" */\n"); 58632316Syokota for (i = 0; i < keymap->n_keys; i++) { 58732486Syokota printf("/*%02x*/{{", i); 58832316Syokota for (j = 0; j < NUM_STATES; j++) { 58932316Syokota if (keymap->key[i].spcl & (0x80 >> j)) 59032316Syokota dump_entry(keymap->key[i].map[j] | 0x100); 59132316Syokota else 59232316Syokota dump_entry(keymap->key[i].map[j]); 59332316Syokota } 59432486Syokota printf("}, 0x%02X,0x%02X },\n", 59532316Syokota (unsigned)keymap->key[i].spcl, 59632316Syokota (unsigned)keymap->key[i].flgs); 59732316Syokota } 59832486Syokota printf("} };\n\n"); 59932316Syokota} 60032316Syokota 60132316Syokotavoid 60232316Syokotadump_accent_definition(char *name, accentmap_t *accentmap) 60332316Syokota{ 60432316Syokota int i, j; 60532316Syokota int c; 60632316Syokota 60732486Syokota printf("static accentmap_t accentmap_%s = { %d", 60832316Syokota name, accentmap->n_accs); 60932486Syokota if (accentmap->n_accs <= 0) { 61032486Syokota printf(" };\n\n"); 61132486Syokota return; 61232486Syokota } 61332486Syokota printf(", {\n"); 61432316Syokota for (i = 0; i < NUM_DEADKEYS; i++) { 61532316Syokota printf(" /* %s=%d */\n {", acc_names[i], i); 61632316Syokota c = accentmap->acc[i].accchar; 61732316Syokota if (c == '\'') 61832316Syokota printf(" '\\'', {"); 61932316Syokota else if (c == '\\') 62032316Syokota printf(" '\\\\', {"); 62132316Syokota else if (isascii(c) && isprint(c)) 62232316Syokota printf(" '%c', {", c); 62332316Syokota else if (c == 0) { 62432316Syokota printf(" 0x00 }, \n"); 62532316Syokota continue; 62632316Syokota } else 62732316Syokota printf(" 0x%02x, {", c); 62832316Syokota for (j = 0; j < NUM_ACCENTCHARS; j++) { 62932316Syokota c = accentmap->acc[i].map[j][0]; 63032316Syokota if (c == 0) 63132316Syokota break; 63232316Syokota if ((j > 0) && ((j % 4) == 0)) 63332316Syokota printf("\n\t "); 63432316Syokota if (isascii(c) && isprint(c)) 63532316Syokota printf(" { '%c',", c); 63632316Syokota else 63732316Syokota printf(" { 0x%02x,", c); 63832316Syokota printf("0x%02x },", accentmap->acc[i].map[j][1]); 63932316Syokota } 64032316Syokota printf(" }, },\n"); 64132316Syokota } 64232486Syokota printf("} };\n\n"); 64332316Syokota} 64432316Syokota 64532316Syokotavoid 64619569Sjoergload_keymap(char *opt, int dumponly) 6472088Ssos{ 64832316Syokota keymap_t keymap; 64932316Syokota accentmap_t accentmap; 6502088Ssos FILE *fd; 65132316Syokota int i; 65219569Sjoerg char *name, *cp; 6532088Ssos char *prefix[] = {"", "", KEYMAP_PATH, NULL}; 6542088Ssos char *postfix[] = {"", ".kbd", ".kbd"}; 6552088Ssos 6562088Ssos for (i=0; prefix[i]; i++) { 6572088Ssos name = mkfullname(prefix[i], opt, postfix[i]); 65829603Scharnier if ((fd = fopen(name, "r"))) 6592088Ssos break; 6602088Ssos } 6612088Ssos if (fd == NULL) { 66229603Scharnier warn("keymap file not found"); 6632088Ssos return; 6642088Ssos } 66532316Syokota memset(&keymap, 0, sizeof(keymap)); 66632316Syokota memset(&accentmap, 0, sizeof(accentmap)); 66732316Syokota token = -1; 6682088Ssos while (1) { 66932316Syokota if (get_definition_line(fd, &keymap, &accentmap) < 0) 6702088Ssos break; 6712088Ssos } 67219569Sjoerg if (dumponly) { 67319569Sjoerg /* fix up the filename to make it a valid C identifier */ 67419569Sjoerg for (cp = opt; *cp; cp++) 67519569Sjoerg if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_'; 67632316Syokota printf("/*\n" 67732316Syokota " * Automatically generated from %s.\n" 67832316Syokota " * DO NOT EDIT!\n" 67932316Syokota " */\n", name); 68032316Syokota dump_key_definition(opt, &keymap); 68132316Syokota dump_accent_definition(opt, &accentmap); 68219569Sjoerg return; 68319569Sjoerg } 68432316Syokota if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) { 68529603Scharnier warn("setting keymap"); 6862088Ssos fclose(fd); 6872088Ssos return; 6882088Ssos } 68932316Syokota if ((accentmap.n_accs > 0) 69032316Syokota && (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) { 69132316Syokota warn("setting accentmap"); 69232316Syokota fclose(fd); 69332316Syokota return; 69432316Syokota } 6952088Ssos} 6962088Ssos 6972088Ssosvoid 6982088Ssosprint_keymap() 6992088Ssos{ 70032316Syokota keymap_t keymap; 70132316Syokota accentmap_t accentmap; 7022088Ssos int i; 7032088Ssos 70432316Syokota if (ioctl(0, GIO_KEYMAP, &keymap) < 0) 70529603Scharnier err(1, "getting keymap"); 70632316Syokota if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0) 70732316Syokota memset(&accentmap, 0, sizeof(accentmap)); 7082088Ssos printf( 7092088Ssos"# alt\n" 7102088Ssos"# scan cntrl alt alt cntrl lock\n" 7112088Ssos"# code base shift cntrl shift alt shift cntrl shift state\n" 7122088Ssos"# ------------------------------------------------------------------\n" 7132088Ssos ); 71432316Syokota for (i=0; i<keymap.n_keys; i++) 71532316Syokota print_key_definition_line(stdout, i, &keymap.key[i]); 71632316Syokota 71732316Syokota printf("\n"); 71832316Syokota for (i = 0; i < NUM_DEADKEYS; i++) 71932316Syokota print_accent_definition_line(stdout, i, &accentmap.acc[i]); 72032316Syokota 7212088Ssos} 7222088Ssos 7232088Ssos 7242088Ssosvoid 7252088Ssosload_default_functionkeys() 7262088Ssos{ 7272088Ssos fkeyarg_t fkey; 7282088Ssos int i; 7292088Ssos 7302088Ssos for (i=0; i<NUM_FKEYS; i++) { 7312088Ssos fkey.keynum = i; 7322088Ssos strcpy(fkey.keydef, fkey_table[i]); 7332088Ssos fkey.flen = strlen(fkey_table[i]); 7342088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 73529603Scharnier warn("setting function key"); 7362088Ssos } 7372088Ssos} 7382088Ssos 7392088Ssosvoid 7402088Ssosset_functionkey(char *keynumstr, char *string) 7412088Ssos{ 7422088Ssos fkeyarg_t fkey; 7432088Ssos 7442088Ssos if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) { 7452088Ssos load_default_functionkeys(); 7462088Ssos return; 7472088Ssos } 7482088Ssos fkey.keynum = atoi(keynumstr); 7492088Ssos if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) { 75029603Scharnier warnx("function key number must be between 1 and %d", 7512088Ssos NUM_FKEYS); 7522088Ssos return; 7532088Ssos } 7542088Ssos if ((fkey.flen = strlen(string)) > MAXFK) { 75529603Scharnier warnx("function key string too long (%d > %d)", 7562088Ssos fkey.flen, MAXFK); 7572088Ssos return; 7582088Ssos } 7592088Ssos strcpy(fkey.keydef, string); 7602088Ssos fkey.keynum -= 1; 7612088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 76229603Scharnier warn("setting function key"); 7632088Ssos} 7642088Ssos 7652088Ssos 7662088Ssosvoid 7672088Ssosset_bell_values(char *opt) 7682088Ssos{ 7695536Ssos int bell, duration, pitch; 7702088Ssos 7718857Srgrimes if (!strcmp(opt, "visual")) 7725536Ssos bell = 1, duration = 1, pitch = 800; 7735536Ssos else if (!strcmp(opt, "normal")) 7745536Ssos bell = 0, duration = 1, pitch = 800; 7752088Ssos else { 7762088Ssos char *v1; 7778857Srgrimes 7785536Ssos bell = 0; 7792088Ssos duration = strtol(opt, &v1, 0); 7802088Ssos if ((duration < 0) || (*v1 != '.')) 7812088Ssos goto badopt; 7822088Ssos opt = ++v1; 7832088Ssos pitch = strtol(opt, &v1, 0); 7842088Ssos if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) { 7852088Ssosbadopt: 78629603Scharnier warnx("argument to -b must be DURATION.PITCH"); 7872088Ssos return; 7882088Ssos } 7892088Ssos } 7902088Ssos 7915536Ssos ioctl(0, CONS_BELLTYPE, &bell); 7925536Ssos if (!bell) 7935536Ssos fprintf(stderr, "[=%d;%dB", pitch, duration); 7942088Ssos} 7952088Ssos 7962088Ssos 7972088Ssosvoid 7982088Ssosset_keyrates(char *opt) 7992088Ssos{ 8002088Ssosstruct { 8012088Ssos int rep:5; 8022088Ssos int del:2; 8032088Ssos int pad:1; 8042088Ssos }rate; 8052088Ssos 8062088Ssos if (!strcmp(opt, "slow")) 8072088Ssos rate.del = 3, rate.rep = 31; 8082088Ssos else if (!strcmp(opt, "normal")) 8092088Ssos rate.del = 1, rate.rep = 15; 8102088Ssos else if (!strcmp(opt, "fast")) 8112088Ssos rate.del = rate.rep = 0; 8122088Ssos else { 8132088Ssos int n; 8142088Ssos int delay, repeat; 8152088Ssos char *v1; 8162088Ssos 8172088Ssos delay = strtol(opt, &v1, 0); 8182088Ssos if ((delay < 0) || (*v1 != '.')) 8192088Ssos goto badopt; 8202088Ssos opt = ++v1; 8212088Ssos repeat = strtol(opt, &v1, 0); 8222088Ssos if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) { 8232088Ssosbadopt: 82429603Scharnier warnx("argument to -r must be delay.repeat"); 8252088Ssos return; 8262088Ssos } 8272088Ssos for (n = 0; n < ndelays - 1; n++) 8282088Ssos if (delay <= delays[n]) 8292088Ssos break; 8302088Ssos rate.del = n; 8312088Ssos for (n = 0; n < nrepeats - 1; n++) 8322088Ssos if (repeat <= repeats[n]) 8332088Ssos break; 8342088Ssos rate.rep = n; 8352088Ssos } 8362088Ssos 8372088Ssos if (ioctl(0, KDSETRAD, rate) < 0) 83829603Scharnier warn("setting keyboard rate"); 8392088Ssos} 8402088Ssos 8412088Ssos 8426046Ssosvoid 8436046Ssosset_history(char *opt) 8446046Ssos{ 8456046Ssos int size; 8466046Ssos 8476046Ssos size = atoi(opt); 8486046Ssos if ((*opt == '\0') || size < 0) { 84929603Scharnier warnx("argument must be a positive number"); 8506046Ssos return; 8516046Ssos } 8526046Ssos if (ioctl(0, CONS_HISTORY, &size) == -1) 85329603Scharnier warn("setting history buffer size"); 8546046Ssos} 8556046Ssos 8566046Ssos 85729603Scharnierstatic void 8582088Ssosusage() 8592088Ssos{ 86029603Scharnier fprintf(stderr, "%s\n%s\n%s\n", 86129603Scharnier"usage: kbdcontrol [-dFx] [-b duration.pitch | belltype]", 86229603Scharnier" [-r delay.repeat | speed] [-l mapfile] [-f # string]", 86329603Scharnier" [-h size] [-L mapfile]"); 86429603Scharnier exit(1); 8652088Ssos} 8662088Ssos 8672088Ssos 8682088Ssosvoid 8692088Ssosmain(int argc, char **argv) 8702088Ssos{ 8712088Ssos int opt; 8722088Ssos 87319569Sjoerg while((opt = getopt(argc, argv, "b:df:h:Fl:L:r:x")) != -1) 8742088Ssos switch(opt) { 8752088Ssos case 'b': 8762088Ssos set_bell_values(optarg); 8772088Ssos break; 8782088Ssos case 'd': 8792088Ssos print_keymap(); 8802088Ssos break; 8812088Ssos case 'l': 88219569Sjoerg load_keymap(optarg, 0); 8832088Ssos break; 88419569Sjoerg case 'L': 88519569Sjoerg load_keymap(optarg, 1); 88619569Sjoerg break; 8872088Ssos case 'f': 8888857Srgrimes set_functionkey(optarg, 8892088Ssos nextarg(argc, argv, &optind, 'f')); 8902088Ssos break; 8912088Ssos case 'F': 8922088Ssos load_default_functionkeys(); 8932088Ssos break; 8946046Ssos case 'h': 8956046Ssos set_history(optarg); 8966046Ssos break; 8972088Ssos case 'r': 8982088Ssos set_keyrates(optarg); 8992088Ssos break; 9002088Ssos case 'x': 9012088Ssos hex = 1; 9022088Ssos break; 9032088Ssos default: 9042088Ssos usage(); 9052088Ssos } 90629603Scharnier if ((optind != argc) || (argc == 1)) 9072088Ssos usage(); 9082088Ssos exit(0); 9092088Ssos} 9102088Ssos 9112088Ssos 912