v15i078: kbmap source posting
Tony Field
tony at ajfcal.cpsc.ucalgary.ca
Mon Oct 15 11:46:23 AEST 1990
Posting-number: Volume 15, Issue 78
Submitted-by: Tony Field <tony at ajfcal.cpsc.ucalgary.ca>
Archive-name: kbmap/part01
"kbmap" is an attempt to modify the AT&T Unix SysV/386 v3.2.2 system
keyboard map. In particular, it can make minor adjustments to the
system's keyboard scancodes to allow all "alt" keys to be used in the
gnuemacs meta-commands. Aside from the system default and emacs maps, any
keyboard map may be manually added to a "kbmap.table" file.
tony...
--------------------------------------------------------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: Readme kbmap.doc kbmap.1 kbmap.c Makefile
# Wrapped by ajf at ajfcal on Sun Sep 9 18:53:46 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Readme' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Readme'\"
else
echo shar: Extracting \"'Readme'\" \(1425 characters\)
sed "s/^X//" >'Readme' <<'END_OF_FILE'
X"kbmap" is an attempt to modify the AT&T Unix SysV/386 v3.2.2 system
Xkeyboard map. In particular, it can make minor adjustments to the
Xsystem's keyboard scancodes to allow all "alt" keys to be used in the
Xgnuemacs meta-mode. Aside from the system default and emacs maps, any
Xkeyboard map may be manually added to a "kbmap.table" file.
X
XTwo gnuemacs mappings are available: one that uses the ALT key to
Xgenerate 8th bit set letters (<letter>|0x080) and another that follows
XAT&T conventions such that the ALT key generates (<esc>N<letter>).
X
XNote that X11R2 will not recognize 8th bit set letters. If you have
XX11R2 and ascii console users, then you should use the 'conventional
X<esc>N<letter> mapping - even so, X11 uses it's own keyboard mapping
Xwhich is similar to, but not the same as, the default map. X11 will NOT
Xrecognize the mappings provided by kbmap. The differences are mostly in
Xthe assignment of the keyboard arrow keys to become Dec'ish in nature.
X
XTo add to the havoc, vtlmgr also takes liberties and twiddles the
Xkeyboard mapping.
X
Xkbmap works on AT&T Unix SysV/386 v3.2.2. It may or may not work on other
Xversions of unix.
X
X
XINSTALLATION: Modify the Makefile to select your compiler, default
X bin directory and default map table name.
X
X Then: make all
X
X Then: read the SETUP section "kbmap.doc" to install
X
Xtony...
END_OF_FILE
if test 1425 -ne `wc -c <'Readme'`; then
echo shar: \"'Readme'\" unpacked with wrong size!
fi
# end of 'Readme'
fi
if test -f 'kbmap.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'kbmap.doc'\"
else
echo shar: Extracting \"'kbmap.doc'\" \(6313 characters\)
sed "s/^X//" >'kbmap.doc' <<'END_OF_FILE'
X
X
X KBMAP(1) Unix System V KBMAP(1)
X
X
X NAME
X kbmap - change keyboard scancode mapping
X
X SYNOPSIS
X kbmap [-i] [-1] [-g] [-n n] [d] [-e] [-m] [-a] [-t /dev/xxx] [file]
X -i = show index of available maps
X -q = query which table is currently in use
X -g = generate a key map table
X -n n = set keyboard to map 'n' mapping
X -d = set keyboard to normal mapping
X -e = set keyboard to <esc>N emacs mapping
X -m = set keyboard to meta (8bit) emacs mapping
X -a = do not convert <alt><ctl> and <alt><shf><ctl>
X -t /dev/xxx = apply map to this device
X file = use specified key map file
X
X
X DESCRIPTION
X Kbmap reads a text file containg keyboard mapping
X information and set the keyboard to the selected mapping.
X
X Kbmap can create a standard mapping file
X (/local/lib/kbmap.table) that contains the system default
X mapping as well as an two different emacs mapping that allow
X alt to be used as the emacs meta-key. Other keyboard
X mappings may be manually added to the kbmap.table file.
X
X Only root may use this programme from the console.
X
X It cannot be run from an rc2.d/xxx file or cron.
X
X True META mapping (with 8th bit set) set with -m cannot be
X used with X11R2 (X11 does not use the standard keyboard
X maps). If you use X11R2 and the ascii console environments,
X the -e option should be used for emacs mapping simply to
X ensure that the .emacs files can be used in either mode
X without change.
X
X
X OPTIONS
X -i Show index of maps recorded in map.table. The map
X numbers may be used with the -n option to select maps
X by number.
X
X
X -q The query option causes the current scancode table in
X the kernal to be compared to all of the tables in
X kbmap.table. If a match is found, the name of the
X currently active table is printed.
X
X If vtlmgr is used, then an attempt is made to identify
X which keyboard map is in use in spite of modifications
X
X
X Page 1 (printed 9/9/90)
X
X
X KBMAP(1) Unix System V KBMAP(1)
X
X
X made by vtlmgr.
X
X
X -g Generate a new keyboard map file. The systems current
X keyboard map is retrieved and written to the
X kbmap.table file. Two mapping files for emacs are
X appended. The system's keyboard map is not updated.
X
X
X file Select file to be the generated keyboard map file,
X usually kbmap.table.
X
X
X -d Select the system default map from kbmap.table and
X update the system's current keyboard map.
X
X
X -e Select the emacs default map from kbmap.table and
X update the system's current keyboard map. Emacs users
X may use alt as the meta-key. If you press the alt key
X and a letter together, the letter is generated with the
X escape sequence <esc>N<letter>.
X
X If this mapping is used, the .emacs files should
X contain the following:
X
X (define-key global-map "\M-N" 'ESC-prefix)
X
X to enable the recognition of the new escape sequences.
X
X The only significant change to the AT&T standard
X keyboard mapping is that the <alt><del> meta is enabled
X to allow backward-kill-word.
X
X
X -m Select the emacs meta-key 8th bit map from kbmap.table
X and update the system's current keyboard map. Emacs
X users may use alt as the meta-key. If you press the
X alt key and a letter together, the letter is generated
X as <letter> | 0x080.
X
X If this mapping is used, the .emacs files should
X contain the following:
X
X (setq meta-flag t)
X
X to enable the recognition 8th bit set meta characters.
X
X X11R2 will not recognize 8th bit set characters. As a
X result, the -m option should not be used if you intend
X to run emacs with X11R2.
X
X
X Page 2 (printed 9/9/90)
X
X
X KBMAP(1) Unix System V KBMAP(1)
X
X
X -n i Select the i'th map from the kbmap.table file and
X update the system. The system default map is 0 and the
X emacs map is 1 or 2. If other keyboard maps are added
X to the end of the kbmap.table file, then they may be
X accessed by number.
X
X
X -a Normally, kbmap extends mapping for <alt><ctl> and
X <alt><shif><ctl> keys. If the -a option is used, these
X will be disabled.
X
X If the -a is used, then the gnuemacs C-M- sequences
X (such as C-M-s (isearch-forward-regexp)) cannot use the
X <alt><ctl><letter> combinations. Instead, the <esc> +
X <ctl><letter> sequence is used.
X
X
X -t /dev/xxx
X Use the specified device rather than stdin. (This is
X not really useful.)
X
X
X SETUP
X Create a basic keyboard mapping file that contains both the
X standard map and the emacs meta-key map:
X
X kbmap -g kbmap.table
X
X The current keyboard table is fetched. The current mapping
X information as described in the keymap_t structure is
X written to disk file kbmap.table. The meta-conversion for
X emacs is performed on the structure and the resulting
X information is appended to kbmap.table. The new information
X is NOT updated in the kernal.
X
X Copy kbmap.table to /local/lib/kbmap.table (or other file as
X specified during system compilation.) Any keyboard
X mapping may now be selected (using the default file
X /local/lib/kbmap.table):
X
X kbmap -d = select default map
X kbmap -e = select emacs <esc>N<letter> map
X kbmap -m = select emacs <letter>|0x080 meta map
X
X Alternatively, the key mapping may be selected by number:
X
X kbmap -m 0 = select map 0 (default map)
X kbmap -m 1 = select map 1 (emacs <letter>|0x08 meta-map)
X kbmap -m 2 = select map 2 (normal <esc>N<letter> emacs)
X kbmap -m 3 = select map 3 (your additional)
X etc.
X
X
X Page 3 (printed 9/9/90)
X
X
X KBMAP(1) Unix System V KBMAP(1)
X
X
X NOTES
X The changes made by kbmap are reset to system defaults
X whenever the system is booted. If permanent changes are
X needed, then the system default mapping in
X /etc/conf/pack.d/kd/Driver.o should be "zapped" with the
X appropriate table and the kernal rebuilt.
X
X
X FILES
X /local/lib/kbmap.table
X
X
X AUTHOR
X Tony Field (tony%ajfcal at cpsc.ucalgary.ca, tony at ajfcal)
X
X
X Page 4 (printed 9/9/90)
X
X
END_OF_FILE
if test 6313 -ne `wc -c <'kbmap.doc'`; then
echo shar: \"'kbmap.doc'\" unpacked with wrong size!
fi
# end of 'kbmap.doc'
fi
if test -f 'kbmap.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'kbmap.1'\"
else
echo shar: Extracting \"'kbmap.1'\" \(5749 characters\)
sed "s/^X//" >'kbmap.1' <<'END_OF_FILE'
X.TH KBMAP 1 ""
X.SH NAME
Xkbmap \- change keyboard scancode mapping
X.SH SYNOPSIS
X.nf
X
Xkbmap [-i] [-1] [-g] [-n n] [d] [-e] [-m] [-a] [-t /dev/xxx] [file]
X -i = show index of available maps
X -q = query which table is currently in use
X -g = generate a key map table
X -n n = set keyboard to map 'n' mapping
X -d = set keyboard to normal mapping
X -e = set keyboard to <esc>N emacs mapping
X -m = set keyboard to meta (8bit) emacs mapping
X -a = do not convert <alt><ctl> and <alt><shf><ctl>
X -t /dev/xxx = apply map to this device
X file = use specified key map file
X.fi
X
X.SH DESCRIPTION
X
XKbmap reads a text file containg keyboard mapping information and
Xset the keyboard to the selected mapping.
X
XKbmap can create a standard mapping file (/local/lib/kbmap.table)
Xthat contains the system default mapping as well as an two different
Xemacs mapping that allow
X.B alt
Xto be used as the emacs meta-key. Other
Xkeyboard mappings may be manually added to the kbmap.table file.
X
XOnly root may use this programme from the console.
X
XIt cannot be run from an rc2.d/xxx file or cron.
X
XTrue META mapping (with 8th bit set) set with -m cannot be used with
XX11R2 (X11 does not use the standard keyboard maps). If you use
XX11R2 and the ascii console environments, the
X.B \-e
Xoption should be used for emacs mapping simply to ensure that
Xthe .emacs files can be used in either mode without change.
X
X.SH OPTIONS
X.TP
X.B \-i
XShow index of maps recorded in map.table. The map numbers
Xmay be used with the
X.B \-n
Xoption to select maps by number.
X
X.TP
X.B \-q
XThe query option causes the current scancode table
Xin the kernal to be compared to all of the tables in
X.B kbmap.table.
XIf a match is found, the name of the currently
Xactive table is printed.
X
XIf vtlmgr is used, then an attempt is made to
Xidentify which keyboard map is in use in spite
Xof modifications made by vtlmgr.
X
X.TP
X.B \-g
XGenerate a new keyboard map file. The systems current keyboard
Xmap is retrieved and written to the
X.B kbmap.table
Xfile. Two mapping files for emacs are appended.
XThe system's keyboard map is not updated.
X
X.TP
X.B file
XSelect
X.B file
Xto be the generated keyboard map file, usually
X.B kbmap.table.
X
X.TP
X.B \-d
XSelect the system default map from
X.B kbmap.table
Xand update the system's current keyboard map.
X
X.TP
X.B \-e
XSelect the emacs default map from
X.B kbmap.table
Xand update the system's current keyboard map. Emacs
Xusers may use
X.B alt
Xas the meta-key. If you press
Xthe
X.B alt
Xkey and a letter together, the letter is generated with
Xthe escape sequence <esc>N<letter>.
X
XIf this mapping is used, the \.emacs files should contain
Xthe following:
X.nf
X
X (define-key global-map "\\M-N" 'ESC-prefix)
X.fi
X
Xto enable the recognition of the new escape sequences.
X
XThe only significant change to the AT&T standard
Xkeyboard mapping is that the <alt><del> meta is
Xenabled to allow backward-kill-word.
X
X.TP
X.B \-m
XSelect the emacs meta-key 8th bit map from
X.B kbmap.table
Xand update the system's current keyboard map. Emacs
Xusers may use
X.B alt
Xas the meta-key. If you press
Xthe
X.B alt
Xkey and a letter together, the letter is generated
Xas <letter> | 0x080.
X
XIf this mapping is used, the \.emacs files should contain
Xthe following:
X.nf
X
X (setq meta-flag t)
X.fi
X
Xto enable the recognition 8th bit set meta characters.
X
XX11R2 will not recognize 8th bit set characters. As a result,
Xthe
X.B \-m
Xoption should not be used if you intend to run emacs with
XX11R2.
X
X.TP
X.B \-n i
XSelect the
X.B i'th
Xmap from the
X.B kbmap.table
Xfile and update the system. The system default map is
X.B 0
Xand the emacs map is
X.B 1
Xor
X.B 2.
XIf other keyboard maps are added to the end of the
X.B kbmap.table
Xfile, then they may be accessed by number.
X
X.TP
X.B \-a
XNormally, kbmap extends mapping for <alt><ctl>
Xand <alt><shif><ctl> keys. If the
X.B \-a
Xoption is used, these will be disabled.
X
XIf the
X.B \-a
Xis used, then the gnuemacs
XC-M- sequences (such as C-M-s (isearch-forward-regexp))
Xcannot use the <alt><ctl><letter> combinations. Instead,
Xthe <esc> + <ctl><letter> sequence is used.
X
X.TP
X.B \-t /dev/xxx
XUse the specified device rather than stdin.
X(This is not really useful.)
X
X.SH SETUP
X
XCreate a basic keyboard mapping file that contains both the
Xstandard map and the emacs meta-key map:
X
X.nf
X kbmap -g kbmap.table
X.fi
X
XThe current keyboard table is fetched. The current mapping
Xinformation as described in the
X.B keymap_t
Xstructure is written to
Xdisk file
X.B kbmap.table.
XThe meta-conversion for
X.B emacs
Xis performed on the structure and the resulting information is appended
Xto
X.B kbmap.table.
XThe new information is NOT updated in the kernal.
X
XCopy
X.B kbmap.table
Xto
X.B \/local\/lib\/kbmap.table
X(or other file as specified during system compilation.)
X
XAny keyboard mapping may now be selected (using the default
Xfile
X.B \/local\/lib\/kbmap.table):
X
X.nf
X kbmap -d = select default map
X kbmap -e = select emacs <esc>N<letter> map
X kbmap -m = select emacs <letter>|0x080 meta map
X.fi
X
XAlternatively, the key mapping may be selected by number:
X.nf
X
X kbmap -m 0 = select map 0 (default map)
X kbmap -m 1 = select map 1 (emacs <letter>|0x08 meta-map)
X kbmap -m 2 = select map 2 (normal <esc>N<letter> emacs)
X kbmap -m 3 = select map 3 (your additional)
X etc.
X.fi
X
X.SH NOTES
X
XThe changes made by kbmap are reset to system defaults whenever
Xthe system is booted. If permanent changes are needed, then
Xthe system default mapping in /etc/conf/pack.d/kd/Driver.o
Xshould be "zapped" with the appropriate table and the kernal
Xrebuilt.
X
X.SH FILES
X
X/local/lib/kbmap.table
X
X.SH AUTHOR
X
XTony Field (tony%ajfcal at cpsc.ucalgary.ca, tony at ajfcal)
END_OF_FILE
if test 5749 -ne `wc -c <'kbmap.1'`; then
echo shar: \"'kbmap.1'\" unpacked with wrong size!
fi
# end of 'kbmap.1'
fi
if test -f 'kbmap.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'kbmap.c'\"
else
echo shar: Extracting \"'kbmap.c'\" \(18744 characters\)
sed "s/^X//" >'kbmap.c' <<'END_OF_FILE'
X/* ta=4 tabs set at 4*/
X/*
X kbmap.c
X
X Kbmap reads a text file containg keyboard mapping information and
X set the keyboard to the selected mapping. It can also create
X a map file with the -g option.
X
X Only root may use this programme from the console.
X It cannot be run from an rc2.d/xxx file or cron.
X
X Then true-meta keys cannot be used with X11R2 - which uses its own map.
X VTLMGR tends to modify a couple of keys. The -q option (query_map())
X tries to detect a vtlmgr modification.
X
X This works for AT&T Unix 3.2.2 - other systems not tested.
X
XAUTHOR: Tony Field (tony%ajfcal at cpsc.ucalgary.ca)
X
XNOTES:
X
X Structure of keyboard translation table (from /usr/include/sys/kd.h)
X
X #define NUM_KEYS 256 Maximum number of keys
X #define NUM_STATES 8 Number of key states
X #pragma pack(2)
X typedef struct {
X short n_keys ; Number of entries in table
X struct key_t {
X unsigned char map[NUM_STATES]; Key code for each state
X unsigned char spcl; Bits marking states as special
X unsigned char flgs; Flags
X } key[NUM_KEYS+1]; One entry for each key
X } keymap_t;
X
X (note: NUM_KEYS is specified as 256, however n_keys only
X describes 128 keys... kbmap only updates the first
X 128 keys. The remainder are unmodified.)
X
X Each key has 8 (NUM_STATES) possible scan states honoured if
X set in the "spcl" field:
X
X spcl map[i]
X bit 7 i=0 = normal
X 6 1 = shifted
X 5 2 = control
X 4 3 = shift-control
X 3 4 = alt
X 2 5 = alt-shift
X 1 6 = alt-control
X 0 7 = alt-shift-control
X
X If the corresponding bit is set, then the feature is enabled. For
X example, if bit 3 is set, then the keyboard driver will translate
X the scan code into the "<esc>Nx" escape sequence. If the 3ed bit is
X NOT set, then the driver will use the character as specified in
X map[4] as the returned value.
X
X The "flgs" field needs no modification: it allows the "numlok",
X "caploc" and "control" keys to be used with specific keys:
X
X 0x8000 allow numlock
X 0x4000 allow caps lock
X 0x2000 allow control
X 0x1000 locking is off
X
X At leaset that is what <sys/kd.h> indicates. But that is not
X what is indicated in the actual dump of the tables... Alphabetic
X characters contain 0x01, the numeric keypad contains 0x02, and
X verything else contains 0x00. Oh well... A more reasonable
X interpretation is that these meanings are assigned to the
X high order 4 bits of "spcl", but that is only a guess.
X
X In addition, the default value for the map[4] entry for most codes
X that can be translated into the <esc>Nx sequence is 0x7d.
X The 7x numbers are used for function key translation. They mean
X (of course i am guessing):
X
X 7d = use <esc>Nx where 'x' is the un-alted value
X 7e = use <esc>Ox of the scan code (funny that 7e
X 7f = use <esc>Lx and 7f do not appear in the table
X nor are visible in keyboard(7))
X
X Conversion of the table to emacs "meta" bits is done as follows:
X
X 1. read the entire keyboard mapping structure with ioctl().
X 2. if the base key (map[0]) is between ' ' & 0x7f and not uppercase
X then remove bit 3 from the spcl field and
X set map[4] = map[0] | 0x80. The creates the
X meta-mapping of the keys for lower case letters.
X 3. if the shifted key (map[1]) is between ' ' & 0x7f and the
X map[0] value is not an upper case character,
X then remove bit 2 from the spcl field and
X set map[5] = map[1] | 0x80. The creates the
X meta-mapping of the keys for upper case letters.
X 4. write the new keyboard mapping with ioctl().
X
X Similar conversion is make for the "normal" emacs <esc>N prefix
X sequence. This requires forcing the 0x7d code into all <alt>x slots.
X
X The map structure contains map[0] entries for both lower and upper
X case letters. The lower case entries "seem" to be the only ones
X used. No explanation is offered for the upper case entries.
X*/
X
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/at_ansi.h>
X#include <sys/kd.h>
X#include <sys/ioctl.h>
X#include <fcntl.h>
X
X/* where does kbmap expect to find the default map table */
X
X#ifndef DEFAULTMAP
X#define DEFAULTMAP "/local/lib/kbmap.table"
X#endif
X
Xchar progname[150];
Xint vtlmgr;
X
Xmain (argc, argv)
Xint argc;
Xchar *argv[];
X{
X extern char *optarg;
X extern int optind;
X int c;
X int select_map = -1;
X char use_file[200];
X int generate_file = 0;
X FILE *use_fp, *open_file();
X char tfile[100];
X int tn = -1;
X int index_only = 0;
X char line[200];
X int query_only = 0;
X int option_count = 0;
X int also_alt_ctl = 1;
X
X strcpy (progname, argv[0]);
X use_fp = NULL;
X use_file[0] = '\0';
X if (argc == 1 || strcmp (argv[1], "-") == 0 || strcmp (argv[1], "--") == 0)
X usage();
X
X while ((c = getopt(argc, argv, "aqgin:dmet:-?")) != -1)
X { option_count++;
X switch (c)
X {
X case 'a': also_alt_ctl = 0; /* disable alt+ctl expansion */
X break;
X case 'i': index_only = 1;
X break;
X case 'n': select_map = atoi (optarg); /* select by number */
X break;
X case 'd': select_map = 0; /* select default = 0 */
X if (use_file[0] == '\0')
X strcpy (use_file, DEFAULTMAP);
X break;
X case 'e': select_map = 2; /* select emacs = 2 */
X if (use_file[0] == '\0')
X strcpy (use_file, DEFAULTMAP);
X break;
X case 'm': select_map = 1; /* select emacs = 1 (meta) */
X if (use_file[0] == '\0')
X strcpy (use_file, DEFAULTMAP);
X break;
X case 't': strcpy (tfile, optarg); /* use terminal at /dev/xxxx */
X if ((tn = open (tfile, O_RDWR)) < 0)
X { fprintf (stderr, "%s: Cannot open %s\n", progname, tfile);
X exit (1);
X }
X break;
X case 'q': query_only = 1;
X break;
X case 'g': generate_file = 1; /* generate map file */
X if (use_file[0] == '\0')
X strcpy (use_file, DEFAULTMAP);
X break;
X
X default: usage ();
X }
X }
X if (optind < argc)
X { strcpy (use_file, argv[optind]); /* specify map file */
X if (option_count == 0)
X index_only = 1;
X }
X
X if (tn < 1)
X tn = 0;
X
X if (index_only) /* show index of maps */
X { use_fp = open_file (use_file, "r");
X c = 0;
X while (fgets (line, 190, use_fp) != NULL)
X if (strncmp (line, "...", 3) == 0)
X printf ("map %d = %s", c++, line + 3);
X fclose (use_fp);
X exit (0);
X }
X
X if (query_only) /* which map is in use */
X { use_fp = open_file (use_file, "r");
X if (query_map (use_fp) == 0)
X printf ("current map is not in %s\n", use_file);
X exit (0);
X }
X
X if (generate_file) /* create new kbmap.table file */
X { if (use_file[0])
X { use_fp = open_file (use_file, "w");
X create_table (use_fp, tn, also_alt_ctl);
X fclose (use_fp);
X }
X else
X create_table (stdout, tn, also_alt_ctl);
X }
X
X if (select_map >= 0)
X { use_fp = open_file (use_file, "r");
X update_map (use_fp, select_map);
X fclose (use_fp);
X }
X
X exit (0);
X}
X
X/****************************************************************************
X* create_table (fp) *
X* Get the existing keyboard mapping structure and write to file. *
X* Translate all alt and alt-shift keys to the meta-mapping. *
X* Write the meta-mapping structure to disk file. *
X****************************************************************************/
X
Xcreate_table (fp, tn, also_alt_ctl)
XFILE *fp; /* file containing the keyboard maps */
Xint tn;
Xint also_alt_ctl; /* convert ALT/CTL and ALT/SHIFT/CTL as well? */
X{
X int i, j, cb, cs;
X keymap_t kt;
X char title[200];
X
X /* get existing mapping */
X
X if (ioctl (tn, GIO_KEYMAP, &kt))
X ioctl_failure ('r');
X
X /* write the existing mapping to the disk file
X
X some potentiall useful keyboard scan numbers:
X
X 1 esc
X 14 bs
X 15 tab
X 28 cr
X 83 del
X 116 cr
X 119 break
X 121 del
X
X For example, if scan code 1 (esc) is specifically selected,
X then the <ALT><ESC> combination becomes available. This is
X not done because double-striking <esc> is quite easy.
X
X It might be useful to force full alt-decoding for cr and tab.
X Emacs would recognize such sequences by default (see comments
X in the code to make this modification)
X
X The variable sequence is:
X char scan scpl flgs NORMAL SHIFT CTRL SHFCTL ALT ALTSHF ALTCTL ALTSHFCTL
X */
X
X header (fp, "system default keyboard mapping", -1);
X for (i = 0; i < kt.n_keys; i++)
X {
X cb = kt.key[i].map[0];
X cs = kt.key[i].map[1];
X fprintf (fp, "%c%c %3d %02x %02x",
X cb > ' ' && cb < 127 ? cb : ' ',
X cs > ' ' && cs < 127 && cs != cb ? cs : ' ',
X i,
X kt.key[i].spcl & 0x0ff,
X kt.key[i].flgs & 0x0ff);
X for (j = 0; j < NUM_STATES; j++)
X fprintf (fp, " %02x", kt.key[i].map[j]);
X fprintf (fp, "\n");
X }
X
X /* convert the existing mapping to emacs-meta (8th bit set) conventions
X and write to file
X */
X
X fprintf (fp, "\n\n");
X strcpy (title, "emacs 8th bit set (<letter>|0x080) meta mapping");
X header (fp, title, also_alt_ctl);
X for (i = 0; i < kt.n_keys; i++)
X {
X cb = kt.key[i].map[NORMAL]; /* base char */
X cs = kt.key[i].map[SHIFT]; /* shifted char */
X
X if (1) /* things to ignore e,g, (i == 121) */
X {
X /* convert ALT key to meta. */
X
X /* add the following the various "if" statements below
X to enable full conversion of \t and \n:
X
X || (i == 15) || (i == 28)
X */
X if ((cb >= ' ' && cb < 'A') || (cb > 'Z' && cb <= 127))
X { kt.key[i].map[ALT] = (kt.key[i].map[NORMAL] | 0x080);
X kt.key[i].spcl &= 0x0f7;
X }
X
X /* convert ALT-CTRL key to meta. (dont include <alt><ctl><del> */
X
X if (also_alt_ctl
X && ((cb >= ' ' && cb < 'A') || (cb > 'Z' && cb < 127)))
X { kt.key[i].map[ALTCTL] = (kt.key[i].map[CTRL] | 0x080);
X kt.key[i].spcl &= 0x0fd;
X }
X
X /* convert ALT-SHIFT to meta */
X
X if (((cb >= ' ' && cb < 'A') || (cb > 'Z' && cb <= 127))
X && (cs >= ' ' && cs <= 127))
X { kt.key[i].map[ALTSHF] = (kt.key[i].map[SHIFT] | 0x080);
X kt.key[i].spcl &= 0x0fb;
X }
X
X /* convert ALT-SHIFT-CTL to meta */
X
X if (also_alt_ctl
X && ((cb >= ' ' && cb < 'A') || (cb > 'Z' && cb <= 127))
X && (cs >= ' ' && cs <= 127))
X { kt.key[i].map[ALTSHFCTL] = (kt.key[i].map[SHFCTL] | 0x080);
X kt.key[i].spcl &= 0x0fe;
X }
X }
X fprintf (fp, "%c%c %3d %02x %02x",
X cb > ' ' && cb < 127 ? cb : ' ',
X cs > ' ' && cs < 127 && cs != cb ? cs : ' ',
X i,
X kt.key[i].spcl & 0x0ff,
X kt.key[i].flgs & 0x0ff);
X for (j = 0; j < NUM_STATES; j++)
X fprintf (fp, " %02x", kt.key[i].map[j]);
X fprintf (fp, "\n");
X }
X
X /* re-get existing mapping to remove the above meta-conversion
X
X Set the k.key[i].map[xx] values to 0x7d. This seems to be
X the code that forces the <esc>N sequence durning translation
X */
X
X if (ioctl (tn, GIO_KEYMAP, &kt))
X ioctl_failure('r');
X
X fprintf (fp, "\n\n");
X strcpy (title, "emacs normal (<esc>N<letter>) meta mapping");
X header (fp, title, also_alt_ctl);
X for (i = 0; i < kt.n_keys; i++)
X {
X cb = kt.key[i].map[NORMAL]; /* base char */
X cs = kt.key[i].map[SHIFT]; /* shifted char */
X
X if (1) /* things to ignore */
X { /* make ALT converssion available */
X
X if ((cb >= ' ' && cb < 'A') || (cb > 'Z' && cb <= 127))
X { kt.key[i].map[ALT] = 0x7d;
X kt.key[i].spcl |= 0x08;
X }
X
X /* make ALT-CTL conversion available (dont include <alt><ctl><del> */
X
X if (also_alt_ctl
X && ((cb >= ' ' && cb < 'A') || (cb > 'Z' && cb < 127)))
X { kt.key[i].map[ALTCTL] = 0x7d;
X kt.key[i].spcl |= 0x02;
X }
X
X /* make ALT-SHIFT available */
X
X if (((cb >= ' ' && cb < 'A') || (cb > 'Z' && cb <= 127))
X && (cs >= ' ' && cs <= 127))
X { kt.key[i].map[ALTSHF] = 0x7d;
X kt.key[i].spcl |= 0x04;
X }
X
X /* make ALT-SHIFT-CTL available */
X
X if (also_alt_ctl
X && ((cb >= ' ' && cb < 'A') || (cb > 'Z' && cb <= 127))
X && (cs >= ' ' && cs <= 127))
X { kt.key[i].map[ALTSHFCTL] = 0x7d;
X kt.key[i].spcl |= 0x01;
X }
X }
X fprintf (fp, "%c%c %3d %02x %02x",
X cb > ' ' && cb < 127 ? cb : ' ',
X cs > ' ' && cs < 127 && cs != cb ? cs : ' ',
X i,
X kt.key[i].spcl & 0x0ff,
X kt.key[i].flgs & 0x0ff);
X for (j = 0; j < NUM_STATES; j++)
X fprintf (fp, " %02x", kt.key[i].map[j]);
X fprintf (fp, "\n");
X }
X
X}
X
X/****************************************************************************
X* header () *
X* Standard table header generation *
X****************************************************************************/
X
Xheader (fp, title, also_alt_ctl)
XFILE *fp;
Xchar *title;
X{ fprintf (fp, "...%s", title);
X if (also_alt_ctl == -1)
X fprintf (fp, "\n");
X else if (also_alt_ctl)
X fprintf (fp, " -- full alt/ctl\n");
X else
X fprintf (fp, " -- no alt/ctl\n");
X fprintf (fp, " alt\n");
X fprintf (fp, " shif alt alt shif\n");
X fprintf (fp, " key spcl flgs norm shif ctrl ctrl alt shif ctrl ctrl\n");
X fprintf (fp, "------ ---- ---- ---- ---- ---- ---- ---- ---- ---- ----\n");
X}
X
X
X/****************************************************************************
X* update_map (fp, which_map) *
X* Read the specified mapping table from the map file. Send the new map *
X* to key keyboard driver. *
X****************************************************************************/
X
Xupdate_map (fp, which_map)
XFILE *fp; /* file containing keyboard maps */
Xint which_map; /* select this table from the file (0..n) */
X{
X int i, j, how;
X keymap_t kt;
X
X /* find the desired map in the file and read it into the keytable */
X
X if (ioctl (1, GIO_KEYMAP, &kt)) /* read current map */
X ioctl_failure ('r');
X
X for (i = 0; i <= which_map; i++)
X how = read_map (i == which_map, fp, &kt, NULL);
X if (how)
X { fprintf (stderr, "%s: map %d not found\n", progname, which_map);
X exit (1);
X }
X if (ioctl (1, PIO_KEYMAP, &kt)) /* send found map to driver */
X ioctl_failure ('w');
X}
X
X/****************************************************************************
X* query_map (fp) *
X* Identifiy which table file map matches the keyboard map in use. *
X****************************************************************************/
X
Xquery_map (fp)
XFILE *fp; /* file containing keyboard maps */
X{
X int i, j, k;
X char text[200];
X keymap_t kt, inuse;
X int found;
X int vtlmgr;
X
X if (ioctl (1, GIO_KEYMAP, &inuse)) /* read current map */
X ioctl_failure ('r');
X
X vtlmgr = 0;
X found = 0;
X kt = inuse;
X for (k = 0; ; k++)
X { if (read_map (1, fp, &kt, text))
X return (found);
X for (i = 0; i < inuse.n_keys; i++)
X { for (j = 0; j < NUM_STATES; j++) /* compare all keys */
X { if (inuse.key[i].map[j] != kt.key[i].map[j])
X { /* detect minor mod made by vtlmgr in line 3 for "1!" */
X if (i == 2 && (j == ALTSHF || j == ALTSHFCTL))
X vtlmgr = 1;
X else
X goto next_map;
X }
X }
X }
X printf ("using map %d: %s\n", k, text);
X if (vtlmgr)
X printf (" (modified by vtlmgr)\n");
X found = 1;
X break;
Xnext_map: ;
X }
X return (found);
X}
X
X/****************************************************************************
X* read_map (fp, kt, title) *
X* Read the nextd mapping table from the map file. *
X****************************************************************************/
X
Xread_map (getit, fp, kt, title)
Xint getit; /* 1 = update kt, 0 = get title only */
XFILE *fp; /* file containing keyboard maps */
Xkeymap_t *kt; /* read structure into this */
Xchar *title; /* read title line into this buffer */
X{
X int i, j, cc;
X char key_line[200], *c;
X int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9;
X int good_read;
X
X /* find the next map in the file and read it into the keytable */
X
X while (good_read = (fgets (key_line, 199, fp) != NULL))
X { if (title != NULL && strncmp (key_line, "...", 3) == 0)
X { strcpy (title, key_line + 3);
X c = title;
X while (*c)
X { if (*c < ' ')
X { *c = '\0';
X break;
X }
X c++;
X }
X }
X else if (strncmp (key_line, "------ -", 8) == 0)
X break;
X }
X if (good_read == 0)
X return (-1);
X if (strncmp (key_line, "------ -", 8) != 0)
X bad_file ();
X
X if (getit == 0)
X return (1);
X for (i = 0; i < kt->n_keys; i++)
X { if (fgets (key_line, 199, fp) == NULL)
X bad_file ();
X if (atoi (key_line + 2) != i)
X bad_file ();
X sscanf (key_line + 7, "%x %x %x %x %x %x %x %x %x %x",
X &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9);
X kt->key[i].spcl = a0;
X kt->key[i].flgs = a1;
X kt->key[i].map[0] = a2;
X kt->key[i].map[1] = a3;
X kt->key[i].map[2] = a4;
X kt->key[i].map[3] = a5;
X kt->key[i].map[4] = a6;
X kt->key[i].map[5] = a7;
X kt->key[i].map[6] = a8;
X kt->key[i].map[7] = a9;
X
X }
X return (0);
X}
X
X/****************************************************************************
X* open_file (use_file, how) *
X* Open a table file. If there is a problem, quit now. *
X****************************************************************************/
X
XFILE *open_file (use_file, how)
Xchar *use_file;
Xchar *how;
X{ FILE *use_fp;
X char *strchr();
X
X if (*use_file == '\0')
X strcpy (use_file, DEFAULTMAP);
X
X if ((use_fp = fopen (use_file, how)) == NULL)
X { fprintf (stderr, "%s: cannot open file %s\n", progname, use_file);
X exit (1);
X }
X return (use_fp);
X}
X
X/****************************************************************************
X* bad_file () *
X****************************************************************************/
X
Xbad_file ()
X{
X fprintf (stderr, "%s: invalid key map file format\n", progname);
X exit (2);
X}
X
Xioctl_failure (how)
Xint how;
X{
X fprintf (stderr, "%s: ioctl failure, %s\n",
X progname, how == 'r' ? "cannot read, possibly using X11???" : "must be root?");
X exit (2);
X}
X
X/****************************************************************************
X* usage () *
X****************************************************************************/
X
Xusage ()
X{
X printf ("Usage: kbmap [-i] [-q] [-g] [-n n] [-d] [-e] [-m] [-1] [-t /dev/xxx] [file]\n");
X printf (" where: -i = show index of available maps\n");
X printf (" -q = identify map currenly in use\n");
X printf (" -g = generate a key map table\n");
X printf (" -n n = set keyboard to map 'n' mapping\n");
X printf (" -d = set keyboard to default mapping\n");
X printf (" -e = set keyboard to emacs mapping (<esc>N)\n");
X printf (" -m = set keyboard to emacs meta-mapping (8bit)\n");
X printf (" -a = disable <alt><ctl> & <alt><shf><ctl>\n");
X printf (" -t /dev/xxx = apply map to this device (default stdin)\n");
X printf (" file = use specified key map file\n");
X printf (" default = %s\n", DEFAULTMAP);
X exit (0);
X}
END_OF_FILE
if test 18744 -ne `wc -c <'kbmap.c'`; then
echo shar: \"'kbmap.c'\" unpacked with wrong size!
fi
# end of 'kbmap.c'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(509 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# k b m a p
X#
X# change the keyboard scan code mapping for AT&T unix SysV 3.2.2
X#
X# Select your compiler and options
X
XCC=gcc
XCFLAGS=-traditional
X
X# CC=cc
X# CFLAGS=
X
X# Set BINDIR as desired. Provide a name for the default keyboard map table.
X
XBINDIR = /local/bin
XMAPTABLE = /local/lib/kbmap.table
X
Xall:
X $(CC) $(CFLAGS) -DDEFAULTMAP="\"$(MAPTABLE)"\" kbmap.c -o kbmap
X
Xinstall:
X strip kbmap
X cp kbmap $(BINDIR)
X
Xshar:
X shar Readme kbmap.doc kbmap.1 kbmap.c Makefile > kbmap.shar
X
Xclean:
X rm -f *.o *.B *.BAK
END_OF_FILE
if test 509 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
echo shar: End of shell archive.
exit 0
More information about the Comp.sources.misc
mailing list