Windows keyboard layout assembler / disassembler using flat assembler

layout


A familiar Linuxoid reproached me, saying that there is no Caps Lock language switch in Windows, nor even the layout can be edited. I looked, and the truth is, all the layouts are contained in the C: \ Windows \ System32 \ kbd * .dll files, and editing this with a hex editor is by no means convenient.


How to reach convenience? To switch Caps Lock layouts, you can use all sorts of attachments, heavy ones like Punto Switcher, or simple ones like lswitch. For editing layouts, there is MSKLC, but it is poorly functional and inconvenient, and analogues like KbdEdit or KLM32 are paid.


And then I decided to write code on a flat assembler that collects the layout DLLs.


The layout was taken as kbdusx.dll, in the system it is called "USA International". I liked it because it has a number of combinations for additional characters. She didn’t like the fact that she turns the <`~>, <6 ^>, <'"> keys into the so-called dead keys, “dead keys.” Their peculiarity is that nothing is printed when pressed, but the next character typed changes. you can enter latin letters with diacritics for which there is no separate keyboard shortcut, but as a programmer I was very unpleasant to “stick” such frequently used keys, and initially I just reset the fields in the hex editor that are responsible for dead keys.


It's time to deal with the format once and for all. At first, things went slowly, then I found kbd.h and some examples of layouts from the Windows Driver Kit.


Inside layout


It's funny that Microsoft decided to put the layouts in the DLL format, although with the exception of the Korean kbdkor.dll and the Japanese kbdjpn.dll, there is no code at all, except for the exported KbdLayerDescriptor function, which returns a pointer to the main table with the layout.


The table looks like this:


32-bit Windows64-bit or WOW64
TitleThe sizeBiasThe sizeBias
modifiers40x0080x00
vk2wchar40x0480x08
deadkeys40x0880x10
keynames40x0C80x18
keynamesExt40x1080x20
keynamesDead40x1480x28
scancode2vk40x1880x30
scancode2vk_size10x1C10x38
e0scancode2vk40x2080x40
e1scancode2vk40x2480x48
locale_flags20x2820x50
version20x2A20x52
ligature_chars10x2C10x54
ligature_size10x2D10x55
ligatures40x3080x58
type40x3440x60
subtype40x3840x64

Thus, the layout file contains the tables of the name of the keys, the conversion of scan codes to virtual (0x1C → VK_RETURN), the conversion of virtual codes to characters, combinations of dead keys, “ligatures”.


Apparently, the names of the keys are rarely used, I could not find programs on my computer that would list them out of the layout.


By changing the table of scan codes, you can reassign any key to another. If you immediately wanted to reassign the power buttons (Power, Sleep, WakeUp), then this is also possible, but this will not cancel their original function. It can be turned off in the power settings.


The symbol table has the juice itself. It decides what the keystrokes K, Shift + K, AltGr + K, Shift + AltGr + K will do, whether Caps Lock affects it, whether it uses the same series of characters as Shift + K or a separate one, whether her Kana; whether the character will be printed immediately, or it will be entered into the dead key queue, or a series of characters from the "ligature" will be printed, or whether nothing will happen.


AltGr - this is the name of the right Alt (if included in the layout with the KLLF_ALTGR flag), it generates the keyboard shortcut Ctrl + Alt.


The list of dead keys contains pairs of characters that must be converted to the third character. This character can be printed immediately, or again go through the list for further conversion. If a pair of characters is not found in the list, then it will simply be printed as is. Using chains of dead keys you can simulate the behavior of Compose Key, but some programs, such as Firefox, do not recognize conversions beyond the first.


The list of "ligatures", which is essentially a set of macros, can allow you to type up to four WCHAR characters at the touch of a button. In fact, up to 16 characters work for me in Windows 7, but with an extremely unpleasant exception: Firefox completely freezes when I encounter such a layout, and if the layout with long “ligatures” is systemic, it completely stops running.


Create Layout


First, I wanted to make two convenient layouts, Russian and English, suitable for writing articles and programs. Ilya Birman’s typographic layout is good, but it could be even better, especially if you do it for yourself.


Then I found out about the Kana key. Kana is a button that switches like a caps lock on a Japanese keyboard. And then I decided to combine the English and Russian layouts into one, and switch between them with the Kana key. Which I reassigned to Caps Lock. I wrote a simple indicator program to display the status of Kana with a Caps Lock light.


Such a combined layout had one pleasant surprise: the layout is now the only one for the entire system, and remains when switching between programs, as well as the “very smart” programs can no longer switch the layout as they wish when editing text or moving the cursor.


And one unpleasant surprise: for some reason, Psi + began to eat the first character entered after switching layouts by pressing Kana.


However, I left this layout in the archive along with the Kana indicator.


Then I discovered that Caps Lock can be assigned a separate series of characters and replaced Kana with Caps Lock. The indicator program has become unnecessary, an unpleasant surprise has disappeared. During the alteration, only one limitation was found: Caps Lock only works with rows K and Shift + K - you cannot hang AltGr + K on it, etc.


In an attempt to fit all the dead keys in two rows (there were four with Kana), I came across the idea of ​​reversing their order: so that AltGr + was typed in a letter, and then a modifier. This allowed me to assign many more characters than before. I called it “undead keys”, “risen from the dead keys”.


And then the perfect layout was ready.


Advantages of the kbdusru_undead layout


  1. Switch between Russian and English with one key Caps Lock.
  2. The Caps Lock indicator shows the current language.
  3. Global layout state for all applications.
  4. The inability of "very smart" programs to spontaneously change the layout.
  5. The ability to enter letters with diacritics and a bunch of other characters.
  6. The ability to easily edit the layout to taste.

An example of entering some additional characters


Keyboard shortcutResult
AltGr + 5
AltGr + 9"
AltGr + 0"
AltGr + --
AltGr + =
AltGr +;°
AltGr +,<
AltGr +.>
AltGr + Shift + // me
AltGr + a, 'á
AltGr + e, `è
AltGr + o, "ő
AltGr + n, ~ñ
AltGr + c, ^ĉ
p, s, AltGr + q, ', b, afish
AltGr + c, o©
AltGr + r, o®
AltGr + t, m(tm)
AltGr + m, uµ
AltGr + h, s
AltGr + f, 2½
AltGr + b, f

