kbdcontrol.c revision 29603
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[] =
3129603Scharnier	"$Id$";
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
515994Ssoschar fkey_table[96][MAXFK] = {
525994Ssos/* 01-04 */	"\033[M", "\033[N", "\033[O", "\033[P",
535994Ssos/* 05-08 */	"\033[Q", "\033[R", "\033[S", "\033[T",
545994Ssos/* 09-12 */	"\033[U", "\033[V", "\033[W", "\033[X",
555994Ssos/* 13-16 */	"\033[Y", "\033[Z", "\033[a", "\033[b",
565994Ssos/* 17-20 */	"\033[c", "\033[d", "\033[e", "\033[f",
575994Ssos/* 21-24 */	"\033[g", "\033[h", "\033[i", "\033[j",
585994Ssos/* 25-28 */	"\033[k", "\033[l", "\033[m", "\033[n",
595994Ssos/* 29-32 */	"\033[o", "\033[p", "\033[q", "\033[r",
605994Ssos/* 33-36 */	"\033[s", "\033[t", "\033[u", "\033[v",
615994Ssos/* 37-40 */	"\033[w", "\033[x", "\033[y", "\033[z",
625994Ssos/* 41-44 */	"\033[@", "\033[[", "\033[\\","\033[]",
639202Srgrimes/* 45-48 */     "\033[^", "\033[_", "\033[`", "\033[{",
645994Ssos/* 49-52 */	"\033[H", "\033[A", "\033[I", "-"     ,
655994Ssos/* 53-56 */	"\033[D", "\033[E", "\033[C", "+"     ,
665994Ssos/* 57-60 */	"\033[F", "\033[B", "\033[G", "\033[L",
679202Srgrimes/* 61-64 */     "\177",   "\033[J", "\033[~", "\033[}",
685994Ssos/* 65-68 */	""      , ""      , ""      , ""      ,
695994Ssos/* 69-72 */	""      , ""      , ""      , ""      ,
705994Ssos/* 73-76 */	""      , ""      , ""      , ""      ,
715994Ssos/* 77-80 */	""      , ""      , ""      , ""      ,
725994Ssos/* 81-84 */	""      , ""      , ""      , ""      ,
735994Ssos/* 85-88 */	""      , ""      , ""      , ""      ,
745994Ssos/* 89-92 */	""      , ""      , ""      , ""      ,
755994Ssos/* 93-96 */	""      , ""      , ""      , ""      ,
762088Ssos	};
772088Ssos
782088Ssosconst int	delays[]  = {250, 500, 750, 1000};
792088Ssosconst int	repeats[] = { 34,  38,  42,  46,  50,  55,  59,  63,
802088Ssos			      68,  76,  84,  92, 100, 110, 118, 126,
812088Ssos			     136, 152, 168, 184, 200, 220, 236, 252,
822088Ssos			     272, 304, 336, 368, 400, 440, 472, 504};
832088Ssosconst int	ndelays = (sizeof(delays) / sizeof(int));
842088Ssosconst int	nrepeats = (sizeof(repeats) / sizeof(int));
852088Ssosint 		hex = 0;
866046Ssosint 		number;
872088Ssoschar 		letter;
882088Ssos
8929603Scharnierstatic void usage __P((void));
902088Ssos
912088Ssoschar *
922088Ssosnextarg(int ac, char **av, int *indp, int oc)
932088Ssos{
942088Ssos	if (*indp < ac)
952088Ssos		return(av[(*indp)++]);
9629603Scharnier	warnx("option requires two arguments -- %c", oc);
972088Ssos	usage();
982088Ssos	return("");
992088Ssos}
1002088Ssos
1012088Ssos
1022088Ssoschar *
1032088Ssosmkfullname(const char *s1, const char *s2, const char *s3)
1042088Ssos{
1055536Ssos	static char	*buf = NULL;
1065536Ssos	static int	bufl = 0;
1075536Ssos	int		f;
1082088Ssos
1092088Ssos	f = strlen(s1) + strlen(s2) + strlen(s3) + 1;
1102088Ssos	if (f > bufl)
1112088Ssos		if (buf)
1122088Ssos			buf = (char *)realloc(buf, f);
1132088Ssos		else
1142088Ssos			buf = (char *)malloc(f);
1152088Ssos	if (!buf) {
1162088Ssos		bufl = 0;
1172088Ssos		return(NULL);
1182088Ssos	}
1192088Ssos
1202088Ssos	bufl = f;
1212088Ssos	strcpy(buf, s1);
1222088Ssos	strcat(buf, s2);
1232088Ssos	strcat(buf, s3);
1242088Ssos	return(buf);
1252088Ssos}
1262088Ssos
1272088Ssos
1282088Ssosint
1292088Ssosget_entry()
1302088Ssos{
1312088Ssos	switch (yylex()) {
1322088Ssos	case TNOP:
1332088Ssos		return NOP | 0x100;
1342088Ssos	case TLSH:
1352088Ssos		return LSH | 0x100;
1362088Ssos	case TRSH:
1372088Ssos		return RSH | 0x100;
1382088Ssos	case TCLK:
1392088Ssos		return CLK | 0x100;
1402088Ssos	case TNLK:
1412088Ssos		return NLK | 0x100;
1422088Ssos	case TSLK:
1432088Ssos		return SLK | 0x100;
1442088Ssos	case TBTAB:
1452088Ssos		return BTAB | 0x100;
1462088Ssos	case TLALT:
1472088Ssos		return LALT | 0x100;
1482088Ssos	case TLCTR:
1492088Ssos		return LCTR | 0x100;
1502088Ssos	case TNEXT:
1512088Ssos		return NEXT | 0x100;
1522088Ssos	case TRCTR:
1532088Ssos		return RCTR | 0x100;
1542088Ssos	case TRALT:
1552088Ssos		return RALT | 0x100;
1562088Ssos	case TALK:
1572088Ssos		return ALK | 0x100;
1582088Ssos	case TASH:
1592088Ssos		return ASH | 0x100;
1602088Ssos	case TMETA:
1612088Ssos		return META | 0x100;
1622088Ssos	case TRBT:
1632088Ssos		return RBT | 0x100;
1642088Ssos	case TDBG:
1652088Ssos		return DBG | 0x100;
1665994Ssos	case TSUSP:
1675994Ssos		return SUSP | 0x100;
1682088Ssos	case TFUNC:
1692088Ssos		if (F(number) > L_FN)
1702088Ssos			return -1;
1712088Ssos		return F(number) | 0x100;
1722088Ssos	case TSCRN:
1732088Ssos		if (S(number) > L_SCR)
1742088Ssos			return -1;
1752088Ssos		return S(number) | 0x100;
1762088Ssos	case TLET:
1772088Ssos		return (unsigned char)letter;
1782088Ssos	case TNUM:
1792088Ssos		if (number < 0 || number > 255)
1802088Ssos			return -1;
1812088Ssos		return number;
1822088Ssos	default:
1832088Ssos		return -1;
1842088Ssos	}
1852088Ssos}
1862088Ssos
1878857Srgrimes
1882088Ssosint
1892088Ssosget_key_definition_line(FILE* fd, keymap_t *map)
1902088Ssos{
1912088Ssos	int i, def, scancode;
1922088Ssos
1932088Ssos	yyin = fd;
1942088Ssos
1952088Ssos	/* get scancode number */
1968857Srgrimes	if (yylex() != TNUM)
1972088Ssos		return -1;
1982088Ssos	if (number < 0 || number >= NUM_KEYS)
1992088Ssos		return -1;
2002088Ssos	scancode = number;
2012088Ssos
2022088Ssos	/* get key definitions */
2032088Ssos	map->key[scancode].spcl = 0;
2042088Ssos	for (i=0; i<NUM_STATES; i++) {
2052088Ssos		if ((def = get_entry()) == -1)
2062088Ssos			return -1;
2072088Ssos		if (def & 0x100)
2082088Ssos			map->key[scancode].spcl |= (0x80 >> i);
2092088Ssos		map->key[scancode].map[i] = def & 0xFF;
2102088Ssos	}
2112088Ssos	/* get lock state key def */
2122088Ssos	if (yylex() != TFLAG)
2132088Ssos		return -1;
2142088Ssos	map->key[scancode].flgs = number;
2152088Ssos		return scancode;
2162088Ssos}
2172088Ssos
2182088Ssos
21929603Scharniervoid
2202088Ssosprint_entry(FILE *fp, int value)
2212088Ssos{
2222088Ssos	int val = value & 0xFF;
2232088Ssos
2242088Ssos	switch (value) {
2252088Ssos	case NOP | 0x100:
2268857Srgrimes		fprintf(fp, " nop   ");
2272088Ssos		break;
2282088Ssos	case LSH | 0x100:
2292088Ssos		fprintf(fp, " lshift");
2302088Ssos		break;
2312088Ssos	case RSH | 0x100:
2322088Ssos		fprintf(fp, " rshift");
2332088Ssos		break;
2342088Ssos	case CLK | 0x100:
2352088Ssos		fprintf(fp, " clock ");
2362088Ssos		break;
2372088Ssos	case NLK | 0x100:
2382088Ssos		fprintf(fp, " nlock ");
2392088Ssos		break;
2402088Ssos	case SLK | 0x100:
2412088Ssos		fprintf(fp, " slock ");
2422088Ssos		break;
2432088Ssos	case BTAB | 0x100:
2442088Ssos		fprintf(fp, " btab  ");
2452088Ssos		break;
2462088Ssos	case LALT | 0x100:
2472088Ssos		fprintf(fp, " lalt  ");
2482088Ssos		break;
2492088Ssos	case LCTR | 0x100:
2502088Ssos		fprintf(fp, " lctrl ");
2512088Ssos		break;
2522088Ssos	case NEXT | 0x100:
2532088Ssos		fprintf(fp, " nscr  ");
2542088Ssos		break;
2552088Ssos	case RCTR | 0x100:
2562088Ssos		fprintf(fp, " rctrl ");
2572088Ssos		break;
2582088Ssos	case RALT | 0x100:
2592088Ssos		fprintf(fp, " ralt  ");
2602088Ssos		break;
2612088Ssos	case ALK | 0x100:
2622088Ssos		fprintf(fp, " alock ");
2632088Ssos		break;
2642088Ssos	case ASH | 0x100:
2652088Ssos		fprintf(fp, " ashift");
2662088Ssos		break;
2672088Ssos	case META | 0x100:
2682088Ssos		fprintf(fp, " meta  ");
2692088Ssos		break;
2702088Ssos	case RBT | 0x100:
2712088Ssos		fprintf(fp, " boot  ");
2722088Ssos		break;
2732088Ssos	case DBG | 0x100:
2742088Ssos		fprintf(fp, " debug ");
2752088Ssos		break;
2762088Ssos	default:
2772088Ssos		if (value & 0x100) {
2788857Srgrimes		 	if (val >= F_FN && val <= L_FN)
2792088Ssos				fprintf(fp, " fkey%02d", val - F_FN + 1);
2808857Srgrimes		 	else if (val >= F_SCR && val <= L_SCR)
2812088Ssos				fprintf(fp, " scr%02d ", val - F_SCR + 1);
2822088Ssos			else if (hex)
2838857Srgrimes				fprintf(fp, " 0x%02x  ", val);
2842088Ssos			else
2858857Srgrimes				fprintf(fp, "  %3d  ", val);
2862088Ssos		}
2872088Ssos		else {
2882088Ssos			if (val < ' ')
2898857Srgrimes				fprintf(fp, " %s   ", ctrl_names[val]);
2902088Ssos			else if (val == 127)
2918857Srgrimes				fprintf(fp, " del   ");
2929202Srgrimes			else if (isascii(val) && isprint(val))
2938857Srgrimes				fprintf(fp, " '%c'   ", val);
2942088Ssos			else if (hex)
2958857Srgrimes				fprintf(fp, " 0x%02x  ", val);
2962088Ssos			else
2978857Srgrimes				fprintf(fp, " %3d   ", val);
2982088Ssos		}
2992088Ssos	}
3002088Ssos}
3012088Ssos
3022088Ssos
3032088Ssosvoid
3042088Ssosprint_key_definition_line(FILE *fp, int scancode, struct key_t *key)
3052088Ssos{
30629603Scharnier	int i;
3072088Ssos
3082088Ssos	/* print scancode number */
3092088Ssos	if (hex)
3102088Ssos		fprintf(fp, " 0x%02x  ", scancode);
3112088Ssos	else
3122088Ssos		fprintf(fp, "  %03d  ", scancode);
3132088Ssos
3142088Ssos	/* print key definitions */
3152088Ssos	for (i=0; i<NUM_STATES; i++) {
3162088Ssos		if (key->spcl & (0x80 >> i))
3172088Ssos			print_entry(fp, key->map[i] | 0x100);
3182088Ssos		else
3198857Srgrimes			print_entry(fp, key->map[i]);
3202088Ssos	}
3212088Ssos
3222088Ssos	/* print lock state key def */
3232088Ssos	switch (key->flgs) {
3242088Ssos	case 0:
3252088Ssos		fprintf(fp, "  O\n");
3262088Ssos		break;
3272088Ssos	case 1:
3282088Ssos		fprintf(fp, "  C\n");
3292088Ssos		break;
3302088Ssos	case 2:
3312088Ssos		fprintf(fp, "  N\n");
3322088Ssos		break;
3336046Ssos	case 3:
3346046Ssos		fprintf(fp, "  B\n");
3356046Ssos		break;
3368857Srgrimes	}
3372088Ssos}
3382088Ssos
3392088Ssos
3402088Ssosvoid
34119569Sjoergload_keymap(char *opt, int dumponly)
3422088Ssos{
3432088Ssos	keymap_t map;
3442088Ssos	FILE	*fd;
34519569Sjoerg	int	scancode, i, j;
34619569Sjoerg	struct key_t *kp;
34719569Sjoerg	char	*name, *cp;
3482088Ssos	char	*prefix[]  = {"", "", KEYMAP_PATH, NULL};
3492088Ssos	char	*postfix[] = {"", ".kbd", ".kbd"};
3502088Ssos
3512088Ssos	for (i=0; prefix[i]; i++) {
3522088Ssos		name = mkfullname(prefix[i], opt, postfix[i]);
35329603Scharnier		if ((fd = fopen(name, "r")))
3542088Ssos			break;
3552088Ssos	}
3562088Ssos	if (fd == NULL) {
35729603Scharnier		warn("keymap file not found");
3582088Ssos		return;
3592088Ssos	}
3603864Sswallace	memset(&map, 0, sizeof(map));
3612088Ssos	while (1) {
3622088Ssos		if ((scancode = get_key_definition_line(fd, &map)) < 0)
3632088Ssos			break;
3642088Ssos		if (scancode > map.n_keys) map.n_keys = scancode;
3652088Ssos    	}
36619569Sjoerg	if (dumponly) {
36719569Sjoerg		/* fix up the filename to make it a valid C identifier */
36819569Sjoerg		for (cp = opt; *cp; cp++)
36919569Sjoerg			if (!isalpha(*cp) && !isdigit(*cp)) *cp = '_';
37019569Sjoerg		printf("static const struct keymap keymap_%s = {\n"
37119569Sjoerg		       "/*\n * Automatically generated from %s.\n"
37219569Sjoerg		       " * DO NOT EDIT!\n */\n\n\t%u,\n{\n",
37319569Sjoerg		       opt, name, (unsigned)map.n_keys);
37419569Sjoerg		for (i = 0; i < map.n_keys; i++) {
37519569Sjoerg			kp = &map.key[i];
37619569Sjoerg
37719569Sjoerg			printf("\t{{ ");
37819569Sjoerg			for (j = 0; j < NUM_STATES; j++)
37919569Sjoerg				printf("0x%02x%c", (unsigned)kp->map[j],
38019569Sjoerg					j == NUM_STATES-1? '}': ',');
38119569Sjoerg			printf(", 0x%x, 0x%x },\n",
38219569Sjoerg			       (unsigned)kp->spcl, (unsigned)kp->flgs);
38319569Sjoerg		}
38419569Sjoerg		printf("}\n};\n\n");
38519569Sjoerg		return;
38619569Sjoerg	}
3872088Ssos	if (ioctl(0, PIO_KEYMAP, &map) < 0) {
38829603Scharnier		warn("setting keymap");
3892088Ssos		fclose(fd);
3902088Ssos		return;
3912088Ssos	}
3922088Ssos}
3932088Ssos
3942088Ssos
3952088Ssosvoid
3962088Ssosprint_keymap()
3972088Ssos{
3982088Ssos	keymap_t map;
3992088Ssos	int i;
4002088Ssos
40129603Scharnier	if (ioctl(0, GIO_KEYMAP, &map) < 0)
40229603Scharnier		err(1, "getting keymap");
4032088Ssos    	printf(
4042088Ssos"#                                                         alt\n"
4052088Ssos"# scan                       cntrl          alt    alt   cntrl lock\n"
4062088Ssos"# code  base   shift  cntrl  shift  alt    shift  cntrl  shift state\n"
4072088Ssos"# ------------------------------------------------------------------\n"
4082088Ssos    	);
4092088Ssos	for (i=0; i<map.n_keys; i++)
4102088Ssos		print_key_definition_line(stdout, i, &map.key[i]);
4112088Ssos}
4122088Ssos
4132088Ssos
4142088Ssosvoid
4152088Ssosload_default_functionkeys()
4162088Ssos{
4172088Ssos	fkeyarg_t fkey;
4182088Ssos	int i;
4192088Ssos
4202088Ssos	for (i=0; i<NUM_FKEYS; i++) {
4212088Ssos		fkey.keynum = i;
4222088Ssos		strcpy(fkey.keydef, fkey_table[i]);
4232088Ssos		fkey.flen = strlen(fkey_table[i]);
4242088Ssos		if (ioctl(0, SETFKEY, &fkey) < 0)
42529603Scharnier			warn("setting function key");
4262088Ssos	}
4272088Ssos}
4282088Ssos
4292088Ssosvoid
4302088Ssosset_functionkey(char *keynumstr, char *string)
4312088Ssos{
4322088Ssos	fkeyarg_t fkey;
4332088Ssos
4342088Ssos	if (!strcmp(keynumstr, "load") && !strcmp(string, "default")) {
4352088Ssos		load_default_functionkeys();
4362088Ssos		return;
4372088Ssos	}
4382088Ssos	fkey.keynum = atoi(keynumstr);
4392088Ssos	if (fkey.keynum < 1 || fkey.keynum > NUM_FKEYS) {
44029603Scharnier		warnx("function key number must be between 1 and %d",
4412088Ssos			NUM_FKEYS);
4422088Ssos		return;
4432088Ssos	}
4442088Ssos	if ((fkey.flen = strlen(string)) > MAXFK) {
44529603Scharnier		warnx("function key string too long (%d > %d)",
4462088Ssos			fkey.flen, MAXFK);
4472088Ssos		return;
4482088Ssos	}
4492088Ssos	strcpy(fkey.keydef, string);
4502088Ssos	fkey.keynum -= 1;
4512088Ssos	if (ioctl(0, SETFKEY, &fkey) < 0)
45229603Scharnier		warn("setting function key");
4532088Ssos}
4542088Ssos
4552088Ssos
4562088Ssosvoid
4572088Ssosset_bell_values(char *opt)
4582088Ssos{
4595536Ssos	int bell, duration, pitch;
4602088Ssos
4618857Srgrimes	if (!strcmp(opt, "visual"))
4625536Ssos		bell = 1, duration = 1, pitch = 800;
4635536Ssos	else if (!strcmp(opt, "normal"))
4645536Ssos		bell = 0, duration = 1, pitch = 800;
4652088Ssos	else {
4662088Ssos		char		*v1;
4678857Srgrimes
4685536Ssos		bell = 0;
4692088Ssos		duration = strtol(opt, &v1, 0);
4702088Ssos		if ((duration < 0) || (*v1 != '.'))
4712088Ssos			goto badopt;
4722088Ssos		opt = ++v1;
4732088Ssos		pitch = strtol(opt, &v1, 0);
4742088Ssos		if ((pitch < 0) || (*opt == '\0') || (*v1 != '\0')) {
4752088Ssosbadopt:
47629603Scharnier			warnx("argument to -b must be DURATION.PITCH");
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:
51429603Scharnier			warnx("argument to -r must be delay.repeat");
5152088Ssos			return;
5162088Ssos		}
5172088Ssos		for (n = 0; n < ndelays - 1; n++)
5182088Ssos			if (delay <= delays[n])
5192088Ssos				break;
5202088Ssos		rate.del = n;
5212088Ssos		for (n = 0; n < nrepeats - 1; n++)
5222088Ssos			if (repeat <= repeats[n])
5232088Ssos				break;
5242088Ssos		rate.rep = n;
5252088Ssos	}
5262088Ssos
5272088Ssos	if (ioctl(0, KDSETRAD, rate) < 0)
52829603Scharnier		warn("setting keyboard rate");
5292088Ssos}
5302088Ssos
5312088Ssos
5326046Ssosvoid
5336046Ssosset_history(char *opt)
5346046Ssos{
5356046Ssos	int size;
5366046Ssos
5376046Ssos	size = atoi(opt);
5386046Ssos	if ((*opt == '\0') || size < 0) {
53929603Scharnier		warnx("argument must be a positive number");
5406046Ssos		return;
5416046Ssos	}
5426046Ssos	if (ioctl(0, CONS_HISTORY, &size) == -1)
54329603Scharnier		warn("setting history buffer size");
5446046Ssos}
5456046Ssos
5466046Ssos
54729603Scharnierstatic void
5482088Ssosusage()
5492088Ssos{
55029603Scharnier	fprintf(stderr, "%s\n%s\n%s\n",
55129603Scharnier"usage: kbdcontrol [-dFx] [-b  duration.pitch | belltype]",
55229603Scharnier"                  [-r delay.repeat | speed] [-l mapfile] [-f # string]",
55329603Scharnier"                  [-h size] [-L mapfile]");
55429603Scharnier	exit(1);
5552088Ssos}
5562088Ssos
5572088Ssos
5582088Ssosvoid
5592088Ssosmain(int argc, char **argv)
5602088Ssos{
5612088Ssos	int		opt;
5622088Ssos
56319569Sjoerg	while((opt = getopt(argc, argv, "b:df:h:Fl:L:r:x")) != -1)
5642088Ssos		switch(opt) {
5652088Ssos			case 'b':
5662088Ssos				set_bell_values(optarg);
5672088Ssos				break;
5682088Ssos			case 'd':
5692088Ssos				print_keymap();
5702088Ssos				break;
5712088Ssos			case 'l':
57219569Sjoerg				load_keymap(optarg, 0);
5732088Ssos				break;
57419569Sjoerg			case 'L':
57519569Sjoerg				load_keymap(optarg, 1);
57619569Sjoerg				break;
5772088Ssos			case 'f':
5788857Srgrimes				set_functionkey(optarg,
5792088Ssos					nextarg(argc, argv, &optind, 'f'));
5802088Ssos				break;
5812088Ssos			case 'F':
5822088Ssos				load_default_functionkeys();
5832088Ssos				break;
5846046Ssos			case 'h':
5856046Ssos				set_history(optarg);
5866046Ssos				break;
5872088Ssos			case 'r':
5882088Ssos				set_keyrates(optarg);
5892088Ssos				break;
5902088Ssos			case 'x':
5912088Ssos				hex = 1;
5922088Ssos				break;
5932088Ssos			default:
5942088Ssos				usage();
5952088Ssos		}
59629603Scharnier	if ((optind != argc) || (argc == 1))
5972088Ssos		usage();
5982088Ssos	exit(0);
5992088Ssos}
6002088Ssos
6012088Ssos
602