[comp.windows.x] keyboard remapper for Sun server

edmoy@OPAL.BERKELEY.EDU (06/24/87)

I've had the need to do yet-another-hack to the Sun server code to allow mapping
the Sun 3/50 keys to simulate a VT100/220 keyboard, for those users who have
Suns and want to talk to VMS (strange but true).

I did it in a more general way, so that the server will look for a
.Xkeybdmap file in the users home directory on startup, or a system-wide
file to replace its default mapping.  Since the maps are in binary, I
wrote a simple program in which you muck with the mapping, compile and
run and it will make the appropriate map file.

Following is a shar file that contains the diffs to libsun/events.c and
libsun/vssite.h and the map-creation program, keybd.c.

Edward Moy (I'd rather VaxStation II than Sun anyday)
Academic Computing Services
University of California
Berkeley, CA  94720

edmoy@opal.Berkeley.EDU
ucbvax!opal!edmoy
--------------- cut ----------------------------- cut -----------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	events.c.diff
#	vssite.h.diff
#	keybd.c
# libsun.shar - archive created: Wed Jun 24 12:30:16 PDT 1987
if test -f events.c.diff
then
	echo shar: will not overwrite existing file "'events.c.diff'"
else
echo 'x - events.c.diff'
cat << \RAZZLE!DAZZLE > events.c.diff
*** events.c.orig	Fri Jan 23 18:12:24 1987
--- events.c	Fri Jun 12 12:06:07 1987
***************
*** 55,60 ****
--- 55,63 ----
  #include	<sundev/kbd.h>
  #ifdef	RAW_KBD
  #include	<sundev/kbio.h>
+ #include	<sys/file.h>
+ #include	<pwd.h>
+ #include	"vssite.h"
  #endif
  #include	<sunwindow/win_input.h>
  
***************
*** 93,98 ****
--- 96,102 ----
  
  #ifdef	RAW_KBD
  extern struct kiockey sunkeymap[];
+ static int init_keybd = 0;
  
  /*
   * Convert from a Sun event to an X event
***************
*** 126,131 ****
--- 130,168 ----
  
      kludgekey = 0;
      if (key >= 0) {
+ 	if(!init_keybd) {
+ 		/*
+ 		 * Do this only once, at the very first.  Try to read in
+ 		 * any existing keyboard map files.  Try users private
+ 		 * .Xkeybdmap in home directory and if none, try systemwide
+ 		 * one in DEFAULT_KEYBD_MAP_PATH (defined in vssite.h).
+ 		 */
+ 		register char *cp;
+ 		register int fd = -1;
+ 		register struct passwd *pw;
+ 		char buf[512];
+ 		char *getenv();
+ 
+ 		init_keybd = 1;
+ 		if((!(cp = getenv("HOME")) || !*cp) &&
+ 		 (pw = getpwuid(getuid())))
+ 			cp = pw->pw_dir;
+ 		if(cp && *cp) {
+ 			strcpy(buf, cp);
+ 			strcat(buf, "/.Xkeybdmap");
+ 			if(access(buf, R_OK) >= 0)
+ 				fd = open(buf, O_RDONLY, 0);
+ 		}
+ 		if(fd < 0 && access(DEFAULT_KEYBD_MAP_PATH, R_OK) >= 0)
+ 			fd = open(DEFAULT_KEYBD_MAP_PATH, O_RDONLY, 0);
+ 		if(fd >= 0) {
+ 			read(fd, (char *)TopKeys, sizeof(TopKeys));
+ 			read(fd, (char *)RightKeys, sizeof(RightKeys));
+ 			read(fd, (char *)LeftKeys, sizeof(LeftKeys));
+ 			read(fd, (char *)BotKeys, sizeof(BotKeys));
+ 			close(fd);
+ 		}
+ 	}
  	xe->vse_device = VSE_DKB;
  	xe->vse_type = VSE_BUTTON;
  
***************
*** 206,221 ****
  				kludgekey = 0206;
  				break;
  			case UPARROW:
! 				kludgekey = 0252;
  				break;
  			case DOWNARROW:
! 				kludgekey = 0251;
  				break;
  			case LEFTARROW:
! 				kludgekey = 0247;
  				break;
  			case RIGHTARROW:
! 				kludgekey = 0250;
  				break;
  			}
  			break;
--- 243,258 ----
  				kludgekey = 0206;
  				break;
  			case UPARROW:
! 				kludgekey = RightKeys[7];
  				break;
  			case DOWNARROW:
! 				kludgekey = RightKeys[13];
  				break;
  			case LEFTARROW:
! 				kludgekey = RightKeys[9];
  				break;
  			case RIGHTARROW:
! 				kludgekey = RightKeys[11];
  				break;
  			}
  			break;
RAZZLE!DAZZLE
fi	# End events.c.diff
if test -f vssite.h.diff
then
	echo shar: will not overwrite existing file "'vssite.h.diff'"
else
echo 'x - vssite.h.diff'
cat << \RAZZLE!DAZZLE > vssite.h.diff
*** vssite.h.orig	Sun Mar  1 13:55:49 1987
--- vssite.h	Fri Jun 12 11:51:03 1987
***************
*** 7,12 ****
  ** be stored so that different sites can have control over where things live.
  **
  */
! #define	DEFAULT_FONT_PATH	"/usr/new/lib/X/font:~/font"
  #define DEFAULT_FONT_SUFFIX	".onx"
  
