dewar@cpsc.ucalgary.ca (Alan Dewar) (02/28/89)
In article <890201-093010-10574@Xerox>, SBartlett.OsbuSouth@xerox.com writes: > Does anyone out there in net-land know of a way I can configure a Sun to > treat its standard keyboard as having a Dvorak layout? I put together a Dvorak keyboard for the Sun 3 some time ago, mostly just to see if it could be done. What I wrote was actually a little more general than that--it can be used to set any keyboard mapping you like. The user interface is somewhat unfriendly, I'm afraid. You have to edit binary files by hand if you want anything new. (I started with the standard QWERTY mapping, obtained by my "getkbd.c", and edited it to get a Dvorak layout.) In any event, it works, and I did get a Dvorak keyboard. Any enhancements to the programs would be welcome. The following programs, getkbd.c and setkbd.c, respectively get and set the keyboard mapping, writing to stdout or reading from stdin. Two mappings (uuencoded) are also included: qwerty.kbd and dvorak.kbd. Alan Dewar Computer Science Dept. University of Calgary dewar@cpsc.UCalgary.CA ..!alberta!calgary!dewar - - - - - - - - - - - - - - - - - cut here - - - - - - - - - - - - - - - - - /* getkbd.c */ /* write the current Sun 3 keyboard layout to stdout (for setkbd) */ /* */ /* Written: 88-04-20 Alan Dewar (dewar@cpsc.UCalgary.CA) */ #include <stdio.h> #include <sys/file.h> #include <sys/ioctl.h> #include <sundev/kbd.h> #include <sys/types.h> #include <sundev/kbio.h> static int TABLEMASKS[] = {0, CAPSMASK, SHIFTMASK, CTRLMASK, UPMASK}; #define NMASKS ( sizeof(TABLEMASKS) / sizeof(int) ) main () { int fd; struct kbd_data { struct keyboard kbd; struct keymap map[NMASKS]; char string[16][KTAB_STRLEN]; } data; struct kiockey key; int mask, station; int m, n; int err; fd = open ("/dev/kbd", O_RDWR); if (fd < 0) { fprintf (stderr, "Cannot open /dev/kbd\n"); exit (-1); } for (m = 0; m < 16; m++) { for (n = 0; n < KTAB_STRLEN; n++) { data.string[m][n] = '\0'; } } for (mask = 0; mask < NMASKS; mask++) { ((struct keymap **)(&data.kbd))[mask] = &data.map[mask]; key.kio_tablemask = TABLEMASKS[mask]; for (station = 0; station < 128; station++) { key.kio_station = station; err = ioctl (fd, KIOCGETKEY, &key); if (err != 0) { fprintf ("Error %d encountered\n", err); } data.map[mask].keymap[station] = key.kio_entry; if (key.kio_entry >= STRING && key.kio_entry < STRING+16) { m = key.kio_entry & 0x0F; for (n = 0; n < KTAB_STRLEN; n++) { data.string[m][n] = key.kio_string[n]; } } } } key.kio_tablemask = -1; err = ioctl (fd, KIOCGETKEY, &key); if (err != 0) { fprintf ("Error %d encountered\n", err); } data.kbd.k_abort1 = key.kio_station; key.kio_tablemask = -2; err = ioctl (fd, KIOCGETKEY, &key); if (err != 0) { fprintf ("Error %d encountered\n", err); } data.kbd.k_abort2 = key.kio_station; for (mask = 0; mask < NMASKS; mask++) { (long) (((struct keymap **)(&data.kbd))[mask]) = (char *) (((struct keymap **)(&data.kbd))[mask]) - (char *) (&data); } fwrite (&data, sizeof(data), 1, stdout); } - - - - - - - - - - - - - - - - - cut here - - - - - - - - - - - - - - - - - /* setkbd.c */ /* set the Sun 3 keyboard layout as specified by stdin (from getkbd) */ /* */ /* Written: 88-04-20 Alan Dewar (dewar@cpsc.UCalgary.CA) */ #include <stdio.h> #include <sys/file.h> #include <sys/ioctl.h> #include <sundev/kbd.h> #include <sys/types.h> #include <sundev/kbio.h> static int TABLEMASKS[] = {0, CAPSMASK, SHIFTMASK, CTRLMASK, UPMASK}; #define NMASKS ( sizeof(TABLEMASKS) / sizeof(int) ) main () { int fd; struct kbd_data { struct keyboard kbd; struct keymap map[NMASKS]; char string[16][KTAB_STRLEN]; } data; struct kiockey key; int mask, station; int m, n; int err; fd = open ("/dev/kbd", O_RDWR); if (fd < 0) { fprintf (stderr, "Cannot open /dev/kbd\n"); exit (-1); } if (fread (&data, sizeof(data), 1, stdin) != 1) { fprintf (stderr, "Cannot read keyboard data\n"); exit (-2); } for (mask = 0; mask < NMASKS; mask++) { (char *) (((struct keymap **)(&data.kbd))[mask]) = (char *) (&data) + (long) (((struct keymap **)(&data.kbd))[mask]); } for (mask = 0; mask < NMASKS; mask++) { key.kio_tablemask = TABLEMASKS[mask]; for (station = 0; station < 128; station++) { key.kio_station = station; key.kio_entry = data.map[mask].keymap[station]; if (key.kio_entry >= STRING && key.kio_entry < STRING+16) { m = key.kio_entry & 0x0F; for (n = 0; n < KTAB_STRLEN; n++) { key.kio_string[n] = data.string[m][n]; } } err = ioctl (fd, KIOCSETKEY, &key); if (err != 0) { fprintf ("Error %d encountered\n", err); } } } key.kio_tablemask = -1; key.kio_station = data.kbd.k_abort1; err = ioctl (fd, KIOCSETKEY, &key); if (err != 0) { fprintf ("Error %d encountered\n", err); } key.kio_tablemask = -2; key.kio_station = data.kbd.k_abort2; err = ioctl (fd, KIOCSETKEY, &key); if (err != 0) { fprintf ("Error %d encountered\n", err); } } - - - - - - - - - - - - - - - - - cut here - - - - - - - - - - - - - - - - - begin 644 qwerty.kbd M (@ *( $B !H@ B( %- **1HL&BX.&BXJ+C MHN2BY:+FY^@&HM#1TJ+"PZ*B&S$R,S0U-C<X.3 M/6 (HM/4U:+$HL6B"7%W M97)T>75I;W!;77^BUK'8HL;'S:*$87-D9F=H:FML.R=<#:*SVK2BR,[)HH)Z M>&-V8FYM+"XO@PK<LMZBHJ*B@) @D**BHJ>HHI&BP:+@X:+BHN.BY*+EHN;G MZ :BT-'2HL+#HJ(;,3(S-#4V-S@Y,"T]8 BBT]35HL2BQ:()45=%4E1954E/ M4%M=?Z+6L=BBQL>BHH1!4T1&1TA*2TP[)UP-HK/:M*+(SLFB@EI80U9"3DTL M+B^#"MRRWJ*BHJ* D""0HJ*BIZBBD:+!HN#AHN*BXZ+DHN6BYN?H!J+0T=*B MPL.BHALA0",D)5XF*B@I7RM^"*+3U-6BQ*+%H@E15T525%E524]0>WU_HM:Q MV*+&QZ*BA$%31$9'2$I+3#HB? VBL]JTHLC.R:*"6EA#5D).33P^/X,*W++> MHJ*BHH"0()"BHJ*GJ**1HL&BX.&BXJ+CHN2BY:+FY^@&HM#1TJ+"PZ*B&S$ M,S0U'C<X.3 ?/1X(HM/4U:+$HL6B"1$7!1(4&14)#Q ;'7^BUK'8HL;'HJ*$ M 1,$!@<("@L,.R<<#:*SVK2BR,[)HH(:& ,6 @X-+"X?@PK<LMZBHJ*B@) MD**BHJ>HHI&BH:*AH:*AHJ&BH:*AHJ&AH:&BH:&@HJ&AHJ*@H*"@H*"@H*"@ MH*"@H*"BH:&@HJ&BH:*@H*"@H*"@H*"@H*"@H**AH:"BH:&BHH2@H*"@H*"@ MH*"@H*"@HJ&AH**AH:&B@J"@H*"@H*"@H*"#H*&AH**BHJ*@D*"0HJ*BHJ8 M &UM! !M;0@ ;6T0 &UM# M M 8 end - - - - - - - - - - - - - - - - - cut here - - - - - - - - - - - - - - - - - begin 644 dvorak.kbd M (@ *( $B !H@ B( %- **1HL&BX.&BXJ+C MHN2BY:+FY^@&HM#1TJ+"PZ*B&S$R,S0U-C<X.3!;76 (HM/4U:+$HL6B"2\L M+G!Y9F=C<FPG/7^BUK'8HL;'S:*$86]E=6ED:'1N<RU<#:*SVK2BR,[)HH([ M<6IK>&)M=W9Z@PK<LMZBHJ*B@) @D**BHJ>HHI&BP:+@X:+BHN.BY*+EHN;G MZ :BT-'2HL+#HJ(;,3(S-#4V-S@Y,%M=8 BBT]35HL2BQ:()+RPN4%E&1T-2 M3"<]?Z+6L=BBQL>BHH1!3T55241(5$Y3+5P-HK/:M*+(SLFB@CM12DM80DU7 M5EJ#"MRRWJ*BHJ* D""0HJ*BIZBBD:+!HN#AHN*BXZ+DHN6BYN?H!J+0T=*B MPL.BHALA0",D)5XF*B@I>WU^"*+3U-6BQ*+%H@D_/#Y0649'0U),(BM_HM:Q MV*+&QZ*BA$%/155)1$A43E-?? VBL]JTHLC.R:*".E%*2UA"35=66H,*W++> MHJ*BHH"0()"BHJ*GJ**1HL&BX.&BXJ+CHN2BY:+FY^@&HM#1TJ+"PZ*B&S$ M,S0U'C<X.3 ;'1X(HM/4U:+$HL6B"1\L+A 9!@<#$@PG/7^BUK'8HL;'HJ*$ M 0\%%0D$"!0.$Q\<#:*SVK2BR,[)HH([$0H+& (-%Q8:@PK<LMZBHJ*B@) MD**BHJ>HHI&BH:*AH:*AHJ&BH:*AHJ&AH:&BH:&@HJ&AHJ*@H*"@H*"@H*"@ MH*"@H*"BH:&@HJ&BH:*@H*"@H*"@H*"@H*"@H**AH:"BH:&BHH2@H*"@H*"@ MH*"@H*"@HJ&AH**AH:&B@J"@H*"@H*"@H*"#H*&AH**BHJ*@D*"0HJ*BHJ8 M &UM! !M;0@ ;6T0 &UM# M M 8 end - - - - - - - - - - - - - - - - - cut here - - - - - - - - - - - - - - - - -
kdo@lucid.com (Ken Olum) (03/01/89)
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);}
dewar@cpsc.ucalgary.ca (Alan Dewar) (03/11/89)
My uuencoded keyboard-layout files seem to have escaped the mailers mostly unscathed, with one exception. The line immediately before the 'end' line should not be empty, but should consist of a single SPACE character. Otherwise, uudecode complains of a "Short file". Make this change to the uuencoded versions of qwerty.kbd and dvorak.kbd and things should work fine. Just in case any other mailers trimmed other trailing blanks, each line after the 'begin' line and before the line beginning with '8' should have enough trailing blanks to make all these lines the same length. The line which begins with '8' should have exactly 32 trailing blanks. Alan Dewar Computer Science Dept. University of Calgary dewar@cpsc.UCalgary.CA ..!alberta!calgary!dewar
dupuy@cs.columbia.edu (Alexander Dupuy) (03/11/89)
Under 4.0, there is a Defaults entry /Input/Keymap_Directory (by default, /usr/lib/keymaps) which contains a number of .keydef files which should seem to be something like the outpuy of your getkbd.c. Ideally, these should be used by input_from_defaults, but they don't seem to be. There doesn't seem to be any documentaion on their format. Perhaps in 4.1, you will be able to set Input/Keymap_Directory to ~/keymaps, and by running input_from_defaults, have a Dvorak keyboard on any machine you use. @alex
guy@uunet.uu.net (Guy Harris) (03/23/89)
>Perhaps in 4.1, you will be able to set Input/Keymap_Directory >to ~/keymaps, and by running input_from_defaults, have a Dvorak keyboard >on any machine you use. I don't expect so, but I may be surprised. However, I *do* expect you'll be able to use a new utility supplied with 4.1 to download the keyboard translation table so as to make it a Dvorak keyboard (both in SunView and when talking to the "raw" console). Of course, with X11 and NeWS you'll have to use some other mechanism - e.g., changing the X11 server's keycode-to-keysym map so that it pretends you have a Dvorak-labelled keyboard - since both X11 and NeWS servers (and, probably, the X11/NeWS server when it comes out) run the keyboard in untranslated mode, so that events read from "/dev/kbd" have keystation codes, not ASCII or ISO 8859 characters, as event codes.
pat@decwrl.dec.com (Pat Lashley) (03/30/89)
In article <8903010045.AA08334@cs.columbia.edu> dupuy@cs.columbia.edu (Alexander Dupuy) writes: > Under 4.0, there is a Defaults entry /Input/Keymap_Directory (by default, > /usr/lib/keymaps) which contains a number of .keydef files which should > seem to be something like the outpuy of your getkbd.c.... You might want to check out the loadkeys(1) and keytables(5) man pages, and the files in /usr/share/lib/keytables. I think that the various layouts defined there are chosen with the /Input/Keyboard_Type defaults entry. The named files in /usr/share/lib/keytables appear to be hard links to the layout_?? files. It should be pretty easy for someone familiar with the Dvorak layout to generate (and post <-- hint) an appropriate table for a Type4 keyboard. These man pages are marked as SunOS Release 4.0.1, they are not marked as 386i specific. I think that the 386i is the only Sun currently available with the type 4 keyboard referred to in loadkeys(1). At least until April... :-) --- Reply to address below - DO NOT auto-route --- PMLashley ...{sun,megatest,sts,zygot}!cohesive!kla!pat KLA Instruments POBox 58016, 3901 Burton Drive Santa Clara, CA 95052 +1 408 988 6100