Author Topic: Custom keyboards and foreign layout (AZERTY for ex), how to map them correctly ?  (Read 4791 times)

0 Members and 1 Guest are viewing this topic.

Offline Nlight

  • Thread Starter
  • Posts: 57
  • Location: France
Hi,

I currently have a custom keyboard project, but I am French and used to AZERTY layout, even if my current key keymap is heavily customized to make a lotta keys more accessible.

I wonder how will I program the firmware, I mean does not EVERY keyboard use QWERTY layout codes, which is then translated by the OS with the correct keymap ? which would explain why when you install an OS it does ask you your "keyboard language".

I thought that I make a firmware directly in let say AZERTY, I would have to make my keyboard layout in the OS as U.S. English keymap.

Is it correct ? How does it work really ?

Offline TalkingTree

  • Posts: 2452
  • Location: Italy (142)
    • My projects
does not EVERY keyboard use QWERTY layout codes, which is then translated by the OS with the correct keymap ?
Yes, you got it, firmwares use the US ANSI (which is a QWERTY) for reference. It's a OS task to translate your inputs (scancodes) into actual characters given the desired language.
My opensource projects: GH80-3000, TOAD, XMMX. Classified: stuff

Offline Nlight

  • Thread Starter
  • Posts: 57
  • Location: France
Ok, thanks :)

I still have some questions though :
on https://kbfirmware.com/
here is a layer example of what I can do :

How can I do this in EasyAVR ? cause in there, to get parenthesis, well the only key in the qwerty keymap that has it is 9...
hmmm... that makes me thinking about the automods that I did not really understand its usefulness, is it what it is for ? In order to have a key that directly output "(" I would have to set the key to Shift+9 ?
« Last Edit: Wed, 20 June 2018, 07:01:21 by Nlight »

Offline TalkingTree

  • Posts: 2452
  • Location: Italy (142)
    • My projects
In order to have a key that directly output "(" I would have to set the key to Shift+9 ?
No, just the 5 key (make sure you don't use the keypad 5 because it's a different key). The US-ANSI 5 in EasyAVR (but generally every keyboard firmware) is actually a placeholder for the scancode 06 which is translated as the ( 5 key in the French AZERTY language. Since in that particular encoding the numbers are actually shifted, you just need to define the keycode as the number 5.
My opensource projects: GH80-3000, TOAD, XMMX. Classified: stuff

Offline Nlight

  • Thread Starter
  • Posts: 57
  • Location: France
Yeah, at first I did not get you, but I should have been more specific, cause I meant my question with the os keymap set to U.S. English. THe main point was to understand the automods in  easyAVR.

I think I will set the os keymap to US and make the firmware main layer "AZERTY", and incorporate in an other layer, a true QWERTY. So in that context of US-ANSI, for a key to output directly "(" it has to be set to 9 + Automods(Shift) ?

The more I read its docs, the more it seems to make sense that this is what automods is used for.

Offline suicidal_orange

  • * Global Moderator
  • Posts: 4771
  • Location: England
Yes 9 + Automods(Shift) is correct for a "(" in US ANSI.  You might find yourself using an FN key instead of shift, if you do you can set the automods on the FN and they will apply to all the keys on the layer :)
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline Nlight

  • Thread Starter
  • Posts: 57
  • Location: France
Quote
Yes 9 + Automods(Shift) is correct for a "(" in US ANSI
God I'm on fire today  :))  Thanks :)
Quote
You might find yourself using an FN key instead of shift, if you do you can set the automods on the FN and they will apply to all the keys on the layer
Oh... sweet :), like real sweet, I dunno If I will have a layer made of only automods of the very same modifier, but that's good to know. thanks

Offline Koren

  • Posts: 133
  • Location: France
does not EVERY keyboard use QWERTY layout codes, which is then translated by the OS with the correct keymap ?
Yes, you got it, firmwares use the US ANSI (which is a QWERTY) for reference. It's a OS task to translate your inputs (scancodes) into actual characters given the desired language.
Definitively not all firmwares.

