Dvorak keyboard software on a Sun (source included)
Ken Olum
kdo at lucid.com
Wed Mar 1 22:32:34 AEST 1989
Here is a program I use to provide Dvorak emulation.
#include <sys/types.h>
#include <sys/file.h>
#include <sundev/kbio.h>
#include <sundev/kbd.h>
#include <stdio.h>
/* Places on the sun3 keyboard where the keys that we hack begin */
#define sun3_top_row 54
#define sun3_middle_row 77
#define sun3_bottom_row 100
/* Strings that describe what to do. The 4 strings go into the normal, the
shift, the all-caps and the control table. In the control-table string only
uppercase characters (@ through _) represent their control-character values.
Other characters are unchanged */
char *normal_keys[4] = {
"qwertyuiopasdfghjkl;zxcvbnm,./" , /* normal */
"QWERTYUIOPASDFGHJKL:ZXCVBNM<>?" , /* shift */
"QWERTYUIOPASDFGHJKL;ZXCVBNM,./" , /* caps */
"QWERTYUIOPASDFGHJKL;ZXCVBNM,._"}; /* control */
char *dvorak_keys[4] = {
"/,.pyfgcrlaoeuidhtns;qjkxbmwvz", /* normal */
"?<>PYFGCRLAOEUIDHTNS:QJKXBMWVZ", /* shift */
"/,.PYFGCRLAOEUIDHTNS;QJKXBMWVZ", /* caps */
"_,.PYFGCRLAOEUIDHTNS QJKXBMWVZ"}; /* control */
/* Tell about how to use the program */
usage()
{
printf("Usage: 'dvorak on' or 'dvorak off'\n");
exit (1); }
main(argc,argv)
int argc;
char **argv;
{
int fd,type;
int dvorak; /* true if going to dvorak */
if (argc!=2) usage();
if (strcmp(argv[1],"on") == 0) dvorak = 1;
else if (strcmp(argv[1],"off") == 0) dvorak = 0;
else usage();
/* Open the keyboard device to hack on it */
if ((fd = open("/dev/kbd",O_RDONLY,0)) < 0)
xerror("Can't open /dev/kbd");
/* Check that the keyboard is the right type. They have different slots
so we could lose badly if it isn't the right one */
if (ioctl(fd, KIOCTYPE, &type) < 0)
xerror("Can't determine keyboard type");
if (type!=KB_SUN3) {
printf("This only works if you have a Sun-3 keyboard\n");
exit(1);}
/* Now do the work */
if (dvorak) set_key_set(fd, dvorak_keys);
else set_key_set(fd, normal_keys);
if (close(fd) < 0)
xerror("Can't close /dev/kbd");
}
set_key_set(fd, set)
char *set[4];
{
set_key_table(fd, 0, set[0]);
set_key_table(fd, SHIFTMASK, set[1]);
set_key_table(fd, CAPSMASK, set[2]); /* Caps is like shift */
set_key_table(fd, CTRLMASK, set[3]);
}
/* Set 30 keys on 3 rows */
set_key_table(fd, table, string)
int fd,table;
char *string;
{
set_key_row(fd, sun3_top_row, table, string);
set_key_row(fd, sun3_middle_row, table, &string[10]);
set_key_row(fd, sun3_bottom_row, table, &string[20]);
}
/* Set a row of 10 keys starting with START from string */
set_key_row(fd, start, table, string)
int fd,table;
char *string;
{
char c;
int i;
for (i=0;i<10;i++) {
c = string[i]; /* Get char from spec */
if (table==CTRLMASK) {
if ((c >= '@') && (c <= '_')) /* Chars that can be controlified */
c = c&0x1F; /* Do that, otherwise leave it alone */
}
do_set_key(fd, table, start++, c); }
}
do_set_key(fd, table, slot, value)
int fd, table, slot, value;
{
struct kiockey keyinfo;
keyinfo.kio_tablemask = table;
keyinfo.kio_station = slot;
keyinfo.kio_entry = value;
if (ioctl(fd, KIOCSETKEY, &keyinfo) < 0) {
perror("Can't change key %d in table %d", slot, table);
exit(1); }
/* For debugging, check keys */
/*
if (ioctl(fd, KIOCGETKEY, &keyinfo) < 0) {
perror("Can't get key %d in table %d", slot, table);
exit(1); }
if (keyinfo.kio_entry == value)
printf("%c", value);
else printf("\n'%c' -> '%c'\n", keyinfo.kio_entry, value);
*/
}
xerror(str)
char *str;
{ perror(str);
exit(1);}
More information about the Comp.sys.sun
mailing list