Return to BSD News archive
Path: sserve!manuel!munnari.oz.au!mips!decwrl!sdd.hp.com!think.com!cayman!brad From: brad@Cayman.COM (Brad Parker) Newsgroups: comp.unix.bsd Subject: new ioctl for keyboard flags Message-ID: <BRAD.92Jul21095535@haiti.Cayman.COM> Date: 21 Jul 92 13:55:35 GMT Sender: news@cayman.COM Organization: Cayman Systems Inc., Cambridge, MA Lines: 431 Nntp-Posting-Host: haiti I was tired of the caps lock key not being a control key and the shift key makeing "control+'-'" not work, so I added to ioctl's and a wrote a little program to wack the "keyboard flags". It also allows you to change the cursor from "fat" to "slim". This was the simplest way I could find to affect the desired result. I have heard to SCO and other 386 unixes have up to three (3!) levels of keyboard mapping which makes doing things like this easier. The kern/pccons.c code looks like it wants to go this direction, but is not quite there yet. oh yes, this also fixes a bug where "control+'2'" would not produce the desired "0x0" code. Since 0x0 is overloaded already in the map to mean "end of string", I overload 0xff to mean "send 0x0". hi ho. -brad --- cut here --- #!/bin/sh # This is a shell archive (shar 3.47) # made 07/21/1992 13:42 UTC by brad@haiti # Source directory /tmp_mnt/home/caicos/brad/pccons # # existing files will NOT be overwritten unless -c is specified # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 105 -rw-r--r-- Makefile # 4472 -rw-r--r-- diffs # 1044 -r--r--r-- pccons.8 # 1604 -rw-r--r-- pccons.c # # ============= Makefile ============== if test -f 'Makefile' -a X"$1" != X"-c"; then echo 'x - skipping Makefile (File already exists)' else echo 'x - extracting Makefile (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile' && # X PROG= pccons MAN8= pccons.0 BINDIR= /usr/local/bin MANDIR= /usr/local/man/man X ..include <bsd.prog.mk> SHAR_EOF chmod 0644 Makefile || echo 'restore of Makefile failed' Wc_c="`wc -c < 'Makefile'`" test 105 -eq "$Wc_c" || echo 'Makefile: original size 105, current size' "$Wc_c" fi # ============= diffs ============== if test -f 'diffs' -a X"$1" != X"-c"; then echo 'x - skipping diffs (File already exists)' else echo 'x - extracting diffs (Text)' sed 's/^X//' << 'SHAR_EOF' > 'diffs' && *** pccons.c.orig Sun Jul 19 05:22:34 1992 --- pccons.c Sun Jul 19 07:27:25 1992 *************** *** 99,108 **** X pcprobe, pcattach, "pc", X }; X - /* block cursor so wfj does not go blind on laptop hunting for - the verdamnt cursor -wfj */ - #define FAT_CURSOR - X #define COL 80 X #define ROW 25 X #define CHR 2 --- 99,104 ---- *************** *** 120,125 **** --- 116,126 ---- X static char *more_chars; X static int char_count; X + static int keybd_flags; + #define IGNORE_SHIFT (!(keybd_flags & TIOCKEYBD_SHIFT)) + #define IGNORE_CAPS_LOCK (keybd_flags & TIOCKEYBD_CAPSLOCK) + #define FAT_CURSOR (keybd_flags & TIOCKEYBD_CURSOR_BLOCK) + X /* X * We check the console periodically to make sure X * that it hasn't wedged. Unfortunately, if an XOFF *************** *** 280,287 **** X #endif X if (!openf) X return; ! while (*cp) ! (*linesw[pccons.t_line].l_rint)(*cp++ & 0xff, &pccons); X } X X pcioctl(dev, cmd, data, flag) --- 281,290 ---- X #endif X if (!openf) X return; ! while (c = *cp++ & 0xff) { ! if (c == 0xff) c = 0; ! (*linesw[pccons.t_line].l_rint)(c, &pccons); ! } X } X X pcioctl(dev, cmd, data, flag) *************** *** 297,302 **** --- 300,313 ---- X error = ttioctl(tp, cmd, data, flag); X if (error >= 0) X return (error); + switch (cmd) { + case TIOCKEYBDG: + *(int *)data = keybd_flags; + return 0; + case TIOCKEYBDS: + keybd_flags = *(int *)data; + return 0; + } X return (ENOTTY); X } X *************** *** 470,481 **** X outb(addr_6845+1, pos>> 8); X outb(addr_6845, 15); X outb(addr_6845+1, pos); ! #ifdef FAT_CURSOR X outb(addr_6845, 10); X outb(addr_6845+1, 0); X outb(addr_6845, 11); X outb(addr_6845+1, 18); ! #endif FAT_CURSOR X if (a == 0) X timeout(cursor, 0, hz/10); X } --- 481,494 ---- X outb(addr_6845+1, pos>> 8); X outb(addr_6845, 15); X outb(addr_6845+1, pos); ! ! if (FAT_CURSOR) { X outb(addr_6845, 10); X outb(addr_6845+1, 0); X outb(addr_6845, 11); X outb(addr_6845+1, 18); ! } ! X if (a == 0) X timeout(cursor, 0, hz/10); X } *************** *** 1095,1101 **** X NONE, "", "", "", /* 0 unused */ X ASCII, "\033", "\033", "\033", /* 1 ESCape */ X ASCII, "1", "!", "!", /* 2 1 */ ! ASCII, "2", "@", "\000", /* 3 2 */ X ASCII, "3", "#", "#", /* 4 3 */ X ASCII, "4", "$", "$", /* 5 4 */ X ASCII, "5", "%", "%", /* 6 5 */ --- 1108,1114 ---- X NONE, "", "", "", /* 0 unused */ X ASCII, "\033", "\033", "\033", /* 1 ESCape */ X ASCII, "1", "!", "!", /* 2 1 */ ! ASCII, "2", "@", "\377", /* 3 2 */ X ASCII, "3", "#", "#", /* 4 3 */ X ASCII, "4", "$", "$", /* 5 4 */ X ASCII, "5", "%", "%", /* 6 5 */ *************** *** 1301,1306 **** --- 1314,1323 ---- X case CTL: X ctrl_down = 0; X break; + case CAPS: + if (IGNORE_CAPS_LOCK) + ctrl_down = 0; + break; X } X } X else *************** *** 1319,1326 **** X update_led(); X break; X case CAPS: ! caps ^= 1; ! update_led(); X break; X case SCROLL: X scroll ^= 1; --- 1336,1346 ---- X update_led(); X break; X case CAPS: ! if (!IGNORE_CAPS_LOCK) { ! caps ^= 1; ! update_led(); ! } else ! ctrl_down = 1; X break; X case SCROLL: X scroll ^= 1; *************** *** 1342,1349 **** X case ASCII: X case NONE: X case FUNC: ! if (shift_down) ! more_chars = scan_codes[dt].shift; X else if (ctrl_down) X more_chars = scan_codes[dt].ctrl; X else --- 1362,1369 ---- X case ASCII: X case NONE: X case FUNC: ! if (shift_down && (IGNORE_SHIFT || !ctrl_down)) ! more_chars = scan_codes[dt].shift; X else if (ctrl_down) X more_chars = scan_codes[dt].ctrl; X else *** ioctl.h.orig Sun Jul 19 05:25:29 1992 --- ioctl.h Sun Jul 19 05:55:05 1992 *************** *** 146,151 **** --- 146,157 ---- X #define TIOCSIG _IO('t', 95) /* pty: generate signal */ X #define TIOCDRAIN _IO('t', 94) /* wait till output drained */ X + #define TIOCKEYBDG _IOR('t', 90, int) /* get keyboard flags */ + #define TIOCKEYBDS _IOW('t', 90, int) /* set keyboard flags */ + #define TIOCKEYBD_SHIFT 0x01 /* shift looses to cntrl */ + #define TIOCKEYBD_CAPSLOCK 0x02 /* caps lock becomes shift */ + #define TIOCKEYBD_CURSOR_BLOCK 0x10 /* cursor is block */ + X #define TTYDISC 0 /* termios tty line discipline */ X #define TABLDISC 3 /* tablet discipline */ X #define SLIPDISC 4 /* serial IP discipline */ SHAR_EOF chmod 0644 diffs || echo 'restore of diffs failed' Wc_c="`wc -c < 'diffs'`" test 4472 -eq "$Wc_c" || echo 'diffs: original size 4472, current size' "$Wc_c" fi # ============= pccons.8 ============== if test -f 'pccons.8' -a X"$1" != X"-c"; then echo 'x - skipping pccons.8 (File already exists)' else echo 'x - extracting pccons.8 (Text)' sed 's/^X//' << 'SHAR_EOF' > 'pccons.8' && ..\" ..\" @(#)pccons.8 ..\" ..Dd July 19, 1992 ..Dt PCCONS 8 ..Os ..Sh NAME ..Nm pccons ..Nd set PC console attributes ..Sh SYNOPSIS ..Nm pccons ..Op Ar options ... ..Sh DESCRIPTION ..Pp ..Nm pccons allows the user to set, reset and view various PC console attributes by name. ..Ar options are words describing each attribute. If an option is "negated" with a "-", the option is turned off. ..Pp The following options are available: ..Bl -tag -width flag ..It shift Ignore the shift key if the control key is pressed. Helpful for hitting keys like "control+shift+underscore". ..It caps-lock Turn the "CapsLock" key into a substitute for the "control" key. ..It block-cursor Make the cursor into a large block. Helpful for LCD screens with poor contrast. ..El ..Sh ERRORS ..Pp If /dev/console does not support the proper ioctl() calls, ..Er ENOTTY will be returned and ..Nm pccons will return 1. ..Sh DIAGNOSTICS ..Pp The ..Nm pccons utility exits 0 on success, and >0 if an error occurs. ..Sh SEE ALSO ..Xr console 4 ..Sh BUGS does not handle partial matches of keywords SHAR_EOF chmod 0444 pccons.8 || echo 'restore of pccons.8 failed' Wc_c="`wc -c < 'pccons.8'`" test 1044 -eq "$Wc_c" || echo 'pccons.8: original size 1044, current size' "$Wc_c" fi # ============= pccons.c ============== if test -f 'pccons.c' -a X"$1" != X"-c"; then echo 'x - skipping pccons.c (File already exists)' else echo 'x - extracting pccons.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'pccons.c' && /* X pccons.c - get/set/clear pc console and keyboard attributes X X Brad Parker <brad@cayman.com> */ X #include <stdio.h> #include <fcntl.h> #include <sys/ioctl.h> X struct { X char *word; X int bits; } flag_words[] = { X "shift", TIOCKEYBD_SHIFT, X "caps-lock", TIOCKEYBD_CAPSLOCK, X "block-cursor", TIOCKEYBD_CURSOR_BLOCK, X "", 0 X }; X main(argc, argv) int argc; char *argv[]; { X int fd, result, i, j; X int flags; X X if ((fd = open("/dev/console", O_RDWR)) < 0) { X perror("/dev/console"); X exit(1); X } X X result = ioctl(fd, TIOCKEYBDG, &flags); X if (result != 0) { X perror("TIOCKEYBDG"); X exit(1); X } X X if (argc == 1) X show(flags); X else { X for (i = 1; i < argc; i++) { X int set = 1; X X if (argv[i][0] == '-') { X set = 0; X argv[i]++; X } X X for (j = 0; flag_words[j].word[0]; j++) { X if (strcmp(argv[i], flag_words[j].word) == 0) { X if (set) X flags |= flag_words[j].bits; X else X flags &= ~flag_words[j].bits; X break; X } X } X X if (flag_words[j].word[0] == 0) X help(); X } X X result = ioctl(fd, TIOCKEYBDS, &flags); X if (result != 0) { X perror("TIOCKEYBDS"); X exit(1); X } X } X X return 0; } X help() { X int j; X X printf("set/clear/view pc console flags\n"); X printf("usage: pccons [ <flags> ]\n"); X printf("valid flags: "); X for (j = 0; flag_words[j].word[0]; j++) X printf("%s ", flag_words[j].word); X printf("\n"); } X show(flags) int flags; { X int j; X X printf("pc console flags: "); X if (flags == 0) X printf("<none>"); X else X for (j = 0; flag_words[j].word[0]; j++) X if (flags & flag_words[j].bits) X printf("%s ", flag_words[j].word); X printf("\n"); } SHAR_EOF chmod 0644 pccons.c || echo 'restore of pccons.c failed' Wc_c="`wc -c < 'pccons.c'`" test 1604 -eq "$Wc_c" || echo 'pccons.c: original size 1604, current size' "$Wc_c" fi exit 0 -- A metaphor is like a simile. Brad Parker Cayman Systems, Inc., Cambridge, Ma. brad@cayman.com