--- 7,13 ----
  ** be stored so that different sites can have control over where things live.
  **
  */
! #define	DEFAULT_FONT_PATH	"/usr/local/lib/X/font:~/font"
  #define DEFAULT_FONT_SUFFIX	".onx"
+ #define	DEFAULT_KEYBD_MAP_PATH	"/usr/local/lib/X/Xkeybdmap"
  
RAZZLE!DAZZLE
fi	# End vssite.h.diff
if test -f keybd.c
then
	echo shar: will not overwrite existing file "'keybd.c'"
else
echo 'x - keybd.c'
cat << \RAZZLE!DAZZLE > keybd.c
/*
 * The program makes a .Xkeybdmap file, used to change the keyboard map
 * of a Sun 3/50 running under X.  The configuration of the map in this file
 * emulates a VT100/220 keyboard and allows the Sun to use the full screen
 * editing capability on VMS, for instance.
 *
 * After changing the map (as needed), compile the program and run it.  The
 * map is written to the standard out.  Use the modified Sun server and either
 * move the map to the home directory as .Xkeybdmap, or install it in the
 * system-wide location as DEFAULT_KEYBD_MAP_PATH (defined in vssite.h).
 *
 * Written by:
 *	Edward Moy
 *	Academic Computing Services
 *	University of California
 *	Berkeley, CA  94720
 *
 *	edmoy@opal.Berkeley.EDU
 *	ucbvax!opal!edmoy
 */

#include <stdio.h>
#include <sys/types.h>

static u_short TopKeys[16] = {
	0252,	/* F1 (UP) */
	0251,	/* F2 (DOWN) */
	0247,	/* F3 (LEFT) */
	0250,	/* F4 (RIGHT) */
	0132,	/* F5 */
	0241,	/* F6 (PF1) */
	0242,	/* F7 (PF2) */
	0243,	/* F8 (PF3) */
	0244,	/* F9 (PF4) */
	0150,	/* F10 */
	0161,	/* F11/ESC */
	0162,	/* F12/BS */
	0163,	/* F13/LF */
	0164,	/* F14 */
	0174,	/* F15 */
	0175,	/* F16 */
};
	

static u_short RightKeys[16] = {
	0235,	/* R1 (7) */
	0236,	/* R2 (8) */
	0237,	/* R3 (9) */
	0231,	/* R4 (4) */
	0232,	/* R5 (5) */
	0233,	/* R6 (6) */
	0226,	/* R7 (1) */
	0227,	/* R8 (2) */
	0230,	/* R9 (3) */
	0222,	/* R10 (0) */
	0224,	/* R11 (PERIOD) */
	0240,	/* R12 (MINUS) */
	0234,	/* R13 (COMMA) */
	0225,	/* R14 (ENTER) */
	0225,	/* R15 (ENTER) */
	0211,	/* R16 */
};

static u_short LeftKeys[16] = {
	0176,	/* L1 */
	0177,	/* L2 */
	0174,	/* L3 (F15) */
	0175,	/* L4 (F16) */
	0212,	/* L5 (E1) */
	0213,	/* L6 (E2) */
	0214,	/* L7 (E3) */
	0215,	/* L8 (E4) */
	0216,	/* L9 (E5) */
	0217,	/* L10(E6) */
	0245,	/* L11/ALT */
	0246,	/* L12 */
	0253,	/* L13 */
	0254,	/* L14 */
	0255,	/* L15 */
	0262,	/* L16 */
};

static u_short BotKeys[16] = {
	0220,	/* B1 */
	0221,	/* B2 */
	0222,	/* B3 (KEYPAD_0) */
	0223,	/* B4 */
	0224,	/* B5 (KEYPAD_PERIOD) */
	0225,	/* B6 (ENTER) */
	0226,	/* B7 (KEYPAD_1) */
	0227,	/* B8 (KEYPAD_2) */
	0230,	/* B9 (KEYPAD_3) */
	0231,	/* B10 (KEYPAD_4) */
	0232,	/* B11 (KEYPAD_5) */
	0233,	/* B12 (KEYPAD_6) */
	0234,	/* B13 (KEYPAD_COMMA) */
	0235,	/* B14 (KEYPAD_7) */
	0236,	/* B15 (KEYPAD_8) */
	0237,	/* B16 (KEYPAD_9) */
};

main()
{
	if(fwrite((char *)TopKeys, 1, sizeof(TopKeys), stdout) !=
	 sizeof(TopKeys)) {
		fputs("write error on TopKeys\n", stderr);
		exit(1);
	}
	if(fwrite((char *)RightKeys, 1, sizeof(RightKeys), stdout) !=
	 sizeof(RightKeys)) {
		fputs("write error on RightKeys\n", stderr);
		exit(1);
	}
	if(fwrite((char *)LeftKeys, 1, sizeof(LeftKeys), stdout) !=
	 sizeof(LeftKeys)) {
		fputs("write error on LeftKeys\n", stderr);
		exit(1);
	}
	if(fwrite((char *)BotKeys, 1, sizeof(BotKeys), stdout) !=
	 sizeof(BotKeys)) {
		fputs("write error on BotKeys\n", stderr);
		exit(1);
	}
	exit(0);
}
RAZZLE!DAZZLE
fi	# End keybd.c
echo '***** End of' libsun.shar '*****'
exit