QMK at the very least allows you to somehow choose the mapping at compilation time. QWERTY is the default when you download the firmware, but it's easy to switch to AZERTY, QWERTZ, or even any custom layout (on OS-side).

But again, it's at compilation time, which is not perfect (if you have a keyboard configured for AZERTY, and you plug it into a computer which has a keyboard configuration for QWERTY, you're basically dead.

(To be more precise, if you want a Q on a key, and the computer is configured as QWERTY, you just put KC_Q in your mapping, but if you know the computer is configured as french AZERTY, you can use FR_Q... which is basically a KC_A in disguise. I'm not a fan of all those #defines, but at least it's simple and compile-time)


The firmware I'm working on can switch it at runtime: you just put CHR_Q in the mapping, and it sends either the proper scancode depending on the PC configuration (the only issues is that you need to put both your layouts for the keyboards and all the layouts you want to be able to translate to in the firmware, which needs some memory)

Offline Nlight

  • Thread Starter
  • Posts: 57
  • Location: France
Quote
(To be more precise, if you want a Q on a key, and the computer is configured as QWERTY, you just put KC_Q in your mapping, but if you know the computer is configured as french AZERTY, you can use FR_Q... which is basically a KC_A in disguise. I'm not a fan of all those #defines, but at least it's simple and compile-time)
Well, if FR_Q is a #define, I guess it must look something like :
Code: [Select]
#define FR_Q KC_Aor more likely this
Code: [Select]
#define KC_A 31
#define FR_Q 31
meaning that before the compilation process starts, FR_Q and KC_A will be replaced by 31, which makes it US qwerty.

In other words, a keyboard is a hardware that sends specific numbers according to specific location in the (standard) keys arrangement. Software on the computer side translates the numbers into characters.

When you say "switch language" at runtime (on the keyboard side), it means your language on the computer side will need to be US English (ANSI or ISO or Whatever) as it is used as reference  for your layers to work as you programmed them. *

  • Let Say that in the firmware, you put a KC_A for AZERTY where there should be Q in QWERTY.
  • Now set your os keyboard layout to FR, and type on your A key, you will send scancode 31 and get Q instead.
  • Now set your os keyboard layout to US, and type on your A key, you will send scancode 31 and get A as intended.
and as you don't have things as dead keys on US layout (for example ¨ or ^), you will have to program that os side, because this is case is software, not hardware.

And all this gives me a better understanding of what you should and should not do with layers, if you expect someone else to use your firmware.

In any way, you seem to be already working on it, I am curious and interested to see how you pull this off.

 (*): Unless there is a scancode or an instruction that the os is hooked to to perform a software switch of the layout somehow... maybe as part of a driver... dunno, i'm way out of my league here. or maybe a unicode thing, which I have not dug yet.
« Last Edit: Wed, 20 June 2018, 18:12:17 by Nlight »

Offline Koren

  • Posts: 133
  • Location: France
Quote
(To be more precise, if you want a Q on a key, and the computer is configured as QWERTY, you just put KC_Q in your mapping, but if you know the computer is configured as french AZERTY, you can use FR_Q... which is basically a KC_A in disguise. I'm not a fan of all those #defines, but at least it's simple and compile-time)
Well, if FR_Q is a #define, I guess it must look something like :
Code: [Select]
#define FR_Q KC_Aor more likely this
Code: [Select]
#define KC_A 31
#define FR_Q 31
Actually, the first but it doesn't matter... It's probably 0x14 (20) rather than 31, too, IIRC.

Edit: 0x04, my bad... since you're referring to QWERTY A

meaning that before the compilation process starts, FR_Q and KC_A will be replaced by 31, which makes it US qwerty.
I'd argue that, for a ANSI/ISO keyboard, codes refer to a physical position, not an actual symbol... So, to me, it's layout-independant.

Granted, with USB HID, the numbering isn't a line/column numbering like it used to be, and the way they designed it, there's a QWERTY bias. You can associate UsageID with symbols (letters) if you want, but to me, the 0x14 UsageID mean AT's position 17, which isn't tied to a specific letter (since that depends on the keyboard)

