Keyboard Layouts - Alt vs. AltGr

All development related issues welcome

Moderator: Moderator Team

stanton
Posts: 10
Joined: Sun Nov 09, 2008 6:31 pm

Keyboard Layouts - Alt vs. AltGr

Post by stanton » Sun Nov 09, 2008 6:47 pm

Hi everybody,

Can anyone tell me which piece in the source code of the kbd*.dll controls the behavior of the right Alt/AltGr key?

Background: I am developing two keyboard layouts; both define extra characters accessible through the AltGr key. For one of them I modified kbdgr.c; here the AltGr key works fine. Pressing AltGr+<key> gives me the extra character I defined for it. The other one I obtained by rewriting kbdusx.c; here the AltGr key behaves just like the Alt key: Pressing AltGr+E has the same effect as pressing Alt+E, i.e. it brings up the Edit menu in most apps. Getting the Euro sign pressing Ctrl+Alt+E works fine, but I can't get AltGr to work as I expect.

I have compared the source codes of both files but can't find a difference that looks significant to me. Any help would be appreciated...

hto
Developer
Posts: 2193
Joined: Sun Oct 01, 2006 3:43 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by hto » Sun Nov 09, 2008 7:12 pm

Try to experiment with modifier_bits.

kbdgr.c:

Code: Select all

ROSDATA MODIFIERS modifier_bits = {
  modifier_keys,
  6,
  { 0, 1, 3, 4, SHFT_INVALID, SHFT_INVALID, 2 } /* Modifier bit order, NONE, SHIFT, CTRL, ALT, MENU, SHIFT + MENU, CTRL + MENU */
};

...

ROSDATA VK_TO_WCHARS3 key_to_chars_3mod[] = {
  /* Normal, Shifted, Ctrl */
  ...
  { 'E', CAPS, {'e', 'E', 0x20ac} },
  ...
};
kbdusx.c:

Code: Select all

ROSDATA MODIFIERS modifier_bits = {
  modifier_keys,
  6,
  { 0, 1, 4, 5, SHFT_INVALID, SHFT_INVALID, 2, 3 }
};

...

ROSDATA VK_TO_WCHARS4 key_to_chars_4mod[] = {
  ...
  { 'E',          CAPS|CAPLOKALTGR, {'e',      'E',      0x00e9,   0x00c9  } },
  ...
};
BTW, maybe you can help developers to write a compiler for .klc format?

stanton
Posts: 10
Joined: Sun Nov 09, 2008 6:31 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by stanton » Mon Nov 10, 2008 11:27 pm

Thanks, I've already done that in the layout based on the German one, which works fine:

Code: Select all

