kbdcontrol.c revision 54380
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
152088Ssos *    derived from this software withough 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
2929603Scharnier#ifndef lint
3029603Scharnierstatic const char rcsid[] =
3150479Speter  "$FreeBSD: head/usr.sbin/kbdcontrol/kbdcontrol.c 54380 1999-12-10 04:24:27Z yokota $";
3229603Scharnier#endif /* not lint */
3329603Scharnier
342088Ssos#include <ctype.h>
3529603Scharnier#include <err.h>
362088Ssos#include <stdio.h>
3729603Scharnier#include <stdlib.h>
383864Sswallace#include <string.h>
3929603Scharnier#include <unistd.h>
4042505Syokota#include <fcntl.h>
412088Ssos#include <machine/console.h>
422088Ssos#include "path.h"
432088Ssos#include "lex.h"
442088Ssos
452088Ssoschar ctrl_names[32][4] = {
468857Srgrimes	"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
472088Ssos	"bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ",
482088Ssos	"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
4938139Syokota	"can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "us "
502088Ssos	};
512088Ssos
5232316Syokotachar acc_names[15][5] = {
5332316Syokota	"dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot",
5432316Syokota	"duml", "dsla", "drin", "dced", "dapo", "ddac", "dogo",
5532316Syokota	"dcar",
5632316Syokota	};
5732316Syokota
5832316Syokotachar acc_names_u[15][5] = {
5932316Syokota	"DGRA", "DACU", "DCIR", "DTIL", "DMAC", "DBRE", "DDOT",
6032316Syokota	"DUML", "DSLA", "DRIN", "DCED", "DAPO", "DDAC", "DOGO",
6132316Syokota	"DCAR",
6232316Syokota	};
6332316Syokota
645994Ssoschar fkey_table[96][MAXFK] = {
655994Ssos/* 01-04 */	"\033[M", "\033[N", "\033[O", "\033[P",
665994Ssos/* 05-08 */	"\033[Q", "\033[R", "\033[S", "\033[T",
675994Ssos/* 09-12 */	"\033[U", "\033[V", "\033[W", "\033[X",
685994Ssos/* 13-16 */	"\033[Y", "\033[Z", "\033[a", "\033[b",
695994Ssos/* 17-20 */	"\033[c", "\033[d", "\033[e", "\033[f",
705994Ssos/* 21-24 */	"\033[g", "\033[h", "\033[i", "\033[j",
715994Ssos/* 25-28 */	"\033[k", "\033[l", "\033[m", "\033[n",
725994Ssos/* 29-32 */	"\033[o", "\033[p", "\033[q", "\033[r",
735994Ssos/* 33-36 */	"\033[s", "\033[t", "\033[u", "\033[v",
745994Ssos/* 37-40 */	"\033[w", "\033[x", "\033[y", "\033[z",
755994Ssos/* 41-44 */	"\033[@", "\033[[", "\033[\\","\033[]",
769202Srgrimes/* 45-48 */     "\033[^", "\033[_", "\033[`", "\033[{",
775994Ssos/* 49-52 */	"\033[H", "\033[A", "\033[I", "-"     ,
785994Ssos/* 53-56 */	"\033[D", "\033[E", "\033[C", "+"     ,
795994Ssos/* 57-60 */	"\033[F", "\033[B", "\033[G", "\033[L",
809202Srgrimes/* 61-64 */     "\177",   "\033[J", "\033[~", "\033[}",
815994Ssos/* 65-68 */	""      , ""      , ""      , ""      ,
825994Ssos/* 69-72 */	""      , ""      , ""      , ""      ,
835994Ssos/* 73-76 */	""      , ""      , ""      , ""      ,
845994Ssos/* 77-80 */	""      , ""      , ""      , ""      ,
855994Ssos/* 81-84 */	""      , ""      , ""      , ""      ,
865994Ssos/* 85-88 */	""      , ""      , ""      , ""      ,
875994Ssos/* 89-92 */	""      , ""      , ""      , ""      ,
885994Ssos/* 93-96 */	""      , ""      , ""      , ""      ,
892088Ssos	};
902088Ssos
9146761Syokotaconst int	delays[]  = {250, 500, 750, 1000};
9246761Syokotaconst int	repeats[] = { 34,  38,  42,  46,  50,  55,  59,  63,
9346761Syokota			      68,  76,  84,  92, 100, 110, 118, 126,
9446761Syokota			     136, 152, 168, 184, 200, 220, 236, 252,
9546761Syokota			     272, 304, 336, 368, 400, 440, 472, 504};
9646761Syokotaconst int	ndelays = (sizeof(delays) / sizeof(int));
9746761Syokotaconst int	nrepeats = (sizeof(repeats) / sizeof(int));
982088Ssosint 		hex = 0;
996046Ssosint 		number;
1002088Ssoschar 		letter;
10132316Syokotaint		token;
1022088Ssos
10329603Scharnierstatic void usage __P((void));
1042088Ssos
1052088Ssoschar *
1062088Ssosnextarg(int ac, char **av, int *indp, int oc)
1072088Ssos{
1082088Ssos	if (*indp < ac)
1092088Ssos		return(av[(*indp)++]);
11029603Scharnier	warnx("option requires two arguments -- %c", oc);
1112088Ssos	usage();
1122088Ssos	return("");
1132088Ssos}
1142088Ssos
1152088Ssos
1162088Ssoschar *
1172088Ssosmkfullname(const char *s1, const char *s2, const char *s3)
1182088Ssos{
1195536Ssos	static char	*buf = NULL;
1205536Ssos	static int	bufl = 0;
1215536Ssos	int		f;
1222088Ssos
1232088Ssos	f = strlen(s1) + strlen(s2) + strlen(s3) + 1;
1242088Ssos	if (f > bufl)
1252088Ssos		if (buf)
1262088Ssos			buf = (char *)realloc(buf, f);
1272088Ssos		else
1282088Ssos			buf = (char *)malloc(f);
1292088Ssos	if (!buf) {
1302088Ssos		bufl = 0;
1312088Ssos		return(NULL);
1322088Ssos	}
1332088Ssos
1342088Ssos	bufl = f;
1352088Ssos	strcpy(buf, s1);
1362088Ssos	strcat(buf, s2);
1372088Ssos	strcat(buf, s3);
1382088Ssos	return(buf);
1392088Ssos}
1402088Ssos
1412088Ssos
1422088Ssosint
1432088Ssosget_entry()
1442088Ssos{
14532316Syokota	switch ((token = yylex())) {
1462088Ssos	case TNOP:
1472088Ssos		return NOP | 0x100;
1482088Ssos	case TLSH:
1492088Ssos		return LSH | 0x100;
1502088Ssos	case TRSH:
1512088Ssos		return RSH | 0x100;
1522088Ssos	case TCLK:
1532088Ssos		return CLK | 0x100;
1542088Ssos	case TNLK:
1552088Ssos		return NLK | 0x100;
1562088Ssos	case TSLK:
1572088Ssos		return SLK | 0x100;
1582088Ssos	case TBTAB:
1592088Ssos		return BTAB | 0x100;
1602088Ssos	case TLALT:
1612088Ssos		return LALT | 0x100;
1622088Ssos	case TLCTR:
1632088Ssos		return LCTR | 0x100;
1642088Ssos	case TNEXT:
1652088Ssos		return NEXT | 0x100;
16648105Syokota	case TPREV:
16748105Syokota		return PREV | 0x100;
1682088Ssos	case TRCTR:
1692088Ssos		return RCTR | 0x100;
1702088Ssos	case TRALT:
1712088Ssos		return RALT | 0x100;
1722088Ssos	case TALK:
1732088Ssos		return ALK | 0x100;
1742088Ssos	case TASH:
1752088Ssos		return ASH | 0x100;
1762088Ssos	case TMETA:
1772088Ssos		return META | 0x100;
1782088Ssos	case TRBT:
1792088Ssos		return RBT | 0x100;
1802088Ssos	case TDBG:
1812088Ssos		return DBG | 0x100;
1825994Ssos	case TSUSP:
1835994Ssos		return SUSP | 0x100;
18438053Syokota	case TSPSC:
18538053Syokota		return SPSC | 0x100;
18654380Syokota	case TPANIC:
18754380Syokota		return PNC | 0x100;
18854380Syokota	case TLSHA:
18954380Syokota		return LSHA | 0x100;
19054380Syokota	case TRSHA:
19154380Syokota		return RSHA | 0x100;
19254380Syokota	case TLCTRA:
19354380Syokota		return LCTRA | 0x100;
19454380Syokota	case TRCTRA:
19554380Syokota		return RCTRA | 0x100;
19654380Syokota	case TLALTA:
19754380Syokota		return LALTA | 0x100;
19854380Syokota	case TRALTA:
19954380Syokota		return RALTA | 0x100;
20032316Syokota	case TACC:
20132316Syokota		if (ACC(number) > L_ACC)
20232316Syokota			return -1;
20332316Syokota		return ACC(number) | 0x100;
2042088Ssos	case TFUNC:
2052088Ssos		if (F(number) > L_FN)
2062088Ssos			return -1;
2072088Ssos		return F(number) | 0x100;
2082088Ssos	case TSCRN:
2092088Ssos		if (S(number) > L_SCR)
2102088Ssos			return -1;
2112088Ssos		return S(number) | 0x100;
2122088Ssos	case TLET:
2132088Ssos		return (unsigned char)letter;
2142088Ssos	case TNUM:
2152088Ssos		if (number < 0 || number > 255)
2162088Ssos			return -1;
2172088Ssos		return number;
2182088Ssos	default:
2192088Ssos		return -1;
2202088Ssos	}
2212088Ssos}
2222088Ssos
2232088Ssosint
22432316Syokotaget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap)
2252088Ssos{
22632316Syokota	int c;
2272088Ssos
2282088Ssos	yyin = fd;
2292088Ssos
23032316Syokota	if (token < 0)
23132316Syokota		token = yylex();
23232316Syokota	switch (token) {
23332316Syokota	case TNUM:
23432316Syokota		c = get_key_definition_line(keymap);
23532316Syokota		if (c < 0)
23632316Syokota			errx(1, "invalid key definition");
23732316Syokota		if (c > keymap->n_keys)
23832316Syokota			keymap->n_keys = c;
23932316Syokota		break;
24032316Syokota	case TACC:
24132316Syokota		c = get_accent_definition_line(accentmap);
24232316Syokota		if (c < 0)
24332316Syokota			errx(1, "invalid accent key definition");
24432316Syokota		if (c > accentmap->n_accs)
24532316Syokota			accentmap->n_accs = c;
24632316Syokota		break;
24732316Syokota	case 0:
24832316Syokota		/* EOF */
2492088Ssos		return -1;
25032316Syokota	default:
25132316Syokota		errx(1, "illegal definition line");
25232316Syokota	}
25332316Syokota	return c;
25432316Syokota}
25532316Syokota
25632316Syokotaint
25732316Syokotaget_key_definition_line(keymap_t *map)
25832316Syokota{
25932316Syokota	int i, def, scancode;
26032316Syokota
26132316Syokota	/* check scancode number */
2622088Ssos	if (number < 0 || number >= NUM_KEYS)
2632088Ssos		return -1;
2642088Ssos	scancode = number;
2652088Ssos
2662088Ssos	/* get key definitions */
2672088Ssos	map->key[scancode].spcl = 0;
2682088Ssos	for (i=0; i<NUM_STATES; i++) {
2692088Ssos		if ((def = get_entry()) == -1)
2702088Ssos			return -1;
2712088Ssos		if (def & 0x100)
2722088Ssos			map->key[scancode].spcl |= (0x80 >> i);
2732088Ssos		map->key[scancode].map[i] = def & 0xFF;
2742088Ssos	}
2752088Ssos	/* get lock state key def */
27632316Syokota	if ((token = yylex()) != TFLAG)
2772088Ssos		return -1;
2782088Ssos	map->key[scancode].flgs = number;
27932316Syokota	token = yylex();
28032316Syokota	return (scancode + 1);
2812088Ssos}
2822088Ssos
28332316Syokotaint
28432316Syokotaget_accent_definition_line(accentmap_t *map)
28532316Syokota{
28632316Syokota	int accent;
28732316Syokota	int c1, c2;
28832316Syokota	int i;
2892088Ssos
29032316Syokota	if (ACC(number) < F_ACC || ACC(number) > L_ACC)
29132316Syokota		/* number out of range */
29232316Syokota		return -1;
29332316Syokota	accent = number;
29432316Syokota	if (map->acc[accent].accchar != 0) {
29532316Syokota		/* this entry has already been defined before! */
29632316Syokota		errx(1, "duplicated accent key definition");
29732316Syokota	}
29832316Syokota
29932316Syokota	switch ((token = yylex())) {
30032316Syokota	case TLET:
30132316Syokota		map->acc[accent].accchar = letter;
30232316Syokota		break;
30332316Syokota	case TNUM:
30432316Syokota		map->acc[accent].accchar = number;
30532316Syokota		break;
30632316Syokota	default:
30732316Syokota		return -1;
30832316Syokota	}
30932316Syokota
31032316Syokota	for (i = 0; (token = yylex()) == '(';) {
31132316Syokota		switch ((token = yylex())) {
31232316Syokota		case TLET:
31332316Syokota			c1 = letter;
31432316Syokota			break;
31532316Syokota		case TNUM:
31632316Syokota			c1 = number;
31732316Syokota			break;
31832316Syokota		default:
31932316Syokota			return -1;
32032316Syokota		}
32132316Syokota		switch ((token = yylex())) {
32232316Syokota		case TLET:
32332316Syokota			c2 = letter;
32432316Syokota			break;
32532316Syokota		case TNUM:
32632316Syokota			c2 = number;
32732316Syokota			break;
32832316Syokota		default:
32932316Syokota			return -1;
33032316Syokota		}
33132316Syokota		if ((token = yylex()) != ')')
33232316Syokota			return -1;
33332316Syokota		if (i >= NUM_ACCENTCHARS) {
33432316Syokota			warnx("too many accented characters, ignored");
33532316Syokota			continue;
33632316Syokota		}
33732316Syokota		map->acc[accent].map[i][0] = c1;
33832316Syokota		map->acc[accent].map[i][1] = c2;
33932316Syokota		++i;
34032316Syokota	}
34132316Syokota	return (accent + 1);
34232316Syokota}
34332316Syokota
34429603Scharniervoid
3452088Ssosprint_entry(FILE *fp, int value)
3462088Ssos{
3472088Ssos	int val = value & 0xFF;
3482088Ssos
3492088Ssos	switch (value) {
3502088Ssos	case NOP | 0x100:
3518857Srgrimes		fprintf(fp, " nop   ");
3522088Ssos		break;
3532088Ssos	case LSH | 0x100:
3542088Ssos		fprintf(fp, " lshift");
3552088Ssos		break;
3562088Ssos	case RSH | 0x100:
3572088Ssos		fprintf(fp, " rshift");
3582088Ssos		break;
3592088Ssos	case CLK | 0x100:
3602088Ssos		fprintf(fp, " clock ");
3612088Ssos		break;
3622088Ssos	case NLK | 0x100:
3632088Ssos		fprintf(fp, " nlock ");
3642088Ssos		break;
3652088Ssos	case SLK | 0x100:
3662088Ssos		fprintf(fp, " slock ");
3672088Ssos		break;
3682088Ssos	case BTAB | 0x100:
3692088Ssos		fprintf(fp, " btab  ");
3702088Ssos		break;
3712088Ssos	case LALT | 0x100:
3722088Ssos		fprintf(fp, " lalt  ");
3732088Ssos		break;
3742088Ssos	case LCTR | 0x100:
3752088Ssos		fprintf(fp, " lctrl ");
3762088Ssos		break;
3772088Ssos	case NEXT | 0x100:
3782088Ssos		fprintf(fp, " nscr  ");
3792088Ssos		break;
38048105Syokota	case PREV | 0x100:
38148105Syokota		fprintf(fp, " pscr  ");
38248105Syokota		break;
3832088Ssos	case RCTR | 0x100:
3842088Ssos		fprintf(fp, " rctrl ");
3852088Ssos		break;
3862088Ssos	case RALT | 0x100:
3872088Ssos		fprintf(fp, " ralt  ");
3882088Ssos		break;
3892088Ssos	case ALK | 0x100:
3902088Ssos		fprintf(fp, " alock ");
3912088Ssos		break;
3922088Ssos	case ASH | 0x100:
3932088Ssos		fprintf(fp, " ashift");
3942088Ssos		break;
3952088Ssos	case META | 0x100:
3962088Ssos		fprintf(fp, " meta  ");
3972088Ssos		break;
3982088Ssos	case RBT | 0x100:
3992088Ssos		fprintf(fp, " boot  ");
4002088Ssos		break;
4012088Ssos	case DBG | 0x100:
4022088Ssos		fprintf(fp, " debug ");
4032088Ssos		break;
40432316Syokota	case SUSP | 0x100:
40532316Syokota		fprintf(fp, " susp  ");
40632316Syokota		break;
40738053Syokota	case SPSC | 0x100:
40838053Syokota		fprintf(fp, " saver ");
40938053Syokota		break;
41054380Syokota	case PNC | 0x100:
41154380Syokota		fprintf(fp, " panic ");
41254380Syokota		break;
41354380Syokota	case LSHA | 0x100:
41454380Syokota		fprintf(fp, " lshifta");
41554380Syokota		break;
41654380Syokota	case RSHA | 0x100:
41754380Syokota		fprintf(fp, " rshifta");
41854380Syokota		break;
41954380Syokota	case LCTRA | 0x100:
42054380Syokota		fprintf(fp, " lctrla");
42154380Syokota		break;
42254380Syokota	case RCTRA | 0x100:
42354380Syokota		fprintf(fp, " rctrla");
42454380Syokota		break;
42554380Syokota	case LALTA | 0x100:
42654380Syokota		fprintf(fp, " lalta ");
42754380Syokota		break;
42854380Syokota	case RALTA | 0x100:
42954380Syokota		fprintf(fp, " ralta ");
43054380Syokota		break;
4312088Ssos	default:
4322088Ssos		if (value & 0x100) {
4338857Srgrimes		 	if (val >= F_FN && val <= L_FN)
4342088Ssos				fprintf(fp, " fkey%02d", val - F_FN + 1);
4358857Srgrimes		 	else if (val >= F_SCR && val <= L_SCR)
4362088Ssos				fprintf(fp, " scr%02d ", val - F_SCR + 1);
43732316Syokota		 	else if (val >= F_ACC && val <= L_ACC)
43832316Syokota				fprintf(fp, " %-6s", acc_names[val - F_ACC]);
4392088Ssos			else if (hex)
4408857Srgrimes				fprintf(fp, " 0x%02x  ", val);
4412088Ssos			else
44232316Syokota				fprintf(fp, " %3d   ", val);
4432088Ssos		}
4442088Ssos		else {
4452088Ssos			if (val < ' ')
4468857Srgrimes				fprintf(fp, " %s   ", ctrl_names[val]);
4472088Ssos			else if (val == 127)
4488857Srgrimes				fprintf(fp, " del   ");
4499202Srgrimes			else if (isascii(val) && isprint(val))
4508857Srgrimes				fprintf(fp, " '%c'   ", val);
4512088Ssos			else if (hex)
4528857Srgrimes				fprintf(fp, " 0x%02x  ", val);
4532088Ssos			else
4548857Srgrimes				fprintf(fp, " %3d   ", val);
4552088Ssos		}
4562088Ssos	}
4572088Ssos}
4582088Ssos
4592088Ssos
4602088Ssosvoid
46142505Syokotaprint_key_definition_line(FILE *fp, int scancode, struct keyent_t *key)
4622088Ssos{
46329603Scharnier	int i;
4642088Ssos
4652088Ssos	/* print scancode number */
4662088Ssos	if (hex)
4672088Ssos		fprintf(fp, " 0x%02x  ", scancode);
4682088Ssos	else
4692088Ssos		fprintf(fp, "  %03d  ", scancode);
4702088Ssos
4712088Ssos	/* print key definitions */
4722088Ssos	for (i=0; i<NUM_STATES; i++) {
4732088Ssos		if (key->spcl & (0x80 >> i))
4742088Ssos			print_entry(fp, key->map[i] | 0x100);
4752088Ssos		else
4768857Srgrimes			print_entry(fp, key->map[i]);
4772088Ssos	}
4782088Ssos
4792088Ssos	/* print lock state key def */
4802088Ssos	switch (key->flgs) {
4812088Ssos	case 0:
4822088Ssos		fprintf(fp, "  O\n");
4832088Ssos		break;
4842088Ssos	case 1:
4852088Ssos		fprintf(fp, "  C\n");
4862088Ssos		break;
4872088Ssos	case 2:
4882088Ssos		fprintf(fp, "  N\n");
4892088Ssos		break;
4906046Ssos	case 3:
4916046Ssos		fprintf(fp, "  B\n");
4926046Ssos		break;
4938857Srgrimes	}
4942088Ssos}
4952088Ssos
49632316Syokotavoid
49732316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key)
49832316Syokota{
49932316Syokota	int c;
50032316Syokota	int i;
5012088Ssos
50232316Syokota	if (key->accchar == 0)
50332316Syokota		return;
50432316Syokota
50532316Syokota	/* print accent number */
50632316Syokota	fprintf(fp, "  %-6s", acc_names[accent]);
50732316Syokota	if (isascii(key->accchar) && isprint(key->accchar))
50832316Syokota		fprintf(fp, "'%c'  ", key->accchar);
50932316Syokota	else if (hex)
51032316Syokota		fprintf(fp, "0x%02x ", key->accchar);
51132316Syokota	else
51232316Syokota		fprintf(fp, "%03d  ", key->accchar);
51332316Syokota
51432316Syokota	for (i = 0; i < NUM_ACCENTCHARS; ++i) {
51532316Syokota		c = key->map[i][0];
51632316Syokota		if (c == 0)
51732316Syokota			break;
51832316Syokota		if ((i > 0) && ((i % 4) == 0))
51932316Syokota			fprintf(fp, "\n             ");
52032316Syokota		if (isascii(c) && isprint(c))
52132316Syokota			fprintf(fp, "( '%c' ", c);
52232316Syokota		else if (hex)
52332316Syokota			fprintf(fp, "(0x%02x ", c);
52432316Syokota		else
52532316Syokota			fprintf(fp, "( %03d ", c);
52632316Syokota		c = key->map[i][1];
52732316Syokota		if (isascii(c) && isprint(c))
52832316Syokota			fprintf(fp, "'%c' ) ", c);
52932316Syokota		else if (hex)
53032316Syokota			fprintf(fp, "0x%02x) ", c);
53132316Syokota		else
53232316Syokota			fprintf(fp, "%03d ) ", c);
53332316Syokota	}
53432316Syokota	fprintf(fp, "\n");
53532316Syokota}
53632316Syokota
5372088Ssosvoid
53832316Syokotadump_entry(int value)
53932316Syokota{
54032316Syokota	if (value & 0x100) {
54132316Syokota		value &= 0x00ff;
54232316Syokota		switch (value) {
54332316Syokota		case NOP:
54432316Syokota			printf("  NOP, ");
54532316Syokota			break;
54632316Syokota		case LSH:
54732316Syokota			printf("  LSH, ");
54832316Syokota			break;
54932316Syokota		case RSH:
55032316Syokota			printf("  RSH, ");
55132316Syokota			break;
55232316Syokota		case CLK:
55332316Syokota			printf("  CLK, ");
55432316Syokota			break;
55532316Syokota		case NLK:
55632316Syokota			printf("  NLK, ");
55732316Syokota			break;
55832316Syokota		case SLK:
55932316Syokota			printf("  SLK, ");
56032316Syokota			break;
56132316Syokota		case BTAB:
56232316Syokota			printf(" BTAB, ");
56332316Syokota			break;
56432316Syokota		case LALT:
56532316Syokota			printf(" LALT, ");
56632316Syokota			break;
56732316Syokota		case LCTR:
56832316Syokota			printf(" LCTR, ");
56932316Syokota			break;
57032316Syokota		case NEXT:
57132316Syokota			printf(" NEXT, ");
57232316Syokota			break;
57348105Syokota		case PREV:
57448105Syokota			printf(" PREV, ");
57548105Syokota			break;
57632316Syokota		case RCTR:
57732316Syokota			printf(" RCTR, ");
57832316Syokota			break;
57932316Syokota		case RALT:
58032316Syokota			printf(" RALT, ");
58132316Syokota			break;
58232316Syokota		case ALK:
58332316Syokota			printf("  ALK, ");
58432316Syokota			break;
58532316Syokota		case ASH:
58632316Syokota			printf("  ASH, ");
58732316Syokota			break;
58832316Syokota		case META:
58932316Syokota			printf(" META, ");
59032316Syokota			break;
59132316Syokota		case RBT:
59232316Syokota			printf("  RBT, ");
59332316Syokota			break;
59432316Syokota		case DBG:
59532316Syokota			printf("  DBG, ");
59632316Syokota			break;
59732316Syokota		case SUSP:
59832316Syokota			printf(" SUSP, ");
59932316Syokota			break;
60038053Syokota		case SPSC:
60138053Syokota			printf(" SPSC, ");
60238053Syokota			break;
60354380Syokota		case PNC:
60454380Syokota			printf("  PNC, ");
60554380Syokota			break;
60654380Syokota		case LSHA:
60754380Syokota			printf(" LSHA, ");
60854380Syokota			break;
60954380Syokota		case RSHA:
61054380Syokota			printf(" RSHA, ");
61154380Syokota			break;
61254380Syokota		case LCTRA:
61354380Syokota			printf("LCTRA, ");
61454380Syokota			break;
61554380Syokota		case RCTRA:
61654380Syokota			printf("RCTRA, ");
61754380Syokota			break;
61854380Syokota		case LALTA:
61954380Syokota			printf("LALTA, ");
62054380Syokota			break;
62154380Syokota		case RALTA:
62254380Syokota			printf("RALTA, ");
62354380Syokota			break;
62432316Syokota		default:
62532316Syokota	 		if (value >= F_FN && value <= L_FN)
62632316Syokota				printf(" F(%2d),", value - F_FN + 1);
62732316Syokota	 		else if (value >= F_SCR && value <= L_SCR)
62832486Syokota				printf(" S(%2d),", value - F_SCR + 1);
62932316Syokota	 		else if (value >= F_ACC && value <= L_ACC)
63032316Syokota				printf(" %-4s, ", acc_names_u[value - F_ACC]);
63132316Syokota			else
63232316Syokota				printf(" 0x%02X, ", value);
63332316Syokota			break;
63432316Syokota		}
63532316Syokota	} else if (value == '\'') {
63632316Syokota		printf(" '\\'', ");
63732316Syokota	} else if (value == '\\') {
63832316Syokota		printf(" '\\\\', ");
63932316Syokota	} else if (isascii(value) && isprint(value)) {
64032316Syokota		printf("  '%c', ", value);
64132316Syokota	} else {
64232316Syokota		printf(" 0x%02X, ", value);
64332316Syokota	}
64432316Syokota}
64532316Syokota
64632316Syokotavoid
64732316Syokotadump_key_definition(char *name, keymap_t *keymap)
64832316Syokota{
64932316Syokota	int	i, j;
65032316Syokota
65132486Syokota	printf("static keymap_t keymap_%s = { 0x%02x, {\n",
65232316Syokota	       name, (unsigned)keymap->n_keys);
65332316Syokota	printf(
65432486Syokota"/*                                                         alt\n"
65532486Syokota" * scan                       cntrl          alt    alt   cntrl\n"
65632486Syokota" * code  base   shift  cntrl  shift   alt   shift  cntrl  shift    spcl flgs\n"
65732316Syokota" * ---------------------------------------------------------------------------\n"
65832316Syokota" */\n");
65932316Syokota	for (i = 0; i < keymap->n_keys; i++) {
66032486Syokota		printf("/*%02x*/{{", i);
66132316Syokota		for (j = 0; j < NUM_STATES; j++) {
66232316Syokota			if (keymap->key[i].spcl & (0x80 >> j))
66332316Syokota				dump_entry(keymap->key[i].map[j] | 0x100);
66432316Syokota			else
66532316Syokota				dump_entry(keymap->key[i].map[j]);
66632316Syokota		}
66732486Syokota		printf("}, 0x%02X,0x%02X },\n",
66832316Syokota		       (unsigned)keymap->key[i].spcl,
66932316Syokota		       (unsigned)keymap->key[i].flgs);
67032316Syokota	}
67132486Syokota	printf("} };\n\n");
67232316Syokota}
67332316Syokota
67432316Syokotavoid
67532316Syokotadump_accent_definition(char *name, accentmap_t *accentmap)
67632316Syokota{
67732316Syokota	int i, j;
67832316Syokota	int c;
67932316Syokota
68032486Syokota	printf("static accentmap_t accentmap_%s = { %d",
68132316Syokota		name, accentmap->n_accs);
68232486Syokota	if (accentmap->n_accs <= 0) {
68332486Syokota		printf(" };\n\n");
68432486Syokota		return;
68532486Syokota	}
68632486Syokota	printf(", {\n");
68732316Syokota	for (i = 0; i < NUM_DEADKEYS; i++) {
68832316Syokota		printf("    /* %s=%d */\n    {", acc_names[i], i);
68932316Syokota		c = accentmap->acc[i].accchar;
69032316Syokota		if (c == '\'')
69132316Syokota			printf(" '\\'', {");
69232316Syokota		else if (c == '\\')
69332316Syokota			printf(" '\\\\', {");
69432316Syokota		else if (isascii(c) && isprint(c))
69532316Syokota			printf("  '%c', {", c);
69632316Syokota		else if (c == 0) {
69732316Syokota			printf(" 0x00 }, \n");
69832316Syokota			continue;
69932316Syokota		} else
70032316Syokota			printf(" 0x%02x, {", c);
70132316Syokota		for (j = 0; j < NUM_ACCENTCHARS; j++) {
70232316Syokota			c = accentmap->acc[i].map[j][0];
70332316Syokota			if (c == 0)
70432316Syokota				break;
70532316Syokota			if ((j > 0) && ((j % 4) == 0))
70632316Syokota				printf("\n\t     ");
70732316Syokota			if (isascii(c) && isprint(c))
70832316Syokota				printf(" {  '%c',", c);
70932316Syokota			else
71032316Syokota				printf(" { 0x%02x,", c);
71132316Syokota			printf("0x%02x },", accentmap->acc[i].map[j][1]);
71232316Syokota		}
71332316Syokota		printf(" }, },\n");
71432316Syokota	}
71532486Syokota	printf("} };\n\n");
71632316Syokota}
71732316Syokota
71832316Syokotavoid
71919569Sjoergload_keymap(char *opt, int dumponly)
7202088Ssos{
72132316Syokota	keymap_t keymap;
72232316Syokota	accentmap_t accentmap;
7232088Ssos	FILE	*fd;
72432316Syokota	int	i;
72519569Sjoerg	char	*name, *cp;
72635750Sdes	char	*prefix[]  = {"", "", KEYMAP_PATH, KEYMAP_PATH, NULL};
72735750Sdes	char	*postfix[] = {"", ".kbd", "", ".kbd"};
7282088Ssos
7292088Ssos	for (i=0; prefix[i]; i++) {
7302088Ssos		name = mkfullname(prefix[i], opt, postfix[i]);
73129603Scharnier		if ((fd = fopen(name, "r")))
7322088Ssos			break;
7332088Ssos	}
7342088Ssos	if (fd == NULL) {
73529603Scharnier		warn("keymap file not found");
7362088Ssos		return;
7372088Ssos	}
73832316Syokota	memset(&keymap, 0, sizeof(keymap));
73932316Syokota	memset(&accentmap, 0, sizeof(accentmap));
74032316Syokota	token = -1;
7412088Ssos	while (1) {
74232316Syokota		if (get_definition_line(fd, &keymap, &accentmap) < 0)
7432088Ssos			break;
7442088Ssos    	}
74519569Sjoerg	if (dumponly) {
74619569Sjoerg		/* fix up the filename to make it a valid C identifier */
74719569Sjoerg		for (cp = opt; *cp; cp++)
74819569Sjoerg			if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_';
74932316Syokota		printf("/*\n"
75032316Syokota		       " * Automatically generated from %s.\n"
75132316Syokota	               " * DO NOT EDIT!\n"
75232316Syokota		       " */\n", name);
75332316Syokota		dump_key_definition(opt, &keymap);
75432316Syokota		dump_accent_definition(opt, &accentmap);
75519569Sjoerg		return;
75619569Sjoerg	}
75732316Syokota	if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) {
75829603Scharnier		warn("setting keymap");
7592088Ssos		fclose(fd);
7602088Ssos		return;
7612088Ssos	}
76232316Syokota	if ((accentmap.n_accs > 0)
76332316Syokota		&& (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) {
76432316Syokota		warn("setting accentmap");
76532316Syokota		fclose(fd);
76632316Syokota		return;
76732316Syokota	}
7682088Ssos}
7692088Ssos
7702088Ssosvoid
7712088Ssosprint_keymap()
7722088Ssos{
77332316Syokota	keymap_t keymap;
77432316Syokota	accentmap_t accentmap;
7752088Ssos	int i;
7762088Ssos
77732316Syokota	if (ioctl(0, GIO_KEYMAP, &keymap) < 0)
77829603Scharnier		err(1, "getting keymap");
77932316Syokota	if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0)
78032316Syokota		memset(&accentmap, 0, sizeof(accentmap));
7812088Ssos    	printf(
7822088Ssos"#                                                         alt\n"
7832088Ssos"# scan                       cntrl          alt    alt   cntrl lock\n"
7842088Ssos"# code  base   shift  cntrl  shift  alt    shift  cntrl  shift state\n"
7852088Ssos"# ------------------------------------------------------------------\n"
7862088Ssos    	);
78732316Syokota	for (i=0; i<keymap.n_keys; i++)
78832316Syokota		print_key_definition_line(stdout, i, &keymap.key[i]);
78932316Syokota
79032316Syokota	printf("\n");
79132316Syokota	for (i = 0; i < NUM_DEADKEYS; i++)
79232316Syokota		print_accent_definition_line(stdout, i, &accentmap.acc[i]);
79332316Syokota
7942088Ssos}
7952088Ssos
7962088Ssos
7972088Ssosvoid
7982088Ssosload_default_functionkeys()
7992088Ssos{
8002088Ssos	fkeyarg_t fkey;
8012088Ssos	int i;
8022088Ssos
8032088Ssos	for (i=0; i<NUM_FKEYS; i++) {
8042088Ssos		fkey.keynum = i;
8052088Ssos		strcpy(fkey.keydef, fkey_table[i]);
8062088Ssos		fkey.flen = strlen(fkey_table[i]);
8072088Ssos		if (ioctl(0, SETFKEY, &fkey) < 0)
80829603Scharnier			warn("setting function key");
8092088Ssos	}
8102088Ssos}
8112088Ssos
8122088Ssosvoid
8132088Ssosset_functionkey(char *keynumstr, char *string)
8142088Ssos{
8152088Ssos	fkeyarg_t fkey;
8162088Ssos
8172088Ssos	if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) {
8182088Ssos		load_default_functionkeys();
8192088Ssos		return;
8202088Ssos	}
8212088Ssos	fkey.keynum = atoi(keynumstr);
8222088Ssos	if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) {
82329603Scharnier		warnx("function key number must be between 1 and %d",
8242088Ssos			NUM_FKEYS);
8252088Ssos		return;
8262088Ssos	}
8272088Ssos	if ((fkey.flen = strlen(string)) > MAXFK) {
82829603Scharnier		warnx("function key string too long (%d > %d)",
8292088Ssos			fkey.flen, MAXFK);
8302088Ssos		return;
8312088Ssos	}
8322088Ssos	strcpy(fkey.keydef, string);
8332088Ssos	fkey.keynum -= 1;
8342088Ssos	if (ioctl(0, SETFKEY, &fkey) < 0)
83529603Scharnier		warn("setting function key");
8362088Ssos}
8372088Ssos
8382088Ssos
8392088Ssosvoid
8402088Ssosset_bell_values(char *opt)
8412088Ssos{
8425536Ssos	int bell, duration, pitch;
8432088Ssos
84438044Syokota	bell = 0;
84538044Syokota	if (!strncmp(opt, "quiet.", 6)) {
84638044Syokota		bell = 2;
84738044Syokota		opt += 6;
84838044Syokota	}
8498857Srgrimes	if (!strcmp(opt, "visual"))
85038044Syokota		bell |= 1;
8515536Ssos	else if (!strcmp(opt, "normal"))
85238044Syokota		duration = 5, pitch = 800;
85348982Syokota	else if (!strcmp(opt, "off"))
85448982Syokota		duration = 0, pitch = 0;
8552088Ssos	else {
8562088Ssos		char		*v1;
8578857Srgrimes
8585536Ssos		bell = 0;
8592088Ssos		duration = strtol(opt, &v1, 0);
8602088Ssos		if ((duration < 0) || (*v1 != '.'))
8612088Ssos			goto badopt;
8622088Ssos		opt = ++v1;
8632088Ssos		pitch = strtol(opt, &v1, 0);
8642088Ssos		if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) {
8652088Ssosbadopt:
86629603Scharnier			warnx("argument to -b must be DURATION.PITCH");
8672088Ssos			return;
8682088Ssos		}
86938044Syokota		if (pitch != 0)
87038044Syokota			pitch = 1193182 / pitch;	/* in Hz */
87138044Syokota		duration /= 10;	/* in 10 m sec */
8722088Ssos	}
8732088Ssos
8745536Ssos	ioctl(0, CONS_BELLTYPE, &bell);
87538044Syokota	if ((bell & ~2) == 0)
8765536Ssos		fprintf(stderr, "[=%d;%dB", pitch, duration);
8772088Ssos}
8782088Ssos
8792088Ssos
8802088Ssosvoid
8812088Ssosset_keyrates(char *opt)
8822088Ssos{
88344628Syokota	int arg[2];
88439047Syokota	int repeat;
88539047Syokota	int delay;
88646761Syokota	int r, d;
8872088Ssos
88846761Syokota	if (!strcmp(opt, "slow")) {
88944628Syokota		delay = 1000, repeat = 500;
89046761Syokota		d = 3, r = 31;
89146761Syokota	} else if (!strcmp(opt, "normal")) {
89244628Syokota		delay = 500, repeat = 125;
89346761Syokota		d = 1, r = 15;
89446761Syokota	} else if (!strcmp(opt, "fast")) {
89539047Syokota		delay = repeat = 0;
89646761Syokota		d = r = 0;
89746761Syokota	} else {
8982088Ssos		int		n;
8992088Ssos		char		*v1;
9002088Ssos
9012088Ssos		delay = strtol(opt, &v1, 0);
9022088Ssos		if ((delay < 0) || (*v1 != '.'))
9032088Ssos			goto badopt;
9042088Ssos		opt = ++v1;
9052088Ssos		repeat = strtol(opt, &v1, 0);
9062088Ssos		if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) {
9072088Ssosbadopt:
90829603Scharnier			warnx("argument to -r must be delay.repeat");
9092088Ssos			return;
9102088Ssos		}
91146761Syokota		for (n = 0; n < ndelays - 1; n++)
91246761Syokota			if (delay <= delays[n])
91346761Syokota				break;
91446761Syokota		d = n;
91546761Syokota		for (n = 0; n < nrepeats - 1; n++)
91646761Syokota			if (repeat <= repeats[n])
91746761Syokota				break;
91846761Syokota		r = n;
9192088Ssos	}
9202088Ssos
92144628Syokota	arg[0] = delay;
92244628Syokota	arg[1] = repeat;
92346761Syokota	if (ioctl(0, KDSETREPEAT, arg)) {
92446761Syokota		if (ioctl(0, KDSETRAD, (d << 5) | r))
92546761Syokota			warn("setting keyboard rate");
92646761Syokota	}
9272088Ssos}
9282088Ssos
9292088Ssos
9306046Ssosvoid
9316046Ssosset_history(char *opt)
9326046Ssos{
9336046Ssos	int size;
9346046Ssos
9356046Ssos	size = atoi(opt);
9366046Ssos	if ((*opt == '\0') || size < 0) {
93729603Scharnier		warnx("argument must be a positive number");
9386046Ssos		return;
9396046Ssos	}
9406046Ssos	if (ioctl(0, CONS_HISTORY, &size) == -1)
94129603Scharnier		warn("setting history buffer size");
9426046Ssos}
9436046Ssos
94442505Syokotastatic char
94542505Syokota*get_kbd_type_name(int type)
94642505Syokota{
94742505Syokota	static struct {
94842505Syokota		int type;
94942505Syokota		char *name;
95042505Syokota	} name_table[] = {
95142505Syokota		{ KB_84,	"AT 84" },
95242505Syokota		{ KB_101,	"AT 101/102" },
95342505Syokota		{ KB_OTHER,	"generic" },
95442505Syokota	};
95542505Syokota	int i;
9566046Ssos
95742505Syokota	for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) {
95842505Syokota		if (type == name_table[i].type)
95942505Syokota			return name_table[i].name;
96042505Syokota	}
96142505Syokota	return "unknown";
96242505Syokota}
96342505Syokota
96442505Syokotavoid
96542505Syokotashow_kbd_info(void)
96642505Syokota{
96742505Syokota	keyboard_info_t info;
96842505Syokota
96942505Syokota	if (ioctl(0, KDGKBINFO, &info) == -1) {
97042505Syokota		warn("unable to obtain keyboard information");
97142505Syokota		return;
97242505Syokota	}
97342505Syokota	printf("kbd%d:\n", info.kb_index);
97442505Syokota	printf("    %.*s%d, type:%s (%d)\n",
97542505Syokota		sizeof(info.kb_name), info.kb_name, info.kb_unit,
97642505Syokota		get_kbd_type_name(info.kb_type), info.kb_type);
97742505Syokota}
97842505Syokota
97942505Syokota
98042505Syokotavoid
98142505Syokotaset_keyboard(char *device)
98242505Syokota{
98342505Syokota	keyboard_info_t info;
98442505Syokota	int fd;
98542505Syokota
98642505Syokota	fd = open(device, O_RDONLY);
98742505Syokota	if (fd < 0) {
98842505Syokota		warn("cannot open %s", device);
98942505Syokota		return;
99042505Syokota	}
99142505Syokota	if (ioctl(fd, KDGKBINFO, &info) == -1) {
99242505Syokota		warn("unable to obtain keyboard information");
99342505Syokota		close(fd);
99442505Syokota		return;
99542505Syokota	}
99642505Syokota	/*
99742505Syokota	 * The keyboard device driver won't release the keyboard by
99842505Syokota	 * the following ioctl, but it automatically will, when the device
99942505Syokota	 * is closed.  So, we don't check error here.
100042505Syokota	 */
100142505Syokota	ioctl(fd, CONS_RELKBD, 0);
100242505Syokota	close(fd);
100342505Syokota#if 1
100442505Syokota	printf("kbd%d\n", info.kb_index);
100542505Syokota	printf("    %.*s%d, type:%s (%d)\n",
100642505Syokota		sizeof(info.kb_name), info.kb_name, info.kb_unit,
100742505Syokota		get_kbd_type_name(info.kb_type), info.kb_type);
100842505Syokota#endif
100942505Syokota
101042505Syokota	if (ioctl(0, CONS_SETKBD, info.kb_index) == -1)
101142505Syokota		warn("unable to set keyboard");
101242505Syokota}
101342505Syokota
101442505Syokota
101542505Syokotavoid
101642505Syokotarelease_keyboard(void)
101742505Syokota{
101842505Syokota	keyboard_info_t info;
101942505Syokota
102042505Syokota	/*
102142505Syokota	 * If stdin is not associated with a keyboard, the following ioctl
102242505Syokota	 * will fail.
102342505Syokota	 */
102442505Syokota	if (ioctl(0, KDGKBINFO, &info) == -1) {
102542505Syokota		warn("unable to obtain keyboard information");
102642505Syokota		return;
102742505Syokota	}
102842505Syokota#if 1
102942505Syokota	printf("kbd%d\n", info.kb_index);
103042505Syokota	printf("    %.*s%d, type:%s (%d)\n",
103142505Syokota		sizeof(info.kb_name), info.kb_name, info.kb_unit,
103242505Syokota		get_kbd_type_name(info.kb_type), info.kb_type);
103342505Syokota#endif
103442505Syokota	if (ioctl(0, CONS_RELKBD, 0) == -1)
103542505Syokota		warn("unable to release the keyboard");
103642505Syokota}
103742505Syokota
103842505Syokota
103929603Scharnierstatic void
10402088Ssosusage()
10412088Ssos{
104229603Scharnier	fprintf(stderr, "%s\n%s\n%s\n",
104342505Syokota"usage: kbdcontrol [-dFKix] [-b  duration.pitch | [quiet.]belltype]",
104429603Scharnier"                  [-r delay.repeat | speed] [-l mapfile] [-f # string]",
104542505Syokota"                  [-h size] [-k device] [-L mapfile]");
104629603Scharnier	exit(1);
10472088Ssos}
10482088Ssos
10492088Ssos
105051287Speterint
10512088Ssosmain(int argc, char **argv)
10522088Ssos{
10532088Ssos	int		opt;
10542088Ssos
105542505Syokota	while((opt = getopt(argc, argv, "b:df:h:iKk:Fl:L:r:x")) != -1)
10562088Ssos		switch(opt) {
10572088Ssos			case 'b':
10582088Ssos				set_bell_values(optarg);
10592088Ssos				break;
10602088Ssos			case 'd':
10612088Ssos				print_keymap();
10622088Ssos				break;
10632088Ssos			case 'l':
106419569Sjoerg				load_keymap(optarg, 0);
10652088Ssos				break;
106619569Sjoerg			case 'L':
106719569Sjoerg				load_keymap(optarg, 1);
106819569Sjoerg				break;
10692088Ssos			case 'f':
10708857Srgrimes				set_functionkey(optarg,
10712088Ssos					nextarg(argc, argv, &optind, 'f'));
10722088Ssos				break;
10732088Ssos			case 'F':
10742088Ssos				load_default_functionkeys();
10752088Ssos				break;
10766046Ssos			case 'h':
10776046Ssos				set_history(optarg);
10786046Ssos				break;
107942505Syokota			case 'i':
108042505Syokota				show_kbd_info();
108142505Syokota				break;
108242505Syokota			case 'K':
108342505Syokota				release_keyboard();
108442505Syokota				break;
108542505Syokota			case 'k':
108642505Syokota				set_keyboard(optarg);
108742505Syokota				break;
10882088Ssos			case 'r':
10892088Ssos				set_keyrates(optarg);
10902088Ssos				break;
10912088Ssos			case 'x':
10922088Ssos				hex = 1;
10932088Ssos				break;
10942088Ssos			default:
10952088Ssos				usage();
10962088Ssos		}
109729603Scharnier	if ((optind != argc) || (argc == 1))
10982088Ssos		usage();
10992088Ssos	exit(0);
11002088Ssos}
11012088Ssos
11022088Ssos
1103