kbdcontrol.c revision 114601
1139825Simp/*- 2139740Sphk * Copyright (c) 1994-1995 S�ren Schmidt 350974Swpaul * All rights reserved. 450974Swpaul * 550974Swpaul * Redistribution and use in source and binary forms, with or without 650974Swpaul * modification, are permitted provided that the following conditions 750974Swpaul * are met: 850974Swpaul * 1. Redistributions of source code must retain the above copyright 950974Swpaul * notice, this list of conditions and the following disclaimer, 1050974Swpaul * in this position and unchanged. 1150974Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1250974Swpaul * notice, this list of conditions and the following disclaimer in the 1350974Swpaul * documentation and/or other materials provided with the distribution. 1450974Swpaul * 3. The name of the author may not be used to endorse or promote products 1550974Swpaul * derived from this software without specific prior written permission 1650974Swpaul * 1750974Swpaul * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1850974Swpaul * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1950974Swpaul * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2050974Swpaul * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2150974Swpaul * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2250974Swpaul * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2350974Swpaul * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2450974Swpaul * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2550974Swpaul * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2650974Swpaul * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2750974Swpaul */ 2850974Swpaul 2950974Swpaul#include <sys/cdefs.h> 3050974Swpaul__FBSDID("$FreeBSD: head/usr.sbin/kbdcontrol/kbdcontrol.c 114601 2003-05-03 21:06:42Z obrien $"); 3150974Swpaul 3250974Swpaul#include <ctype.h> 3350974Swpaul#include <err.h> 34122678Sobrien#include <stdio.h> 35122678Sobrien#include <stdlib.h> 36122678Sobrien#include <string.h> 3750974Swpaul#include <unistd.h> 3850974Swpaul#include <fcntl.h> 3950974Swpaul#include <sys/kbio.h> 4050974Swpaul#include <sys/consio.h> 4164963Swpaul#include "path.h" 4264963Swpaul#include "lex.h" 4364963Swpaul 4450974Swpaul/* 4550974Swpaul * HALT, PDWN, and PASTE aren't defined in 4.x, but we need them to bridge 4650974Swpaul * to 5.0-current so define them here as a stop gap transition measure. 4750974Swpaul */ 4850974Swpaul#ifndef HALT 4950974Swpaul#define HALT 0xa1 /* halt machine */ 5050974Swpaul#endif 5150974Swpaul#ifndef PDWN 5250974Swpaul#define PDWN 0xa2 /* halt machine and power down */ 5350974Swpaul#endif 5450974Swpaul#ifndef PASTE 5550974Swpaul#define PASTE 0xa3 /* paste from cut-paste buffer */ 5650974Swpaul#endif 5750974Swpaul 5850974Swpaulchar ctrl_names[32][4] = { 5950974Swpaul "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", 6050974Swpaul "bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ", 61150968Sglebius "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", 62150968Sglebius "can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "us " 63150968Sglebius }; 64150968Sglebius 6550974Swpaulchar acc_names[15][5] = { 6650974Swpaul "dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot", 67212109Syongari "duml", "dsla", "drin", "dced", "dapo", "ddac", "dogo", 68212109Syongari "dcar", 69212109Syongari }; 70212109Syongari 71212109Syongarichar acc_names_u[15][5] = { 7250974Swpaul "DGRA", "DACU", "DCIR", "DTIL", "DMAC", "DBRE", "DDOT", 73129876Sphk "DUML", "DSLA", "DRIN", "DCED", "DAPO", "DDAC", "DOGO", 7450974Swpaul "DCAR", 75212109Syongari }; 76212157Syongari 7750974Swpaulchar fkey_table[96][MAXFK] = { 7850974Swpaul/* 01-04 */ "\033[M", "\033[N", "\033[O", "\033[P", 7950974Swpaul/* 05-08 */ "\033[Q", "\033[R", "\033[S", "\033[T", 8050974Swpaul/* 09-12 */ "\033[U", "\033[V", "\033[W", "\033[X", 8150974Swpaul/* 13-16 */ "\033[Y", "\033[Z", "\033[a", "\033[b", 8250974Swpaul/* 17-20 */ "\033[c", "\033[d", "\033[e", "\033[f", 8387390Sjhay/* 21-24 */ "\033[g", "\033[h", "\033[i", "\033[j", 8487390Sjhay/* 25-28 */ "\033[k", "\033[l", "\033[m", "\033[n", 8550974Swpaul/* 29-32 */ "\033[o", "\033[p", "\033[q", "\033[r", 8650974Swpaul/* 33-36 */ "\033[s", "\033[t", "\033[u", "\033[v", 8750974Swpaul/* 37-40 */ "\033[w", "\033[x", "\033[y", "\033[z", 8850974Swpaul/* 41-44 */ "\033[@", "\033[[", "\033[\\","\033[]", 8950974Swpaul/* 45-48 */ "\033[^", "\033[_", "\033[`", "\033[{", 9050974Swpaul/* 49-52 */ "\033[H", "\033[A", "\033[I", "-" , 9150974Swpaul/* 53-56 */ "\033[D", "\033[E", "\033[C", "+" , 9250974Swpaul/* 57-60 */ "\033[F", "\033[B", "\033[G", "\033[L", 9350974Swpaul/* 61-64 */ "\177", "\033[J", "\033[~", "\033[}", 9450974Swpaul/* 65-68 */ "" , "" , "" , "" , 9550974Swpaul/* 69-72 */ "" , "" , "" , "" , 96119288Simp/* 73-76 */ "" , "" , "" , "" , 97119288Simp/* 77-80 */ "" , "" , "" , "" , 9850974Swpaul/* 81-84 */ "" , "" , "" , "" , 9950974Swpaul/* 85-88 */ "" , "" , "" , "" , 10050974Swpaul/* 89-92 */ "" , "" , "" , "" , 101181524Simp/* 93-96 */ "" , "" , "" , "" , 10250974Swpaul }; 103113506Smdodd 104113506Smdoddconst int delays[] = {250, 500, 750, 1000}; 10559758Speterconst int repeats[] = { 34, 38, 42, 46, 50, 55, 59, 63, 10659758Speter 68, 76, 84, 92, 100, 110, 118, 126, 107151545Simp 136, 152, 168, 184, 200, 220, 236, 252, 10850974Swpaul 272, 304, 336, 368, 400, 440, 472, 504}; 10950974Swpaulconst int ndelays = (sizeof(delays) / sizeof(int)); 110150369Sphkconst int nrepeats = (sizeof(repeats) / sizeof(int)); 111150369Sphkint hex = 0; 112150369Sphkint number; 113150369Sphkchar letter; 11450974Swpaulint token; 115150369Sphk 116150369Sphkvoid dump_accent_definition(char *name, accentmap_t *accentmap); 117150526Sphkvoid dump_entry(int value); 118150369Sphkvoid dump_key_definition(char *name, keymap_t *keymap); 119150526Sphkint get_accent_definition_line(accentmap_t *); 120150369Sphkint get_entry(void); 121150526Sphkint get_key_definition_line(keymap_t *); 122150369Sphkvoid load_keymap(char *opt, int dumponly); 123150369Sphkvoid load_default_functionkeys(void); 12450974Swpaulchar * nextarg(int ac, char **av, int *indp, int oc); 12550974Swpaulchar * mkfullname(const char *s1, const char *s2, const char *s3); 12650974Swpaulvoid print_accent_definition_line(FILE *fp, int accent, 12750974Swpaul struct acc_t *key); 12850974Swpaulvoid print_entry(FILE *fp, int value); 129119712Sphkvoid print_key_definition_line(FILE *fp, int scancode, 13050974Swpaul struct keyent_t *key); 13150974Swpaulvoid print_keymap(void); 13250974Swpaulvoid release_keyboard(void); 133139801Sphkvoid set_bell_values(char *opt); 134212109Syongarivoid set_functionkey(char *keynumstr, char *string); 135212109Syongarivoid set_keyboard(char *device); 136212109Syongarivoid set_keyrates(char *opt); 137212109Syongarivoid show_kbd_info(void); 138212109Syongarivoid usage(void) __dead2; 139212109Syongari 140212109Syongarichar * 141212109Syongarinextarg(int ac, char **av, int *indp, int oc) 142212109Syongari{ 143139801Sphk if (*indp < ac) 144139801Sphk return(av[(*indp)++]); 145139801Sphk warnx("option requires two arguments -- %c", oc); 146139801Sphk usage(); 147139801Sphk} 148139801Sphk 149212109Syongari 150212167Syongarichar * 151212109Syongarimkfullname(const char *s1, const char *s2, const char *s3) 152139801Sphk{ 153139801Sphk static char *buf = NULL; 154139801Sphk static int bufl = 0; 155212167Syongari int f; 156212157Syongari 157166940Sdelphij f = strlen(s1) + strlen(s2) + strlen(s3) + 1; 158212167Syongari if (f > bufl) { 15950974Swpaul if (buf) 160150526Sphk buf = (char *)realloc(buf, f); 161150526Sphk else 16250974Swpaul buf = (char *)malloc(f); 163150526Sphk } 16450974Swpaul if (!buf) { 165150526Sphk bufl = 0; 16650974Swpaul return(NULL); 167150526Sphk } 168150526Sphk 169150526Sphk bufl = f; 17050974Swpaul strcpy(buf, s1); 17150974Swpaul strcat(buf, s2); 17250974Swpaul strcat(buf, s3); 17350974Swpaul return(buf); 17450974Swpaul} 17550974Swpaul 17650974Swpaul 17750974Swpaulint 17850974Swpaulget_entry(void) 17950974Swpaul{ 18050974Swpaul switch ((token = yylex())) { 18150974Swpaul case TNOP: 18250974Swpaul return NOP | 0x100; 18350974Swpaul case TLSH: 18450974Swpaul return LSH | 0x100; 18562672Swpaul case TRSH: 18662672Swpaul return RSH | 0x100; 18762672Swpaul case TCLK: 18862672Swpaul return CLK | 0x100; 189139740Sphk case TNLK: 190139740Sphk return NLK | 0x100; 19162672Swpaul case TSLK: 19262672Swpaul return SLK | 0x100; 19362672Swpaul case TBTAB: 19462672Swpaul return BTAB | 0x100; 19562672Swpaul case TLALT: 19662672Swpaul return LALT | 0x100; 197212104Syongari case TLCTR: 19862672Swpaul return LCTR | 0x100; 19962672Swpaul case TNEXT: 200102334Salfred return NEXT | 0x100; 201139740Sphk case TPREV: 20250974Swpaul return PREV | 0x100; 20350974Swpaul case TRCTR: 20450974Swpaul return RCTR | 0x100; 20550974Swpaul case TRALT: 20650974Swpaul return RALT | 0x100; 20750974Swpaul case TALK: 20850974Swpaul return ALK | 0x100; 209102334Salfred case TASH: 210139740Sphk return ASH | 0x100; 21150974Swpaul case TMETA: 212139708Sphk return META | 0x100; 21350974Swpaul case TRBT: 21450974Swpaul return RBT | 0x100; 21550974Swpaul case TDBG: 21650974Swpaul return DBG | 0x100; 21750974Swpaul case TSUSP: 21850974Swpaul return SUSP | 0x100; 21950974Swpaul case TSPSC: 22050974Swpaul return SPSC | 0x100; 22150974Swpaul case TPANIC: 22250974Swpaul return PNC | 0x100; 22350974Swpaul case TLSHA: 22450974Swpaul return LSHA | 0x100; 22550974Swpaul case TRSHA: 22650974Swpaul return RSHA | 0x100; 22750974Swpaul case TLCTRA: 22850974Swpaul return LCTRA | 0x100; 22950974Swpaul case TRCTRA: 23050974Swpaul return RCTRA | 0x100; 23150974Swpaul case TLALTA: 23250974Swpaul return LALTA | 0x100; 23350974Swpaul case TRALTA: 23450974Swpaul return RALTA | 0x100; 23550974Swpaul case THALT: 236102334Salfred return HALT | 0x100; 237139740Sphk case TPDWN: 23850974Swpaul return PDWN | 0x100; 239139708Sphk case TPASTE: 24050974Swpaul return PASTE | 0x100; 24150974Swpaul case TACC: 24250974Swpaul if (ACC(number) > L_ACC) 24350974Swpaul return -1; 24450974Swpaul return ACC(number) | 0x100; 24550974Swpaul case TFUNC: 24650974Swpaul if (F(number) > L_FN) 24750974Swpaul return -1; 24850974Swpaul return F(number) | 0x100; 24950974Swpaul case TSCRN: 25050974Swpaul if (S(number) > L_SCR) 25150974Swpaul return -1; 25250974Swpaul return S(number) | 0x100; 25350974Swpaul case TLET: 25450974Swpaul return (unsigned char)letter; 25550974Swpaul case TNUM: 25650974Swpaul if (number < 0 || number > 255) 25750974Swpaul return -1; 25850974Swpaul return number; 25950974Swpaul default: 26050974Swpaul return -1; 26150974Swpaul } 26250974Swpaul} 263102334Salfred 264139740Sphkstatic int 26550974Swpaulget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap) 266139708Sphk{ 267212113Syongari int c; 26850974Swpaul 26950974Swpaul yyin = fd; 27050974Swpaul 27150974Swpaul if (token < 0) 27250974Swpaul token = yylex(); 27350974Swpaul switch (token) { 27462672Swpaul case TNUM: 27562672Swpaul c = get_key_definition_line(keymap); 27650974Swpaul if (c < 0) 27750974Swpaul errx(1, "invalid key definition"); 27850974Swpaul if (c > keymap->n_keys) 27950974Swpaul keymap->n_keys = c; 28050974Swpaul break; 28150974Swpaul case TACC: 28250974Swpaul c = get_accent_definition_line(accentmap); 28350974Swpaul if (c < 0) 28450974Swpaul errx(1, "invalid accent key definition"); 28550974Swpaul if (c > accentmap->n_accs) 28650974Swpaul accentmap->n_accs = c; 28750974Swpaul break; 28850974Swpaul case 0: 28950974Swpaul /* EOF */ 29050974Swpaul return -1; 29150974Swpaul default: 29250974Swpaul errx(1, "illegal definition line"); 29350974Swpaul } 29450974Swpaul return c; 29550974Swpaul} 29650974Swpaul 29750974Swpaulint 29850974Swpaulget_key_definition_line(keymap_t *map) 29950974Swpaul{ 30050974Swpaul int i, def, scancode; 30150974Swpaul 30250974Swpaul /* check scancode number */ 30350974Swpaul if (number < 0 || number >= NUM_KEYS) 30450974Swpaul return -1; 30550974Swpaul scancode = number; 306102334Salfred 307139740Sphk /* get key definitions */ 30850974Swpaul map->key[scancode].spcl = 0; 30950974Swpaul for (i=0; i<NUM_STATES; i++) { 310212113Syongari if ((def = get_entry()) == -1) 31150974Swpaul return -1; 31250974Swpaul if (def & 0x100) 31350974Swpaul map->key[scancode].spcl |= (0x80 >> i); 314212113Syongari map->key[scancode].map[i] = def & 0xFF; 31550974Swpaul } 31650974Swpaul /* get lock state key def */ 31750974Swpaul if ((token = yylex()) != TFLAG) 31850974Swpaul return -1; 31950974Swpaul map->key[scancode].flgs = number; 32050974Swpaul token = yylex(); 32150974Swpaul return (scancode + 1); 322144243Sobrien} 323102334Salfred 324139740Sphkint 32572197Swpaulget_accent_definition_line(accentmap_t *map) 32672197Swpaul{ 32772197Swpaul int accent; 32872197Swpaul int c1, c2; 32972197Swpaul int i; 33072197Swpaul 33172197Swpaul if (ACC(number) < F_ACC || ACC(number) > L_ACC) 33287994Sarchie /* number out of range */ 33372197Swpaul return -1; 33472197Swpaul accent = number; 33572197Swpaul if (map->acc[accent].accchar != 0) { 336212104Syongari /* this entry has already been defined before! */ 33772197Swpaul errx(1, "duplicated accent key definition"); 33872197Swpaul } 33972197Swpaul 34072197Swpaul switch ((token = yylex())) { 341182065Simp case TLET: 342182065Simp map->acc[accent].accchar = letter; 34372197Swpaul break; 34472197Swpaul case TNUM: 34572197Swpaul map->acc[accent].accchar = number; 34672197Swpaul break; 34787994Sarchie default: 348182065Simp return -1; 34987994Sarchie } 35072197Swpaul 35172197Swpaul for (i = 0; (token = yylex()) == '(';) { 352182065Simp switch ((token = yylex())) { 35372197Swpaul case TLET: 35472197Swpaul c1 = letter; 35587994Sarchie break; 35672197Swpaul case TNUM: 357212104Syongari c1 = number; 35872197Swpaul break; 35972197Swpaul default: 360102334Salfred return -1; 361139740Sphk } 36272197Swpaul switch ((token = yylex())) { 36372197Swpaul case TLET: 364212113Syongari c2 = letter; 36572197Swpaul break; 36672197Swpaul case TNUM: 36772197Swpaul c2 = number; 36872197Swpaul break; 36972197Swpaul default: 37072197Swpaul return -1; 37172197Swpaul } 37272197Swpaul if ((token = yylex()) != ')') 37372197Swpaul return -1; 37472197Swpaul if (i >= NUM_ACCENTCHARS) { 375144243Sobrien warnx("too many accented characters, ignored"); 37672197Swpaul continue; 377144243Sobrien } 378144243Sobrien map->acc[accent].map[i][0] = c1; 379144243Sobrien map->acc[accent].map[i][1] = c2; 38072197Swpaul ++i; 38172197Swpaul } 38272197Swpaul return (accent + 1); 38372197Swpaul} 38472197Swpaul 38572197Swpaulvoid 38672197Swpaulprint_entry(FILE *fp, int value) 38772197Swpaul{ 38889296Swpaul int val = value & 0xFF; 389102334Salfred 390139740Sphk switch (value) { 39189296Swpaul case NOP | 0x100: 392212113Syongari fprintf(fp, " nop "); 39389296Swpaul break; 39489296Swpaul case LSH | 0x100: 39589296Swpaul fprintf(fp, " lshift"); 39689296Swpaul break; 39789296Swpaul case RSH | 0x100: 39889296Swpaul fprintf(fp, " rshift"); 399212103Syongari break; 40089296Swpaul case CLK | 0x100: 40189296Swpaul fprintf(fp, " clock "); 40289296Swpaul break; 403212113Syongari case NLK | 0x100: 40489296Swpaul fprintf(fp, " nlock "); 405212113Syongari break; 40689296Swpaul case SLK | 0x100: 407212113Syongari fprintf(fp, " slock "); 40889296Swpaul break; 40989296Swpaul case BTAB | 0x100: 41089296Swpaul fprintf(fp, " btab "); 41189296Swpaul break; 41272197Swpaul case LALT | 0x100: 41372197Swpaul fprintf(fp, " lalt "); 414109060Smbr break; 415109060Smbr case LCTR | 0x100: 416109060Smbr fprintf(fp, " lctrl "); 417139740Sphk break; 418139740Sphk case NEXT | 0x100: 419109060Smbr fprintf(fp, " nscr "); 420139708Sphk break; 421212103Syongari case PREV | 0x100: 422109060Smbr fprintf(fp, " pscr "); 423212103Syongari break; 424109060Smbr case RCTR | 0x100: 425109060Smbr fprintf(fp, " rctrl "); 426109060Smbr break; 427109060Smbr case RALT | 0x100: 428109060Smbr fprintf(fp, " ralt "); 429109060Smbr break; 430109060Smbr case ALK | 0x100: 431212103Syongari fprintf(fp, " alock "); 432109060Smbr break; 433109060Smbr case ASH | 0x100: 434109060Smbr fprintf(fp, " ashift"); 435139740Sphk break; 436139740Sphk case META | 0x100: 437109060Smbr fprintf(fp, " meta "); 438109060Smbr break; 439212103Syongari case RBT | 0x100: 440109060Smbr fprintf(fp, " boot "); 441212103Syongari break; 442109060Smbr case DBG | 0x100: 443109060Smbr fprintf(fp, " debug "); 444109060Smbr break; 445109060Smbr case SUSP | 0x100: 446109060Smbr fprintf(fp, " susp "); 447109060Smbr break; 448109060Smbr case SPSC | 0x100: 449109060Smbr fprintf(fp, " saver "); 450109060Smbr break; 451109060Smbr case PNC | 0x100: 452109060Smbr fprintf(fp, " panic "); 453109060Smbr break; 454212103Syongari case LSHA | 0x100: 455109060Smbr fprintf(fp, " lshifta"); 456109060Smbr break; 457109060Smbr case RSHA | 0x100: 458139740Sphk fprintf(fp, " rshifta"); 459139740Sphk break; 460109060Smbr case LCTRA | 0x100: 461150583Sjhb fprintf(fp, " lctrla"); 462212103Syongari break; 463109060Smbr case RCTRA | 0x100: 464109060Smbr fprintf(fp, " rctrla"); 465109060Smbr break; 466109060Smbr case LALTA | 0x100: 467109060Smbr fprintf(fp, " lalta "); 468109060Smbr break; 469109060Smbr case RALTA | 0x100: 470212103Syongari fprintf(fp, " ralta "); 471109060Smbr break; 472109060Smbr case HALT | 0x100: 473109060Smbr fprintf(fp, " halt "); 474109060Smbr break; 475109060Smbr case PDWN | 0x100: 476109060Smbr fprintf(fp, " pdwn "); 477212103Syongari break; 478109060Smbr case PASTE | 0x100: 479109060Smbr fprintf(fp, " paste "); 480109060Smbr break; 481109060Smbr default: 482109060Smbr if (value & 0x100) { 483109060Smbr if (val >= F_FN && val <= L_FN) 484109060Smbr fprintf(fp, " fkey%02d", val - F_FN + 1); 485212103Syongari else if (val >= F_SCR && val <= L_SCR) 486109060Smbr fprintf(fp, " scr%02d ", val - F_SCR + 1); 487109060Smbr else if (val >= F_ACC && val <= L_ACC) 488109060Smbr fprintf(fp, " %-6s", acc_names[val - F_ACC]); 489109060Smbr else if (hex) 490109060Smbr fprintf(fp, " 0x%02x ", val); 491212103Syongari else 492109060Smbr fprintf(fp, " %3d ", val); 493109060Smbr } 494212103Syongari else { 495109060Smbr if (val < ' ') 496109060Smbr fprintf(fp, " %s ", ctrl_names[val]); 497109060Smbr else if (val == 127) 498109060Smbr fprintf(fp, " del "); 499109060Smbr else if (isascii(val) && isprint(val)) 500109060Smbr fprintf(fp, " '%c' ", val); 501212103Syongari else if (hex) 502109060Smbr fprintf(fp, " 0x%02x ", val); 503109060Smbr else 504109060Smbr fprintf(fp, " %3d ", val); 505109060Smbr } 506109060Smbr } 507212104Syongari} 508109060Smbr 509109060Smbrvoid 510109060Smbrprint_key_definition_line(FILE *fp, int scancode, struct keyent_t *key) 511109060Smbr{ 512109060Smbr int i; 513109060Smbr 514109060Smbr /* print scancode number */ 515212103Syongari if (hex) 516109060Smbr fprintf(fp, " 0x%02x ", scancode); 517109060Smbr else 518109060Smbr fprintf(fp, " %03d ", scancode); 519109060Smbr 520109060Smbr /* print key definitions */ 521109060Smbr for (i=0; i<NUM_STATES; i++) { 522109060Smbr if (key->spcl & (0x80 >> i)) 523109060Smbr print_entry(fp, key->map[i] | 0x100); 524109060Smbr else 525109060Smbr print_entry(fp, key->map[i]); 526109060Smbr } 527109060Smbr 528109060Smbr /* print lock state key def */ 529109060Smbr switch (key->flgs) { 530109060Smbr case 0: 531109060Smbr fprintf(fp, " O\n"); 532109060Smbr break; 533109060Smbr case 1: 534109060Smbr fprintf(fp, " C\n"); 535109060Smbr break; 536212104Syongari case 2: 537212104Syongari fprintf(fp, " N\n"); 538109060Smbr break; 539212103Syongari case 3: 540109060Smbr fprintf(fp, " B\n"); 541109060Smbr break; 542109060Smbr } 543139740Sphk} 544139740Sphk 545109060Smbrvoid 546212103Syongariprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key) 547109060Smbr{ 548109060Smbr int c; 549109060Smbr int i; 550212103Syongari 551109060Smbr if (key->accchar == 0) 552109060Smbr return; 553109060Smbr 554212103Syongari /* print accent number */ 555109060Smbr fprintf(fp, " %-6s", acc_names[accent]); 556109060Smbr if (isascii(key->accchar) && isprint(key->accchar)) 557109060Smbr fprintf(fp, "'%c' ", key->accchar); 558109060Smbr else if (hex) 559212103Syongari fprintf(fp, "0x%02x ", key->accchar); 560109060Smbr else 561212103Syongari fprintf(fp, "%03d ", key->accchar); 562109060Smbr 563109060Smbr for (i = 0; i < NUM_ACCENTCHARS; ++i) { 564109060Smbr c = key->map[i][0]; 565109060Smbr if (c == 0) 566109060Smbr break; 567109060Smbr if ((i > 0) && ((i % 4) == 0)) 568212103Syongari fprintf(fp, "\n "); 569109060Smbr if (isascii(c) && isprint(c)) 570109060Smbr fprintf(fp, "( '%c' ", c); 571109060Smbr else if (hex) 572109060Smbr fprintf(fp, "(0x%02x ", c); 573109060Smbr else 574212103Syongari fprintf(fp, "( %03d ", c); 575109060Smbr c = key->map[i][1]; 576109060Smbr if (isascii(c) && isprint(c)) 577109060Smbr fprintf(fp, "'%c' ) ", c); 578109060Smbr else if (hex) 579212103Syongari fprintf(fp, "0x%02x) ", c); 580212104Syongari else 581109060Smbr fprintf(fp, "%03d ) ", c); 582109060Smbr } 583102334Salfred fprintf(fp, "\n"); 584139740Sphk} 58550974Swpaul 58650974Swpaulvoid 587109060Smbrdump_entry(int value) 58850974Swpaul{ 58950974Swpaul if (value & 0x100) { 59050974Swpaul value &= 0x00ff; 59162672Swpaul switch (value) { 59262672Swpaul case NOP: 593212104Syongari printf(" NOP, "); 59462672Swpaul break; 59562672Swpaul case LSH: 59662672Swpaul printf(" LSH, "); 59762672Swpaul break; 59862672Swpaul case RSH: 59962672Swpaul printf(" RSH, "); 60062672Swpaul break; 60162672Swpaul case CLK: 60262672Swpaul printf(" CLK, "); 60362672Swpaul break; 60462672Swpaul case NLK: 60562672Swpaul printf(" NLK, "); 606109060Smbr break; 60762672Swpaul case SLK: 60862672Swpaul printf(" SLK, "); 609109976Smbr break; 610109976Smbr case BTAB: 611109976Smbr printf(" BTAB, "); 612109976Smbr break; 613109976Smbr case LALT: 61489296Swpaul printf(" LALT, "); 615109976Smbr break; 616109976Smbr case LCTR: 61750974Swpaul printf(" LCTR, "); 618109976Smbr break; 619212104Syongari case NEXT: 62050974Swpaul printf(" NEXT, "); 621109976Smbr break; 622109976Smbr case PREV: 623109976Smbr printf(" PREV, "); 62450974Swpaul break; 625109976Smbr case RCTR: 626109976Smbr printf(" RCTR, "); 627109976Smbr break; 628109976Smbr case RALT: 629109976Smbr printf(" RALT, "); 630109976Smbr break; 631162315Sglebius case ALK: 632212104Syongari printf(" ALK, "); 633109976Smbr break; 634109976Smbr case ASH: 635109976Smbr printf(" ASH, "); 636109976Smbr break; 637109976Smbr case META: 638212104Syongari printf(" META, "); 639109976Smbr break; 640212104Syongari case RBT: 641109976Smbr printf(" RBT, "); 642109976Smbr break; 643109976Smbr case DBG: 644109976Smbr printf(" DBG, "); 645109976Smbr break; 646109976Smbr case SUSP: 647109976Smbr printf(" SUSP, "); 648212104Syongari break; 649109976Smbr case SPSC: 65050974Swpaul printf(" SPSC, "); 65150974Swpaul break; 652102334Salfred case PNC: 653139740Sphk printf(" PNC, "); 65450974Swpaul break; 65550974Swpaul case LSHA: 656109060Smbr printf(" LSHA, "); 65750974Swpaul break; 65850974Swpaul case RSHA: 65950974Swpaul printf(" RSHA, "); 66062672Swpaul break; 66162672Swpaul case LCTRA: 662212104Syongari printf("LCTRA, "); 66362672Swpaul break; 664212104Syongari case RCTRA: 66562672Swpaul printf("RCTRA, "); 66662672Swpaul break; 667109976Smbr case LALTA: 668109976Smbr printf("LALTA, "); 669109976Smbr break; 670109976Smbr case RALTA: 671109976Smbr printf("RALTA, "); 672109976Smbr break; 673109976Smbr case HALT: 674109976Smbr printf(" HALT, "); 67550974Swpaul break; 676109976Smbr case PDWN: 677212104Syongari printf(" PDWN, "); 67850974Swpaul break; 679109976Smbr case PASTE: 680109976Smbr printf("PASTE, "); 681109976Smbr break; 68250974Swpaul default: 683109976Smbr if (value >= F_FN && value <= L_FN) 684109976Smbr printf(" F(%2d),", value - F_FN + 1); 685109976Smbr else if (value >= F_SCR && value <= L_SCR) 686109976Smbr printf(" S(%2d),", value - F_SCR + 1); 68750974Swpaul else if (value >= F_ACC && value <= L_ACC) 688109976Smbr printf(" %-4s, ", acc_names_u[value - F_ACC]); 689162315Sglebius else 690109976Smbr printf(" 0x%02X, ", value); 691109976Smbr break; 692109976Smbr } 693109976Smbr } else if (value == '\'') { 694109976Smbr printf(" '\\'', "); 695109976Smbr } else if (value == '\\') { 696109976Smbr printf(" '\\\\', "); 697109976Smbr } else if (isascii(value) && isprint(value)) { 698212104Syongari printf(" '%c', ", value); 69950974Swpaul } else { 70050974Swpaul printf(" 0x%02X, ", value); 701102334Salfred } 702139717Sphk} 70350974Swpaul 70450974Swpaulvoid 705212116Syongaridump_key_definition(char *name, keymap_t *keymap) 706212116Syongari{ 707212116Syongari int i, j; 70850974Swpaul 70950974Swpaul printf("static keymap_t keymap_%s = { 0x%02x, {\n", 710139717Sphk name, (unsigned)keymap->n_keys); 711212116Syongari printf( 712212116Syongari"/* alt\n" 713212116Syongari" * scan cntrl alt alt cntrl\n" 714212116Syongari" * code base shift cntrl shift alt shift cntrl shift spcl flgs\n" 715212116Syongari" * ---------------------------------------------------------------------------\n" 716212116Syongari" */\n"); 717212116Syongari for (i = 0; i < keymap->n_keys; i++) { 718212157Syongari printf("/*%02x*/{{", i); 719212116Syongari for (j = 0; j < NUM_STATES; j++) { 720212116Syongari if (keymap->key[i].spcl & (0x80 >> j)) 721212116Syongari dump_entry(keymap->key[i].map[j] | 0x100); 722212116Syongari else 723212116Syongari dump_entry(keymap->key[i].map[j]); 724212157Syongari } 725212116Syongari printf("}, 0x%02X,0x%02X },\n", 726212116Syongari (unsigned)keymap->key[i].spcl, 727212116Syongari (unsigned)keymap->key[i].flgs); 728212157Syongari } 729212116Syongari printf("} };\n\n"); 730212116Syongari} 731212116Syongari 732212116Syongarivoid 733212116Syongaridump_accent_definition(char *name, accentmap_t *accentmap) 734212116Syongari{ 735212157Syongari int i, j; 736212116Syongari int c; 737212116Syongari 738212116Syongari printf("static accentmap_t accentmap_%s = { %d", 739212116Syongari name, accentmap->n_accs); 740212116Syongari if (accentmap->n_accs <= 0) { 741212116Syongari printf(" };\n\n"); 742212116Syongari return; 743212116Syongari } 744212116Syongari printf(", {\n"); 745212116Syongari for (i = 0; i < NUM_DEADKEYS; i++) { 746212116Syongari printf(" /* %s=%d */\n {", acc_names[i], i); 747212116Syongari c = accentmap->acc[i].accchar; 748212116Syongari if (c == '\'') 749212116Syongari printf(" '\\'', {"); 750212116Syongari else if (c == '\\') 751212116Syongari printf(" '\\\\', {"); 752212116Syongari else if (isascii(c) && isprint(c)) 753212116Syongari printf(" '%c', {", c); 754212116Syongari else if (c == 0) { 755212116Syongari printf(" 0x00 }, \n"); 756212116Syongari continue; 757212116Syongari } else 758212116Syongari printf(" 0x%02x, {", c); 759212116Syongari for (j = 0; j < NUM_ACCENTCHARS; j++) { 760212116Syongari c = accentmap->acc[i].map[j][0]; 761212116Syongari if (c == 0) 762212116Syongari break; 763212116Syongari if ((j > 0) && ((j % 4) == 0)) 764212116Syongari printf("\n\t "); 765212116Syongari if (isascii(c) && isprint(c)) 766212116Syongari printf(" { '%c',", c); 767212116Syongari else 768212116Syongari printf(" { 0x%02x,", c); 769212116Syongari printf("0x%02x },", accentmap->acc[i].map[j][1]); 770212116Syongari } 771212116Syongari printf(" }, },\n"); 772212116Syongari } 773212116Syongari printf("} };\n\n"); 774212116Syongari} 775212116Syongari 776212116Syongarivoid 777212116Syongariload_keymap(char *opt, int dumponly) 778212116Syongari{ 779212116Syongari keymap_t keymap; 780212116Syongari accentmap_t accentmap; 781212116Syongari FILE *fd; 782212116Syongari int i, j; 783212116Syongari char *name, *cp; 784212116Syongari char blank[] = "", keymap_path[] = KEYMAP_PATH, dotkbd[] = ".kbd"; 78550974Swpaul char *prefix[] = {blank, blank, keymap_path, NULL}; 78650974Swpaul char *postfix[] = {blank, dotkbd, NULL}; 787139740Sphk 788139740Sphk cp = getenv("KEYMAP_PATH"); 78950974Swpaul if (cp != NULL) 790130270Snaddy asprintf(&(prefix[0]), "%s/", cp); 79150974Swpaul 79250974Swpaul fd = NULL; 793130270Snaddy for (i=0; prefix[i] && fd == NULL; i++) { 79450974Swpaul for (j=0; postfix[j] && fd == NULL; j++) { 79562672Swpaul name = mkfullname(prefix[i], opt, postfix[j]); 79662672Swpaul fd = fopen(name, "r"); 79762672Swpaul } 79862672Swpaul } 79962672Swpaul if (fd == NULL) { 80062672Swpaul warn("keymap file \"%s\" not found", opt); 80162672Swpaul return; 802109060Smbr } 803109976Smbr memset(&keymap, 0, sizeof(keymap)); 804109976Smbr memset(&accentmap, 0, sizeof(accentmap)); 805109060Smbr token = -1; 806109976Smbr while (1) { 807109976Smbr if (get_definition_line(fd, &keymap, &accentmap) < 0) 80850974Swpaul break; 80950974Swpaul } 810102334Salfred if (dumponly) { 811139740Sphk /* fix up the filename to make it a valid C identifier */ 81250974Swpaul for (cp = opt; *cp; cp++) 81350974Swpaul if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_'; 81450974Swpaul printf("/*\n" 815212113Syongari " * Automatically generated from %s.\n" 81662672Swpaul " * DO NOT EDIT!\n" 81750974Swpaul " */\n", name); 818147256Sbrooks dump_key_definition(opt, &keymap); 81950974Swpaul dump_accent_definition(opt, &accentmap); 82050974Swpaul return; 82162672Swpaul } 82250974Swpaul if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) { 82350974Swpaul warn("setting keymap"); 82450974Swpaul fclose(fd); 82550974Swpaul return; 82662672Swpaul } 82762672Swpaul if ((accentmap.n_accs > 0) 82862672Swpaul && (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) { 82962672Swpaul warn("setting accentmap"); 83062672Swpaul fclose(fd); 83150974Swpaul return; 83250974Swpaul } 83350974Swpaul} 83450974Swpaul 83550974Swpaulvoid 83662672Swpaulprint_keymap(void) 83762672Swpaul{ 83862672Swpaul keymap_t keymap; 83962672Swpaul accentmap_t accentmap; 84062672Swpaul int i; 841195049Srwatson 84272084Sphk if (ioctl(0, GIO_KEYMAP, &keymap) < 0) 84362672Swpaul err(1, "getting keymap"); 84462672Swpaul if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0) 845122625Sobrien memset(&accentmap, 0, sizeof(accentmap)); 846122625Sobrien printf( 84762672Swpaul"# alt\n" 84862672Swpaul"# scan cntrl alt alt cntrl lock\n" 84962672Swpaul"# code base shift cntrl shift alt shift cntrl shift state\n" 85062672Swpaul"# ------------------------------------------------------------------\n" 85162672Swpaul ); 85262672Swpaul for (i=0; i<keymap.n_keys; i++) 85362672Swpaul print_key_definition_line(stdout, i, &keymap.key[i]); 854195049Srwatson 85562672Swpaul printf("\n"); 85662672Swpaul for (i = 0; i < NUM_DEADKEYS; i++) 85762672Swpaul print_accent_definition_line(stdout, i, &accentmap.acc[i]); 85862672Swpaul 859102334Salfred} 860139740Sphk 86162672Swpaulvoid 86262672Swpaulload_default_functionkeys(void) 86362672Swpaul{ 864212113Syongari fkeyarg_t fkey; 865212113Syongari int i; 86662672Swpaul 867147256Sbrooks for (i=0; i<NUM_FKEYS; i++) { 86862672Swpaul fkey.keynum = i; 869109060Smbr strcpy(fkey.keydef, fkey_table[i]); 870109976Smbr fkey.flen = strlen(fkey_table[i]); 871109976Smbr if (ioctl(0, SETFKEY, &fkey) < 0) 872109976Smbr warn("setting function key"); 873109976Smbr } 874109976Smbr} 87562672Swpaul 876109060Smbrvoid 87762672Swpaulset_functionkey(char *keynumstr, char *string) 878109060Smbr{ 879109060Smbr fkeyarg_t fkey; 88062672Swpaul 881109060Smbr if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) { 882109060Smbr load_default_functionkeys(); 883109060Smbr return; 884109060Smbr } 885109060Smbr fkey.keynum = atoi(keynumstr); 886109060Smbr if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) { 887109060Smbr warnx("function key number must be between 1 and %d", 888109060Smbr NUM_FKEYS); 889109060Smbr return; 890109060Smbr } 891195049Srwatson if ((fkey.flen = strlen(string)) > MAXFK) { 892109060Smbr warnx("function key string too long (%d > %d)", 893109060Smbr fkey.flen, MAXFK); 894109060Smbr return; 895122625Sobrien } 896109060Smbr strcpy(fkey.keydef, string); 897109060Smbr fkey.keynum -= 1; 898109060Smbr if (ioctl(0, SETFKEY, &fkey) < 0) 899109060Smbr warn("setting function key"); 900195049Srwatson} 901109060Smbr 902109060Smbrvoid 903109060Smbrset_bell_values(char *opt) 904109060Smbr{ 905109060Smbr int bell, duration, pitch; 90650974Swpaul 90750974Swpaul bell = 0; 908109060Smbr if (!strncmp(opt, "quiet.", 6)) { 909109060Smbr bell = 2; 910109060Smbr opt += 6; 91150974Swpaul } 91250974Swpaul if (!strcmp(opt, "visual")) 913109060Smbr bell |= 1; 91450974Swpaul else if (!strcmp(opt, "normal")) 91550974Swpaul duration = 5, pitch = 800; 916102334Salfred else if (!strcmp(opt, "off")) 917139717Sphk duration = 0, pitch = 0; 91850974Swpaul else { 919139708Sphk char *v1; 92050974Swpaul 92150974Swpaul bell = 0; 92250974Swpaul duration = strtol(opt, &v1, 0); 92350974Swpaul if ((duration < 0) || (*v1 != '.')) 92450974Swpaul goto badopt; 92550974Swpaul opt = ++v1; 92650974Swpaul pitch = strtol(opt, &v1, 0); 92750974Swpaul if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) { 92850974Swpaulbadopt: 929162315Sglebius warnx("argument to -b must be duration.pitch or [quiet.]visual|normal|off"); 93050974Swpaul return; 93150974Swpaul } 93250974Swpaul if (pitch != 0) 93372813Swpaul pitch = 1193182 / pitch; /* in Hz */ 93472813Swpaul duration /= 10; /* in 10 m sec */ 93572813Swpaul } 93672813Swpaul 93772813Swpaul ioctl(0, CONS_BELLTYPE, &bell); 93872813Swpaul if ((bell & ~2) == 0) 93972813Swpaul fprintf(stderr, "[=%d;%dB", pitch, duration); 94072813Swpaul} 941212167Syongari 942212167Syongarivoid 943212167Syongariset_keyrates(char *opt) 94472813Swpaul{ 94550974Swpaul int arg[2]; 94650974Swpaul int repeat; 94750974Swpaul int delay; 94850974Swpaul int r, d; 94950974Swpaul 95050974Swpaul if (!strcmp(opt, "slow")) { 951102334Salfred delay = 1000, repeat = 500; 952139740Sphk d = 3, r = 31; 95350974Swpaul } else if (!strcmp(opt, "normal")) { 95450974Swpaul delay = 500, repeat = 125; 95550974Swpaul d = 1, r = 15; 95650974Swpaul } else if (!strcmp(opt, "fast")) { 95750974Swpaul delay = repeat = 0; 958212104Syongari d = r = 0; 95950974Swpaul } else { 96050974Swpaul int n; 96150974Swpaul char *v1; 962142398Simp 96350974Swpaul delay = strtol(opt, &v1, 0); 96450974Swpaul if ((delay < 0) || (*v1 != '.')) 96550974Swpaul goto badopt; 96650974Swpaul opt = ++v1; 967212104Syongari repeat = strtol(opt, &v1, 0); 96850974Swpaul if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) { 96950974Swpaulbadopt: 97050974Swpaul warnx("argument to -r must be delay.repeat or slow|normal|fast"); 97150974Swpaul return; 97250974Swpaul } 97350974Swpaul for (n = 0; n < ndelays - 1; n++) 974102334Salfred if (delay <= delays[n]) 975139740Sphk break; 97650974Swpaul d = n; 97750974Swpaul for (n = 0; n < nrepeats - 1; n++) 97850974Swpaul if (repeat <= repeats[n]) 97950974Swpaul break; 980212167Syongari r = n; 98150974Swpaul } 982109061Smbr 98350974Swpaul arg[0] = delay; 98450974Swpaul arg[1] = repeat; 985162315Sglebius if (ioctl(0, KDSETREPEAT, arg)) { 986119712Sphk if (ioctl(0, KDSETRAD, (d << 5) | r)) 98793818Sjhb warn("setting keyboard rate"); 988139810Sphk } 989150583Sjhb} 99069583Swpaul 99150974Swpaulstatic const char * 99250974Swpaulget_kbd_type_name(int type) 99350974Swpaul{ 99450974Swpaul static struct { 99562672Swpaul int type; 99662672Swpaul const char *name; 99750974Swpaul } name_table[] = { 99889296Swpaul { KB_84, "AT 84" }, 99950974Swpaul { KB_101, "AT 101/102" }, 100050974Swpaul { KB_OTHER, "generic" }, 100150974Swpaul }; 100272813Swpaul unsigned int i; 100350974Swpaul 1004150526Sphk for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) { 1005150583Sjhb if (type == name_table[i].type) 1006150583Sjhb return name_table[i].name; 1007150583Sjhb } 1008150583Sjhb return "unknown"; 100950974Swpaul} 101050974Swpaul 101150974Swpaulvoid 101250974Swpaulshow_kbd_info(void) 1013109976Smbr{ 1014212103Syongari keyboard_info_t info; 1015212103Syongari 1016109976Smbr if (ioctl(0, KDGKBINFO, &info) == -1) { 1017109976Smbr warn("unable to obtain keyboard information"); 1018109976Smbr return; 1019109976Smbr } 102050974Swpaul printf("kbd%d:\n", info.kb_index); 102150974Swpaul printf(" %.*s%d, type:%s (%d)\n", 102250974Swpaul (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 102362672Swpaul get_kbd_type_name(info.kb_type), info.kb_type); 102462672Swpaul} 1025119712Sphk 1026119712Sphkvoid 1027119712Sphkset_keyboard(char *device) 1028119712Sphk{ 1029119712Sphk keyboard_info_t info; 1030119712Sphk int fd; 1031119712Sphk 1032119712Sphk fd = open(device, O_RDONLY); 1033119712Sphk if (fd < 0) { 1034119712Sphk warn("cannot open %s", device); 1035119712Sphk return; 1036119712Sphk } 103762672Swpaul if (ioctl(fd, KDGKBINFO, &info) == -1) { 103862672Swpaul warn("unable to obtain keyboard information"); 103962672Swpaul close(fd); 104062672Swpaul return; 104162672Swpaul } 104262672Swpaul /* 104362672Swpaul * The keyboard device driver won't release the keyboard by 104462672Swpaul * the following ioctl, but it automatically will, when the device 104562672Swpaul * is closed. So, we don't check error here. 104662672Swpaul */ 104762672Swpaul ioctl(fd, CONS_RELKBD, 0); 104862672Swpaul close(fd); 104962672Swpaul#if 1 1050212113Syongari printf("kbd%d\n", info.kb_index); 105150974Swpaul printf(" %.*s%d, type:%s (%d)\n", 105262672Swpaul (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 105362672Swpaul get_kbd_type_name(info.kb_type), info.kb_type); 105462672Swpaul#endif 105562672Swpaul 105662672Swpaul if (ioctl(0, CONS_SETKBD, info.kb_index) == -1) 105762681Swpaul warn("unable to set keyboard"); 105862672Swpaul} 105962681Swpaul 106062672Swpaulvoid 106162681Swpaulrelease_keyboard(void) 106262672Swpaul{ 106362672Swpaul keyboard_info_t info; 106462672Swpaul 106562672Swpaul /* 106662672Swpaul * If stdin is not associated with a keyboard, the following ioctl 106762672Swpaul * will fail. 1068212156Syongari */ 1069212156Syongari if (ioctl(0, KDGKBINFO, &info) == -1) { 1070212156Syongari warn("unable to obtain keyboard information"); 1071212156Syongari return; 1072212156Syongari } 1073212156Syongari#if 1 107462672Swpaul printf("kbd%d\n", info.kb_index); 107562672Swpaul printf(" %.*s%d, type:%s (%d)\n", 107662672Swpaul (int)sizeof(info.kb_name), info.kb_name, info.kb_unit, 107762672Swpaul get_kbd_type_name(info.kb_type), info.kb_type); 1078144243Sobrien#endif 107972197Swpaul if (ioctl(0, CONS_RELKBD, 0) == -1) 108072197Swpaul warn("unable to release the keyboard"); 108172197Swpaul} 108272197Swpaul 108372197Swpaul 108472197Swpaulvoid 108572197Swpaulusage() 108672197Swpaul{ 108772197Swpaul fprintf(stderr, "%s\n%s\n%s\n", 108872197Swpaul"usage: kbdcontrol [-dFKix] [-b duration.pitch | [quiet.]belltype]", 108972197Swpaul" [-r delay.repeat | speed] [-l mapfile] [-f # string]", 109072197Swpaul" [-k device] [-L mapfile]"); 109172197Swpaul exit(1); 109272197Swpaul} 109372197Swpaul 109489296Swpaul 109589296Swpaulint 109690328Sambriskomain(int argc, char **argv) 109772197Swpaul{ 109889296Swpaul int opt; 109990328Sambrisko 110090328Sambrisko while((opt = getopt(argc, argv, "b:df:iKk:Fl:L:r:x")) != -1) 110189296Swpaul switch(opt) { 1102109061Smbr case 'b': 1103109061Smbr set_bell_values(optarg); 1104109061Smbr break; 1105109061Smbr case 'd': 1106109061Smbr print_keymap(); 1107109061Smbr break; 1108109061Smbr case 'l': 1109109061Smbr load_keymap(optarg, 0); 1110109061Smbr break; 1111109061Smbr case 'L': 1112109061Smbr load_keymap(optarg, 1); 1113109061Smbr break; 1114109061Smbr case 'f': 1115109061Smbr set_functionkey(optarg, 1116109061Smbr nextarg(argc, argv, &optind, 'f')); 1117109061Smbr break; 1118109061Smbr case 'F': 1119109061Smbr load_default_functionkeys(); 1120109061Smbr break; 1121109061Smbr case 'i': 1122109061Smbr show_kbd_info(); 1123109061Smbr break; 1124109061Smbr case 'K': 1125109061Smbr release_keyboard(); 1126109061Smbr break; 112772197Swpaul case 'k': 112872197Swpaul set_keyboard(optarg); 112972197Swpaul break; 113062672Swpaul case 'r': 113162672Swpaul set_keyrates(optarg); 113262672Swpaul break; 1133212157Syongari case 'x': 1134212157Syongari hex = 1; 1135212109Syongari break; 1136212109Syongari default: 1137112872Snjl usage(); 113850974Swpaul } 1139147256Sbrooks if ((optind != argc) || (argc == 1)) 1140147256Sbrooks usage(); 1141150583Sjhb exit(0); 1142147256Sbrooks} 1143147256Sbrooks