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