kbdcontrol.c revision 32486
12088Ssos/*-
25536Ssos * Copyright (c) 1994-1995 S�ren Schmidt
32088Ssos * All rights reserved.
42088Ssos *
52088Ssos * Redistribution and use in source and binary forms, with or without
62088Ssos * modification, are permitted provided that the following conditions
72088Ssos * are met:
82088Ssos * 1. Redistributions of source code must retain the above copyright
95994Ssos *    notice, this list of conditions and the following disclaimer,
105994Ssos *    in this position and unchanged.
112088Ssos * 2. Redistributions in binary form must reproduce the above copyright
122088Ssos *    notice, this list of conditions and the following disclaimer in the
132088Ssos *    documentation and/or other materials provided with the distribution.
142088Ssos * 3. The name of the author may not be used to endorse or promote products
152088Ssos *    derived from this software withough specific prior written permission
162088Ssos *
172088Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
182088Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
192088Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
202088Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
212088Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
222088Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232088Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242088Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252088Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
262088Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272088Ssos */
282088Ssos
2929603Scharnier#ifndef lint
3029603Scharnierstatic const char rcsid[] =
3132486Syokota	"$Id: kbdcontrol.c,v 1.12 1998/01/07 08:43:27 yokota Exp $";
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>
402088Ssos#include <machine/console.h>
412088Ssos#include "path.h"
422088Ssos#include "lex.h"
432088Ssos
442088Ssoschar ctrl_names[32][4] = {
458857Srgrimes	"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
462088Ssos	"bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ",
472088Ssos	"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
482088Ssos	"can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "ns "
492088Ssos	};
502088Ssos
5132316Syokotachar acc_names[15][5] = {
5232316Syokota	"dgra", "dacu", "dcir", "dtil", "dmac", "dbre", "ddot",
5332316Syokota	"duml", "dsla", "drin", "dced", "dapo", "ddac", "dogo",
5432316Syokota	"dcar",
5532316Syokota	};
5632316Syokota
5732316Syokotachar acc_names_u[15][5] = {
5832316Syokota	"DGRA", "DACU", "DCIR", "DTIL", "DMAC", "DBRE", "DDOT",
5932316Syokota	"DUML", "DSLA", "DRIN", "DCED", "DAPO", "DDAC", "DOGO",
6032316Syokota	"DCAR",
6132316Syokota	};
6232316Syokota
635994Ssoschar fkey_table[96][MAXFK] = {
645994Ssos/* 01-04 */	"\033[M", "\033[N", "\033[O", "\033[P",
655994Ssos/* 05-08 */	"\033[Q", "\033[R", "\033[S", "\033[T",
665994Ssos/* 09-12 */	"\033[U", "\033[V", "\033[W", "\033[X",
675994Ssos/* 13-16 */	"\033[Y", "\033[Z", "\033[a", "\033[b",
685994Ssos/* 17-20 */	"\033[c", "\033[d", "\033[e", "\033[f",
695994Ssos/* 21-24 */	"\033[g", "\033[h", "\033[i", "\033[j",
705994Ssos/* 25-28 */	"\033[k", "\033[l", "\033[m", "\033[n",
715994Ssos/* 29-32 */	"\033[o", "\033[p", "\033[q", "\033[r",
725994Ssos/* 33-36 */	"\033[s", "\033[t", "\033[u", "\033[v",
735994Ssos/* 37-40 */	"\033[w", "\033[x", "\033[y", "\033[z",
745994Ssos/* 41-44 */	"\033[@", "\033[[", "\033[\\","\033[]",
759202Srgrimes/* 45-48 */     "\033[^", "\033[_", "\033[`", "\033[{",
765994Ssos/* 49-52 */	"\033[H", "\033[A", "\033[I", "-"     ,
775994Ssos/* 53-56 */	"\033[D", "\033[E", "\033[C", "+"     ,
785994Ssos/* 57-60 */	"\033[F", "\033[B", "\033[G", "\033[L",
799202Srgrimes/* 61-64 */     "\177",   "\033[J", "\033[~", "\033[}",
805994Ssos/* 65-68 */	""      , ""      , ""      , ""      ,
815994Ssos/* 69-72 */	""      , ""      , ""      , ""      ,
825994Ssos/* 73-76 */	""      , ""      , ""      , ""      ,
835994Ssos/* 77-80 */	""      , ""      , ""      , ""      ,
845994Ssos/* 81-84 */	""      , ""      , ""      , ""      ,
855994Ssos/* 85-88 */	""      , ""      , ""      , ""      ,
865994Ssos/* 89-92 */	""      , ""      , ""      , ""      ,
875994Ssos/* 93-96 */	""      , ""      , ""      , ""      ,
882088Ssos	};
892088Ssos
902088Ssosconst int	delays[]  = {250, 500, 750, 1000};
912088Ssosconst int	repeats[] = { 34,  38,  42,  46,  50,  55,  59,  63,
922088Ssos			      68,  76,  84,  92, 100, 110, 118, 126,
932088Ssos			     136, 152, 168, 184, 200, 220, 236, 252,
942088Ssos			     272, 304, 336, 368, 400, 440, 472, 504};
952088Ssosconst int	ndelays = (sizeof(delays) / sizeof(int));
962088Ssosconst int	nrepeats = (sizeof(repeats) / sizeof(int));
972088Ssosint 		hex = 0;
986046Ssosint 		number;
992088Ssoschar 		letter;
10032316Syokotaint		token;
1012088Ssos
10229603Scharnierstatic void usage __P((void));
1032088Ssos
1042088Ssoschar *
1052088Ssosnextarg(int ac, char **av, int *indp, int oc)
1062088Ssos{
1072088Ssos	if (*indp < ac)
1082088Ssos		return(av[(*indp)++]);
10929603Scharnier	warnx("option requires two arguments -- %c", oc);
1102088Ssos	usage();
1112088Ssos	return("");
1122088Ssos}
1132088Ssos
1142088Ssos
1152088Ssoschar *
1162088Ssosmkfullname(const char *s1, const char *s2, const char *s3)
1172088Ssos{
1185536Ssos	static char	*buf = NULL;
1195536Ssos	static int	bufl = 0;
1205536Ssos	int		f;
1212088Ssos
1222088Ssos	f = strlen(s1) + strlen(s2) + strlen(s3) + 1;
1232088Ssos	if (f > bufl)
1242088Ssos		if (buf)
1252088Ssos			buf = (char *)realloc(buf, f);
1262088Ssos		else
1272088Ssos			buf = (char *)malloc(f);
1282088Ssos	if (!buf) {
1292088Ssos		bufl = 0;
1302088Ssos		return(NULL);
1312088Ssos	}
1322088Ssos
1332088Ssos	bufl = f;
1342088Ssos	strcpy(buf, s1);
1352088Ssos	strcat(buf, s2);
1362088Ssos	strcat(buf, s3);
1372088Ssos	return(buf);
1382088Ssos}
1392088Ssos
1402088Ssos
1412088Ssosint
1422088Ssosget_entry()
1432088Ssos{
14432316Syokota	switch ((token = yylex())) {
1452088Ssos	case TNOP:
1462088Ssos		return NOP | 0x100;
1472088Ssos	case TLSH:
1482088Ssos		return LSH | 0x100;
1492088Ssos	case TRSH:
1502088Ssos		return RSH | 0x100;
1512088Ssos	case TCLK:
1522088Ssos		return CLK | 0x100;
1532088Ssos	case TNLK:
1542088Ssos		return NLK | 0x100;
1552088Ssos	case TSLK:
1562088Ssos		return SLK | 0x100;
1572088Ssos	case TBTAB:
1582088Ssos		return BTAB | 0x100;
1592088Ssos	case TLALT:
1602088Ssos		return LALT | 0x100;
1612088Ssos	case TLCTR:
1622088Ssos		return LCTR | 0x100;
1632088Ssos	case TNEXT:
1642088Ssos		return NEXT | 0x100;
1652088Ssos	case TRCTR:
1662088Ssos		return RCTR | 0x100;
1672088Ssos	case TRALT:
1682088Ssos		return RALT | 0x100;
1692088Ssos	case TALK:
1702088Ssos		return ALK | 0x100;
1712088Ssos	case TASH:
1722088Ssos		return ASH | 0x100;
1732088Ssos	case TMETA:
1742088Ssos		return META | 0x100;
1752088Ssos	case TRBT:
1762088Ssos		return RBT | 0x100;
1772088Ssos	case TDBG:
1782088Ssos		return DBG | 0x100;
1795994Ssos	case TSUSP:
1805994Ssos		return SUSP | 0x100;
18132316Syokota	case TACC:
18232316Syokota		if (ACC(number) > L_ACC)
18332316Syokota			return -1;
18432316Syokota		return ACC(number) | 0x100;
1852088Ssos	case TFUNC:
1862088Ssos		if (F(number) > L_FN)
1872088Ssos			return -1;
1882088Ssos		return F(number) | 0x100;
1892088Ssos	case TSCRN:
1902088Ssos		if (S(number) > L_SCR)
1912088Ssos			return -1;
1922088Ssos		return S(number) | 0x100;
1932088Ssos	case TLET:
1942088Ssos		return (unsigned char)letter;
1952088Ssos	case TNUM:
1962088Ssos		if (number < 0 || number > 255)
1972088Ssos			return -1;
1982088Ssos		return number;
1992088Ssos	default:
2002088Ssos		return -1;
2012088Ssos	}
2022088Ssos}
2032088Ssos
2042088Ssosint
20532316Syokotaget_definition_line(FILE *fd, keymap_t *keymap, accentmap_t *accentmap)
2062088Ssos{
20732316Syokota	int c;
2082088Ssos
2092088Ssos	yyin = fd;
2102088Ssos
21132316Syokota	if (token < 0)
21232316Syokota		token = yylex();
21332316Syokota	switch (token) {
21432316Syokota	case TNUM:
21532316Syokota		c = get_key_definition_line(keymap);
21632316Syokota		if (c < 0)
21732316Syokota			errx(1, "invalid key definition");
21832316Syokota		if (c > keymap->n_keys)
21932316Syokota			keymap->n_keys = c;
22032316Syokota		break;
22132316Syokota	case TACC:
22232316Syokota		c = get_accent_definition_line(accentmap);
22332316Syokota		if (c < 0)
22432316Syokota			errx(1, "invalid accent key definition");
22532316Syokota		if (c > accentmap->n_accs)
22632316Syokota			accentmap->n_accs = c;
22732316Syokota		break;
22832316Syokota	case 0:
22932316Syokota		/* EOF */
2302088Ssos		return -1;
23132316Syokota	default:
23232316Syokota		errx(1, "illegal definition line");
23332316Syokota	}
23432316Syokota	return c;
23532316Syokota}
23632316Syokota
23732316Syokotaint
23832316Syokotaget_key_definition_line(keymap_t *map)
23932316Syokota{
24032316Syokota	int i, def, scancode;
24132316Syokota
24232316Syokota	/* check scancode number */
2432088Ssos	if (number < 0 || number >= NUM_KEYS)
2442088Ssos		return -1;
2452088Ssos	scancode = number;
2462088Ssos
2472088Ssos	/* get key definitions */
2482088Ssos	map->key[scancode].spcl = 0;
2492088Ssos	for (i=0; i<NUM_STATES; i++) {
2502088Ssos		if ((def = get_entry()) == -1)
2512088Ssos			return -1;
2522088Ssos		if (def & 0x100)
2532088Ssos			map->key[scancode].spcl |= (0x80 >> i);
2542088Ssos		map->key[scancode].map[i] = def & 0xFF;
2552088Ssos	}
2562088Ssos	/* get lock state key def */
25732316Syokota	if ((token = yylex()) != TFLAG)
2582088Ssos		return -1;
2592088Ssos	map->key[scancode].flgs = number;
26032316Syokota	token = yylex();
26132316Syokota	return (scancode + 1);
2622088Ssos}
2632088Ssos
26432316Syokotaint
26532316Syokotaget_accent_definition_line(accentmap_t *map)
26632316Syokota{
26732316Syokota	int accent;
26832316Syokota	int c1, c2;
26932316Syokota	int i;
2702088Ssos
27132316Syokota	if (ACC(number) < F_ACC || ACC(number) > L_ACC)
27232316Syokota		/* number out of range */
27332316Syokota		return -1;
27432316Syokota	accent = number;
27532316Syokota	if (map->acc[accent].accchar != 0) {
27632316Syokota		/* this entry has already been defined before! */
27732316Syokota		errx(1, "duplicated accent key definition");
27832316Syokota	}
27932316Syokota
28032316Syokota	switch ((token = yylex())) {
28132316Syokota	case TLET:
28232316Syokota		map->acc[accent].accchar = letter;
28332316Syokota		break;
28432316Syokota	case TNUM:
28532316Syokota		map->acc[accent].accchar = number;
28632316Syokota		break;
28732316Syokota	default:
28832316Syokota		return -1;
28932316Syokota	}
29032316Syokota
29132316Syokota	for (i = 0; (token = yylex()) == '(';) {
29232316Syokota		switch ((token = yylex())) {
29332316Syokota		case TLET:
29432316Syokota			c1 = letter;
29532316Syokota			break;
29632316Syokota		case TNUM:
29732316Syokota			c1 = number;
29832316Syokota			break;
29932316Syokota		default:
30032316Syokota			return -1;
30132316Syokota		}
30232316Syokota		switch ((token = yylex())) {
30332316Syokota		case TLET:
30432316Syokota			c2 = letter;
30532316Syokota			break;
30632316Syokota		case TNUM:
30732316Syokota			c2 = number;
30832316Syokota			break;
30932316Syokota		default:
31032316Syokota			return -1;
31132316Syokota		}
31232316Syokota		if ((token = yylex()) != ')')
31332316Syokota			return -1;
31432316Syokota		if (i >= NUM_ACCENTCHARS) {
31532316Syokota			warnx("too many accented characters, ignored");
31632316Syokota			continue;
31732316Syokota		}
31832316Syokota		map->acc[accent].map[i][0] = c1;
31932316Syokota		map->acc[accent].map[i][1] = c2;
32032316Syokota		++i;
32132316Syokota	}
32232316Syokota	return (accent + 1);
32332316Syokota}
32432316Syokota
32529603Scharniervoid
3262088Ssosprint_entry(FILE *fp, int value)
3272088Ssos{
3282088Ssos	int val = value & 0xFF;
3292088Ssos
3302088Ssos	switch (value) {
3312088Ssos	case NOP | 0x100:
3328857Srgrimes		fprintf(fp, " nop   ");
3332088Ssos		break;
3342088Ssos	case LSH | 0x100:
3352088Ssos		fprintf(fp, " lshift");
3362088Ssos		break;
3372088Ssos	case RSH | 0x100:
3382088Ssos		fprintf(fp, " rshift");
3392088Ssos		break;
3402088Ssos	case CLK | 0x100:
3412088Ssos		fprintf(fp, " clock ");
3422088Ssos		break;
3432088Ssos	case NLK | 0x100:
3442088Ssos		fprintf(fp, " nlock ");
3452088Ssos		break;
3462088Ssos	case SLK | 0x100:
3472088Ssos		fprintf(fp, " slock ");
3482088Ssos		break;
3492088Ssos	case BTAB | 0x100:
3502088Ssos		fprintf(fp, " btab  ");
3512088Ssos		break;
3522088Ssos	case LALT | 0x100:
3532088Ssos		fprintf(fp, " lalt  ");
3542088Ssos		break;
3552088Ssos	case LCTR | 0x100:
3562088Ssos		fprintf(fp, " lctrl ");
3572088Ssos		break;
3582088Ssos	case NEXT | 0x100:
3592088Ssos		fprintf(fp, " nscr  ");
3602088Ssos		break;
3612088Ssos	case RCTR | 0x100:
3622088Ssos		fprintf(fp, " rctrl ");
3632088Ssos		break;
3642088Ssos	case RALT | 0x100:
3652088Ssos		fprintf(fp, " ralt  ");
3662088Ssos		break;
3672088Ssos	case ALK | 0x100:
3682088Ssos		fprintf(fp, " alock ");
3692088Ssos		break;
3702088Ssos	case ASH | 0x100:
3712088Ssos		fprintf(fp, " ashift");
3722088Ssos		break;
3732088Ssos	case META | 0x100:
3742088Ssos		fprintf(fp, " meta  ");
3752088Ssos		break;
3762088Ssos	case RBT | 0x100:
3772088Ssos		fprintf(fp, " boot  ");
3782088Ssos		break;
3792088Ssos	case DBG | 0x100:
3802088Ssos		fprintf(fp, " debug ");
3812088Ssos		break;
38232316Syokota	case SUSP | 0x100:
38332316Syokota		fprintf(fp, " susp  ");
38432316Syokota		break;
3852088Ssos	default:
3862088Ssos		if (value & 0x100) {
3878857Srgrimes		 	if (val >= F_FN && val <= L_FN)
3882088Ssos				fprintf(fp, " fkey%02d", val - F_FN + 1);
3898857Srgrimes		 	else if (val >= F_SCR && val <= L_SCR)
3902088Ssos				fprintf(fp, " scr%02d ", val - F_SCR + 1);
39132316Syokota		 	else if (val >= F_ACC && val <= L_ACC)
39232316Syokota				fprintf(fp, " %-6s", acc_names[val - F_ACC]);
3932088Ssos			else if (hex)
3948857Srgrimes				fprintf(fp, " 0x%02x  ", val);
3952088Ssos			else
39632316Syokota				fprintf(fp, " %3d   ", val);
3972088Ssos		}
3982088Ssos		else {
3992088Ssos			if (val < ' ')
4008857Srgrimes				fprintf(fp, " %s   ", ctrl_names[val]);
4012088Ssos			else if (val == 127)
4028857Srgrimes				fprintf(fp, " del   ");
4039202Srgrimes			else if (isascii(val) && isprint(val))
4048857Srgrimes				fprintf(fp, " '%c'   ", val);
4052088Ssos			else if (hex)
4068857Srgrimes				fprintf(fp, " 0x%02x  ", val);
4072088Ssos			else
4088857Srgrimes				fprintf(fp, " %3d   ", val);
4092088Ssos		}
4102088Ssos	}
4112088Ssos}
4122088Ssos
4132088Ssos
4142088Ssosvoid
4152088Ssosprint_key_definition_line(FILE *fp, int scancode, struct key_t *key)
4162088Ssos{
41729603Scharnier	int i;
4182088Ssos
4192088Ssos	/* print scancode number */
4202088Ssos	if (hex)
4212088Ssos		fprintf(fp, " 0x%02x  ", scancode);
4222088Ssos	else
4232088Ssos		fprintf(fp, "  %03d  ", scancode);
4242088Ssos
4252088Ssos	/* print key definitions */
4262088Ssos	for (i=0; i<NUM_STATES; i++) {
4272088Ssos		if (key->spcl & (0x80 >> i))
4282088Ssos			print_entry(fp, key->map[i] | 0x100);
4292088Ssos		else
4308857Srgrimes			print_entry(fp, key->map[i]);
4312088Ssos	}
4322088Ssos
4332088Ssos	/* print lock state key def */
4342088Ssos	switch (key->flgs) {
4352088Ssos	case 0:
4362088Ssos		fprintf(fp, "  O\n");
4372088Ssos		break;
4382088Ssos	case 1:
4392088Ssos		fprintf(fp, "  C\n");
4402088Ssos		break;
4412088Ssos	case 2:
4422088Ssos		fprintf(fp, "  N\n");
4432088Ssos		break;
4446046Ssos	case 3:
4456046Ssos		fprintf(fp, "  B\n");
4466046Ssos		break;
4478857Srgrimes	}
4482088Ssos}
4492088Ssos
45032316Syokotavoid
45132316Syokotaprint_accent_definition_line(FILE *fp, int accent, struct acc_t *key)
45232316Syokota{
45332316Syokota	int c;
45432316Syokota	int i;
4552088Ssos
45632316Syokota	if (key->accchar == 0)
45732316Syokota		return;
45832316Syokota
45932316Syokota	/* print accent number */
46032316Syokota	fprintf(fp, "  %-6s", acc_names[accent]);
46132316Syokota	if (isascii(key->accchar) && isprint(key->accchar))
46232316Syokota		fprintf(fp, "'%c'  ", key->accchar);
46332316Syokota	else if (hex)
46432316Syokota		fprintf(fp, "0x%02x ", key->accchar);
46532316Syokota	else
46632316Syokota		fprintf(fp, "%03d  ", key->accchar);
46732316Syokota
46832316Syokota	for (i = 0; i < NUM_ACCENTCHARS; ++i) {
46932316Syokota		c = key->map[i][0];
47032316Syokota		if (c == 0)
47132316Syokota			break;
47232316Syokota		if ((i > 0) && ((i % 4) == 0))
47332316Syokota			fprintf(fp, "\n             ");
47432316Syokota		if (isascii(c) && isprint(c))
47532316Syokota			fprintf(fp, "( '%c' ", c);
47632316Syokota		else if (hex)
47732316Syokota			fprintf(fp, "(0x%02x ", c);
47832316Syokota		else
47932316Syokota			fprintf(fp, "( %03d ", c);
48032316Syokota		c = key->map[i][1];
48132316Syokota		if (isascii(c) && isprint(c))
48232316Syokota			fprintf(fp, "'%c' ) ", c);
48332316Syokota		else if (hex)
48432316Syokota			fprintf(fp, "0x%02x) ", c);
48532316Syokota		else
48632316Syokota			fprintf(fp, "%03d ) ", c);
48732316Syokota	}
48832316Syokota	fprintf(fp, "\n");
48932316Syokota}
49032316Syokota
4912088Ssosvoid
49232316Syokotadump_entry(int value)
49332316Syokota{
49432316Syokota	if (value & 0x100) {
49532316Syokota		value &= 0x00ff;
49632316Syokota		switch (value) {
49732316Syokota		case NOP:
49832316Syokota			printf("  NOP, ");
49932316Syokota			break;
50032316Syokota		case LSH:
50132316Syokota			printf("  LSH, ");
50232316Syokota			break;
50332316Syokota		case RSH:
50432316Syokota			printf("  RSH, ");
50532316Syokota			break;
50632316Syokota		case CLK:
50732316Syokota			printf("  CLK, ");
50832316Syokota			break;
50932316Syokota		case NLK:
51032316Syokota			printf("  NLK, ");
51132316Syokota			break;
51232316Syokota		case SLK:
51332316Syokota			printf("  SLK, ");
51432316Syokota			break;
51532316Syokota		case BTAB:
51632316Syokota			printf(" BTAB, ");
51732316Syokota			break;
51832316Syokota		case LALT:
51932316Syokota			printf(" LALT, ");
52032316Syokota			break;
52132316Syokota		case LCTR:
52232316Syokota			printf(" LCTR, ");
52332316Syokota			break;
52432316Syokota		case NEXT:
52532316Syokota			printf(" NEXT, ");
52632316Syokota			break;
52732316Syokota		case RCTR:
52832316Syokota			printf(" RCTR, ");
52932316Syokota			break;
53032316Syokota		case RALT:
53132316Syokota			printf(" RALT, ");
53232316Syokota			break;
53332316Syokota		case ALK:
53432316Syokota			printf("  ALK, ");
53532316Syokota			break;
53632316Syokota		case ASH:
53732316Syokota			printf("  ASH, ");
53832316Syokota			break;
53932316Syokota		case META:
54032316Syokota			printf(" META, ");
54132316Syokota			break;
54232316Syokota		case RBT:
54332316Syokota			printf("  RBT, ");
54432316Syokota			break;
54532316Syokota		case DBG:
54632316Syokota			printf("  DBG, ");
54732316Syokota			break;
54832316Syokota		case SUSP:
54932316Syokota			printf(" SUSP, ");
55032316Syokota			break;
55132316Syokota		default:
55232316Syokota	 		if (value >= F_FN && value <= L_FN)
55332316Syokota				printf(" F(%2d),", value - F_FN + 1);
55432316Syokota	 		else if (value >= F_SCR && value <= L_SCR)
55532486Syokota				printf(" S(%2d),", value - F_SCR + 1);
55632316Syokota	 		else if (value >= F_ACC && value <= L_ACC)
55732316Syokota				printf(" %-4s, ", acc_names_u[value - F_ACC]);
55832316Syokota			else
55932316Syokota				printf(" 0x%02X, ", value);
56032316Syokota			break;
56132316Syokota		}
56232316Syokota	} else if (value == '\'') {
56332316Syokota		printf(" '\\'', ");
56432316Syokota	} else if (value == '\\') {
56532316Syokota		printf(" '\\\\', ");
56632316Syokota	} else if (isascii(value) && isprint(value)) {
56732316Syokota		printf("  '%c', ", value);
56832316Syokota	} else {
56932316Syokota		printf(" 0x%02X, ", value);
57032316Syokota	}
57132316Syokota}
57232316Syokota
57332316Syokotavoid
57432316Syokotadump_key_definition(char *name, keymap_t *keymap)
57532316Syokota{
57632316Syokota	int	i, j;
57732316Syokota
57832486Syokota	printf("static keymap_t keymap_%s = { 0x%02x, {\n",
57932316Syokota	       name, (unsigned)keymap->n_keys);
58032316Syokota	printf(
58132486Syokota"/*                                                         alt\n"
58232486Syokota" * scan                       cntrl          alt    alt   cntrl\n"
58332486Syokota" * code  base   shift  cntrl  shift   alt   shift  cntrl  shift    spcl flgs\n"
58432316Syokota" * ---------------------------------------------------------------------------\n"
58532316Syokota" */\n");
58632316Syokota	for (i = 0; i < keymap->n_keys; i++) {
58732486Syokota		printf("/*%02x*/{{", i);
58832316Syokota		for (j = 0; j < NUM_STATES; j++) {
58932316Syokota			if (keymap->key[i].spcl & (0x80 >> j))
59032316Syokota				dump_entry(keymap->key[i].map[j] | 0x100);
59132316Syokota			else
59232316Syokota				dump_entry(keymap->key[i].map[j]);
59332316Syokota		}
59432486Syokota		printf("}, 0x%02X,0x%02X },\n",
59532316Syokota		       (unsigned)keymap->key[i].spcl,
59632316Syokota		       (unsigned)keymap->key[i].flgs);
59732316Syokota	}
59832486Syokota	printf("} };\n\n");
59932316Syokota}
60032316Syokota
60132316Syokotavoid
60232316Syokotadump_accent_definition(char *name, accentmap_t *accentmap)
60332316Syokota{
60432316Syokota	int i, j;
60532316Syokota	int c;
60632316Syokota
60732486Syokota	printf("static accentmap_t accentmap_%s = { %d",
60832316Syokota		name, accentmap->n_accs);
60932486Syokota	if (accentmap->n_accs <= 0) {
61032486Syokota		printf(" };\n\n");
61132486Syokota		return;
61232486Syokota	}
61332486Syokota	printf(", {\n");
61432316Syokota	for (i = 0; i < NUM_DEADKEYS; i++) {
61532316Syokota		printf("    /* %s=%d */\n    {", acc_names[i], i);
61632316Syokota		c = accentmap->acc[i].accchar;
61732316Syokota		if (c == '\'')
61832316Syokota			printf(" '\\'', {");
61932316Syokota		else if (c == '\\')
62032316Syokota			printf(" '\\\\', {");
62132316Syokota		else if (isascii(c) && isprint(c))
62232316Syokota			printf("  '%c', {", c);
62332316Syokota		else if (c == 0) {
62432316Syokota			printf(" 0x00 }, \n");
62532316Syokota			continue;
62632316Syokota		} else
62732316Syokota			printf(" 0x%02x, {", c);
62832316Syokota		for (j = 0; j < NUM_ACCENTCHARS; j++) {
62932316Syokota			c = accentmap->acc[i].map[j][0];
63032316Syokota			if (c == 0)
63132316Syokota				break;
63232316Syokota			if ((j > 0) && ((j % 4) == 0))
63332316Syokota				printf("\n\t     ");
63432316Syokota			if (isascii(c) && isprint(c))
63532316Syokota				printf(" {  '%c',", c);
63632316Syokota			else
63732316Syokota				printf(" { 0x%02x,", c);
63832316Syokota			printf("0x%02x },", accentmap->acc[i].map[j][1]);
63932316Syokota		}
64032316Syokota		printf(" }, },\n");
64132316Syokota	}
64232486Syokota	printf("} };\n\n");
64332316Syokota}
64432316Syokota
64532316Syokotavoid
64619569Sjoergload_keymap(char *opt, int dumponly)
6472088Ssos{
64832316Syokota	keymap_t keymap;
64932316Syokota	accentmap_t accentmap;
6502088Ssos	FILE	*fd;
65132316Syokota	int	i;
65219569Sjoerg	char	*name, *cp;
6532088Ssos	char	*prefix[]  = {"", "", KEYMAP_PATH, NULL};
6542088Ssos	char	*postfix[] = {"", ".kbd", ".kbd"};
6552088Ssos
6562088Ssos	for (i=0; prefix[i]; i++) {
6572088Ssos		name = mkfullname(prefix[i], opt, postfix[i]);
65829603Scharnier		if ((fd = fopen(name, "r")))
6592088Ssos			break;
6602088Ssos	}
6612088Ssos	if (fd == NULL) {
66229603Scharnier		warn("keymap file not found");
6632088Ssos		return;
6642088Ssos	}
66532316Syokota	memset(&keymap, 0, sizeof(keymap));
66632316Syokota	memset(&accentmap, 0, sizeof(accentmap));
66732316Syokota	token = -1;
6682088Ssos	while (1) {
66932316Syokota		if (get_definition_line(fd, &keymap, &accentmap) < 0)
6702088Ssos			break;
6712088Ssos    	}
67219569Sjoerg	if (dumponly) {
67319569Sjoerg		/* fix up the filename to make it a valid C identifier */
67419569Sjoerg		for (cp = opt; *cp; cp++)
67519569Sjoerg			if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_';
67632316Syokota		printf("/*\n"
67732316Syokota		       " * Automatically generated from %s.\n"
67832316Syokota	               " * DO NOT EDIT!\n"
67932316Syokota		       " */\n", name);
68032316Syokota		dump_key_definition(opt, &keymap);
68132316Syokota		dump_accent_definition(opt, &accentmap);
68219569Sjoerg		return;
68319569Sjoerg	}
68432316Syokota	if ((keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) {
68529603Scharnier		warn("setting keymap");
6862088Ssos		fclose(fd);
6872088Ssos		return;
6882088Ssos	}
68932316Syokota	if ((accentmap.n_accs > 0)
69032316Syokota		&& (ioctl(0, PIO_DEADKEYMAP, &accentmap) < 0)) {
69132316Syokota		warn("setting accentmap");
69232316Syokota		fclose(fd);
69332316Syokota		return;
69432316Syokota	}
6952088Ssos}
6962088Ssos
6972088Ssosvoid
6982088Ssosprint_keymap()
6992088Ssos{
70032316Syokota	keymap_t keymap;
70132316Syokota	accentmap_t accentmap;
7022088Ssos	int i;
7032088Ssos
70432316Syokota	if (ioctl(0, GIO_KEYMAP, &keymap) < 0)
70529603Scharnier		err(1, "getting keymap");
70632316Syokota	if (ioctl(0, GIO_DEADKEYMAP, &accentmap) < 0)
70732316Syokota		memset(&accentmap, 0, sizeof(accentmap));
7082088Ssos    	printf(
7092088Ssos"#                                                         alt\n"
7102088Ssos"# scan                       cntrl          alt    alt   cntrl lock\n"
7112088Ssos"# code  base   shift  cntrl  shift  alt    shift  cntrl  shift state\n"
7122088Ssos"# ------------------------------------------------------------------\n"
7132088Ssos    	);
71432316Syokota	for (i=0; i<keymap.n_keys; i++)
71532316Syokota		print_key_definition_line(stdout, i, &keymap.key[i]);
71632316Syokota
71732316Syokota	printf("\n");
71832316Syokota	for (i = 0; i < NUM_DEADKEYS; i++)
71932316Syokota		print_accent_definition_line(stdout, i, &accentmap.acc[i]);
72032316Syokota
7212088Ssos}
7222088Ssos
7232088Ssos
7242088Ssosvoid
7252088Ssosload_default_functionkeys()
7262088Ssos{
7272088Ssos	fkeyarg_t fkey;
7282088Ssos	int i;
7292088Ssos
7302088Ssos	for (i=0; i<NUM_FKEYS; i++) {
7312088Ssos		fkey.keynum = i;
7322088Ssos		strcpy(fkey.keydef, fkey_table[i]);
7332088Ssos		fkey.flen = strlen(fkey_table[i]);
7342088Ssos		if (ioctl(0, SETFKEY, &fkey) < 0)
73529603Scharnier			warn("setting function key");
7362088Ssos	}
7372088Ssos}
7382088Ssos
7392088Ssosvoid
7402088Ssosset_functionkey(char *keynumstr, char *string)
7412088Ssos{
7422088Ssos	fkeyarg_t fkey;
7432088Ssos
7442088Ssos	if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) {
7452088Ssos		load_default_functionkeys();
7462088Ssos		return;
7472088Ssos	}
7482088Ssos	fkey.keynum = atoi(keynumstr);
7492088Ssos	if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) {
75029603Scharnier		warnx("function key number must be between 1 and %d",
7512088Ssos			NUM_FKEYS);
7522088Ssos		return;
7532088Ssos	}
7542088Ssos	if ((fkey.flen = strlen(string)) > MAXFK) {
75529603Scharnier		warnx("function key string too long (%d > %d)",
7562088Ssos			fkey.flen, MAXFK);
7572088Ssos		return;
7582088Ssos	}
7592088Ssos	strcpy(fkey.keydef, string);
7602088Ssos	fkey.keynum -= 1;
7612088Ssos	if (ioctl(0, SETFKEY, &fkey) < 0)
76229603Scharnier		warn("setting function key");
7632088Ssos}
7642088Ssos
7652088Ssos
7662088Ssosvoid
7672088Ssosset_bell_values(char *opt)
7682088Ssos{
7695536Ssos	int bell, duration, pitch;
7702088Ssos
7718857Srgrimes	if (!strcmp(opt, "visual"))
7725536Ssos		bell = 1, duration = 1, pitch = 800;
7735536Ssos	else if (!strcmp(opt, "normal"))
7745536Ssos		bell = 0, duration = 1, pitch = 800;
7752088Ssos	else {
7762088Ssos		char		*v1;
7778857Srgrimes
7785536Ssos		bell = 0;
7792088Ssos		duration = strtol(opt, &v1, 0);
7802088Ssos		if ((duration < 0) || (*v1 != '.'))
7812088Ssos			goto badopt;
7822088Ssos		opt = ++v1;
7832088Ssos		pitch = strtol(opt, &v1, 0);
7842088Ssos		if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) {
7852088Ssosbadopt:
78629603Scharnier			warnx("argument to -b must be DURATION.PITCH");
7872088Ssos			return;
7882088Ssos		}
7892088Ssos	}
7902088Ssos
7915536Ssos	ioctl(0, CONS_BELLTYPE, &bell);
7925536Ssos	if (!bell)
7935536Ssos		fprintf(stderr, "[=%d;%dB", pitch, duration);
7942088Ssos}
7952088Ssos
7962088Ssos
7972088Ssosvoid
7982088Ssosset_keyrates(char *opt)
7992088Ssos{
8002088Ssosstruct	{
8012088Ssos	int	rep:5;
8022088Ssos	int	del:2;
8032088Ssos	int	pad:1;
8042088Ssos	}rate;
8052088Ssos
8062088Ssos	if (!strcmp(opt, "slow"))
8072088Ssos		rate.del = 3, rate.rep = 31;
8082088Ssos	else if (!strcmp(opt, "normal"))
8092088Ssos		rate.del = 1, rate.rep = 15;
8102088Ssos	else if (!strcmp(opt, "fast"))
8112088Ssos		rate.del = rate.rep = 0;
8122088Ssos	else {
8132088Ssos		int		n;
8142088Ssos		int		delay, repeat;
8152088Ssos		char		*v1;
8162088Ssos
8172088Ssos		delay = strtol(opt, &v1, 0);
8182088Ssos		if ((delay < 0) || (*v1 != '.'))
8192088Ssos			goto badopt;
8202088Ssos		opt = ++v1;
8212088Ssos		repeat = strtol(opt, &v1, 0);
8222088Ssos		if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) {
8232088Ssosbadopt:
82429603Scharnier			warnx("argument to -r must be delay.repeat");
8252088Ssos			return;
8262088Ssos		}
8272088Ssos		for (n = 0; n < ndelays - 1; n++)
8282088Ssos			if (delay <= delays[n])
8292088Ssos				break;
8302088Ssos		rate.del = n;
8312088Ssos		for (n = 0; n < nrepeats - 1; n++)
8322088Ssos			if (repeat <= repeats[n])
8332088Ssos				break;
8342088Ssos		rate.rep = n;
8352088Ssos	}
8362088Ssos
8372088Ssos	if (ioctl(0, KDSETRAD, rate) < 0)
83829603Scharnier		warn("setting keyboard rate");
8392088Ssos}
8402088Ssos
8412088Ssos
8426046Ssosvoid
8436046Ssosset_history(char *opt)
8446046Ssos{
8456046Ssos	int size;
8466046Ssos
8476046Ssos	size = atoi(opt);
8486046Ssos	if ((*opt == '\0') || size < 0) {
84929603Scharnier		warnx("argument must be a positive number");
8506046Ssos		return;
8516046Ssos	}
8526046Ssos	if (ioctl(0, CONS_HISTORY, &size) == -1)
85329603Scharnier		warn("setting history buffer size");
8546046Ssos}
8556046Ssos
8566046Ssos
85729603Scharnierstatic void
8582088Ssosusage()
8592088Ssos{
86029603Scharnier	fprintf(stderr, "%s\n%s\n%s\n",
86129603Scharnier"usage: kbdcontrol [-dFx] [-b  duration.pitch | belltype]",
86229603Scharnier"                  [-r delay.repeat | speed] [-l mapfile] [-f # string]",
86329603Scharnier"                  [-h size] [-L mapfile]");
86429603Scharnier	exit(1);
8652088Ssos}
8662088Ssos
8672088Ssos
8682088Ssosvoid
8692088Ssosmain(int argc, char **argv)
8702088Ssos{
8712088Ssos	int		opt;
8722088Ssos
87319569Sjoerg	while((opt = getopt(argc, argv, "b:df:h:Fl:L:r:x")) != -1)
8742088Ssos		switch(opt) {
8752088Ssos			case 'b':
8762088Ssos				set_bell_values(optarg);
8772088Ssos				break;
8782088Ssos			case 'd':
8792088Ssos				print_keymap();
8802088Ssos				break;
8812088Ssos			case 'l':
88219569Sjoerg				load_keymap(optarg, 0);
8832088Ssos				break;
88419569Sjoerg			case 'L':
88519569Sjoerg				load_keymap(optarg, 1);
88619569Sjoerg				break;
8872088Ssos			case 'f':
8888857Srgrimes				set_functionkey(optarg,
8892088Ssos					nextarg(argc, argv, &optind, 'f'));
8902088Ssos				break;
8912088Ssos			case 'F':
8922088Ssos				load_default_functionkeys();
8932088Ssos				break;
8946046Ssos			case 'h':
8956046Ssos				set_history(optarg);
8966046Ssos				break;
8972088Ssos			case 'r':
8982088Ssos				set_keyrates(optarg);
8992088Ssos				break;
9002088Ssos			case 'x':
9012088Ssos				hex = 1;
9022088Ssos				break;
9032088Ssos			default:
9042088Ssos				usage();
9052088Ssos		}
90629603Scharnier	if ((optind != argc) || (argc == 1))
9072088Ssos		usage();
9082088Ssos	exit(0);
9092088Ssos}
9102088Ssos
9112088Ssos
912