Subject: Re: cygwin 1.3.2 bug on non-us keyboard layouts
From: Corinna Vinschen <[email-masked]>
To: [email-masked]
Cc: Marius Gedminas <[email-masked]>
Date: Thu, 21 Jun 2001 20:34:22 +0200

Marius,

I would be glad if you could send that as a patch. Even if that
patch doesn't match all keyboard/language combination, it sounds as
if we would get a convenient solution for most users and it doesn't
exclude later refinement.

Please, send the patch to [email-masked] including
a ChangeLog entry as plain text.

Thanks in advance,
Corinna

On Tue, Jun 19, 2001 at 12:59:15AM +0200, Marius Gedminas wrote:
> Hi,
> 
> On Fri, Jun 15, 2001 at 02:35:03PM -0700, Jason Tiller wrote:
> > > Actually, some non-US keyboards also do not use AltGr.  I use a
> > > nonstandard "Lithuanian (Programmers)" layout which uses dead keys,
> > > and I'm quite used to have both Alt keys work as META.
> > 
> > Hmm.  Sounds like defining the exact conditions (without user input)
> > that determine when AltGr should be interpreted as META is more
> > challenging than originally thought (but isn't it always that way?).
> 
> Unfortunatelly, yes.
> 
> > > The best solution would be to see how the selected keyboard layout
> > > defines the right Alt key.  I don't know if that's possible.  I'll
> > > try to look into this on MSDN.
> > 
> > Hmm.  I don't know if MapVirtualKey would do it or not.  I'm certainly
> > interested in any ideas that you have!  I don't purport to be an
> > expert at this, not at all...
> 
> Well, I'm not an expert either.
> 
> AFAIK AltGr is equivalent to both Ctrl an Alt (with some exceptions).
> For example, kbd.h from Windows NT DDK says:
> 
>    Keyboards using AltGr as a Modifier Key usually translate the Virtual
>      ScanCode to Virtual Keys VK_CTRL + VK_ALT at input time: the Modifier
>      tables should be written to treat Ctrl + Alt as a valid shifter
>      key combination in these cases.
> 
> I've performed some tests on Windows 2000 and Windows 98 with German (Standard)
> and US English (International) both of which use AltGr.   Microsoft Spy++
> indicates that pressing AltGr results in two WM_KEYDOWN (and later
> WM_KEYUP) events sent: one for VK_MENU and another for VK_CONTROL.
> Besides, all the third level characters accessible with AltGr can also
> be typed by holding (either of) Ctrl + left Alt.
> 
> On Windows 2000 the same behavior can be observed with ReadConsoleInput:
> holding down AltGr results in events sent with both RIGHT_ALT_PRESSED
> and LEFT_CTRL_PRESSED bits set in dwControlKeyState.  Also note that
> even with US English 101 keyboard layout (which doesn't have AltGr) one
> cannot input characters with Ctrl + Alt -- ReadConsoleInput always
> returns UnicodeChar == 0 in this case (this is also docummented in the
> kbd.h from WinNT DDK mentioned above, under the section `AN EXAMPLE OF
> VALID AND INVALID MODIFIER KEY COMBINATIONS').  Therefore on Win2000
> (and I think WinNT 4.0 ought to be the same) it is possible to detect
> AltGr by checking if CTRL and ALT flags are both used.  This also does
> the right thing if the user actually uses Ctrl + Alt (the left one),
> since this combination is treated as equivalent to AltGr both in normal
> and in console windows.
> 
> Unfortunatelly, Windows 98 only passes RIGHT_ALT_PRESSED in
> dwControlKeyState when you use AltGr.  Also, in a console window
> Ctrl+Alt isn't considered to be equivalent to AltGr (while it is in all
> other windows).
> 
> I'm therefore afraid that it is only possible to achieve sane behavior
> on WinNT family of systems.
> 
> Possible solution for WinNT:
> 
>   Do not use meta_mask.
>   In fhandler_console::read change the test from
> 
>      /* Determine if the keystroke is modified by META. */
>      if (!(input_rec.Event.KeyEvent.dwControlKeyState & meta_mask))
> 
>   to
> 
>      /* Determine if the keystroke is modified by META. */
>      const DWORD key_state = input_rec.Event.KeyEvent.dwControlKeyState;
>      if ((key_state & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) == 0
>          || (key_state & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) != 0)
> 
>   This also has the following advantages:
>   - Ctrl+Alt is uniformly treated as equivalent to AltGr uniformly
>     throughought the system
>   - The actual keyboard layout selected at the moment of the keypress is
>     used to determine the behavior of right Alt key
> 
>   Note: since nothing prohibits the keyboard layout to allow Ctrl+Alt+x
>   keystrokes to generate ^x characters, it might be worthvile to add an
>   additional check for (ich >= 0 && ich <= 0x1f || ich == 0x7f) and add
>   META prefix in that case.
> 
> Possible solution for Win9x:
> 
>   Do it like it is done now.  So far I've been unable to find a better
>   way to determine if the primary keyboard layout uses right Alt as
>   AltGr, but maybe I just didn't look hard enough?  Maybe it would be
>   a good idea to add something like the initial proposal for CYGWIN
>   variable to allow the user to override incorrect guesses (hey, I can
>   use primary language US English with a US English (International)
>   keyboard and then I have AltGr).
> 
>   Two notes:
>   - Ctrl+Alt isn't uniformly treated as equivalent to AltGr by Windows
>     itself.
>   - It is impossible to change the actual keyboard layout for a console
>     window.  I think it's impossible to change the default keyboard
>     layout without rebooting (at least I couldn't find a way).
> 
> Combined solution:
> 
>   I'm afraid that requires distinguishing between WinNT/Win9x at runtime,
>   and therefore in the combined solution the simple test
> 
>      /* Determine if the keystroke is modified by META. */
>      if (!(input_rec.Event.KeyEvent.dwControlKeyState & meta_mask))
>        ...
> 
>   becomes
> 
>      /* Determine if the keystroke is modified by META. */
>      const DWORD key_state = input_rec.Event.KeyEvent.dwControlKeyState;
>      bool meta;
>      if (THIS_IS_WINDOWS_NT)
>          meta = (key_state & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) != 0
>              && (key_state & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) == 0
>              || (ich >= 0 && ich <= 0x1f || ich == 0x7f);
>      else
>          meta = (key_state & meta_mask) != 0;
>      if (!meta)
>        ...
> 
> What do you think?
> 
> Is sane behavior on sane systems (i.e. NT) worth the additional
> complications?  If so, I could write a patch to implement the proposed
> combined solution that I described above.  Or maybe I should write a
> small console application that implements this heuristic so that people
> with different keyboard layouts can test it on different systems and see
> how this heuristic performs in practice?
> 
> Marius Gedminas
> -- 
> If it wasn't for C, we'd be using BASI, PASAL and OBOL
> 
> --
> Want to unsubscribe from this list?
> Check out: http://cygwin.com/ml/#unsubscribe-simple

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Developer                                mailto:[email-masked]
Red Hat, Inc.

--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple