AltGR problems with Windows XP

Harold L Hunt II huntharo@msu.edu
Mon Nov 4 13:08:00 GMT 2002


Andreas,

Interesting.  I think you may have found the reason (and solution) for 
why a select few users with non-U.S. keyboard layouts are still having 
problems with fake Control_L presses and releases.

I appreciate the FSM state transition table, but could you give me a few 
sentences describing how the new code detects the fake Control_L presses 
and releases?  That will make it a little easier for me to understand 
your table.

Thanks for the patch,

Harold

Andreas Schessner wrote:

> Hello,
>
> I use the X server of Cygwin/XFree86 (XWin) and it is working fine on my
> Windows 2000 Workstation but
> running the same version on my Notebook (Windows XP) causes problems
> with the AltGr handling.
>
> I've noticed that pressing the AltGr Key produces a
>     KeyPress-Control_L
>     KeyPress-Mode_switch
>     KeyRelease-Control_L
>     KeyRelease-Mode_switch
> event sequence (see xev output at the end of this mail).
>
> I began to trace the code (winkeybd.c, function winIsFakeCtrl_L) and
> found out that on my XP notebook the windows messages VK_CONTROL (the
> faked Control_L) and VK_MENU don't have the same timestamp and it is not
> always possible to get the following VK_MENU message by issuing the
> PeekMessage().
>
> I don't know if this problem is relating to my Notebook (Dell Latitude)
> or to Windows XP. Are there other people having the same problems?
>
> Andreas
>
>
> PS.
> For now I've implemented a workarround. I'm using a translation of the
> incomming windows messages, which recognizes the fake Control_L messages
> and filters them out.
> Changes were made on following sources: win.h, winkeybd.c, winwndproc.c
> The modified sources can be obtained from mee if desired:
> This works fine for me...
>
>
> The algorithm is desccribed below as a deterministic finite automata 
> (DFA)
>
> input           \ state | 0 (start) | 1        |  2          |  3
> -------------------------------------------------------------------------------- 
>
> KeyPressed-CtrlL  (PCL) |  1  -     | 1  -       |  2  PCL   |  1  -
> KeyReleased-CtrlL (RCL) |  0  RCL   | 0  PCL,RCL |  3  -     |  0 RCL
> KeyPressed-AltR   (PAR) |  0  PAR   | 2  PAR     |  2  PAR   |  0 PAR
> KeyReleased-AltR  (RAR) |  0  RAR   | 0  PCL,RAR |  1  RAR   |  0 RAR 
>   any other key     (*)   |  0  *     | 0  PCL,*   |  2  *     |  0  *
>
> States:
>      0 (start),1,2,3
> input and output alphabet:
>      KeyPressed-CtrlL (PCL), KeyReleased-CtrlL (RCL),
>      KeyPressed-AltR (PAR), KeyReleased-AltR (RAR),
>      no key (-), any other key(*)
>
> the table shows the transitions:
>       <new-state>  <output>
>
> e.g. assume you are in state "1" and you receive a KeyReleased-CtrlL 
> message
>      then the new state of the DFA would be "0" and the events for
> KeyPressed-CtrlL and KeyReleased-CtrlL
>      are sent to the XWin X-Server.
>
>
> Implementation:
> =========================================================
>
> void winProcessKeyEvent (DWORD dwVirtualKey, DWORD dwKeyData)
> {
>   static int   iState     = 0; /* initial State of DFA */
>   static int   iCtrlCode  = 0; /* initialized when first pressed... */
>
>   Bool      fDown            = ((dwKeyData & 0x80000000)          == 0);
>   Bool     fExt             = ((HIWORD(dwKeyData) & KF_EXTENDED) != 0);
>   int    iPreKeyCode      = XK_VoidSymbol;
>
>   Bool   fCtrlUp, fCtrlDown, fMenuUp, fMenuDown;
>   int    iKeyCode, i;
>
>
>   winTranslateKey (dwVirtualKey, dwKeyData, &iKeyCode);
>
>   /*
>    * determine the input for the DFA
>    * (we use boolean indicators instead of an real alphabet)
>    */
>   fCtrlUp = fCtrlDown = fMenuUp = fMenuDown = FALSE;
>
>   if (dwVirtualKey == VK_CONTROL) {
>     iCtrlCode = iKeyCode;     /* save the scan code for VK_CONTROL */
>     if (fDown) fCtrlDown=TRUE;
>     else       fCtrlUp  =TRUE;
>   }
>   else if (dwVirtualKey == VK_MENU && fExt)  {
>     if (fDown) fMenuDown=TRUE;
>     else       fMenuUp  =TRUE;
>   }
>
> #if CYGDEBUG
>   ErrorF("winProcessKeyEvent:   0x%0x, 0x%0x\n",dwVirtualKey,dwKeyData);
>   ErrorF("State=%d Input=0x%0x (%s) 
> ",iState,dwVirtualKey,(fDown?"DOWN":"UP"));
> #endif
>
>   switch (iState) {
>
>     default:
>     case 0 :
>       if      (fCtrlDown)  { iState=1; iKeyCode=XK_VoidSymbol; }
>       else                 { iState=0; }
>       break;
>
>
>     case 1 :
>       if      (fCtrlDown)  { iState=1; }
>       else if (fMenuDown)  { iState=2; }
>       else                 { iState=0; iPreKeyCode=iCtrlCode; }
>       break;
>
>
>     case 2 :
>       if      (fCtrlUp)    { iState=3; }
>       else if (fMenuUp)    { iState=1; }
>       else                 { iState=2; }
>       break;
>
>     case 3 :
>        if     (fCtrlDown)  { iState=1; iKeyCode=XK_VoidSymbol; }
>        else                { iState=0; }
>        break;
>
>   }
>
> #if CYGDEBUG
>   ErrorF(" -> State=%d", iState);
>   if (iPreKeyCode != XK_VoidSymbol) ErrorF(" 0x%0x [0x0],",iPreKeyCode);
>   ErrorF(" 0x%0x [0x%0x]\n",iKeyCode,dwKeyData);
> #endif
>
>   if (iPreKeyCode != XK_VoidSymbol)
>     winSendKeyEvent(iPreKeyCode,TRUE);
>
>   if (iKeyCode    != XK_VoidSymbol)
>     for (i = 0; i < LOWORD(dwKeyData); ++i)
>       winSendKeyEvent(iKeyCode, (dwKeyData & 0x80000000)==0);
>
> }
>
>
> Output of xev with the original XWin:
> =========================================================
> KeyPress event, serial 22, synthetic NO, window 0xa00001,
>     root 0x36, subw 0xa00002, time 249118172, (38,43), root:(591,66),
>     state 0x0, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>     XLookupString gives 0 characters:  ""
>
> KeyPress event, serial 22, synthetic NO, window 0xa00001,
>     root 0x36, subw 0xa00002, time 249118172, (38,43), root:(591,66),
>     state 0x4, keycode 113 (keysym 0xff7e, Mode_switch), same_screen YES,
>     XLookupString gives 0 characters:  ""
>
> KeyRelease event, serial 22, synthetic NO, window 0xa00001,
>     root 0x36, subw 0xa00002, time 249118303, (38,43), root:(591,66),
>     state 0x2004, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>     XLookupString gives 0 characters:  ""
>
> KeyRelease event, serial 22, synthetic NO, window 0xa00001,
>     root 0x36, subw 0xa00002, time 249118303, (38,43), root:(591,66),
>     state 0x2000, keycode 113 (keysym 0xff7e, Mode_switch), 
> same_screen YES,
>     XLookupString gives 0 characters:  ""
>
> KeyPress event, serial 22, synthetic NO, window 0xa00001,
>     root 0x36, subw 0xa00002, time 249119024, (38,43), root:(591,66),
>     state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
>     XLookupString gives 1 characters:  "a"
>
> ....
>
> KeyPress event, serial 22, synthetic NO, window 0xa00001,
>     root 0x36, subw 0xa00002, time 249131181, (38,43), root:(591,66),
>     state 0x0, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
>     XLookupString gives 0 characters:  ""
>
> KeyPress event, serial 22, synthetic NO, window 0xa00001,
>     root 0x36, subw 0xa00002, time 249131191, (38,43), root:(591,66),
>     state 0x4, keycode 113 (keysym 0xff7e, Mode_switch), same_screen YES,
>     XLookupString gives 0 characters:  ""
>
> KeyRelease event, serial 22, synthetic NO, window 0xa00001,
>     root 0x36, subw 0xa00002, time 249131381, (38,43), root:(591,66),
>     state 0x2004, keycode 113 (keysym 0xff7e, Mode_switch), 
> same_screen YES,
>     XLookupString gives 0 characters:  ""
>
> KeyPress event, serial 22, synthetic NO, window 0xa00001,
>     root 0x36, subw 0xa00002, time 249132383, (38,43), root:(591,66),
>     state 0x4, keycode 38 (keysym 0x61, a), same_screen YES,
>     XLookupString gives 1 characters:  ""
>
>
>



More information about the Cygwin-xfree mailing list