Remove some unnecessary braces and fix a gcc 3.4 warning.
[dragonfly.git] / usr.sbin / pcvt / kcon / kcon.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1992,1993,1994 Hellmuth Michaelis
3 *
4 * Copyright (c) 1992,1993 Holger Veit.
5 *
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to 386BSD by
9 * Holger Veit
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by
22 * Hellmuth Michaelis and Holger Veit
23 * 4. The name authors may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
2e27e3e5 37 * $DragonFly: src/usr.sbin/pcvt/kcon/Attic/kcon.c,v 1.3 2005/02/28 17:31:22 swildner Exp $
984263bc
MD
38 */
39
40static char *id =
41 "@(#)kcon.c, 3.20, Last Edit-Date: [Wed Jan 25 16:33:08 1995]";
42
43/*---------------------------------------------------------------------------*
44 *
45 * kcon.c Keyboard control and remapping
46 * ----------------------------------------------
47 *
48 * based on "keymap" which was written by
49 * Holger Veit (veit@du9ds3.uni-duisburg.de)
50 *
51 * -hm a first rewrite
52 * -hm rewrite for pcvt 2.0 distribution
53 * -hm adding show current typematic values
54 * -hm hex/octal/esc output choices
55 * -hm remapping debugging
56 * -hm garbage output for remapped keys bugfix
57 * -hm patch from Lon Willet, adding -R
58 *
59 *---------------------------------------------------------------------------*/
60
984263bc
MD
61#include <sys/types.h>
62#include <sys/ioctl.h>
63#include <machine/pcvt_ioctl.h>
64
fcc9ea4e
CP
65#include <stdio.h>
66#include <string.h>
67
984263bc
MD
68#include "keycap.h"
69
fcc9ea4e
CP
70static void usage(void);
71static void listcurrent(int);
72static void setrepeat(int, int);
73static void settypeam(int, int, int);
74static void remapkeys(int, char *);
75static void set_lock(char[], int);
76static void set_shift(char[], int);
77static void set_char(char[], int);
78
984263bc
MD
79int Rf = 0;
80int df = 0;
81int lf = 0;
82int mf = 0;
83int of = 0;
84int pf = 0;
85int rf = 0;
86int tf = 0;
87int xf = 0;
88int sf = 0;
89
90/*---------------------------------------------------------------------------*
91 * main entry
92 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
93int
94main(int argc, char **argv)
984263bc
MD
95{
96 extern char *optarg;
97 extern int optind;
98
99 int c = 0;
100
101 int errf = 0;
102
103 int rate = -1;
104 int delay = -1;
105 char *map;
106 int kbfd;
107
108 while((c = getopt(argc, argv, "Rd:lm:opr:st:x")) != -1)
109 {
110 switch(c)
111 {
112 case 'R':
113 Rf = 1;
114 break;
115
116 case 'd':
117 df = 1;
118 delay = atoi(optarg);
119 break;
120
121 case 'l':
122 lf = 1;
123 break;
124
125 case 'm':
126 mf = 1;
127 map = optarg;
128 break;
129
130 case 'o':
131 if(xf)
132 errf = 1;
133 else
134 of = 1;
135 break;
136
137 case 'p':
138 pf = 1;
139 break;
140
141 case 'r':
142 rf = 1;
143 rate = atoi(optarg);
144 break;
145
146 case 's':
147 sf = 1;
148 break;
149
150 case 't':
151 if(*optarg == '+')
152 tf = 1;
153 else if(*optarg == '-')
154 tf = -1;
155 else
156 errf = 1;
157 break;
158
159 case 'x':
160 if(of)
161 errf = 1;
162 else
163 xf = 1;
164 break;
165
166 default:
167 usage();
168 }
169 }
170
171 if((Rf == 0 && df == 0 && lf == 0 && tf == 0 && sf == 0 &&
172 rf == 0 && mf == 0 ) || errf)
173 {
174 usage();
175 }
176
177 if((kbfd = open(KEYB_DEVICE, 0)) < 0)
178 {
179 perror("kcon: keyboard open failiure");
180 exit(1);
181 }
182
183 if(sf)
184 {
185 showtypeamatic(kbfd);
186 exit(0);
187 }
188
189 if(lf)
190 {
191 listcurrent(kbfd);
192 exit(0);
193 }
194
195 if (Rf)
196 {
197 if (ioctl(kbfd, KBDRESET, 0) < 0) {
198 perror ("kcon: ioctl KBDRESET failed");
199 exit (1);
200 }
201 }
202
203 if(tf)
204 {
205 setrepeat(kbfd, tf);
206 }
207
208 if(df || rf)
209 {
210 if(delay > 3)
211 {
212 fprintf(stderr,"Delay value (%d) out of range, possible values are 0..3!\n",delay);
213 exit(1);
214 }
215 if(rate > 31)
216 {
217 fprintf(stderr,"Rate value (%d) out of range, possible values are 0..31!\n",rate);
218 exit(1);
219 }
220 settypeam(kbfd, delay, rate);
221 }
222
223 if(mf)
224 {
225 remapkeys(kbfd, map);
226 }
227
228 close(kbfd);
229 exit(0);
230}
231
232/*---------------------------------------------------------------------------*
233 * display usage info & exit
234 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
235void
236usage(void)
984263bc
MD
237{
238 fprintf(stderr, "\nkcon: keyboard control and remapping utility for pcvt video driver\n");
239 fprintf(stderr, "usage: [-R] [-d delay] [-l] [-m map] [-o] [-p] [-r rate] [-t +/-] [-x]\n");
240 fprintf(stderr, " -R full reset of keyboard\n");
241 fprintf(stderr, " -d delay until a key is repeated (range: 0...3 => 250...1000ms)\n");
242 fprintf(stderr, " -l produce listing of current keyboard mapping\n");
243 fprintf(stderr, " -m set keyboard remapping from a keycap entry\n");
244 fprintf(stderr, " -o set octal output for listing\n");
245 fprintf(stderr, " -p pure, don't display escape as 'ESC' for listing\n");
246 fprintf(stderr, " -r chars/second repeat value (range: 0...31 => 30...2 chars/sec)\n");
247 fprintf(stderr, " -s show, display the current keyboard typematic values\n");
248 fprintf(stderr, " -t switch repeat on(+) or off(-)\n");
249 fprintf(stderr, " -x set hexadecimal output for listing\n\n");
250 exit(1);
251}
252
253/*---------------------------------------------------------------------------*
254 * convert control char in string to printable values
255 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
256char *
257showcntrl(u_char *s)
984263bc
MD
258{
259 static char res_str[80];
260 static char conv_buf[80];
261 int i;
262
263 res_str[0] = '\0';
264
265 for(i = 0; s[i]; i++)
266 {
2e27e3e5 267 if(((s[i] > 0x20) && (s[i] <= 0x7e)) || (s[i] >= 0xa0))
984263bc
MD
268 {
269 conv_buf[0] = s[i];
270 conv_buf[1] = '\0';
271 }
272 else if((s[i] == 0x1b) && (pf == 0))
984263bc 273 strcpy(conv_buf,"ESC ");
984263bc 274 else if(of)
984263bc 275 sprintf(conv_buf,"\\%03.3o ", s[i]);
984263bc 276 else
984263bc 277 sprintf(conv_buf,"0x%02.2X ", s[i]);
984263bc
MD
278 strcat(res_str, conv_buf);
279 }
280 return(res_str);
281}
282
283/*---------------------------------------------------------------------------*
284 * list the current keyboard mapping
285 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
286void
287listcurrent(int kbfd)
984263bc
MD
288{
289 static char *keytypetab[] = {
290 "NONE ",
291 "SHIFT ",
292 "ALT/META ",
293 "NUMLOCK ",
294 "CONTROL ",
295 "CAPSLOCK ",
296 "ASCII ",
297 "SCROLL ",
298 "FUNCTION ",
299 "KEYPAD ",
300 "BREAK ",
301 "ALTGR ",
302 "SHIFTLOCK",
303 "CURSOR ",
304 "RETURN "
305 };
306
307 struct kbd_ovlkey keyboardmap[KBDMAXKEYS];
308 struct kbd_ovlkey *kbmapp;
309 int keytype;
310 int altgr_defined;
311 int i;
312
313 altgr_defined = 0;
314 kbmapp = keyboardmap;
315
316 for (i = 0; i < KBDMAXKEYS; i++)
317 {
318 kbmapp->keynum = i;
319
320 if(ioctl(kbfd, KBDGCKEY, kbmapp) < 0)
321 {
322 perror("kcon: ioctl KBDGCKEY failed");
323 exit(1);
324 }
325
326 if((kbmapp->type & KBD_MASK) == KBD_ALTGR)
327 altgr_defined = i;
328
329 kbmapp++;
330 }
331
332 if(altgr_defined)
333 {
334 printf("S Key KeyType Normal Shift Control Altgr \n");
335 printf("- --- --------- --------------- --------------- --------------- ---------------\n");
336 }
337 else
338 {
339 printf("S Key KeyType Normal Shift Control \n");
340 printf("- --- --------- --------------- --------------- ---------------\n");
341 }
342
343 kbmapp = &keyboardmap[1];
344
345 for(i = 1; i < KBDMAXKEYS; i++)
346 {
347 keytype = kbmapp->type;
348
349 if(keytype)
350 {
351 if(keytype & KBD_OVERLOAD)
352 printf("! %3.3d %9.9s ", i, keytypetab[keytype & KBD_MASK]);
353 else
354 printf("- %3.3d %9.9s ", i, keytypetab[keytype & KBD_MASK]);
355
356 switch(keytype & KBD_MASK)
357 {
358
359 case KBD_NUM:
360 case KBD_ASCII:
361 case KBD_FUNC:
362 case KBD_KP:
363 case KBD_CURSOR:
364 case KBD_RETURN: /* ??? */
365
366 if(kbmapp->subu == KBD_SUBT_STR)
367 printf("%-15s ",showcntrl(kbmapp->unshift));
368 else
369 printf("Function() ");
370
371 if(kbmapp->subs == KBD_SUBT_STR)
372 printf("%-15s ",showcntrl(kbmapp->shift));
373 else
374 printf("Function() ");
375
376 if(kbmapp->subc == KBD_SUBT_STR)
377 printf("%-15s ",showcntrl(kbmapp->ctrl));
378 else
379 printf("Function() ");
380
381 if(altgr_defined)
382 {
383 if(kbmapp->suba == KBD_SUBT_STR)
384 printf("%-15s ",showcntrl(kbmapp->altgr));
385 else
386 printf("Function() ");
387 }
388 break;
389 }
390 putchar('\n');
391 }
392 kbmapp++;
393 }
394}
395
396/*---------------------------------------------------------------------------*
397 * show delay and rate values for keyboard
398 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
399int
400showtypeamatic(int kbfd)
984263bc
MD
401{
402 static char *delaytab[] = {
403 "250",
404 "500",
405 "750",
406 "1000"
407 };
408
409 static char *ratetab[] = {
410 "30.0",
411 "26.7",
412 "24.0",
413 "21.8",
414 "20.0",
415 "18.5",
416 "17.1",
417 "16.0",
418 "15.0",
419 "13.3",
420 "12.0",
421 "10.9",
422 "10.0",
423 "9.2",
424 "8.6",
425 "8.0",
426 "7.5",
427 "6.7",
428 "6.0",
429 "5.5",
430 "5.0",
431 "4.6",
432 "4.3",
433 "4.0",
434 "3.7",
435 "3.3",
436 "3.0",
437 "2.7",
438 "2.5",
439 "2.3",
440 "2.1",
441 "2.0"
442 };
443
444 int cur_typemat_val;
445 int delay, rate;
446
447 if((ioctl(kbfd, KBDGTPMAT, &cur_typemat_val)) < 0)
448 {
449 perror("kcon: ioctl KBDGTPMAT failed");
450 exit(1);
451 }
452
453 delay = ((cur_typemat_val & 0x60) >> 5);
454 rate = cur_typemat_val & 0x1f;
455
456 printf("\nDisplaying the current keyboard typematic values:\n\n");
457 printf("The delay-until-repeat time is [ %s ] milliseconds\n",delaytab[delay]);
458 printf("The repeat-rate is [ %s ] characters per second\n\n",ratetab[rate]);
459}
460
461/*---------------------------------------------------------------------------*
462 * set repeat feature on/off
463 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
464void
465setrepeat(int kbfd, int tf)
984263bc
MD
466{
467 int srepsw_val;
468
469 if(tf == 1)
470 srepsw_val = KBD_REPEATON;
471 else
472 srepsw_val = KBD_REPEATOFF;
473
474 if(ioctl(kbfd, KBDSREPSW, &srepsw_val) < 0)
475 {
476 perror("kcon: ioctl KBDREPSW failed");
477 exit(1);
478 }
479}
480
481/*---------------------------------------------------------------------------*
482 * set delay and rate values for keyboard
483 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
484void
485settypeam(int kbfd, int delay, int rate)
984263bc
MD
486{
487 int cur_typemat_val;
488 int new_typemat_val;
489
490 if((ioctl(kbfd, KBDGTPMAT, &cur_typemat_val)) < 0)
491 {
492 perror("kcon: ioctl KBDGTPMAT failed");
493 exit(1);
494 }
495
496 if(delay == -1)
497 delay = (cur_typemat_val & 0x60);
498 else
499 delay = ((delay << 5) & 0x60);
500
501 if(rate == -1)
502 rate = (cur_typemat_val & 0x1f);
503 else
504 rate &= 0x1f;
505
506 new_typemat_val = delay | rate;
507
508 if((ioctl(kbfd, KBDSTPMAT, &new_typemat_val)) < 0)
509 {
510 perror("kcon: ioctl KBDSTPMAT failed");
511 exit(1);
512 }
513}
514
515/*---------------------------------------------------------------------------*
516 * remap keyboard from keycap entry
517 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
518void
519remapkeys(int kbfd, char *map)
984263bc
MD
520{
521 char cap_entry[1024];
522 int ret;
523 char keyflag[128];
524 int i;
525
526 /* try to find the entry */
527
528 ret = kgetent(cap_entry, map);
529
530 if(ret == -1)
531 {
532 fprintf(stderr, "kcon: keycap database not found or not accessible!\n");
533 exit(1);
534 }
535 else if(ret == 0)
536 {
537 fprintf(stderr, "kcon: keycap entry [%s] not found in database!\n", map);
538 exit(1);
539 }
540
541 /* set default mapping */
542
543 if((ioctl(kbfd, KBDDEFAULT)) < 0)
544 {
545 perror("kcon: ioctl KBDDEFAULT failed");
546 exit(1);
547 }
548
549 /* DE flag present? */
550
551 if(kgetflag("de"))
552 return;
553
554 for(i = 0; i < KBDMAXKEYS; i++)
555 keyflag[i] = 0;
556
557 set_lock(keyflag, kbfd);
558
559 set_shift(keyflag, kbfd);
560
561 set_char(keyflag, kbfd);
562}
563
564/*---------------------------------------------------------------------------*
565 * care for lock keys
566 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
567void
568set_lock(char keyflag[], int kbfd)
984263bc
MD
569{
570 int i, j;
571 char cap[16];
572 struct kbd_ovlkey entry;
573
574 struct {
575 char *ch;
576 u_short typ;
577 } lock[] =
578 {
579 "ca", KBD_CAPS,
580 "sh", KBD_SHFTLOCK,
581 "nl", KBD_NUMLOCK,
582 "sc", KBD_SCROLL
583 };
584
585
586 for(i = 0; i < 4; i++)
587 {
588 int n;
589
590 sprintf(cap, "%s", lock[i].ch);
591
592 n = kgetnum(cap);
593
594 if(n > 0)
595 {
596 if (keyflag[n])
597 {
598 fprintf(stderr,"kcon: duplicate key definition for key [%d]!\n",n);
599 exit(1);
600 }
601 keyflag[n] = 1;
602
603 entry.keynum = n;
604 entry.type = lock[i].typ;
605
606 if((ioctl(kbfd, KBDSCKEY, &entry)) < 0)
607 {
608 perror("kcon: ioctl KBDSCKEY failed");
609 exit(1);
610 }
611 }
612 }
613}
614
615/*---------------------------------------------------------------------------*
616 * care for shifting keys
617 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
618void
619set_shift(char keyflag[], int kbfd)
984263bc
MD
620{
621 int i, j;
622 char cap[16];
623 struct kbd_ovlkey entry;
624
625 struct {
626 char ch;
627 u_short typ;
628 } shift[] =
629 {
630 'm', KBD_META,
631 'l', KBD_ALTGR,
632 'h', KBD_SHIFT,
633 't', KBD_CTL
634 };
635
636 for(i = 0; i < 4; i++)
637 {
638 for(j = 1; j < 10; j++)
639 {
640 int n;
641
642 sprintf(cap, "%c%d", shift[i].ch,j);
643
644 n = kgetnum(cap);
645
646 if (n >= 0)
647 {
648 if (keyflag[n])
649 {
650 fprintf(stderr,"kcon: duplicate key definition for key [%d]!\n",n);
651 exit(1);
652 }
653 keyflag[n] = 1;
654
655 entry.keynum = n;
656 entry.type = shift[i].typ;
657 if((ioctl(kbfd, KBDSCKEY, &entry)) < 0)
658 {
659 perror("kcon: ioctl KBDSCKEY failed");
660 exit(1);
661 }
662 }
663 }
664 }
665}
666
667/*---------------------------------------------------------------------------*
668 * care for normal keys
669 *---------------------------------------------------------------------------*/
fcc9ea4e
CP
670void
671set_char(char keyflag[], int kbfd)
984263bc
MD
672{
673 int i, j;
674 char cap[16];
675 int setflag;
676 char *addr_str;
677 char *new_str;
678 struct kbd_ovlkey entry;
679
680 struct {
681 char *addr;
682 char ch;
683 } standard[] = {
684 0, 'D',
685 &entry.unshift[0], 'K',
686 &entry.shift[0], 'S',
687 &entry.ctrl[0], 'C',
688 &entry.altgr[0], 'A'
689 };
690
691 for(i = 1; i < KBDMAXKEYS; i++)
692 {
693 setflag = 0;
694
695 entry.keynum = i;
696
697 if((ioctl(kbfd, KBDGOKEY, &entry)) < 0)
698 {
699 perror("kcon: ioctl KBDGOKEY failed");
700 exit(1);
701 }
702
703 entry.type = KBD_ASCII;
704
705 for(j = 0; j < 5; j++)
706 {
707 sprintf(cap, "%c%d", standard[j].ch,i);
708
709 if((j == 0) && (kgetflag(cap)))
710 {
711 /* delete a key */
712
713 entry.type = KBD_NONE;
714 setflag = 1;
715 goto setit;
716
717 }
718 else
719 {
720 addr_str = standard[j].addr;
721 if(new_str = kgetstr(cap, &addr_str))
722 {
723 if(strlen(new_str) > KBDMAXOVLKEYSIZE)
724 {
725 fprintf(stderr, "kcon: database entry string [%s] longer than max [%d]!\n",new_str,KBDMAXOVLKEYSIZE);
726 exit(1);
727 }
728 setflag = 1;
729 }
730 }
731 }
732
733setit: if (setflag)
734 {
735 if (keyflag[i])
736 {
737 fprintf(stderr,"kcon: duplicate key definition for key [%d]!\n",i);
738 exit(1);
739 }
740 keyflag[i] = 1;
741
742 if((ioctl(kbfd, KBDSCKEY, &entry)) < 0)
743 {
744 perror("kcon: ioctl KBDSCKEY failed");
745 exit(1);
746 }
747 }
748 }
749}
750
751/*------------------- EOF ------------------------------------------------*/