[comp.windows.x] US keyboard layout dependent code...

tml@HEMULI.TIK.VTT.FI (Tor Lillqvist) (10/25/90)

			  X Window System Bug Report
			    xbugs@expo.lcs.mit.edu


VERSION:
    R4

CLIENT MACHINE and OPERATING SYSTEM:
    Irrelevant

DISPLAY TYPE:
    Irrelevant

WINDOW MANAGER:
    Irrelevant

AREA:
    Xlib

SYNOPSIS:
    XLookupString assumes US keyboard layout 

DESCRIPTION:
    In mit/lib/X/XKeyBind.c we find the following code fragment, which
    is invoked from XLookupString:

	/* only apply Control key if it makes sense, else ignore it */
	if (modifiers & ControlMask) {
	    if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
	    else if (c == '2') c = '\000';
	    else if (c >= '3' && c <= '7') c -= ('3' - '\033');
	    else if (c == '8') c = '\177';
	    else if (c == '/') c = '_' & 0x1F;
	}

    This clearly assumes that the keyboard is of the US variety, where
    shift-2 is '@', shift-8 is '?' etc.  When the user types
    control-2, we can assume he means control-shift-2, i.e. control-@
    == '\000'.

    However, for example on Finnish keyboards shift-2 is '"'.  I think
    it would be more correct to check what the second keysym
    associated with the keycode is, and if it such that it can be
    controlified, use that.

    In the Finnish keyboard case, control-2, i.e. control-", doesn't
    make sense.  But for instance shift-+ is '?', and typing control-+
    could reasonably be expected to produce control-?, which commonly
    is taken to mean '\177'.


REPEAT BY:
    

SAMPLE FIX:

*** XKeyBind.c	Tue Dec 12 02:09:42 1989
--- XKeyBind.new.c	Thu Oct 25 10:37:25 1990
***************
*** 302,309 ****
  }
  
  static int
! XTranslateKeySym(dpy, symbol, modifiers, buffer, nbytes)
      Display *dpy;
      register KeySym symbol;
      unsigned int modifiers;
      char *buffer;
--- 302,310 ----
  }
  
  static int
! XTranslateKeySym(dpy, kc, symbol, modifiers, buffer, nbytes)
      Display *dpy;
+     KeyCode kc;
      register KeySym symbol;
      unsigned int modifiers;
      char *buffer;
***************
*** 351,362 ****
      else
  	c = symbol & 0xFF;
      /* only apply Control key if it makes sense, else ignore it */
      if (modifiers & ControlMask) {
  	if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
! 	else if (c == '2') c = '\000';
! 	else if (c >= '3' && c <= '7') c -= ('3' - '\033');
! 	else if (c == '8') c = '\177';
! 	else if (c == '/') c = '_' & 0x1F;
      }
      buffer[0] = c;
      return 1;
--- 352,371 ----
      else
  	c = symbol & 0xFF;
      /* only apply Control key if it makes sense, else ignore it */
+     /* Control of ' ', '?' or '@' .. '~' makes sense,
+        or control of a key whose shifted keysym is in the above set */
      if (modifiers & ControlMask) {
  	if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
! 	else if (c == '?') c = '\177';
! 	else {
! 	   KeySym shifted = KeyCodetoKeySym(dpy, kc, 1);
! 	   int s = 0;
! 	   if ((shifted >> 8) == 0 &&
! 	       ((s = (shifted & 0xFF)) >= '@' && s < '\177') || s == ' ')
! 		c = s & 0x1F;
! 	   else if (s == '?')
! 	        c = '\177';
! 	}
      }
      buffer[0] = c;
      return 1;
***************
*** 381,388 ****
      if (keysym)
  	*keysym = symbol;
      /* arguable whether to use (event->state & ~modifiers) here */
!     return XTranslateKeySym(event->display, symbol, event->state,
! 			    buffer, nbytes);
  }
  
  #if NeedFunctionPrototypes
--- 390,397 ----
      if (keysym)
  	*keysym = symbol;
      /* arguable whether to use (event->state & ~modifiers) here */
!     return XTranslateKeySym(event->display, event->keycode, symbol, 
! 			    event->state, buffer, nbytes);
  }
  
  #if NeedFunctionPrototypes