[comp.emacs] Suggested new X11 function key keybindings

cks@white.toronto.edu (Chris Siebenmann) (06/27/89)

 Recently I became disenchanted with how GNU Emacs bound X11 function
keys (because of things such as using a hardcoded list that differed on Suns
vs. everyone else, missing various useful keys like the keyboard
function keys), and decided to find a better scheme. My current
technique is to generate the sequence

	ESC [ <keysym name or hex number> ~

(eg ESC [ F 1 ~ for F1) (hex numbers are only generated if the keysym
has no name, eg the Remove key on DEC and GraphOn keyboards).

 The new code is smaller, simpler, more predictable, and lets you bind
any key that your keyboard produces; it uses the same names for keys
as all other X11 programs do. Its only disadvantage is that it isn't
compatable with the old scheme -- considering how .. ah .. baroque the
old scheme was I don't consider this much of a disadvantage.

 If you want to do this too, apply the following patch to
src/x11term.c:

*** x11term.c.orig	Fri Feb 24 16:44:00 1989
--- x11term.c	Tue Jun 20 16:50:11 1989
***************
*** 1055,1211
   * from elisp.
   */
  
- #ifdef sun
- char *stringFuncVal(keycode)
- 	KeySym keycode;
- {
- 	switch (keycode) {
- 	case XK_L1:
- 		return("192");
- 	case XK_L2:
- 		return("193");
- 	case XK_L3:
- 		return("194");
- 	case XK_L4:
- 		return("195");
- 	case XK_L5:
- 		return("196");
- 	case XK_L6:
- 		return("197");
- 	case XK_L7:
- 		return("198");
- 	case XK_L8:
- 		return("199");
- 	case XK_L9:
- 		return("200");
- 	case XK_L10:
- 		return("201");
- 
- 	case XK_R1:
- 		return("208");
- 	case XK_R2:
- 		return("209");
- 	case XK_R3:
- 		return("210");
- 	case XK_R4:
- 		return("211");
- 	case XK_R5:
- 		return("212");
- 	case XK_R6:
- 		return("213");
- 	case XK_R7:
- 		return("214");
- 	case XK_R8:
- 		return("215");
- 	case XK_R9:
- 		return("216");
- 	case XK_R10:
- 		return("217");
- 	case XK_R11:
- 		return("218");
- 	case XK_R12:
- 		return("219");
- 	case XK_R13:
- 		return("220");
- 	case XK_R14:
- 		return("221");
- 	case XK_R15:
- 		return("222");
- 
- 	case XK_Break:			/* Sun3 "Alternate" key */
- 		return("223");
- 
- 	case XK_F1:
- 		return("224");
- 	case XK_F2:
- 		return("225");
- 	case XK_F3:
- 		return("226");
- 	case XK_F4:
- 		return("227");
- 	case XK_F5:
- 		return("228");
- 	case XK_F6:
- 		return("229");
- 	case XK_F7:
- 		return("230");
- 	case XK_F8:
- 		return("231");
- 	case XK_F9:
- 		return("232");
- 
- 	default:
- 		return("-1");
- 	}
- }
- #else
- char *stringFuncVal(keycode)
- 	KeySym keycode;
- {
- 	switch (keycode) {
- 	case XK_F1:
- 		return("11");
- 	case XK_F2:
- 		return("12");
- 	case XK_F3:
- 		return("13");
- 	case XK_F4:
- 		return("14");
- 	case XK_F5:
- 		return("15");
- 	case XK_F6:
- 		return("17");
- 	case XK_F7:
- 		return("18");
- 	case XK_F8:
- 		return("19");
- 	case XK_F9:
- 		return("20");
- 	case XK_F10:
- 		return("21");
- 	case XK_F11:
- 		return("23");
- 	case XK_F12:
- 		return("24");
- 	case XK_F13:
- 		return("25");
- 	case XK_F14:
- 		return("26");
- 	case XK_F15:
- 		return("28");
- 	case XK_Help:
- 		return("28");
- 	case XK_F16:
- 		return("29");
- 	case XK_Menu:
- 		return("29");
- 	case XK_F17:
- 		return("31");
- 	case XK_F18:
- 		return("32");
- 	case XK_F19:
- 		return("33");
- 	case XK_F20:
- 		return("34");
- 	
- 	case XK_Find :
- 		return("1");
- 	case XK_Insert:
- 		return("2");
- 	case XK_Delete:
- 		return("3");
- 	case XK_Select:
- 		return("4");
- 	case XK_Prior:
- 		return("5");
- 	case XK_Next:
- 		return("6");
- 	default:
- 		return("-1");
- 	}
- }
- #endif /* not sun */
- 	
  internal_socket_read(bufp, numchars)
  	register unsigned char *bufp;
  	register int numchars;

--- 1055,1060 -----
   * from elisp.
   */
  
  internal_socket_read(bufp, numchars)
  	register unsigned char *bufp;
  	register int numchars;
***************
*** 1324,1344
        nbytes = XLookupString (&event,
  			      mapping_buf, 20, &keysym,
  			      &status);
!       /* Someday this will be unnecessary as we will
! 	 be able to use XRebindKeysym so XLookupString
! 	 will have already given us the string we want. */
!       if (IsFunctionKey(keysym) ||
! 	  IsMiscFunctionKey(keysym)) {
! 	strcpy(mapping_buf,"[");
! 	strcat(mapping_buf,stringFuncVal(keysym));
! #ifdef sun
! 	strcat(mapping_buf,"z");
! #else
! 	strcat(mapping_buf,"~");
! #endif /* sun */
! 	nbytes = strlen(mapping_buf);
!       }
!       else {
  	switch (keysym) {
  	case XK_Left:
  	  strcpy(mapping_buf,"\002");

--- 1173,1189 -----
        nbytes = XLookupString (&event,
  			      mapping_buf, 20, &keysym,
  			      &status);
!       /* If XLookupString knows a string for this buffer, or the key
! 	 doesn't have a symbol, or the key is a modifier key (like shift)
! 	 we take it as-is. Otherwise, we take what XKeysymToString gives
! 	 us with a ESC-[ on front and a ~ on the end. If XKeysymToString
! 	 gives us nothing, we use the hex code instead. */
!       if (nbytes == 0 && keysym != NoSymbol && !IsModifierKey(keysym)) {
! 	char *ksname;
! 
! #ifndef	NOCURSORHACK
! 	/* This shouldn't really be needed, but the great god Backwards
! 	   Compatability dictates that we do this. */
  	switch (keysym) {
  	case XK_Left:
  	  strcpy(mapping_buf,"\002");
***************
*** 1356,1361
  	  strcpy(mapping_buf,"\016");
  	  nbytes = 1;
  	  break;
  	}
        }
        if (nbytes) {

--- 1201,1218 -----
  	  strcpy(mapping_buf,"\016");
  	  nbytes = 1;
  	  break;
+ 	default:
+ #endif
+ 	  ksname = XKeysymToString (keysym);
+ 	  if (ksname == NULL)
+ 	    sprintf(mapping_buf, "[%x~", keysym);
+ 	  else {
+ 	    strcpy(mapping_buf, "[");
+ 	    strcat(mapping_buf, ksname);
+ 	    strcat(mapping_buf, "~");	/* none of this sun oddity BS */
+ 	  }
+ 	  nbytes = strlen(mapping_buf);
+ #ifndef	NOCURSORHACK
  	}
  #endif
        }
***************
*** 1357,1362
  	  nbytes = 1;
  	  break;
  	}
        }
        if (nbytes) {
  	if (event.xkey.state & Mod1Mask)

--- 1214,1220 -----
  	  nbytes = strlen(mapping_buf);
  #ifndef	NOCURSORHACK
  	}
+ #endif
        }
        if (nbytes) {
  	if (event.xkey.state & Mod1Mask)

-- 
	"I shall clasp my hands together and bow to the corners of the world."
			Number Ten Ox, "Bridge of Birds"
Chris Siebenmann		...!utgpu!{ncrcan,ontmoh!moore}!ziebmef!cks
cks@white.toronto.edu	     or ...!utgpu!{,csri!}cks

cks@white.toronto.edu (Chris Siebenmann) (06/28/89)

 Oops, as they say. It has been pointed out to me that the patches I
posted had explicit escape characters in them which got swallowed up
by our news software. Here's a corrected patch; apply this one INSTEAD
of the previous patch.

*** x11term.c.orig	Fri Feb 24 16:44:00 1989
--- x11term.c	Wed Jun 28 14:03:00 1989
***************
*** 1055,1211
   * from elisp.
   */
  
- #ifdef sun
- char *stringFuncVal(keycode)
- 	KeySym keycode;
- {
- 	switch (keycode) {
- 	case XK_L1:
- 		return("192");
- 	case XK_L2:
- 		return("193");
- 	case XK_L3:
- 		return("194");
- 	case XK_L4:
- 		return("195");
- 	case XK_L5:
- 		return("196");
- 	case XK_L6:
- 		return("197");
- 	case XK_L7:
- 		return("198");
- 	case XK_L8:
- 		return("199");
- 	case XK_L9:
- 		return("200");
- 	case XK_L10:
- 		return("201");
- 
- 	case XK_R1:
- 		return("208");
- 	case XK_R2:
- 		return("209");
- 	case XK_R3:
- 		return("210");
- 	case XK_R4:
- 		return("211");
- 	case XK_R5:
- 		return("212");
- 	case XK_R6:
- 		return("213");
- 	case XK_R7:
- 		return("214");
- 	case XK_R8:
- 		return("215");
- 	case XK_R9:
- 		return("216");
- 	case XK_R10:
- 		return("217");
- 	case XK_R11:
- 		return("218");
- 	case XK_R12:
- 		return("219");
- 	case XK_R13:
- 		return("220");
- 	case XK_R14:
- 		return("221");
- 	case XK_R15:
- 		return("222");
- 
- 	case XK_Break:			/* Sun3 "Alternate" key */
- 		return("223");
- 
- 	case XK_F1:
- 		return("224");
- 	case XK_F2:
- 		return("225");
- 	case XK_F3:
- 		return("226");
- 	case XK_F4:
- 		return("227");
- 	case XK_F5:
- 		return("228");
- 	case XK_F6:
- 		return("229");
- 	case XK_F7:
- 		return("230");
- 	case XK_F8:
- 		return("231");
- 	case XK_F9:
- 		return("232");
- 
- 	default:
- 		return("-1");
- 	}
- }
- #else
- char *stringFuncVal(keycode)
- 	KeySym keycode;
- {
- 	switch (keycode) {
- 	case XK_F1:
- 		return("11");
- 	case XK_F2:
- 		return("12");
- 	case XK_F3:
- 		return("13");
- 	case XK_F4:
- 		return("14");
- 	case XK_F5:
- 		return("15");
- 	case XK_F6:
- 		return("17");
- 	case XK_F7:
- 		return("18");
- 	case XK_F8:
- 		return("19");
- 	case XK_F9:
- 		return("20");
- 	case XK_F10:
- 		return("21");
- 	case XK_F11:
- 		return("23");
- 	case XK_F12:
- 		return("24");
- 	case XK_F13:
- 		return("25");
- 	case XK_F14:
- 		return("26");
- 	case XK_F15:
- 		return("28");
- 	case XK_Help:
- 		return("28");
- 	case XK_F16:
- 		return("29");
- 	case XK_Menu:
- 		return("29");
- 	case XK_F17:
- 		return("31");
- 	case XK_F18:
- 		return("32");
- 	case XK_F19:
- 		return("33");
- 	case XK_F20:
- 		return("34");
- 	
- 	case XK_Find :
- 		return("1");
- 	case XK_Insert:
- 		return("2");
- 	case XK_Delete:
- 		return("3");
- 	case XK_Select:
- 		return("4");
- 	case XK_Prior:
- 		return("5");
- 	case XK_Next:
- 		return("6");
- 	default:
- 		return("-1");
- 	}
- }
- #endif /* not sun */
- 	
  internal_socket_read(bufp, numchars)
  	register unsigned char *bufp;
  	register int numchars;

--- 1055,1060 -----
   * from elisp.
   */
  
  internal_socket_read(bufp, numchars)
  	register unsigned char *bufp;
  	register int numchars;
***************
*** 1324,1344
        nbytes = XLookupString (&event,
  			      mapping_buf, 20, &keysym,
  			      &status);
!       /* Someday this will be unnecessary as we will
! 	 be able to use XRebindKeysym so XLookupString
! 	 will have already given us the string we want. */
!       if (IsFunctionKey(keysym) ||
! 	  IsMiscFunctionKey(keysym)) {
! 	strcpy(mapping_buf,"[");
! 	strcat(mapping_buf,stringFuncVal(keysym));
! #ifdef sun
! 	strcat(mapping_buf,"z");
! #else
! 	strcat(mapping_buf,"~");
! #endif /* sun */
! 	nbytes = strlen(mapping_buf);
!       }
!       else {
  	switch (keysym) {
  	case XK_Left:
  	  strcpy(mapping_buf,"\002");

--- 1173,1189 -----
        nbytes = XLookupString (&event,
  			      mapping_buf, 20, &keysym,
  			      &status);
!       /* If XLookupString knows a string for this buffer, or the key
! 	 doesn't have a symbol, or the key is a modifier key (like shift)
! 	 we take it as-is. Otherwise, we take what XKeysymToString gives
! 	 us with a ESC-[ on front and a ~ on the end. If XKeysymToString
! 	 gives us nothing, we use the hex code instead. */
!       if (nbytes == 0 && keysym != NoSymbol && !IsModifierKey(keysym)) {
! 	char *ksname;
! 
! #ifndef	NOCURSORHACK
! 	/* This shouldn't really be needed, but the great god Backwards
! 	   Compatability dictates that we do this. */
  	switch (keysym) {
  	case XK_Left:
  	  strcpy(mapping_buf,"\002");
***************
*** 1356,1361
  	  strcpy(mapping_buf,"\016");
  	  nbytes = 1;
  	  break;
  	}
        }
        if (nbytes) {

--- 1201,1218 -----
  	  strcpy(mapping_buf,"\016");
  	  nbytes = 1;
  	  break;
+ 	default:
+ #endif
+ 	  ksname = XKeysymToString (keysym);
+ 	  if (ksname == NULL)
+ 	    sprintf(mapping_buf, "\033[%x~", keysym);
+ 	  else {
+ 	    strcpy(mapping_buf, "\033[");
+ 	    strcat(mapping_buf, ksname);
+ 	    strcat(mapping_buf, "~");	/* none of this sun oddity BS */
+ 	  }
+ 	  nbytes = strlen(mapping_buf);
+ #ifndef	NOCURSORHACK
  	}
  #endif
        }
***************
*** 1357,1362
  	  nbytes = 1;
  	  break;
  	}
        }
        if (nbytes) {
  	if (event.xkey.state & Mod1Mask)

--- 1214,1220 -----
  	  nbytes = strlen(mapping_buf);
  #ifndef	NOCURSORHACK
  	}
+ #endif
        }
        if (nbytes) {
  	if (event.xkey.state & Mod1Mask)

-- 
	"I shall clasp my hands together and bow to the corners of the world."
			Number Ten Ox, "Bridge of Birds"
Chris Siebenmann		...!utgpu!{ncrcan,ontmoh!moore}!ziebmef!cks
cks@white.toronto.edu	     or ...!utgpu!{,csri!}cks

cks@white.toronto.edu (Chris Siebenmann) (06/28/89)

 *Sigh ... of course, the second patch won't do people much good,
since the original code has explicit escapes in it. I guess people
will just have to apply the last two portions of the patch by hand
(grr, grumble).

-- 
	"I shall clasp my hands together and bow to the corners of the world."
			Number Ten Ox, "Bridge of Birds"
Chris Siebenmann		...!utgpu!{ncrcan,ontmoh!moore}!ziebmef!cks
cks@white.toronto.edu	     or ...!utgpu!{,csri!}cks