Send language layout from USB HID keyboard

Mark14074

01 Jun 2019, 12:11

I am currently working on a USB HID keyboard using an Atmel microcontroller.

Everything is working fine but I usually use different keyboard layouts on different machines.

Now I started wondering if it would be possible to tell the host which keyboard layout to use, i.e. EN-US, so that keycodes will always get mapped on the right character on every machine.

Any ideas?

krogerfeedback

User avatar
vvp

01 Jun 2019, 20:41

Not without a a custom driver.

You can write some macro which will do it for you or an application which will switch the layout after some special input (e.g. on F13).

And you can use something like Compose key or Unicode hex input to simulate changing layouts.
Compose key support is native in linux and requires an application to get support on windows.
Unicode hex input should be supported by both windows and linux but there probably will be caveats. I did not really try it.

Findecanor

02 Jun 2019, 03:09

There is a "bCountryCode" field in the HID descriptor which is downloaded from the keyboard to the host when the keyboard is connected, but I believe that it is unsupported by operating systems because code the code space is badly defined and I think most keyboards are manufactured with their internals supporting multiple layouts (code 0: "Not supported") anyway.
Spoiler:
Country, language and layout are three different things, and they are jumbled up. For instance it has "Canadian-Bilingual", "Canadian-French" and "Latin American" as "country codes" whereas I would call those layout codes, but "Swedish" and "Finnish" as distinct codes when those two countries use the same keyboard layout. Then there is "Portuguese" ... but Brazil or Portugal?
There are only 35 codes, which is only a handful.
You could perhaps put a USB hub inside the keyboard, with the keyboard and a USB stick under the hub. Then put a autorun.inf on the stick with a command to change the layout.
That would require the computers to run MS Windows, have autorun enabled and you would only be able to change to the one layout on the stick.
Although I suppose you could circumvent the latter by having multiple sticks and use a physical switch to power up only one at a time. (But that would really be a kludge)

User avatar
depletedvespene

02 Jun 2019, 03:12

... not that I mean to be a prick, but a keyboard with a program to run on the host when plugged onto it would be rejected anywhere with any sense of security (EVEN my former bank).

User avatar
AlbertoGP

04 Jun 2019, 09:04

Findecanor wrote:
02 Jun 2019, 03:09
There is a "bCountryCode" field in the HID descriptor which is downloaded from the keyboard to the host when the keyboard is connected, but I believe that it is unsupported by operating systems because code the code space is badly defined and I think most keyboards are manufactured with their internals supporting multiple layouts (code 0: "Not supported") anyway.
That’s right, I just tried with my Sun Type 7 keyboard in Linux, MacOS X, and Windows 10, and the selected layout does not change to the one reported by the keyboard when I plug it in.

From the USB Device Class Definition for Human Interface Devices (HID) Firmware Specification Version 1.11, page 22 (32 in PDF):
https://usb.org/sites/default/files/doc ... _11.pdf#32
The value bCountryCode identifies which country the hardware is localized for. Most hardware is not localized and thus this value would be zero (0).
However, keyboards may use the field to indicate the language of the key caps.
Devices are not required to place a value other than zero in this field, but some operating environments may require this information. The following table specifies the valid country codes.
As far as I know, the only OS to use this is Sun’s Solaris. They believed in it so much that in their SPARC-based machines “You cannot change the layout of Type 6 keyboards because the back of the keyboard has no DIP switch. Some Type 5 and 5c keyboards, for example, U.S.A., U.S.A./UNIX, and Japanese keyboards have jumpers instead of DIP switches. Other than the xmodmap utility or the kbd -s command, the SPARC platform does not offer utilities or tools that you can use to switch keyboards.” [1]

[1] https://docs.oracle.com/cd/E19253-01/81 ... index.html

Anakey

04 Jun 2019, 09:18

I would say the best way to do it would be to use something like QMK firmware and have the different layouts that you want on different layers so you would be able to cycle to the layer that you want depending on the system you are in and with all programming done and remaining on the keyboard level.

Findecanor

04 Jun 2019, 10:23

Anakey wrote:
04 Jun 2019, 09:18
...different layouts that you want on different layers...
The problem is that language-layout is interpreted by the host, not the keyboard.

I think that ultimately, the solution would have to be in host software.
Either make sure that you have to log in and have the layout changed in your login script.
Or make a script (for AutoHotKey or a USB device management program) that detects the particular VendorID/ProductID pair of your keyboard and changes the layout as a result.

User avatar
vvp

04 Jun 2019, 11:06

Findecanor wrote:
04 Jun 2019, 10:23
Anakey wrote:
04 Jun 2019, 09:18
...different layouts that you want on different layers...
The problem is that language-layout is interpreted by the host, not the keyboard.
That is only a problem if one cannot get a generic super set of all layouts working. Like Compose key or unicode hex input. Then you can issue any key using the right tiny macro. Compose key(*) works fine on both windows and linux. I cannot comment much on unicode hex input since I did not use it. There may be other usable options.

(*) Compose key on windows requires installation of an additional program but it works well.

User avatar
depletedvespene

04 Jun 2019, 11:14

vvp wrote:
04 Jun 2019, 11:06
(*) Compose key on windows requires installation of an additional program but it works well.
And that is another problem with requiring the usage of a language code hardcoded (so to speak) in the keyboard itself: it would restrict its usage to a certain list of pre-known national layouts, limiting the creation of others customized for a particular user's whims or for new languages, or even new takes on an existing language (not to even mention if things get political when it comes to the language itself). In the end, I think the current state of things (the keyboard sends codes corresponding to the physical layout and the operating systems translate them to the corresponding characters according to one of many conversion tables that it has on hand).

Of course, the physical layout could be improved, and many national layouts (as specified by those conversion tables) need serious updates, too, but that's another matter. I should know. :mrgreen:

User avatar
swampangel

04 Jun 2019, 13:42

Mark14074 wrote:
01 Jun 2019, 12:11
Now I started wondering if it would be possible to tell the host which keyboard layout to use, i.e. EN-US, so that keycodes will always get mapped on the right character on every machine.

Any ideas?
Others have given you some advice on why this might not be a great idea. But I think it's possible, if your hosts all run the same OS at least:

https://h3llwings.wordpress.com/2016/10 ... th-teensy/

https://docs.microsoft.com/en-us/powers ... w=win10-ps

You'd be creating an exploit, more or less, to run powershell commands when you plug in or press a certain key combo. I imagine you could do the same for mac/linux too with different commands.

Post Reply

Return to “Keyboards”