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