That being said, it's almost philosophical, and it's not important for the user...

What I meant is, it's totally symmetric in QMK firmware:
If you've installed a QWERTY keyboard, use KC_Q to reference the letter Q, it'll send a 0x14, and you'll get a Q
If you've installed an AZERTY keyboard, use FR_Q to reference the letter Q, it'll send a 0x04, and you'll get a Q

You just have to hardcode in the firmware which UsageID is linked to which symbol. QMK has basically all mappings (QWERTY, AZERTY, QWERTZ...) defined...

When you say "switch language" at runtime (on the keyboard side), it means your language on the computer side will need to be US English (ANSI or ISO or Whatever) as it is used as reference  for your layers to work as you programmed them.
Well, no, precisely...

What I mean is that if I associate a physical key to KEY_Q in a layer, when I send the UsageID, I use a second translation table. So I can choose, at runtime, whether I send a 0x14 or a 0x04.

For example, when the OS is launched, I have an AZERTY layout installed. When I press Q, a Q appear on screen. Now, for some reason (BIOS lacking layout support, old DOS game, etc.), a software assume a QWERTY layout. If I press Q, I would normally get A.

In this case, I just press the QWERTY/AZERTY switch on the keyboard, and I get Q in the DOS game without any change in the computer side.


(*): Unless there is a scancode or an instruction that the os is hooked to to perform a software switch of the layout somehow... maybe as part of a driver... dunno, i'm way out of my league here. or maybe a unicode thing, which I have not dug yet.
There is, but it's OS dependant, and I don't want this.

It's actually like the keyboard disguising itself.

The OS think you have a QWERTY keyboard? My firmware will act as a QWERTY keyboard.

Now it assumes you have an AZERTY one? A single switch, and the firmware act as an AZERTY one.


In other words:

* first table, in firmware:
    physical position -> unicode identifier

* second table, in firmware
    unicode indentifier -> UsageID code

* third table, in OS :
    UsageID code -> actual character typed


Thing is, you don't always has control on the third table, since it's the layout installed on the OS (or hardcoded into the application)

Most firmware merge the first two translations into a single one: physical position -> UsageID code.

Problem is, you need to know the third table (thus the hardware configuration) when you compile the firmware...

By handling a double translation mechanism, I can adapt to different layout installed in the OS.

I probably should do a video, it would be simpler :)

 
Beside the obvious "****, it's configured as QWERTY" issue, I use a very different layout on my computers (more symbols, and characters in unusual places). I obviously want to be able my keyboard with my specific layout installed (partly because there's plently of characters in it that are neither in AZERTY nor in QWERTY).

But if I plug my keyboard into someone else computer (which will be either AZERTY or QWERTY), I want it to work normally, without touching anything in the computer configuration.
« Last Edit: Thu, 21 June 2018, 13:22:56 by Koren »

Offline Nlight

  • Thread Starter
  • Posts: 57
  • Location: France
Hmmm... There are several terms you mention that I need to dig.

I am on my phone in vaccation in italy, so I'll be short. My guts tell me that you won't be able to hardcode into the firmware a full AZERTY. But I would be very glad to be correctes. Tell me, how would you do to output "ë" ?

Or even tu output any non-latin character ? I Ask it as a rethorical question, but you may very well have an answer that I would find very useful.

Cheers

Offline suicidal_orange

  • * Global Moderator
  • Posts: 4771
  • Location: England
Tell me, how would you do to output "ë" ?
You can hold Alt and type 137 on your numberpad, this can be done in a macro in the firmware.  Full list of codes :)
120/100g linear Zealio R1  
GMK Hyperfuse
'Split everything' perfection  
MX Clear
SA Hack'd by Geeks     
EasyAVR mod

Offline Nlight

  • Thread Starter
  • Posts: 57
  • Location: France
So simple, yet functional ☺, i didn't remember this function