xref: /reactos/dll/keyboard/kbdrost/kbdrost.c (revision b09b5584)
1 // This file is converted by code7bit.
2 // code7bit: https://github.com/katahiromz/code7bit
3 // To revert conversion, please execute "code7bit -r <file>".
4 /*
5  * ReactOS Romanian (Standard) Keyboard layout
6  * Copyright (C) 2018 ReactOS
7  * Author: Ștefan Fulea (stefan dot fulea at mail dot com)
8  * License: LGPL, see: LGPL.txt
9  *
10  * Thanks to: http://www.barcodeman.com/altek/mule/scandoc.php
11  * and http://win.tue.nl/~aeb/linux/kbd/scancodes-1.html
12  *
13  * Romanian standard layout as defined in SR 13392:2004 by
14  * Romanian Standards Association (ASRO), with enacted use in
15  * romanian public institutions through Order no. 414/25.09.2006
16  * http://legislatie.just.ro/Public/FormaPrintabila/00000G22CFKNTV3ZAR52IRPL5V03Y1CD
17  *
18  * The combining characters, non-romanian diacritics and other
19  * symbols were taken as reference from Microsoft's demo layout:
20  * https://docs.microsoft.com/en-us/globalization/keyboards/kbdrost.html
21  *
22  * Finally, considering the amount of combining characters unused in Romanian
23  * but present by default in this language's keyboard layouts, I've took the
24  * liberty to add one combining character that it may use but I haven't
25  * encountered as of the time of this writing. The combining comma below,
26  * provides an alternative way of generating romanian S-comma and T-comma
27  * characters and is set as a dead character under letter Q.
28  *
29  */
30 
31 #define WIN32_NO_STATUS
32 #include <stdarg.h>
33 #include <windef.h>
34 #include <winuser.h>
35 #include <ndk/kbd.h>
36 
37 #ifdef _M_IA64
38 #define ROSDATA static __declspec(allocate(".data"))
39 #else
40 #ifdef _MSC_VER
41 #pragma data_seg(".data")
42 #define ROSDATA static
43 #else
44 #define ROSDATA static __attribute__((section(".data")))
45 #endif
46 #endif
47 
48 #define VK_EMPTY  0xff   /* The non-existent VK */
49 
50 #define KNUMS     KBDNUMPAD|KBDSPECIAL /* Special + number pad */
51 #define KMEXT     KBDEXT|KBDMULTIVK    /* Multi + ext */
52 
53 ROSDATA USHORT scancode_to_vk[] =
54 {
55   /* Numbers Row */
56   /* - 00 - */
57   /* 1 ...         2 ...         3 ...         4 ... */
58   VK_EMPTY,     VK_ESCAPE,    '1',          '2',
59   '3',          '4',          '5',          '6',
60   '7',          '8',          '9',          '0',
61   VK_OEM_MINUS, VK_OEM_PLUS,  VK_BACK,
62 
63   /* - 0f - */
64   /* First Letters Row */
65   VK_TAB,       'Q',          'W',          'E',
66   'R',          'T',          'Y',          'U',
67   'I',          'O',          'P',
68   VK_OEM_4,     VK_OEM_6,     VK_RETURN,
69 
70   /* - 1d - */
71   /* Second Letters Row */
72   VK_LCONTROL,
73   'A',          'S',          'D',          'F',
74   'G',          'H',          'J',          'K',
75   'L',          VK_OEM_1,     VK_OEM_7,     VK_OEM_3,
76   VK_LSHIFT,    VK_OEM_5,
77 
78   /* - 2c - */
79   /* Third letters row */
80   'Z',          'X',          'C',          'V',
81   'B',          'N',          'M',          VK_OEM_COMMA,
82   VK_OEM_PERIOD,VK_OEM_2,     VK_RSHIFT,
83 
84   /* - 37 - */
85   /* Bottom Row */
86   VK_MULTIPLY,  VK_LMENU,     VK_SPACE,     VK_CAPITAL,
87 
88   /* - 3b - */
89   /* F-Keys */
90   VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6,
91   VK_F7, VK_F8, VK_F9, VK_F10,
92 
93   /* - 45 - */
94   /* Locks */
95   VK_NUMLOCK | KMEXT,
96   VK_SCROLL | KBDMULTIVK,
97 
98   /* - 47 - */
99   /* Number-Pad */
100   VK_HOME | KNUMS,      VK_UP | KNUMS,         VK_PRIOR | KNUMS, VK_SUBTRACT,
101   VK_LEFT | KNUMS,      VK_CLEAR | KNUMS,      VK_RIGHT | KNUMS, VK_ADD,
102   VK_END | KNUMS,       VK_DOWN | KNUMS,       VK_NEXT | KNUMS,
103   VK_INSERT | KNUMS,    VK_DELETE | KNUMS,
104 
105   /* - 54 - */
106   /* Presumably PrtSc */
107   VK_SNAPSHOT,
108 
109   /* - 55 - */
110   /* Oddities, and the remaining standard F-Keys */
111   VK_EMPTY,     VK_OEM_102,     VK_F11,       VK_F12,
112 
113   /* - 59 - */
114   VK_CLEAR,     VK_EMPTY,     VK_EMPTY,     VK_EMPTY,     VK_EMPTY, /* EREOF */
115   VK_EMPTY,     VK_EMPTY,     VK_EMPTY,     VK_EMPTY,     VK_EMPTY, /* ZOOM */
116   VK_HELP,
117 
118   /* - 64 - */
119   /* Even more F-Keys (for example, NCR keyboards from the early 90's) */
120   VK_F13, VK_F14, VK_F15, VK_F16, VK_F17, VK_F18, VK_F19, VK_F20,
121   VK_F21, VK_F22, VK_F23,
122 
123   /* - 6f - */
124   /* Not sure who uses these codes */
125   VK_EMPTY, VK_EMPTY, VK_EMPTY,
126 
127   /* - 72 - */
128   VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY,
129 
130   /* - 76 - */
131   /* One more f-key */
132   VK_F24,
133 
134   /* - 77 - */
135   VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY,
136   VK_EMPTY, VK_EMPTY, VK_EMPTY, VK_EMPTY, /* PA1 */
137 };
138 
139 ROSDATA VSC_VK extcode0_to_vk[] =
140 {
141   { 0x10, VK_MEDIA_PREV_TRACK | KBDEXT },
142   { 0x19, VK_MEDIA_NEXT_TRACK | KBDEXT },
143   { 0x1D, VK_RCONTROL | KBDEXT },
144   { 0x20, VK_VOLUME_MUTE | KBDEXT },
145   { 0x21, VK_LAUNCH_APP2 | KBDEXT },
146   { 0x22, VK_MEDIA_PLAY_PAUSE | KBDEXT },
147   { 0x24, VK_MEDIA_STOP | KBDEXT },
148   { 0x2E, VK_VOLUME_DOWN | KBDEXT },
149   { 0x30, VK_VOLUME_UP | KBDEXT },
150   { 0x32, VK_BROWSER_HOME | KBDEXT },
151   { 0x35, VK_DIVIDE | KBDEXT },
152   { 0x37, VK_SNAPSHOT | KBDEXT },
153   { 0x38, VK_RMENU | KBDEXT },
154   { 0x47, VK_HOME | KBDEXT },
155   { 0x48, VK_UP | KBDEXT },
156   { 0x49, VK_PRIOR | KBDEXT },
157   { 0x4B, VK_LEFT | KBDEXT },
158   { 0x4D, VK_RIGHT | KBDEXT },
159   { 0x4F, VK_END | KBDEXT },
160   { 0x50, VK_DOWN | KBDEXT },
161   { 0x51, VK_NEXT | KBDEXT },
162   { 0x52, VK_INSERT | KBDEXT },
163   { 0x53, VK_DELETE | KBDEXT },
164   { 0x5B, VK_LWIN | KBDEXT },
165   { 0x5C, VK_RWIN | KBDEXT },
166   { 0x5D, VK_APPS | KBDEXT },
167   { 0x5F, VK_SLEEP | KBDEXT },
168   { 0x65, VK_BROWSER_SEARCH | KBDEXT },
169   { 0x66, VK_BROWSER_FAVORITES | KBDEXT },
170   { 0x67, VK_BROWSER_REFRESH | KBDEXT },
171   { 0x68, VK_BROWSER_STOP | KBDEXT },
172   { 0x69, VK_BROWSER_FORWARD | KBDEXT },
173   { 0x6A, VK_BROWSER_BACK | KBDEXT },
174   { 0x6B, VK_LAUNCH_APP1 | KBDEXT },
175   { 0x6C, VK_LAUNCH_MAIL | KBDEXT },
176   { 0x6D, VK_LAUNCH_MEDIA_SELECT | KBDEXT },
177   { 0x1C, VK_RETURN | KBDEXT },
178   { 0x46, VK_CANCEL | KBDEXT },
179   { 0, 0 }
180 };
181 
182 ROSDATA VSC_VK extcode1_to_vk[] =
183 {
184   { 0x1d, VK_PAUSE },
185   { 0, 0 }
186 };
187 
188 ROSDATA VK_TO_BIT modifier_keys[] =
189 {
190   { VK_SHIFT,   KBDSHIFT },
191   { VK_CONTROL, KBDCTRL },
192   { VK_MENU,    KBDALT },
193   { 0,          0 }
194 };
195 
196 ROSDATA MODIFIERS modifier_bits =
197 {
198   modifier_keys,
199    7,
200    { 0, 1, 2, SHFT_INVALID, SHFT_INVALID, SHFT_INVALID, 3, 4 }
201    /* Modifiers order: NONE, SHIFT, CTRL, ALTGR, SHIFT-ALTGR */
202 };
203 
204 ROSDATA VK_TO_WCHARS2 key_to_chars_2mod[] =
205 {
206   /* The alphabet */
207   { 'A', CAPLOK, {'a', 'A'} },
208   { 'B', CAPLOK, {'b', 'B'} },
209   { 'C', CAPLOK, {'c', 'C'} },
210   { 'F', CAPLOK, {'f', 'F'} },
211   { 'G', CAPLOK, {'g', 'G'} },
212   { 'H', CAPLOK, {'h', 'H'} },
213   { 'I', CAPLOK, {'i', 'I'} },
214   { 'J', CAPLOK, {'j', 'J'} },
215   { 'K', CAPLOK, {'k', 'K'} },
216   { 'M', CAPLOK, {'m', 'M'} },
217   { 'N', CAPLOK, {'n', 'N'} },
218   { 'O', CAPLOK, {'o', 'O'} },
219   { 'R', CAPLOK, {'r', 'R'} },
220   { 'T', CAPLOK, {'t', 'T'} },
221   { 'U', CAPLOK, {'u', 'U'} },
222   { 'V', CAPLOK, {'v', 'V'} },
223   { 'W', CAPLOK, {'w', 'W'} },
224   { 'X', CAPLOK, {'x', 'X'} },
225   { 'Y', CAPLOK, {'y', 'Y'} },
226   { 'Z', CAPLOK, {'z', 'Z'} },
227 
228   /* Specials */
229   { VK_OEM_2, 0, {'/', '?'} },
230 
231   /* Keys that do not have shift states */
232   { VK_TAB,      0, {'\t','\t'} },
233   { VK_ADD,      0, {'+', '+'} },
234   { VK_SUBTRACT, 0, {'-', '-'} },
235   { VK_MULTIPLY, 0, {'*', '*'} },
236   { VK_DIVIDE,   0, {'/', '/'} },
237 
238   { 0, 0 }
239 };
240 
241 ROSDATA VK_TO_WCHARS3 key_to_chars_3mod[] =
242 {
243   /* Legacy (telnet-style) ascii escapes */
244   { VK_OEM_102, 0, {'\\','|', 0x1c /* FS */} },
245   { VK_BACK,    0, {0x8, 0x8, 0x7F } },
246   { VK_ESCAPE,  0, {0x1b,0x1b,0x1b } },
247   { VK_RETURN,  0, {'\r','\r','\n'} },
248   { VK_SPACE,   0, {' ', ' ', ' '} },
249   { VK_CANCEL,  0, {0x3, 0x3, 0x3} },
250   { 0, 0 }
251 };
252 
253 ROSDATA VK_TO_WCHARS4 key_to_chars_4mod[] =
254 {
255   { '1', 0, {'1', '!', WCH_NONE, 0x0303 /* COMBINING TILDE */} },
256   { '2', 0, {'2', '@', WCH_NONE, 0x030C /* COMBINING CARON */} },
257   { '3', 0, {'3', '#', WCH_NONE, 0x0302 /* COMBINING CIRCUMFLEX */} },
258   { '4', 0, {'4', '$', WCH_NONE, 0x0306 /* COMBINING BREVE */} },
259   { '5', 0, {'5', '%', WCH_NONE, 0x030A /* COMBINING RING ABOVE */} },
260   { '6', 0, {'6', '^', WCH_NONE, 0x0328 /* COMBINING OGONEK */} },
261   { '7', 0, {'7', '&', WCH_NONE, 0x0300 /* COMBINING GRAVE ACCENT */} },
262   { '8', 0, {'8', '*', WCH_NONE, 0x0307 /* COMBINING DOT ABOVE */} },
263   { '9', 0, {'9', '(', WCH_NONE, 0x0301 /* COMBINING ACUTE ACCENT */} },
264   { '0', 0, {'0', ')', WCH_NONE, 0x030B /* COMBINING DOUBLE ACUTE ACCENT */} },
265   { 'Q', CAPLOK, {'q', 'Q', WCH_NONE, 0x0326 /* COMBINING COMMA BELOW */} },
266   { 'E', CAPLOK, {'e', 'E', WCH_NONE, 0x20AC /* EURO SIGN */} },
267   { 'P', CAPLOK, {'p', 'P', WCH_NONE, 0x00A7 /* SECTION SIGN */} },
268   { 'S', CAPLOK, {'s', 'S', WCH_NONE, 0x00DF /* LATIN SMALL LETTER SHARP S */} },
269   { 0, 0 }
270 };
271 
272 ROSDATA VK_TO_WCHARS5 key_to_chars_5mod[] =
273 {
274   { VK_OEM_3, 0,  {0x201E /* DOUBLE QUOTE 99 LOW */, 0x201D /* DOUBLE QUOTE 99 HIGH */, WCH_NONE, '`', '~' } },
275   { VK_OEM_MINUS, 0, {'-', '_', WCH_NONE, 0x0308 /* COMBINING DIAERESIS */, 0x2013 /* EN DASH */} },
276   { VK_OEM_PLUS, 0, {'=', '+', WCH_NONE, 0x0327 /* COMBINING CEDILLA */, 0x00B1 /* PLUS-MINUS SIGN */} },
277   { VK_OEM_4, CAPLOK, {0x0103 /* a BREVE */, 0x0102 /* A BREVE */, 0x1b /* ESC */, '[', '{' } },
278   { VK_OEM_6, CAPLOK, {0x00ee /* i CIRCUMFLEX */, 0x00ce /* I CIRCUMFLEX */, 0x1d /* GS */, ']', '}' } },
279   { 'D', CAPLOK, {'d', 'D', WCH_NONE, 0x0111 /* d WITH STROKE */, 0x0110 /* D WITH STROKE */} },
280   { 'L', CAPLOK, {'l', 'L', WCH_NONE, 0x0142 /* l WITH STROKE */, 0x0141 /* L WITH STROKE */} },
281   { VK_OEM_1, CAPLOK, {0x0219 /* s COMMA */, 0x0218 /* S COMMA */, WCH_NONE, ';', ':' } },
282   { VK_OEM_7, CAPLOK, {0x021B /* t COMMA */, 0x021A /* T COMMA */, WCH_NONE, '\'', '"' } },
283   { VK_OEM_5, CAPLOK, {0x00e2 /* a CIRCUMFLEX */, 0x00c2 /* A CIRCUMFLEX */, 0x1c /* FS */, '\\', '|' } },
284   { VK_OEM_COMMA, 0, {',', ';', WCH_NONE, '<', 0x00AB /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ } },
285   { VK_OEM_PERIOD, 0, {'.', ':', WCH_NONE, '>', 0x00BB /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ } },
286   { 0, 0 }
287 };
288 
289 ROSDATA VK_TO_WCHARS1 keypad_numbers[] =
290 {
291   { VK_NUMPAD0,  0, {'0'} },
292   { VK_NUMPAD1,  0, {'1'} },
293   { VK_NUMPAD2,  0, {'2'} },
294   { VK_NUMPAD3,  0, {'3'} },
295   { VK_NUMPAD4,  0, {'4'} },
296   { VK_NUMPAD5,  0, {'5'} },
297   { VK_NUMPAD6,  0, {'6'} },
298   { VK_NUMPAD7,  0, {'7'} },
299   { VK_NUMPAD8,  0, {'8'} },
300   { VK_NUMPAD9,  0, {'9'} },
301   { VK_DECIMAL,  0, {','} },
302   { 0, 0 }
303 };
304 
305 #define vk_master(n, x) { (PVK_TO_WCHARS1)x, n, sizeof(x[0]) }
306 ROSDATA VK_TO_WCHAR_TABLE vk_to_wchar_master_table[] =
307 {
308   vk_master(2, key_to_chars_2mod),
309   vk_master(3, key_to_chars_3mod),
310   vk_master(4, key_to_chars_4mod),
311   vk_master(5, key_to_chars_5mod),
312   vk_master(1, keypad_numbers),
313   { 0, 0, 0 }
314 };
315 
316 ROSDATA VSC_LPWSTR key_names[] =
317 {
318   { 0x01, L"Esc" },
319   { 0x0e, L"Retro\u0219tergere" },
320   { 0x0f, L"Tabulator" },
321   { 0x1c, L"Intrare" },
322   { 0x1d, L"Control" },
323   { 0x2a, L"Schimb" },
324   { 0x35, L"/ (num.)" },
325   { 0x36, L"Schimb dreapta" },
326   { 0x37, L"* (num.)" },
327   { 0x38, L"Alt" },
328   { 0x39, L"Spa\u021Biu" },
329   { 0x3a, L"MAJUSCULE" },
330   { 0x3b, L"F1" },
331   { 0x3c, L"F2" },
332   { 0x3d, L"F3" },
333   { 0x3e, L"F4" },
334   { 0x3f, L"F5" },
335   { 0x40, L"F6" },
336   { 0x41, L"F7" },
337   { 0x42, L"F8" },
338   { 0x43, L"F9" },
339   { 0x44, L"F10" },
340   { 0x45, L"Pauz\u0103" },
341   { 0x46, L"Fix. derulare" },
342   { 0x47, L"7 (num.)" },
343   { 0x48, L"8 (num.)" },
344   { 0x49, L"9 (num.)" },
345   { 0x4a, L"- (num.)" },
346   { 0x4b, L"4 (num.)" },
347   { 0x4c, L"5 (num.)" },
348   { 0x4d, L"6 (num.)" },
349   { 0x4e, L"+ (num.)" },
350   { 0x4f, L"1 (num.)" },
351   { 0x50, L"2 (num.)" },
352   { 0x51, L"3 (num.)" },
353   { 0x52, L"0 (num.)" },
354   { 0x53, L"Sep. zecimal" },
355   { 0x54, L"Sys Req" },
356   { 0x56, L"\\" },
357   { 0x57, L"F11" },
358   { 0x58, L"F12" },
359   { 0x7c, L"F13" },
360   { 0x7d, L"F14" },
361   { 0x7e, L"F15" },
362   { 0x7f, L"F16" },
363   { 0x80, L"F17" },
364   { 0x81, L"F18" },
365   { 0x82, L"F19" },
366   { 0x83, L"F20" },
367   { 0x84, L"F21" },
368   { 0x85, L"F22" },
369   { 0x86, L"F23" },
370   { 0x87, L"F24" },
371   { 0, NULL }
372 };
373 
374 ROSDATA VSC_LPWSTR extended_key_names[] =
375 {
376   { 0x1c, L"Intr. numerice" },
377   { 0x1d, L"Control dreapta" },
378   { 0x37, L"Imprimare" },
379   { 0x38, L"Alt dreapta" },
380   { 0x45, L"Fix. numerice" },
381   { 0x46, L"\u00CEntrerupere" },
382   { 0x47, L"Acas\u0103" },
383   { 0x48, L"Sus" },
384   { 0x49, L"Pag. sus" },
385   { 0x4b, L"St\u00E2nga" },
386   { 0x4c, L"Centru" },
387   { 0x4d, L"Dreapta" },
388   { 0x4f, L"Sf\u00E2r\u0219it" },
389   { 0x50, L"Jos" },
390   { 0x51, L"Pag. jos" },
391   { 0x52, L"Inser\u021Bie" },
392   { 0x53, L"\u0218tergere" },
393   { 0x54, L"Meniu" },
394   { 0x56, L"Ajutor" },
395   { 0x5b, L"Meniu st\u00E2nga" },
396   { 0x5c, L"Meniu dreapta" },
397   { 0, NULL }
398 };
399 
400 ROSDATA DEADKEY_LPWSTR dead_key_names[] =
401 {
402     L"\x0300"   L"Accent grav",
403     L"\x0301"   L"Accent acut",
404     L"\x0302"   L"Circumflex",
405     L"\x0303"   L"Tild\u0103",
406     L"\x0306"   L"Breve",
407     L"\x0307"   L"Suprapunct",
408     L"\x0308"   L"Trem\u0103",
409     L"\x030A"   L"Supracerc",
410     L"\x030B"   L"Accent acut dublu",
411     L"\x030C"   L"Caron",
412     L"\x0326"   L"Virgul\u0103",
413     L"\x0327"   L"Sedil\u0103",
414     L"\x0328"   L"Ogonek",
415     NULL
416 };
417 
418 #define DEADTRANS(ch, accent, comp, flags) MAKELONG(ch, accent), comp, flags
419 ROSDATA DEADKEY dead_key[] =
420 {
421   /*
422    * combining diacritics: tilde, caron, circumflex,
423    * breve, ring above, ogonek, grave accent, dot above,
424    * acute accent, double acute accent, and comma below
425    */
426   #include "deadkeys/tilde"
427   #include "deadkeys/caron"
428   #include "deadkeys/circumflex"
429   #include "deadkeys/breve"
430   #include "deadkeys/ring_above"
431   #include "deadkeys/ogonek"
432   #include "deadkeys/grave_acc"
433   #include "deadkeys/dot_above"
434   #include "deadkeys/acute_acc"
435   #include "deadkeys/dbl_acute_acc"
436   #include "deadkeys/comma_below"
437 
438   { 0, 0 }
439 };
440 
441 /* Finally, the master table */
442 ROSDATA KBDTABLES keyboard_layout_table =
443 {
444   /* modifier assignments */
445   &modifier_bits,
446 
447   /* character from vk tables */
448   vk_to_wchar_master_table,
449 
450   /* diacritical marks */
451   dead_key,
452 
453   /* Key names */
454   key_names,
455   extended_key_names,
456   dead_key_names,
457 
458   /* scan code to virtual key maps */
459   scancode_to_vk,
460   RTL_NUMBER_OF(scancode_to_vk),
461   extcode0_to_vk,
462   extcode1_to_vk,
463 
464   MAKELONG(KLLF_ALTGR, 1), /* Version 1.0 */
465 
466   /* Ligatures (Romanian doesn't have any) */
467   0,
468   0,
469   NULL
470 };
471 
472 PKBDTABLES WINAPI KbdLayerDescriptor(VOID)
473 {
474   return &keyboard_layout_table;
475 }
476