kbdcontrol.c revision 133353
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 133353 2004-08-09 04:27:58Z jmg $");
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);
13399816Salfredvoid		set_bell_values(char *opt);
13499816Salfredvoid		set_functionkey(char *keynumstr, char *string);
13599816Salfredvoid		set_keyboard(char *device);
13699816Salfredvoid		set_keyrates(char *opt);
13799816Salfredvoid		show_kbd_info(void);
13899816Salfredvoid		usage(void) __dead2;
1392088Ssos
1402088Ssoschar *
1412088Ssosnextarg(int ac, char **av, int *indp, int oc)
1422088Ssos{
1432088Ssos	if (*indp < ac)
1442088Ssos		return(av[(*indp)++]);
14529603Scharnier	warnx("option requires two arguments -- %c", oc);
1462088Ssos	usage();
1472088Ssos}
1482088Ssos
1492088Ssos
1502088Ssoschar *
1512088Ssosmkfullname(const char *s1, const char *s2, const char *s3)
1522088Ssos{
1535536Ssos	static char	*buf = NULL;
1545536Ssos	static int	bufl = 0;
1555536Ssos	int		f;
1562088Ssos
1572088Ssos	f = strlen(s1) + strlen(s2) + strlen(s3) + 1;
15877394Ssobomax	if (f > bufl) {
1592088Ssos		if (buf)
1602088Ssos			buf = (char *)realloc(buf, f);
1612088Ssos		else
1622088Ssos			buf = (char *)malloc(f);
16377394Ssobomax	}
1642088Ssos	if (!buf) {
1652088Ssos		bufl = 0;
1662088Ssos		return(NULL);
1672088Ssos	}
1682088Ssos
1692088Ssos	bufl = f;
1702088Ssos	strcpy(buf, s1);
1712088Ssos	strcat(buf, s2);
1722088Ssos	strcat(buf, s3);
1732088Ssos	return(buf);
1742088Ssos}
1752088Ssos
1762088Ssos
1772088Ssosint
17899816Salfredget_entry(void)
1792088Ssos{
18032316Syokota	switch ((token = yylex())) {
1812088Ssos	case TNOP:
1822088Ssos		return NOP | 0x100;
1832088Ssos	case TLSH:
1842088Ssos		return LSH | 0x100;
1852088Ssos	case TRSH:
1862088Ssos		return RSH | 0x100;
1872088Ssos	case TCLK:
1882088Ssos		return CLK | 0x100;
1892088Ssos	case TNLK:
1902088Ssos		return NLK | 0x100;
1912088Ssos	case TSLK:
1922088Ssos		return SLK | 0x100;
1932088Ssos	case TBTAB:
1942088Ssos		return BTAB | 0x100;
1952088Ssos	case TLALT:
1962088Ssos		return LALT | 0x100;
1972088Ssos	case TLCTR:
1982088Ssos		return LCTR | 0x100;
1992088Ssos	case TNEXT:
2002088Ssos		return NEXT | 0x100;
20148105Syokota	case TPREV:
20248105Syokota		return PREV | 0x100;
2032088Ssos	case TRCTR:
2042088Ssos		return RCTR | 0x100;
2052088Ssos	case TRALT:
2062088Ssos		return RALT | 0x100;
2072088Ssos	case TALK:
2082088Ssos		return ALK | 0x100;
2092088Ssos	case TASH:
2102088Ssos		return ASH | 0x100;
2112088Ssos	case TMETA:
2122088Ssos		return META | 0x100;
2132088Ssos	case TRBT:
2142088Ssos		return RBT | 0x100;
2152088Ssos	case TDBG:
2162088Ssos		return DBG | 0x100;
2175994Ssos	case TSUSP:
2185994Ssos		return SUSP | 0x100;
21938053Syokota	case TSPSC:
22038053Syokota		return SPSC | 0x100;
22154380Syokota	case TPANIC:
22254380Syokota		return PNC | 0x100;
22354380Syokota	case TLSHA:
22454380Syokota		return LSHA | 0x100;
22554380Syokota	case TRSHA:
22654380Syokota		return RSHA | 0x100;
22754380Syokota	case TLCTRA:
22854380Syokota		return LCTRA | 0x100;
22954380Syokota	case TRCTRA:
23054380Syokota		return RCTRA | 0x100;
23154380Syokota	case TLALTA:
23254380Syokota		return LALTA | 0x100;
23354380Syokota	case TRALTA:
23454380Syokota		return RALTA | 0x100;
23565759Sdwmalone	case THALT:
23665759Sdwmalone		return HALT | 0x100;
23765759Sdwmalone	case TPDWN:
23865759Sdwmalone		return PDWN | 0x100;
23974118Sache	case TPASTE:
24074118Sache		return PASTE | 0x100;
24132316Syokota	case TACC:
24232316Syokota		if (ACC(number) > L_ACC)
24332316Syokota			return -1;
24432316Syokota		return ACC(number) | 0x100;
2452088Ssos	case TFUNC:
2462088Ssos		if (F(number) > L_FN)
2472088Ssos			return -1;
2482088Ssos		return F(number) | 0x100;
2492088Ssos	case TSCRN:
2502088Ssos		if (S(number) > L_SCR)
2512088Ssos			return -1;
2522088Ssos		return S(number) | 0x100;
2532088Ssos	case TLET:
2542088Ssos		return (unsigned char)letter;
2552088Ssos	case TNUM:
2562088Ssos		if (number < 0 || number > 255)
2572088Ssos			return -1;
2582088Ssos		return number;
2592088Ssos	default:
2602088Ssos		return -1;
2612088Ssos	}
2622088Ssos}
2632088Ssos
26477394Ssobomaxstatic int
26532316Syokotaget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap)
2662088Ssos{
26732316Syokota	int c;
2682088Ssos
2692088Ssos	yyin = fd;
2702088Ssos
27132316Syokota	if (token < 0)
27232316Syokota		token = yylex();
27332316Syokota	switch (token) {
27432316Syokota	case TNUM:
27532316Syokota		c = get_key_definition_line(keymap);
27632316Syokota		if (c < 0)
27732316Syokota			errx(1, "invalid key definition");
27832316Syokota		if (c > keymap->n_keys)
27932316Syokota			keymap->n_keys = c;
28032316Syokota		break;
28132316Syokota	case TACC:
28232316Syokota		c = get_accent_definition_line(accentmap);
28332316Syokota		if (c < 0)
28432316Syokota			errx(1, "invalid accent key definition");
28532316Syokota		if (c > accentmap->n_accs)
28632316Syokota			accentmap->n_accs = c;
28732316Syokota		break;
28832316Syokota	case 0:
28932316Syokota		/* EOF */
2902088Ssos		return -1;
29132316Syokota	default:
29232316Syokota		errx(1, "illegal definition line");
29332316Syokota	}
29432316Syokota	return c;
29532316Syokota}
29632316Syokota
29732316Syokotaint
29832316Syokotaget_key_definition_line(keymap_t *map)
29932316Syokota{
30032316Syokota	int i, def, scancode;
30132316Syokota
30232316Syokota	/* check scancode number */
3032088Ssos	if (number < 0 || number >= NUM_KEYS)
3042088Ssos		return -1;
3052088Ssos	scancode = number;
3062088Ssos
3072088Ssos	/* get key definitions */
3082088Ssos	map->key[scancode].spcl = 0;
3092088Ssos	for (i=0; i<NUM_STATES; i++) {
3102088Ssos		if ((def = get_entry()) == -1)
3112088Ssos			return -1;
3122088Ssos		if (def & 0x100)
3132088Ssos			map->key[scancode].spcl |= (0x80 >> i);
3142088Ssos		map->key[scancode].map[i] = def & 0xFF;
3152088Ssos	}
3162088Ssos	/* get lock state key def */
31732316Syokota	if ((token = yylex()) != TFLAG)
3182088Ssos		return -1;
3192088Ssos	map->key[scancode].flgs = number;
32032316Syokota	token = yylex();
32132316Syokota	return (scancode + 1);
3222088Ssos}
3232088Ssos
32432316Syokotaint
32532316Syokotaget_accent_definition_line(accentmap_t *map)
32632316Syokota{
32732316Syokota	int accent;
32832316Syokota	int c1, c2;
32932316Syokota	int i;
3302088Ssos
33132316Syokota	if (ACC(number) < F_ACC || ACC(number) > L_ACC)
33232316Syokota		/* number out of range */
33332316Syokota		return -1;
33432316Syokota	accent = number;
33532316Syokota	if (map->acc[accent].accchar != 0) {
33632316Syokota		/* this entry has already been defined before! */
33732316Syokota		errx(1, "duplicated accent key definition");
33832316Syokota	}
33932316Syokota
34032316Syokota	switch ((token = yylex())) {
34132316Syokota	case TLET:
34232316Syokota		map->acc[accent].accchar = letter;
34332316Syokota		break;
34432316Syokota	case TNUM:
34532316Syokota		map->acc[accent].accchar = number;
34632316Syokota		break;
34732316Syokota	default:
34832316Syokota		return -1;
34932316Syokota	}
35032316Syokota
35132316Syokota	for (i = 0; (token = yylex()) == '(';) {
35232316Syokota		switch ((token = yylex())) {
35332316Syokota		case TLET:
35432316Syokota			c1 = letter;
35532316Syokota			break;
35632316Syokota		case TNUM:
35732316Syokota			c1 = number;
35832316Syokota			break;
35932316Syokota		default:
36032316Syokota			return -1;
36132316Syokota		}
36232316Syokota		switch ((token = yylex())) {
36332316Syokota		case TLET:
36432316Syokota			c2 = letter;
36532316Syokota			break;
36632316Syokota		case TNUM:
36732316Syokota			c2 = number;
36832316Syokota			break;
36932316Syokota		default:
37032316Syokota			return -1;
37132316Syokota		}
37232316Syokota		if ((token = yylex()) != ')')
37332316Syokota			return -1;
37432316Syokota		if (i >= NUM_ACCENTCHARS) {
37532316Syokota			warnx("too many accented characters, ignored");
37632316Syokota			continue;
37732316Syokota		}
37832316Syokota		map->acc[accent].map[i][0] = c1;
37932316Syokota		map->acc[accent].map[i][1] = c2;
38032316Syokota		++i;
38132316Syokota	}
38232316Syokota	return (accent + 1);
38332316Syokota}
38432316Syokota
38529603Scharniervoid
3862088Ssosprint_entry(FILE *fp, int value)
3872088Ssos{
3882088Ssos	int val = value & 0xFF;
3892088Ssos
3902088Ssos	switch (value) {
3912088Ssos	case NOP | 0x100:
3928857Srgrimes		fprintf(fp, " nop   ");
3932088Ssos		break;
3942088Ssos	case LSH | 0x100:
3952088Ssos		fprintf(fp, " lshift");
3962088Ssos		break;
3972088Ssos	case RSH | 0x100:
3982088Ssos		fprintf(fp, " rshift");
3992088Ssos		break;
4002088Ssos	case CLK | 0x100:
4012088Ssos		fprintf(fp, " clock ");
4022088Ssos		break;
4032088Ssos	case NLK | 0x100:
4042088Ssos		fprintf(fp, " nlock ");
4052088Ssos		break;
4062088Ssos	case SLK | 0x100:
4072088Ssos		fprintf(fp, " slock ");
4082088Ssos		break;
4092088Ssos	case BTAB | 0x100:
4102088Ssos		fprintf(fp, " btab  ");
4112088Ssos		break;
4122088Ssos	case LALT | 0x100:
4132088Ssos		fprintf(fp, " lalt  ");
4142088Ssos		break;
4152088Ssos	case LCTR | 0x100:
4162088Ssos		fprintf(fp, " lctrl ");
4172088Ssos		break;
4182088Ssos	case NEXT | 0x100:
4192088Ssos		fprintf(fp, " nscr  ");
4202088Ssos		break;
42148105Syokota	case PREV | 0x100:
42248105Syokota		fprintf(fp, " pscr  ");
42348105Syokota		break;
4242088Ssos	case RCTR | 0x100:
4252088Ssos		fprintf(fp, " rctrl ");
4262088Ssos		break;
4272088Ssos	case RALT | 0x100:
4282088Ssos		fprintf(fp, " ralt  ");
4292088Ssos		break;
4302088Ssos	case ALK | 0x100:
4312088Ssos		fprintf(fp, " alock ");
4322088Ssos		break;
4332088Ssos	case ASH | 0x100:
4342088Ssos		fprintf(fp, " ashift");
4352088Ssos		break;
4362088Ssos	case META | 0x100:
4372088Ssos		fprintf(fp, " meta  ");
4382088Ssos		break;
4392088Ssos	case RBT | 0x100:
4402088Ssos		fprintf(fp, " boot  ");
4412088Ssos		break;
4422088Ssos	case DBG | 0x100:
4432088Ssos		fprintf(fp, " debug ");
4442088Ssos		break;
44532316Syokota	case SUSP | 0x100:
44632316Syokota		fprintf(fp, " susp  ");
44732316Syokota		break;
44838053Syokota	case SPSC | 0x100:
44938053Syokota		fprintf(fp, " saver ");
45038053Syokota		break;
45154380Syokota	case PNC | 0x100:
45254380Syokota		fprintf(fp, " panic ");
45354380Syokota		break;
45454380Syokota	case LSHA | 0x100:
45554380Syokota		fprintf(fp, " lshifta");
45654380Syokota		break;
45754380Syokota	case RSHA | 0x100:
45854380Syokota		fprintf(fp, " rshifta");
45954380Syokota		break;
46054380Syokota	case LCTRA | 0x100:
46154380Syokota		fprintf(fp, " lctrla");
46254380Syokota		break;
46354380Syokota	case RCTRA | 0x100:
46454380Syokota		fprintf(fp, " rctrla");
46554380Syokota		break;
46654380Syokota	case LALTA | 0x100:
46754380Syokota		fprintf(fp, " lalta ");
46854380Syokota		break;
46954380Syokota	case RALTA | 0x100:
47054380Syokota		fprintf(fp, " ralta ");
47154380Syokota		break;
47265759Sdwmalone	case HALT | 0x100:
47365759Sdwmalone		fprintf(fp, " halt  ");
47465759Sdwmalone		break;
47565759Sdwmalone	case PDWN | 0x100:
47665759Sdwmalone		fprintf(fp, " pdwn  ");
47765759Sdwmalone		break;
47874118Sache	case PASTE | 0x100:
47974118Sache		fprintf(fp, " paste ");
48074118Sache		break;
4812088Ssos	default:
4822088Ssos		if (value & 0x100) {
4838857Srgrimes		 	if (val >= F_FN && val <= L_FN)
4842088Ssos				fprintf(fp, " fkey%02d", val - F_FN + 1);
4858857Srgrimes		 	else if (val >= F_SCR && val <= L_SCR)
4862088Ssos				fprintf(fp, " scr%02d ", val - F_SCR + 1);
48732316Syokota		 	else if (val >= F_ACC && val <= L_ACC)
48832316Syokota				fprintf(fp, " %-6s", acc_names[val - F_ACC]);
4892088Ssos			else if (hex)
4908857Srgrimes				fprintf(fp, " 0x%02x  ", val);
4912088Ssos			else
49232316Syokota				fprintf(fp, " %3d   ", val);
4932088Ssos		}
4942088Ssos		else {
4952088Ssos			if (val < ' ')
4968857Srgrimes				fprintf(fp, " %s   ", ctrl_names[val]);
4972088Ssos			else if (val == 127)
4988857Srgrimes				fprintf(fp, " del   ");
4999202Srgrimes			else if (isascii(val) && isprint(val))
5008857Srgrimes				fprintf(fp, " '%c'   ", val);
5012088Ssos			else if (hex)
5028857Srgrimes				fprintf(fp, " 0x%02x  ", val);
5032088Ssos			else
5048857Srgrimes				fprintf(fp, " %3d   ", val);
5052088Ssos		}
5062088Ssos	}
5072088Ssos}
5082088Ssos
5092088Ssosvoid
51042505Syokotaprint_key_definition_line(FILE *fp, int scancode, struct keyent_t *key)
5112088Ssos{
51229603Scharnier	int i;
5132088Ssos
5142088Ssos	/* print scancode number */
5152088Ssos	if (hex)
5162088Ssos		fprintf(fp, " 0x%02x  ", scancode);
5172088Ssos	else
5182088Ssos		fprintf(fp, "  %03d  ", scancode);
5192088Ssos
5202088Ssos	/* print key definitions */
5212088Ssos	for (i=0; i<NUM_STATES; i++) {
5222088Ssos		if (key->spcl & (0x80 >> i))
5232088Ssos			print_entry(fp, key->map[i] | 0x100);
5242088Ssos		else
5258857Srgrimes			print_entry(fp, key->map[i]);
5262088Ssos	}
5272088Ssos
5282088Ssos	/* print lock state key def */
5292088Ssos	switch (key->flgs) {
5302088Ssos	case 0:
5312088Ssos		fprintf(fp, "  O\n");
5322088Ssos		break;
5332088Ssos	case 1:
5342088Ssos		fprintf(fp, "  C\n");
5352088Ssos		break;
5362088Ssos	case 2:
5372088Ssos		fprintf(fp, "  N\n");
5382088Ssos		break;
5396046Ssos	case 3:
5406046Ssos		fprintf(fp, "  B\n");
5416046Ssos		break;
5428857Srgrimes	}
5432088Ssos}
5442088Ssos
54532316Syokotavoid
54632316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key)
54732316Syokota{
54832316Syokota	int c;
54932316Syokota	int i;
5502088Ssos
55132316Syokota	if (key->accchar == 0)
55232316Syokota		return;
55332316Syokota
55432316Syokota	/* print accent number */
55532316Syokota	fprintf(fp, "  %-6s", acc_names[accent]);
55632316Syokota	if (isascii(key->accchar) && isprint(key->accchar))
55732316Syokota		fprintf(fp, "'%c'  ", key->accchar);
55832316Syokota	else if (hex)
55932316Syokota		fprintf(fp, "0x%02x ", key->accchar);
56032316Syokota	else
56132316Syokota		fprintf(fp, "%03d  ", key->accchar);
56232316Syokota
56332316Syokota	for (i = 0; i < NUM_ACCENTCHARS; ++i) {
56432316Syokota		c = key->map[i][0];
56532316Syokota		if (c == 0)
56632316Syokota			break;
56732316Syokota		if ((i > 0) && ((i % 4) == 0))
56832316Syokota			fprintf(fp, "\n             ");
56932316Syokota		if (isascii(c) && isprint(c))
57032316Syokota			fprintf(fp, "( '%c' ", c);
57132316Syokota		else if (hex)
57232316Syokota			fprintf(fp, "(0x%02x ", c);
57332316Syokota		else
57432316Syokota			fprintf(fp, "( %03d ", c);
57532316Syokota		c = key->map[i][1];
57632316Syokota		if (isascii(c) && isprint(c))
57732316Syokota			fprintf(fp, "'%c' ) ", c);
57832316Syokota		else if (hex)
57932316Syokota			fprintf(fp, "0x%02x) ", c);
58032316Syokota		else
58132316Syokota			fprintf(fp, "%03d ) ", c);
58232316Syokota	}
58332316Syokota	fprintf(fp, "\n");
58432316Syokota}
58532316Syokota
5862088Ssosvoid
58732316Syokotadump_entry(int value)
58832316Syokota{
58932316Syokota	if (value & 0x100) {
59032316Syokota		value &= 0x00ff;
59132316Syokota		switch (value) {
59232316Syokota		case NOP:
59332316Syokota			printf("  NOP, ");
59432316Syokota			break;
59532316Syokota		case LSH:
59632316Syokota			printf("  LSH, ");
59732316Syokota			break;
59832316Syokota		case RSH:
59932316Syokota			printf("  RSH, ");
60032316Syokota			break;
60132316Syokota		case CLK:
60232316Syokota			printf("  CLK, ");
60332316Syokota			break;
60432316Syokota		case NLK:
60532316Syokota			printf("  NLK, ");
60632316Syokota			break;
60732316Syokota		case SLK:
60832316Syokota			printf("  SLK, ");
60932316Syokota			break;
61032316Syokota		case BTAB:
61132316Syokota			printf(" BTAB, ");
61232316Syokota			break;
61332316Syokota		case LALT:
61432316Syokota			printf(" LALT, ");
61532316Syokota			break;
61632316Syokota		case LCTR:
61732316Syokota			printf(" LCTR, ");
61832316Syokota			break;
61932316Syokota		case NEXT:
62032316Syokota			printf(" NEXT, ");
62132316Syokota			break;
62248105Syokota		case PREV:
62348105Syokota			printf(" PREV, ");
62448105Syokota			break;
62532316Syokota		case RCTR:
62632316Syokota			printf(" RCTR, ");
62732316Syokota			break;
62832316Syokota		case RALT:
62932316Syokota			printf(" RALT, ");
63032316Syokota			break;
63132316Syokota		case ALK:
63232316Syokota			printf("  ALK, ");
63332316Syokota			break;
63432316Syokota		case ASH:
63532316Syokota			printf("  ASH, ");
63632316Syokota			break;
63732316Syokota		case META:
63832316Syokota			printf(" META, ");
63932316Syokota			break;
64032316Syokota		case RBT:
64132316Syokota			printf("  RBT, ");
64232316Syokota			break;
64332316Syokota		case DBG:
64432316Syokota			printf("  DBG, ");
64532316Syokota			break;
64632316Syokota		case SUSP:
64732316Syokota			printf(" SUSP, ");
64832316Syokota			break;
64938053Syokota		case SPSC:
65038053Syokota			printf(" SPSC, ");
65138053Syokota			break;
65254380Syokota		case PNC:
65354380Syokota			printf("  PNC, ");
65454380Syokota			break;
65554380Syokota		case LSHA:
65654380Syokota			printf(" LSHA, ");
65754380Syokota			break;
65854380Syokota		case RSHA:
65954380Syokota			printf(" RSHA, ");
66054380Syokota			break;
66154380Syokota		case LCTRA:
66254380Syokota			printf("LCTRA, ");
66354380Syokota			break;
66454380Syokota		case RCTRA:
66554380Syokota			printf("RCTRA, ");
66654380Syokota			break;
66754380Syokota		case LALTA:
66854380Syokota			printf("LALTA, ");
66954380Syokota			break;
67054380Syokota		case RALTA:
67154380Syokota			printf("RALTA, ");
67254380Syokota			break;
67365759Sdwmalone		case HALT:
67465759Sdwmalone			printf(" HALT, ");
67565759Sdwmalone			break;
67665759Sdwmalone		case PDWN:
67765759Sdwmalone			printf(" PDWN, ");
67865759Sdwmalone			break;
67974118Sache		case PASTE:
68074118Sache			printf("PASTE, ");
68174118Sache			break;
68232316Syokota		default:
68332316Syokota	 		if (value >= F_FN && value <= L_FN)
68432316Syokota				printf(" F(%2d),", value - F_FN + 1);
68532316Syokota	 		else if (value >= F_SCR && value <= L_SCR)
68632486Syokota				printf(" S(%2d),", value - F_SCR + 1);
68732316Syokota	 		else if (value >= F_ACC && value <= L_ACC)
68832316Syokota				printf(" %-4s, ", acc_names_u[value - F_ACC]);
68932316Syokota			else
69032316Syokota				printf(" 0x%02X, ", value);
69132316Syokota			break;
69232316Syokota		}
69332316Syokota	} else if (value == '\'') {
69432316Syokota		printf(" '\\'', ");
69532316Syokota	} else if (value == '\\') {
69632316Syokota		printf(" '\\\\', ");
69732316Syokota	} else if (isascii(value) && isprint(value)) {
69832316Syokota		printf("  '%c', ", value);
69932316Syokota	} else {
70032316Syokota		printf(" 0x%02X, ", value);
70132316Syokota	}
70232316Syokota}
70332316Syokota
70432316Syokotavoid
70532316Syokotadump_key_definition(char *name, keymap_t *keymap)
70632316Syokota{
70732316Syokota	int	i, j;
70832316Syokota
70932486Syokota	printf("static keymap_t keymap_%s = { 0x%02x, {\n",
71032316Syokota	       name, (unsigned)keymap->n_keys);
71132316Syokota	printf(
71232486Syokota"/*                                                         alt\n"
71332486Syokota" * scan                       cntrl          alt    alt   cntrl\n"
71432486Syokota" * code  base   shift  cntrl  shift   alt   shift  cntrl  shift    spcl flgs\n"
71532316Syokota" * ---------------------------------------------------------------------------\n"
71632316Syokota" */\n");
71732316Syokota	for (i = 0; i < keymap->n_keys; i++) {
71832486Syokota		printf("/*%02x*/{{", i);
71932316Syokota		for (j = 0; j < NUM_STATES; j++) {
72032316Syokota			if (keymap->key[i].spcl & (0x80 >> j))
72132316Syokota				dump_entry(keymap->key[i].map[j] | 0x100);
72232316Syokota			else
72332316Syokota				dump_entry(keymap->key[i].map[j]);
72432316Syokota		}
72532486Syokota		printf("}, 0x%02X,0x%02X },\n",
72632316Syokota		       (unsigned)keymap->key[i].spcl,
72732316Syokota		       (unsigned)keymap->key[i].flgs);
72832316Syokota	}
72932486Syokota	printf("} };\n\n");
73032316Syokota}
73132316Syokota
73232316Syokotavoid
73332316Syokotadump_accent_definition(char *name, accentmap_t *accentmap)
73432316Syokota{
73532316Syokota	int i, j;
73632316Syokota	int c;
73732316Syokota
73832486Syokota	printf("static accentmap_t accentmap_%s = { %d",
73932316Syokota		name, accentmap->n_accs);
74032486Syokota	if (accentmap->n_accs <= 0) {
74132486Syokota		printf(" };\n\n");
74232486Syokota		return;
74332486Syokota	}
74432486Syokota	printf(", {\n");
74532316Syokota	for (i = 0; i < NUM_DEADKEYS; i++) {
74632316Syokota		printf("    /* %s=%d */\n    {", acc_names[i], i);
74732316Syokota		c = accentmap->acc[i].accchar;
74832316Syokota		if (c == '\'')
74932316Syokota			printf(" '\\'', {");
75032316Syokota		else if (c == '\\')
75132316Syokota			printf(" '\\\\', {");
75232316Syokota		else if (isascii(c) && isprint(c))
75332316Syokota			printf("  '%c', {", c);
75432316Syokota		else if (c == 0) {
75532316Syokota			printf(" 0x00 }, \n");
75632316Syokota			continue;
75732316Syokota		} else
75832316Syokota			printf(" 0x%02x, {", c);
75932316Syokota		for (j = 0; j < NUM_ACCENTCHARS; j++) {
76032316Syokota			c = accentmap->acc[i].map[j][0];
76132316Syokota			if (c == 0)
76232316Syokota				break;
76332316Syokota			if ((j > 0) && ((j % 4) == 0))
76432316Syokota				printf("\n\t     ");
76532316Syokota			if (isascii(c) && isprint(c))
76632316Syokota				printf(" {  '%c',", c);
76732316Syokota			else
76832316Syokota				printf(" { 0x%02x,", c);
76932316Syokota			printf("0x%02x },", accentmap->acc[i].map[j][1]);
77032316Syokota		}
77132316Syokota		printf(" }, },\n");
77232316Syokota	}
77332486Syokota	printf("} };\n\n");
77432316Syokota}
77532316Syokota
77632316Syokotavoid
77719569Sjoergload_keymap(char *opt, int dumponly)
7782088Ssos{
77932316Syokota	keymap_t keymap;
78032316Syokota	accentmap_t accentmap;
7812088Ssos	FILE	*fd;
78276502Ssobomax	int	i, j;
78319569Sjoerg	char	*name, *cp;
78499816Salfred	char	blank[] = "", keymap_path[] = KEYMAP_PATH, dotkbd[] = ".kbd";
78599816Salfred	char	*prefix[]  = {blank, blank, keymap_path, NULL};
78699816Salfred	char	*postfix[] = {blank, dotkbd, NULL};
7872088Ssos
78876569Ssobomax	cp = getenv("KEYMAP_PATH");
78976569Ssobomax	if (cp != NULL)
79076569Ssobomax		asprintf(&(prefix[0]), "%s/", cp);
79176502Ssobomax
79276643Simp	fd = NULL;
79376643Simp	for (i=0; prefix[i] && fd == NULL; i++) {
79476643Simp		for (j=0; postfix[j] && fd == NULL; j++) {
79576502Ssobomax			name = mkfullname(prefix[i], opt, postfix[j]);
79676643Simp			fd = fopen(name, "r");
79776502Ssobomax		}
79876643Simp	}
7992088Ssos	if (fd == NULL) {
80079677Sobrien		warn("keymap file \"%s\" not found", opt);
8012088Ssos		return;
8022088Ssos	}
80332316Syokota	memset(&keymap, 0, sizeof(keymap));
80432316Syokota	memset(&accentmap, 0, sizeof(accentmap));
80532316Syokota	token = -1;
8062088Ssos	while (1) {
80732316Syokota		if (get_definition_line(fd, &keymap, &accentmap) < 0)
8082088Ssos			break;
8092088Ssos    	}
81019569Sjoerg	if (dumponly) {
81119569Sjoerg		/* fix up the filename to make it a valid C identifier */
81219569Sjoerg		for (cp = opt; *cp; cp++)
81319569Sjoerg			if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_';
81432316Syokota		printf("/*\n"
81532316Syokota		       " * Automatically generated from %s.\n"
81632316Syokota	               " * DO NOT EDIT!\n"
81732316Syokota		       " */\n", name);
81832316Syokota		dump_key_definition(opt, &keymap);
81932316Syokota		dump_accent_definition(opt, &accentmap);
82019569Sjoerg		return;
82119569Sjoerg	}
82232316Syokota	if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) {
82329603Scharnier		warn("setting keymap");
8242088Ssos		fclose(fd);
8252088Ssos		return;
8262088Ssos	}
82732316Syokota	if ((accentmap.n_accs > 0)
82832316Syokota		&& (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) {
82932316Syokota		warn("setting accentmap");
83032316Syokota		fclose(fd);
83132316Syokota		return;
83232316Syokota	}
8332088Ssos}
8342088Ssos
8352088Ssosvoid
83699816Salfredprint_keymap(void)
8372088Ssos{
83832316Syokota	keymap_t keymap;
83932316Syokota	accentmap_t accentmap;
8402088Ssos	int i;
8412088Ssos
84232316Syokota	if (ioctl(0, GIO_KEYMAP, &keymap) < 0)
84329603Scharnier		err(1, "getting keymap");
84432316Syokota	if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0)
84532316Syokota		memset(&accentmap, 0, sizeof(accentmap));
8462088Ssos    	printf(
8472088Ssos"#                                                         alt\n"
8482088Ssos"# scan                       cntrl          alt    alt   cntrl lock\n"
8492088Ssos"# code  base   shift  cntrl  shift  alt    shift  cntrl  shift state\n"
8502088Ssos"# ------------------------------------------------------------------\n"
8512088Ssos    	);
85232316Syokota	for (i=0; i<keymap.n_keys; i++)
85332316Syokota		print_key_definition_line(stdout, i, &keymap.key[i]);
85432316Syokota
85532316Syokota	printf("\n");
85632316Syokota	for (i = 0; i < NUM_DEADKEYS; i++)
85732316Syokota		print_accent_definition_line(stdout, i, &accentmap.acc[i]);
85832316Syokota
8592088Ssos}
8602088Ssos
8612088Ssosvoid
86299816Salfredload_default_functionkeys(void)
8632088Ssos{
8642088Ssos	fkeyarg_t fkey;
8652088Ssos	int i;
8662088Ssos
8672088Ssos	for (i=0; i<NUM_FKEYS; i++) {
8682088Ssos		fkey.keynum = i;
8692088Ssos		strcpy(fkey.keydef, fkey_table[i]);
8702088Ssos		fkey.flen = strlen(fkey_table[i]);
8712088Ssos		if (ioctl(0, SETFKEY, &fkey) < 0)
87229603Scharnier			warn("setting function key");
8732088Ssos	}
8742088Ssos}
8752088Ssos
8762088Ssosvoid
8772088Ssosset_functionkey(char *keynumstr, char *string)
8782088Ssos{
8792088Ssos	fkeyarg_t fkey;
8802088Ssos
8812088Ssos	if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) {
8822088Ssos		load_default_functionkeys();
8832088Ssos		return;
8842088Ssos	}
8852088Ssos	fkey.keynum = atoi(keynumstr);
8862088Ssos	if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) {
88729603Scharnier		warnx("function key number must be between 1 and %d",
8882088Ssos			NUM_FKEYS);
8892088Ssos		return;
8902088Ssos	}
8912088Ssos	if ((fkey.flen = strlen(string)) > MAXFK) {
89229603Scharnier		warnx("function key string too long (%d > %d)",
8932088Ssos			fkey.flen, MAXFK);
8942088Ssos		return;
8952088Ssos	}
896133353Sjmg	strncpy(fkey.keydef, string, MAXFK);
8972088Ssos	fkey.keynum -= 1;
8982088Ssos	if (ioctl(0, SETFKEY, &fkey) < 0)
89929603Scharnier		warn("setting function key");
9002088Ssos}
9012088Ssos
9022088Ssosvoid
9032088Ssosset_bell_values(char *opt)
9042088Ssos{
9055536Ssos	int bell, duration, pitch;
9062088Ssos
90738044Syokota	bell = 0;
90838044Syokota	if (!strncmp(opt, "quiet.", 6)) {
90938044Syokota		bell = 2;
91038044Syokota		opt += 6;
91138044Syokota	}
9128857Srgrimes	if (!strcmp(opt, "visual"))
91338044Syokota		bell |= 1;
9145536Ssos	else if (!strcmp(opt, "normal"))
91538044Syokota		duration = 5, pitch = 800;
91648982Syokota	else if (!strcmp(opt, "off"))
91748982Syokota		duration = 0, pitch = 0;
9182088Ssos	else {
9192088Ssos		char		*v1;
9208857Srgrimes
9215536Ssos		bell = 0;
9222088Ssos		duration = strtol(opt, &v1, 0);
9232088Ssos		if ((duration < 0) || (*v1 != '.'))
9242088Ssos			goto badopt;
9252088Ssos		opt = ++v1;
9262088Ssos		pitch = strtol(opt, &v1, 0);
9272088Ssos		if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) {
9282088Ssosbadopt:
92977394Ssobomax			warnx("argument to -b must be duration.pitch or [quiet.]visual|normal|off");
9302088Ssos			return;
9312088Ssos		}
93238044Syokota		if (pitch != 0)
93338044Syokota			pitch = 1193182 / pitch;	/* in Hz */
93438044Syokota		duration /= 10;	/* in 10 m sec */
9352088Ssos	}
9362088Ssos
9375536Ssos	ioctl(0, CONS_BELLTYPE, &bell);
93838044Syokota	if ((bell & ~2) == 0)
9395536Ssos		fprintf(stderr, "[=%d;%dB", pitch, duration);
9402088Ssos}
9412088Ssos
9422088Ssosvoid
9432088Ssosset_keyrates(char *opt)
9442088Ssos{
94544628Syokota	int arg[2];
94639047Syokota	int repeat;
94739047Syokota	int delay;
94846761Syokota	int r, d;
9492088Ssos
95046761Syokota	if (!strcmp(opt, "slow")) {
95144628Syokota		delay = 1000, repeat = 500;
95246761Syokota		d = 3, r = 31;
95346761Syokota	} else if (!strcmp(opt, "normal")) {
95444628Syokota		delay = 500, repeat = 125;
95546761Syokota		d = 1, r = 15;
95646761Syokota	} else if (!strcmp(opt, "fast")) {
95739047Syokota		delay = repeat = 0;
95846761Syokota		d = r = 0;
95946761Syokota	} else {
9602088Ssos		int		n;
9612088Ssos		char		*v1;
9622088Ssos
9632088Ssos		delay = strtol(opt, &v1, 0);
9642088Ssos		if ((delay < 0) || (*v1 != '.'))
9652088Ssos			goto badopt;
9662088Ssos		opt = ++v1;
9672088Ssos		repeat = strtol(opt, &v1, 0);
9682088Ssos		if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) {
9692088Ssosbadopt:
97077394Ssobomax			warnx("argument to -r must be delay.repeat or slow|normal|fast");
9712088Ssos			return;
9722088Ssos		}
97346761Syokota		for (n = 0; n < ndelays - 1; n++)
97446761Syokota			if (delay <= delays[n])
97546761Syokota				break;
97646761Syokota		d = n;
97746761Syokota		for (n = 0; n < nrepeats - 1; n++)
97846761Syokota			if (repeat <= repeats[n])
97946761Syokota				break;
98046761Syokota		r = n;
9812088Ssos	}
9822088Ssos
98344628Syokota	arg[0] = delay;
98444628Syokota	arg[1] = repeat;
98546761Syokota	if (ioctl(0, KDSETREPEAT, arg)) {
98646761Syokota		if (ioctl(0, KDSETRAD, (d << 5) | r))
98746761Syokota			warn("setting keyboard rate");
98846761Syokota	}
9892088Ssos}
9902088Ssos
99199816Salfredstatic const char *
99299816Salfredget_kbd_type_name(int type)
99342505Syokota{
99442505Syokota	static struct {
99542505Syokota		int type;
99699816Salfred		const char *name;
99742505Syokota	} name_table[] = {
99842505Syokota		{ KB_84,	"AT 84" },
99942505Syokota		{ KB_101,	"AT 101/102" },
100042505Syokota		{ KB_OTHER,	"generic" },
100142505Syokota	};
100299816Salfred	unsigned int i;
10036046Ssos
100442505Syokota	for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) {
100542505Syokota		if (type == name_table[i].type)
100642505Syokota			return name_table[i].name;
100742505Syokota	}
100842505Syokota	return "unknown";
100942505Syokota}
101042505Syokota
101142505Syokotavoid
101242505Syokotashow_kbd_info(void)
101342505Syokota{
101442505Syokota	keyboard_info_t info;
101542505Syokota
101642505Syokota	if (ioctl(0, KDGKBINFO, &info) == -1) {
101742505Syokota		warn("unable to obtain keyboard information");
101842505Syokota		return;
101942505Syokota	}
102042505Syokota	printf("kbd%d:\n", info.kb_index);
102142505Syokota	printf("    %.*s%d, type:%s (%d)\n",
102277394Ssobomax		(int)sizeof(info.kb_name), info.kb_name, info.kb_unit,
102342505Syokota		get_kbd_type_name(info.kb_type), info.kb_type);
102442505Syokota}
102542505Syokota
102642505Syokotavoid
102742505Syokotaset_keyboard(char *device)
102842505Syokota{
102942505Syokota	keyboard_info_t info;
103042505Syokota	int fd;
103142505Syokota
103242505Syokota	fd = open(device, O_RDONLY);
103342505Syokota	if (fd < 0) {
103442505Syokota		warn("cannot open %s", device);
103542505Syokota		return;
103642505Syokota	}
103742505Syokota	if (ioctl(fd, KDGKBINFO, &info) == -1) {
103842505Syokota		warn("unable to obtain keyboard information");
103942505Syokota		close(fd);
104042505Syokota		return;
104142505Syokota	}
104242505Syokota	/*
104342505Syokota	 * The keyboard device driver won't release the keyboard by
104442505Syokota	 * the following ioctl, but it automatically will, when the device
104542505Syokota	 * is closed.  So, we don't check error here.
104642505Syokota	 */
104742505Syokota	ioctl(fd, CONS_RELKBD, 0);
104842505Syokota	close(fd);
104942505Syokota#if 1
105042505Syokota	printf("kbd%d\n", info.kb_index);
105142505Syokota	printf("    %.*s%d, type:%s (%d)\n",
105277394Ssobomax		(int)sizeof(info.kb_name), info.kb_name, info.kb_unit,
105342505Syokota		get_kbd_type_name(info.kb_type), info.kb_type);
105442505Syokota#endif
105542505Syokota
105642505Syokota	if (ioctl(0, CONS_SETKBD, info.kb_index) == -1)
105742505Syokota		warn("unable to set keyboard");
105842505Syokota}
105942505Syokota
106042505Syokotavoid
106142505Syokotarelease_keyboard(void)
106242505Syokota{
106342505Syokota	keyboard_info_t info;
106442505Syokota
106542505Syokota	/*
106642505Syokota	 * If stdin is not associated with a keyboard, the following ioctl
106742505Syokota	 * will fail.
106842505Syokota	 */
106942505Syokota	if (ioctl(0, KDGKBINFO, &info) == -1) {
107042505Syokota		warn("unable to obtain keyboard information");
107142505Syokota		return;
107242505Syokota	}
107342505Syokota#if 1
107442505Syokota	printf("kbd%d\n", info.kb_index);
107542505Syokota	printf("    %.*s%d, type:%s (%d)\n",
107677394Ssobomax		(int)sizeof(info.kb_name), info.kb_name, info.kb_unit,
107742505Syokota		get_kbd_type_name(info.kb_type), info.kb_type);
107842505Syokota#endif
107942505Syokota	if (ioctl(0, CONS_RELKBD, 0) == -1)
108042505Syokota		warn("unable to release the keyboard");
108142505Syokota}
108242505Syokota
108342505Syokota
108477394Ssobomaxvoid
10852088Ssosusage()
10862088Ssos{
108729603Scharnier	fprintf(stderr, "%s\n%s\n%s\n",
108877329Sdes"usage: kbdcontrol [-dFKix] [-b duration.pitch | [quiet.]belltype]",
108929603Scharnier"                  [-r delay.repeat | speed] [-l mapfile] [-f # string]",
109077329Sdes"                  [-k device] [-L mapfile]");
109129603Scharnier	exit(1);
10922088Ssos}
10932088Ssos
10942088Ssos
109551287Speterint
10962088Ssosmain(int argc, char **argv)
10972088Ssos{
10982088Ssos	int		opt;
10992088Ssos
110077329Sdes	while((opt = getopt(argc, argv, "b:df:iKk:Fl:L:r:x")) != -1)
11012088Ssos		switch(opt) {
110277329Sdes		case 'b':
110377329Sdes			set_bell_values(optarg);
110477329Sdes			break;
110577329Sdes		case 'd':
110677329Sdes			print_keymap();
110777329Sdes			break;
110877329Sdes		case 'l':
110977329Sdes			load_keymap(optarg, 0);
111077329Sdes			break;
111177329Sdes		case 'L':
111277329Sdes			load_keymap(optarg, 1);
111377329Sdes			break;
111477329Sdes		case 'f':
111577329Sdes			set_functionkey(optarg,
111677329Sdes			    nextarg(argc, argv, &optind, 'f'));
111777329Sdes			break;
111877329Sdes		case 'F':
111977329Sdes			load_default_functionkeys();
112077329Sdes			break;
112177329Sdes		case 'i':
112277329Sdes			show_kbd_info();
112377329Sdes			break;
112477329Sdes		case 'K':
112577329Sdes			release_keyboard();
112677329Sdes			break;
112777329Sdes		case 'k':
112877329Sdes			set_keyboard(optarg);
112977329Sdes			break;
113077329Sdes		case 'r':
113177329Sdes			set_keyrates(optarg);
113277329Sdes			break;
113377329Sdes		case 'x':
113477329Sdes			hex = 1;
113577329Sdes			break;
113677329Sdes		default:
113777329Sdes			usage();
11382088Ssos		}
113929603Scharnier	if ((optind != argc) || (argc == 1))
11402088Ssos		usage();
11412088Ssos	exit(0);
11422088Ssos}
1143