kbdcontrol.c revision 266839
12088Ssos/*- 2228976Suqs * 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 1597748Sschweikh * derived from this software without 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 29114601Sobrien#include <sys/cdefs.h> 30114601Sobrien__FBSDID("$FreeBSD: head/usr.sbin/kbdcontrol/kbdcontrol.c 266839 2014-05-29 14:39:25Z ray $"); 3129603Scharnier 322088Ssos#include <ctype.h> 3329603Scharnier#include <err.h> 342088Ssos#include <stdio.h> 3529603Scharnier#include <stdlib.h> 363864Sswallace#include <string.h> 3729603Scharnier#include <unistd.h> 3842505Syokota#include <fcntl.h> 3966834Sphk#include <sys/kbio.h> 4066834Sphk#include <sys/consio.h> 41266839Sray#include <sys/sysctl.h> 422088Ssos#include "path.h" 432088Ssos#include "lex.h" 442088Ssos 4576643Simp/* 4690394Sru * HALT, PDWN, and PASTE aren't defined in 4.x, but we need them to bridge 4790394Sru * to 5.0-current so define them here as a stop gap transition measure. 4876643Simp */ 4990394Sru#ifndef HALT 5090394Sru#define HALT 0xa1 /* halt machine */ 5190394Sru#endif 5290394Sru#ifndef PDWN 5390394Sru#define PDWN 0xa2 /* halt machine and power down */ 5490394Sru#endif 5576643Simp#ifndef PASTE 5676643Simp#define PASTE 0xa3 /* paste from cut-paste buffer */ 5776643Simp#endif 5876643Simp 59196500Sed#define SPECIAL 0x80000000 60196500Sed 61228437Sedstatic const char ctrl_names[32][4] = { 628857Srgrimes "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 632088Ssos "bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ", 642088Ssos "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 6538139Syokota "can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "us " 662088Ssos }; 672088Ssos 68228437Sedstatic const char acc_names[15][5] = { 6932316Syokota "dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot", 7032316Syokota "duml", "dsla", "drin", "dced", "dapo", "ddac", "dogo", 7132316Syokota "dcar", 7232316Syokota }; 7332316Syokota 74228437Sedstatic const char acc_names_u[15][5] = { 7532316Syokota "DGRA", "DACU", "DCIR", "DTIL", "DMAC", "DBRE", "DDOT", 7632316Syokota "DUML", "DSLA", "DRIN", "DCED", "DAPO", "DDAC", "DOGO", 7732316Syokota "DCAR", 7832316Syokota }; 7932316Syokota 80228437Sedstatic const char fkey_table[96][MAXFK] = { 815994Ssos/* 01-04 */ "\033[M", "\033[N", "\033[O", "\033[P", 825994Ssos/* 05-08 */ "\033[Q", "\033[R", "\033[S", "\033[T", 835994Ssos/* 09-12 */ "\033[U", "\033[V", "\033[W", "\033[X", 845994Ssos/* 13-16 */ "\033[Y", "\033[Z", "\033[a", "\033[b", 855994Ssos/* 17-20 */ "\033[c", "\033[d", "\033[e", "\033[f", 865994Ssos/* 21-24 */ "\033[g", "\033[h", "\033[i", "\033[j", 875994Ssos/* 25-28 */ "\033[k", "\033[l", "\033[m", "\033[n", 885994Ssos/* 29-32 */ "\033[o", "\033[p", "\033[q", "\033[r", 895994Ssos/* 33-36 */ "\033[s", "\033[t", "\033[u", "\033[v", 905994Ssos/* 37-40 */ "\033[w", "\033[x", "\033[y", "\033[z", 915994Ssos/* 41-44 */ "\033[@", "\033[[", "\033[\\","\033[]", 929202Srgrimes/* 45-48 */ "\033[^", "\033[_", "\033[`", "\033[{", 935994Ssos/* 49-52 */ "\033[H", "\033[A", "\033[I", "-" , 945994Ssos/* 53-56 */ "\033[D", "\033[E", "\033[C", "+" , 955994Ssos/* 57-60 */ "\033[F", "\033[B", "\033[G", "\033[L", 969202Srgrimes/* 61-64 */ "\177", "\033[J", "\033[~", "\033[}", 975994Ssos/* 65-68 */ "" , "" , "" , "" , 985994Ssos/* 69-72 */ "" , "" , "" , "" , 995994Ssos/* 73-76 */ "" , "" , "" , "" , 1005994Ssos/* 77-80 */ "" , "" , "" , "" , 1015994Ssos/* 81-84 */ "" , "" , "" , "" , 1025994Ssos/* 85-88 */ "" , "" , "" , "" , 1035994Ssos/* 89-92 */ "" , "" , "" , "" , 1045994Ssos/* 93-96 */ "" , "" , "" , "" , 1052088Ssos }; 1062088Ssos 107228437Sedstatic const int delays[] = {250, 500, 750, 1000}; 108228437Sedstatic const int repeats[] = { 34, 38, 42, 46, 50, 55, 59, 63, 109228437Sed 68, 76, 84, 92, 100, 110, 118, 126, 110228437Sed 136, 152, 168, 184, 200, 220, 236, 252, 111228437Sed 272, 304, 336, 368, 400, 440, 472, 504}; 112228437Sedstatic const int ndelays = (sizeof(delays) / sizeof(int)); 113228437Sedstatic const int nrepeats = (sizeof(repeats) / sizeof(int)); 114228437Sedstatic int hex = 0; 115228437Sedstatic int token; 1162088Ssos 117228437Sedint number; 118228437Sedchar letter; 1192088Ssos 120228437Sedstatic void dump_accent_definition(char *name, accentmap_t *accentmap); 121228437Sedstatic void dump_entry(int value); 122228437Sedstatic void dump_key_definition(char *name, keymap_t *keymap); 123228437Sedstatic int get_accent_definition_line(accentmap_t *); 124228437Sedstatic int get_entry(void); 125228437Sedstatic int get_key_definition_line(keymap_t *); 126228437Sedstatic void load_keymap(char *opt, int dumponly); 127228437Sedstatic void load_default_functionkeys(void); 128228437Sedstatic char * nextarg(int ac, char **av, int *indp, int oc); 129228437Sedstatic char * mkfullname(const char *s1, const char *s2, const char *s3); 130228437Sedstatic void print_accent_definition_line(FILE *fp, int accent, 131228437Sed struct acc_t *key); 132228437Sedstatic void print_entry(FILE *fp, int value); 133228437Sedstatic void print_key_definition_line(FILE *fp, int scancode, 134228437Sed struct keyent_t *key); 135228437Sedstatic void print_keymap(void); 136228437Sedstatic void release_keyboard(void); 137228437Sedstatic void mux_keyboard(u_int op, char *kbd); 138228437Sedstatic void set_bell_values(char *opt); 139228437Sedstatic void set_functionkey(char *keynumstr, char *string); 140228437Sedstatic void set_keyboard(char *device); 141228437Sedstatic void set_keyrates(char *opt); 142228437Sedstatic void show_kbd_info(void); 143228437Sedstatic void usage(void) __dead2; 144228437Sed 145266839Sray/* Detect presence of vt(4). */ 146266839Sraystatic int 147266839Srayis_vt4(void) 148266839Sray{ 149266839Sray 150266839Sray if (sysctlbyname("kern.vt.deadtimer", NULL, NULL, NULL, 0) == 0) 151266839Sray return (1); 152266839Sray 153266839Sray return (0); 154266839Sray} 155266839Sray 156228437Sedstatic char * 1572088Ssosnextarg(int ac, char **av, int *indp, int oc) 1582088Ssos{ 1592088Ssos if (*indp < ac) 1602088Ssos return(av[(*indp)++]); 16129603Scharnier warnx("option requires two arguments -- %c", oc); 1622088Ssos usage(); 1632088Ssos} 1642088Ssos 1652088Ssos 166228437Sedstatic char * 1672088Ssosmkfullname(const char *s1, const char *s2, const char *s3) 1682088Ssos{ 1695536Ssos static char *buf = NULL; 1705536Ssos static int bufl = 0; 1715536Ssos int f; 1722088Ssos 1732088Ssos f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 17477394Ssobomax if (f > bufl) { 1752088Ssos if (buf) 1762088Ssos buf = (char *)realloc(buf, f); 1772088Ssos else 1782088Ssos buf = (char *)malloc(f); 17977394Ssobomax } 1802088Ssos if (!buf) { 1812088Ssos bufl = 0; 1822088Ssos return(NULL); 1832088Ssos } 1842088Ssos 1852088Ssos bufl = f; 1862088Ssos strcpy(buf, s1); 1872088Ssos strcat(buf, s2); 1882088Ssos strcat(buf, s3); 1892088Ssos return(buf); 1902088Ssos} 1912088Ssos 1922088Ssos 193228437Sedstatic int 19499816Salfredget_entry(void) 1952088Ssos{ 19632316Syokota switch ((token = yylex())) { 1972088Ssos case TNOP: 198196500Sed return NOP | SPECIAL; 1992088Ssos case TLSH: 200196500Sed return LSH | SPECIAL; 2012088Ssos case TRSH: 202196500Sed return RSH | SPECIAL; 2032088Ssos case TCLK: 204196500Sed return CLK | SPECIAL; 2052088Ssos case TNLK: 206196500Sed return NLK | SPECIAL; 2072088Ssos case TSLK: 208196500Sed return SLK | SPECIAL; 2092088Ssos case TBTAB: 210196500Sed return BTAB | SPECIAL; 2112088Ssos case TLALT: 212196500Sed return LALT | SPECIAL; 2132088Ssos case TLCTR: 214196500Sed return LCTR | SPECIAL; 2152088Ssos case TNEXT: 216196500Sed return NEXT | SPECIAL; 21748105Syokota case TPREV: 218196500Sed return PREV | SPECIAL; 2192088Ssos case TRCTR: 220196500Sed return RCTR | SPECIAL; 2212088Ssos case TRALT: 222196500Sed return RALT | SPECIAL; 2232088Ssos case TALK: 224196500Sed return ALK | SPECIAL; 2252088Ssos case TASH: 226196500Sed return ASH | SPECIAL; 2272088Ssos case TMETA: 228196500Sed return META | SPECIAL; 2292088Ssos case TRBT: 230196500Sed return RBT | SPECIAL; 2312088Ssos case TDBG: 232196500Sed return DBG | SPECIAL; 2335994Ssos case TSUSP: 234196500Sed return SUSP | SPECIAL; 23538053Syokota case TSPSC: 236196500Sed return SPSC | SPECIAL; 23754380Syokota case TPANIC: 238196500Sed return PNC | SPECIAL; 23954380Syokota case TLSHA: 240196500Sed return LSHA | SPECIAL; 24154380Syokota case TRSHA: 242196500Sed return RSHA | SPECIAL; 24354380Syokota case TLCTRA: 244196500Sed return LCTRA | SPECIAL; 24554380Syokota case TRCTRA: 246196500Sed return RCTRA | SPECIAL; 24754380Syokota case TLALTA: 248196500Sed return LALTA | SPECIAL; 24954380Syokota case TRALTA: 250196500Sed return RALTA | SPECIAL; 25165759Sdwmalone case THALT: 252196500Sed return HALT | SPECIAL; 25365759Sdwmalone case TPDWN: 254196500Sed return PDWN | SPECIAL; 25574118Sache case TPASTE: 256196500Sed return PASTE | SPECIAL; 25732316Syokota case TACC: 25832316Syokota if (ACC(number) > L_ACC) 25932316Syokota return -1; 260196500Sed return ACC(number) | SPECIAL; 2612088Ssos case TFUNC: 2622088Ssos if (F(number) > L_FN) 2632088Ssos return -1; 264196500Sed return F(number) | SPECIAL; 2652088Ssos case TSCRN: 2662088Ssos if (S(number) > L_SCR) 2672088Ssos return -1; 268196500Sed return S(number) | SPECIAL; 2692088Ssos case TLET: 2702088Ssos return (unsigned char)letter; 2712088Ssos case TNUM: 272197330Sed if (number < 0x000000 || number > 0x10FFFF) 2732088Ssos return -1; 2742088Ssos return number; 2752088Ssos default: 2762088Ssos return -1; 2772088Ssos } 2782088Ssos} 2792088Ssos 28077394Ssobomaxstatic int 28132316Syokotaget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap) 2822088Ssos{ 28332316Syokota int c; 2842088Ssos 2852088Ssos yyin = fd; 2862088Ssos 28732316Syokota if (token < 0) 28832316Syokota token = yylex(); 28932316Syokota switch (token) { 29032316Syokota case TNUM: 29132316Syokota c = get_key_definition_line(keymap); 29232316Syokota if (c < 0) 29332316Syokota errx(1, "invalid key definition"); 29432316Syokota if (c > keymap->n_keys) 29532316Syokota keymap->n_keys = c; 29632316Syokota break; 29732316Syokota case TACC: 29832316Syokota c = get_accent_definition_line(accentmap); 29932316Syokota if (c < 0) 30032316Syokota errx(1, "invalid accent key definition"); 30132316Syokota if (c > accentmap->n_accs) 30232316Syokota accentmap->n_accs = c; 30332316Syokota break; 30432316Syokota case 0: 30532316Syokota /* EOF */ 3062088Ssos return -1; 30732316Syokota default: 30832316Syokota errx(1, "illegal definition line"); 30932316Syokota } 31032316Syokota return c; 31132316Syokota} 31232316Syokota 313228437Sedstatic int 31432316Syokotaget_key_definition_line(keymap_t *map) 31532316Syokota{ 31632316Syokota int i, def, scancode; 31732316Syokota 31832316Syokota /* check scancode number */ 3192088Ssos if (number < 0 || number >= NUM_KEYS) 3202088Ssos return -1; 3212088Ssos scancode = number; 3222088Ssos 3232088Ssos /* get key definitions */ 3242088Ssos map->key[scancode].spcl = 0; 3252088Ssos for (i=0; i<NUM_STATES; i++) { 3262088Ssos if ((def = get_entry()) == -1) 3272088Ssos return -1; 328196500Sed if (def & SPECIAL) 3292088Ssos map->key[scancode].spcl |= (0x80 >> i); 330196500Sed map->key[scancode].map[i] = def & ~SPECIAL; 3312088Ssos } 3322088Ssos /* get lock state key def */ 33332316Syokota if ((token = yylex()) != TFLAG) 3342088Ssos return -1; 3352088Ssos map->key[scancode].flgs = number; 33632316Syokota token = yylex(); 33732316Syokota return (scancode + 1); 3382088Ssos} 3392088Ssos 340228437Sedstatic int 34132316Syokotaget_accent_definition_line(accentmap_t *map) 34232316Syokota{ 34332316Syokota int accent; 34432316Syokota int c1, c2; 34532316Syokota int i; 3462088Ssos 34732316Syokota if (ACC(number) < F_ACC || ACC(number) > L_ACC) 34832316Syokota /* number out of range */ 34932316Syokota return -1; 35032316Syokota accent = number; 35132316Syokota if (map->acc[accent].accchar != 0) { 35232316Syokota /* this entry has already been defined before! */ 35332316Syokota errx(1, "duplicated accent key definition"); 35432316Syokota } 35532316Syokota 35632316Syokota switch ((token = yylex())) { 35732316Syokota case TLET: 35832316Syokota map->acc[accent].accchar = letter; 35932316Syokota break; 36032316Syokota case TNUM: 36132316Syokota map->acc[accent].accchar = number; 36232316Syokota break; 36332316Syokota default: 36432316Syokota return -1; 36532316Syokota } 36632316Syokota 36732316Syokota for (i = 0; (token = yylex()) == '(';) { 36832316Syokota switch ((token = yylex())) { 36932316Syokota case TLET: 37032316Syokota c1 = letter; 37132316Syokota break; 37232316Syokota case TNUM: 37332316Syokota c1 = number; 37432316Syokota break; 37532316Syokota default: 37632316Syokota return -1; 37732316Syokota } 37832316Syokota switch ((token = yylex())) { 37932316Syokota case TLET: 38032316Syokota c2 = letter; 38132316Syokota break; 38232316Syokota case TNUM: 38332316Syokota c2 = number; 38432316Syokota break; 38532316Syokota default: 38632316Syokota return -1; 38732316Syokota } 38832316Syokota if ((token = yylex()) != ')') 38932316Syokota return -1; 39032316Syokota if (i >= NUM_ACCENTCHARS) { 39132316Syokota warnx("too many accented characters, ignored"); 39232316Syokota continue; 39332316Syokota } 39432316Syokota map->acc[accent].map[i][0] = c1; 39532316Syokota map->acc[accent].map[i][1] = c2; 39632316Syokota ++i; 39732316Syokota } 39832316Syokota return (accent + 1); 39932316Syokota} 40032316Syokota 401228437Sedstatic void 4022088Ssosprint_entry(FILE *fp, int value) 4032088Ssos{ 404196500Sed int val = value & ~SPECIAL; 4052088Ssos 4062088Ssos switch (value) { 407196500Sed case NOP | SPECIAL: 4088857Srgrimes fprintf(fp, " nop "); 4092088Ssos break; 410196500Sed case LSH | SPECIAL: 4112088Ssos fprintf(fp, " lshift"); 4122088Ssos break; 413196500Sed case RSH | SPECIAL: 4142088Ssos fprintf(fp, " rshift"); 4152088Ssos break; 416196500Sed case CLK | SPECIAL: 4172088Ssos fprintf(fp, " clock "); 4182088Ssos break; 419196500Sed case NLK | SPECIAL: 4202088Ssos fprintf(fp, " nlock "); 4212088Ssos break; 422196500Sed case SLK | SPECIAL: 4232088Ssos fprintf(fp, " slock "); 4242088Ssos break; 425196500Sed case BTAB | SPECIAL: 4262088Ssos fprintf(fp, " btab "); 4272088Ssos break; 428196500Sed case LALT | SPECIAL: 4292088Ssos fprintf(fp, " lalt "); 4302088Ssos break; 431196500Sed case LCTR | SPECIAL: 4322088Ssos fprintf(fp, " lctrl "); 4332088Ssos break; 434196500Sed case NEXT | SPECIAL: 4352088Ssos fprintf(fp, " nscr "); 4362088Ssos break; 437196500Sed case PREV | SPECIAL: 43848105Syokota fprintf(fp, " pscr "); 43948105Syokota break; 440196500Sed case RCTR | SPECIAL: 4412088Ssos fprintf(fp, " rctrl "); 4422088Ssos break; 443196500Sed case RALT | SPECIAL: 4442088Ssos fprintf(fp, " ralt "); 4452088Ssos break; 446196500Sed case ALK | SPECIAL: 4472088Ssos fprintf(fp, " alock "); 4482088Ssos break; 449196500Sed case ASH | SPECIAL: 4502088Ssos fprintf(fp, " ashift"); 4512088Ssos break; 452196500Sed case META | SPECIAL: 4532088Ssos fprintf(fp, " meta "); 4542088Ssos break; 455196500Sed case RBT | SPECIAL: 4562088Ssos fprintf(fp, " boot "); 4572088Ssos break; 458196500Sed case DBG | SPECIAL: 4592088Ssos fprintf(fp, " debug "); 4602088Ssos break; 461196500Sed case SUSP | SPECIAL: 46232316Syokota fprintf(fp, " susp "); 46332316Syokota break; 464196500Sed case SPSC | SPECIAL: 46538053Syokota fprintf(fp, " saver "); 46638053Syokota break; 467196500Sed case PNC | SPECIAL: 46854380Syokota fprintf(fp, " panic "); 46954380Syokota break; 470196500Sed case LSHA | SPECIAL: 47154380Syokota fprintf(fp, " lshifta"); 47254380Syokota break; 473196500Sed case RSHA | SPECIAL: 47454380Syokota fprintf(fp, " rshifta"); 47554380Syokota break; 476196500Sed case LCTRA | SPECIAL: 47754380Syokota fprintf(fp, " lctrla"); 47854380Syokota break; 479196500Sed case RCTRA | SPECIAL: 48054380Syokota fprintf(fp, " rctrla"); 48154380Syokota break; 482196500Sed case LALTA | SPECIAL: 48354380Syokota fprintf(fp, " lalta "); 48454380Syokota break; 485196500Sed case RALTA | SPECIAL: 48654380Syokota fprintf(fp, " ralta "); 48754380Syokota break; 488196500Sed case HALT | SPECIAL: 48965759Sdwmalone fprintf(fp, " halt "); 49065759Sdwmalone break; 491196500Sed case PDWN | SPECIAL: 49265759Sdwmalone fprintf(fp, " pdwn "); 49365759Sdwmalone break; 494196500Sed case PASTE | SPECIAL: 49574118Sache fprintf(fp, " paste "); 49674118Sache break; 4972088Ssos default: 498196500Sed if (value & SPECIAL) { 4998857Srgrimes if (val >= F_FN && val <= L_FN) 5002088Ssos fprintf(fp, " fkey%02d", val - F_FN + 1); 5018857Srgrimes else if (val >= F_SCR && val <= L_SCR) 5022088Ssos fprintf(fp, " scr%02d ", val - F_SCR + 1); 50332316Syokota else if (val >= F_ACC && val <= L_ACC) 50432316Syokota fprintf(fp, " %-6s", acc_names[val - F_ACC]); 5052088Ssos else if (hex) 5068857Srgrimes fprintf(fp, " 0x%02x ", val); 5072088Ssos else 50832316Syokota fprintf(fp, " %3d ", val); 5092088Ssos } 5102088Ssos else { 5112088Ssos if (val < ' ') 5128857Srgrimes fprintf(fp, " %s ", ctrl_names[val]); 5132088Ssos else if (val == 127) 5148857Srgrimes fprintf(fp, " del "); 5159202Srgrimes else if (isascii(val) && isprint(val)) 5168857Srgrimes fprintf(fp, " '%c' ", val); 5172088Ssos else if (hex) 5188857Srgrimes fprintf(fp, " 0x%02x ", val); 5192088Ssos else 5208857Srgrimes fprintf(fp, " %3d ", val); 5212088Ssos } 5222088Ssos } 5232088Ssos} 5242088Ssos 525228437Sedstatic void 52642505Syokotaprint_key_definition_line(FILE *fp, int scancode, struct keyent_t *key) 5272088Ssos{ 52829603Scharnier int i; 5292088Ssos 5302088Ssos /* print scancode number */ 5312088Ssos if (hex) 5322088Ssos fprintf(fp, " 0x%02x ", scancode); 5332088Ssos else 5342088Ssos fprintf(fp, " %03d ", scancode); 5352088Ssos 5362088Ssos /* print key definitions */ 5372088Ssos for (i=0; i<NUM_STATES; i++) { 5382088Ssos if (key->spcl & (0x80 >> i)) 539196500Sed print_entry(fp, key->map[i] | SPECIAL); 5402088Ssos else 5418857Srgrimes print_entry(fp, key->map[i]); 5422088Ssos } 5432088Ssos 5442088Ssos /* print lock state key def */ 5452088Ssos switch (key->flgs) { 5462088Ssos case 0: 5472088Ssos fprintf(fp, " O\n"); 5482088Ssos break; 5492088Ssos case 1: 5502088Ssos fprintf(fp, " C\n"); 5512088Ssos break; 5522088Ssos case 2: 5532088Ssos fprintf(fp, " N\n"); 5542088Ssos break; 5556046Ssos case 3: 5566046Ssos fprintf(fp, " B\n"); 5576046Ssos break; 5588857Srgrimes } 5592088Ssos} 5602088Ssos 561228437Sedstatic void 56232316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key) 56332316Syokota{ 56432316Syokota int c; 56532316Syokota int i; 5662088Ssos 56732316Syokota if (key->accchar == 0) 56832316Syokota return; 56932316Syokota 57032316Syokota /* print accent number */ 57132316Syokota fprintf(fp, " %-6s", acc_names[accent]); 57232316Syokota if (isascii(key->accchar) && isprint(key->accchar)) 57332316Syokota fprintf(fp, "'%c' ", key->accchar); 57432316Syokota else if (hex) 57532316Syokota fprintf(fp, "0x%02x ", key->accchar); 57632316Syokota else 57732316Syokota fprintf(fp, "%03d ", key->accchar); 57832316Syokota 57932316Syokota for (i = 0; i < NUM_ACCENTCHARS; ++i) { 58032316Syokota c = key->map[i][0]; 58132316Syokota if (c == 0) 58232316Syokota break; 58332316Syokota if ((i > 0) && ((i % 4) == 0)) 58432316Syokota fprintf(fp, "\n "); 58532316Syokota if (isascii(c) && isprint(c)) 58632316Syokota fprintf(fp, "( '%c' ", c); 58732316Syokota else if (hex) 58832316Syokota fprintf(fp, "(0x%02x ", c); 58932316Syokota else 59032316Syokota fprintf(fp, "( %03d ", c); 59132316Syokota c = key->map[i][1]; 59232316Syokota if (isascii(c) && isprint(c)) 59332316Syokota fprintf(fp, "'%c' ) ", c); 59432316Syokota else if (hex) 59532316Syokota fprintf(fp, "0x%02x) ", c); 59632316Syokota else 59732316Syokota fprintf(fp, "%03d ) ", c); 59832316Syokota } 59932316Syokota fprintf(fp, "\n"); 60032316Syokota} 60132316Syokota 602228437Sedstatic void 60332316Syokotadump_entry(int value) 60432316Syokota{ 605196500Sed if (value & SPECIAL) { 606196500Sed value &= ~SPECIAL; 60732316Syokota switch (value) { 60832316Syokota case NOP: 60932316Syokota printf(" NOP, "); 61032316Syokota break; 61132316Syokota case LSH: 61232316Syokota printf(" LSH, "); 61332316Syokota break; 61432316Syokota case RSH: 61532316Syokota printf(" RSH, "); 61632316Syokota break; 61732316Syokota case CLK: 61832316Syokota printf(" CLK, "); 61932316Syokota break; 62032316Syokota case NLK: 62132316Syokota printf(" NLK, "); 62232316Syokota break; 62332316Syokota case SLK: 62432316Syokota printf(" SLK, "); 62532316Syokota break; 62632316Syokota case BTAB: 62732316Syokota printf(" BTAB, "); 62832316Syokota break; 62932316Syokota case LALT: 63032316Syokota printf(" LALT, "); 63132316Syokota break; 63232316Syokota case LCTR: 63332316Syokota printf(" LCTR, "); 63432316Syokota break; 63532316Syokota case NEXT: 63632316Syokota printf(" NEXT, "); 63732316Syokota break; 63848105Syokota case PREV: 63948105Syokota printf(" PREV, "); 64048105Syokota break; 64132316Syokota case RCTR: 64232316Syokota printf(" RCTR, "); 64332316Syokota break; 64432316Syokota case RALT: 64532316Syokota printf(" RALT, "); 64632316Syokota break; 64732316Syokota case ALK: 64832316Syokota printf(" ALK, "); 64932316Syokota break; 65032316Syokota case ASH: 65132316Syokota printf(" ASH, "); 65232316Syokota break; 65332316Syokota case META: 65432316Syokota printf(" META, "); 65532316Syokota break; 65632316Syokota case RBT: 65732316Syokota printf(" RBT, "); 65832316Syokota break; 65932316Syokota case DBG: 66032316Syokota printf(" DBG, "); 66132316Syokota break; 66232316Syokota case SUSP: 66332316Syokota printf(" SUSP, "); 66432316Syokota break; 66538053Syokota case SPSC: 66638053Syokota printf(" SPSC, "); 66738053Syokota break; 66854380Syokota case PNC: 66954380Syokota printf(" PNC, "); 67054380Syokota break; 67154380Syokota case LSHA: 67254380Syokota printf(" LSHA, "); 67354380Syokota break; 67454380Syokota case RSHA: 67554380Syokota printf(" RSHA, "); 67654380Syokota break; 67754380Syokota case LCTRA: 67854380Syokota printf("LCTRA, "); 67954380Syokota break; 68054380Syokota case RCTRA: 68154380Syokota printf("RCTRA, "); 68254380Syokota break; 68354380Syokota case LALTA: 68454380Syokota printf("LALTA, "); 68554380Syokota break; 68654380Syokota case RALTA: 68754380Syokota printf("RALTA, "); 68854380Syokota break; 68965759Sdwmalone case HALT: 69065759Sdwmalone printf(" HALT, "); 69165759Sdwmalone break; 69265759Sdwmalone case PDWN: 69365759Sdwmalone printf(" PDWN, "); 69465759Sdwmalone break; 69574118Sache case PASTE: 69674118Sache printf("PASTE, "); 69774118Sache break; 69832316Syokota default: 69932316Syokota if (value >= F_FN && value <= L_FN) 70032316Syokota printf(" F(%2d),", value - F_FN + 1); 70132316Syokota else if (value >= F_SCR && value <= L_SCR) 70232486Syokota printf(" S(%2d),", value - F_SCR + 1); 70332316Syokota else if (value >= F_ACC && value <= L_ACC) 70432316Syokota printf(" %-4s, ", acc_names_u[value - F_ACC]); 70532316Syokota else 70632316Syokota printf(" 0x%02X, ", value); 70732316Syokota break; 70832316Syokota } 70932316Syokota } else if (value == '\'') { 71032316Syokota printf(" '\\'', "); 71132316Syokota } else if (value == '\\') { 71232316Syokota printf(" '\\\\', "); 71332316Syokota } else if (isascii(value) && isprint(value)) { 71432316Syokota printf(" '%c', ", value); 71532316Syokota } else { 71632316Syokota printf(" 0x%02X, ", value); 71732316Syokota } 71832316Syokota} 71932316Syokota 720228437Sedstatic void 72132316Syokotadump_key_definition(char *name, keymap_t *keymap) 72232316Syokota{ 72332316Syokota int i, j; 72432316Syokota 72532486Syokota printf("static keymap_t keymap_%s = { 0x%02x, {\n", 72632316Syokota name, (unsigned)keymap->n_keys); 72732316Syokota printf( 72832486Syokota"/* alt\n" 72932486Syokota" * scan cntrl alt alt cntrl\n" 73032486Syokota" * code base shift cntrl shift alt shift cntrl shift spcl flgs\n" 73132316Syokota" * ---------------------------------------------------------------------------\n" 73232316Syokota" */\n"); 73332316Syokota for (i = 0; i < keymap->n_keys; i++) { 73432486Syokota printf("/*%02x*/{{", i); 73532316Syokota for (j = 0; j < NUM_STATES; j++) { 73632316Syokota if (keymap->key[i].spcl & (0x80 >> j)) 737196500Sed dump_entry(keymap->key[i].map[j] | SPECIAL); 73832316Syokota else 73932316Syokota dump_entry(keymap->key[i].map[j]); 74032316Syokota } 74132486Syokota printf("}, 0x%02X,0x%02X },\n", 74232316Syokota (unsigned)keymap->key[i].spcl, 74332316Syokota (unsigned)keymap->key[i].flgs); 74432316Syokota } 74532486Syokota printf("} };\n\n"); 74632316Syokota} 74732316Syokota 748228437Sedstatic void 74932316Syokotadump_accent_definition(char *name, accentmap_t *accentmap) 75032316Syokota{ 75132316Syokota int i, j; 75232316Syokota int c; 75332316Syokota 75432486Syokota printf("static accentmap_t accentmap_%s = { %d", 75532316Syokota name, accentmap->n_accs); 75632486Syokota if (accentmap->n_accs <= 0) { 75732486Syokota printf(" };\n\n"); 75832486Syokota return; 75932486Syokota } 76032486Syokota printf(", {\n"); 76132316Syokota for (i = 0; i < NUM_DEADKEYS; i++) { 76232316Syokota printf(" /* %s=%d */\n {", acc_names[i], i); 76332316Syokota c = accentmap->acc[i].accchar; 76432316Syokota if (c == '\'') 76532316Syokota printf(" '\\'', {"); 76632316Syokota else if (c == '\\') 76732316Syokota printf(" '\\\\', {"); 76832316Syokota else if (isascii(c) && isprint(c)) 76932316Syokota printf(" '%c', {", c); 77032316Syokota else if (c == 0) { 77132316Syokota printf(" 0x00 }, \n"); 77232316Syokota continue; 77332316Syokota } else 77432316Syokota printf(" 0x%02x, {", c); 77532316Syokota for (j = 0; j < NUM_ACCENTCHARS; j++) { 77632316Syokota c = accentmap->acc[i].map[j][0]; 77732316Syokota if (c == 0) 77832316Syokota break; 77932316Syokota if ((j > 0) && ((j % 4) == 0)) 78032316Syokota printf("\n\t "); 78132316Syokota if (isascii(c) && isprint(c)) 78232316Syokota printf(" { '%c',", c); 78332316Syokota else 78432316Syokota printf(" { 0x%02x,", c); 78532316Syokota printf("0x%02x },", accentmap->acc[i].map[j][1]); 78632316Syokota } 78732316Syokota printf(" }, },\n"); 78832316Syokota } 78932486Syokota printf("} };\n\n"); 79032316Syokota} 79132316Syokota 792228437Sedstatic void 79319569Sjoergload_keymap(char *opt, int dumponly) 7942088Ssos{ 79532316Syokota keymap_t keymap; 79632316Syokota accentmap_t accentmap; 7972088Ssos FILE *fd; 79876502Ssobomax int i, j; 79919569Sjoerg char *name, *cp; 800266839Sray char blank[] = "", keymap_path[] = KEYMAP_PATH; 801266839Sray char vt_keymap_path[] = VT_KEYMAP_PATH, dotkbd[] = ".kbd"; 80299816Salfred char *prefix[] = {blank, blank, keymap_path, NULL}; 80399816Salfred char *postfix[] = {blank, dotkbd, NULL}; 8042088Ssos 805266839Sray if (is_vt4()) 806266839Sray prefix[2] = vt_keymap_path; 80776569Ssobomax cp = getenv("KEYMAP_PATH"); 80876569Ssobomax if (cp != NULL) 80976569Ssobomax asprintf(&(prefix[0]), "%s/", cp); 81076502Ssobomax 81176643Simp fd = NULL; 81276643Simp for (i=0; prefix[i] && fd == NULL; i++) { 81376643Simp for (j=0; postfix[j] && fd == NULL; j++) { 81476502Ssobomax name = mkfullname(prefix[i], opt, postfix[j]); 81576643Simp fd = fopen(name, "r"); 81676502Ssobomax } 81776643Simp } 8182088Ssos if (fd == NULL) { 81979677Sobrien warn("keymap file \"%s\" not found", opt); 8202088Ssos return; 8212088Ssos } 82232316Syokota memset(&keymap, 0, sizeof(keymap)); 82332316Syokota memset(&accentmap, 0, sizeof(accentmap)); 82432316Syokota token = -1; 8252088Ssos while (1) { 82632316Syokota if (get_definition_line(fd, &keymap, &accentmap) < 0) 8272088Ssos break; 8282088Ssos } 82919569Sjoerg if (dumponly) { 83019569Sjoerg /* fix up the filename to make it a valid C identifier */ 83119569Sjoerg for (cp = opt; *cp; cp++) 83219569Sjoerg if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_'; 83332316Syokota printf("/*\n" 83432316Syokota " * Automatically generated from %s.\n" 83532316Syokota " * DO NOT EDIT!\n" 83632316Syokota " */\n", name); 83732316Syokota dump_key_definition(opt, &keymap); 83832316Syokota dump_accent_definition(opt, &accentmap); 83919569Sjoerg return; 84019569Sjoerg } 84132316Syokota if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) { 84229603Scharnier warn("setting keymap"); 8432088Ssos fclose(fd); 8442088Ssos return; 8452088Ssos } 84632316Syokota if ((accentmap.n_accs > 0) 84732316Syokota && (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) { 84832316Syokota warn("setting accentmap"); 84932316Syokota fclose(fd); 85032316Syokota return; 85132316Syokota } 8522088Ssos} 8532088Ssos 854228437Sedstatic void 85599816Salfredprint_keymap(void) 8562088Ssos{ 85732316Syokota keymap_t keymap; 85832316Syokota accentmap_t accentmap; 8592088Ssos int i; 8602088Ssos 86132316Syokota if (ioctl(0, GIO_KEYMAP, &keymap) < 0) 86229603Scharnier err(1, "getting keymap"); 86332316Syokota if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0) 86432316Syokota memset(&accentmap, 0, sizeof(accentmap)); 8652088Ssos printf( 8662088Ssos"# alt\n" 8672088Ssos"# scan cntrl alt alt cntrl lock\n" 8682088Ssos"# code base shift cntrl shift alt shift cntrl shift state\n" 8692088Ssos"# ------------------------------------------------------------------\n" 8702088Ssos ); 87132316Syokota for (i=0; i<keymap.n_keys; i++) 87232316Syokota print_key_definition_line(stdout, i, &keymap.key[i]); 87332316Syokota 87432316Syokota printf("\n"); 87532316Syokota for (i = 0; i < NUM_DEADKEYS; i++) 87632316Syokota print_accent_definition_line(stdout, i, &accentmap.acc[i]); 87732316Syokota 8782088Ssos} 8792088Ssos 880228437Sedstatic void 88199816Salfredload_default_functionkeys(void) 8822088Ssos{ 8832088Ssos fkeyarg_t fkey; 8842088Ssos int i; 8852088Ssos 8862088Ssos for (i=0; i<NUM_FKEYS; i++) { 8872088Ssos fkey.keynum = i; 8882088Ssos strcpy(fkey.keydef, fkey_table[i]); 8892088Ssos fkey.flen = strlen(fkey_table[i]); 8902088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 89129603Scharnier warn("setting function key"); 8922088Ssos } 8932088Ssos} 8942088Ssos 895228437Sedstatic void 8962088Ssosset_functionkey(char *keynumstr, char *string) 8972088Ssos{ 8982088Ssos fkeyarg_t fkey; 8992088Ssos 9002088Ssos if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) { 9012088Ssos load_default_functionkeys(); 9022088Ssos return; 9032088Ssos } 9042088Ssos fkey.keynum = atoi(keynumstr); 9052088Ssos if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) { 90629603Scharnier warnx("function key number must be between 1 and %d", 9072088Ssos NUM_FKEYS); 9082088Ssos return; 9092088Ssos } 9102088Ssos if ((fkey.flen = strlen(string)) > MAXFK) { 91129603Scharnier warnx("function key string too long (%d > %d)", 9122088Ssos fkey.flen, MAXFK); 9132088Ssos return; 9142088Ssos } 915133353Sjmg strncpy(fkey.keydef, string, MAXFK); 9162088Ssos fkey.keynum -= 1; 9172088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 91829603Scharnier warn("setting function key"); 9192088Ssos} 9202088Ssos 921228437Sedstatic void 9222088Ssosset_bell_values(char *opt) 9232088Ssos{ 9245536Ssos int bell, duration, pitch; 9252088Ssos 92638044Syokota bell = 0; 92738044Syokota if (!strncmp(opt, "quiet.", 6)) { 928164333Sru bell = CONS_QUIET_BELL; 92938044Syokota opt += 6; 93038044Syokota } 9318857Srgrimes if (!strcmp(opt, "visual")) 932164333Sru bell |= CONS_VISUAL_BELL; 9335536Ssos else if (!strcmp(opt, "normal")) 93438044Syokota duration = 5, pitch = 800; 93548982Syokota else if (!strcmp(opt, "off")) 93648982Syokota duration = 0, pitch = 0; 9372088Ssos else { 9382088Ssos char *v1; 9398857Srgrimes 9405536Ssos bell = 0; 9412088Ssos duration = strtol(opt, &v1, 0); 9422088Ssos if ((duration < 0) || (*v1 != '.')) 9432088Ssos goto badopt; 9442088Ssos opt = ++v1; 9452088Ssos pitch = strtol(opt, &v1, 0); 9462088Ssos if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) { 9472088Ssosbadopt: 94877394Ssobomax warnx("argument to -b must be duration.pitch or [quiet.]visual|normal|off"); 9492088Ssos return; 9502088Ssos } 95138044Syokota if (pitch != 0) 95238044Syokota pitch = 1193182 / pitch; /* in Hz */ 95338044Syokota duration /= 10; /* in 10 m sec */ 9542088Ssos } 9552088Ssos 9565536Ssos ioctl(0, CONS_BELLTYPE, &bell); 957164333Sru if (!(bell & CONS_VISUAL_BELL)) 9585536Ssos fprintf(stderr, "[=%d;%dB", pitch, duration); 9592088Ssos} 9602088Ssos 961228437Sedstatic void 9622088Ssosset_keyrates(char *opt) 9632088Ssos{ 96444628Syokota int arg[2]; 96539047Syokota int repeat; 96639047Syokota int delay; 96746761Syokota int r, d; 9682088Ssos 96946761Syokota if (!strcmp(opt, "slow")) { 97044628Syokota delay = 1000, repeat = 500; 97146761Syokota d = 3, r = 31; 97246761Syokota } else if (!strcmp(opt, "normal")) { 97344628Syokota delay = 500, repeat = 125; 97446761Syokota d = 1, r = 15; 97546761Syokota } else if (!strcmp(opt, "fast")) { 97639047Syokota delay = repeat = 0; 97746761Syokota d = r = 0; 97846761Syokota } else { 9792088Ssos int n; 9802088Ssos char *v1; 9812088Ssos 9822088Ssos delay = strtol(opt, &v1, 0); 9832088Ssos if ((delay < 0) || (*v1 != '.')) 9842088Ssos goto badopt; 9852088Ssos opt = ++v1; 9862088Ssos repeat = strtol(opt, &v1, 0); 9872088Ssos if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) { 9882088Ssosbadopt: 98977394Ssobomax warnx("argument to -r must be delay.repeat or slow|normal|fast"); 9902088Ssos return; 9912088Ssos } 99246761Syokota for (n = 0; n < ndelays - 1; n++) 99346761Syokota if (delay <= delays[n]) 99446761Syokota break; 99546761Syokota d = n; 99646761Syokota for (n = 0; n < nrepeats - 1; n++) 99746761Syokota if (repeat <= repeats[n]) 99846761Syokota break; 99946761Syokota r = n; 10002088Ssos } 10012088Ssos 100244628Syokota arg[0] = delay; 100344628Syokota arg[1] = repeat; 100446761Syokota if (ioctl(0, KDSETREPEAT, arg)) { 100546761Syokota if (ioctl(0, KDSETRAD, (d << 5) | r)) 100646761Syokota warn("setting keyboard rate"); 100746761Syokota } 10082088Ssos} 10092088Ssos 101099816Salfredstatic const char * 101199816Salfredget_kbd_type_name(int type) 101242505Syokota{ 101342505Syokota static struct { 101442505Syokota int type; 101599816Salfred const char *name; 101642505Syokota } name_table[] = { 101742505Syokota { KB_84, "AT 84" }, 101842505Syokota { KB_101, "AT 101/102" }, 101942505Syokota { KB_OTHER, "generic" }, 102042505Syokota }; 102199816Salfred unsigned int i; 10226046Ssos 102342505Syokota for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) { 102442505Syokota if (type == name_table[i].type) 102542505Syokota return name_table[i].name; 102642505Syokota } 102742505Syokota return "unknown"; 102842505Syokota} 102942505Syokota 1030228437Sedstatic void 103142505Syokotashow_kbd_info(void) 103242505Syokota{ 103342505Syokota keyboard_info_t info; 103442505Syokota 103542505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 103642505Syokota warn("unable to obtain keyboard information"); 103742505Syokota return; 103842505Syokota } 103942505Syokota printf("kbd%d:\n", info.kb_index); 104042505Syokota printf(" %.*s%d, type:%s (%d)\n", 104177394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 104242505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 104342505Syokota} 104442505Syokota 1045228437Sedstatic void 104642505Syokotaset_keyboard(char *device) 104742505Syokota{ 104842505Syokota keyboard_info_t info; 104942505Syokota int fd; 105042505Syokota 105142505Syokota fd = open(device, O_RDONLY); 105242505Syokota if (fd < 0) { 105342505Syokota warn("cannot open %s", device); 105442505Syokota return; 105542505Syokota } 105642505Syokota if (ioctl(fd, KDGKBINFO, &info) == -1) { 105742505Syokota warn("unable to obtain keyboard information"); 105842505Syokota close(fd); 105942505Syokota return; 106042505Syokota } 106142505Syokota /* 106242505Syokota * The keyboard device driver won't release the keyboard by 106342505Syokota * the following ioctl, but it automatically will, when the device 106442505Syokota * is closed. So, we don't check error here. 106542505Syokota */ 106642505Syokota ioctl(fd, CONS_RELKBD, 0); 106742505Syokota close(fd); 106842505Syokota#if 1 106942505Syokota printf("kbd%d\n", info.kb_index); 107042505Syokota printf(" %.*s%d, type:%s (%d)\n", 107177394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 107242505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 107342505Syokota#endif 107442505Syokota 107542505Syokota if (ioctl(0, CONS_SETKBD, info.kb_index) == -1) 107642505Syokota warn("unable to set keyboard"); 107742505Syokota} 107842505Syokota 1079228437Sedstatic void 108042505Syokotarelease_keyboard(void) 108142505Syokota{ 108242505Syokota keyboard_info_t info; 108342505Syokota 108442505Syokota /* 108542505Syokota * If stdin is not associated with a keyboard, the following ioctl 108642505Syokota * will fail. 108742505Syokota */ 108842505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 108942505Syokota warn("unable to obtain keyboard information"); 109042505Syokota return; 109142505Syokota } 109242505Syokota#if 1 109342505Syokota printf("kbd%d\n", info.kb_index); 109442505Syokota printf(" %.*s%d, type:%s (%d)\n", 109577394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 109642505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 109742505Syokota#endif 109842505Syokota if (ioctl(0, CONS_RELKBD, 0) == -1) 109942505Syokota warn("unable to release the keyboard"); 110042505Syokota} 110142505Syokota 1102228437Sedstatic void 1103162327Semaxmux_keyboard(u_int op, char *kbd) 1104148017Semax{ 1105148017Semax keyboard_info_t info; 1106148017Semax char *unit, *ep; 110742505Syokota 1108148017Semax /* 1109148017Semax * If stdin is not associated with a keyboard, the following ioctl 1110148017Semax * will fail. 1111148017Semax */ 1112148017Semax if (ioctl(0, KDGKBINFO, &info) == -1) { 1113148017Semax warn("unable to obtain keyboard information"); 1114148017Semax return; 1115148017Semax } 1116148017Semax#if 1 1117148017Semax printf("kbd%d\n", info.kb_index); 1118148017Semax printf(" %.*s%d, type:%s (%d)\n", 1119148017Semax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 1120148017Semax get_kbd_type_name(info.kb_type), info.kb_type); 1121148017Semax#endif 1122148017Semax /* 1123148017Semax * split kbd into name and unit. find the right most part of the 1124148017Semax * kbd string that consist of only digits. 1125148017Semax */ 1126148017Semax 1127148017Semax memset(&info, 0, sizeof(info)); 1128148017Semax 1129148017Semax info.kb_unit = -1; 1130148017Semax ep = kbd - 1; 1131148017Semax 1132148017Semax do { 1133148017Semax unit = strpbrk(ep + 1, "0123456789"); 1134148017Semax if (unit != NULL) { 1135148017Semax info.kb_unit = strtol(unit, &ep, 10); 1136148017Semax if (*ep != '\0') 1137148017Semax info.kb_unit = -1; 1138148017Semax } 1139148017Semax } while (unit != NULL && info.kb_unit == -1); 1140148017Semax 1141148017Semax if (info.kb_unit == -1) { 1142148017Semax warnx("unable to find keyboard driver unit in '%s'", kbd); 1143148017Semax return; 1144148017Semax } 1145148017Semax 1146148017Semax if (unit == kbd) { 1147148017Semax warnx("unable to find keyboard driver name in '%s'", kbd); 1148148017Semax return; 1149148017Semax } 1150148017Semax if (unit - kbd >= (int) sizeof(info.kb_name)) { 1151148017Semax warnx("keyboard name '%s' is too long", kbd); 1152148017Semax return; 1153148017Semax } 1154148017Semax 1155148017Semax strncpy(info.kb_name, kbd, unit - kbd); 1156148017Semax 1157148017Semax /* 1158148017Semax * If stdin is not associated with a kbdmux(4) keyboard, the following 1159148017Semax * ioctl will fail. 1160148017Semax */ 1161148017Semax 1162148017Semax if (ioctl(0, op, &info) == -1) 1163148017Semax warn("unable to (un)mux the keyboard"); 1164148017Semax} 1165148017Semax 1166228437Sedstatic void 1167201387Sedusage(void) 11682088Ssos{ 116929603Scharnier fprintf(stderr, "%s\n%s\n%s\n", 1170148017Semax"usage: kbdcontrol [-dFKix] [-A name] [-a name] [-b duration.pitch | [quiet.]belltype]", 117129603Scharnier" [-r delay.repeat | speed] [-l mapfile] [-f # string]", 117277329Sdes" [-k device] [-L mapfile]"); 117329603Scharnier exit(1); 11742088Ssos} 11752088Ssos 11762088Ssos 117751287Speterint 11782088Ssosmain(int argc, char **argv) 11792088Ssos{ 11802088Ssos int opt; 11812088Ssos 1182148017Semax while((opt = getopt(argc, argv, "A:a:b:df:iKk:Fl:L:r:x")) != -1) 11832088Ssos switch(opt) { 1184148017Semax case 'A': 1185148017Semax case 'a': 1186148017Semax mux_keyboard((opt == 'A')? KBRELKBD : KBADDKBD, optarg); 1187148017Semax break; 118877329Sdes case 'b': 118977329Sdes set_bell_values(optarg); 119077329Sdes break; 119177329Sdes case 'd': 119277329Sdes print_keymap(); 119377329Sdes break; 119477329Sdes case 'l': 119577329Sdes load_keymap(optarg, 0); 119677329Sdes break; 119777329Sdes case 'L': 119877329Sdes load_keymap(optarg, 1); 119977329Sdes break; 120077329Sdes case 'f': 120177329Sdes set_functionkey(optarg, 120277329Sdes nextarg(argc, argv, &optind, 'f')); 120377329Sdes break; 120477329Sdes case 'F': 120577329Sdes load_default_functionkeys(); 120677329Sdes break; 120777329Sdes case 'i': 120877329Sdes show_kbd_info(); 120977329Sdes break; 121077329Sdes case 'K': 121177329Sdes release_keyboard(); 121277329Sdes break; 121377329Sdes case 'k': 121477329Sdes set_keyboard(optarg); 121577329Sdes break; 121677329Sdes case 'r': 121777329Sdes set_keyrates(optarg); 121877329Sdes break; 121977329Sdes case 'x': 122077329Sdes hex = 1; 122177329Sdes break; 122277329Sdes default: 122377329Sdes usage(); 12242088Ssos } 122529603Scharnier if ((optind != argc) || (argc == 1)) 12262088Ssos usage(); 12272088Ssos exit(0); 12282088Ssos} 1229