2 * ReactOS Spanish Keyboard Layout
3 * Copyright (C) 2003-2014 ReactOS
4 * License: LGPL, see: LGPL.txt
6 * (c) 2003 - Created by HUMA2000 <huma2000@terra.es> from kbdus, kbdgr, kbdda and kbdfr.
7 * (c) 2014 - Updated by Swyter <swyterzone+ros@gmail.com>
9 * Thanks to: arty, for the kbtest utility and help.
10 * Thanks to: carraca, from reactos.com forum for his fixes.
11 * Thanks to: Elrond, for help.
13 * Thanks to: http://www.barcodeman.com/altek/mule/scandoc.php
14 * and http://win.tue.nl/~aeb/linux/kbd/scancodes-1.html
17 #define WIN32_NO_STATUS
24 #define ROSDATA static __declspec(allocate(".data"))
27 #pragma data_seg(".data")
28 #define ROSDATA static
30 #define ROSDATA static __attribute__((section(".data")))
34 #define VK_EMPTY 0xff /* The non-existent VK */
36 #define KNUMS KBDNUMPAD|KBDSPECIAL /* Special + number pad */
37 #define KMEXT KBDEXT|KBDMULTIVK /* Multi + ext */
39 ROSDATA USHORT scancode_to_vk
[] =
92 /* 33 */ VK_OEM_COMMA
,
93 /* 34 */ VK_OEM_PERIOD
,
94 /* 35 */ VK_OEM_MINUS
,
110 /* 45 */ VK_NUMLOCK
| KMEXT
,
111 /* 46 */ VK_SCROLL
| KBDMULTIVK
,
112 /* 47 */ VK_HOME
| KNUMS
,
113 /* 48 */ VK_UP
| KNUMS
,
114 /* 49 */ VK_PRIOR
| KNUMS
,
115 /* 4a */ VK_SUBTRACT
,
116 /* 4b */ VK_LEFT
| KNUMS
,
117 /* 4c */ VK_CLEAR
| KNUMS
,
118 /* 4d */ VK_RIGHT
| KNUMS
,
120 /* 4f */ VK_END
| KNUMS
,
121 /* 50 */ VK_DOWN
| KNUMS
,
122 /* 51 */ VK_NEXT
| KNUMS
,
123 /* 52 */ VK_INSERT
| KNUMS
,
124 /* 53 */ VK_DELETE
| KNUMS
,
125 /* 54 */ VK_SNAPSHOT
,
135 /* 5e */ VK_EMPTY
, /* EREOF */
140 /* 63 */ VK_EMPTY
, /* ZOOM */
173 ROSDATA VSC_VK extcode0_to_vk
[] =
175 { 0x10, KBDEXT
| VK_MEDIA_PREV_TRACK
}, // Pista anterior, no puedo probarlo hasta que no se implemente el sonido
176 { 0x19, KBDEXT
| VK_MEDIA_NEXT_TRACK
}, // Pista siguiente,
177 { 0x1D, KBDEXT
| VK_RCONTROL
}, // Tecla control
178 { 0x20, KBDEXT
| VK_VOLUME_MUTE
}, // Silenciar volumen
179 { 0x21, KBDEXT
| VK_LAUNCH_APP2
}, // Tecla calculadora
180 { 0x22, KBDEXT
| VK_MEDIA_PLAY_PAUSE
}, // Reproducir/Pausa
181 { 0x24, KBDEXT
| VK_MEDIA_STOP
}, // Stop
182 { 0x2E, KBDEXT
| VK_VOLUME_DOWN
}, // Bajar volumen
183 { 0x30, KBDEXT
| VK_VOLUME_UP
}, // Subir volumen
184 { 0x32, KBDEXT
| VK_BROWSER_HOME
}, // Pagina de inicio del navegador de Internet o abrirlo si no esta activo
185 { 0x35, KBDEXT
| VK_DIVIDE
}, // Tecla
186 { 0x37, KBDEXT
| VK_SNAPSHOT
}, // La tecla de imprimir pantalla
187 { 0x38, KBDEXT
| VK_RMENU
}, // Tecla Alt
188 { 0x47, KBDEXT
| VK_HOME
}, // Tecla inicio
189 { 0x48, KBDEXT
| VK_UP
}, // Cursor arriba
190 { 0x49, KBDEXT
| VK_PRIOR
}, // Tecla Repág
191 { 0x4B, KBDEXT
| VK_LEFT
}, // Cursor izquierda
192 { 0x4D, KBDEXT
| VK_RIGHT
}, // Cursor derecha
193 { 0x4F, KBDEXT
| VK_END
}, // Tecla Fin
194 { 0x50, KBDEXT
| VK_DOWN
}, // Cursor abajo
195 { 0x51, KBDEXT
| VK_NEXT
}, // Tecla Avpág
196 { 0x52, KBDEXT
| VK_INSERT
}, // Tecla Ins
197 { 0x53, KBDEXT
| VK_DELETE
}, // Tecla Supr
198 { 0x5B, KBDEXT
| VK_LWIN
}, // Tecla Windows izquierda
199 { 0x5C, KBDEXT
| VK_RWIN
}, // Tecla Windows derecha
200 { 0x5D, KBDEXT
| VK_APPS
}, // Tecla menú aplicacion derecha
201 { 0x5F, KBDEXT
| VK_SLEEP
}, // Tecla Suspensión
202 { 0x65, KBDEXT
| VK_BROWSER_SEARCH
}, // Pagina de búsqueda en el navegador de Internet
203 { 0x66, KBDEXT
| VK_BROWSER_FAVORITES
}, // Favoritos, tengo que esperar a que el tcp/ip
204 { 0x67, KBDEXT
| VK_BROWSER_REFRESH
}, // Refrescar el navegador de Internet
205 { 0x68, KBDEXT
| VK_BROWSER_STOP
}, // Stop en el navegador de Internet
206 { 0x69, KBDEXT
| VK_BROWSER_FORWARD
}, // Adelante en el navegador de Internet
207 { 0x6A, KBDEXT
| VK_BROWSER_BACK
}, // Atrás en el navegador de Internet
208 { 0x6B, KBDEXT
| VK_LAUNCH_APP1
}, // Tecla Mi PC
209 { 0x6C, KBDEXT
| VK_LAUNCH_MAIL
}, // Abrir programa de e-mail
210 { 0x6D, KBDEXT
| VK_LAUNCH_MEDIA_SELECT
}, // Abrir reproductor multimedia
211 { 0x1C, KBDEXT
| VK_RETURN
}, // La tecla de intro
212 { 0x46, KBDEXT
| VK_CANCEL
}, // Tecla escape
216 ROSDATA VSC_VK extcode1_to_vk
[] =
221 ROSDATA VK_TO_BIT modifier_keys
[] =
223 { VK_SHIFT
, KBDSHIFT
},
224 { VK_CONTROL
, KBDCTRL
},
229 ROSDATA MODIFIERS modifier_bits
=
237 2|1, /* CTRL+MAYÚS */
244 ROSDATA VK_TO_WCHARS2 key_to_chars_2mod
[] =
247 /* The numbers -- Del 1 al 6 tienen tres estados */
248 { L
'7', 0, {L
'7', L
'/'} },
249 { L
'8', 0, {L
'8', L
'('} },
250 { L
'9', 0, {L
'9', L
')'} },
251 { L
'0', 0, {L
'0', L
'='} },
252 { VK_OEM_3
, CAPLOK
, {L
'ñ', L
'Ñ'} }, /* ñÑ */
255 /* Ctrl-_ generates ES */
256 { VK_OEM_6
, 0, {L
'¡', L
'¿'} }, /* ¡¿ */
257 { VK_OEM_4
, 0, {0x27, L
'?'} }, /* '? */
258 { VK_OEM_COMMA
, 0, {L
',', L
';'} },
259 { VK_OEM_PERIOD
, 0, {L
'.', L
':'} },
260 { VK_OEM_MINUS
, 0, {L
'-', L
'_'} },
261 { VK_OEM_102
, 0, {L
'<', L
'>'} },
263 /* Keys that do not have shift states */
264 { VK_TAB
, 0, {L
'\t', L
'\t'} },
265 { VK_ADD
, 0, {L
'+', L
'+'} },
266 { VK_SUBTRACT
, 0, {L
'-', L
'-'} },
267 { VK_MULTIPLY
, 0, {L
'*', L
'*'} },
268 { VK_DIVIDE
, 0, {L
'/', L
'/'} },
269 { VK_ESCAPE
, 0, {0x1b, 0x1b} },
270 { VK_SPACE
, 0, {L
' ', L
' '} },
274 ROSDATA VK_TO_WCHARS3 key_to_chars_3mod
[] =
276 /* Normal, Mayús, Ctrl */
278 { L
'A', CAPLOK
, {L
'a', L
'A', 0x01} },
279 { L
'B', CAPLOK
, {L
'b', L
'B', 0x02} },
280 { L
'C', CAPLOK
, {L
'c', L
'C', 0x03} },
281 { L
'D', CAPLOK
, {L
'd', L
'D', 0x04} },
282 { L
'F', CAPLOK
, {L
'f', L
'F', 0x06} },
283 { L
'G', CAPLOK
, {L
'g', L
'G', 0x07} },
284 { L
'H', CAPLOK
, {L
'h', L
'H', 0x08} },
285 { L
'I', CAPLOK
, {L
'i', L
'I', 0x09} },
286 { L
'J', CAPLOK
, {L
'j', L
'J', 0x0a} },
287 { L
'K', CAPLOK
, {L
'k', L
'K', 0x0b} },
288 { L
'L', CAPLOK
, {L
'l', L
'L', 0x0c} },
289 { L
'M', CAPLOK
, {L
'm', L
'M', 0x0d} },
290 { L
'N', CAPLOK
, {L
'n', L
'N', 0x0e} },
291 { L
'O', CAPLOK
, {L
'o', L
'O', 0x0f} },
292 { L
'P', CAPLOK
, {L
'p', L
'P', 0x10} },
293 { L
'Q', CAPLOK
, {L
'q', L
'Q', 0x11} },
294 { L
'R', CAPLOK
, {L
'r', L
'R', 0x12} },
295 { L
'S', CAPLOK
, {L
's', L
'S', 0x13} },
296 { L
'T', CAPLOK
, {L
't', L
'T', 0x14} },
297 { L
'U', CAPLOK
, {L
'u', L
'U', 0x15} },
298 { L
'V', CAPLOK
, {L
'v', L
'V', 0x16} },
299 { L
'W', CAPLOK
, {L
'w', L
'W', 0x17} },
300 { L
'X', CAPLOK
, {L
'x', L
'X', 0x18} },
301 { L
'Y', CAPLOK
, {L
'y', L
'Y', 0x19} },
302 { L
'Z', CAPLOK
, {L
'z', L
'Z', 0x1a} },
304 /* Legacy (telnet-style) ascii escapes */
305 { VK_RETURN
, 0, {L
'\r',L
'\r',L
'\n'} },
309 ROSDATA VK_TO_WCHARS4 key_to_chars_4mod
[] =
311 /* Normal, Mayús, Ctrl, Alt+Gr */
312 { L
'1', 0, {L
'1', L
'!', WCH_NONE
, L
'|'} }, /* 1!| */
313 { L
'2', 0, {L
'2', L
'"', WCH_NONE
, L
'@'} }, /* 2"@ */
314 { L
'3', 0, {L
'3', L
'·', WCH_NONE
, L
'#'} }, /* 3·# */
315 { L
'4', 0, {L
'4', L
'$', WCH_NONE
, WCH_DEAD
} }, /* 4$~ */
316 { VK_EMPTY
, 0, {WCH_NONE
, WCH_NONE
, WCH_NONE
, L
'~'} }, /* 4$~ */
317 { L
'5', 0, {L
'5', L
'%', WCH_NONE
, L
'€'} }, /* 5%€ */
318 { L
'6', 0, {L
'6', L
'&', WCH_NONE
, L
'¬'} }, /* 6&¬ */
319 { L
'E', CAPLOK
, {L
'e', L
'E', 0x05, L
'€'} }, /* eE€ */
320 { VK_OEM_PLUS
, 0, {L
'+', L
'*', WCH_NONE
, L
']'} }, /* +*] */
321 { VK_OEM_2
, 0, {L
'ç', L
'Ç', WCH_NONE
, L
'}'} }, /* çÇ} */
323 { VK_OEM_7
, 0, {WCH_DEAD
, WCH_DEAD
, WCH_NONE
, L
'{'} }, /* ´¨{ */
324 { VK_EMPTY
, 0, {L
'´', L
'¨', WCH_NONE
, WCH_NONE
} }, /* ´¨{ */
326 { VK_OEM_1
, 0, {WCH_DEAD
, WCH_DEAD
, WCH_NONE
, L
'['} }, /* `^[ */
327 { VK_EMPTY
, 0, {L
'`', L
'^', WCH_NONE
, WCH_NONE
} }, /* `^[ */
329 { VK_OEM_5
, 0, {L
'º', L
'ª', WCH_NONE
, 0x5c} }, /* ºª\ */
333 ROSDATA VK_TO_WCHARS1 keypad_numbers
[] =
335 { VK_NUMPAD0
, 0, {L
'0'} },
336 { VK_NUMPAD1
, 0, {L
'1'} },
337 { VK_NUMPAD2
, 0, {L
'2'} },
338 { VK_NUMPAD3
, 0, {L
'3'} },
339 { VK_NUMPAD4
, 0, {L
'4'} },
340 { VK_NUMPAD5
, 0, {L
'5'} },
341 { VK_NUMPAD6
, 0, {L
'6'} },
342 { VK_NUMPAD7
, 0, {L
'7'} },
343 { VK_NUMPAD8
, 0, {L
'8'} },
344 { VK_NUMPAD9
, 0, {L
'9'} },
345 { VK_DECIMAL
, 0, {L
'.'} },
346 { VK_BACK
, 0, {L
'\010'} },
350 #define vk_master(n,x) { (PVK_TO_WCHARS1)x, n, sizeof(x[0]) }
352 ROSDATA VK_TO_WCHAR_TABLE vk_to_wchar_master_table
[] =
354 vk_master(1, keypad_numbers
),
355 vk_master(2, key_to_chars_2mod
),
356 vk_master(3, key_to_chars_3mod
),
357 vk_master(4, key_to_chars_4mod
),
361 #define DEADTRANS(ch, accent, comp, flags) MAKELONG(ch, accent), comp, flags //no funciona
362 ROSDATA DEADKEY deadkey
[] =
365 { DEADTRANS(L
'a', L
'´', 0xE1, 0x00) }, // letra a con ´ | á
366 { DEADTRANS(L
'A', L
'´', 0xC1, 0x00) }, // letra A con ´ | Á
367 { DEADTRANS(L
'e', L
'´', 0xE9, 0x00) }, // letra e con ´ | é
368 { DEADTRANS(L
'E', L
'´', 0xC9, 0x00) }, // letra E con ´ | É
369 { DEADTRANS(L
'i', L
'´', 0xED, 0x00) }, // letra i con ´ | í
370 { DEADTRANS(L
'I', L
'´', 0xCD, 0x00) }, // letra I con ´ | Í
371 { DEADTRANS(L
'o', L
'´', 0xF3, 0x00) }, // letra o con ´ | ó
372 { DEADTRANS(L
'O', L
'´', 0xD3, 0x00) }, // letra O con ´ | Ó
373 { DEADTRANS(L
'u', L
'´', 0xFA, 0x00) }, // letra u con ´ | ú
374 { DEADTRANS(L
'U', L
'´', 0xDA, 0x00) }, // letra U con ´ | Ú
377 { DEADTRANS(L
'a', L
'`', 0xE0, 0x00) }, // letra a con ` | à
378 { DEADTRANS(L
'A', L
'`', 0xC0, 0x00) }, // letra A con ` | À
379 { DEADTRANS(L
'e', L
'`', 0xE8, 0x00) }, // letra e con ` | è
380 { DEADTRANS(L
'E', L
'`', 0xC8, 0x00) }, // letra E con ` | È
381 { DEADTRANS(L
'i', L
'`', 0xEC, 0x00) }, // letra i con ` | ì
382 { DEADTRANS(L
'I', L
'`', 0xCC, 0x00) }, // letra I con ` | Ì
383 { DEADTRANS(L
'o', L
'`', 0xF2, 0x00) }, // letra o con ` | ò
384 { DEADTRANS(L
'O', L
'`', 0xD2, 0x00) }, // letra O con ` | Ò
385 { DEADTRANS(L
'u', L
'`', 0xF9, 0x00) }, // letra u con ` | ù
386 { DEADTRANS(L
'U', L
'`', 0xD9, 0x00) }, // letra U con ` | Ù
389 { DEADTRANS(L
'a', L
'^', 0xE2, 0x00) }, // letra a con ^ | â
390 { DEADTRANS(L
'A', L
'^', 0xC2, 0x00) }, // letra A con ^ | Â
391 { DEADTRANS(L
'e', L
'^', 0xEA, 0x00) }, // letra e con ^ | ê
392 { DEADTRANS(L
'E', L
'^', 0xCA, 0x00) }, // letra E con ^ | Ê
393 { DEADTRANS(L
'i', L
'^', 0xEE, 0x00) }, // letra i con ^ | î
394 { DEADTRANS(L
'I', L
'^', 0xCE, 0x00) }, // letra I con ^ | Î
395 { DEADTRANS(L
'o', L
'^', 0xF4, 0x00) }, // letra o con ^ | ô
396 { DEADTRANS(L
'O', L
'^', 0xD4, 0x00) }, // letra O con ^ | Ô
397 { DEADTRANS(L
'u', L
'^', 0xFB, 0x00) }, // letra u con ^ | û
398 { DEADTRANS(L
'U', L
'^', 0xDB, 0x00) }, // letra U con ^ | Û
401 { DEADTRANS(L
'a', L
'¨', 0xE4, 0x00) }, // letra a con ¨ | ä
402 { DEADTRANS(L
'A', L
'¨', 0xC4, 0x00) }, // letra A con ¨ | Ä
403 { DEADTRANS(L
'e', L
'¨', 0xEB, 0x00) }, // letra e con ¨ | ë
404 { DEADTRANS(L
'E', L
'¨', 0xCB, 0x00) }, // letra E con ¨ | Ë
405 { DEADTRANS(L
'i', L
'¨', 0xEF, 0x00) }, // letra i con ¨ | ï
406 { DEADTRANS(L
'I', L
'¨', 0xCF, 0x00) }, // letra I con ¨ | Ï
407 { DEADTRANS(L
'o', L
'¨', 0xF6, 0x00) }, // letra o con ¨ | ö
408 { DEADTRANS(L
'O', L
'¨', 0xD6, 0x00) }, // letra O con ¨ | Ö
409 { DEADTRANS(L
'u', L
'¨', 0xFC, 0x00) }, // letra u con ¨ | ü
410 { DEADTRANS(L
'U', L
'¨', 0xDC, 0x00) }, // letra U con ¨ | Ü
413 { DEADTRANS(L
'a', L
'~', 0xe3, 0x00) }, // letra a con ~ | ã
414 { DEADTRANS(L
'A', L
'~', 0xc3, 0x00) }, // letra A con ~ | Ã
415 { DEADTRANS(L
'n', L
'~', 0xf1, 0x00) }, // letra n con ~ | ñ
416 { DEADTRANS(L
'N', L
'~', 0xd1, 0x00) }, // letra N con ~ | Ñ
417 { DEADTRANS(L
'o', L
'~', 0xf5, 0x00) }, // letra o con ~ | õ
418 { DEADTRANS(L
'O', L
'~', 0xd5, 0x00) }, // letra O con ~ | Õ
423 ROSDATA VSC_LPWSTR key_names
[] =
427 { 0x0e, L
"Retroceso" },
432 { 0x36, L
"Mayús der." },
435 { 0x39, L
"Espacio" },
436 { 0x3a, L
"Bloq mayús" },
448 { 0x46, L
"Bloqueo despl." },
461 { 0x53, L
"Supr numér." },
462 { 0x54, L
"Pet sist" },
480 ROSDATA VSC_LPWSTR extended_key_names
[] =
482 { 0x1c, L
"Intro num" },
483 { 0x1d, L
"Ctrl der." },
485 { 0x37, L
"Impr pant." },
486 { 0x38, L
"Alt der." },
487 { 0x45, L
"Bloq num" },
492 { 0x4b, L
"Izquierda" },
493 { 0x4c, L
"Centrar" },
494 { 0x4d, L
"Derecha" },
500 { 0x54, L
"<ReactOS>" },
502 { 0x5b, L
"Windows izq." },
503 { 0x5c, L
"Windows der." },
507 ROSDATA DEADKEY_LPWSTR dead_key_names
[] =
511 L
"\x005e" L
"Circunflejo",
512 L
"\x00A8" L
"Diéresis",
516 /* Finally, the master table */
517 ROSDATA KBDTABLES keyboard_layout_table
=
519 /* modifier assignments */
522 /* character from vk tables */
523 vk_to_wchar_master_table
,
525 /* diacritical marks -- currently implemented by wine code, spanish has several */
529 (VSC_LPWSTR
*)key_names
,
530 (VSC_LPWSTR
*)extended_key_names
,
535 /* scan code to virtual key maps */
537 sizeof(scancode_to_vk
) / sizeof(scancode_to_vk
[0]),
542 MAKELONG(KLLF_ALTGR
, 1),
544 /* ligatures -- Spanish does not have any */
550 PKBDTABLES WINAPI
KbdLayerDescriptor(VOID
)
552 return &keyboard_layout_table
;