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$"); 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> 412088Ssos#include "path.h" 422088Ssos#include "lex.h" 432088Ssos 4476643Simp/* 4590394Sru * HALT, PDWN, and PASTE aren't defined in 4.x, but we need them to bridge 4690394Sru * to 5.0-current so define them here as a stop gap transition measure. 4776643Simp */ 4890394Sru#ifndef HALT 4990394Sru#define HALT 0xa1 /* halt machine */ 5090394Sru#endif 5190394Sru#ifndef PDWN 5290394Sru#define PDWN 0xa2 /* halt machine and power down */ 5390394Sru#endif 5476643Simp#ifndef PASTE 5576643Simp#define PASTE 0xa3 /* paste from cut-paste buffer */ 5676643Simp#endif 5776643Simp 58196500Sed#define SPECIAL 0x80000000 59196500Sed 60228437Sedstatic const char ctrl_names[32][4] = { 618857Srgrimes "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 622088Ssos "bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ", 632088Ssos "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 6438139Syokota "can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "us " 652088Ssos }; 662088Ssos 67228437Sedstatic const char acc_names[15][5] = { 6832316Syokota "dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot", 6932316Syokota "duml", "dsla", "drin", "dced", "dapo", "ddac", "dogo", 7032316Syokota "dcar", 7132316Syokota }; 7232316Syokota 73228437Sedstatic const char acc_names_u[15][5] = { 7432316Syokota "DGRA", "DACU", "DCIR", "DTIL", "DMAC", "DBRE", "DDOT", 7532316Syokota "DUML", "DSLA", "DRIN", "DCED", "DAPO", "DDAC", "DOGO", 7632316Syokota "DCAR", 7732316Syokota }; 7832316Syokota 79228437Sedstatic const char fkey_table[96][MAXFK] = { 805994Ssos/* 01-04 */ "\033[M", "\033[N", "\033[O", "\033[P", 815994Ssos/* 05-08 */ "\033[Q", "\033[R", "\033[S", "\033[T", 825994Ssos/* 09-12 */ "\033[U", "\033[V", "\033[W", "\033[X", 835994Ssos/* 13-16 */ "\033[Y", "\033[Z", "\033[a", "\033[b", 845994Ssos/* 17-20 */ "\033[c", "\033[d", "\033[e", "\033[f", 855994Ssos/* 21-24 */ "\033[g", "\033[h", "\033[i", "\033[j", 865994Ssos/* 25-28 */ "\033[k", "\033[l", "\033[m", "\033[n", 875994Ssos/* 29-32 */ "\033[o", "\033[p", "\033[q", "\033[r", 885994Ssos/* 33-36 */ "\033[s", "\033[t", "\033[u", "\033[v", 895994Ssos/* 37-40 */ "\033[w", "\033[x", "\033[y", "\033[z", 905994Ssos/* 41-44 */ "\033[@", "\033[[", "\033[\\","\033[]", 919202Srgrimes/* 45-48 */ "\033[^", "\033[_", "\033[`", "\033[{", 925994Ssos/* 49-52 */ "\033[H", "\033[A", "\033[I", "-" , 935994Ssos/* 53-56 */ "\033[D", "\033[E", "\033[C", "+" , 945994Ssos/* 57-60 */ "\033[F", "\033[B", "\033[G", "\033[L", 959202Srgrimes/* 61-64 */ "\177", "\033[J", "\033[~", "\033[}", 965994Ssos/* 65-68 */ "" , "" , "" , "" , 975994Ssos/* 69-72 */ "" , "" , "" , "" , 985994Ssos/* 73-76 */ "" , "" , "" , "" , 995994Ssos/* 77-80 */ "" , "" , "" , "" , 1005994Ssos/* 81-84 */ "" , "" , "" , "" , 1015994Ssos/* 85-88 */ "" , "" , "" , "" , 1025994Ssos/* 89-92 */ "" , "" , "" , "" , 1035994Ssos/* 93-96 */ "" , "" , "" , "" , 1042088Ssos }; 1052088Ssos 106228437Sedstatic const int delays[] = {250, 500, 750, 1000}; 107228437Sedstatic const int repeats[] = { 34, 38, 42, 46, 50, 55, 59, 63, 108228437Sed 68, 76, 84, 92, 100, 110, 118, 126, 109228437Sed 136, 152, 168, 184, 200, 220, 236, 252, 110228437Sed 272, 304, 336, 368, 400, 440, 472, 504}; 111228437Sedstatic const int ndelays = (sizeof(delays) / sizeof(int)); 112228437Sedstatic const int nrepeats = (sizeof(repeats) / sizeof(int)); 113228437Sedstatic int hex = 0; 114228437Sedstatic int token; 1152088Ssos 116228437Sedint number; 117228437Sedchar letter; 1182088Ssos 119228437Sedstatic void dump_accent_definition(char *name, accentmap_t *accentmap); 120228437Sedstatic void dump_entry(int value); 121228437Sedstatic void dump_key_definition(char *name, keymap_t *keymap); 122228437Sedstatic int get_accent_definition_line(accentmap_t *); 123228437Sedstatic int get_entry(void); 124228437Sedstatic int get_key_definition_line(keymap_t *); 125228437Sedstatic void load_keymap(char *opt, int dumponly); 126228437Sedstatic void load_default_functionkeys(void); 127228437Sedstatic char * nextarg(int ac, char **av, int *indp, int oc); 128228437Sedstatic char * mkfullname(const char *s1, const char *s2, const char *s3); 129228437Sedstatic void print_accent_definition_line(FILE *fp, int accent, 130228437Sed struct acc_t *key); 131228437Sedstatic void print_entry(FILE *fp, int value); 132228437Sedstatic void print_key_definition_line(FILE *fp, int scancode, 133228437Sed struct keyent_t *key); 134228437Sedstatic void print_keymap(void); 135228437Sedstatic void release_keyboard(void); 136228437Sedstatic void mux_keyboard(u_int op, char *kbd); 137228437Sedstatic void set_bell_values(char *opt); 138228437Sedstatic void set_functionkey(char *keynumstr, char *string); 139228437Sedstatic void set_keyboard(char *device); 140228437Sedstatic void set_keyrates(char *opt); 141228437Sedstatic void show_kbd_info(void); 142228437Sedstatic void usage(void) __dead2; 143228437Sed 144228437Sedstatic char * 1452088Ssosnextarg(int ac, char **av, int *indp, int oc) 1462088Ssos{ 1472088Ssos if (*indp < ac) 1482088Ssos return(av[(*indp)++]); 14929603Scharnier warnx("option requires two arguments -- %c", oc); 1502088Ssos usage(); 1512088Ssos} 1522088Ssos 1532088Ssos 154228437Sedstatic char * 1552088Ssosmkfullname(const char *s1, const char *s2, const char *s3) 1562088Ssos{ 1575536Ssos static char *buf = NULL; 1585536Ssos static int bufl = 0; 1595536Ssos int f; 1602088Ssos 1612088Ssos f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 16277394Ssobomax if (f > bufl) { 1632088Ssos if (buf) 1642088Ssos buf = (char *)realloc(buf, f); 1652088Ssos else 1662088Ssos buf = (char *)malloc(f); 16777394Ssobomax } 1682088Ssos if (!buf) { 1692088Ssos bufl = 0; 1702088Ssos return(NULL); 1712088Ssos } 1722088Ssos 1732088Ssos bufl = f; 1742088Ssos strcpy(buf, s1); 1752088Ssos strcat(buf, s2); 1762088Ssos strcat(buf, s3); 1772088Ssos return(buf); 1782088Ssos} 1792088Ssos 1802088Ssos 181228437Sedstatic int 18299816Salfredget_entry(void) 1832088Ssos{ 18432316Syokota switch ((token = yylex())) { 1852088Ssos case TNOP: 186196500Sed return NOP | SPECIAL; 1872088Ssos case TLSH: 188196500Sed return LSH | SPECIAL; 1892088Ssos case TRSH: 190196500Sed return RSH | SPECIAL; 1912088Ssos case TCLK: 192196500Sed return CLK | SPECIAL; 1932088Ssos case TNLK: 194196500Sed return NLK | SPECIAL; 1952088Ssos case TSLK: 196196500Sed return SLK | SPECIAL; 1972088Ssos case TBTAB: 198196500Sed return BTAB | SPECIAL; 1992088Ssos case TLALT: 200196500Sed return LALT | SPECIAL; 2012088Ssos case TLCTR: 202196500Sed return LCTR | SPECIAL; 2032088Ssos case TNEXT: 204196500Sed return NEXT | SPECIAL; 20548105Syokota case TPREV: 206196500Sed return PREV | SPECIAL; 2072088Ssos case TRCTR: 208196500Sed return RCTR | SPECIAL; 2092088Ssos case TRALT: 210196500Sed return RALT | SPECIAL; 2112088Ssos case TALK: 212196500Sed return ALK | SPECIAL; 2132088Ssos case TASH: 214196500Sed return ASH | SPECIAL; 2152088Ssos case TMETA: 216196500Sed return META | SPECIAL; 2172088Ssos case TRBT: 218196500Sed return RBT | SPECIAL; 2192088Ssos case TDBG: 220196500Sed return DBG | SPECIAL; 2215994Ssos case TSUSP: 222196500Sed return SUSP | SPECIAL; 22338053Syokota case TSPSC: 224196500Sed return SPSC | SPECIAL; 22554380Syokota case TPANIC: 226196500Sed return PNC | SPECIAL; 22754380Syokota case TLSHA: 228196500Sed return LSHA | SPECIAL; 22954380Syokota case TRSHA: 230196500Sed return RSHA | SPECIAL; 23154380Syokota case TLCTRA: 232196500Sed return LCTRA | SPECIAL; 23354380Syokota case TRCTRA: 234196500Sed return RCTRA | SPECIAL; 23554380Syokota case TLALTA: 236196500Sed return LALTA | SPECIAL; 23754380Syokota case TRALTA: 238196500Sed return RALTA | SPECIAL; 23965759Sdwmalone case THALT: 240196500Sed return HALT | SPECIAL; 24165759Sdwmalone case TPDWN: 242196500Sed return PDWN | SPECIAL; 24374118Sache case TPASTE: 244196500Sed return PASTE | SPECIAL; 24532316Syokota case TACC: 24632316Syokota if (ACC(number) > L_ACC) 24732316Syokota return -1; 248196500Sed return ACC(number) | SPECIAL; 2492088Ssos case TFUNC: 2502088Ssos if (F(number) > L_FN) 2512088Ssos return -1; 252196500Sed return F(number) | SPECIAL; 2532088Ssos case TSCRN: 2542088Ssos if (S(number) > L_SCR) 2552088Ssos return -1; 256196500Sed return S(number) | SPECIAL; 2572088Ssos case TLET: 2582088Ssos return (unsigned char)letter; 2592088Ssos case TNUM: 260197330Sed if (number < 0x000000 || number > 0x10FFFF) 2612088Ssos return -1; 2622088Ssos return number; 2632088Ssos default: 2642088Ssos return -1; 2652088Ssos } 2662088Ssos} 2672088Ssos 26877394Ssobomaxstatic int 26932316Syokotaget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap) 2702088Ssos{ 27132316Syokota int c; 2722088Ssos 2732088Ssos yyin = fd; 2742088Ssos 27532316Syokota if (token < 0) 27632316Syokota token = yylex(); 27732316Syokota switch (token) { 27832316Syokota case TNUM: 27932316Syokota c = get_key_definition_line(keymap); 28032316Syokota if (c < 0) 28132316Syokota errx(1, "invalid key definition"); 28232316Syokota if (c > keymap->n_keys) 28332316Syokota keymap->n_keys = c; 28432316Syokota break; 28532316Syokota case TACC: 28632316Syokota c = get_accent_definition_line(accentmap); 28732316Syokota if (c < 0) 28832316Syokota errx(1, "invalid accent key definition"); 28932316Syokota if (c > accentmap->n_accs) 29032316Syokota accentmap->n_accs = c; 29132316Syokota break; 29232316Syokota case 0: 29332316Syokota /* EOF */ 2942088Ssos return -1; 29532316Syokota default: 29632316Syokota errx(1, "illegal definition line"); 29732316Syokota } 29832316Syokota return c; 29932316Syokota} 30032316Syokota 301228437Sedstatic int 30232316Syokotaget_key_definition_line(keymap_t *map) 30332316Syokota{ 30432316Syokota int i, def, scancode; 30532316Syokota 30632316Syokota /* check scancode number */ 3072088Ssos if (number < 0 || number >= NUM_KEYS) 3082088Ssos return -1; 3092088Ssos scancode = number; 3102088Ssos 3112088Ssos /* get key definitions */ 3122088Ssos map->key[scancode].spcl = 0; 3132088Ssos for (i=0; i<NUM_STATES; i++) { 3142088Ssos if ((def = get_entry()) == -1) 3152088Ssos return -1; 316196500Sed if (def & SPECIAL) 3172088Ssos map->key[scancode].spcl |= (0x80 >> i); 318196500Sed map->key[scancode].map[i] = def & ~SPECIAL; 3192088Ssos } 3202088Ssos /* get lock state key def */ 32132316Syokota if ((token = yylex()) != TFLAG) 3222088Ssos return -1; 3232088Ssos map->key[scancode].flgs = number; 32432316Syokota token = yylex(); 32532316Syokota return (scancode + 1); 3262088Ssos} 3272088Ssos 328228437Sedstatic int 32932316Syokotaget_accent_definition_line(accentmap_t *map) 33032316Syokota{ 33132316Syokota int accent; 33232316Syokota int c1, c2; 33332316Syokota int i; 3342088Ssos 33532316Syokota if (ACC(number) < F_ACC || ACC(number) > L_ACC) 33632316Syokota /* number out of range */ 33732316Syokota return -1; 33832316Syokota accent = number; 33932316Syokota if (map->acc[accent].accchar != 0) { 34032316Syokota /* this entry has already been defined before! */ 34132316Syokota errx(1, "duplicated accent key definition"); 34232316Syokota } 34332316Syokota 34432316Syokota switch ((token = yylex())) { 34532316Syokota case TLET: 34632316Syokota map->acc[accent].accchar = letter; 34732316Syokota break; 34832316Syokota case TNUM: 34932316Syokota map->acc[accent].accchar = number; 35032316Syokota break; 35132316Syokota default: 35232316Syokota return -1; 35332316Syokota } 35432316Syokota 35532316Syokota for (i = 0; (token = yylex()) == '(';) { 35632316Syokota switch ((token = yylex())) { 35732316Syokota case TLET: 35832316Syokota c1 = letter; 35932316Syokota break; 36032316Syokota case TNUM: 36132316Syokota c1 = number; 36232316Syokota break; 36332316Syokota default: 36432316Syokota return -1; 36532316Syokota } 36632316Syokota switch ((token = yylex())) { 36732316Syokota case TLET: 36832316Syokota c2 = letter; 36932316Syokota break; 37032316Syokota case TNUM: 37132316Syokota c2 = number; 37232316Syokota break; 37332316Syokota default: 37432316Syokota return -1; 37532316Syokota } 37632316Syokota if ((token = yylex()) != ')') 37732316Syokota return -1; 37832316Syokota if (i >= NUM_ACCENTCHARS) { 37932316Syokota warnx("too many accented characters, ignored"); 38032316Syokota continue; 38132316Syokota } 38232316Syokota map->acc[accent].map[i][0] = c1; 38332316Syokota map->acc[accent].map[i][1] = c2; 38432316Syokota ++i; 38532316Syokota } 38632316Syokota return (accent + 1); 38732316Syokota} 38832316Syokota 389228437Sedstatic void 3902088Ssosprint_entry(FILE *fp, int value) 3912088Ssos{ 392196500Sed int val = value & ~SPECIAL; 3932088Ssos 3942088Ssos switch (value) { 395196500Sed case NOP | SPECIAL: 3968857Srgrimes fprintf(fp, " nop "); 3972088Ssos break; 398196500Sed case LSH | SPECIAL: 3992088Ssos fprintf(fp, " lshift"); 4002088Ssos break; 401196500Sed case RSH | SPECIAL: 4022088Ssos fprintf(fp, " rshift"); 4032088Ssos break; 404196500Sed case CLK | SPECIAL: 4052088Ssos fprintf(fp, " clock "); 4062088Ssos break; 407196500Sed case NLK | SPECIAL: 4082088Ssos fprintf(fp, " nlock "); 4092088Ssos break; 410196500Sed case SLK | SPECIAL: 4112088Ssos fprintf(fp, " slock "); 4122088Ssos break; 413196500Sed case BTAB | SPECIAL: 4142088Ssos fprintf(fp, " btab "); 4152088Ssos break; 416196500Sed case LALT | SPECIAL: 4172088Ssos fprintf(fp, " lalt "); 4182088Ssos break; 419196500Sed case LCTR | SPECIAL: 4202088Ssos fprintf(fp, " lctrl "); 4212088Ssos break; 422196500Sed case NEXT | SPECIAL: 4232088Ssos fprintf(fp, " nscr "); 4242088Ssos break; 425196500Sed case PREV | SPECIAL: 42648105Syokota fprintf(fp, " pscr "); 42748105Syokota break; 428196500Sed case RCTR | SPECIAL: 4292088Ssos fprintf(fp, " rctrl "); 4302088Ssos break; 431196500Sed case RALT | SPECIAL: 4322088Ssos fprintf(fp, " ralt "); 4332088Ssos break; 434196500Sed case ALK | SPECIAL: 4352088Ssos fprintf(fp, " alock "); 4362088Ssos break; 437196500Sed case ASH | SPECIAL: 4382088Ssos fprintf(fp, " ashift"); 4392088Ssos break; 440196500Sed case META | SPECIAL: 4412088Ssos fprintf(fp, " meta "); 4422088Ssos break; 443196500Sed case RBT | SPECIAL: 4442088Ssos fprintf(fp, " boot "); 4452088Ssos break; 446196500Sed case DBG | SPECIAL: 4472088Ssos fprintf(fp, " debug "); 4482088Ssos break; 449196500Sed case SUSP | SPECIAL: 45032316Syokota fprintf(fp, " susp "); 45132316Syokota break; 452196500Sed case SPSC | SPECIAL: 45338053Syokota fprintf(fp, " saver "); 45438053Syokota break; 455196500Sed case PNC | SPECIAL: 45654380Syokota fprintf(fp, " panic "); 45754380Syokota break; 458196500Sed case LSHA | SPECIAL: 45954380Syokota fprintf(fp, " lshifta"); 46054380Syokota break; 461196500Sed case RSHA | SPECIAL: 46254380Syokota fprintf(fp, " rshifta"); 46354380Syokota break; 464196500Sed case LCTRA | SPECIAL: 46554380Syokota fprintf(fp, " lctrla"); 46654380Syokota break; 467196500Sed case RCTRA | SPECIAL: 46854380Syokota fprintf(fp, " rctrla"); 46954380Syokota break; 470196500Sed case LALTA | SPECIAL: 47154380Syokota fprintf(fp, " lalta "); 47254380Syokota break; 473196500Sed case RALTA | SPECIAL: 47454380Syokota fprintf(fp, " ralta "); 47554380Syokota break; 476196500Sed case HALT | SPECIAL: 47765759Sdwmalone fprintf(fp, " halt "); 47865759Sdwmalone break; 479196500Sed case PDWN | SPECIAL: 48065759Sdwmalone fprintf(fp, " pdwn "); 48165759Sdwmalone break; 482196500Sed case PASTE | SPECIAL: 48374118Sache fprintf(fp, " paste "); 48474118Sache break; 4852088Ssos default: 486196500Sed if (value & SPECIAL) { 4878857Srgrimes if (val >= F_FN && val <= L_FN) 4882088Ssos fprintf(fp, " fkey%02d", val - F_FN + 1); 4898857Srgrimes else if (val >= F_SCR && val <= L_SCR) 4902088Ssos fprintf(fp, " scr%02d ", val - F_SCR + 1); 49132316Syokota else if (val >= F_ACC && val <= L_ACC) 49232316Syokota fprintf(fp, " %-6s", acc_names[val - F_ACC]); 4932088Ssos else if (hex) 4948857Srgrimes fprintf(fp, " 0x%02x ", val); 4952088Ssos else 49632316Syokota fprintf(fp, " %3d ", val); 4972088Ssos } 4982088Ssos else { 4992088Ssos if (val < ' ') 5008857Srgrimes fprintf(fp, " %s ", ctrl_names[val]); 5012088Ssos else if (val == 127) 5028857Srgrimes fprintf(fp, " del "); 5039202Srgrimes else if (isascii(val) && isprint(val)) 5048857Srgrimes fprintf(fp, " '%c' ", val); 5052088Ssos else if (hex) 5068857Srgrimes fprintf(fp, " 0x%02x ", val); 5072088Ssos else 5088857Srgrimes fprintf(fp, " %3d ", val); 5092088Ssos } 5102088Ssos } 5112088Ssos} 5122088Ssos 513228437Sedstatic void 51442505Syokotaprint_key_definition_line(FILE *fp, int scancode, struct keyent_t *key) 5152088Ssos{ 51629603Scharnier int i; 5172088Ssos 5182088Ssos /* print scancode number */ 5192088Ssos if (hex) 5202088Ssos fprintf(fp, " 0x%02x ", scancode); 5212088Ssos else 5222088Ssos fprintf(fp, " %03d ", scancode); 5232088Ssos 5242088Ssos /* print key definitions */ 5252088Ssos for (i=0; i<NUM_STATES; i++) { 5262088Ssos if (key->spcl & (0x80 >> i)) 527196500Sed print_entry(fp, key->map[i] | SPECIAL); 5282088Ssos else 5298857Srgrimes print_entry(fp, key->map[i]); 5302088Ssos } 5312088Ssos 5322088Ssos /* print lock state key def */ 5332088Ssos switch (key->flgs) { 5342088Ssos case 0: 5352088Ssos fprintf(fp, " O\n"); 5362088Ssos break; 5372088Ssos case 1: 5382088Ssos fprintf(fp, " C\n"); 5392088Ssos break; 5402088Ssos case 2: 5412088Ssos fprintf(fp, " N\n"); 5422088Ssos break; 5436046Ssos case 3: 5446046Ssos fprintf(fp, " B\n"); 5456046Ssos break; 5468857Srgrimes } 5472088Ssos} 5482088Ssos 549228437Sedstatic void 55032316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key) 55132316Syokota{ 55232316Syokota int c; 55332316Syokota int i; 5542088Ssos 55532316Syokota if (key->accchar == 0) 55632316Syokota return; 55732316Syokota 55832316Syokota /* print accent number */ 55932316Syokota fprintf(fp, " %-6s", acc_names[accent]); 56032316Syokota if (isascii(key->accchar) && isprint(key->accchar)) 56132316Syokota fprintf(fp, "'%c' ", key->accchar); 56232316Syokota else if (hex) 56332316Syokota fprintf(fp, "0x%02x ", key->accchar); 56432316Syokota else 56532316Syokota fprintf(fp, "%03d ", key->accchar); 56632316Syokota 56732316Syokota for (i = 0; i < NUM_ACCENTCHARS; ++i) { 56832316Syokota c = key->map[i][0]; 56932316Syokota if (c == 0) 57032316Syokota break; 57132316Syokota if ((i > 0) && ((i % 4) == 0)) 57232316Syokota fprintf(fp, "\n "); 57332316Syokota if (isascii(c) && isprint(c)) 57432316Syokota fprintf(fp, "( '%c' ", c); 57532316Syokota else if (hex) 57632316Syokota fprintf(fp, "(0x%02x ", c); 57732316Syokota else 57832316Syokota fprintf(fp, "( %03d ", c); 57932316Syokota c = key->map[i][1]; 58032316Syokota if (isascii(c) && isprint(c)) 58132316Syokota fprintf(fp, "'%c' ) ", c); 58232316Syokota else if (hex) 58332316Syokota fprintf(fp, "0x%02x) ", c); 58432316Syokota else 58532316Syokota fprintf(fp, "%03d ) ", c); 58632316Syokota } 58732316Syokota fprintf(fp, "\n"); 58832316Syokota} 58932316Syokota 590228437Sedstatic void 59132316Syokotadump_entry(int value) 59232316Syokota{ 593196500Sed if (value & SPECIAL) { 594196500Sed value &= ~SPECIAL; 59532316Syokota switch (value) { 59632316Syokota case NOP: 59732316Syokota printf(" NOP, "); 59832316Syokota break; 59932316Syokota case LSH: 60032316Syokota printf(" LSH, "); 60132316Syokota break; 60232316Syokota case RSH: 60332316Syokota printf(" RSH, "); 60432316Syokota break; 60532316Syokota case CLK: 60632316Syokota printf(" CLK, "); 60732316Syokota break; 60832316Syokota case NLK: 60932316Syokota printf(" NLK, "); 61032316Syokota break; 61132316Syokota case SLK: 61232316Syokota printf(" SLK, "); 61332316Syokota break; 61432316Syokota case BTAB: 61532316Syokota printf(" BTAB, "); 61632316Syokota break; 61732316Syokota case LALT: 61832316Syokota printf(" LALT, "); 61932316Syokota break; 62032316Syokota case LCTR: 62132316Syokota printf(" LCTR, "); 62232316Syokota break; 62332316Syokota case NEXT: 62432316Syokota printf(" NEXT, "); 62532316Syokota break; 62648105Syokota case PREV: 62748105Syokota printf(" PREV, "); 62848105Syokota break; 62932316Syokota case RCTR: 63032316Syokota printf(" RCTR, "); 63132316Syokota break; 63232316Syokota case RALT: 63332316Syokota printf(" RALT, "); 63432316Syokota break; 63532316Syokota case ALK: 63632316Syokota printf(" ALK, "); 63732316Syokota break; 63832316Syokota case ASH: 63932316Syokota printf(" ASH, "); 64032316Syokota break; 64132316Syokota case META: 64232316Syokota printf(" META, "); 64332316Syokota break; 64432316Syokota case RBT: 64532316Syokota printf(" RBT, "); 64632316Syokota break; 64732316Syokota case DBG: 64832316Syokota printf(" DBG, "); 64932316Syokota break; 65032316Syokota case SUSP: 65132316Syokota printf(" SUSP, "); 65232316Syokota break; 65338053Syokota case SPSC: 65438053Syokota printf(" SPSC, "); 65538053Syokota break; 65654380Syokota case PNC: 65754380Syokota printf(" PNC, "); 65854380Syokota break; 65954380Syokota case LSHA: 66054380Syokota printf(" LSHA, "); 66154380Syokota break; 66254380Syokota case RSHA: 66354380Syokota printf(" RSHA, "); 66454380Syokota break; 66554380Syokota case LCTRA: 66654380Syokota printf("LCTRA, "); 66754380Syokota break; 66854380Syokota case RCTRA: 66954380Syokota printf("RCTRA, "); 67054380Syokota break; 67154380Syokota case LALTA: 67254380Syokota printf("LALTA, "); 67354380Syokota break; 67454380Syokota case RALTA: 67554380Syokota printf("RALTA, "); 67654380Syokota break; 67765759Sdwmalone case HALT: 67865759Sdwmalone printf(" HALT, "); 67965759Sdwmalone break; 68065759Sdwmalone case PDWN: 68165759Sdwmalone printf(" PDWN, "); 68265759Sdwmalone break; 68374118Sache case PASTE: 68474118Sache printf("PASTE, "); 68574118Sache break; 68632316Syokota default: 68732316Syokota if (value >= F_FN && value <= L_FN) 68832316Syokota printf(" F(%2d),", value - F_FN + 1); 68932316Syokota else if (value >= F_SCR && value <= L_SCR) 69032486Syokota printf(" S(%2d),", value - F_SCR + 1); 69132316Syokota else if (value >= F_ACC && value <= L_ACC) 69232316Syokota printf(" %-4s, ", acc_names_u[value - F_ACC]); 69332316Syokota else 69432316Syokota printf(" 0x%02X, ", value); 69532316Syokota break; 69632316Syokota } 69732316Syokota } else if (value == '\'') { 69832316Syokota printf(" '\\'', "); 69932316Syokota } else if (value == '\\') { 70032316Syokota printf(" '\\\\', "); 70132316Syokota } else if (isascii(value) && isprint(value)) { 70232316Syokota printf(" '%c', ", value); 70332316Syokota } else { 70432316Syokota printf(" 0x%02X, ", value); 70532316Syokota } 70632316Syokota} 70732316Syokota 708228437Sedstatic void 70932316Syokotadump_key_definition(char *name, keymap_t *keymap) 71032316Syokota{ 71132316Syokota int i, j; 71232316Syokota 71332486Syokota printf("static keymap_t keymap_%s = { 0x%02x, {\n", 71432316Syokota name, (unsigned)keymap->n_keys); 71532316Syokota printf( 71632486Syokota"/* alt\n" 71732486Syokota" * scan cntrl alt alt cntrl\n" 71832486Syokota" * code base shift cntrl shift alt shift cntrl shift spcl flgs\n" 71932316Syokota" * ---------------------------------------------------------------------------\n" 72032316Syokota" */\n"); 72132316Syokota for (i = 0; i < keymap->n_keys; i++) { 72232486Syokota printf("/*%02x*/{{", i); 72332316Syokota for (j = 0; j < NUM_STATES; j++) { 72432316Syokota if (keymap->key[i].spcl & (0x80 >> j)) 725196500Sed dump_entry(keymap->key[i].map[j] | SPECIAL); 72632316Syokota else 72732316Syokota dump_entry(keymap->key[i].map[j]); 72832316Syokota } 72932486Syokota printf("}, 0x%02X,0x%02X },\n", 73032316Syokota (unsigned)keymap->key[i].spcl, 73132316Syokota (unsigned)keymap->key[i].flgs); 73232316Syokota } 73332486Syokota printf("} };\n\n"); 73432316Syokota} 73532316Syokota 736228437Sedstatic void 73732316Syokotadump_accent_definition(char *name, accentmap_t *accentmap) 73832316Syokota{ 73932316Syokota int i, j; 74032316Syokota int c; 74132316Syokota 74232486Syokota printf("static accentmap_t accentmap_%s = { %d", 74332316Syokota name, accentmap->n_accs); 74432486Syokota if (accentmap->n_accs <= 0) { 74532486Syokota printf(" };\n\n"); 74632486Syokota return; 74732486Syokota } 74832486Syokota printf(", {\n"); 74932316Syokota for (i = 0; i < NUM_DEADKEYS; i++) { 75032316Syokota printf(" /* %s=%d */\n {", acc_names[i], i); 75132316Syokota c = accentmap->acc[i].accchar; 75232316Syokota if (c == '\'') 75332316Syokota printf(" '\\'', {"); 75432316Syokota else if (c == '\\') 75532316Syokota printf(" '\\\\', {"); 75632316Syokota else if (isascii(c) && isprint(c)) 75732316Syokota printf(" '%c', {", c); 75832316Syokota else if (c == 0) { 75932316Syokota printf(" 0x00 }, \n"); 76032316Syokota continue; 76132316Syokota } else 76232316Syokota printf(" 0x%02x, {", c); 76332316Syokota for (j = 0; j < NUM_ACCENTCHARS; j++) { 76432316Syokota c = accentmap->acc[i].map[j][0]; 76532316Syokota if (c == 0) 76632316Syokota break; 76732316Syokota if ((j > 0) && ((j % 4) == 0)) 76832316Syokota printf("\n\t "); 76932316Syokota if (isascii(c) && isprint(c)) 77032316Syokota printf(" { '%c',", c); 77132316Syokota else 77232316Syokota printf(" { 0x%02x,", c); 77332316Syokota printf("0x%02x },", accentmap->acc[i].map[j][1]); 77432316Syokota } 77532316Syokota printf(" }, },\n"); 77632316Syokota } 77732486Syokota printf("} };\n\n"); 77832316Syokota} 77932316Syokota 780228437Sedstatic void 78119569Sjoergload_keymap(char *opt, int dumponly) 7822088Ssos{ 78332316Syokota keymap_t keymap; 78432316Syokota accentmap_t accentmap; 7852088Ssos FILE *fd; 78676502Ssobomax int i, j; 78719569Sjoerg char *name, *cp; 78899816Salfred char blank[] = "", keymap_path[] = KEYMAP_PATH, dotkbd[] = ".kbd"; 78999816Salfred char *prefix[] = {blank, blank, keymap_path, NULL}; 79099816Salfred char *postfix[] = {blank, dotkbd, NULL}; 7912088Ssos 79276569Ssobomax cp = getenv("KEYMAP_PATH"); 79376569Ssobomax if (cp != NULL) 79476569Ssobomax asprintf(&(prefix[0]), "%s/", cp); 79576502Ssobomax 79676643Simp fd = NULL; 79776643Simp for (i=0; prefix[i] && fd == NULL; i++) { 79876643Simp for (j=0; postfix[j] && fd == NULL; j++) { 79976502Ssobomax name = mkfullname(prefix[i], opt, postfix[j]); 80076643Simp fd = fopen(name, "r"); 80176502Ssobomax } 80276643Simp } 8032088Ssos if (fd == NULL) { 80479677Sobrien warn("keymap file \"%s\" not found", opt); 8052088Ssos return; 8062088Ssos } 80732316Syokota memset(&keymap, 0, sizeof(keymap)); 80832316Syokota memset(&accentmap, 0, sizeof(accentmap)); 80932316Syokota token = -1; 8102088Ssos while (1) { 81132316Syokota if (get_definition_line(fd, &keymap, &accentmap) < 0) 8122088Ssos break; 8132088Ssos } 81419569Sjoerg if (dumponly) { 81519569Sjoerg /* fix up the filename to make it a valid C identifier */ 81619569Sjoerg for (cp = opt; *cp; cp++) 81719569Sjoerg if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_'; 81832316Syokota printf("/*\n" 81932316Syokota " * Automatically generated from %s.\n" 82032316Syokota " * DO NOT EDIT!\n" 82132316Syokota " */\n", name); 82232316Syokota dump_key_definition(opt, &keymap); 82332316Syokota dump_accent_definition(opt, &accentmap); 82419569Sjoerg return; 82519569Sjoerg } 82632316Syokota if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) { 82729603Scharnier warn("setting keymap"); 8282088Ssos fclose(fd); 8292088Ssos return; 8302088Ssos } 83132316Syokota if ((accentmap.n_accs > 0) 83232316Syokota && (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) { 83332316Syokota warn("setting accentmap"); 83432316Syokota fclose(fd); 83532316Syokota return; 83632316Syokota } 8372088Ssos} 8382088Ssos 839228437Sedstatic void 84099816Salfredprint_keymap(void) 8412088Ssos{ 84232316Syokota keymap_t keymap; 84332316Syokota accentmap_t accentmap; 8442088Ssos int i; 8452088Ssos 84632316Syokota if (ioctl(0, GIO_KEYMAP, &keymap) < 0) 84729603Scharnier err(1, "getting keymap"); 84832316Syokota if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0) 84932316Syokota memset(&accentmap, 0, sizeof(accentmap)); 8502088Ssos printf( 8512088Ssos"# alt\n" 8522088Ssos"# scan cntrl alt alt cntrl lock\n" 8532088Ssos"# code base shift cntrl shift alt shift cntrl shift state\n" 8542088Ssos"# ------------------------------------------------------------------\n" 8552088Ssos ); 85632316Syokota for (i=0; i<keymap.n_keys; i++) 85732316Syokota print_key_definition_line(stdout, i, &keymap.key[i]); 85832316Syokota 85932316Syokota printf("\n"); 86032316Syokota for (i = 0; i < NUM_DEADKEYS; i++) 86132316Syokota print_accent_definition_line(stdout, i, &accentmap.acc[i]); 86232316Syokota 8632088Ssos} 8642088Ssos 865228437Sedstatic void 86699816Salfredload_default_functionkeys(void) 8672088Ssos{ 8682088Ssos fkeyarg_t fkey; 8692088Ssos int i; 8702088Ssos 8712088Ssos for (i=0; i<NUM_FKEYS; i++) { 8722088Ssos fkey.keynum = i; 8732088Ssos strcpy(fkey.keydef, fkey_table[i]); 8742088Ssos fkey.flen = strlen(fkey_table[i]); 8752088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 87629603Scharnier warn("setting function key"); 8772088Ssos } 8782088Ssos} 8792088Ssos 880228437Sedstatic void 8812088Ssosset_functionkey(char *keynumstr, char *string) 8822088Ssos{ 8832088Ssos fkeyarg_t fkey; 8842088Ssos 8852088Ssos if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) { 8862088Ssos load_default_functionkeys(); 8872088Ssos return; 8882088Ssos } 8892088Ssos fkey.keynum = atoi(keynumstr); 8902088Ssos if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) { 89129603Scharnier warnx("function key number must be between 1 and %d", 8922088Ssos NUM_FKEYS); 8932088Ssos return; 8942088Ssos } 8952088Ssos if ((fkey.flen = strlen(string)) > MAXFK) { 89629603Scharnier warnx("function key string too long (%d > %d)", 8972088Ssos fkey.flen, MAXFK); 8982088Ssos return; 8992088Ssos } 900133353Sjmg strncpy(fkey.keydef, string, MAXFK); 9012088Ssos fkey.keynum -= 1; 9022088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 90329603Scharnier warn("setting function key"); 9042088Ssos} 9052088Ssos 906228437Sedstatic void 9072088Ssosset_bell_values(char *opt) 9082088Ssos{ 9095536Ssos int bell, duration, pitch; 9102088Ssos 91138044Syokota bell = 0; 91238044Syokota if (!strncmp(opt, "quiet.", 6)) { 913164333Sru bell = CONS_QUIET_BELL; 91438044Syokota opt += 6; 91538044Syokota } 9168857Srgrimes if (!strcmp(opt, "visual")) 917164333Sru bell |= CONS_VISUAL_BELL; 9185536Ssos else if (!strcmp(opt, "normal")) 91938044Syokota duration = 5, pitch = 800; 92048982Syokota else if (!strcmp(opt, "off")) 92148982Syokota duration = 0, pitch = 0; 9222088Ssos else { 9232088Ssos char *v1; 9248857Srgrimes 9255536Ssos bell = 0; 9262088Ssos duration = strtol(opt, &v1, 0); 9272088Ssos if ((duration < 0) || (*v1 != '.')) 9282088Ssos goto badopt; 9292088Ssos opt = ++v1; 9302088Ssos pitch = strtol(opt, &v1, 0); 9312088Ssos if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) { 9322088Ssosbadopt: 93377394Ssobomax warnx("argument to -b must be duration.pitch or [quiet.]visual|normal|off"); 9342088Ssos return; 9352088Ssos } 93638044Syokota if (pitch != 0) 93738044Syokota pitch = 1193182 / pitch; /* in Hz */ 93838044Syokota duration /= 10; /* in 10 m sec */ 9392088Ssos } 9402088Ssos 9415536Ssos ioctl(0, CONS_BELLTYPE, &bell); 942164333Sru if (!(bell & CONS_VISUAL_BELL)) 9435536Ssos fprintf(stderr, "[=%d;%dB", pitch, duration); 9442088Ssos} 9452088Ssos 946228437Sedstatic void 9472088Ssosset_keyrates(char *opt) 9482088Ssos{ 94944628Syokota int arg[2]; 95039047Syokota int repeat; 95139047Syokota int delay; 95246761Syokota int r, d; 9532088Ssos 95446761Syokota if (!strcmp(opt, "slow")) { 95544628Syokota delay = 1000, repeat = 500; 95646761Syokota d = 3, r = 31; 95746761Syokota } else if (!strcmp(opt, "normal")) { 95844628Syokota delay = 500, repeat = 125; 95946761Syokota d = 1, r = 15; 96046761Syokota } else if (!strcmp(opt, "fast")) { 96139047Syokota delay = repeat = 0; 96246761Syokota d = r = 0; 96346761Syokota } else { 9642088Ssos int n; 9652088Ssos char *v1; 9662088Ssos 9672088Ssos delay = strtol(opt, &v1, 0); 9682088Ssos if ((delay < 0) || (*v1 != '.')) 9692088Ssos goto badopt; 9702088Ssos opt = ++v1; 9712088Ssos repeat = strtol(opt, &v1, 0); 9722088Ssos if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) { 9732088Ssosbadopt: 97477394Ssobomax warnx("argument to -r must be delay.repeat or slow|normal|fast"); 9752088Ssos return; 9762088Ssos } 97746761Syokota for (n = 0; n < ndelays - 1; n++) 97846761Syokota if (delay <= delays[n]) 97946761Syokota break; 98046761Syokota d = n; 98146761Syokota for (n = 0; n < nrepeats - 1; n++) 98246761Syokota if (repeat <= repeats[n]) 98346761Syokota break; 98446761Syokota r = n; 9852088Ssos } 9862088Ssos 98744628Syokota arg[0] = delay; 98844628Syokota arg[1] = repeat; 98946761Syokota if (ioctl(0, KDSETREPEAT, arg)) { 99046761Syokota if (ioctl(0, KDSETRAD, (d << 5) | r)) 99146761Syokota warn("setting keyboard rate"); 99246761Syokota } 9932088Ssos} 9942088Ssos 99599816Salfredstatic const char * 99699816Salfredget_kbd_type_name(int type) 99742505Syokota{ 99842505Syokota static struct { 99942505Syokota int type; 100099816Salfred const char *name; 100142505Syokota } name_table[] = { 100242505Syokota { KB_84, "AT 84" }, 100342505Syokota { KB_101, "AT 101/102" }, 100442505Syokota { KB_OTHER, "generic" }, 100542505Syokota }; 100699816Salfred unsigned int i; 10076046Ssos 100842505Syokota for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) { 100942505Syokota if (type == name_table[i].type) 101042505Syokota return name_table[i].name; 101142505Syokota } 101242505Syokota return "unknown"; 101342505Syokota} 101442505Syokota 1015228437Sedstatic void 101642505Syokotashow_kbd_info(void) 101742505Syokota{ 101842505Syokota keyboard_info_t info; 101942505Syokota 102042505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 102142505Syokota warn("unable to obtain keyboard information"); 102242505Syokota return; 102342505Syokota } 102442505Syokota printf("kbd%d:\n", info.kb_index); 102542505Syokota printf(" %.*s%d, type:%s (%d)\n", 102677394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 102742505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 102842505Syokota} 102942505Syokota 1030228437Sedstatic void 103142505Syokotaset_keyboard(char *device) 103242505Syokota{ 103342505Syokota keyboard_info_t info; 103442505Syokota int fd; 103542505Syokota 103642505Syokota fd = open(device, O_RDONLY); 103742505Syokota if (fd < 0) { 103842505Syokota warn("cannot open %s", device); 103942505Syokota return; 104042505Syokota } 104142505Syokota if (ioctl(fd, KDGKBINFO, &info) == -1) { 104242505Syokota warn("unable to obtain keyboard information"); 104342505Syokota close(fd); 104442505Syokota return; 104542505Syokota } 104642505Syokota /* 104742505Syokota * The keyboard device driver won't release the keyboard by 104842505Syokota * the following ioctl, but it automatically will, when the device 104942505Syokota * is closed. So, we don't check error here. 105042505Syokota */ 105142505Syokota ioctl(fd, CONS_RELKBD, 0); 105242505Syokota close(fd); 105342505Syokota#if 1 105442505Syokota printf("kbd%d\n", info.kb_index); 105542505Syokota printf(" %.*s%d, type:%s (%d)\n", 105677394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 105742505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 105842505Syokota#endif 105942505Syokota 106042505Syokota if (ioctl(0, CONS_SETKBD, info.kb_index) == -1) 106142505Syokota warn("unable to set keyboard"); 106242505Syokota} 106342505Syokota 1064228437Sedstatic void 106542505Syokotarelease_keyboard(void) 106642505Syokota{ 106742505Syokota keyboard_info_t info; 106842505Syokota 106942505Syokota /* 107042505Syokota * If stdin is not associated with a keyboard, the following ioctl 107142505Syokota * will fail. 107242505Syokota */ 107342505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 107442505Syokota warn("unable to obtain keyboard information"); 107542505Syokota return; 107642505Syokota } 107742505Syokota#if 1 107842505Syokota printf("kbd%d\n", info.kb_index); 107942505Syokota printf(" %.*s%d, type:%s (%d)\n", 108077394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 108142505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 108242505Syokota#endif 108342505Syokota if (ioctl(0, CONS_RELKBD, 0) == -1) 108442505Syokota warn("unable to release the keyboard"); 108542505Syokota} 108642505Syokota 1087228437Sedstatic void 1088162327Semaxmux_keyboard(u_int op, char *kbd) 1089148017Semax{ 1090148017Semax keyboard_info_t info; 1091148017Semax char *unit, *ep; 109242505Syokota 1093148017Semax /* 1094148017Semax * If stdin is not associated with a keyboard, the following ioctl 1095148017Semax * will fail. 1096148017Semax */ 1097148017Semax if (ioctl(0, KDGKBINFO, &info) == -1) { 1098148017Semax warn("unable to obtain keyboard information"); 1099148017Semax return; 1100148017Semax } 1101148017Semax#if 1 1102148017Semax printf("kbd%d\n", info.kb_index); 1103148017Semax printf(" %.*s%d, type:%s (%d)\n", 1104148017Semax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 1105148017Semax get_kbd_type_name(info.kb_type), info.kb_type); 1106148017Semax#endif 1107148017Semax /* 1108148017Semax * split kbd into name and unit. find the right most part of the 1109148017Semax * kbd string that consist of only digits. 1110148017Semax */ 1111148017Semax 1112148017Semax memset(&info, 0, sizeof(info)); 1113148017Semax 1114148017Semax info.kb_unit = -1; 1115148017Semax ep = kbd - 1; 1116148017Semax 1117148017Semax do { 1118148017Semax unit = strpbrk(ep + 1, "0123456789"); 1119148017Semax if (unit != NULL) { 1120148017Semax info.kb_unit = strtol(unit, &ep, 10); 1121148017Semax if (*ep != '\0') 1122148017Semax info.kb_unit = -1; 1123148017Semax } 1124148017Semax } while (unit != NULL && info.kb_unit == -1); 1125148017Semax 1126148017Semax if (info.kb_unit == -1) { 1127148017Semax warnx("unable to find keyboard driver unit in '%s'", kbd); 1128148017Semax return; 1129148017Semax } 1130148017Semax 1131148017Semax if (unit == kbd) { 1132148017Semax warnx("unable to find keyboard driver name in '%s'", kbd); 1133148017Semax return; 1134148017Semax } 1135148017Semax if (unit - kbd >= (int) sizeof(info.kb_name)) { 1136148017Semax warnx("keyboard name '%s' is too long", kbd); 1137148017Semax return; 1138148017Semax } 1139148017Semax 1140148017Semax strncpy(info.kb_name, kbd, unit - kbd); 1141148017Semax 1142148017Semax /* 1143148017Semax * If stdin is not associated with a kbdmux(4) keyboard, the following 1144148017Semax * ioctl will fail. 1145148017Semax */ 1146148017Semax 1147148017Semax if (ioctl(0, op, &info) == -1) 1148148017Semax warn("unable to (un)mux the keyboard"); 1149148017Semax} 1150148017Semax 1151228437Sedstatic void 1152201387Sedusage(void) 11532088Ssos{ 115429603Scharnier fprintf(stderr, "%s\n%s\n%s\n", 1155148017Semax"usage: kbdcontrol [-dFKix] [-A name] [-a name] [-b duration.pitch | [quiet.]belltype]", 115629603Scharnier" [-r delay.repeat | speed] [-l mapfile] [-f # string]", 115777329Sdes" [-k device] [-L mapfile]"); 115829603Scharnier exit(1); 11592088Ssos} 11602088Ssos 11612088Ssos 116251287Speterint 11632088Ssosmain(int argc, char **argv) 11642088Ssos{ 11652088Ssos int opt; 11662088Ssos 1167148017Semax while((opt = getopt(argc, argv, "A:a:b:df:iKk:Fl:L:r:x")) != -1) 11682088Ssos switch(opt) { 1169148017Semax case 'A': 1170148017Semax case 'a': 1171148017Semax mux_keyboard((opt == 'A')? KBRELKBD : KBADDKBD, optarg); 1172148017Semax break; 117377329Sdes case 'b': 117477329Sdes set_bell_values(optarg); 117577329Sdes break; 117677329Sdes case 'd': 117777329Sdes print_keymap(); 117877329Sdes break; 117977329Sdes case 'l': 118077329Sdes load_keymap(optarg, 0); 118177329Sdes break; 118277329Sdes case 'L': 118377329Sdes load_keymap(optarg, 1); 118477329Sdes break; 118577329Sdes case 'f': 118677329Sdes set_functionkey(optarg, 118777329Sdes nextarg(argc, argv, &optind, 'f')); 118877329Sdes break; 118977329Sdes case 'F': 119077329Sdes load_default_functionkeys(); 119177329Sdes break; 119277329Sdes case 'i': 119377329Sdes show_kbd_info(); 119477329Sdes break; 119577329Sdes case 'K': 119677329Sdes release_keyboard(); 119777329Sdes break; 119877329Sdes case 'k': 119977329Sdes set_keyboard(optarg); 120077329Sdes break; 120177329Sdes case 'r': 120277329Sdes set_keyrates(optarg); 120377329Sdes break; 120477329Sdes case 'x': 120577329Sdes hex = 1; 120677329Sdes break; 120777329Sdes default: 120877329Sdes usage(); 12092088Ssos } 121029603Scharnier if ((optind != argc) || (argc == 1)) 12112088Ssos usage(); 12122088Ssos exit(0); 12132088Ssos} 1214