kbdcontrol.c revision 19569
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 *
2819569Sjoerg *	$Id: kbdcontrol.c,v 1.7 1995/06/11 19:32:41 rgrimes Exp $
292088Ssos */
302088Ssos
312088Ssos#include <ctype.h>
322088Ssos#include <stdio.h>
333864Sswallace#include <string.h>
342088Ssos#include <machine/console.h>
352088Ssos#include "path.h"
362088Ssos#include "lex.h"
372088Ssos
382088Ssoschar ctrl_names[32][4] = {
398857Srgrimes	"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
402088Ssos	"bs ", "ht ", "nl ", "vt ", "ff ", "cr ", "so ", "si ",
412088Ssos	"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
422088Ssos	"can", "em ", "sub", "esc", "fs ", "gs ", "rs ", "ns "
432088Ssos	};
442088Ssos
455994Ssoschar fkey_table[96][MAXFK] = {
465994Ssos/* 01-04 */	"\033[M", "\033[N", "\033[O", "\033[P",
475994Ssos/* 05-08 */	"\033[Q", "\033[R", "\033[S", "\033[T",
485994Ssos/* 09-12 */	"\033[U", "\033[V", "\033[W", "\033[X",
495994Ssos/* 13-16 */	"\033[Y", "\033[Z", "\033[a", "\033[b",
505994Ssos/* 17-20 */	"\033[c", "\033[d", "\033[e", "\033[f",
515994Ssos/* 21-24 */	"\033[g", "\033[h", "\033[i", "\033[j",
525994Ssos/* 25-28 */	"\033[k", "\033[l", "\033[m", "\033[n",
535994Ssos/* 29-32 */	"\033[o", "\033[p", "\033[q", "\033[r",
545994Ssos/* 33-36 */	"\033[s", "\033[t", "\033[u", "\033[v",
555994Ssos/* 37-40 */	"\033[w", "\033[x", "\033[y", "\033[z",
565994Ssos/* 41-44 */	"\033[@", "\033[[", "\033[\\","\033[]",
579202Srgrimes/* 45-48 */     "\033[^", "\033[_", "\033[`", "\033[{",
585994Ssos/* 49-52 */	"\033[H", "\033[A", "\033[I", "-"     ,
595994Ssos/* 53-56 */	"\033[D", "\033[E", "\033[C", "+"     ,
605994Ssos/* 57-60 */	"\033[F", "\033[B", "\033[G", "\033[L",
619202Srgrimes/* 61-64 */     "\177",   "\033[J", "\033[~", "\033[}",
625994Ssos/* 65-68 */	""      , ""      , ""      , ""      ,
635994Ssos/* 69-72 */	""      , ""      , ""      , ""      ,
645994Ssos/* 73-76 */	""      , ""      , ""      , ""      ,
655994Ssos/* 77-80 */	""      , ""      , ""      , ""      ,
665994Ssos/* 81-84 */	""      , ""      , ""      , ""      ,
675994Ssos/* 85-88 */	""      , ""      , ""      , ""      ,
685994Ssos/* 89-92 */	""      , ""      , ""      , ""      ,
695994Ssos/* 93-96 */	""      , ""      , ""      , ""      ,
702088Ssos	};
712088Ssos
722088Ssosconst int	delays[]  = {250, 500, 750, 1000};
732088Ssosconst int	repeats[] = { 34,  38,  42,  46,  50,  55,  59,  63,
742088Ssos			      68,  76,  84,  92, 100, 110, 118, 126,
752088Ssos			     136, 152, 168, 184, 200, 220, 236, 252,
762088Ssos			     272, 304, 336, 368, 400, 440, 472, 504};
772088Ssosconst int	ndelays = (sizeof(delays) / sizeof(int));
782088Ssosconst int	nrepeats = (sizeof(repeats) / sizeof(int));
792088Ssosint 		hex = 0;
806046Ssosint 		number;
812088Ssoschar 		letter;
822088Ssos
832088Ssos
842088Ssoschar *
852088Ssosnextarg(int ac, char **av, int *indp, int oc)
862088Ssos{
872088Ssos	if (*indp < ac)
882088Ssos		return(av[(*indp)++]);
892088Ssos	fprintf(stderr, "%s: option requires two arguments -- %c\n", av[0], oc);
902088Ssos	usage();
912088Ssos	exit(1);
922088Ssos	return("");
932088Ssos}
942088Ssos
952088Ssos
962088Ssoschar *
972088Ssosmkfullname(const char *s1, const char *s2, const char *s3)
982088Ssos{
995536Ssos	static char	*buf = NULL;
1005536Ssos	static int	bufl = 0;
1015536Ssos	int		f;
1022088Ssos
1032088Ssos	f = strlen(s1) + strlen(s2) + strlen(s3) + 1;
1042088Ssos	if (f > bufl)
1052088Ssos		if (buf)
1062088Ssos			buf = (char *)realloc(buf, f);
1072088Ssos		else
1082088Ssos			buf = (char *)malloc(f);
1092088Ssos	if (!buf) {
1102088Ssos		bufl = 0;
1112088Ssos		return(NULL);
1122088Ssos	}
1132088Ssos
1142088Ssos	bufl = f;
1152088Ssos	strcpy(buf, s1);
1162088Ssos	strcat(buf, s2);
1172088Ssos	strcat(buf, s3);
1182088Ssos	return(buf);
1192088Ssos}
1202088Ssos
1212088Ssos
1222088Ssosint
1232088Ssosget_entry()
1242088Ssos{
1252088Ssos	switch (yylex()) {
1262088Ssos	case TNOP:
1272088Ssos		return NOP | 0x100;
1282088Ssos	case TLSH:
1292088Ssos		return LSH | 0x100;
1302088Ssos	case TRSH:
1312088Ssos		return RSH | 0x100;
1322088Ssos	case TCLK:
1332088Ssos		return CLK | 0x100;
1342088Ssos	case TNLK:
1352088Ssos		return NLK | 0x100;
1362088Ssos	case TSLK:
1372088Ssos		return SLK | 0x100;
1382088Ssos	case TBTAB:
1392088Ssos		return BTAB | 0x100;
1402088Ssos	case TLALT:
1412088Ssos		return LALT | 0x100;
1422088Ssos	case TLCTR:
1432088Ssos		return LCTR | 0x100;
1442088Ssos	case TNEXT:
1452088Ssos		return NEXT | 0x100;
1462088Ssos	case TRCTR:
1472088Ssos		return RCTR | 0x100;
1482088Ssos	case TRALT:
1492088Ssos		return RALT | 0x100;
1502088Ssos	case TALK:
1512088Ssos		return ALK | 0x100;
1522088Ssos	case TASH:
1532088Ssos		return ASH | 0x100;
1542088Ssos	case TMETA:
1552088Ssos		return META | 0x100;
1562088Ssos	case TRBT:
1572088Ssos		return RBT | 0x100;
1582088Ssos	case TDBG:
1592088Ssos		return DBG | 0x100;
1605994Ssos	case TSUSP:
1615994Ssos		return SUSP | 0x100;
1622088Ssos	case TFUNC:
1632088Ssos		if (F(number) > L_FN)
1642088Ssos			return -1;
1652088Ssos		return F(number) | 0x100;
1662088Ssos	case TSCRN:
1672088Ssos		if (S(number) > L_SCR)
1682088Ssos			return -1;
1692088Ssos		return S(number) | 0x100;
1702088Ssos	case TLET:
1712088Ssos		return (unsigned char)letter;
1722088Ssos	case TNUM:
1732088Ssos		if (number < 0 || number > 255)
1742088Ssos			return -1;
1752088Ssos		return number;
1762088Ssos	default:
1772088Ssos		return -1;
1782088Ssos	}
1792088Ssos}
1802088Ssos
1818857Srgrimes
1822088Ssosint
1832088Ssosget_key_definition_line(FILE* fd, keymap_t *map)
1842088Ssos{
1852088Ssos	int i, def, scancode;
1862088Ssos
1872088Ssos	yyin = fd;
1882088Ssos
1892088Ssos	/* get scancode number */
1908857Srgrimes	if (yylex() != TNUM)
1912088Ssos		return -1;
1922088Ssos	if (number < 0 || number >= NUM_KEYS)
1932088Ssos		return -1;
1942088Ssos	scancode = number;
1952088Ssos
1962088Ssos	/* get key definitions */
1972088Ssos	map->key[scancode].spcl = 0;
1982088Ssos	for (i=0; i<NUM_STATES; i++) {
1992088Ssos		if ((def = get_entry()) == -1)
2002088Ssos			return -1;
2012088Ssos		if (def & 0x100)
2022088Ssos			map->key[scancode].spcl |= (0x80 >> i);
2032088Ssos		map->key[scancode].map[i] = def & 0xFF;
2042088Ssos	}
2052088Ssos	/* get lock state key def */
2062088Ssos	if (yylex() != TFLAG)
2072088Ssos		return -1;
2082088Ssos	map->key[scancode].flgs = number;
2092088Ssos		return scancode;
2102088Ssos}
2112088Ssos
2122088Ssos
2138857Srgrimesint
2142088Ssosprint_entry(FILE *fp, int value)
2152088Ssos{
2162088Ssos	int val = value & 0xFF;
2172088Ssos
2182088Ssos	switch (value) {
2192088Ssos	case NOP | 0x100:
2208857Srgrimes		fprintf(fp, " nop   ");
2212088Ssos		break;
2222088Ssos	case LSH | 0x100:
2232088Ssos		fprintf(fp, " lshift");
2242088Ssos		break;
2252088Ssos	case RSH | 0x100:
2262088Ssos		fprintf(fp, " rshift");
2272088Ssos		break;
2282088Ssos	case CLK | 0x100:
2292088Ssos		fprintf(fp, " clock ");
2302088Ssos		break;
2312088Ssos	case NLK | 0x100:
2322088Ssos		fprintf(fp, " nlock ");
2332088Ssos		break;
2342088Ssos	case SLK | 0x100:
2352088Ssos		fprintf(fp, " slock ");
2362088Ssos		break;
2372088Ssos	case BTAB | 0x100:
2382088Ssos		fprintf(fp, " btab  ");
2392088Ssos		break;
2402088Ssos	case LALT | 0x100:
2412088Ssos		fprintf(fp, " lalt  ");
2422088Ssos		break;
2432088Ssos	case LCTR | 0x100:
2442088Ssos		fprintf(fp, " lctrl ");
2452088Ssos		break;
2462088Ssos	case NEXT | 0x100:
2472088Ssos		fprintf(fp, " nscr  ");
2482088Ssos		break;
2492088Ssos	case RCTR | 0x100:
2502088Ssos		fprintf(fp, " rctrl ");
2512088Ssos		break;
2522088Ssos	case RALT | 0x100:
2532088Ssos		fprintf(fp, " ralt  ");
2542088Ssos		break;
2552088Ssos	case ALK | 0x100:
2562088Ssos		fprintf(fp, " alock ");
2572088Ssos		break;
2582088Ssos	case ASH | 0x100:
2592088Ssos		fprintf(fp, " ashift");
2602088Ssos		break;
2612088Ssos	case META | 0x100:
2622088Ssos		fprintf(fp, " meta  ");
2632088Ssos		break;
2642088Ssos	case RBT | 0x100:
2652088Ssos		fprintf(fp, " boot  ");
2662088Ssos		break;
2672088Ssos	case DBG | 0x100:
2682088Ssos		fprintf(fp, " debug ");
2692088Ssos		break;
2702088Ssos	default:
2712088Ssos		if (value & 0x100) {
2728857Srgrimes		 	if (val >= F_FN && val <= L_FN)
2732088Ssos				fprintf(fp, " fkey%02d", val - F_FN + 1);
2748857Srgrimes		 	else if (val >= F_SCR && val <= L_SCR)
2752088Ssos				fprintf(fp, " scr%02d ", val - F_SCR + 1);
2762088Ssos			else if (hex)
2778857Srgrimes				fprintf(fp, " 0x%02x  ", val);
2782088Ssos			else
2798857Srgrimes				fprintf(fp, "  %3d  ", val);
2802088Ssos		}
2812088Ssos		else {
2822088Ssos			if (val < ' ')
2838857Srgrimes				fprintf(fp, " %s   ", ctrl_names[val]);
2842088Ssos			else if (val == 127)
2858857Srgrimes				fprintf(fp, " del   ");
2869202Srgrimes			else if (isascii(val) && isprint(val))
2878857Srgrimes				fprintf(fp, " '%c'   ", val);
2882088Ssos			else if (hex)
2898857Srgrimes				fprintf(fp, " 0x%02x  ", val);
2902088Ssos			else
2918857Srgrimes				fprintf(fp, " %3d   ", val);
2922088Ssos		}
2932088Ssos	}
2942088Ssos}
2952088Ssos
2962088Ssos
2972088Ssosvoid
2982088Ssosprint_key_definition_line(FILE *fp, int scancode, struct key_t *key)
2992088Ssos{
3002088Ssos	int i, value;
3012088Ssos
3022088Ssos	/* print scancode number */
3032088Ssos	if (hex)
3042088Ssos		fprintf(fp, " 0x%02x  ", scancode);
3052088Ssos	else
3062088Ssos		fprintf(fp, "  %03d  ", scancode);
3072088Ssos
3082088Ssos	/* print key definitions */
3092088Ssos	for (i=0; i<NUM_STATES; i++) {
3102088Ssos		if (key->spcl & (0x80 >> i))
3112088Ssos			print_entry(fp, key->map[i] | 0x100);
3122088Ssos		else
3138857Srgrimes			print_entry(fp, key->map[i]);
3142088Ssos	}
3152088Ssos
3162088Ssos	/* print lock state key def */
3172088Ssos	switch (key->flgs) {
3182088Ssos	case 0:
3192088Ssos		fprintf(fp, "  O\n");
3202088Ssos		break;
3212088Ssos	case 1:
3222088Ssos		fprintf(fp, "  C\n");
3232088Ssos		break;
3242088Ssos	case 2:
3252088Ssos		fprintf(fp, "  N\n");
3262088Ssos		break;
3276046Ssos	case 3:
3286046Ssos		fprintf(fp, "  B\n");
3296046Ssos		break;
3308857Srgrimes	}
3312088Ssos}
3322088Ssos
3332088Ssos
3342088Ssosvoid
33519569Sjoergload_keymap(char *opt, int dumponly)
3362088Ssos{
3372088Ssos	keymap_t map;
3382088Ssos	FILE	*fd;
33919569Sjoerg	int	scancode, i, j;
34019569Sjoerg	struct key_t *kp;
34119569Sjoerg	char	*name, *cp;
3422088Ssos	char	*prefix[]  = {"", "", KEYMAP_PATH, NULL};
3432088Ssos	char	*postfix[] = {"", ".kbd", ".kbd"};
3442088Ssos
3452088Ssos	for (i=0; prefix[i]; i++) {
3462088Ssos		name = mkfullname(prefix[i], opt, postfix[i]);
3472088Ssos		if (fd = fopen(name, "r"))
3482088Ssos			break;
3492088Ssos	}
3502088Ssos	if (fd == NULL) {
3512088Ssos		perror("keymap file not found");
3522088Ssos		return;
3532088Ssos	}
3543864Sswallace	memset(&map, 0, sizeof(map));
3552088Ssos	while (1) {
3562088Ssos		if ((scancode = get_key_definition_line(fd, &map)) < 0)
3572088Ssos			break;
3582088Ssos		if (scancode > map.n_keys) map.n_keys = scancode;
3592088Ssos    	}
36019569Sjoerg	if (dumponly) {
36119569Sjoerg		/* fix up the filename to make it a valid C identifier */
36219569Sjoerg		for (cp = opt; *cp; cp++)
36319569Sjoerg			if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_';
36419569Sjoerg		printf("static const struct keymap keymap_%s = {\n"
36519569Sjoerg		       "/*\n * Automatically generated from %s.\n"
36619569Sjoerg		       " * DO NOT EDIT!\n */\n\n\t%u,\n{\n",
36719569Sjoerg		       opt, name, (unsigned)map.n_keys);
36819569Sjoerg		for (i = 0; i < map.n_keys; i++) {
36919569Sjoerg			kp = &map.key[i];
37019569Sjoerg
37119569Sjoerg			printf("\t{{ ");
37219569Sjoerg			for (j = 0; j < NUM_STATES; j++)
37319569Sjoerg				printf("0x%02x%c", (unsigned)kp->map[j],
37419569Sjoerg					j == NUM_STATES-1? '}': ',');
37519569Sjoerg			printf(", 0x%x, 0x%x },\n",
37619569Sjoerg			       (unsigned)kp->spcl, (unsigned)kp->flgs);
37719569Sjoerg		}
37819569Sjoerg		printf("}\n};\n\n");
37919569Sjoerg		return;
38019569Sjoerg	}
3812088Ssos	if (ioctl(0, PIO_KEYMAP, &map) < 0) {
3822088Ssos		perror("setting keymap");
3832088Ssos		fclose(fd);
3842088Ssos		return;
3852088Ssos	}
3862088Ssos}
3872088Ssos
3882088Ssos
3892088Ssosvoid
3902088Ssosprint_keymap()
3912088Ssos{
3922088Ssos	keymap_t map;
3932088Ssos	int i;
3942088Ssos
3952088Ssos	if (ioctl(0, GIO_KEYMAP, &map) < 0) {
3962088Ssos		perror("getting keymap");
3972088Ssos		exit(1);
3982088Ssos	}
3992088Ssos    	printf(
4002088Ssos"#                                                         alt\n"
4012088Ssos"# scan                       cntrl          alt    alt   cntrl lock\n"
4022088Ssos"# code  base   shift  cntrl  shift  alt    shift  cntrl  shift state\n"
4032088Ssos"# ------------------------------------------------------------------\n"
4042088Ssos    	);
4052088Ssos	for (i=0; i<map.n_keys; i++)
4062088Ssos		print_key_definition_line(stdout, i, &map.key[i]);
4072088Ssos}
4082088Ssos
4092088Ssos
4102088Ssosvoid
4112088Ssosload_default_functionkeys()
4122088Ssos{
4132088Ssos	fkeyarg_t fkey;
4142088Ssos	int i;
4152088Ssos
4162088Ssos	for (i=0; i<NUM_FKEYS; i++) {
4172088Ssos		fkey.keynum = i;
4182088Ssos		strcpy(fkey.keydef, fkey_table[i]);
4192088Ssos		fkey.flen = strlen(fkey_table[i]);
4202088Ssos		if (ioctl(0, SETFKEY, &fkey) < 0)
4212088Ssos			perror("setting function key");
4222088Ssos	}
4232088Ssos}
4242088Ssos
4252088Ssosvoid
4262088Ssosset_functionkey(char *keynumstr, char *string)
4272088Ssos{
4282088Ssos	fkeyarg_t fkey;
4292088Ssos	int keynum;
4302088Ssos
4312088Ssos	if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) {
4322088Ssos		load_default_functionkeys();
4332088Ssos		return;
4342088Ssos	}
4352088Ssos	fkey.keynum = atoi(keynumstr);
4362088Ssos	if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) {
4378857Srgrimes		fprintf(stderr,
4382088Ssos			"function key number must be between 1 and %d\n",
4392088Ssos			NUM_FKEYS);
4402088Ssos		return;
4412088Ssos	}
4422088Ssos	if ((fkey.flen = strlen(string)) > MAXFK) {
4432088Ssos		fprintf(stderr, "function key string too long (%d > %d)\n",
4442088Ssos			fkey.flen, MAXFK);
4452088Ssos		return;
4462088Ssos	}
4472088Ssos	strcpy(fkey.keydef, string);
4482088Ssos	fkey.keynum -= 1;
4492088Ssos	if (ioctl(0, SETFKEY, &fkey) < 0)
4502088Ssos		perror("setting function key");
4512088Ssos}
4522088Ssos
4532088Ssos
4542088Ssosvoid
4552088Ssosset_bell_values(char *opt)
4562088Ssos{
4575536Ssos	int bell, duration, pitch;
4582088Ssos
4598857Srgrimes	if (!strcmp(opt, "visual"))
4605536Ssos		bell = 1, duration = 1, pitch = 800;
4615536Ssos	else if (!strcmp(opt, "normal"))
4625536Ssos		bell = 0, duration = 1, pitch = 800;
4632088Ssos	else {
4642088Ssos		int		n;
4652088Ssos		char		*v1;
4668857Srgrimes
4675536Ssos		bell = 0;
4682088Ssos		duration = strtol(opt, &v1, 0);
4692088Ssos		if ((duration < 0) || (*v1 != '.'))
4702088Ssos			goto badopt;
4712088Ssos		opt = ++v1;
4722088Ssos		pitch = strtol(opt, &v1, 0);
4732088Ssos		if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) {
4742088Ssosbadopt:
4758857Srgrimes			fprintf(stderr,
4762088Ssos				"argument to -b must be DURATION.PITCH\n");
4772088Ssos			return;
4782088Ssos		}
4792088Ssos	}
4802088Ssos
4815536Ssos	ioctl(0, CONS_BELLTYPE, &bell);
4825536Ssos	if (!bell)
4835536Ssos		fprintf(stderr, "[=%d;%dB", pitch, duration);
4842088Ssos}
4852088Ssos
4862088Ssos
4872088Ssosvoid
4882088Ssosset_keyrates(char *opt)
4892088Ssos{
4902088Ssosstruct	{
4912088Ssos	int	rep:5;
4922088Ssos	int	del:2;
4932088Ssos	int	pad:1;
4942088Ssos	}rate;
4952088Ssos
4962088Ssos	if (!strcmp(opt, "slow"))
4972088Ssos		rate.del = 3, rate.rep = 31;
4982088Ssos	else if (!strcmp(opt, "normal"))
4992088Ssos		rate.del = 1, rate.rep = 15;
5002088Ssos	else if (!strcmp(opt, "fast"))
5012088Ssos		rate.del = rate.rep = 0;
5022088Ssos	else {
5032088Ssos		int		n;
5042088Ssos		int		delay, repeat;
5052088Ssos		char		*v1;
5062088Ssos
5072088Ssos		delay = strtol(opt, &v1, 0);
5082088Ssos		if ((delay < 0) || (*v1 != '.'))
5092088Ssos			goto badopt;
5102088Ssos		opt = ++v1;
5112088Ssos		repeat = strtol(opt, &v1, 0);
5122088Ssos		if ((repeat < 0) || (*opt == '\0') || (*v1 != '\0')) {
5132088Ssosbadopt:
5148857Srgrimes			fprintf(stderr,
5152088Ssos				"argument to -r must be delay.repeat\n");
5162088Ssos			return;
5172088Ssos		}
5182088Ssos		for (n = 0; n < ndelays - 1; n++)
5192088Ssos			if (delay <= delays[n])
5202088Ssos				break;
5212088Ssos		rate.del = n;
5222088Ssos		for (n = 0; n < nrepeats - 1; n++)
5232088Ssos			if (repeat <= repeats[n])
5242088Ssos				break;
5252088Ssos		rate.rep = n;
5262088Ssos	}
5272088Ssos
5282088Ssos	if (ioctl(0, KDSETRAD, rate) < 0)
5292088Ssos		perror("setting keyboard rate");
5302088Ssos}
5312088Ssos
5322088Ssos
5336046Ssosvoid
5346046Ssosset_history(char *opt)
5356046Ssos{
5366046Ssos	int size;
5376046Ssos
5386046Ssos	size = atoi(opt);
5396046Ssos	if ((*opt == '\0') || size < 0) {
5406046Ssos		fprintf(stderr, "argument must be a positive number\n");
5416046Ssos		return;
5426046Ssos	}
5436046Ssos	if (ioctl(0, CONS_HISTORY, &size) == -1)
5446046Ssos		perror("setting history buffer size");
5456046Ssos}
5466046Ssos
5476046Ssos
5482088Ssosusage()
5492088Ssos{
5502088Ssos	fprintf(stderr,
5515536Ssos"Usage: kbdcontrol -b duration.pitch   (set bell duration & pitch)\n"
5525536Ssos"                  -b normal | visual  (set bell to visual type)\n"
5535536Ssos"                  -d                  (dump keyboard map to stdout)\n"
5545536Ssos"                  -l filename         (load keyboard map file)\n"
5556046Ssos"                  -h <N>              (set history buffer size (in lines))\n"
5565536Ssos"                  -f <N> string       (set function key N to send <string>)\n"
5575536Ssos"                  -F                  (set function keys back to default)\n"
5585536Ssos"                  -r delay.repeat     (set keyboard delay & repeat rate)\n"
5595536Ssos"                  -r slow             (set keyboard delay & repeat to slow)\n"
5605536Ssos"                  -r normal           (set keyboard delay & repeat to normal)\n"
5615536Ssos"                  -r fast             (set keyboard delay & repeat to fast)\n"
5629202Srgrimes"                  -x                  (use hexadecimal numbers in -d option)\n"
5632088Ssos	);
5642088Ssos}
5652088Ssos
5662088Ssos
5672088Ssosvoid
5682088Ssosmain(int argc, char **argv)
5692088Ssos{
5702088Ssos	extern char	*optarg;
5712088Ssos	extern int	optind;
5722088Ssos	int		opt;
5732088Ssos
57419569Sjoerg	while((opt = getopt(argc, argv, "b:df:h:Fl:L:r:x")) != -1)
5752088Ssos		switch(opt) {
5762088Ssos			case 'b':
5772088Ssos				set_bell_values(optarg);
5782088Ssos				break;
5792088Ssos			case 'd':
5802088Ssos				print_keymap();
5812088Ssos				break;
5822088Ssos			case 'l':
58319569Sjoerg				load_keymap(optarg, 0);
5842088Ssos				break;
58519569Sjoerg			case 'L':
58619569Sjoerg				load_keymap(optarg, 1);
58719569Sjoerg				break;
5882088Ssos			case 'f':
5898857Srgrimes				set_functionkey(optarg,
5902088Ssos					nextarg(argc, argv, &optind, 'f'));
5912088Ssos				break;
5922088Ssos			case 'F':
5932088Ssos				load_default_functionkeys();
5942088Ssos				break;
5956046Ssos			case 'h':
5966046Ssos				set_history(optarg);
5976046Ssos				break;
5982088Ssos			case 'r':
5992088Ssos				set_keyrates(optarg);
6002088Ssos				break;
6012088Ssos			case 'x':
6022088Ssos				hex = 1;
6032088Ssos				break;
6042088Ssos			default:
6052088Ssos				usage();
6062088Ssos				exit(1);
6072088Ssos		}
6082088Ssos	if ((optind != argc) || (argc == 1)) {
6092088Ssos		usage();
6102088Ssos		exit(1);
6112088Ssos	}
6122088Ssos	exit(0);
6132088Ssos}
6142088Ssos
6152088Ssos
616