kbdcontrol.c revision 99816
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
2929603Scharnier#ifndef lint
3029603Scharnierstatic const char rcsid[] =
3150479Speter  "$FreeBSD: head/usr.sbin/kbdcontrol/kbdcontrol.c 99816 2002-07-11 21:12:18Z alfred $";
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>
4166834Sphk#include <sys/kbio.h>
4266834Sphk#include <sys/consio.h>
432088Ssos#include "path.h"
442088Ssos#include "lex.h"
452088Ssos
4676643Simp/*
4790394Sru * HALT, PDWN, and PASTE aren't defined in 4.x, but we need them to bridge
4890394Sru * to 5.0-current so define them here as a stop gap transition measure.
4976643Simp */
5090394Sru#ifndef	HALT
5190394Sru#define	HALT		0xa1		/* halt machine */
5290394Sru#endif
5390394Sru#ifndef PDWN
5490394Sru#define	PDWN		0xa2		/* halt machine and power down */
5590394Sru#endif
5676643Simp#ifndef PASTE
5776643Simp#define PASTE		0xa3		/* paste from cut-paste buffer */
5876643Simp#endif
5976643Simp
602088Ssoschar ctrl_names[32][4] = {
618857Srgrimes	"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
622088Ssos	"bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ",
632088Ssos	"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
6438139Syokota	"can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "us "
652088Ssos	};
662088Ssos
6732316Syokotachar acc_names[15][5] = {
6832316Syokota	"dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot",
6932316Syokota	"duml", "dsla", "drin", "dced", "dapo", "ddac", "dogo",
7032316Syokota	"dcar",
7132316Syokota	};
7232316Syokota
7332316Syokotachar acc_names_u[15][5] = {
7432316Syokota	"DGRA", "DACU", "DCIR", "DTIL", "DMAC", "DBRE", "DDOT",
7532316Syokota	"DUML", "DSLA", "DRIN", "DCED", "DAPO", "DDAC", "DOGO",
7632316Syokota	"DCAR",
7732316Syokota	};
7832316Syokota
795994Ssoschar fkey_table[96][MAXFK] = {
805994Ssos/* 01-04 */	"\033[M", "\033[N", "\033[O", "\033[P",
815994Ssos/* 05-08 */	"\033[Q", "\033[R", "\033[S", "\033[T",
825994Ssos/* 09-12 */	"\033[U", "\033[V", "\033[W", "\033[X",
835994Ssos/* 13-16 */	"\033[Y", "\033[Z", "\033[a", "\033[b",
845994Ssos/* 17-20 */	"\033[c", "\033[d", "\033[e", "\033[f",
855994Ssos/* 21-24 */	"\033[g", "\033[h", "\033[i", "\033[j",
865994Ssos/* 25-28 */	"\033[k", "\033[l", "\033[m", "\033[n",
875994Ssos/* 29-32 */	"\033[o", "\033[p", "\033[q", "\033[r",
885994Ssos/* 33-36 */	"\033[s", "\033[t", "\033[u", "\033[v",
895994Ssos/* 37-40 */	"\033[w", "\033[x", "\033[y", "\033[z",
905994Ssos/* 41-44 */	"\033[@", "\033[[", "\033[\\","\033[]",
919202Srgrimes/* 45-48 */     "\033[^", "\033[_", "\033[`", "\033[{",
925994Ssos/* 49-52 */	"\033[H", "\033[A", "\033[I", "-"     ,
935994Ssos/* 53-56 */	"\033[D", "\033[E", "\033[C", "+"     ,
945994Ssos/* 57-60 */	"\033[F", "\033[B", "\033[G", "\033[L",
959202Srgrimes/* 61-64 */     "\177",   "\033[J", "\033[~", "\033[}",
965994Ssos/* 65-68 */	""      , ""      , ""      , ""      ,
975994Ssos/* 69-72 */	""      , ""      , ""      , ""      ,
985994Ssos/* 73-76 */	""      , ""      , ""      , ""      ,
995994Ssos/* 77-80 */	""      , ""      , ""      , ""      ,
1005994Ssos/* 81-84 */	""      , ""      , ""      , ""      ,
1015994Ssos/* 85-88 */	""      , ""      , ""      , ""      ,
1025994Ssos/* 89-92 */	""      , ""      , ""      , ""      ,
1035994Ssos/* 93-96 */	""      , ""      , ""      , ""      ,
1042088Ssos	};
1052088Ssos
10646761Syokotaconst int	delays[]  = {250, 500, 750, 1000};
10746761Syokotaconst int	repeats[] = { 34,  38,  42,  46,  50,  55,  59,  63,
10846761Syokota			      68,  76,  84,  92, 100, 110, 118, 126,
10946761Syokota			     136, 152, 168, 184, 200, 220, 236, 252,
11046761Syokota			     272, 304, 336, 368, 400, 440, 472, 504};
11146761Syokotaconst int	ndelays = (sizeof(delays) / sizeof(int));
11246761Syokotaconst int	nrepeats = (sizeof(repeats) / sizeof(int));
1132088Ssosint 		hex = 0;
1146046Ssosint 		number;
1152088Ssoschar 		letter;
11632316Syokotaint		token;
1172088Ssos
11899816Salfredvoid		dump_accent_definition(char *name, accentmap_t *accentmap);
11999816Salfredvoid		dump_entry(int value);
12099816Salfredvoid		dump_key_definition(char *name, keymap_t *keymap);
12199814Salfredint		get_accent_definition_line(accentmap_t *);
12299816Salfredint		get_entry(void);
12399814Salfredint		get_key_definition_line(keymap_t *);
12499816Salfredvoid		load_keymap(char *opt, int dumponly);
12599816Salfredvoid		load_default_functionkeys(void);
12699816Salfredchar *		nextarg(int ac, char **av, int *indp, int oc);
12799816Salfredchar *		mkfullname(const char *s1, const char *s2, const char *s3);
12899816Salfredvoid		print_accent_definition_line(FILE *fp, int accent,
12999816Salfred			struct acc_t *key);
13099816Salfredvoid		print_entry(FILE *fp, int value);
13199816Salfredvoid		print_key_definition_line(FILE *fp, int scancode,
13299816Salfred			struct keyent_t *key);
13399816Salfredvoid		print_keymap(void);
13499816Salfredvoid		release_keyboard(void);
13599816Salfredvoid		set_bell_values(char *opt);
13699816Salfredvoid		set_functionkey(char *keynumstr, char *string);
13799816Salfredvoid		set_keyboard(char *device);
13899816Salfredvoid		set_keyrates(char *opt);
13999816Salfredvoid		show_kbd_info(void);
14099816Salfredvoid		usage(void) __dead2;
1412088Ssos
1422088Ssoschar *
1432088Ssosnextarg(int ac, char **av, int *indp, int oc)
1442088Ssos{
1452088Ssos	if (*indp < ac)
1462088Ssos		return(av[(*indp)++]);
14729603Scharnier	warnx("option requires two arguments -- %c", oc);
1482088Ssos	usage();
1492088Ssos}
1502088Ssos
1512088Ssos
1522088Ssoschar *
1532088Ssosmkfullname(const char *s1, const char *s2, const char *s3)
1542088Ssos{
1555536Ssos	static char	*buf = NULL;
1565536Ssos	static int	bufl = 0;
1575536Ssos	int		f;
1582088Ssos
1592088Ssos	f = strlen(s1) + strlen(s2) + strlen(s3) + 1;
16077394Ssobomax	if (f > bufl) {
1612088Ssos		if (buf)
1622088Ssos			buf = (char *)realloc(buf, f);
1632088Ssos		else
1642088Ssos			buf = (char *)malloc(f);
16577394Ssobomax	}
1662088Ssos	if (!buf) {
1672088Ssos		bufl = 0;
1682088Ssos		return(NULL);
1692088Ssos	}
1702088Ssos
1712088Ssos	bufl = f;
1722088Ssos	strcpy(buf, s1);
1732088Ssos	strcat(buf, s2);
1742088Ssos	strcat(buf, s3);
1752088Ssos	return(buf);
1762088Ssos}
1772088Ssos
1782088Ssos
1792088Ssosint
18099816Salfredget_entry(void)
1812088Ssos{
18232316Syokota	switch ((token = yylex())) {
1832088Ssos	case TNOP:
1842088Ssos		return NOP | 0x100;
1852088Ssos	case TLSH:
1862088Ssos		return LSH | 0x100;
1872088Ssos	case TRSH:
1882088Ssos		return RSH | 0x100;
1892088Ssos	case TCLK:
1902088Ssos		return CLK | 0x100;
1912088Ssos	case TNLK:
1922088Ssos		return NLK | 0x100;
1932088Ssos	case TSLK:
1942088Ssos		return SLK | 0x100;
1952088Ssos	case TBTAB:
1962088Ssos		return BTAB | 0x100;
1972088Ssos	case TLALT:
1982088Ssos		return LALT | 0x100;
1992088Ssos	case TLCTR:
2002088Ssos		return LCTR | 0x100;
2012088Ssos	case TNEXT:
2022088Ssos		return NEXT | 0x100;
20348105Syokota	case TPREV:
20448105Syokota		return PREV | 0x100;
2052088Ssos	case TRCTR:
2062088Ssos		return RCTR | 0x100;
2072088Ssos	case TRALT:
2082088Ssos		return RALT | 0x100;
2092088Ssos	case TALK:
2102088Ssos		return ALK | 0x100;
2112088Ssos	case TASH:
2122088Ssos		return ASH | 0x100;
2132088Ssos	case TMETA:
2142088Ssos		return META | 0x100;
2152088Ssos	case TRBT:
2162088Ssos		return RBT | 0x100;
2172088Ssos	case TDBG:
2182088Ssos		return DBG | 0x100;
2195994Ssos	case TSUSP:
2205994Ssos		return SUSP | 0x100;
22138053Syokota	case TSPSC:
22238053Syokota		return SPSC | 0x100;
22354380Syokota	case TPANIC:
22454380Syokota		return PNC | 0x100;
22554380Syokota	case TLSHA:
22654380Syokota		return LSHA | 0x100;
22754380Syokota	case TRSHA:
22854380Syokota		return RSHA | 0x100;
22954380Syokota	case TLCTRA:
23054380Syokota		return LCTRA | 0x100;
23154380Syokota	case TRCTRA:
23254380Syokota		return RCTRA | 0x100;
23354380Syokota	case TLALTA:
23454380Syokota		return LALTA | 0x100;
23554380Syokota	case TRALTA:
23654380Syokota		return RALTA | 0x100;
23765759Sdwmalone	case THALT:
23865759Sdwmalone		return HALT | 0x100;
23965759Sdwmalone	case TPDWN:
24065759Sdwmalone		return PDWN | 0x100;
24174118Sache	case TPASTE:
24274118Sache		return PASTE | 0x100;
24332316Syokota	case TACC:
24432316Syokota		if (ACC(number) > L_ACC)
24532316Syokota			return -1;
24632316Syokota		return ACC(number) | 0x100;
2472088Ssos	case TFUNC:
2482088Ssos		if (F(number) > L_FN)
2492088Ssos			return -1;
2502088Ssos		return F(number) | 0x100;
2512088Ssos	case TSCRN:
2522088Ssos		if (S(number) > L_SCR)
2532088Ssos			return -1;
2542088Ssos		return S(number) | 0x100;
2552088Ssos	case TLET:
2562088Ssos		return (unsigned char)letter;
2572088Ssos	case TNUM:
2582088Ssos		if (number < 0 || number > 255)
2592088Ssos			return -1;
2602088Ssos		return number;
2612088Ssos	default:
2622088Ssos		return -1;
2632088Ssos	}
2642088Ssos}
2652088Ssos
26677394Ssobomaxstatic int
26732316Syokotaget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap)
2682088Ssos{
26932316Syokota	int c;
2702088Ssos
2712088Ssos	yyin = fd;
2722088Ssos
27332316Syokota	if (token < 0)
27432316Syokota		token = yylex();
27532316Syokota	switch (token) {
27632316Syokota	case TNUM:
27732316Syokota		c = get_key_definition_line(keymap);
27832316Syokota		if (c < 0)
27932316Syokota			errx(1, "invalid key definition");
28032316Syokota		if (c > keymap->n_keys)
28132316Syokota			keymap->n_keys = c;
28232316Syokota		break;
28332316Syokota	case TACC:
28432316Syokota		c = get_accent_definition_line(accentmap);
28532316Syokota		if (c < 0)
28632316Syokota			errx(1, "invalid accent key definition");
28732316Syokota		if (c > accentmap->n_accs)
28832316Syokota			accentmap->n_accs = c;
28932316Syokota		break;
29032316Syokota	case 0:
29132316Syokota		/* EOF */
2922088Ssos		return -1;
29332316Syokota	default:
29432316Syokota		errx(1, "illegal definition line");
29532316Syokota	}
29632316Syokota	return c;
29732316Syokota}
29832316Syokota
29932316Syokotaint
30032316Syokotaget_key_definition_line(keymap_t *map)
30132316Syokota{
30232316Syokota	int i, def, scancode;
30332316Syokota
30432316Syokota	/* check scancode number */
3052088Ssos	if (number < 0 || number >= NUM_KEYS)
3062088Ssos		return -1;
3072088Ssos	scancode = number;
3082088Ssos
3092088Ssos	/* get key definitions */
3102088Ssos	map->key[scancode].spcl = 0;
3112088Ssos	for (i=0; i<NUM_STATES; i++) {
3122088Ssos		if ((def = get_entry()) == -1)
3132088Ssos			return -1;
3142088Ssos		if (def & 0x100)
3152088Ssos			map->key[scancode].spcl |= (0x80 >> i);
3162088Ssos		map->key[scancode].map[i] = def & 0xFF;
3172088Ssos	}
3182088Ssos	/* get lock state key def */
31932316Syokota	if ((token = yylex()) != TFLAG)
3202088Ssos		return -1;
3212088Ssos	map->key[scancode].flgs = number;
32232316Syokota	token = yylex();
32332316Syokota	return (scancode + 1);
3242088Ssos}
3252088Ssos
32632316Syokotaint
32732316Syokotaget_accent_definition_line(accentmap_t *map)
32832316Syokota{
32932316Syokota	int accent;
33032316Syokota	int c1, c2;
33132316Syokota	int i;
3322088Ssos
33332316Syokota	if (ACC(number) < F_ACC || ACC(number) > L_ACC)
33432316Syokota		/* number out of range */
33532316Syokota		return -1;
33632316Syokota	accent = number;
33732316Syokota	if (map->acc[accent].accchar != 0) {
33832316Syokota		/* this entry has already been defined before! */
33932316Syokota		errx(1, "duplicated accent key definition");
34032316Syokota	}
34132316Syokota
34232316Syokota	switch ((token = yylex())) {
34332316Syokota	case TLET:
34432316Syokota		map->acc[accent].accchar = letter;
34532316Syokota		break;
34632316Syokota	case TNUM:
34732316Syokota		map->acc[accent].accchar = number;
34832316Syokota		break;
34932316Syokota	default:
35032316Syokota		return -1;
35132316Syokota	}
35232316Syokota
35332316Syokota	for (i = 0; (token = yylex()) == '(';) {
35432316Syokota		switch ((token = yylex())) {
35532316Syokota		case TLET:
35632316Syokota			c1 = letter;
35732316Syokota			break;
35832316Syokota		case TNUM:
35932316Syokota			c1 = number;
36032316Syokota			break;
36132316Syokota		default:
36232316Syokota			return -1;
36332316Syokota		}
36432316Syokota		switch ((token = yylex())) {
36532316Syokota		case TLET:
36632316Syokota			c2 = letter;
36732316Syokota			break;
36832316Syokota		case TNUM:
36932316Syokota			c2 = number;
37032316Syokota			break;
37132316Syokota		default:
37232316Syokota			return -1;
37332316Syokota		}
37432316Syokota		if ((token = yylex()) != ')')
37532316Syokota			return -1;
37632316Syokota		if (i >= NUM_ACCENTCHARS) {
37732316Syokota			warnx("too many accented characters, ignored");
37832316Syokota			continue;
37932316Syokota		}
38032316Syokota		map->acc[accent].map[i][0] = c1;
38132316Syokota		map->acc[accent].map[i][1] = c2;
38232316Syokota		++i;
38332316Syokota	}
38432316Syokota	return (accent + 1);
38532316Syokota}
38632316Syokota
38729603Scharniervoid
3882088Ssosprint_entry(FILE *fp, int value)
3892088Ssos{
3902088Ssos	int val = value & 0xFF;
3912088Ssos
3922088Ssos	switch (value) {
3932088Ssos	case NOP | 0x100:
3948857Srgrimes		fprintf(fp, " nop   ");
3952088Ssos		break;
3962088Ssos	case LSH | 0x100:
3972088Ssos		fprintf(fp, " lshift");
3982088Ssos		break;
3992088Ssos	case RSH | 0x100:
4002088Ssos		fprintf(fp, " rshift");
4012088Ssos		break;
4022088Ssos	case CLK | 0x100:
4032088Ssos		fprintf(fp, " clock ");
4042088Ssos		break;
4052088Ssos	case NLK | 0x100:
4062088Ssos		fprintf(fp, " nlock ");
4072088Ssos		break;
4082088Ssos	case SLK | 0x100:
4092088Ssos		fprintf(fp, " slock ");
4102088Ssos		break;
4112088Ssos	case BTAB | 0x100:
4122088Ssos		fprintf(fp, " btab  ");
4132088Ssos		break;
4142088Ssos	case LALT | 0x100:
4152088Ssos		fprintf(fp, " lalt  ");
4162088Ssos		break;
4172088Ssos	case LCTR | 0x100:
4182088Ssos		fprintf(fp, " lctrl ");
4192088Ssos		break;
4202088Ssos	case NEXT | 0x100:
4212088Ssos		fprintf(fp, " nscr  ");
4222088Ssos		break;
42348105Syokota	case PREV | 0x100:
42448105Syokota		fprintf(fp, " pscr  ");
42548105Syokota		break;
4262088Ssos	case RCTR | 0x100:
4272088Ssos		fprintf(fp, " rctrl ");
4282088Ssos		break;
4292088Ssos	case RALT | 0x100:
4302088Ssos		fprintf(fp, " ralt  ");
4312088Ssos		break;
4322088Ssos	case ALK | 0x100:
4332088Ssos		fprintf(fp, " alock ");
4342088Ssos		break;
4352088Ssos	case ASH | 0x100:
4362088Ssos		fprintf(fp, " ashift");
4372088Ssos		break;
4382088Ssos	case META | 0x100:
4392088Ssos		fprintf(fp, " meta  ");
4402088Ssos		break;
4412088Ssos	case RBT | 0x100:
4422088Ssos		fprintf(fp, " boot  ");
4432088Ssos		break;
4442088Ssos	case DBG | 0x100:
4452088Ssos		fprintf(fp, " debug ");
4462088Ssos		break;
44732316Syokota	case SUSP | 0x100:
44832316Syokota		fprintf(fp, " susp  ");
44932316Syokota		break;
45038053Syokota	case SPSC | 0x100:
45138053Syokota		fprintf(fp, " saver ");
45238053Syokota		break;
45354380Syokota	case PNC | 0x100:
45454380Syokota		fprintf(fp, " panic ");
45554380Syokota		break;
45654380Syokota	case LSHA | 0x100:
45754380Syokota		fprintf(fp, " lshifta");
45854380Syokota		break;
45954380Syokota	case RSHA | 0x100:
46054380Syokota		fprintf(fp, " rshifta");
46154380Syokota		break;
46254380Syokota	case LCTRA | 0x100:
46354380Syokota		fprintf(fp, " lctrla");
46454380Syokota		break;
46554380Syokota	case RCTRA | 0x100:
46654380Syokota		fprintf(fp, " rctrla");
46754380Syokota		break;
46854380Syokota	case LALTA | 0x100:
46954380Syokota		fprintf(fp, " lalta ");
47054380Syokota		break;
47154380Syokota	case RALTA | 0x100:
47254380Syokota		fprintf(fp, " ralta ");
47354380Syokota		break;
47465759Sdwmalone	case HALT | 0x100:
47565759Sdwmalone		fprintf(fp, " halt  ");
47665759Sdwmalone		break;
47765759Sdwmalone	case PDWN | 0x100:
47865759Sdwmalone		fprintf(fp, " pdwn  ");
47965759Sdwmalone		break;
48074118Sache	case PASTE | 0x100:
48174118Sache		fprintf(fp, " paste ");
48274118Sache		break;
4832088Ssos	default:
4842088Ssos		if (value & 0x100) {
4858857Srgrimes		 	if (val >= F_FN && val <= L_FN)
4862088Ssos				fprintf(fp, " fkey%02d", val - F_FN + 1);
4878857Srgrimes		 	else if (val >= F_SCR && val <= L_SCR)
4882088Ssos				fprintf(fp, " scr%02d ", val - F_SCR + 1);
48932316Syokota		 	else if (val >= F_ACC && val <= L_ACC)
49032316Syokota				fprintf(fp, " %-6s", acc_names[val - F_ACC]);
4912088Ssos			else if (hex)
4928857Srgrimes				fprintf(fp, " 0x%02x  ", val);
4932088Ssos			else
49432316Syokota				fprintf(fp, " %3d   ", val);
4952088Ssos		}
4962088Ssos		else {
4972088Ssos			if (val < ' ')
4988857Srgrimes				fprintf(fp, " %s   ", ctrl_names[val]);
4992088Ssos			else if (val == 127)
5008857Srgrimes				fprintf(fp, " del   ");
5019202Srgrimes			else if (isascii(val) && isprint(val))
5028857Srgrimes				fprintf(fp, " '%c'   ", val);
5032088Ssos			else if (hex)
5048857Srgrimes				fprintf(fp, " 0x%02x  ", val);
5052088Ssos			else
5068857Srgrimes				fprintf(fp, " %3d   ", val);
5072088Ssos		}
5082088Ssos	}
5092088Ssos}
5102088Ssos
5112088Ssosvoid
51242505Syokotaprint_key_definition_line(FILE *fp, int scancode, struct keyent_t *key)
5132088Ssos{
51429603Scharnier	int i;
5152088Ssos
5162088Ssos	/* print scancode number */
5172088Ssos	if (hex)
5182088Ssos		fprintf(fp, " 0x%02x  ", scancode);
5192088Ssos	else
5202088Ssos		fprintf(fp, "  %03d  ", scancode);
5212088Ssos
5222088Ssos	/* print key definitions */
5232088Ssos	for (i=0; i<NUM_STATES; i++) {
5242088Ssos		if (key->spcl & (0x80 >> i))
5252088Ssos			print_entry(fp, key->map[i] | 0x100);
5262088Ssos		else
5278857Srgrimes			print_entry(fp, key->map[i]);
5282088Ssos	}
5292088Ssos
5302088Ssos	/* print lock state key def */
5312088Ssos	switch (key->flgs) {
5322088Ssos	case 0:
5332088Ssos		fprintf(fp, "  O\n");
5342088Ssos		break;
5352088Ssos	case 1:
5362088Ssos		fprintf(fp, "  C\n");
5372088Ssos		break;
5382088Ssos	case 2:
5392088Ssos		fprintf(fp, "  N\n");
5402088Ssos		break;
5416046Ssos	case 3:
5426046Ssos		fprintf(fp, "  B\n");
5436046Ssos		break;
5448857Srgrimes	}
5452088Ssos}
5462088Ssos
54732316Syokotavoid
54832316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key)
54932316Syokota{
55032316Syokota	int c;
55132316Syokota	int i;
5522088Ssos
55332316Syokota	if (key->accchar == 0)
55432316Syokota		return;
55532316Syokota
55632316Syokota	/* print accent number */
55732316Syokota	fprintf(fp, "  %-6s", acc_names[accent]);
55832316Syokota	if (isascii(key->accchar) && isprint(key->accchar))
55932316Syokota		fprintf(fp, "'%c'  ", key->accchar);
56032316Syokota	else if (hex)
56132316Syokota		fprintf(fp, "0x%02x ", key->accchar);
56232316Syokota	else
56332316Syokota		fprintf(fp, "%03d  ", key->accchar);
56432316Syokota
56532316Syokota	for (i = 0; i < NUM_ACCENTCHARS; ++i) {
56632316Syokota		c = key->map[i][0];
56732316Syokota		if (c == 0)
56832316Syokota			break;
56932316Syokota		if ((i > 0) && ((i % 4) == 0))
57032316Syokota			fprintf(fp, "\n             ");
57132316Syokota		if (isascii(c) && isprint(c))
57232316Syokota			fprintf(fp, "( '%c' ", c);
57332316Syokota		else if (hex)
57432316Syokota			fprintf(fp, "(0x%02x ", c);
57532316Syokota		else
57632316Syokota			fprintf(fp, "( %03d ", c);
57732316Syokota		c = key->map[i][1];
57832316Syokota		if (isascii(c) && isprint(c))
57932316Syokota			fprintf(fp, "'%c' ) ", c);
58032316Syokota		else if (hex)
58132316Syokota			fprintf(fp, "0x%02x) ", c);
58232316Syokota		else
58332316Syokota			fprintf(fp, "%03d ) ", c);
58432316Syokota	}
58532316Syokota	fprintf(fp, "\n");
58632316Syokota}
58732316Syokota
5882088Ssosvoid
58932316Syokotadump_entry(int value)
59032316Syokota{
59132316Syokota	if (value & 0x100) {
59232316Syokota		value &= 0x00ff;
59332316Syokota		switch (value) {
59432316Syokota		case NOP:
59532316Syokota			printf("  NOP, ");
59632316Syokota			break;
59732316Syokota		case LSH:
59832316Syokota			printf("  LSH, ");
59932316Syokota			break;
60032316Syokota		case RSH:
60132316Syokota			printf("  RSH, ");
60232316Syokota			break;
60332316Syokota		case CLK:
60432316Syokota			printf("  CLK, ");
60532316Syokota			break;
60632316Syokota		case NLK:
60732316Syokota			printf("  NLK, ");
60832316Syokota			break;
60932316Syokota		case SLK:
61032316Syokota			printf("  SLK, ");
61132316Syokota			break;
61232316Syokota		case BTAB:
61332316Syokota			printf(" BTAB, ");
61432316Syokota			break;
61532316Syokota		case LALT:
61632316Syokota			printf(" LALT, ");
61732316Syokota			break;
61832316Syokota		case LCTR:
61932316Syokota			printf(" LCTR, ");
62032316Syokota			break;
62132316Syokota		case NEXT:
62232316Syokota			printf(" NEXT, ");
62332316Syokota			break;
62448105Syokota		case PREV:
62548105Syokota			printf(" PREV, ");
62648105Syokota			break;
62732316Syokota		case RCTR:
62832316Syokota			printf(" RCTR, ");
62932316Syokota			break;
63032316Syokota		case RALT:
63132316Syokota			printf(" RALT, ");
63232316Syokota			break;
63332316Syokota		case ALK:
63432316Syokota			printf("  ALK, ");
63532316Syokota			break;
63632316Syokota		case ASH:
63732316Syokota			printf("  ASH, ");
63832316Syokota			break;
63932316Syokota		case META:
64032316Syokota			printf(" META, ");
64132316Syokota			break;
64232316Syokota		case RBT:
64332316Syokota			printf("  RBT, ");
64432316Syokota			break;
64532316Syokota		case DBG:
64632316Syokota			printf("  DBG, ");
64732316Syokota			break;
64832316Syokota		case SUSP:
64932316Syokota			printf(" SUSP, ");
65032316Syokota			break;
65138053Syokota		case SPSC:
65238053Syokota			printf(" SPSC, ");
65338053Syokota			break;
65454380Syokota		case PNC:
65554380Syokota			printf("  PNC, ");
65654380Syokota			break;
65754380Syokota		case LSHA:
65854380Syokota			printf(" LSHA, ");
65954380Syokota			break;
66054380Syokota		case RSHA:
66154380Syokota			printf(" RSHA, ");
66254380Syokota			break;
66354380Syokota		case LCTRA:
66454380Syokota			printf("LCTRA, ");
66554380Syokota			break;
66654380Syokota		case RCTRA:
66754380Syokota			printf("RCTRA, ");
66854380Syokota			break;
66954380Syokota		case LALTA:
67054380Syokota			printf("LALTA, ");
67154380Syokota			break;
67254380Syokota		case RALTA:
67354380Syokota			printf("RALTA, ");
67454380Syokota			break;
67565759Sdwmalone		case HALT:
67665759Sdwmalone			printf(" HALT, ");
67765759Sdwmalone			break;
67865759Sdwmalone		case PDWN:
67965759Sdwmalone			printf(" PDWN, ");
68065759Sdwmalone			break;
68174118Sache		case PASTE:
68274118Sache			printf("PASTE, ");
68374118Sache			break;
68432316Syokota		default:
68532316Syokota	 		if (value >= F_FN && value <= L_FN)
68632316Syokota				printf(" F(%2d),", value - F_FN + 1);
68732316Syokota	 		else if (value >= F_SCR && value <= L_SCR)
68832486Syokota				printf(" S(%2d),", value - F_SCR + 1);
68932316Syokota	 		else if (value >= F_ACC && value <= L_ACC)
69032316Syokota				printf(" %-4s, ", acc_names_u[value - F_ACC]);
69132316Syokota			else
69232316Syokota				printf(" 0x%02X, ", value);
69332316Syokota			break;
69432316Syokota		}
69532316Syokota	} else if (value == '\'') {
69632316Syokota		printf(" '\\'', ");
69732316Syokota	} else if (value == '\\') {
69832316Syokota		printf(" '\\\\', ");
69932316Syokota	} else if (isascii(value) && isprint(value)) {
70032316Syokota		printf("  '%c', ", value);
70132316Syokota	} else {
70232316Syokota		printf(" 0x%02X, ", value);
70332316Syokota	}
70432316Syokota}
70532316Syokota
70632316Syokotavoid
70732316Syokotadump_key_definition(char *name, keymap_t *keymap)
70832316Syokota{
70932316Syokota	int	i, j;
71032316Syokota
71132486Syokota	printf("static keymap_t keymap_%s = { 0x%02x, {\n",
71232316Syokota	       name, (unsigned)keymap->n_keys);
71332316Syokota	printf(
71432486Syokota"/*                                                         alt\n"
71532486Syokota" * scan                       cntrl          alt    alt   cntrl\n"
71632486Syokota" * code  base   shift  cntrl  shift   alt   shift  cntrl  shift    spcl flgs\n"
71732316Syokota" * ---------------------------------------------------------------------------\n"
71832316Syokota" */\n");
71932316Syokota	for (i = 0; i < keymap->n_keys; i++) {
72032486Syokota		printf("/*%02x*/{{", i);
72132316Syokota		for (j = 0; j < NUM_STATES; j++) {
72232316Syokota			if (keymap->key[i].spcl & (0x80 >> j))
72332316Syokota				dump_entry(keymap->key[i].map[j] | 0x100);
72432316Syokota			else
72532316Syokota				dump_entry(keymap->key[i].map[j]);
72632316Syokota		}
72732486Syokota		printf("}, 0x%02X,0x%02X },\n",
72832316Syokota		       (unsigned)keymap->key[i].spcl,
72932316Syokota		       (unsigned)keymap->key[i].flgs);
73032316Syokota	}
73132486Syokota	printf("} };\n\n");
73232316Syokota}
73332316Syokota
73432316Syokotavoid
73532316Syokotadump_accent_definition(char *name, accentmap_t *accentmap)
73632316Syokota{
73732316Syokota	int i, j;
73832316Syokota	int c;
73932316Syokota
74032486Syokota	printf("static accentmap_t accentmap_%s = { %d",
74132316Syokota		name, accentmap->n_accs);
74232486Syokota	if (accentmap->n_accs <= 0) {
74332486Syokota		printf(" };\n\n");
74432486Syokota		return;
74532486Syokota	}
74632486Syokota	printf(", {\n");
74732316Syokota	for (i = 0; i < NUM_DEADKEYS; i++) {
74832316Syokota		printf("    /* %s=%d */\n    {", acc_names[i], i);
74932316Syokota		c = accentmap->acc[i].accchar;
75032316Syokota		if (c == '\'')
75132316Syokota			printf(" '\\'', {");
75232316Syokota		else if (c == '\\')
75332316Syokota			printf(" '\\\\', {");
75432316Syokota		else if (isascii(c) && isprint(c))
75532316Syokota			printf("  '%c', {", c);
75632316Syokota		else if (c == 0) {
75732316Syokota			printf(" 0x00 }, \n");
75832316Syokota			continue;
75932316Syokota		} else
76032316Syokota			printf(" 0x%02x, {", c);
76132316Syokota		for (j = 0; j < NUM_ACCENTCHARS; j++) {
76232316Syokota			c = accentmap->acc[i].map[j][0];
76332316Syokota			if (c == 0)
76432316Syokota				break;
76532316Syokota			if ((j > 0) && ((j % 4) == 0))
76632316Syokota				printf("\n\t     ");
76732316Syokota			if (isascii(c) && isprint(c))
76832316Syokota				printf(" {  '%c',", c);
76932316Syokota			else
77032316Syokota				printf(" { 0x%02x,", c);
77132316Syokota			printf("0x%02x },", accentmap->acc[i].map[j][1]);
77232316Syokota		}
77332316Syokota		printf(" }, },\n");
77432316Syokota	}
77532486Syokota	printf("} };\n\n");
77632316Syokota}
77732316Syokota
77832316Syokotavoid
77919569Sjoergload_keymap(char *opt, int dumponly)
7802088Ssos{
78132316Syokota	keymap_t keymap;
78232316Syokota	accentmap_t accentmap;
7832088Ssos	FILE	*fd;
78476502Ssobomax	int	i, j;
78519569Sjoerg	char	*name, *cp;
78699816Salfred	char	blank[] = "", keymap_path[] = KEYMAP_PATH, dotkbd[] = ".kbd";
78799816Salfred	char	*prefix[]  = {blank, blank, keymap_path, NULL};
78899816Salfred	char	*postfix[] = {blank, dotkbd, NULL};
7892088Ssos
79076569Ssobomax	cp = getenv("KEYMAP_PATH");
79176569Ssobomax	if (cp != NULL)
79276569Ssobomax		asprintf(&(prefix[0]), "%s/", cp);
79376502Ssobomax
79476643Simp	fd = NULL;
79576643Simp	for (i=0; prefix[i] && fd == NULL; i++) {
79676643Simp		for (j=0; postfix[j] && fd == NULL; j++) {
79776502Ssobomax			name = mkfullname(prefix[i], opt, postfix[j]);
79876643Simp			fd = fopen(name, "r");
79976502Ssobomax		}
80076643Simp	}
8012088Ssos	if (fd == NULL) {
80279677Sobrien		warn("keymap file \"%s\" not found", opt);
8032088Ssos		return;
8042088Ssos	}
80532316Syokota	memset(&keymap, 0, sizeof(keymap));
80632316Syokota	memset(&accentmap, 0, sizeof(accentmap));
80732316Syokota	token = -1;
8082088Ssos	while (1) {
80932316Syokota		if (get_definition_line(fd, &keymap, &accentmap) < 0)
8102088Ssos			break;
8112088Ssos    	}
81219569Sjoerg	if (dumponly) {
81319569Sjoerg		/* fix up the filename to make it a valid C identifier */
81419569Sjoerg		for (cp = opt; *cp; cp++)
81519569Sjoerg			if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_';
81632316Syokota		printf("/*\n"
81732316Syokota		       " * Automatically generated from %s.\n"
81832316Syokota	               " * DO NOT EDIT!\n"
81932316Syokota		       " */\n", name);
82032316Syokota		dump_key_definition(opt, &keymap);
82132316Syokota		dump_accent_definition(opt, &accentmap);
82219569Sjoerg		return;
82319569Sjoerg	}
82432316Syokota	if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) {
82529603Scharnier		warn("setting keymap");
8262088Ssos		fclose(fd);
8272088Ssos		return;
8282088Ssos	}
82932316Syokota	if ((accentmap.n_accs > 0)
83032316Syokota		&& (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) {
83132316Syokota		warn("setting accentmap");
83232316Syokota		fclose(fd);
83332316Syokota		return;
83432316Syokota	}
8352088Ssos}
8362088Ssos
8372088Ssosvoid
83899816Salfredprint_keymap(void)
8392088Ssos{
84032316Syokota	keymap_t keymap;
84132316Syokota	accentmap_t accentmap;
8422088Ssos	int i;
8432088Ssos
84432316Syokota	if (ioctl(0, GIO_KEYMAP, &keymap) < 0)
84529603Scharnier		err(1, "getting keymap");
84632316Syokota	if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0)
84732316Syokota		memset(&accentmap, 0, sizeof(accentmap));
8482088Ssos    	printf(
8492088Ssos"#                                                         alt\n"
8502088Ssos"# scan                       cntrl          alt    alt   cntrl lock\n"
8512088Ssos"# code  base   shift  cntrl  shift  alt    shift  cntrl  shift state\n"
8522088Ssos"# ------------------------------------------------------------------\n"
8532088Ssos    	);
85432316Syokota	for (i=0; i<keymap.n_keys; i++)
85532316Syokota		print_key_definition_line(stdout, i, &keymap.key[i]);
85632316Syokota
85732316Syokota	printf("\n");
85832316Syokota	for (i = 0; i < NUM_DEADKEYS; i++)
85932316Syokota		print_accent_definition_line(stdout, i, &accentmap.acc[i]);
86032316Syokota
8612088Ssos}
8622088Ssos
8632088Ssosvoid
86499816Salfredload_default_functionkeys(void)
8652088Ssos{
8662088Ssos	fkeyarg_t fkey;
8672088Ssos	int i;
8682088Ssos
8692088Ssos	for (i=0; i<NUM_FKEYS; i++) {
8702088Ssos		fkey.keynum = i;
8712088Ssos		strcpy(fkey.keydef, fkey_table[i]);
8722088Ssos		fkey.flen = strlen(fkey_table[i]);
8732088Ssos		if (ioctl(0, SETFKEY, &fkey) < 0)
87429603Scharnier			warn("setting function key");
8752088Ssos	}
8762088Ssos}
8772088Ssos
8782088Ssosvoid
8792088Ssosset_functionkey(char *keynumstr, char *string)
8802088Ssos{
8812088Ssos	fkeyarg_t fkey;
8822088Ssos
8832088Ssos	if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) {
8842088Ssos		load_default_functionkeys();
8852088Ssos		return;
8862088Ssos	}
8872088Ssos	fkey.keynum = atoi(keynumstr);
8882088Ssos	if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) {
88929603Scharnier		warnx("function key number must be between 1 and %d",
8902088Ssos			NUM_FKEYS);
8912088Ssos		return;
8922088Ssos	}
8932088Ssos	if ((fkey.flen = strlen(string)) > MAXFK) {
89429603Scharnier		warnx("function key string too long (%d > %d)",
8952088Ssos			fkey.flen, MAXFK);
8962088Ssos		return;
8972088Ssos	}
8982088Ssos	strcpy(fkey.keydef, string);
8992088Ssos	fkey.keynum -= 1;
9002088Ssos	if (ioctl(0, SETFKEY, &fkey) < 0)
90129603Scharnier		warn("setting function key");
9022088Ssos}
9032088Ssos
9042088Ssosvoid
9052088Ssosset_bell_values(char *opt)
9062088Ssos{
9075536Ssos	int bell, duration, pitch;
9082088Ssos
90938044Syokota	bell = 0;
91038044Syokota	if (!strncmp(opt, "quiet.", 6)) {
91138044Syokota		bell = 2;
91238044Syokota		opt += 6;
91338044Syokota	}
9148857Srgrimes	if (!strcmp(opt, "visual"))
91538044Syokota		bell |= 1;
9165536Ssos	else if (!strcmp(opt, "normal"))
91738044Syokota		duration = 5, pitch = 800;
91848982Syokota	else if (!strcmp(opt, "off"))
91948982Syokota		duration = 0, pitch = 0;
9202088Ssos	else {
9212088Ssos		char		*v1;
9228857Srgrimes
9235536Ssos		bell = 0;
9242088Ssos		duration = strtol(opt, &v1, 0);
9252088Ssos		if ((duration < 0) || (*v1 != '.'))
9262088Ssos			goto badopt;
9272088Ssos		opt = ++v1;
9282088Ssos		pitch = strtol(opt, &v1, 0);
9292088Ssos		if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) {
9302088Ssosbadopt:
93177394Ssobomax			warnx("argument to -b must be duration.pitch or [quiet.]visual|normal|off");
9322088Ssos			return;
9332088Ssos		}
93438044Syokota		if (pitch != 0)
93538044Syokota			pitch = 1193182 / pitch;	/* in Hz */
93638044Syokota		duration /= 10;	/* in 10 m sec */
9372088Ssos	}
9382088Ssos
9395536Ssos	ioctl(0, CONS_BELLTYPE, &bell);
94038044Syokota	if ((bell & ~2) == 0)
9415536Ssos		fprintf(stderr, "[=%d;%dB", pitch, duration);
9422088Ssos}
9432088Ssos
9442088Ssosvoid
9452088Ssosset_keyrates(char *opt)
9462088Ssos{
94744628Syokota	int arg[2];
94839047Syokota	int repeat;
94939047Syokota	int delay;
95046761Syokota	int r, d;
9512088Ssos
95246761Syokota	if (!strcmp(opt, "slow")) {
95344628Syokota		delay = 1000, repeat = 500;
95446761Syokota		d = 3, r = 31;
95546761Syokota	} else if (!strcmp(opt, "normal")) {
95644628Syokota		delay = 500, repeat = 125;
95746761Syokota		d = 1, r = 15;
95846761Syokota	} else if (!strcmp(opt, "fast")) {
95939047Syokota		delay = repeat = 0;
96046761Syokota		d = r = 0;
96146761Syokota	} else {
9622088Ssos		int		n;
9632088Ssos		char		*v1;
9642088Ssos
9652088Ssos		delay = strtol(opt, &v1, 0);
9662088Ssos		if ((delay < 0) || (*v1 != '.'))
9672088Ssos			goto badopt;
9682088Ssos		opt = ++v1;
9692088Ssos		repeat = strtol(opt, &v1, 0);
9702088Ssos		if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) {
9712088Ssosbadopt:
97277394Ssobomax			warnx("argument to -r must be delay.repeat or slow|normal|fast");
9732088Ssos			return;
9742088Ssos		}
97546761Syokota		for (n = 0; n < ndelays - 1; n++)
97646761Syokota			if (delay <= delays[n])
97746761Syokota				break;
97846761Syokota		d = n;
97946761Syokota		for (n = 0; n < nrepeats - 1; n++)
98046761Syokota			if (repeat <= repeats[n])
98146761Syokota				break;
98246761Syokota		r = n;
9832088Ssos	}
9842088Ssos
98544628Syokota	arg[0] = delay;
98644628Syokota	arg[1] = repeat;
98746761Syokota	if (ioctl(0, KDSETREPEAT, arg)) {
98846761Syokota		if (ioctl(0, KDSETRAD, (d << 5) | r))
98946761Syokota			warn("setting keyboard rate");
99046761Syokota	}
9912088Ssos}
9922088Ssos
99399816Salfredstatic const char *
99499816Salfredget_kbd_type_name(int type)
99542505Syokota{
99642505Syokota	static struct {
99742505Syokota		int type;
99899816Salfred		const char *name;
99942505Syokota	} name_table[] = {
100042505Syokota		{ KB_84,	"AT 84" },
100142505Syokota		{ KB_101,	"AT 101/102" },
100242505Syokota		{ KB_OTHER,	"generic" },
100342505Syokota	};
100499816Salfred	unsigned int i;
10056046Ssos
100642505Syokota	for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) {
100742505Syokota		if (type == name_table[i].type)
100842505Syokota			return name_table[i].name;
100942505Syokota	}
101042505Syokota	return "unknown";
101142505Syokota}
101242505Syokota
101342505Syokotavoid
101442505Syokotashow_kbd_info(void)
101542505Syokota{
101642505Syokota	keyboard_info_t info;
101742505Syokota
101842505Syokota	if (ioctl(0, KDGKBINFO, &info) == -1) {
101942505Syokota		warn("unable to obtain keyboard information");
102042505Syokota		return;
102142505Syokota	}
102242505Syokota	printf("kbd%d:\n", info.kb_index);
102342505Syokota	printf("    %.*s%d, type:%s (%d)\n",
102477394Ssobomax		(int)sizeof(info.kb_name), info.kb_name, info.kb_unit,
102542505Syokota		get_kbd_type_name(info.kb_type), info.kb_type);
102642505Syokota}
102742505Syokota
102842505Syokotavoid
102942505Syokotaset_keyboard(char *device)
103042505Syokota{
103142505Syokota	keyboard_info_t info;
103242505Syokota	int fd;
103342505Syokota
103442505Syokota	fd = open(device, O_RDONLY);
103542505Syokota	if (fd < 0) {
103642505Syokota		warn("cannot open %s", device);
103742505Syokota		return;
103842505Syokota	}
103942505Syokota	if (ioctl(fd, KDGKBINFO, &info) == -1) {
104042505Syokota		warn("unable to obtain keyboard information");
104142505Syokota		close(fd);
104242505Syokota		return;
104342505Syokota	}
104442505Syokota	/*
104542505Syokota	 * The keyboard device driver won't release the keyboard by
104642505Syokota	 * the following ioctl, but it automatically will, when the device
104742505Syokota	 * is closed.  So, we don't check error here.
104842505Syokota	 */
104942505Syokota	ioctl(fd, CONS_RELKBD, 0);
105042505Syokota	close(fd);
105142505Syokota#if 1
105242505Syokota	printf("kbd%d\n", info.kb_index);
105342505Syokota	printf("    %.*s%d, type:%s (%d)\n",
105477394Ssobomax		(int)sizeof(info.kb_name), info.kb_name, info.kb_unit,
105542505Syokota		get_kbd_type_name(info.kb_type), info.kb_type);
105642505Syokota#endif
105742505Syokota
105842505Syokota	if (ioctl(0, CONS_SETKBD, info.kb_index) == -1)
105942505Syokota		warn("unable to set keyboard");
106042505Syokota}
106142505Syokota
106242505Syokotavoid
106342505Syokotarelease_keyboard(void)
106442505Syokota{
106542505Syokota	keyboard_info_t info;
106642505Syokota
106742505Syokota	/*
106842505Syokota	 * If stdin is not associated with a keyboard, the following ioctl
106942505Syokota	 * will fail.
107042505Syokota	 */
107142505Syokota	if (ioctl(0, KDGKBINFO, &info) == -1) {
107242505Syokota		warn("unable to obtain keyboard information");
107342505Syokota		return;
107442505Syokota	}
107542505Syokota#if 1
107642505Syokota	printf("kbd%d\n", info.kb_index);
107742505Syokota	printf("    %.*s%d, type:%s (%d)\n",
107877394Ssobomax		(int)sizeof(info.kb_name), info.kb_name, info.kb_unit,
107942505Syokota		get_kbd_type_name(info.kb_type), info.kb_type);
108042505Syokota#endif
108142505Syokota	if (ioctl(0, CONS_RELKBD, 0) == -1)
108242505Syokota		warn("unable to release the keyboard");
108342505Syokota}
108442505Syokota
108542505Syokota
108677394Ssobomaxvoid
10872088Ssosusage()
10882088Ssos{
108929603Scharnier	fprintf(stderr, "%s\n%s\n%s\n",
109077329Sdes"usage: kbdcontrol [-dFKix] [-b duration.pitch | [quiet.]belltype]",
109129603Scharnier"                  [-r delay.repeat | speed] [-l mapfile] [-f # string]",
109277329Sdes"                  [-k device] [-L mapfile]");
109329603Scharnier	exit(1);
10942088Ssos}
10952088Ssos
10962088Ssos
109751287Speterint
10982088Ssosmain(int argc, char **argv)
10992088Ssos{
11002088Ssos	int		opt;
11012088Ssos
110277329Sdes	while((opt = getopt(argc, argv, "b:df:iKk:Fl:L:r:x")) != -1)
11032088Ssos		switch(opt) {
110477329Sdes		case 'b':
110577329Sdes			set_bell_values(optarg);
110677329Sdes			break;
110777329Sdes		case 'd':
110877329Sdes			print_keymap();
110977329Sdes			break;
111077329Sdes		case 'l':
111177329Sdes			load_keymap(optarg, 0);
111277329Sdes			break;
111377329Sdes		case 'L':
111477329Sdes			load_keymap(optarg, 1);
111577329Sdes			break;
111677329Sdes		case 'f':
111777329Sdes			set_functionkey(optarg,
111877329Sdes			    nextarg(argc, argv, &optind, 'f'));
111977329Sdes			break;
112077329Sdes		case 'F':
112177329Sdes			load_default_functionkeys();
112277329Sdes			break;
112377329Sdes		case 'i':
112477329Sdes			show_kbd_info();
112577329Sdes			break;
112677329Sdes		case 'K':
112777329Sdes			release_keyboard();
112877329Sdes			break;
112977329Sdes		case 'k':
113077329Sdes			set_keyboard(optarg);
113177329Sdes			break;
113277329Sdes		case 'r':
113377329Sdes			set_keyrates(optarg);
113477329Sdes			break;
113577329Sdes		case 'x':
113677329Sdes			hex = 1;
113777329Sdes			break;
113877329Sdes		default:
113977329Sdes			usage();
11402088Ssos		}
114129603Scharnier	if ((optind != argc) || (argc == 1))
11422088Ssos		usage();
11432088Ssos	exit(0);
11442088Ssos}
1145