Installation


I just replace the system file C: \ Windows \ System32 \ kbdru.dll with my layout, because it is better in every way. On Windows XP or 2000, in this case, you must remember to delete C: \ Windows \ System32 \ dllcache \ kbdru.dll.


But if you do not like such a forced upgrade of Windows, then the layout can be copied to the C: \ Windows \ System32 \ folder and registered in the system using such a reg-file:


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\07430419]
"Layout Text"="US+RU"
"Layout Display Name"="United States-International + Russian + Extra"
"Layout File"="kbdusru_undead.dll"
"Layout Id"="00d0"

The first part of the code, 0743 is arbitrary digits for the unique identification of the layout, and 0419 is the Russian language code under which the layout should appear. The layout behavior in non-Unicode (ANSI) programs depends on the language code. If question marks appear when typing letters, then this is a sure sign of an incorrectly specified language code.


Further more


It gives me pleasure to program on a flat assembler: a powerful macro language, a beautiful and obedient syntax, the uselessness of all kinds of linkers and a mess of parameters on the command line.


Поэтому я решил написать на нём программу, которая при ассемблировании читает DLL раскладки, а на выходе — исходный код. Странно, правда? Использовать ассемблер, как дизассемблер. Но мощь fasm'а это позволяет.


В результате у меня получились раскладки, которые позволяют переключаться между языками Caps Lock'ом без внешних программ глобально для всей системы, а также набор инструментов, который позволяет нам удобно редактировать раскладки клавиатуры Windows.


Всё выложено на https://github.com/grompe/kbdasm как общественное достояние.


Если у вас 64-битная Windows, можно скачать архив, распаковать и запустить make.bat, а затем install.bat. Для 32-битной придётся сперва подправить файл kbdusru_undead.asm.


Also in the archive there is a program get_scancodes. If you have a tricky keyboard with additional keys, using the program you can find out the scan codes and use these keys in the layout.


Also popular now: