kbdcontrol.c revision 65759
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[] = 3150479Speter "$FreeBSD: head/usr.sbin/kbdcontrol/kbdcontrol.c 65759 2000-09-11 20:37:42Z dwmalone $"; 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; 16648105Syokota case TPREV: 16748105Syokota return PREV | 0x100; 1682088Ssos case TRCTR: 1692088Ssos return RCTR | 0x100; 1702088Ssos case TRALT: 1712088Ssos return RALT | 0x100; 1722088Ssos case TALK: 1732088Ssos return ALK | 0x100; 1742088Ssos case TASH: 1752088Ssos return ASH | 0x100; 1762088Ssos case TMETA: 1772088Ssos return META | 0x100; 1782088Ssos case TRBT: 1792088Ssos return RBT | 0x100; 1802088Ssos case TDBG: 1812088Ssos return DBG | 0x100; 1825994Ssos case TSUSP: 1835994Ssos return SUSP | 0x100; 18438053Syokota case TSPSC: 18538053Syokota return SPSC | 0x100; 18654380Syokota case TPANIC: 18754380Syokota return PNC | 0x100; 18854380Syokota case TLSHA: 18954380Syokota return LSHA | 0x100; 19054380Syokota case TRSHA: 19154380Syokota return RSHA | 0x100; 19254380Syokota case TLCTRA: 19354380Syokota return LCTRA | 0x100; 19454380Syokota case TRCTRA: 19554380Syokota return RCTRA | 0x100; 19654380Syokota case TLALTA: 19754380Syokota return LALTA | 0x100; 19854380Syokota case TRALTA: 19954380Syokota return RALTA | 0x100; 20065759Sdwmalone case THALT: 20165759Sdwmalone return HALT | 0x100; 20265759Sdwmalone case TPDWN: 20365759Sdwmalone return PDWN | 0x100; 20432316Syokota case TACC: 20532316Syokota if (ACC(number) > L_ACC) 20632316Syokota return -1; 20732316Syokota return ACC(number) | 0x100; 2082088Ssos case TFUNC: 2092088Ssos if (F(number) > L_FN) 2102088Ssos return -1; 2112088Ssos return F(number) | 0x100; 2122088Ssos case TSCRN: 2132088Ssos if (S(number) > L_SCR) 2142088Ssos return -1; 2152088Ssos return S(number) | 0x100; 2162088Ssos case TLET: 2172088Ssos return (unsigned char)letter; 2182088Ssos case TNUM: 2192088Ssos if (number < 0 || number > 255) 2202088Ssos return -1; 2212088Ssos return number; 2222088Ssos default: 2232088Ssos return -1; 2242088Ssos } 2252088Ssos} 2262088Ssos 2272088Ssosint 22832316Syokotaget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap) 2292088Ssos{ 23032316Syokota int c; 2312088Ssos 2322088Ssos yyin = fd; 2332088Ssos 23432316Syokota if (token < 0) 23532316Syokota token = yylex(); 23632316Syokota switch (token) { 23732316Syokota case TNUM: 23832316Syokota c = get_key_definition_line(keymap); 23932316Syokota if (c < 0) 24032316Syokota errx(1, "invalid key definition"); 24132316Syokota if (c > keymap->n_keys) 24232316Syokota keymap->n_keys = c; 24332316Syokota break; 24432316Syokota case TACC: 24532316Syokota c = get_accent_definition_line(accentmap); 24632316Syokota if (c < 0) 24732316Syokota errx(1, "invalid accent key definition"); 24832316Syokota if (c > accentmap->n_accs) 24932316Syokota accentmap->n_accs = c; 25032316Syokota break; 25132316Syokota case 0: 25232316Syokota /* EOF */ 2532088Ssos return -1; 25432316Syokota default: 25532316Syokota errx(1, "illegal definition line"); 25632316Syokota } 25732316Syokota return c; 25832316Syokota} 25932316Syokota 26032316Syokotaint 26132316Syokotaget_key_definition_line(keymap_t *map) 26232316Syokota{ 26332316Syokota int i, def, scancode; 26432316Syokota 26532316Syokota /* check scancode number */ 2662088Ssos if (number < 0 || number >= NUM_KEYS) 2672088Ssos return -1; 2682088Ssos scancode = number; 2692088Ssos 2702088Ssos /* get key definitions */ 2712088Ssos map->key[scancode].spcl = 0; 2722088Ssos for (i=0; i<NUM_STATES; i++) { 2732088Ssos if ((def = get_entry()) == -1) 2742088Ssos return -1; 2752088Ssos if (def & 0x100) 2762088Ssos map->key[scancode].spcl |= (0x80 >> i); 2772088Ssos map->key[scancode].map[i] = def & 0xFF; 2782088Ssos } 2792088Ssos /* get lock state key def */ 28032316Syokota if ((token = yylex()) != TFLAG) 2812088Ssos return -1; 2822088Ssos map->key[scancode].flgs = number; 28332316Syokota token = yylex(); 28432316Syokota return (scancode + 1); 2852088Ssos} 2862088Ssos 28732316Syokotaint 28832316Syokotaget_accent_definition_line(accentmap_t *map) 28932316Syokota{ 29032316Syokota int accent; 29132316Syokota int c1, c2; 29232316Syokota int i; 2932088Ssos 29432316Syokota if (ACC(number) < F_ACC || ACC(number) > L_ACC) 29532316Syokota /* number out of range */ 29632316Syokota return -1; 29732316Syokota accent = number; 29832316Syokota if (map->acc[accent].accchar != 0) { 29932316Syokota /* this entry has already been defined before! */ 30032316Syokota errx(1, "duplicated accent key definition"); 30132316Syokota } 30232316Syokota 30332316Syokota switch ((token = yylex())) { 30432316Syokota case TLET: 30532316Syokota map->acc[accent].accchar = letter; 30632316Syokota break; 30732316Syokota case TNUM: 30832316Syokota map->acc[accent].accchar = number; 30932316Syokota break; 31032316Syokota default: 31132316Syokota return -1; 31232316Syokota } 31332316Syokota 31432316Syokota for (i = 0; (token = yylex()) == '(';) { 31532316Syokota switch ((token = yylex())) { 31632316Syokota case TLET: 31732316Syokota c1 = letter; 31832316Syokota break; 31932316Syokota case TNUM: 32032316Syokota c1 = number; 32132316Syokota break; 32232316Syokota default: 32332316Syokota return -1; 32432316Syokota } 32532316Syokota switch ((token = yylex())) { 32632316Syokota case TLET: 32732316Syokota c2 = letter; 32832316Syokota break; 32932316Syokota case TNUM: 33032316Syokota c2 = number; 33132316Syokota break; 33232316Syokota default: 33332316Syokota return -1; 33432316Syokota } 33532316Syokota if ((token = yylex()) != ')') 33632316Syokota return -1; 33732316Syokota if (i >= NUM_ACCENTCHARS) { 33832316Syokota warnx("too many accented characters, ignored"); 33932316Syokota continue; 34032316Syokota } 34132316Syokota map->acc[accent].map[i][0] = c1; 34232316Syokota map->acc[accent].map[i][1] = c2; 34332316Syokota ++i; 34432316Syokota } 34532316Syokota return (accent + 1); 34632316Syokota} 34732316Syokota 34829603Scharniervoid 3492088Ssosprint_entry(FILE *fp, int value) 3502088Ssos{ 3512088Ssos int val = value & 0xFF; 3522088Ssos 3532088Ssos switch (value) { 3542088Ssos case NOP | 0x100: 3558857Srgrimes fprintf(fp, " nop "); 3562088Ssos break; 3572088Ssos case LSH | 0x100: 3582088Ssos fprintf(fp, " lshift"); 3592088Ssos break; 3602088Ssos case RSH | 0x100: 3612088Ssos fprintf(fp, " rshift"); 3622088Ssos break; 3632088Ssos case CLK | 0x100: 3642088Ssos fprintf(fp, " clock "); 3652088Ssos break; 3662088Ssos case NLK | 0x100: 3672088Ssos fprintf(fp, " nlock "); 3682088Ssos break; 3692088Ssos case SLK | 0x100: 3702088Ssos fprintf(fp, " slock "); 3712088Ssos break; 3722088Ssos case BTAB | 0x100: 3732088Ssos fprintf(fp, " btab "); 3742088Ssos break; 3752088Ssos case LALT | 0x100: 3762088Ssos fprintf(fp, " lalt "); 3772088Ssos break; 3782088Ssos case LCTR | 0x100: 3792088Ssos fprintf(fp, " lctrl "); 3802088Ssos break; 3812088Ssos case NEXT | 0x100: 3822088Ssos fprintf(fp, " nscr "); 3832088Ssos break; 38448105Syokota case PREV | 0x100: 38548105Syokota fprintf(fp, " pscr "); 38648105Syokota break; 3872088Ssos case RCTR | 0x100: 3882088Ssos fprintf(fp, " rctrl "); 3892088Ssos break; 3902088Ssos case RALT | 0x100: 3912088Ssos fprintf(fp, " ralt "); 3922088Ssos break; 3932088Ssos case ALK | 0x100: 3942088Ssos fprintf(fp, " alock "); 3952088Ssos break; 3962088Ssos case ASH | 0x100: 3972088Ssos fprintf(fp, " ashift"); 3982088Ssos break; 3992088Ssos case META | 0x100: 4002088Ssos fprintf(fp, " meta "); 4012088Ssos break; 4022088Ssos case RBT | 0x100: 4032088Ssos fprintf(fp, " boot "); 4042088Ssos break; 4052088Ssos case DBG | 0x100: 4062088Ssos fprintf(fp, " debug "); 4072088Ssos break; 40832316Syokota case SUSP | 0x100: 40932316Syokota fprintf(fp, " susp "); 41032316Syokota break; 41138053Syokota case SPSC | 0x100: 41238053Syokota fprintf(fp, " saver "); 41338053Syokota break; 41454380Syokota case PNC | 0x100: 41554380Syokota fprintf(fp, " panic "); 41654380Syokota break; 41754380Syokota case LSHA | 0x100: 41854380Syokota fprintf(fp, " lshifta"); 41954380Syokota break; 42054380Syokota case RSHA | 0x100: 42154380Syokota fprintf(fp, " rshifta"); 42254380Syokota break; 42354380Syokota case LCTRA | 0x100: 42454380Syokota fprintf(fp, " lctrla"); 42554380Syokota break; 42654380Syokota case RCTRA | 0x100: 42754380Syokota fprintf(fp, " rctrla"); 42854380Syokota break; 42954380Syokota case LALTA | 0x100: 43054380Syokota fprintf(fp, " lalta "); 43154380Syokota break; 43254380Syokota case RALTA | 0x100: 43354380Syokota fprintf(fp, " ralta "); 43454380Syokota break; 43565759Sdwmalone case HALT | 0x100: 43665759Sdwmalone fprintf(fp, " halt "); 43765759Sdwmalone break; 43865759Sdwmalone case PDWN | 0x100: 43965759Sdwmalone fprintf(fp, " pdwn "); 44065759Sdwmalone break; 4412088Ssos default: 4422088Ssos if (value & 0x100) { 4438857Srgrimes if (val >= F_FN && val <= L_FN) 4442088Ssos fprintf(fp, " fkey%02d", val - F_FN + 1); 4458857Srgrimes else if (val >= F_SCR && val <= L_SCR) 4462088Ssos fprintf(fp, " scr%02d ", val - F_SCR + 1); 44732316Syokota else if (val >= F_ACC && val <= L_ACC) 44832316Syokota fprintf(fp, " %-6s", acc_names[val - F_ACC]); 4492088Ssos else if (hex) 4508857Srgrimes fprintf(fp, " 0x%02x ", val); 4512088Ssos else 45232316Syokota fprintf(fp, " %3d ", val); 4532088Ssos } 4542088Ssos else { 4552088Ssos if (val < ' ') 4568857Srgrimes fprintf(fp, " %s ", ctrl_names[val]); 4572088Ssos else if (val == 127) 4588857Srgrimes fprintf(fp, " del "); 4599202Srgrimes else if (isascii(val) && isprint(val)) 4608857Srgrimes fprintf(fp, " '%c' ", val); 4612088Ssos else if (hex) 4628857Srgrimes fprintf(fp, " 0x%02x ", val); 4632088Ssos else 4648857Srgrimes fprintf(fp, " %3d ", val); 4652088Ssos } 4662088Ssos } 4672088Ssos} 4682088Ssos 4692088Ssos 4702088Ssosvoid 47142505Syokotaprint_key_definition_line(FILE *fp, int scancode, struct keyent_t *key) 4722088Ssos{ 47329603Scharnier int i; 4742088Ssos 4752088Ssos /* print scancode number */ 4762088Ssos if (hex) 4772088Ssos fprintf(fp, " 0x%02x ", scancode); 4782088Ssos else 4792088Ssos fprintf(fp, " %03d ", scancode); 4802088Ssos 4812088Ssos /* print key definitions */ 4822088Ssos for (i=0; i<NUM_STATES; i++) { 4832088Ssos if (key->spcl & (0x80 >> i)) 4842088Ssos print_entry(fp, key->map[i] | 0x100); 4852088Ssos else 4868857Srgrimes print_entry(fp, key->map[i]); 4872088Ssos } 4882088Ssos 4892088Ssos /* print lock state key def */ 4902088Ssos switch (key->flgs) { 4912088Ssos case 0: 4922088Ssos fprintf(fp, " O\n"); 4932088Ssos break; 4942088Ssos case 1: 4952088Ssos fprintf(fp, " C\n"); 4962088Ssos break; 4972088Ssos case 2: 4982088Ssos fprintf(fp, " N\n"); 4992088Ssos break; 5006046Ssos case 3: 5016046Ssos fprintf(fp, " B\n"); 5026046Ssos break; 5038857Srgrimes } 5042088Ssos} 5052088Ssos 50632316Syokotavoid 50732316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key) 50832316Syokota{ 50932316Syokota int c; 51032316Syokota int i; 5112088Ssos 51232316Syokota if (key->accchar == 0) 51332316Syokota return; 51432316Syokota 51532316Syokota /* print accent number */ 51632316Syokota fprintf(fp, " %-6s", acc_names[accent]); 51732316Syokota if (isascii(key->accchar) && isprint(key->accchar)) 51832316Syokota fprintf(fp, "'%c' ", key->accchar); 51932316Syokota else if (hex) 52032316Syokota fprintf(fp, "0x%02x ", key->accchar); 52132316Syokota else 52232316Syokota fprintf(fp, "%03d ", key->accchar); 52332316Syokota 52432316Syokota for (i = 0; i < NUM_ACCENTCHARS; ++i) { 52532316Syokota c = key->map[i][0]; 52632316Syokota if (c == 0) 52732316Syokota break; 52832316Syokota if ((i > 0) && ((i % 4) == 0)) 52932316Syokota fprintf(fp, "\n "); 53032316Syokota if (isascii(c) && isprint(c)) 53132316Syokota fprintf(fp, "( '%c' ", c); 53232316Syokota else if (hex) 53332316Syokota fprintf(fp, "(0x%02x ", c); 53432316Syokota else 53532316Syokota fprintf(fp, "( %03d ", c); 53632316Syokota c = key->map[i][1]; 53732316Syokota if (isascii(c) && isprint(c)) 53832316Syokota fprintf(fp, "'%c' ) ", c); 53932316Syokota else if (hex) 54032316Syokota fprintf(fp, "0x%02x) ", c); 54132316Syokota else 54232316Syokota fprintf(fp, "%03d ) ", c); 54332316Syokota } 54432316Syokota fprintf(fp, "\n"); 54532316Syokota} 54632316Syokota 5472088Ssosvoid 54832316Syokotadump_entry(int value) 54932316Syokota{ 55032316Syokota if (value & 0x100) { 55132316Syokota value &= 0x00ff; 55232316Syokota switch (value) { 55332316Syokota case NOP: 55432316Syokota printf(" NOP, "); 55532316Syokota break; 55632316Syokota case LSH: 55732316Syokota printf(" LSH, "); 55832316Syokota break; 55932316Syokota case RSH: 56032316Syokota printf(" RSH, "); 56132316Syokota break; 56232316Syokota case CLK: 56332316Syokota printf(" CLK, "); 56432316Syokota break; 56532316Syokota case NLK: 56632316Syokota printf(" NLK, "); 56732316Syokota break; 56832316Syokota case SLK: 56932316Syokota printf(" SLK, "); 57032316Syokota break; 57132316Syokota case BTAB: 57232316Syokota printf(" BTAB, "); 57332316Syokota break; 57432316Syokota case LALT: 57532316Syokota printf(" LALT, "); 57632316Syokota break; 57732316Syokota case LCTR: 57832316Syokota printf(" LCTR, "); 57932316Syokota break; 58032316Syokota case NEXT: 58132316Syokota printf(" NEXT, "); 58232316Syokota break; 58348105Syokota case PREV: 58448105Syokota printf(" PREV, "); 58548105Syokota break; 58632316Syokota case RCTR: 58732316Syokota printf(" RCTR, "); 58832316Syokota break; 58932316Syokota case RALT: 59032316Syokota printf(" RALT, "); 59132316Syokota break; 59232316Syokota case ALK: 59332316Syokota printf(" ALK, "); 59432316Syokota break; 59532316Syokota case ASH: 59632316Syokota printf(" ASH, "); 59732316Syokota break; 59832316Syokota case META: 59932316Syokota printf(" META, "); 60032316Syokota break; 60132316Syokota case RBT: 60232316Syokota printf(" RBT, "); 60332316Syokota break; 60432316Syokota case DBG: 60532316Syokota printf(" DBG, "); 60632316Syokota break; 60732316Syokota case SUSP: 60832316Syokota printf(" SUSP, "); 60932316Syokota break; 61038053Syokota case SPSC: 61138053Syokota printf(" SPSC, "); 61238053Syokota break; 61354380Syokota case PNC: 61454380Syokota printf(" PNC, "); 61554380Syokota break; 61654380Syokota case LSHA: 61754380Syokota printf(" LSHA, "); 61854380Syokota break; 61954380Syokota case RSHA: 62054380Syokota printf(" RSHA, "); 62154380Syokota break; 62254380Syokota case LCTRA: 62354380Syokota printf("LCTRA, "); 62454380Syokota break; 62554380Syokota case RCTRA: 62654380Syokota printf("RCTRA, "); 62754380Syokota break; 62854380Syokota case LALTA: 62954380Syokota printf("LALTA, "); 63054380Syokota break; 63154380Syokota case RALTA: 63254380Syokota printf("RALTA, "); 63354380Syokota break; 63465759Sdwmalone case HALT: 63565759Sdwmalone printf(" HALT, "); 63665759Sdwmalone break; 63765759Sdwmalone case PDWN: 63865759Sdwmalone printf(" PDWN, "); 63965759Sdwmalone break; 64032316Syokota default: 64132316Syokota if (value >= F_FN && value <= L_FN) 64232316Syokota printf(" F(%2d),", value - F_FN + 1); 64332316Syokota else if (value >= F_SCR && value <= L_SCR) 64432486Syokota printf(" S(%2d),", value - F_SCR + 1); 64532316Syokota else if (value >= F_ACC && value <= L_ACC) 64632316Syokota printf(" %-4s, ", acc_names_u[value - F_ACC]); 64732316Syokota else 64832316Syokota printf(" 0x%02X, ", value); 64932316Syokota break; 65032316Syokota } 65132316Syokota } else if (value == '\'') { 65232316Syokota printf(" '\\'', "); 65332316Syokota } else if (value == '\\') { 65432316Syokota printf(" '\\\\', "); 65532316Syokota } else if (isascii(value) && isprint(value)) { 65632316Syokota printf(" '%c', ", value); 65732316Syokota } else { 65832316Syokota printf(" 0x%02X, ", value); 65932316Syokota } 66032316Syokota} 66132316Syokota 66232316Syokotavoid 66332316Syokotadump_key_definition(char *name, keymap_t *keymap) 66432316Syokota{ 66532316Syokota int i, j; 66632316Syokota 66732486Syokota printf("static keymap_t keymap_%s = { 0x%02x, {\n", 66832316Syokota name, (unsigned)keymap->n_keys); 66932316Syokota printf( 67032486Syokota"/* alt\n" 67132486Syokota" * scan cntrl alt alt cntrl\n" 67232486Syokota" * code base shift cntrl shift alt shift cntrl shift spcl flgs\n" 67332316Syokota" * ---------------------------------------------------------------------------\n" 67432316Syokota" */\n"); 67532316Syokota for (i = 0; i < keymap->n_keys; i++) { 67632486Syokota printf("/*%02x*/{{", i); 67732316Syokota for (j = 0; j < NUM_STATES; j++) { 67832316Syokota if (keymap->key[i].spcl & (0x80 >> j)) 67932316Syokota dump_entry(keymap->key[i].map[j] | 0x100); 68032316Syokota else 68132316Syokota dump_entry(keymap->key[i].map[j]); 68232316Syokota } 68332486Syokota printf("}, 0x%02X,0x%02X },\n", 68432316Syokota (unsigned)keymap->key[i].spcl, 68532316Syokota (unsigned)keymap->key[i].flgs); 68632316Syokota } 68732486Syokota printf("} };\n\n"); 68832316Syokota} 68932316Syokota 69032316Syokotavoid 69132316Syokotadump_accent_definition(char *name, accentmap_t *accentmap) 69232316Syokota{ 69332316Syokota int i, j; 69432316Syokota int c; 69532316Syokota 69632486Syokota printf("static accentmap_t accentmap_%s = { %d", 69732316Syokota name, accentmap->n_accs); 69832486Syokota if (accentmap->n_accs <= 0) { 69932486Syokota printf(" };\n\n"); 70032486Syokota return; 70132486Syokota } 70232486Syokota printf(", {\n"); 70332316Syokota for (i = 0; i < NUM_DEADKEYS; i++) { 70432316Syokota printf(" /* %s=%d */\n {", acc_names[i], i); 70532316Syokota c = accentmap->acc[i].accchar; 70632316Syokota if (c == '\'') 70732316Syokota printf(" '\\'', {"); 70832316Syokota else if (c == '\\') 70932316Syokota printf(" '\\\\', {"); 71032316Syokota else if (isascii(c) && isprint(c)) 71132316Syokota printf(" '%c', {", c); 71232316Syokota else if (c == 0) { 71332316Syokota printf(" 0x00 }, \n"); 71432316Syokota continue; 71532316Syokota } else 71632316Syokota printf(" 0x%02x, {", c); 71732316Syokota for (j = 0; j < NUM_ACCENTCHARS; j++) { 71832316Syokota c = accentmap->acc[i].map[j][0]; 71932316Syokota if (c == 0) 72032316Syokota break; 72132316Syokota if ((j > 0) && ((j % 4) == 0)) 72232316Syokota printf("\n\t "); 72332316Syokota if (isascii(c) && isprint(c)) 72432316Syokota printf(" { '%c',", c); 72532316Syokota else 72632316Syokota printf(" { 0x%02x,", c); 72732316Syokota printf("0x%02x },", accentmap->acc[i].map[j][1]); 72832316Syokota } 72932316Syokota printf(" }, },\n"); 73032316Syokota } 73132486Syokota printf("} };\n\n"); 73232316Syokota} 73332316Syokota 73432316Syokotavoid 73519569Sjoergload_keymap(char *opt, int dumponly) 7362088Ssos{ 73732316Syokota keymap_t keymap; 73832316Syokota accentmap_t accentmap; 7392088Ssos FILE *fd; 74032316Syokota int i; 74119569Sjoerg char *name, *cp; 74235750Sdes char *prefix[] = {"", "", KEYMAP_PATH, KEYMAP_PATH, NULL}; 74335750Sdes char *postfix[] = {"", ".kbd", "", ".kbd"}; 7442088Ssos 7452088Ssos for (i=0; prefix[i]; i++) { 7462088Ssos name = mkfullname(prefix[i], opt, postfix[i]); 74729603Scharnier if ((fd = fopen(name, "r"))) 7482088Ssos break; 7492088Ssos } 7502088Ssos if (fd == NULL) { 75129603Scharnier warn("keymap file not found"); 7522088Ssos return; 7532088Ssos } 75432316Syokota memset(&keymap, 0, sizeof(keymap)); 75532316Syokota memset(&accentmap, 0, sizeof(accentmap)); 75632316Syokota token = -1; 7572088Ssos while (1) { 75832316Syokota if (get_definition_line(fd, &keymap, &accentmap) < 0) 7592088Ssos break; 7602088Ssos } 76119569Sjoerg if (dumponly) { 76219569Sjoerg /* fix up the filename to make it a valid C identifier */ 76319569Sjoerg for (cp = opt; *cp; cp++) 76419569Sjoerg if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_'; 76532316Syokota printf("/*\n" 76632316Syokota " * Automatically generated from %s.\n" 76732316Syokota " * DO NOT EDIT!\n" 76832316Syokota " */\n", name); 76932316Syokota dump_key_definition(opt, &keymap); 77032316Syokota dump_accent_definition(opt, &accentmap); 77119569Sjoerg return; 77219569Sjoerg } 77332316Syokota if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) { 77429603Scharnier warn("setting keymap"); 7752088Ssos fclose(fd); 7762088Ssos return; 7772088Ssos } 77832316Syokota if ((accentmap.n_accs > 0) 77932316Syokota && (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) { 78032316Syokota warn("setting accentmap"); 78132316Syokota fclose(fd); 78232316Syokota return; 78332316Syokota } 7842088Ssos} 7852088Ssos 7862088Ssosvoid 7872088Ssosprint_keymap() 7882088Ssos{ 78932316Syokota keymap_t keymap; 79032316Syokota accentmap_t accentmap; 7912088Ssos int i; 7922088Ssos 79332316Syokota if (ioctl(0, GIO_KEYMAP, &keymap) < 0) 79429603Scharnier err(1, "getting keymap"); 79532316Syokota if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0) 79632316Syokota memset(&accentmap, 0, sizeof(accentmap)); 7972088Ssos printf( 7982088Ssos"# alt\n" 7992088Ssos"# scan cntrl alt alt cntrl lock\n" 8002088Ssos"# code base shift cntrl shift alt shift cntrl shift state\n" 8012088Ssos"# ------------------------------------------------------------------\n" 8022088Ssos ); 80332316Syokota for (i=0; i<keymap.n_keys; i++) 80432316Syokota print_key_definition_line(stdout, i, &keymap.key[i]); 80532316Syokota 80632316Syokota printf("\n"); 80732316Syokota for (i = 0; i < NUM_DEADKEYS; i++) 80832316Syokota print_accent_definition_line(stdout, i, &accentmap.acc[i]); 80932316Syokota 8102088Ssos} 8112088Ssos 8122088Ssos 8132088Ssosvoid 8142088Ssosload_default_functionkeys() 8152088Ssos{ 8162088Ssos fkeyarg_t fkey; 8172088Ssos int i; 8182088Ssos 8192088Ssos for (i=0; i<NUM_FKEYS; i++) { 8202088Ssos fkey.keynum = i; 8212088Ssos strcpy(fkey.keydef, fkey_table[i]); 8222088Ssos fkey.flen = strlen(fkey_table[i]); 8232088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 82429603Scharnier warn("setting function key"); 8252088Ssos } 8262088Ssos} 8272088Ssos 8282088Ssosvoid 8292088Ssosset_functionkey(char *keynumstr, char *string) 8302088Ssos{ 8312088Ssos fkeyarg_t fkey; 8322088Ssos 8332088Ssos if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) { 8342088Ssos load_default_functionkeys(); 8352088Ssos return; 8362088Ssos } 8372088Ssos fkey.keynum = atoi(keynumstr); 8382088Ssos if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) { 83929603Scharnier warnx("function key number must be between 1 and %d", 8402088Ssos NUM_FKEYS); 8412088Ssos return; 8422088Ssos } 8432088Ssos if ((fkey.flen = strlen(string)) > MAXFK) { 84429603Scharnier warnx("function key string too long (%d > %d)", 8452088Ssos fkey.flen, MAXFK); 8462088Ssos return; 8472088Ssos } 8482088Ssos strcpy(fkey.keydef, string); 8492088Ssos fkey.keynum -= 1; 8502088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 85129603Scharnier warn("setting function key"); 8522088Ssos} 8532088Ssos 8542088Ssos 8552088Ssosvoid 8562088Ssosset_bell_values(char *opt) 8572088Ssos{ 8585536Ssos int bell, duration, pitch; 8592088Ssos 86038044Syokota bell = 0; 86138044Syokota if (!strncmp(opt, "quiet.", 6)) { 86238044Syokota bell = 2; 86338044Syokota opt += 6; 86438044Syokota } 8658857Srgrimes if (!strcmp(opt, "visual")) 86638044Syokota bell |= 1; 8675536Ssos else if (!strcmp(opt, "normal")) 86838044Syokota duration = 5, pitch = 800; 86948982Syokota else if (!strcmp(opt, "off")) 87048982Syokota duration = 0, pitch = 0; 8712088Ssos else { 8722088Ssos char *v1; 8738857Srgrimes 8745536Ssos bell = 0; 8752088Ssos duration = strtol(opt, &v1, 0); 8762088Ssos if ((duration < 0) || (*v1 != '.')) 8772088Ssos goto badopt; 8782088Ssos opt = ++v1; 8792088Ssos pitch = strtol(opt, &v1, 0); 8802088Ssos if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) { 8812088Ssosbadopt: 88229603Scharnier warnx("argument to -b must be DURATION.PITCH"); 8832088Ssos return; 8842088Ssos } 88538044Syokota if (pitch != 0) 88638044Syokota pitch = 1193182 / pitch; /* in Hz */ 88738044Syokota duration /= 10; /* in 10 m sec */ 8882088Ssos } 8892088Ssos 8905536Ssos ioctl(0, CONS_BELLTYPE, &bell); 89138044Syokota if ((bell & ~2) == 0) 8925536Ssos fprintf(stderr, "[=%d;%dB", pitch, duration); 8932088Ssos} 8942088Ssos 8952088Ssos 8962088Ssosvoid 8972088Ssosset_keyrates(char *opt) 8982088Ssos{ 89944628Syokota int arg[2]; 90039047Syokota int repeat; 90139047Syokota int delay; 90246761Syokota int r, d; 9032088Ssos 90446761Syokota if (!strcmp(opt, "slow")) { 90544628Syokota delay = 1000, repeat = 500; 90646761Syokota d = 3, r = 31; 90746761Syokota } else if (!strcmp(opt, "normal")) { 90844628Syokota delay = 500, repeat = 125; 90946761Syokota d = 1, r = 15; 91046761Syokota } else if (!strcmp(opt, "fast")) { 91139047Syokota delay = repeat = 0; 91246761Syokota d = r = 0; 91346761Syokota } else { 9142088Ssos int n; 9152088Ssos char *v1; 9162088Ssos 9172088Ssos delay = strtol(opt, &v1, 0); 9182088Ssos if ((delay < 0) || (*v1 != '.')) 9192088Ssos goto badopt; 9202088Ssos opt = ++v1; 9212088Ssos repeat = strtol(opt, &v1, 0); 9222088Ssos if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) { 9232088Ssosbadopt: 92429603Scharnier warnx("argument to -r must be delay.repeat"); 9252088Ssos return; 9262088Ssos } 92746761Syokota for (n = 0; n < ndelays - 1; n++) 92846761Syokota if (delay <= delays[n]) 92946761Syokota break; 93046761Syokota d = n; 93146761Syokota for (n = 0; n < nrepeats - 1; n++) 93246761Syokota if (repeat <= repeats[n]) 93346761Syokota break; 93446761Syokota r = n; 9352088Ssos } 9362088Ssos 93744628Syokota arg[0] = delay; 93844628Syokota arg[1] = repeat; 93946761Syokota if (ioctl(0, KDSETREPEAT, arg)) { 94046761Syokota if (ioctl(0, KDSETRAD, (d << 5) | r)) 94146761Syokota warn("setting keyboard rate"); 94246761Syokota } 9432088Ssos} 9442088Ssos 9452088Ssos 9466046Ssosvoid 9476046Ssosset_history(char *opt) 9486046Ssos{ 9496046Ssos int size; 9506046Ssos 9516046Ssos size = atoi(opt); 9526046Ssos if ((*opt == '\0') || size < 0) { 95329603Scharnier warnx("argument must be a positive number"); 9546046Ssos return; 9556046Ssos } 9566046Ssos if (ioctl(0, CONS_HISTORY, &size) == -1) 95729603Scharnier warn("setting history buffer size"); 9586046Ssos} 9596046Ssos 96042505Syokotastatic char 96142505Syokota*get_kbd_type_name(int type) 96242505Syokota{ 96342505Syokota static struct { 96442505Syokota int type; 96542505Syokota char *name; 96642505Syokota } name_table[] = { 96742505Syokota { KB_84, "AT 84" }, 96842505Syokota { KB_101, "AT 101/102" }, 96942505Syokota { KB_OTHER, "generic" }, 97042505Syokota }; 97142505Syokota int i; 9726046Ssos 97342505Syokota for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) { 97442505Syokota if (type == name_table[i].type) 97542505Syokota return name_table[i].name; 97642505Syokota } 97742505Syokota return "unknown"; 97842505Syokota} 97942505Syokota 98042505Syokotavoid 98142505Syokotashow_kbd_info(void) 98242505Syokota{ 98342505Syokota keyboard_info_t info; 98442505Syokota 98542505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 98642505Syokota warn("unable to obtain keyboard information"); 98742505Syokota return; 98842505Syokota } 98942505Syokota printf("kbd%d:\n", info.kb_index); 99042505Syokota printf(" %.*s%d, type:%s (%d)\n", 99142505Syokota sizeof(info.kb_name), info.kb_name, info.kb_unit, 99242505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 99342505Syokota} 99442505Syokota 99542505Syokota 99642505Syokotavoid 99742505Syokotaset_keyboard(char *device) 99842505Syokota{ 99942505Syokota keyboard_info_t info; 100042505Syokota int fd; 100142505Syokota 100242505Syokota fd = open(device, O_RDONLY); 100342505Syokota if (fd < 0) { 100442505Syokota warn("cannot open %s", device); 100542505Syokota return; 100642505Syokota } 100742505Syokota if (ioctl(fd, KDGKBINFO, &info) == -1) { 100842505Syokota warn("unable to obtain keyboard information"); 100942505Syokota close(fd); 101042505Syokota return; 101142505Syokota } 101242505Syokota /* 101342505Syokota * The keyboard device driver won't release the keyboard by 101442505Syokota * the following ioctl, but it automatically will, when the device 101542505Syokota * is closed. So, we don't check error here. 101642505Syokota */ 101742505Syokota ioctl(fd, CONS_RELKBD, 0); 101842505Syokota close(fd); 101942505Syokota#if 1 102042505Syokota printf("kbd%d\n", info.kb_index); 102142505Syokota printf(" %.*s%d, type:%s (%d)\n", 102242505Syokota sizeof(info.kb_name), info.kb_name, info.kb_unit, 102342505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 102442505Syokota#endif 102542505Syokota 102642505Syokota if (ioctl(0, CONS_SETKBD, info.kb_index) == -1) 102742505Syokota warn("unable to set keyboard"); 102842505Syokota} 102942505Syokota 103042505Syokota 103142505Syokotavoid 103242505Syokotarelease_keyboard(void) 103342505Syokota{ 103442505Syokota keyboard_info_t info; 103542505Syokota 103642505Syokota /* 103742505Syokota * If stdin is not associated with a keyboard, the following ioctl 103842505Syokota * will fail. 103942505Syokota */ 104042505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 104142505Syokota warn("unable to obtain keyboard information"); 104242505Syokota return; 104342505Syokota } 104442505Syokota#if 1 104542505Syokota printf("kbd%d\n", info.kb_index); 104642505Syokota printf(" %.*s%d, type:%s (%d)\n", 104742505Syokota sizeof(info.kb_name), info.kb_name, info.kb_unit, 104842505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 104942505Syokota#endif 105042505Syokota if (ioctl(0, CONS_RELKBD, 0) == -1) 105142505Syokota warn("unable to release the keyboard"); 105242505Syokota} 105342505Syokota 105442505Syokota 105529603Scharnierstatic void 10562088Ssosusage() 10572088Ssos{ 105829603Scharnier fprintf(stderr, "%s\n%s\n%s\n", 105942505Syokota"usage: kbdcontrol [-dFKix] [-b duration.pitch | [quiet.]belltype]", 106029603Scharnier" [-r delay.repeat | speed] [-l mapfile] [-f # string]", 106142505Syokota" [-h size] [-k device] [-L mapfile]"); 106229603Scharnier exit(1); 10632088Ssos} 10642088Ssos 10652088Ssos 106651287Speterint 10672088Ssosmain(int argc, char **argv) 10682088Ssos{ 10692088Ssos int opt; 10702088Ssos 107142505Syokota while((opt = getopt(argc, argv, "b:df:h:iKk:Fl:L:r:x")) != -1) 10722088Ssos switch(opt) { 10732088Ssos case 'b': 10742088Ssos set_bell_values(optarg); 10752088Ssos break; 10762088Ssos case 'd': 10772088Ssos print_keymap(); 10782088Ssos break; 10792088Ssos case 'l': 108019569Sjoerg load_keymap(optarg, 0); 10812088Ssos break; 108219569Sjoerg case 'L': 108319569Sjoerg load_keymap(optarg, 1); 108419569Sjoerg break; 10852088Ssos case 'f': 10868857Srgrimes set_functionkey(optarg, 10872088Ssos nextarg(argc, argv, &optind, 'f')); 10882088Ssos break; 10892088Ssos case 'F': 10902088Ssos load_default_functionkeys(); 10912088Ssos break; 10926046Ssos case 'h': 10936046Ssos set_history(optarg); 10946046Ssos break; 109542505Syokota case 'i': 109642505Syokota show_kbd_info(); 109742505Syokota break; 109842505Syokota case 'K': 109942505Syokota release_keyboard(); 110042505Syokota break; 110142505Syokota case 'k': 110242505Syokota set_keyboard(optarg); 110342505Syokota break; 11042088Ssos case 'r': 11052088Ssos set_keyrates(optarg); 11062088Ssos break; 11072088Ssos case 'x': 11082088Ssos hex = 1; 11092088Ssos break; 11102088Ssos default: 11112088Ssos usage(); 11122088Ssos } 111329603Scharnier if ((optind != argc) || (argc == 1)) 11142088Ssos usage(); 11152088Ssos exit(0); 11162088Ssos} 11172088Ssos 11182088Ssos 1119