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> 41298297Semaste#include <sys/queue.h> 42267540Sray#include <sys/sysctl.h> 432088Ssos#include "path.h" 442088Ssos#include "lex.h" 452088Ssos 4676643Simp/* 4790394Sru * HALT, PDWN, and PASTE aren't defined in 4.x, but we need them to bridge 4890394Sru * to 5.0-current so define them here as a stop gap transition measure. 4976643Simp */ 5090394Sru#ifndef HALT 5190394Sru#define HALT 0xa1 /* halt machine */ 5290394Sru#endif 5390394Sru#ifndef PDWN 5490394Sru#define PDWN 0xa2 /* halt machine and power down */ 5590394Sru#endif 5676643Simp#ifndef PASTE 5776643Simp#define PASTE 0xa3 /* paste from cut-paste buffer */ 5876643Simp#endif 5976643Simp 60196500Sed#define SPECIAL 0x80000000 61196500Sed 62228437Sedstatic const char ctrl_names[32][4] = { 638857Srgrimes "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 642088Ssos "bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ", 652088Ssos "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 6638139Syokota "can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "us " 672088Ssos }; 682088Ssos 69228437Sedstatic const char acc_names[15][5] = { 7032316Syokota "dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot", 7132316Syokota "duml", "dsla", "drin", "dced", "dapo", "ddac", "dogo", 7232316Syokota "dcar", 7332316Syokota }; 7432316Syokota 75228437Sedstatic const char acc_names_u[15][5] = { 7632316Syokota "DGRA", "DACU", "DCIR", "DTIL", "DMAC", "DBRE", "DDOT", 7732316Syokota "DUML", "DSLA", "DRIN", "DCED", "DAPO", "DDAC", "DOGO", 7832316Syokota "DCAR", 7932316Syokota }; 8032316Syokota 81228437Sedstatic const char fkey_table[96][MAXFK] = { 825994Ssos/* 01-04 */ "\033[M", "\033[N", "\033[O", "\033[P", 835994Ssos/* 05-08 */ "\033[Q", "\033[R", "\033[S", "\033[T", 845994Ssos/* 09-12 */ "\033[U", "\033[V", "\033[W", "\033[X", 855994Ssos/* 13-16 */ "\033[Y", "\033[Z", "\033[a", "\033[b", 865994Ssos/* 17-20 */ "\033[c", "\033[d", "\033[e", "\033[f", 875994Ssos/* 21-24 */ "\033[g", "\033[h", "\033[i", "\033[j", 885994Ssos/* 25-28 */ "\033[k", "\033[l", "\033[m", "\033[n", 895994Ssos/* 29-32 */ "\033[o", "\033[p", "\033[q", "\033[r", 905994Ssos/* 33-36 */ "\033[s", "\033[t", "\033[u", "\033[v", 915994Ssos/* 37-40 */ "\033[w", "\033[x", "\033[y", "\033[z", 925994Ssos/* 41-44 */ "\033[@", "\033[[", "\033[\\","\033[]", 939202Srgrimes/* 45-48 */ "\033[^", "\033[_", "\033[`", "\033[{", 945994Ssos/* 49-52 */ "\033[H", "\033[A", "\033[I", "-" , 955994Ssos/* 53-56 */ "\033[D", "\033[E", "\033[C", "+" , 965994Ssos/* 57-60 */ "\033[F", "\033[B", "\033[G", "\033[L", 979202Srgrimes/* 61-64 */ "\177", "\033[J", "\033[~", "\033[}", 985994Ssos/* 65-68 */ "" , "" , "" , "" , 995994Ssos/* 69-72 */ "" , "" , "" , "" , 1005994Ssos/* 73-76 */ "" , "" , "" , "" , 1015994Ssos/* 77-80 */ "" , "" , "" , "" , 1025994Ssos/* 81-84 */ "" , "" , "" , "" , 1035994Ssos/* 85-88 */ "" , "" , "" , "" , 1045994Ssos/* 89-92 */ "" , "" , "" , "" , 1055994Ssos/* 93-96 */ "" , "" , "" , "" , 1062088Ssos }; 1072088Ssos 108228437Sedstatic const int delays[] = {250, 500, 750, 1000}; 109228437Sedstatic const int repeats[] = { 34, 38, 42, 46, 50, 55, 59, 63, 110228437Sed 68, 76, 84, 92, 100, 110, 118, 126, 111228437Sed 136, 152, 168, 184, 200, 220, 236, 252, 112228437Sed 272, 304, 336, 368, 400, 440, 472, 504}; 113228437Sedstatic const int ndelays = (sizeof(delays) / sizeof(int)); 114228437Sedstatic const int nrepeats = (sizeof(repeats) / sizeof(int)); 115228437Sedstatic int hex = 0; 116298297Semastestatic int paths_configured = 0; 117228437Sedstatic int token; 1182088Ssos 119228437Sedint number; 120228437Sedchar letter; 1212088Ssos 122298297Semastestatic void add_keymap_path(const char *path); 123228437Sedstatic void dump_accent_definition(char *name, accentmap_t *accentmap); 124228437Sedstatic void dump_entry(int value); 125228437Sedstatic void dump_key_definition(char *name, keymap_t *keymap); 126228437Sedstatic int get_accent_definition_line(accentmap_t *); 127228437Sedstatic int get_entry(void); 128228437Sedstatic int get_key_definition_line(keymap_t *); 129228437Sedstatic void load_keymap(char *opt, int dumponly); 130228437Sedstatic void load_default_functionkeys(void); 131228437Sedstatic char * nextarg(int ac, char **av, int *indp, int oc); 132228437Sedstatic char * mkfullname(const char *s1, const char *s2, const char *s3); 133228437Sedstatic void print_accent_definition_line(FILE *fp, int accent, 134228437Sed struct acc_t *key); 135228437Sedstatic void print_entry(FILE *fp, int value); 136228437Sedstatic void print_key_definition_line(FILE *fp, int scancode, 137228437Sed struct keyent_t *key); 138228437Sedstatic void print_keymap(void); 139228437Sedstatic void release_keyboard(void); 140228437Sedstatic void mux_keyboard(u_int op, char *kbd); 141228437Sedstatic void set_bell_values(char *opt); 142228437Sedstatic void set_functionkey(char *keynumstr, char *string); 143228437Sedstatic void set_keyboard(char *device); 144228437Sedstatic void set_keyrates(char *opt); 145228437Sedstatic void show_kbd_info(void); 146228437Sedstatic void usage(void) __dead2; 147228437Sed 148298297Semastestruct pathent { 149298297Semaste STAILQ_ENTRY(pathent) next; 150298297Semaste char *path; 151298297Semaste}; 152298297Semastestatic STAILQ_HEAD(, pathent) pathlist = STAILQ_HEAD_INITIALIZER(pathlist); 153298297Semaste 154267540Sray/* Detect presence of vt(4). */ 155267540Sraystatic int 156267540Srayis_vt4(void) 157267540Sray{ 158268366Sray char vty_name[4] = ""; 159268366Sray size_t len = sizeof(vty_name); 160267540Sray 161268366Sray if (sysctlbyname("kern.vty", vty_name, &len, NULL, 0) != 0) 162268366Sray return (0); 163268366Sray return (strcmp(vty_name, "vt") == 0); 164267540Sray} 165267540Sray 166228437Sedstatic char * 1672088Ssosnextarg(int ac, char **av, int *indp, int oc) 1682088Ssos{ 1692088Ssos if (*indp < ac) 1702088Ssos return(av[(*indp)++]); 17129603Scharnier warnx("option requires two arguments -- %c", oc); 1722088Ssos usage(); 1732088Ssos} 1742088Ssos 1752088Ssos 176228437Sedstatic char * 1772088Ssosmkfullname(const char *s1, const char *s2, const char *s3) 1782088Ssos{ 1795536Ssos static char *buf = NULL; 1805536Ssos static int bufl = 0; 1815536Ssos int f; 1822088Ssos 1832088Ssos f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 18477394Ssobomax if (f > bufl) { 1852088Ssos if (buf) 1862088Ssos buf = (char *)realloc(buf, f); 1872088Ssos else 1882088Ssos buf = (char *)malloc(f); 18977394Ssobomax } 1902088Ssos if (!buf) { 1912088Ssos bufl = 0; 1922088Ssos return(NULL); 1932088Ssos } 1942088Ssos 1952088Ssos bufl = f; 1962088Ssos strcpy(buf, s1); 1972088Ssos strcat(buf, s2); 1982088Ssos strcat(buf, s3); 1992088Ssos return(buf); 2002088Ssos} 2012088Ssos 2022088Ssos 203228437Sedstatic int 20499816Salfredget_entry(void) 2052088Ssos{ 20632316Syokota switch ((token = yylex())) { 2072088Ssos case TNOP: 208196500Sed return NOP | SPECIAL; 2092088Ssos case TLSH: 210196500Sed return LSH | SPECIAL; 2112088Ssos case TRSH: 212196500Sed return RSH | SPECIAL; 2132088Ssos case TCLK: 214196500Sed return CLK | SPECIAL; 2152088Ssos case TNLK: 216196500Sed return NLK | SPECIAL; 2172088Ssos case TSLK: 218196500Sed return SLK | SPECIAL; 2192088Ssos case TBTAB: 220196500Sed return BTAB | SPECIAL; 2212088Ssos case TLALT: 222196500Sed return LALT | SPECIAL; 2232088Ssos case TLCTR: 224196500Sed return LCTR | SPECIAL; 2252088Ssos case TNEXT: 226196500Sed return NEXT | SPECIAL; 22748105Syokota case TPREV: 228196500Sed return PREV | SPECIAL; 2292088Ssos case TRCTR: 230196500Sed return RCTR | SPECIAL; 2312088Ssos case TRALT: 232196500Sed return RALT | SPECIAL; 2332088Ssos case TALK: 234196500Sed return ALK | SPECIAL; 2352088Ssos case TASH: 236196500Sed return ASH | SPECIAL; 2372088Ssos case TMETA: 238196500Sed return META | SPECIAL; 2392088Ssos case TRBT: 240196500Sed return RBT | SPECIAL; 2412088Ssos case TDBG: 242196500Sed return DBG | SPECIAL; 2435994Ssos case TSUSP: 244196500Sed return SUSP | SPECIAL; 24538053Syokota case TSPSC: 246196500Sed return SPSC | SPECIAL; 24754380Syokota case TPANIC: 248196500Sed return PNC | SPECIAL; 24954380Syokota case TLSHA: 250196500Sed return LSHA | SPECIAL; 25154380Syokota case TRSHA: 252196500Sed return RSHA | SPECIAL; 25354380Syokota case TLCTRA: 254196500Sed return LCTRA | SPECIAL; 25554380Syokota case TRCTRA: 256196500Sed return RCTRA | SPECIAL; 25754380Syokota case TLALTA: 258196500Sed return LALTA | SPECIAL; 25954380Syokota case TRALTA: 260196500Sed return RALTA | SPECIAL; 26165759Sdwmalone case THALT: 262196500Sed return HALT | SPECIAL; 26365759Sdwmalone case TPDWN: 264196500Sed return PDWN | SPECIAL; 26574118Sache case TPASTE: 266196500Sed return PASTE | SPECIAL; 26732316Syokota case TACC: 26832316Syokota if (ACC(number) > L_ACC) 26932316Syokota return -1; 270196500Sed return ACC(number) | SPECIAL; 2712088Ssos case TFUNC: 2722088Ssos if (F(number) > L_FN) 2732088Ssos return -1; 274196500Sed return F(number) | SPECIAL; 2752088Ssos case TSCRN: 2762088Ssos if (S(number) > L_SCR) 2772088Ssos return -1; 278196500Sed return S(number) | SPECIAL; 2792088Ssos case TLET: 2802088Ssos return (unsigned char)letter; 2812088Ssos case TNUM: 282197330Sed if (number < 0x000000 || number > 0x10FFFF) 2832088Ssos return -1; 2842088Ssos return number; 2852088Ssos default: 2862088Ssos return -1; 2872088Ssos } 2882088Ssos} 2892088Ssos 29077394Ssobomaxstatic int 291298297Semasteget_definition_line(FILE *file, keymap_t *keymap, accentmap_t *accentmap) 2922088Ssos{ 29332316Syokota int c; 2942088Ssos 295298297Semaste yyin = file; 2962088Ssos 29732316Syokota if (token < 0) 29832316Syokota token = yylex(); 29932316Syokota switch (token) { 30032316Syokota case TNUM: 30132316Syokota c = get_key_definition_line(keymap); 30232316Syokota if (c < 0) 30332316Syokota errx(1, "invalid key definition"); 30432316Syokota if (c > keymap->n_keys) 30532316Syokota keymap->n_keys = c; 30632316Syokota break; 30732316Syokota case TACC: 30832316Syokota c = get_accent_definition_line(accentmap); 30932316Syokota if (c < 0) 31032316Syokota errx(1, "invalid accent key definition"); 31132316Syokota if (c > accentmap->n_accs) 31232316Syokota accentmap->n_accs = c; 31332316Syokota break; 31432316Syokota case 0: 31532316Syokota /* EOF */ 3162088Ssos return -1; 31732316Syokota default: 31832316Syokota errx(1, "illegal definition line"); 31932316Syokota } 32032316Syokota return c; 32132316Syokota} 32232316Syokota 323228437Sedstatic int 32432316Syokotaget_key_definition_line(keymap_t *map) 32532316Syokota{ 32632316Syokota int i, def, scancode; 32732316Syokota 32832316Syokota /* check scancode number */ 3292088Ssos if (number < 0 || number >= NUM_KEYS) 3302088Ssos return -1; 3312088Ssos scancode = number; 3322088Ssos 3332088Ssos /* get key definitions */ 3342088Ssos map->key[scancode].spcl = 0; 3352088Ssos for (i=0; i<NUM_STATES; i++) { 3362088Ssos if ((def = get_entry()) == -1) 3372088Ssos return -1; 338196500Sed if (def & SPECIAL) 3392088Ssos map->key[scancode].spcl |= (0x80 >> i); 340196500Sed map->key[scancode].map[i] = def & ~SPECIAL; 3412088Ssos } 3422088Ssos /* get lock state key def */ 34332316Syokota if ((token = yylex()) != TFLAG) 3442088Ssos return -1; 3452088Ssos map->key[scancode].flgs = number; 34632316Syokota token = yylex(); 34732316Syokota return (scancode + 1); 3482088Ssos} 3492088Ssos 350228437Sedstatic int 35132316Syokotaget_accent_definition_line(accentmap_t *map) 35232316Syokota{ 35332316Syokota int accent; 35432316Syokota int c1, c2; 35532316Syokota int i; 3562088Ssos 35732316Syokota if (ACC(number) < F_ACC || ACC(number) > L_ACC) 35832316Syokota /* number out of range */ 35932316Syokota return -1; 36032316Syokota accent = number; 36132316Syokota if (map->acc[accent].accchar != 0) { 36232316Syokota /* this entry has already been defined before! */ 36332316Syokota errx(1, "duplicated accent key definition"); 36432316Syokota } 36532316Syokota 36632316Syokota switch ((token = yylex())) { 36732316Syokota case TLET: 36832316Syokota map->acc[accent].accchar = letter; 36932316Syokota break; 37032316Syokota case TNUM: 37132316Syokota map->acc[accent].accchar = number; 37232316Syokota break; 37332316Syokota default: 37432316Syokota return -1; 37532316Syokota } 37632316Syokota 37732316Syokota for (i = 0; (token = yylex()) == '(';) { 37832316Syokota switch ((token = yylex())) { 37932316Syokota case TLET: 38032316Syokota c1 = letter; 38132316Syokota break; 38232316Syokota case TNUM: 38332316Syokota c1 = number; 38432316Syokota break; 38532316Syokota default: 38632316Syokota return -1; 38732316Syokota } 38832316Syokota switch ((token = yylex())) { 38932316Syokota case TLET: 39032316Syokota c2 = letter; 39132316Syokota break; 39232316Syokota case TNUM: 39332316Syokota c2 = number; 39432316Syokota break; 39532316Syokota default: 39632316Syokota return -1; 39732316Syokota } 39832316Syokota if ((token = yylex()) != ')') 39932316Syokota return -1; 40032316Syokota if (i >= NUM_ACCENTCHARS) { 40132316Syokota warnx("too many accented characters, ignored"); 40232316Syokota continue; 40332316Syokota } 40432316Syokota map->acc[accent].map[i][0] = c1; 40532316Syokota map->acc[accent].map[i][1] = c2; 40632316Syokota ++i; 40732316Syokota } 40832316Syokota return (accent + 1); 40932316Syokota} 41032316Syokota 411228437Sedstatic void 4122088Ssosprint_entry(FILE *fp, int value) 4132088Ssos{ 414196500Sed int val = value & ~SPECIAL; 4152088Ssos 4162088Ssos switch (value) { 417196500Sed case NOP | SPECIAL: 4188857Srgrimes fprintf(fp, " nop "); 4192088Ssos break; 420196500Sed case LSH | SPECIAL: 4212088Ssos fprintf(fp, " lshift"); 4222088Ssos break; 423196500Sed case RSH | SPECIAL: 4242088Ssos fprintf(fp, " rshift"); 4252088Ssos break; 426196500Sed case CLK | SPECIAL: 4272088Ssos fprintf(fp, " clock "); 4282088Ssos break; 429196500Sed case NLK | SPECIAL: 4302088Ssos fprintf(fp, " nlock "); 4312088Ssos break; 432196500Sed case SLK | SPECIAL: 4332088Ssos fprintf(fp, " slock "); 4342088Ssos break; 435196500Sed case BTAB | SPECIAL: 4362088Ssos fprintf(fp, " btab "); 4372088Ssos break; 438196500Sed case LALT | SPECIAL: 4392088Ssos fprintf(fp, " lalt "); 4402088Ssos break; 441196500Sed case LCTR | SPECIAL: 4422088Ssos fprintf(fp, " lctrl "); 4432088Ssos break; 444196500Sed case NEXT | SPECIAL: 4452088Ssos fprintf(fp, " nscr "); 4462088Ssos break; 447196500Sed case PREV | SPECIAL: 44848105Syokota fprintf(fp, " pscr "); 44948105Syokota break; 450196500Sed case RCTR | SPECIAL: 4512088Ssos fprintf(fp, " rctrl "); 4522088Ssos break; 453196500Sed case RALT | SPECIAL: 4542088Ssos fprintf(fp, " ralt "); 4552088Ssos break; 456196500Sed case ALK | SPECIAL: 4572088Ssos fprintf(fp, " alock "); 4582088Ssos break; 459196500Sed case ASH | SPECIAL: 4602088Ssos fprintf(fp, " ashift"); 4612088Ssos break; 462196500Sed case META | SPECIAL: 4632088Ssos fprintf(fp, " meta "); 4642088Ssos break; 465196500Sed case RBT | SPECIAL: 4662088Ssos fprintf(fp, " boot "); 4672088Ssos break; 468196500Sed case DBG | SPECIAL: 4692088Ssos fprintf(fp, " debug "); 4702088Ssos break; 471196500Sed case SUSP | SPECIAL: 47232316Syokota fprintf(fp, " susp "); 47332316Syokota break; 474196500Sed case SPSC | SPECIAL: 47538053Syokota fprintf(fp, " saver "); 47638053Syokota break; 477196500Sed case PNC | SPECIAL: 47854380Syokota fprintf(fp, " panic "); 47954380Syokota break; 480196500Sed case LSHA | SPECIAL: 48154380Syokota fprintf(fp, " lshifta"); 48254380Syokota break; 483196500Sed case RSHA | SPECIAL: 48454380Syokota fprintf(fp, " rshifta"); 48554380Syokota break; 486196500Sed case LCTRA | SPECIAL: 48754380Syokota fprintf(fp, " lctrla"); 48854380Syokota break; 489196500Sed case RCTRA | SPECIAL: 49054380Syokota fprintf(fp, " rctrla"); 49154380Syokota break; 492196500Sed case LALTA | SPECIAL: 49354380Syokota fprintf(fp, " lalta "); 49454380Syokota break; 495196500Sed case RALTA | SPECIAL: 49654380Syokota fprintf(fp, " ralta "); 49754380Syokota break; 498196500Sed case HALT | SPECIAL: 49965759Sdwmalone fprintf(fp, " halt "); 50065759Sdwmalone break; 501196500Sed case PDWN | SPECIAL: 50265759Sdwmalone fprintf(fp, " pdwn "); 50365759Sdwmalone break; 504196500Sed case PASTE | SPECIAL: 50574118Sache fprintf(fp, " paste "); 50674118Sache break; 5072088Ssos default: 508196500Sed if (value & SPECIAL) { 5098857Srgrimes if (val >= F_FN && val <= L_FN) 5102088Ssos fprintf(fp, " fkey%02d", val - F_FN + 1); 5118857Srgrimes else if (val >= F_SCR && val <= L_SCR) 5122088Ssos fprintf(fp, " scr%02d ", val - F_SCR + 1); 51332316Syokota else if (val >= F_ACC && val <= L_ACC) 51432316Syokota fprintf(fp, " %-6s", acc_names[val - F_ACC]); 5152088Ssos else if (hex) 5168857Srgrimes fprintf(fp, " 0x%02x ", val); 5172088Ssos else 51832316Syokota fprintf(fp, " %3d ", val); 5192088Ssos } 5202088Ssos else { 5212088Ssos if (val < ' ') 5228857Srgrimes fprintf(fp, " %s ", ctrl_names[val]); 5232088Ssos else if (val == 127) 5248857Srgrimes fprintf(fp, " del "); 5259202Srgrimes else if (isascii(val) && isprint(val)) 5268857Srgrimes fprintf(fp, " '%c' ", val); 5272088Ssos else if (hex) 5288857Srgrimes fprintf(fp, " 0x%02x ", val); 5292088Ssos else 5308857Srgrimes fprintf(fp, " %3d ", val); 5312088Ssos } 5322088Ssos } 5332088Ssos} 5342088Ssos 535228437Sedstatic void 53642505Syokotaprint_key_definition_line(FILE *fp, int scancode, struct keyent_t *key) 5372088Ssos{ 53829603Scharnier int i; 5392088Ssos 5402088Ssos /* print scancode number */ 5412088Ssos if (hex) 5422088Ssos fprintf(fp, " 0x%02x ", scancode); 5432088Ssos else 5442088Ssos fprintf(fp, " %03d ", scancode); 5452088Ssos 5462088Ssos /* print key definitions */ 5472088Ssos for (i=0; i<NUM_STATES; i++) { 5482088Ssos if (key->spcl & (0x80 >> i)) 549196500Sed print_entry(fp, key->map[i] | SPECIAL); 5502088Ssos else 5518857Srgrimes print_entry(fp, key->map[i]); 5522088Ssos } 5532088Ssos 5542088Ssos /* print lock state key def */ 5552088Ssos switch (key->flgs) { 5562088Ssos case 0: 5572088Ssos fprintf(fp, " O\n"); 5582088Ssos break; 5592088Ssos case 1: 5602088Ssos fprintf(fp, " C\n"); 5612088Ssos break; 5622088Ssos case 2: 5632088Ssos fprintf(fp, " N\n"); 5642088Ssos break; 5656046Ssos case 3: 5666046Ssos fprintf(fp, " B\n"); 5676046Ssos break; 5688857Srgrimes } 5692088Ssos} 5702088Ssos 571228437Sedstatic void 57232316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key) 57332316Syokota{ 57432316Syokota int c; 57532316Syokota int i; 5762088Ssos 57732316Syokota if (key->accchar == 0) 57832316Syokota return; 57932316Syokota 58032316Syokota /* print accent number */ 58132316Syokota fprintf(fp, " %-6s", acc_names[accent]); 58232316Syokota if (isascii(key->accchar) && isprint(key->accchar)) 58332316Syokota fprintf(fp, "'%c' ", key->accchar); 58432316Syokota else if (hex) 58532316Syokota fprintf(fp, "0x%02x ", key->accchar); 58632316Syokota else 58732316Syokota fprintf(fp, "%03d ", key->accchar); 58832316Syokota 58932316Syokota for (i = 0; i < NUM_ACCENTCHARS; ++i) { 59032316Syokota c = key->map[i][0]; 59132316Syokota if (c == 0) 59232316Syokota break; 59332316Syokota if ((i > 0) && ((i % 4) == 0)) 59432316Syokota fprintf(fp, "\n "); 59532316Syokota if (isascii(c) && isprint(c)) 59632316Syokota fprintf(fp, "( '%c' ", c); 59732316Syokota else if (hex) 59832316Syokota fprintf(fp, "(0x%02x ", c); 59932316Syokota else 60032316Syokota fprintf(fp, "( %03d ", c); 60132316Syokota c = key->map[i][1]; 60232316Syokota if (isascii(c) && isprint(c)) 60332316Syokota fprintf(fp, "'%c' ) ", c); 60432316Syokota else if (hex) 60532316Syokota fprintf(fp, "0x%02x) ", c); 60632316Syokota else 60732316Syokota fprintf(fp, "%03d ) ", c); 60832316Syokota } 60932316Syokota fprintf(fp, "\n"); 61032316Syokota} 61132316Syokota 612228437Sedstatic void 61332316Syokotadump_entry(int value) 61432316Syokota{ 615196500Sed if (value & SPECIAL) { 616196500Sed value &= ~SPECIAL; 61732316Syokota switch (value) { 61832316Syokota case NOP: 61932316Syokota printf(" NOP, "); 62032316Syokota break; 62132316Syokota case LSH: 62232316Syokota printf(" LSH, "); 62332316Syokota break; 62432316Syokota case RSH: 62532316Syokota printf(" RSH, "); 62632316Syokota break; 62732316Syokota case CLK: 62832316Syokota printf(" CLK, "); 62932316Syokota break; 63032316Syokota case NLK: 63132316Syokota printf(" NLK, "); 63232316Syokota break; 63332316Syokota case SLK: 63432316Syokota printf(" SLK, "); 63532316Syokota break; 63632316Syokota case BTAB: 63732316Syokota printf(" BTAB, "); 63832316Syokota break; 63932316Syokota case LALT: 64032316Syokota printf(" LALT, "); 64132316Syokota break; 64232316Syokota case LCTR: 64332316Syokota printf(" LCTR, "); 64432316Syokota break; 64532316Syokota case NEXT: 64632316Syokota printf(" NEXT, "); 64732316Syokota break; 64848105Syokota case PREV: 64948105Syokota printf(" PREV, "); 65048105Syokota break; 65132316Syokota case RCTR: 65232316Syokota printf(" RCTR, "); 65332316Syokota break; 65432316Syokota case RALT: 65532316Syokota printf(" RALT, "); 65632316Syokota break; 65732316Syokota case ALK: 65832316Syokota printf(" ALK, "); 65932316Syokota break; 66032316Syokota case ASH: 66132316Syokota printf(" ASH, "); 66232316Syokota break; 66332316Syokota case META: 66432316Syokota printf(" META, "); 66532316Syokota break; 66632316Syokota case RBT: 66732316Syokota printf(" RBT, "); 66832316Syokota break; 66932316Syokota case DBG: 67032316Syokota printf(" DBG, "); 67132316Syokota break; 67232316Syokota case SUSP: 67332316Syokota printf(" SUSP, "); 67432316Syokota break; 67538053Syokota case SPSC: 67638053Syokota printf(" SPSC, "); 67738053Syokota break; 67854380Syokota case PNC: 67954380Syokota printf(" PNC, "); 68054380Syokota break; 68154380Syokota case LSHA: 68254380Syokota printf(" LSHA, "); 68354380Syokota break; 68454380Syokota case RSHA: 68554380Syokota printf(" RSHA, "); 68654380Syokota break; 68754380Syokota case LCTRA: 68854380Syokota printf("LCTRA, "); 68954380Syokota break; 69054380Syokota case RCTRA: 69154380Syokota printf("RCTRA, "); 69254380Syokota break; 69354380Syokota case LALTA: 69454380Syokota printf("LALTA, "); 69554380Syokota break; 69654380Syokota case RALTA: 69754380Syokota printf("RALTA, "); 69854380Syokota break; 69965759Sdwmalone case HALT: 70065759Sdwmalone printf(" HALT, "); 70165759Sdwmalone break; 70265759Sdwmalone case PDWN: 70365759Sdwmalone printf(" PDWN, "); 70465759Sdwmalone break; 70574118Sache case PASTE: 70674118Sache printf("PASTE, "); 70774118Sache break; 70832316Syokota default: 70932316Syokota if (value >= F_FN && value <= L_FN) 71032316Syokota printf(" F(%2d),", value - F_FN + 1); 71132316Syokota else if (value >= F_SCR && value <= L_SCR) 71232486Syokota printf(" S(%2d),", value - F_SCR + 1); 71332316Syokota else if (value >= F_ACC && value <= L_ACC) 71432316Syokota printf(" %-4s, ", acc_names_u[value - F_ACC]); 71532316Syokota else 71632316Syokota printf(" 0x%02X, ", value); 71732316Syokota break; 71832316Syokota } 71932316Syokota } else if (value == '\'') { 72032316Syokota printf(" '\\'', "); 72132316Syokota } else if (value == '\\') { 72232316Syokota printf(" '\\\\', "); 72332316Syokota } else if (isascii(value) && isprint(value)) { 72432316Syokota printf(" '%c', ", value); 72532316Syokota } else { 72632316Syokota printf(" 0x%02X, ", value); 72732316Syokota } 72832316Syokota} 72932316Syokota 730228437Sedstatic void 73132316Syokotadump_key_definition(char *name, keymap_t *keymap) 73232316Syokota{ 73332316Syokota int i, j; 73432316Syokota 73532486Syokota printf("static keymap_t keymap_%s = { 0x%02x, {\n", 73632316Syokota name, (unsigned)keymap->n_keys); 73732316Syokota printf( 73832486Syokota"/* alt\n" 73932486Syokota" * scan cntrl alt alt cntrl\n" 74032486Syokota" * code base shift cntrl shift alt shift cntrl shift spcl flgs\n" 74132316Syokota" * ---------------------------------------------------------------------------\n" 74232316Syokota" */\n"); 74332316Syokota for (i = 0; i < keymap->n_keys; i++) { 74432486Syokota printf("/*%02x*/{{", i); 74532316Syokota for (j = 0; j < NUM_STATES; j++) { 74632316Syokota if (keymap->key[i].spcl & (0x80 >> j)) 747196500Sed dump_entry(keymap->key[i].map[j] | SPECIAL); 74832316Syokota else 74932316Syokota dump_entry(keymap->key[i].map[j]); 75032316Syokota } 75132486Syokota printf("}, 0x%02X,0x%02X },\n", 75232316Syokota (unsigned)keymap->key[i].spcl, 75332316Syokota (unsigned)keymap->key[i].flgs); 75432316Syokota } 75532486Syokota printf("} };\n\n"); 75632316Syokota} 75732316Syokota 758228437Sedstatic void 75932316Syokotadump_accent_definition(char *name, accentmap_t *accentmap) 76032316Syokota{ 76132316Syokota int i, j; 76232316Syokota int c; 76332316Syokota 76432486Syokota printf("static accentmap_t accentmap_%s = { %d", 76532316Syokota name, accentmap->n_accs); 76632486Syokota if (accentmap->n_accs <= 0) { 76732486Syokota printf(" };\n\n"); 76832486Syokota return; 76932486Syokota } 77032486Syokota printf(", {\n"); 77132316Syokota for (i = 0; i < NUM_DEADKEYS; i++) { 77232316Syokota printf(" /* %s=%d */\n {", acc_names[i], i); 77332316Syokota c = accentmap->acc[i].accchar; 77432316Syokota if (c == '\'') 77532316Syokota printf(" '\\'', {"); 77632316Syokota else if (c == '\\') 77732316Syokota printf(" '\\\\', {"); 77832316Syokota else if (isascii(c) && isprint(c)) 77932316Syokota printf(" '%c', {", c); 78032316Syokota else if (c == 0) { 78132316Syokota printf(" 0x00 }, \n"); 78232316Syokota continue; 78332316Syokota } else 78432316Syokota printf(" 0x%02x, {", c); 78532316Syokota for (j = 0; j < NUM_ACCENTCHARS; j++) { 78632316Syokota c = accentmap->acc[i].map[j][0]; 78732316Syokota if (c == 0) 78832316Syokota break; 78932316Syokota if ((j > 0) && ((j % 4) == 0)) 79032316Syokota printf("\n\t "); 79132316Syokota if (isascii(c) && isprint(c)) 79232316Syokota printf(" { '%c',", c); 79332316Syokota else 79432316Syokota printf(" { 0x%02x,", c); 79532316Syokota printf("0x%02x },", accentmap->acc[i].map[j][1]); 79632316Syokota } 79732316Syokota printf(" }, },\n"); 79832316Syokota } 79932486Syokota printf("} };\n\n"); 80032316Syokota} 80132316Syokota 802228437Sedstatic void 803298297Semasteadd_keymap_path(const char *path) 804298297Semaste{ 805298297Semaste struct pathent* pe; 806298297Semaste size_t len; 807298297Semaste 808298297Semaste len = strlen(path); 809298297Semaste if ((pe = malloc(sizeof(*pe))) == NULL || 810298297Semaste (pe->path = malloc(len + 2)) == NULL) 811298297Semaste err(1, "malloc"); 812298297Semaste memcpy(pe->path, path, len); 813298297Semaste if (len > 0 && path[len - 1] != '/') 814298297Semaste pe->path[len++] = '/'; 815298297Semaste pe->path[len] = '\0'; 816298297Semaste STAILQ_INSERT_TAIL(&pathlist, pe, next); 817298297Semaste} 818298297Semaste 819298297Semastestatic void 82019569Sjoergload_keymap(char *opt, int dumponly) 8212088Ssos{ 82232316Syokota keymap_t keymap; 82332316Syokota accentmap_t accentmap; 824298297Semaste struct pathent *pe; 825298297Semaste FILE *file; 826298297Semaste int j; 82719569Sjoerg char *name, *cp; 828267540Sray char blank[] = "", keymap_path[] = KEYMAP_PATH; 829267540Sray char vt_keymap_path[] = VT_KEYMAP_PATH, dotkbd[] = ".kbd"; 83099816Salfred char *postfix[] = {blank, dotkbd, NULL}; 8312088Ssos 832298297Semaste if (!paths_configured) { 833298297Semaste cp = getenv("KEYMAP_PATH"); 834298297Semaste if (cp != NULL) 835298297Semaste add_keymap_path(cp); 836298297Semaste add_keymap_path(""); 837298297Semaste if (is_vt4()) 838298297Semaste add_keymap_path(vt_keymap_path); 839298297Semaste else 840298297Semaste add_keymap_path(keymap_path); 841298297Semaste paths_configured = 1; 842298297Semaste } 84376502Ssobomax 844298297Semaste file = NULL; 845298297Semaste STAILQ_FOREACH(pe, &pathlist, next) { 846298297Semaste for (j=0; postfix[j] && file == NULL; j++) { 847298297Semaste name = mkfullname(pe->path, opt, postfix[j]); 848298297Semaste file = fopen(name, "r"); 849298297Semaste if (file != NULL) 850298297Semaste break; 85176502Ssobomax } 85276643Simp } 853298297Semaste if (file == NULL) { 85479677Sobrien warn("keymap file \"%s\" not found", opt); 8552088Ssos return; 8562088Ssos } 85732316Syokota memset(&keymap, 0, sizeof(keymap)); 85832316Syokota memset(&accentmap, 0, sizeof(accentmap)); 85932316Syokota token = -1; 8602088Ssos while (1) { 861298297Semaste if (get_definition_line(file, &keymap, &accentmap) < 0) 8622088Ssos break; 8632088Ssos } 86419569Sjoerg if (dumponly) { 86519569Sjoerg /* fix up the filename to make it a valid C identifier */ 86619569Sjoerg for (cp = opt; *cp; cp++) 86719569Sjoerg if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_'; 86832316Syokota printf("/*\n" 86932316Syokota " * Automatically generated from %s.\n" 87032316Syokota " * DO NOT EDIT!\n" 87132316Syokota " */\n", name); 87232316Syokota dump_key_definition(opt, &keymap); 87332316Syokota dump_accent_definition(opt, &accentmap); 87419569Sjoerg return; 87519569Sjoerg } 87632316Syokota if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) { 87729603Scharnier warn("setting keymap"); 878298297Semaste fclose(file); 8792088Ssos return; 8802088Ssos } 88132316Syokota if ((accentmap.n_accs > 0) 88232316Syokota && (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) { 88332316Syokota warn("setting accentmap"); 884298297Semaste fclose(file); 88532316Syokota return; 88632316Syokota } 8872088Ssos} 8882088Ssos 889228437Sedstatic void 89099816Salfredprint_keymap(void) 8912088Ssos{ 89232316Syokota keymap_t keymap; 89332316Syokota accentmap_t accentmap; 8942088Ssos int i; 8952088Ssos 89632316Syokota if (ioctl(0, GIO_KEYMAP, &keymap) < 0) 89729603Scharnier err(1, "getting keymap"); 89832316Syokota if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0) 89932316Syokota memset(&accentmap, 0, sizeof(accentmap)); 9002088Ssos printf( 9012088Ssos"# alt\n" 9022088Ssos"# scan cntrl alt alt cntrl lock\n" 9032088Ssos"# code base shift cntrl shift alt shift cntrl shift state\n" 9042088Ssos"# ------------------------------------------------------------------\n" 9052088Ssos ); 90632316Syokota for (i=0; i<keymap.n_keys; i++) 90732316Syokota print_key_definition_line(stdout, i, &keymap.key[i]); 90832316Syokota 90932316Syokota printf("\n"); 91032316Syokota for (i = 0; i < NUM_DEADKEYS; i++) 91132316Syokota print_accent_definition_line(stdout, i, &accentmap.acc[i]); 91232316Syokota 9132088Ssos} 9142088Ssos 915228437Sedstatic void 91699816Salfredload_default_functionkeys(void) 9172088Ssos{ 9182088Ssos fkeyarg_t fkey; 9192088Ssos int i; 9202088Ssos 9212088Ssos for (i=0; i<NUM_FKEYS; i++) { 9222088Ssos fkey.keynum = i; 9232088Ssos strcpy(fkey.keydef, fkey_table[i]); 9242088Ssos fkey.flen = strlen(fkey_table[i]); 9252088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 92629603Scharnier warn("setting function key"); 9272088Ssos } 9282088Ssos} 9292088Ssos 930228437Sedstatic void 9312088Ssosset_functionkey(char *keynumstr, char *string) 9322088Ssos{ 9332088Ssos fkeyarg_t fkey; 9342088Ssos 9352088Ssos if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) { 9362088Ssos load_default_functionkeys(); 9372088Ssos return; 9382088Ssos } 9392088Ssos fkey.keynum = atoi(keynumstr); 9402088Ssos if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) { 94129603Scharnier warnx("function key number must be between 1 and %d", 9422088Ssos NUM_FKEYS); 9432088Ssos return; 9442088Ssos } 9452088Ssos if ((fkey.flen = strlen(string)) > MAXFK) { 94629603Scharnier warnx("function key string too long (%d > %d)", 9472088Ssos fkey.flen, MAXFK); 9482088Ssos return; 9492088Ssos } 950133353Sjmg strncpy(fkey.keydef, string, MAXFK); 9512088Ssos fkey.keynum -= 1; 9522088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 95329603Scharnier warn("setting function key"); 9542088Ssos} 9552088Ssos 956228437Sedstatic void 9572088Ssosset_bell_values(char *opt) 9582088Ssos{ 9595536Ssos int bell, duration, pitch; 9602088Ssos 96138044Syokota bell = 0; 96238044Syokota if (!strncmp(opt, "quiet.", 6)) { 963164333Sru bell = CONS_QUIET_BELL; 96438044Syokota opt += 6; 96538044Syokota } 9668857Srgrimes if (!strcmp(opt, "visual")) 967164333Sru bell |= CONS_VISUAL_BELL; 9685536Ssos else if (!strcmp(opt, "normal")) 96938044Syokota duration = 5, pitch = 800; 97048982Syokota else if (!strcmp(opt, "off")) 97148982Syokota duration = 0, pitch = 0; 9722088Ssos else { 9732088Ssos char *v1; 9748857Srgrimes 9755536Ssos bell = 0; 9762088Ssos duration = strtol(opt, &v1, 0); 9772088Ssos if ((duration < 0) || (*v1 != '.')) 9782088Ssos goto badopt; 9792088Ssos opt = ++v1; 9802088Ssos pitch = strtol(opt, &v1, 0); 9812088Ssos if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) { 9822088Ssosbadopt: 98377394Ssobomax warnx("argument to -b must be duration.pitch or [quiet.]visual|normal|off"); 9842088Ssos return; 9852088Ssos } 98638044Syokota if (pitch != 0) 98738044Syokota pitch = 1193182 / pitch; /* in Hz */ 98838044Syokota duration /= 10; /* in 10 m sec */ 9892088Ssos } 9902088Ssos 9915536Ssos ioctl(0, CONS_BELLTYPE, &bell); 992164333Sru if (!(bell & CONS_VISUAL_BELL)) 9935536Ssos fprintf(stderr, "[=%d;%dB", pitch, duration); 9942088Ssos} 9952088Ssos 996228437Sedstatic void 9972088Ssosset_keyrates(char *opt) 9982088Ssos{ 99944628Syokota int arg[2]; 100039047Syokota int repeat; 100139047Syokota int delay; 100246761Syokota int r, d; 10032088Ssos 100446761Syokota if (!strcmp(opt, "slow")) { 100544628Syokota delay = 1000, repeat = 500; 100646761Syokota d = 3, r = 31; 100746761Syokota } else if (!strcmp(opt, "normal")) { 100844628Syokota delay = 500, repeat = 125; 100946761Syokota d = 1, r = 15; 101046761Syokota } else if (!strcmp(opt, "fast")) { 101139047Syokota delay = repeat = 0; 101246761Syokota d = r = 0; 101346761Syokota } else { 10142088Ssos int n; 10152088Ssos char *v1; 10162088Ssos 10172088Ssos delay = strtol(opt, &v1, 0); 10182088Ssos if ((delay < 0) || (*v1 != '.')) 10192088Ssos goto badopt; 10202088Ssos opt = ++v1; 10212088Ssos repeat = strtol(opt, &v1, 0); 10222088Ssos if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) { 10232088Ssosbadopt: 102477394Ssobomax warnx("argument to -r must be delay.repeat or slow|normal|fast"); 10252088Ssos return; 10262088Ssos } 102746761Syokota for (n = 0; n < ndelays - 1; n++) 102846761Syokota if (delay <= delays[n]) 102946761Syokota break; 103046761Syokota d = n; 103146761Syokota for (n = 0; n < nrepeats - 1; n++) 103246761Syokota if (repeat <= repeats[n]) 103346761Syokota break; 103446761Syokota r = n; 10352088Ssos } 10362088Ssos 103744628Syokota arg[0] = delay; 103844628Syokota arg[1] = repeat; 103946761Syokota if (ioctl(0, KDSETREPEAT, arg)) { 104046761Syokota if (ioctl(0, KDSETRAD, (d << 5) | r)) 104146761Syokota warn("setting keyboard rate"); 104246761Syokota } 10432088Ssos} 10442088Ssos 104599816Salfredstatic const char * 104699816Salfredget_kbd_type_name(int type) 104742505Syokota{ 104842505Syokota static struct { 104942505Syokota int type; 105099816Salfred const char *name; 105142505Syokota } name_table[] = { 105242505Syokota { KB_84, "AT 84" }, 105342505Syokota { KB_101, "AT 101/102" }, 105442505Syokota { KB_OTHER, "generic" }, 105542505Syokota }; 105699816Salfred unsigned int i; 10576046Ssos 105842505Syokota for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) { 105942505Syokota if (type == name_table[i].type) 106042505Syokota return name_table[i].name; 106142505Syokota } 106242505Syokota return "unknown"; 106342505Syokota} 106442505Syokota 1065228437Sedstatic void 106642505Syokotashow_kbd_info(void) 106742505Syokota{ 106842505Syokota keyboard_info_t info; 106942505Syokota 107042505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 107142505Syokota warn("unable to obtain keyboard information"); 107242505Syokota return; 107342505Syokota } 107442505Syokota printf("kbd%d:\n", info.kb_index); 107542505Syokota printf(" %.*s%d, type:%s (%d)\n", 107677394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 107742505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 107842505Syokota} 107942505Syokota 1080228437Sedstatic void 108142505Syokotaset_keyboard(char *device) 108242505Syokota{ 108342505Syokota keyboard_info_t info; 108442505Syokota int fd; 108542505Syokota 108642505Syokota fd = open(device, O_RDONLY); 108742505Syokota if (fd < 0) { 108842505Syokota warn("cannot open %s", device); 108942505Syokota return; 109042505Syokota } 109142505Syokota if (ioctl(fd, KDGKBINFO, &info) == -1) { 109242505Syokota warn("unable to obtain keyboard information"); 109342505Syokota close(fd); 109442505Syokota return; 109542505Syokota } 109642505Syokota /* 109742505Syokota * The keyboard device driver won't release the keyboard by 109842505Syokota * the following ioctl, but it automatically will, when the device 109942505Syokota * is closed. So, we don't check error here. 110042505Syokota */ 110142505Syokota ioctl(fd, CONS_RELKBD, 0); 110242505Syokota close(fd); 110342505Syokota#if 1 110442505Syokota printf("kbd%d\n", info.kb_index); 110542505Syokota printf(" %.*s%d, type:%s (%d)\n", 110677394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 110742505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 110842505Syokota#endif 110942505Syokota 111042505Syokota if (ioctl(0, CONS_SETKBD, info.kb_index) == -1) 111142505Syokota warn("unable to set keyboard"); 111242505Syokota} 111342505Syokota 1114228437Sedstatic void 111542505Syokotarelease_keyboard(void) 111642505Syokota{ 111742505Syokota keyboard_info_t info; 111842505Syokota 111942505Syokota /* 112042505Syokota * If stdin is not associated with a keyboard, the following ioctl 112142505Syokota * will fail. 112242505Syokota */ 112342505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 112442505Syokota warn("unable to obtain keyboard information"); 112542505Syokota return; 112642505Syokota } 112742505Syokota#if 1 112842505Syokota printf("kbd%d\n", info.kb_index); 112942505Syokota printf(" %.*s%d, type:%s (%d)\n", 113077394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 113142505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 113242505Syokota#endif 113342505Syokota if (ioctl(0, CONS_RELKBD, 0) == -1) 113442505Syokota warn("unable to release the keyboard"); 113542505Syokota} 113642505Syokota 1137228437Sedstatic void 1138162327Semaxmux_keyboard(u_int op, char *kbd) 1139148017Semax{ 1140148017Semax keyboard_info_t info; 1141148017Semax char *unit, *ep; 114242505Syokota 1143148017Semax /* 1144148017Semax * If stdin is not associated with a keyboard, the following ioctl 1145148017Semax * will fail. 1146148017Semax */ 1147148017Semax if (ioctl(0, KDGKBINFO, &info) == -1) { 1148148017Semax warn("unable to obtain keyboard information"); 1149148017Semax return; 1150148017Semax } 1151148017Semax#if 1 1152148017Semax printf("kbd%d\n", info.kb_index); 1153148017Semax printf(" %.*s%d, type:%s (%d)\n", 1154148017Semax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 1155148017Semax get_kbd_type_name(info.kb_type), info.kb_type); 1156148017Semax#endif 1157148017Semax /* 1158148017Semax * split kbd into name and unit. find the right most part of the 1159148017Semax * kbd string that consist of only digits. 1160148017Semax */ 1161148017Semax 1162148017Semax memset(&info, 0, sizeof(info)); 1163148017Semax 1164148017Semax info.kb_unit = -1; 1165148017Semax ep = kbd - 1; 1166148017Semax 1167148017Semax do { 1168148017Semax unit = strpbrk(ep + 1, "0123456789"); 1169148017Semax if (unit != NULL) { 1170148017Semax info.kb_unit = strtol(unit, &ep, 10); 1171148017Semax if (*ep != '\0') 1172148017Semax info.kb_unit = -1; 1173148017Semax } 1174148017Semax } while (unit != NULL && info.kb_unit == -1); 1175148017Semax 1176148017Semax if (info.kb_unit == -1) { 1177148017Semax warnx("unable to find keyboard driver unit in '%s'", kbd); 1178148017Semax return; 1179148017Semax } 1180148017Semax 1181148017Semax if (unit == kbd) { 1182148017Semax warnx("unable to find keyboard driver name in '%s'", kbd); 1183148017Semax return; 1184148017Semax } 1185148017Semax if (unit - kbd >= (int) sizeof(info.kb_name)) { 1186148017Semax warnx("keyboard name '%s' is too long", kbd); 1187148017Semax return; 1188148017Semax } 1189148017Semax 1190148017Semax strncpy(info.kb_name, kbd, unit - kbd); 1191148017Semax 1192148017Semax /* 1193148017Semax * If stdin is not associated with a kbdmux(4) keyboard, the following 1194148017Semax * ioctl will fail. 1195148017Semax */ 1196148017Semax 1197148017Semax if (ioctl(0, op, &info) == -1) 1198148017Semax warn("unable to (un)mux the keyboard"); 1199148017Semax} 1200148017Semax 1201228437Sedstatic void 1202201387Sedusage(void) 12032088Ssos{ 120429603Scharnier fprintf(stderr, "%s\n%s\n%s\n", 1205148017Semax"usage: kbdcontrol [-dFKix] [-A name] [-a name] [-b duration.pitch | [quiet.]belltype]", 120629603Scharnier" [-r delay.repeat | speed] [-l mapfile] [-f # string]", 1207298297Semaste" [-k device] [-L mapfile] [-P path]"); 120829603Scharnier exit(1); 12092088Ssos} 12102088Ssos 12112088Ssos 121251287Speterint 12132088Ssosmain(int argc, char **argv) 12142088Ssos{ 1215298297Semaste const char *optstring = "A:a:b:df:iKk:Fl:L:P:r:x"; 12162088Ssos int opt; 12172088Ssos 1218298297Semaste /* Collect any -P arguments, regardless of where they appear. */ 1219298297Semaste while ((opt = getopt(argc, argv, optstring)) != -1) 1220298297Semaste if (opt == 'P') 1221298297Semaste add_keymap_path(optarg); 1222298297Semaste 1223298297Semaste optind = optreset = 1; 1224298297Semaste while ((opt = getopt(argc, argv, optstring)) != -1) 12252088Ssos switch(opt) { 1226148017Semax case 'A': 1227148017Semax case 'a': 1228148017Semax mux_keyboard((opt == 'A')? KBRELKBD : KBADDKBD, optarg); 1229148017Semax break; 123077329Sdes case 'b': 123177329Sdes set_bell_values(optarg); 123277329Sdes break; 123377329Sdes case 'd': 123477329Sdes print_keymap(); 123577329Sdes break; 123677329Sdes case 'l': 123777329Sdes load_keymap(optarg, 0); 123877329Sdes break; 123977329Sdes case 'L': 124077329Sdes load_keymap(optarg, 1); 124177329Sdes break; 1242298297Semaste case 'P': 1243298297Semaste break; 124477329Sdes case 'f': 124577329Sdes set_functionkey(optarg, 124677329Sdes nextarg(argc, argv, &optind, 'f')); 124777329Sdes break; 124877329Sdes case 'F': 124977329Sdes load_default_functionkeys(); 125077329Sdes break; 125177329Sdes case 'i': 125277329Sdes show_kbd_info(); 125377329Sdes break; 125477329Sdes case 'K': 125577329Sdes release_keyboard(); 125677329Sdes break; 125777329Sdes case 'k': 125877329Sdes set_keyboard(optarg); 125977329Sdes break; 126077329Sdes case 'r': 126177329Sdes set_keyrates(optarg); 126277329Sdes break; 126377329Sdes case 'x': 126477329Sdes hex = 1; 126577329Sdes break; 126677329Sdes default: 126777329Sdes usage(); 12682088Ssos } 126929603Scharnier if ((optind != argc) || (argc == 1)) 12702088Ssos usage(); 12712088Ssos exit(0); 12722088Ssos} 1273