kbdcontrol.c revision 148017
12088Ssos/*- 25536Ssos * Copyright (c) 1994-1995 S�ren Schmidt 32088Ssos * All rights reserved. 42088Ssos * 52088Ssos * Redistribution and use in source and binary forms, with or without 62088Ssos * modification, are permitted provided that the following conditions 72088Ssos * are met: 82088Ssos * 1. Redistributions of source code must retain the above copyright 95994Ssos * notice, this list of conditions and the following disclaimer, 105994Ssos * in this position and unchanged. 112088Ssos * 2. Redistributions in binary form must reproduce the above copyright 122088Ssos * notice, this list of conditions and the following disclaimer in the 132088Ssos * documentation and/or other materials provided with the distribution. 142088Ssos * 3. The name of the author may not be used to endorse or promote products 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 148017 2005-07-14 22:43:20Z emax $"); 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 582088Ssoschar ctrl_names[32][4] = { 598857Srgrimes "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 602088Ssos "bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ", 612088Ssos "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 6238139Syokota "can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "us " 632088Ssos }; 642088Ssos 6532316Syokotachar acc_names[15][5] = { 6632316Syokota "dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot", 6732316Syokota "duml", "dsla", "drin", "dced", "dapo", "ddac", "dogo", 6832316Syokota "dcar", 6932316Syokota }; 7032316Syokota 7132316Syokotachar acc_names_u[15][5] = { 7232316Syokota "DGRA", "DACU", "DCIR", "DTIL", "DMAC", "DBRE", "DDOT", 7332316Syokota "DUML", "DSLA", "DRIN", "DCED", "DAPO", "DDAC", "DOGO", 7432316Syokota "DCAR", 7532316Syokota }; 7632316Syokota 775994Ssoschar fkey_table[96][MAXFK] = { 785994Ssos/* 01-04 */ "\033[M", "\033[N", "\033[O", "\033[P", 795994Ssos/* 05-08 */ "\033[Q", "\033[R", "\033[S", "\033[T", 805994Ssos/* 09-12 */ "\033[U", "\033[V", "\033[W", "\033[X", 815994Ssos/* 13-16 */ "\033[Y", "\033[Z", "\033[a", "\033[b", 825994Ssos/* 17-20 */ "\033[c", "\033[d", "\033[e", "\033[f", 835994Ssos/* 21-24 */ "\033[g", "\033[h", "\033[i", "\033[j", 845994Ssos/* 25-28 */ "\033[k", "\033[l", "\033[m", "\033[n", 855994Ssos/* 29-32 */ "\033[o", "\033[p", "\033[q", "\033[r", 865994Ssos/* 33-36 */ "\033[s", "\033[t", "\033[u", "\033[v", 875994Ssos/* 37-40 */ "\033[w", "\033[x", "\033[y", "\033[z", 885994Ssos/* 41-44 */ "\033[@", "\033[[", "\033[\\","\033[]", 899202Srgrimes/* 45-48 */ "\033[^", "\033[_", "\033[`", "\033[{", 905994Ssos/* 49-52 */ "\033[H", "\033[A", "\033[I", "-" , 915994Ssos/* 53-56 */ "\033[D", "\033[E", "\033[C", "+" , 925994Ssos/* 57-60 */ "\033[F", "\033[B", "\033[G", "\033[L", 939202Srgrimes/* 61-64 */ "\177", "\033[J", "\033[~", "\033[}", 945994Ssos/* 65-68 */ "" , "" , "" , "" , 955994Ssos/* 69-72 */ "" , "" , "" , "" , 965994Ssos/* 73-76 */ "" , "" , "" , "" , 975994Ssos/* 77-80 */ "" , "" , "" , "" , 985994Ssos/* 81-84 */ "" , "" , "" , "" , 995994Ssos/* 85-88 */ "" , "" , "" , "" , 1005994Ssos/* 89-92 */ "" , "" , "" , "" , 1015994Ssos/* 93-96 */ "" , "" , "" , "" , 1022088Ssos }; 1032088Ssos 10446761Syokotaconst int delays[] = {250, 500, 750, 1000}; 10546761Syokotaconst int repeats[] = { 34, 38, 42, 46, 50, 55, 59, 63, 10646761Syokota 68, 76, 84, 92, 100, 110, 118, 126, 10746761Syokota 136, 152, 168, 184, 200, 220, 236, 252, 10846761Syokota 272, 304, 336, 368, 400, 440, 472, 504}; 10946761Syokotaconst int ndelays = (sizeof(delays) / sizeof(int)); 11046761Syokotaconst int nrepeats = (sizeof(repeats) / sizeof(int)); 1112088Ssosint hex = 0; 1126046Ssosint number; 1132088Ssoschar letter; 11432316Syokotaint token; 1152088Ssos 11699816Salfredvoid dump_accent_definition(char *name, accentmap_t *accentmap); 11799816Salfredvoid dump_entry(int value); 11899816Salfredvoid dump_key_definition(char *name, keymap_t *keymap); 11999814Salfredint get_accent_definition_line(accentmap_t *); 12099816Salfredint get_entry(void); 12199814Salfredint get_key_definition_line(keymap_t *); 12299816Salfredvoid load_keymap(char *opt, int dumponly); 12399816Salfredvoid load_default_functionkeys(void); 12499816Salfredchar * nextarg(int ac, char **av, int *indp, int oc); 12599816Salfredchar * mkfullname(const char *s1, const char *s2, const char *s3); 12699816Salfredvoid print_accent_definition_line(FILE *fp, int accent, 12799816Salfred struct acc_t *key); 12899816Salfredvoid print_entry(FILE *fp, int value); 12999816Salfredvoid print_key_definition_line(FILE *fp, int scancode, 13099816Salfred struct keyent_t *key); 13199816Salfredvoid print_keymap(void); 13299816Salfredvoid release_keyboard(void); 133148017Semaxvoid mux_keyboard(int op, char *kbd); 13499816Salfredvoid set_bell_values(char *opt); 13599816Salfredvoid set_functionkey(char *keynumstr, char *string); 13699816Salfredvoid set_keyboard(char *device); 13799816Salfredvoid set_keyrates(char *opt); 13899816Salfredvoid show_kbd_info(void); 13999816Salfredvoid usage(void) __dead2; 1402088Ssos 1412088Ssoschar * 1422088Ssosnextarg(int ac, char **av, int *indp, int oc) 1432088Ssos{ 1442088Ssos if (*indp < ac) 1452088Ssos return(av[(*indp)++]); 14629603Scharnier warnx("option requires two arguments -- %c", oc); 1472088Ssos usage(); 1482088Ssos} 1492088Ssos 1502088Ssos 1512088Ssoschar * 1522088Ssosmkfullname(const char *s1, const char *s2, const char *s3) 1532088Ssos{ 1545536Ssos static char *buf = NULL; 1555536Ssos static int bufl = 0; 1565536Ssos int f; 1572088Ssos 1582088Ssos f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 15977394Ssobomax if (f > bufl) { 1602088Ssos if (buf) 1612088Ssos buf = (char *)realloc(buf, f); 1622088Ssos else 1632088Ssos buf = (char *)malloc(f); 16477394Ssobomax } 1652088Ssos if (!buf) { 1662088Ssos bufl = 0; 1672088Ssos return(NULL); 1682088Ssos } 1692088Ssos 1702088Ssos bufl = f; 1712088Ssos strcpy(buf, s1); 1722088Ssos strcat(buf, s2); 1732088Ssos strcat(buf, s3); 1742088Ssos return(buf); 1752088Ssos} 1762088Ssos 1772088Ssos 1782088Ssosint 17999816Salfredget_entry(void) 1802088Ssos{ 18132316Syokota switch ((token = yylex())) { 1822088Ssos case TNOP: 1832088Ssos return NOP | 0x100; 1842088Ssos case TLSH: 1852088Ssos return LSH | 0x100; 1862088Ssos case TRSH: 1872088Ssos return RSH | 0x100; 1882088Ssos case TCLK: 1892088Ssos return CLK | 0x100; 1902088Ssos case TNLK: 1912088Ssos return NLK | 0x100; 1922088Ssos case TSLK: 1932088Ssos return SLK | 0x100; 1942088Ssos case TBTAB: 1952088Ssos return BTAB | 0x100; 1962088Ssos case TLALT: 1972088Ssos return LALT | 0x100; 1982088Ssos case TLCTR: 1992088Ssos return LCTR | 0x100; 2002088Ssos case TNEXT: 2012088Ssos return NEXT | 0x100; 20248105Syokota case TPREV: 20348105Syokota return PREV | 0x100; 2042088Ssos case TRCTR: 2052088Ssos return RCTR | 0x100; 2062088Ssos case TRALT: 2072088Ssos return RALT | 0x100; 2082088Ssos case TALK: 2092088Ssos return ALK | 0x100; 2102088Ssos case TASH: 2112088Ssos return ASH | 0x100; 2122088Ssos case TMETA: 2132088Ssos return META | 0x100; 2142088Ssos case TRBT: 2152088Ssos return RBT | 0x100; 2162088Ssos case TDBG: 2172088Ssos return DBG | 0x100; 2185994Ssos case TSUSP: 2195994Ssos return SUSP | 0x100; 22038053Syokota case TSPSC: 22138053Syokota return SPSC | 0x100; 22254380Syokota case TPANIC: 22354380Syokota return PNC | 0x100; 22454380Syokota case TLSHA: 22554380Syokota return LSHA | 0x100; 22654380Syokota case TRSHA: 22754380Syokota return RSHA | 0x100; 22854380Syokota case TLCTRA: 22954380Syokota return LCTRA | 0x100; 23054380Syokota case TRCTRA: 23154380Syokota return RCTRA | 0x100; 23254380Syokota case TLALTA: 23354380Syokota return LALTA | 0x100; 23454380Syokota case TRALTA: 23554380Syokota return RALTA | 0x100; 23665759Sdwmalone case THALT: 23765759Sdwmalone return HALT | 0x100; 23865759Sdwmalone case TPDWN: 23965759Sdwmalone return PDWN | 0x100; 24074118Sache case TPASTE: 24174118Sache return PASTE | 0x100; 24232316Syokota case TACC: 24332316Syokota if (ACC(number) > L_ACC) 24432316Syokota return -1; 24532316Syokota return ACC(number) | 0x100; 2462088Ssos case TFUNC: 2472088Ssos if (F(number) > L_FN) 2482088Ssos return -1; 2492088Ssos return F(number) | 0x100; 2502088Ssos case TSCRN: 2512088Ssos if (S(number) > L_SCR) 2522088Ssos return -1; 2532088Ssos return S(number) | 0x100; 2542088Ssos case TLET: 2552088Ssos return (unsigned char)letter; 2562088Ssos case TNUM: 2572088Ssos if (number < 0 || number > 255) 2582088Ssos return -1; 2592088Ssos return number; 2602088Ssos default: 2612088Ssos return -1; 2622088Ssos } 2632088Ssos} 2642088Ssos 26577394Ssobomaxstatic int 26632316Syokotaget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap) 2672088Ssos{ 26832316Syokota int c; 2692088Ssos 2702088Ssos yyin = fd; 2712088Ssos 27232316Syokota if (token < 0) 27332316Syokota token = yylex(); 27432316Syokota switch (token) { 27532316Syokota case TNUM: 27632316Syokota c = get_key_definition_line(keymap); 27732316Syokota if (c < 0) 27832316Syokota errx(1, "invalid key definition"); 27932316Syokota if (c > keymap->n_keys) 28032316Syokota keymap->n_keys = c; 28132316Syokota break; 28232316Syokota case TACC: 28332316Syokota c = get_accent_definition_line(accentmap); 28432316Syokota if (c < 0) 28532316Syokota errx(1, "invalid accent key definition"); 28632316Syokota if (c > accentmap->n_accs) 28732316Syokota accentmap->n_accs = c; 28832316Syokota break; 28932316Syokota case 0: 29032316Syokota /* EOF */ 2912088Ssos return -1; 29232316Syokota default: 29332316Syokota errx(1, "illegal definition line"); 29432316Syokota } 29532316Syokota return c; 29632316Syokota} 29732316Syokota 29832316Syokotaint 29932316Syokotaget_key_definition_line(keymap_t *map) 30032316Syokota{ 30132316Syokota int i, def, scancode; 30232316Syokota 30332316Syokota /* check scancode number */ 3042088Ssos if (number < 0 || number >= NUM_KEYS) 3052088Ssos return -1; 3062088Ssos scancode = number; 3072088Ssos 3082088Ssos /* get key definitions */ 3092088Ssos map->key[scancode].spcl = 0; 3102088Ssos for (i=0; i<NUM_STATES; i++) { 3112088Ssos if ((def = get_entry()) == -1) 3122088Ssos return -1; 3132088Ssos if (def & 0x100) 3142088Ssos map->key[scancode].spcl |= (0x80 >> i); 3152088Ssos map->key[scancode].map[i] = def & 0xFF; 3162088Ssos } 3172088Ssos /* get lock state key def */ 31832316Syokota if ((token = yylex()) != TFLAG) 3192088Ssos return -1; 3202088Ssos map->key[scancode].flgs = number; 32132316Syokota token = yylex(); 32232316Syokota return (scancode + 1); 3232088Ssos} 3242088Ssos 32532316Syokotaint 32632316Syokotaget_accent_definition_line(accentmap_t *map) 32732316Syokota{ 32832316Syokota int accent; 32932316Syokota int c1, c2; 33032316Syokota int i; 3312088Ssos 33232316Syokota if (ACC(number) < F_ACC || ACC(number) > L_ACC) 33332316Syokota /* number out of range */ 33432316Syokota return -1; 33532316Syokota accent = number; 33632316Syokota if (map->acc[accent].accchar != 0) { 33732316Syokota /* this entry has already been defined before! */ 33832316Syokota errx(1, "duplicated accent key definition"); 33932316Syokota } 34032316Syokota 34132316Syokota switch ((token = yylex())) { 34232316Syokota case TLET: 34332316Syokota map->acc[accent].accchar = letter; 34432316Syokota break; 34532316Syokota case TNUM: 34632316Syokota map->acc[accent].accchar = number; 34732316Syokota break; 34832316Syokota default: 34932316Syokota return -1; 35032316Syokota } 35132316Syokota 35232316Syokota for (i = 0; (token = yylex()) == '(';) { 35332316Syokota switch ((token = yylex())) { 35432316Syokota case TLET: 35532316Syokota c1 = letter; 35632316Syokota break; 35732316Syokota case TNUM: 35832316Syokota c1 = number; 35932316Syokota break; 36032316Syokota default: 36132316Syokota return -1; 36232316Syokota } 36332316Syokota switch ((token = yylex())) { 36432316Syokota case TLET: 36532316Syokota c2 = letter; 36632316Syokota break; 36732316Syokota case TNUM: 36832316Syokota c2 = number; 36932316Syokota break; 37032316Syokota default: 37132316Syokota return -1; 37232316Syokota } 37332316Syokota if ((token = yylex()) != ')') 37432316Syokota return -1; 37532316Syokota if (i >= NUM_ACCENTCHARS) { 37632316Syokota warnx("too many accented characters, ignored"); 37732316Syokota continue; 37832316Syokota } 37932316Syokota map->acc[accent].map[i][0] = c1; 38032316Syokota map->acc[accent].map[i][1] = c2; 38132316Syokota ++i; 38232316Syokota } 38332316Syokota return (accent + 1); 38432316Syokota} 38532316Syokota 38629603Scharniervoid 3872088Ssosprint_entry(FILE *fp, int value) 3882088Ssos{ 3892088Ssos int val = value & 0xFF; 3902088Ssos 3912088Ssos switch (value) { 3922088Ssos case NOP | 0x100: 3938857Srgrimes fprintf(fp, " nop "); 3942088Ssos break; 3952088Ssos case LSH | 0x100: 3962088Ssos fprintf(fp, " lshift"); 3972088Ssos break; 3982088Ssos case RSH | 0x100: 3992088Ssos fprintf(fp, " rshift"); 4002088Ssos break; 4012088Ssos case CLK | 0x100: 4022088Ssos fprintf(fp, " clock "); 4032088Ssos break; 4042088Ssos case NLK | 0x100: 4052088Ssos fprintf(fp, " nlock "); 4062088Ssos break; 4072088Ssos case SLK | 0x100: 4082088Ssos fprintf(fp, " slock "); 4092088Ssos break; 4102088Ssos case BTAB | 0x100: 4112088Ssos fprintf(fp, " btab "); 4122088Ssos break; 4132088Ssos case LALT | 0x100: 4142088Ssos fprintf(fp, " lalt "); 4152088Ssos break; 4162088Ssos case LCTR | 0x100: 4172088Ssos fprintf(fp, " lctrl "); 4182088Ssos break; 4192088Ssos case NEXT | 0x100: 4202088Ssos fprintf(fp, " nscr "); 4212088Ssos break; 42248105Syokota case PREV | 0x100: 42348105Syokota fprintf(fp, " pscr "); 42448105Syokota break; 4252088Ssos case RCTR | 0x100: 4262088Ssos fprintf(fp, " rctrl "); 4272088Ssos break; 4282088Ssos case RALT | 0x100: 4292088Ssos fprintf(fp, " ralt "); 4302088Ssos break; 4312088Ssos case ALK | 0x100: 4322088Ssos fprintf(fp, " alock "); 4332088Ssos break; 4342088Ssos case ASH | 0x100: 4352088Ssos fprintf(fp, " ashift"); 4362088Ssos break; 4372088Ssos case META | 0x100: 4382088Ssos fprintf(fp, " meta "); 4392088Ssos break; 4402088Ssos case RBT | 0x100: 4412088Ssos fprintf(fp, " boot "); 4422088Ssos break; 4432088Ssos case DBG | 0x100: 4442088Ssos fprintf(fp, " debug "); 4452088Ssos break; 44632316Syokota case SUSP | 0x100: 44732316Syokota fprintf(fp, " susp "); 44832316Syokota break; 44938053Syokota case SPSC | 0x100: 45038053Syokota fprintf(fp, " saver "); 45138053Syokota break; 45254380Syokota case PNC | 0x100: 45354380Syokota fprintf(fp, " panic "); 45454380Syokota break; 45554380Syokota case LSHA | 0x100: 45654380Syokota fprintf(fp, " lshifta"); 45754380Syokota break; 45854380Syokota case RSHA | 0x100: 45954380Syokota fprintf(fp, " rshifta"); 46054380Syokota break; 46154380Syokota case LCTRA | 0x100: 46254380Syokota fprintf(fp, " lctrla"); 46354380Syokota break; 46454380Syokota case RCTRA | 0x100: 46554380Syokota fprintf(fp, " rctrla"); 46654380Syokota break; 46754380Syokota case LALTA | 0x100: 46854380Syokota fprintf(fp, " lalta "); 46954380Syokota break; 47054380Syokota case RALTA | 0x100: 47154380Syokota fprintf(fp, " ralta "); 47254380Syokota break; 47365759Sdwmalone case HALT | 0x100: 47465759Sdwmalone fprintf(fp, " halt "); 47565759Sdwmalone break; 47665759Sdwmalone case PDWN | 0x100: 47765759Sdwmalone fprintf(fp, " pdwn "); 47865759Sdwmalone break; 47974118Sache case PASTE | 0x100: 48074118Sache fprintf(fp, " paste "); 48174118Sache break; 4822088Ssos default: 4832088Ssos if (value & 0x100) { 4848857Srgrimes if (val >= F_FN && val <= L_FN) 4852088Ssos fprintf(fp, " fkey%02d", val - F_FN + 1); 4868857Srgrimes else if (val >= F_SCR && val <= L_SCR) 4872088Ssos fprintf(fp, " scr%02d ", val - F_SCR + 1); 48832316Syokota else if (val >= F_ACC && val <= L_ACC) 48932316Syokota fprintf(fp, " %-6s", acc_names[val - F_ACC]); 4902088Ssos else if (hex) 4918857Srgrimes fprintf(fp, " 0x%02x ", val); 4922088Ssos else 49332316Syokota fprintf(fp, " %3d ", val); 4942088Ssos } 4952088Ssos else { 4962088Ssos if (val < ' ') 4978857Srgrimes fprintf(fp, " %s ", ctrl_names[val]); 4982088Ssos else if (val == 127) 4998857Srgrimes fprintf(fp, " del "); 5009202Srgrimes else if (isascii(val) && isprint(val)) 5018857Srgrimes fprintf(fp, " '%c' ", val); 5022088Ssos else if (hex) 5038857Srgrimes fprintf(fp, " 0x%02x ", val); 5042088Ssos else 5058857Srgrimes fprintf(fp, " %3d ", val); 5062088Ssos } 5072088Ssos } 5082088Ssos} 5092088Ssos 5102088Ssosvoid 51142505Syokotaprint_key_definition_line(FILE *fp, int scancode, struct keyent_t *key) 5122088Ssos{ 51329603Scharnier int i; 5142088Ssos 5152088Ssos /* print scancode number */ 5162088Ssos if (hex) 5172088Ssos fprintf(fp, " 0x%02x ", scancode); 5182088Ssos else 5192088Ssos fprintf(fp, " %03d ", scancode); 5202088Ssos 5212088Ssos /* print key definitions */ 5222088Ssos for (i=0; i<NUM_STATES; i++) { 5232088Ssos if (key->spcl & (0x80 >> i)) 5242088Ssos print_entry(fp, key->map[i] | 0x100); 5252088Ssos else 5268857Srgrimes print_entry(fp, key->map[i]); 5272088Ssos } 5282088Ssos 5292088Ssos /* print lock state key def */ 5302088Ssos switch (key->flgs) { 5312088Ssos case 0: 5322088Ssos fprintf(fp, " O\n"); 5332088Ssos break; 5342088Ssos case 1: 5352088Ssos fprintf(fp, " C\n"); 5362088Ssos break; 5372088Ssos case 2: 5382088Ssos fprintf(fp, " N\n"); 5392088Ssos break; 5406046Ssos case 3: 5416046Ssos fprintf(fp, " B\n"); 5426046Ssos break; 5438857Srgrimes } 5442088Ssos} 5452088Ssos 54632316Syokotavoid 54732316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key) 54832316Syokota{ 54932316Syokota int c; 55032316Syokota int i; 5512088Ssos 55232316Syokota if (key->accchar == 0) 55332316Syokota return; 55432316Syokota 55532316Syokota /* print accent number */ 55632316Syokota fprintf(fp, " %-6s", acc_names[accent]); 55732316Syokota if (isascii(key->accchar) && isprint(key->accchar)) 55832316Syokota fprintf(fp, "'%c' ", key->accchar); 55932316Syokota else if (hex) 56032316Syokota fprintf(fp, "0x%02x ", key->accchar); 56132316Syokota else 56232316Syokota fprintf(fp, "%03d ", key->accchar); 56332316Syokota 56432316Syokota for (i = 0; i < NUM_ACCENTCHARS; ++i) { 56532316Syokota c = key->map[i][0]; 56632316Syokota if (c == 0) 56732316Syokota break; 56832316Syokota if ((i > 0) && ((i % 4) == 0)) 56932316Syokota fprintf(fp, "\n "); 57032316Syokota if (isascii(c) && isprint(c)) 57132316Syokota fprintf(fp, "( '%c' ", c); 57232316Syokota else if (hex) 57332316Syokota fprintf(fp, "(0x%02x ", c); 57432316Syokota else 57532316Syokota fprintf(fp, "( %03d ", c); 57632316Syokota c = key->map[i][1]; 57732316Syokota if (isascii(c) && isprint(c)) 57832316Syokota fprintf(fp, "'%c' ) ", c); 57932316Syokota else if (hex) 58032316Syokota fprintf(fp, "0x%02x) ", c); 58132316Syokota else 58232316Syokota fprintf(fp, "%03d ) ", c); 58332316Syokota } 58432316Syokota fprintf(fp, "\n"); 58532316Syokota} 58632316Syokota 5872088Ssosvoid 58832316Syokotadump_entry(int value) 58932316Syokota{ 59032316Syokota if (value & 0x100) { 59132316Syokota value &= 0x00ff; 59232316Syokota switch (value) { 59332316Syokota case NOP: 59432316Syokota printf(" NOP, "); 59532316Syokota break; 59632316Syokota case LSH: 59732316Syokota printf(" LSH, "); 59832316Syokota break; 59932316Syokota case RSH: 60032316Syokota printf(" RSH, "); 60132316Syokota break; 60232316Syokota case CLK: 60332316Syokota printf(" CLK, "); 60432316Syokota break; 60532316Syokota case NLK: 60632316Syokota printf(" NLK, "); 60732316Syokota break; 60832316Syokota case SLK: 60932316Syokota printf(" SLK, "); 61032316Syokota break; 61132316Syokota case BTAB: 61232316Syokota printf(" BTAB, "); 61332316Syokota break; 61432316Syokota case LALT: 61532316Syokota printf(" LALT, "); 61632316Syokota break; 61732316Syokota case LCTR: 61832316Syokota printf(" LCTR, "); 61932316Syokota break; 62032316Syokota case NEXT: 62132316Syokota printf(" NEXT, "); 62232316Syokota break; 62348105Syokota case PREV: 62448105Syokota printf(" PREV, "); 62548105Syokota break; 62632316Syokota case RCTR: 62732316Syokota printf(" RCTR, "); 62832316Syokota break; 62932316Syokota case RALT: 63032316Syokota printf(" RALT, "); 63132316Syokota break; 63232316Syokota case ALK: 63332316Syokota printf(" ALK, "); 63432316Syokota break; 63532316Syokota case ASH: 63632316Syokota printf(" ASH, "); 63732316Syokota break; 63832316Syokota case META: 63932316Syokota printf(" META, "); 64032316Syokota break; 64132316Syokota case RBT: 64232316Syokota printf(" RBT, "); 64332316Syokota break; 64432316Syokota case DBG: 64532316Syokota printf(" DBG, "); 64632316Syokota break; 64732316Syokota case SUSP: 64832316Syokota printf(" SUSP, "); 64932316Syokota break; 65038053Syokota case SPSC: 65138053Syokota printf(" SPSC, "); 65238053Syokota break; 65354380Syokota case PNC: 65454380Syokota printf(" PNC, "); 65554380Syokota break; 65654380Syokota case LSHA: 65754380Syokota printf(" LSHA, "); 65854380Syokota break; 65954380Syokota case RSHA: 66054380Syokota printf(" RSHA, "); 66154380Syokota break; 66254380Syokota case LCTRA: 66354380Syokota printf("LCTRA, "); 66454380Syokota break; 66554380Syokota case RCTRA: 66654380Syokota printf("RCTRA, "); 66754380Syokota break; 66854380Syokota case LALTA: 66954380Syokota printf("LALTA, "); 67054380Syokota break; 67154380Syokota case RALTA: 67254380Syokota printf("RALTA, "); 67354380Syokota break; 67465759Sdwmalone case HALT: 67565759Sdwmalone printf(" HALT, "); 67665759Sdwmalone break; 67765759Sdwmalone case PDWN: 67865759Sdwmalone printf(" PDWN, "); 67965759Sdwmalone break; 68074118Sache case PASTE: 68174118Sache printf("PASTE, "); 68274118Sache break; 68332316Syokota default: 68432316Syokota if (value >= F_FN && value <= L_FN) 68532316Syokota printf(" F(%2d),", value - F_FN + 1); 68632316Syokota else if (value >= F_SCR && value <= L_SCR) 68732486Syokota printf(" S(%2d),", value - F_SCR + 1); 68832316Syokota else if (value >= F_ACC && value <= L_ACC) 68932316Syokota printf(" %-4s, ", acc_names_u[value - F_ACC]); 69032316Syokota else 69132316Syokota printf(" 0x%02X, ", value); 69232316Syokota break; 69332316Syokota } 69432316Syokota } else if (value == '\'') { 69532316Syokota printf(" '\\'', "); 69632316Syokota } else if (value == '\\') { 69732316Syokota printf(" '\\\\', "); 69832316Syokota } else if (isascii(value) && isprint(value)) { 69932316Syokota printf(" '%c', ", value); 70032316Syokota } else { 70132316Syokota printf(" 0x%02X, ", value); 70232316Syokota } 70332316Syokota} 70432316Syokota 70532316Syokotavoid 70632316Syokotadump_key_definition(char *name, keymap_t *keymap) 70732316Syokota{ 70832316Syokota int i, j; 70932316Syokota 71032486Syokota printf("static keymap_t keymap_%s = { 0x%02x, {\n", 71132316Syokota name, (unsigned)keymap->n_keys); 71232316Syokota printf( 71332486Syokota"/* alt\n" 71432486Syokota" * scan cntrl alt alt cntrl\n" 71532486Syokota" * code base shift cntrl shift alt shift cntrl shift spcl flgs\n" 71632316Syokota" * ---------------------------------------------------------------------------\n" 71732316Syokota" */\n"); 71832316Syokota for (i = 0; i < keymap->n_keys; i++) { 71932486Syokota printf("/*%02x*/{{", i); 72032316Syokota for (j = 0; j < NUM_STATES; j++) { 72132316Syokota if (keymap->key[i].spcl & (0x80 >> j)) 72232316Syokota dump_entry(keymap->key[i].map[j] | 0x100); 72332316Syokota else 72432316Syokota dump_entry(keymap->key[i].map[j]); 72532316Syokota } 72632486Syokota printf("}, 0x%02X,0x%02X },\n", 72732316Syokota (unsigned)keymap->key[i].spcl, 72832316Syokota (unsigned)keymap->key[i].flgs); 72932316Syokota } 73032486Syokota printf("} };\n\n"); 73132316Syokota} 73232316Syokota 73332316Syokotavoid 73432316Syokotadump_accent_definition(char *name, accentmap_t *accentmap) 73532316Syokota{ 73632316Syokota int i, j; 73732316Syokota int c; 73832316Syokota 73932486Syokota printf("static accentmap_t accentmap_%s = { %d", 74032316Syokota name, accentmap->n_accs); 74132486Syokota if (accentmap->n_accs <= 0) { 74232486Syokota printf(" };\n\n"); 74332486Syokota return; 74432486Syokota } 74532486Syokota printf(", {\n"); 74632316Syokota for (i = 0; i < NUM_DEADKEYS; i++) { 74732316Syokota printf(" /* %s=%d */\n {", acc_names[i], i); 74832316Syokota c = accentmap->acc[i].accchar; 74932316Syokota if (c == '\'') 75032316Syokota printf(" '\\'', {"); 75132316Syokota else if (c == '\\') 75232316Syokota printf(" '\\\\', {"); 75332316Syokota else if (isascii(c) && isprint(c)) 75432316Syokota printf(" '%c', {", c); 75532316Syokota else if (c == 0) { 75632316Syokota printf(" 0x00 }, \n"); 75732316Syokota continue; 75832316Syokota } else 75932316Syokota printf(" 0x%02x, {", c); 76032316Syokota for (j = 0; j < NUM_ACCENTCHARS; j++) { 76132316Syokota c = accentmap->acc[i].map[j][0]; 76232316Syokota if (c == 0) 76332316Syokota break; 76432316Syokota if ((j > 0) && ((j % 4) == 0)) 76532316Syokota printf("\n\t "); 76632316Syokota if (isascii(c) && isprint(c)) 76732316Syokota printf(" { '%c',", c); 76832316Syokota else 76932316Syokota printf(" { 0x%02x,", c); 77032316Syokota printf("0x%02x },", accentmap->acc[i].map[j][1]); 77132316Syokota } 77232316Syokota printf(" }, },\n"); 77332316Syokota } 77432486Syokota printf("} };\n\n"); 77532316Syokota} 77632316Syokota 77732316Syokotavoid 77819569Sjoergload_keymap(char *opt, int dumponly) 7792088Ssos{ 78032316Syokota keymap_t keymap; 78132316Syokota accentmap_t accentmap; 7822088Ssos FILE *fd; 78376502Ssobomax int i, j; 78419569Sjoerg char *name, *cp; 78599816Salfred char blank[] = "", keymap_path[] = KEYMAP_PATH, dotkbd[] = ".kbd"; 78699816Salfred char *prefix[] = {blank, blank, keymap_path, NULL}; 78799816Salfred char *postfix[] = {blank, dotkbd, NULL}; 7882088Ssos 78976569Ssobomax cp = getenv("KEYMAP_PATH"); 79076569Ssobomax if (cp != NULL) 79176569Ssobomax asprintf(&(prefix[0]), "%s/", cp); 79276502Ssobomax 79376643Simp fd = NULL; 79476643Simp for (i=0; prefix[i] && fd == NULL; i++) { 79576643Simp for (j=0; postfix[j] && fd == NULL; j++) { 79676502Ssobomax name = mkfullname(prefix[i], opt, postfix[j]); 79776643Simp fd = fopen(name, "r"); 79876502Ssobomax } 79976643Simp } 8002088Ssos if (fd == NULL) { 80179677Sobrien warn("keymap file \"%s\" not found", opt); 8022088Ssos return; 8032088Ssos } 80432316Syokota memset(&keymap, 0, sizeof(keymap)); 80532316Syokota memset(&accentmap, 0, sizeof(accentmap)); 80632316Syokota token = -1; 8072088Ssos while (1) { 80832316Syokota if (get_definition_line(fd, &keymap, &accentmap) < 0) 8092088Ssos break; 8102088Ssos } 81119569Sjoerg if (dumponly) { 81219569Sjoerg /* fix up the filename to make it a valid C identifier */ 81319569Sjoerg for (cp = opt; *cp; cp++) 81419569Sjoerg if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_'; 81532316Syokota printf("/*\n" 81632316Syokota " * Automatically generated from %s.\n" 81732316Syokota " * DO NOT EDIT!\n" 81832316Syokota " */\n", name); 81932316Syokota dump_key_definition(opt, &keymap); 82032316Syokota dump_accent_definition(opt, &accentmap); 82119569Sjoerg return; 82219569Sjoerg } 82332316Syokota if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) { 82429603Scharnier warn("setting keymap"); 8252088Ssos fclose(fd); 8262088Ssos return; 8272088Ssos } 82832316Syokota if ((accentmap.n_accs > 0) 82932316Syokota && (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) { 83032316Syokota warn("setting accentmap"); 83132316Syokota fclose(fd); 83232316Syokota return; 83332316Syokota } 8342088Ssos} 8352088Ssos 8362088Ssosvoid 83799816Salfredprint_keymap(void) 8382088Ssos{ 83932316Syokota keymap_t keymap; 84032316Syokota accentmap_t accentmap; 8412088Ssos int i; 8422088Ssos 84332316Syokota if (ioctl(0, GIO_KEYMAP, &keymap) < 0) 84429603Scharnier err(1, "getting keymap"); 84532316Syokota if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0) 84632316Syokota memset(&accentmap, 0, sizeof(accentmap)); 8472088Ssos printf( 8482088Ssos"# alt\n" 8492088Ssos"# scan cntrl alt alt cntrl lock\n" 8502088Ssos"# code base shift cntrl shift alt shift cntrl shift state\n" 8512088Ssos"# ------------------------------------------------------------------\n" 8522088Ssos ); 85332316Syokota for (i=0; i<keymap.n_keys; i++) 85432316Syokota print_key_definition_line(stdout, i, &keymap.key[i]); 85532316Syokota 85632316Syokota printf("\n"); 85732316Syokota for (i = 0; i < NUM_DEADKEYS; i++) 85832316Syokota print_accent_definition_line(stdout, i, &accentmap.acc[i]); 85932316Syokota 8602088Ssos} 8612088Ssos 8622088Ssosvoid 86399816Salfredload_default_functionkeys(void) 8642088Ssos{ 8652088Ssos fkeyarg_t fkey; 8662088Ssos int i; 8672088Ssos 8682088Ssos for (i=0; i<NUM_FKEYS; i++) { 8692088Ssos fkey.keynum = i; 8702088Ssos strcpy(fkey.keydef, fkey_table[i]); 8712088Ssos fkey.flen = strlen(fkey_table[i]); 8722088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 87329603Scharnier warn("setting function key"); 8742088Ssos } 8752088Ssos} 8762088Ssos 8772088Ssosvoid 8782088Ssosset_functionkey(char *keynumstr, char *string) 8792088Ssos{ 8802088Ssos fkeyarg_t fkey; 8812088Ssos 8822088Ssos if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) { 8832088Ssos load_default_functionkeys(); 8842088Ssos return; 8852088Ssos } 8862088Ssos fkey.keynum = atoi(keynumstr); 8872088Ssos if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) { 88829603Scharnier warnx("function key number must be between 1 and %d", 8892088Ssos NUM_FKEYS); 8902088Ssos return; 8912088Ssos } 8922088Ssos if ((fkey.flen = strlen(string)) > MAXFK) { 89329603Scharnier warnx("function key string too long (%d > %d)", 8942088Ssos fkey.flen, MAXFK); 8952088Ssos return; 8962088Ssos } 897133353Sjmg strncpy(fkey.keydef, string, MAXFK); 8982088Ssos fkey.keynum -= 1; 8992088Ssos if (ioctl(0, SETFKEY, &fkey) < 0) 90029603Scharnier warn("setting function key"); 9012088Ssos} 9022088Ssos 9032088Ssosvoid 9042088Ssosset_bell_values(char *opt) 9052088Ssos{ 9065536Ssos int bell, duration, pitch; 9072088Ssos 90838044Syokota bell = 0; 90938044Syokota if (!strncmp(opt, "quiet.", 6)) { 91038044Syokota bell = 2; 91138044Syokota opt += 6; 91238044Syokota } 9138857Srgrimes if (!strcmp(opt, "visual")) 91438044Syokota bell |= 1; 9155536Ssos else if (!strcmp(opt, "normal")) 91638044Syokota duration = 5, pitch = 800; 91748982Syokota else if (!strcmp(opt, "off")) 91848982Syokota duration = 0, pitch = 0; 9192088Ssos else { 9202088Ssos char *v1; 9218857Srgrimes 9225536Ssos bell = 0; 9232088Ssos duration = strtol(opt, &v1, 0); 9242088Ssos if ((duration < 0) || (*v1 != '.')) 9252088Ssos goto badopt; 9262088Ssos opt = ++v1; 9272088Ssos pitch = strtol(opt, &v1, 0); 9282088Ssos if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) { 9292088Ssosbadopt: 93077394Ssobomax warnx("argument to -b must be duration.pitch or [quiet.]visual|normal|off"); 9312088Ssos return; 9322088Ssos } 93338044Syokota if (pitch != 0) 93438044Syokota pitch = 1193182 / pitch; /* in Hz */ 93538044Syokota duration /= 10; /* in 10 m sec */ 9362088Ssos } 9372088Ssos 9385536Ssos ioctl(0, CONS_BELLTYPE, &bell); 93938044Syokota if ((bell & ~2) == 0) 9405536Ssos fprintf(stderr, "[=%d;%dB", pitch, duration); 9412088Ssos} 9422088Ssos 9432088Ssosvoid 9442088Ssosset_keyrates(char *opt) 9452088Ssos{ 94644628Syokota int arg[2]; 94739047Syokota int repeat; 94839047Syokota int delay; 94946761Syokota int r, d; 9502088Ssos 95146761Syokota if (!strcmp(opt, "slow")) { 95244628Syokota delay = 1000, repeat = 500; 95346761Syokota d = 3, r = 31; 95446761Syokota } else if (!strcmp(opt, "normal")) { 95544628Syokota delay = 500, repeat = 125; 95646761Syokota d = 1, r = 15; 95746761Syokota } else if (!strcmp(opt, "fast")) { 95839047Syokota delay = repeat = 0; 95946761Syokota d = r = 0; 96046761Syokota } else { 9612088Ssos int n; 9622088Ssos char *v1; 9632088Ssos 9642088Ssos delay = strtol(opt, &v1, 0); 9652088Ssos if ((delay < 0) || (*v1 != '.')) 9662088Ssos goto badopt; 9672088Ssos opt = ++v1; 9682088Ssos repeat = strtol(opt, &v1, 0); 9692088Ssos if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) { 9702088Ssosbadopt: 97177394Ssobomax warnx("argument to -r must be delay.repeat or slow|normal|fast"); 9722088Ssos return; 9732088Ssos } 97446761Syokota for (n = 0; n < ndelays - 1; n++) 97546761Syokota if (delay <= delays[n]) 97646761Syokota break; 97746761Syokota d = n; 97846761Syokota for (n = 0; n < nrepeats - 1; n++) 97946761Syokota if (repeat <= repeats[n]) 98046761Syokota break; 98146761Syokota r = n; 9822088Ssos } 9832088Ssos 98444628Syokota arg[0] = delay; 98544628Syokota arg[1] = repeat; 98646761Syokota if (ioctl(0, KDSETREPEAT, arg)) { 98746761Syokota if (ioctl(0, KDSETRAD, (d << 5) | r)) 98846761Syokota warn("setting keyboard rate"); 98946761Syokota } 9902088Ssos} 9912088Ssos 99299816Salfredstatic const char * 99399816Salfredget_kbd_type_name(int type) 99442505Syokota{ 99542505Syokota static struct { 99642505Syokota int type; 99799816Salfred const char *name; 99842505Syokota } name_table[] = { 99942505Syokota { KB_84, "AT 84" }, 100042505Syokota { KB_101, "AT 101/102" }, 100142505Syokota { KB_OTHER, "generic" }, 100242505Syokota }; 100399816Salfred unsigned int i; 10046046Ssos 100542505Syokota for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) { 100642505Syokota if (type == name_table[i].type) 100742505Syokota return name_table[i].name; 100842505Syokota } 100942505Syokota return "unknown"; 101042505Syokota} 101142505Syokota 101242505Syokotavoid 101342505Syokotashow_kbd_info(void) 101442505Syokota{ 101542505Syokota keyboard_info_t info; 101642505Syokota 101742505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 101842505Syokota warn("unable to obtain keyboard information"); 101942505Syokota return; 102042505Syokota } 102142505Syokota printf("kbd%d:\n", info.kb_index); 102242505Syokota printf(" %.*s%d, type:%s (%d)\n", 102377394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 102442505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 102542505Syokota} 102642505Syokota 102742505Syokotavoid 102842505Syokotaset_keyboard(char *device) 102942505Syokota{ 103042505Syokota keyboard_info_t info; 103142505Syokota int fd; 103242505Syokota 103342505Syokota fd = open(device, O_RDONLY); 103442505Syokota if (fd < 0) { 103542505Syokota warn("cannot open %s", device); 103642505Syokota return; 103742505Syokota } 103842505Syokota if (ioctl(fd, KDGKBINFO, &info) == -1) { 103942505Syokota warn("unable to obtain keyboard information"); 104042505Syokota close(fd); 104142505Syokota return; 104242505Syokota } 104342505Syokota /* 104442505Syokota * The keyboard device driver won't release the keyboard by 104542505Syokota * the following ioctl, but it automatically will, when the device 104642505Syokota * is closed. So, we don't check error here. 104742505Syokota */ 104842505Syokota ioctl(fd, CONS_RELKBD, 0); 104942505Syokota close(fd); 105042505Syokota#if 1 105142505Syokota printf("kbd%d\n", info.kb_index); 105242505Syokota printf(" %.*s%d, type:%s (%d)\n", 105377394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 105442505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 105542505Syokota#endif 105642505Syokota 105742505Syokota if (ioctl(0, CONS_SETKBD, info.kb_index) == -1) 105842505Syokota warn("unable to set keyboard"); 105942505Syokota} 106042505Syokota 106142505Syokotavoid 106242505Syokotarelease_keyboard(void) 106342505Syokota{ 106442505Syokota keyboard_info_t info; 106542505Syokota 106642505Syokota /* 106742505Syokota * If stdin is not associated with a keyboard, the following ioctl 106842505Syokota * will fail. 106942505Syokota */ 107042505Syokota if (ioctl(0, KDGKBINFO, &info) == -1) { 107142505Syokota warn("unable to obtain keyboard information"); 107242505Syokota return; 107342505Syokota } 107442505Syokota#if 1 107542505Syokota printf("kbd%d\n", info.kb_index); 107642505Syokota printf(" %.*s%d, type:%s (%d)\n", 107777394Ssobomax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 107842505Syokota get_kbd_type_name(info.kb_type), info.kb_type); 107942505Syokota#endif 108042505Syokota if (ioctl(0, CONS_RELKBD, 0) == -1) 108142505Syokota warn("unable to release the keyboard"); 108242505Syokota} 108342505Syokota 1084148017Semaxvoid 1085148017Semaxmux_keyboard(int op, char *kbd) 1086148017Semax{ 1087148017Semax keyboard_info_t info; 1088148017Semax char *unit, *ep; 108942505Syokota 1090148017Semax /* 1091148017Semax * If stdin is not associated with a keyboard, the following ioctl 1092148017Semax * will fail. 1093148017Semax */ 1094148017Semax if (ioctl(0, KDGKBINFO, &info) == -1) { 1095148017Semax warn("unable to obtain keyboard information"); 1096148017Semax return; 1097148017Semax } 1098148017Semax#if 1 1099148017Semax printf("kbd%d\n", info.kb_index); 1100148017Semax printf(" %.*s%d, type:%s (%d)\n", 1101148017Semax (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 1102148017Semax get_kbd_type_name(info.kb_type), info.kb_type); 1103148017Semax#endif 1104148017Semax /* 1105148017Semax * split kbd into name and unit. find the right most part of the 1106148017Semax * kbd string that consist of only digits. 1107148017Semax */ 1108148017Semax 1109148017Semax memset(&info, 0, sizeof(info)); 1110148017Semax 1111148017Semax info.kb_unit = -1; 1112148017Semax ep = kbd - 1; 1113148017Semax 1114148017Semax do { 1115148017Semax unit = strpbrk(ep + 1, "0123456789"); 1116148017Semax if (unit != NULL) { 1117148017Semax info.kb_unit = strtol(unit, &ep, 10); 1118148017Semax if (*ep != '\0') 1119148017Semax info.kb_unit = -1; 1120148017Semax } 1121148017Semax } while (unit != NULL && info.kb_unit == -1); 1122148017Semax 1123148017Semax if (info.kb_unit == -1) { 1124148017Semax warnx("unable to find keyboard driver unit in '%s'", kbd); 1125148017Semax return; 1126148017Semax } 1127148017Semax 1128148017Semax if (unit == kbd) { 1129148017Semax warnx("unable to find keyboard driver name in '%s'", kbd); 1130148017Semax return; 1131148017Semax } 1132148017Semax if (unit - kbd >= (int) sizeof(info.kb_name)) { 1133148017Semax warnx("keyboard name '%s' is too long", kbd); 1134148017Semax return; 1135148017Semax } 1136148017Semax 1137148017Semax strncpy(info.kb_name, kbd, unit - kbd); 1138148017Semax 1139148017Semax /* 1140148017Semax * If stdin is not associated with a kbdmux(4) keyboard, the following 1141148017Semax * ioctl will fail. 1142148017Semax */ 1143148017Semax 1144148017Semax if (ioctl(0, op, &info) == -1) 1145148017Semax warn("unable to (un)mux the keyboard"); 1146148017Semax} 1147148017Semax 114877394Ssobomaxvoid 11492088Ssosusage() 11502088Ssos{ 115129603Scharnier fprintf(stderr, "%s\n%s\n%s\n", 1152148017Semax"usage: kbdcontrol [-dFKix] [-A name] [-a name] [-b duration.pitch | [quiet.]belltype]", 115329603Scharnier" [-r delay.repeat | speed] [-l mapfile] [-f # string]", 115477329Sdes" [-k device] [-L mapfile]"); 115529603Scharnier exit(1); 11562088Ssos} 11572088Ssos 11582088Ssos 115951287Speterint 11602088Ssosmain(int argc, char **argv) 11612088Ssos{ 11622088Ssos int opt; 11632088Ssos 1164148017Semax while((opt = getopt(argc, argv, "A:a:b:df:iKk:Fl:L:r:x")) != -1) 11652088Ssos switch(opt) { 1166148017Semax case 'A': 1167148017Semax case 'a': 1168148017Semax mux_keyboard((opt == 'A')? KBRELKBD : KBADDKBD, optarg); 1169148017Semax break; 117077329Sdes case 'b': 117177329Sdes set_bell_values(optarg); 117277329Sdes break; 117377329Sdes case 'd': 117477329Sdes print_keymap(); 117577329Sdes break; 117677329Sdes case 'l': 117777329Sdes load_keymap(optarg, 0); 117877329Sdes break; 117977329Sdes case 'L': 118077329Sdes load_keymap(optarg, 1); 118177329Sdes break; 118277329Sdes case 'f': 118377329Sdes set_functionkey(optarg, 118477329Sdes nextarg(argc, argv, &optind, 'f')); 118577329Sdes break; 118677329Sdes case 'F': 118777329Sdes load_default_functionkeys(); 118877329Sdes break; 118977329Sdes case 'i': 119077329Sdes show_kbd_info(); 119177329Sdes break; 119277329Sdes case 'K': 119377329Sdes release_keyboard(); 119477329Sdes break; 119577329Sdes case 'k': 119677329Sdes set_keyboard(optarg); 119777329Sdes break; 119877329Sdes case 'r': 119977329Sdes set_keyrates(optarg); 120077329Sdes break; 120177329Sdes case 'x': 120277329Sdes hex = 1; 120377329Sdes break; 120477329Sdes default: 120577329Sdes usage(); 12062088Ssos } 120729603Scharnier if ((optind != argc) || (argc == 1)) 12082088Ssos usage(); 12092088Ssos exit(0); 12102088Ssos} 1211