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