ROSDATA MODIFIERS modifier_bits = {
  modifier_keys,
  8,
  { 0, 1, 3, 4, SHFT_INVALID, SHFT_INVALID, 2, 5 } /* Modifier bit order, NONE, SHIFT, CTRL, ALT, MENU, SHIFT + MENU, CTRL + MENU */
};
In the layout derived from US-International (which doesn't do what I want) I have:

Code: Select all

ROSDATA MODIFIERS modifier_bits = {
  modifier_keys,
  8,
  { 0, 1, 4, 5, SHFT_INVALID, SHFT_INVALID, 2, 3 }
};
As far as I have understood, the members of the modifier_bits structure have the following meaning:
  • modifier_keys: Pointer to a modifier_keys array. This one is identical in both source files, so that's out.
  • 8: Number of items in the following array
  • The following array controls the mapping between the modifier key combinations and the column in the key_to_chars_nmod array: The sum of the modifier bits is used to index into the array; the member is the index of the entry in the key_to_chars_nmod definition.
AltGr sets the ALT and CTRL modifier bits, which is 6. If in the above example, we look at the 7th member of the array in modifier_bits, we find the value 2. This means that the character generated when pressing a key with AltGr is defined in the 3rd member of the respective array.

In the following example...

Code: Select all

ROSDATA VK_TO_WCHARS6 key_to_chars_6mod[] = {
  /* Normal, Shifted, AltGr, Ctrl, C-S-x, AG-S-x */
  { '2',         CAPS,   {'2', '\"', 0xb2, WCH_NONE, 0x00, 0x215b} },
  ...
...pressing AltGr+2 would output a superscript 2 (Unicode 0x00b2).

Any fault in modifier_bits would not only impact the behavior when pressing AltGr+<key> but also when pressing Ctrl+Alt+<key>. As I understand it, it would not change the behavior of the AltGr key itself. This must be defined somewhere else...

stanton
Posts: 10
Joined: Sun Nov 09, 2008 6:31 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by stanton » Tue Nov 11, 2008 12:19 am

Update...

Just copied the modifier_bits definition from the working (DE-based) layout into the broken (US Intl-based) layout, recompiled and tested. However, the AltGr key still behaves like a plain Alt key - so the modifier_bits are definitely innocent. The fault must lie somewhere else...

hto
Developer
Posts: 2193
Joined: Sun Oct 01, 2006 3:43 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by hto » Tue Nov 11, 2008 3:09 am

Look at TryToTranslateChar() in subsystems/win32/win32k/ntuser/keyboard.c.

Code: Select all

DPRINT("%d %04x: CapsMod %08x CapsState %08x Char %04x\n",
       nMod, wVirtKey,
       CapsMod, CapsState, *pwcTranslatedChar);
Replace DPRINT by DPRINT1 and see in debug log how it works, what it do with that AltGr+2.

stanton
Posts: 10
Joined: Sun Nov 09, 2008 6:31 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by stanton » Tue Nov 11, 2008 10:07 pm

Got me... I have no experience yet with debugging ReactOS components. The way I test is to build the DLL, then drop it into a Windows 2000 test system and use it. (I have no intention of building ReactOS - all I really need is a keyboard driver to use with Windows.)

However, I don't think the debugging will tell me terribly much: When I use the US-Intl-based layout, fire up Notepad and press AltGr, the keyboard shortcuts in the menu get underlined, as they are supposed to when I press the Alt key. With the DE-based layout, they don't. Hence I conclude that for some reason, with the US-Intl-based layout, the key labeled AltGr is an Alt key by all means. Hence I'm almost convinced that DPRINT will just report that I pressed Alt when in fact I pressed AltGr.

Is there anyone who can explain to me the mechanism that causes the AltGr key to set both the ALT and CTRL modifier bits when pressed, and where to find it in the code of, say, kbdgr.c?

hto
Developer
Posts: 2193
Joined: Sun Oct 01, 2006 3:43 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by hto » Wed Nov 12, 2008 4:46 am

Is there anyone who can explain to me the mechanism that causes the AltGr key to set both the ALT and CTRL modifier bits when pressed, and where to find it in the code of, say, kbdgr.c?
See ModBits() in subsystems/win32/win32k/ntuser/keyboard.c.

I don't know whether Windows works the same way or not. Some parts of ReactOS' Win32k are crap — should be rewritten.

By the way, if you want to talk with developers, join #reactos IRC channel.

stanton
Posts: 10
Joined: Sun Nov 09, 2008 6:31 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by stanton » Thu Nov 13, 2008 8:32 pm

Thanks for the hint. This has helped me understand that ReactOS in this respect is still fundamentally different from Windows:

In ReactOS, the right ALT key (VK_RMENU) is always the AltGr key because of the ModBits() function:

Code: Select all

   if (KeysSet( pkKT, KeyState, VK_LMENU, VK_RMENU ) &
         KS_DOWN_BIT )
      ModBits |= GetShiftBit( pkKT, VK_MENU );

   /* Handle Alt+Gr */
   if (KeysSet( pkKT, KeyState, VK_RMENU, 0 ) &
         KS_DOWN_BIT )
      ModBits |= GetShiftBit( pkKT, VK_CONTROL );
This is applied regardless of the keyboard layout and will always set the CTRL modifier bit when VK_RMENU is pressed. The only way to bypass this behavior is to define the right ALT key as VK_LMENU (kbdus.c does not define it altogether).

However, even with the US layout I notice that the right ALT key behaves differently from the left one in ReactOS: The left one will bring up the menu immediately, the right one will not. (Tested on 0.3.6, though.)

In short: ReactOS handles AltGr differently from Windows: While Windows seems to expect kind of information on the intended behavior of the right Alt/AltGr key from the layout itself (though I'm not sure what exactly this is), ReactOS ignores this and always makes it act like AltGr.

stanton
Posts: 10
Joined: Sun Nov 09, 2008 6:31 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by stanton » Thu Nov 13, 2008 10:30 pm

OK, now I got ReactOS 0.3.7 and tried to test both layouts on it:

The US-Intl-based layout works fine (AltGr behaves as expected on ReactOS but not on Windows, which confirms my previous suspicion).

The DE-based layout, however, doesn't do anything. When I select it, I get the standard German layout (keybgr.dll) instead. Weird...

I copied the compiled DLLs manually to the system32 dir of the VMware image and added the following entries to the registry:

Code: Select all

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\00040407]
"Layout Text"="German (Latin-1)"
"Layout File"="KBDGRLA1.DLL"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\00060409]
"Layout Text"="US (Latin-1)"
"Layout File"="KBDUSLA1.DLL"
So this leaves me with two questions:
  • How does Windows handle the Alt-vs-AltGr issue? How would I specify this in a keyboard driver?
  • And why can I use one keyboard layout on ReactOS but not the other, even though both work under Windows (except for the AltGr bug)?

stanton
Posts: 10
Joined: Sun Nov 09, 2008 6:31 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by stanton » Sun Nov 16, 2008 5:36 pm

OK... now I've simply downloaded Microsoft Keyboard Layout Creator, imported each of my ReactOS DLLs into it and generated new DLLs with MSKLC. These work as expected on Windows, which solves my initial problem.

As for the differences in Windows/ReactOS: In theory I could now call KbdLayoutDescriptor() of both DLLs (the Windows and the ReactOS one) and see what they return and how these data structures differ among them, so I would get an idea of the differences between Windows and ReactOS.

Is anybody aware of a tool that calls KbdLayoutDescriptor and dumps the structure returned, or would I have to write my own?

Z98
Release Engineer
Posts: 3379
Joined: Tue May 02, 2006 8:16 pm
Contact:

Re: Keyboard Layouts - Alt vs. AltGr

Post by Z98 » Sun Nov 16, 2008 7:09 pm

Write your own. Though perhaps there's a Winetest or something that does that.

stanton
Posts: 10
Joined: Sun Nov 09, 2008 6:31 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by stanton » Wed Nov 19, 2008 12:24 am

OK, I have started writing a dump utility and taking a close look at the first test outputs I might have found out what controls the AltGr behavior in Windows: It seems to be the lowest bit of the fLocalFlags member of the KBDTABLES structure.

Testing the various DLLs returned the following:

0x00010000 - kbdus.dll (Windows 2000)
0x00010001 - kbdusx.dll (Windows 2000)
0x00010000 - kbdusx.dll (ReactOS)
0x00010001 - kbdgr.dll (Windows 2000)
0x00010001 - kbdgr.dll (ReactOS)

So: It seems to me that the kbdusx.dll in ReactOS contains a bug that has gone unnoticed until now as the AltGr behavior is hardcoded in ReactOS rather than dependent on fLocalFlags. On Windows the AltGr key would be a plain Alt key.

The source files of the keyboard layout DLLs have a somewhat misleading comment next to this member:

Code: Select all

  MAKELONG(0,1), /* Version 1.0 */
This is why I never paid any real attention to this line of code...

Lone_Rifle
Test Team
Posts: 802
Joined: Thu Apr 03, 2008 2:17 pm
Contact:

Re: Keyboard Layouts - Alt vs. AltGr

Post by Lone_Rifle » Wed Nov 19, 2008 2:31 am

If you're quite sure that's where the problem lies, would you be able to file a Bugzilla? If you can also submit an SVN patch that would also be appreciated.... Not sure if this actually hampers ROS' compatibility with Windows, but I'm sure one of the devs would be interested...

hto
Developer
Posts: 2193
Joined: Sun Oct 01, 2006 3:43 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by hto » Wed Nov 19, 2008 2:51 am

Stanton, thanks for the discovery.
Lone_Rifle wrote: [...] would you be able to file a Bugzilla?
Done: http://www.reactos.org/bugzilla/show_bug.cgi?id=3887 .

stanton
Posts: 10
Joined: Sun Nov 09, 2008 6:31 pm

Re: Keyboard Layouts - Alt vs. AltGr

Post by stanton » Wed Nov 19, 2008 9:32 pm

Thanks for filing the bugzilla. I'll do some more research to get a deeper insight into the meaning of fLocalFlags and post it here. If I can confirm what I find now, a SVN patch should not be too difficult...

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests