FreeRDP
Loading...
Searching...
No Matches
TestScancode.c
1#include <winpr/input.h>
2
3static bool testKeyboardType(enum WINPR_KBD_TYPE type, DWORD flag)
4{
5 for (DWORD x = 0; x < 0x100; x++)
6 {
7 const DWORD vk = GetVirtualKeyCodeFromVirtualScanCode(x | flag, type);
8
9 /* > 127 is out of range */
10 if (x > 127)
11 {
12 if (vk != VK_NONE)
13 return false;
14 }
15
16 const DWORD sc = GetVirtualScanCodeFromVirtualKeyCode(vk | flag, type);
17 if (sc != x)
18 {
19 if ((sc != 0) && (vk != VK_NONE))
20 {
21 DWORD buffer[256] = WINPR_C_ARRAY_INIT;
22 const DWORD count = GetVirtualScanCodesFromVirtualKeyCode(vk | flag, type, buffer,
23 ARRAYSIZE(buffer));
24
25 bool isOK = false;
26 for (DWORD i = 0; i < count; i++)
27 {
28 const DWORD cur = buffer[i];
29 if (cur == sc)
30 {
31 isOK = true;
32 break;
33 }
34 }
35 if (!isOK)
36 {
37 printf("[%" PRIu32 "]: got %" PRIu32 ", expected %" PRIu32, type, sc, x);
38 return false;
39 }
40 }
41 else if ((sc == 0) && (vk == VK_NONE))
42 {
43 }
44 else
45 {
46 printf("[%" PRIu32 "]: got %" PRIu32 ", expected %" PRIu32, type, sc, x);
47 return false;
48 }
49 }
50 }
51 return true;
52}
53
54static bool testKeyboardTypes(enum WINPR_KBD_TYPE type)
55{
56 if (!testKeyboardType(type, 0))
57 return false;
58 if (!testKeyboardType(type, KBDMULTIVK))
59 return false;
60 return testKeyboardType(type, KBDEXT);
61}
62
63/* the modifier keys of a Mac keyboard, both ways (right Control was listed as the right
64 * Windows key, so a Windows right Control found no Mac key at all) */
65static bool testAppleModifiers(void)
66{
67 const struct
68 {
69 DWORD keycode;
70 DWORD vkcode;
71 } modifiers[] = { { 0x36, VK_RWIN | KBDEXT }, { 0x37, VK_LWIN | KBDEXT },
72 { 0x38, VK_LSHIFT }, { 0x3A, VK_LMENU },
73 { 0x3B, VK_LCONTROL }, { 0x3C, VK_RSHIFT },
74 { 0x3D, VK_RMENU | KBDEXT }, { 0x3E, VK_RCONTROL | KBDEXT } };
75
76 for (size_t x = 0; x < ARRAYSIZE(modifiers); x++)
77 {
78 const DWORD keycode = modifiers[x].keycode;
79 const DWORD vkcode = modifiers[x].vkcode;
80 const DWORD vk = GetVirtualKeyCodeFromKeycode(keycode, WINPR_KEYCODE_TYPE_APPLE);
81 const DWORD kc = GetKeycodeFromVirtualKeyCode(vkcode, WINPR_KEYCODE_TYPE_APPLE);
82 if ((vk != vkcode) || (kc != keycode))
83 {
84 printf("Apple keycode 0x%02" PRIx32 ": got VK 0x%04" PRIx32 " and keycode 0x%02" PRIx32
85 ", expected VK 0x%04" PRIx32 "\n",
86 keycode, vk, kc, vkcode);
87 return false;
88 }
89 }
90 return true;
91}
92
93static bool testVKToKeycode(WINPR_KEYCODE_TYPE type)
94{
95
96 for (DWORD x = 0; x <= 0x100; x++)
97 {
98 const DWORD vkc = GetVirtualKeyCodeFromKeycode(x, type);
99 const DWORD kc = GetKeycodeFromVirtualKeyCode(vkc, type);
100 if (x != kc)
101 {
102 if (!((kc == 0) && (vkc == VK_NONE)))
103 {
104 DWORD keycodes[0x100] = WINPR_C_ARRAY_INIT;
105 const DWORD count =
106 GetKeycodesFromVirtualKeyCode(vkc, type, keycodes, ARRAYSIZE(keycodes));
107 bool rc = false;
108 for (DWORD y = 0; y < count; y++)
109 {
110 if (keycodes[y] == x)
111 rc = true;
112 }
113 if (!rc)
114 return false;
115 }
116 }
117 }
118 return true;
119}
120
121static bool testVKToKeycodes(void)
122{
123 const WINPR_KEYCODE_TYPE types[] = { WINPR_KEYCODE_TYPE_NONE, WINPR_KEYCODE_TYPE_APPLE,
124 WINPR_KEYCODE_TYPE_EVDEV, WINPR_KEYCODE_TYPE_XKB };
125
126 for (size_t x = 0; x < ARRAYSIZE(types); x++)
127 {
128 const WINPR_KEYCODE_TYPE type = types[x];
129 if (!testVKToKeycode(type))
130 return false;
131 }
132 return true;
133}
134
135int TestScancode(WINPR_ATTR_UNUSED int argc, WINPR_ATTR_UNUSED char* argv[])
136{
137 if (!testVKToKeycodes())
138 return -23;
139
140 if (!testAppleModifiers())
141 return -24;
142
143 const enum WINPR_KBD_TYPE types[] = { WINPR_KBD_TYPE_IBM_PC_XT, WINPR_KBD_TYPE_OLIVETTI_ICO,
144 WINPR_KBD_TYPE_IBM_PC_AT, WINPR_KBD_TYPE_IBM_ENHANCED,
145 WINPR_KBD_TYPE_NOKIA_1050, WINPR_KBD_TYPE_NOKIA_9140,
146 WINPR_KBD_TYPE_JAPANESE, WINPR_KBD_TYPE_KOREAN };
147
148 int rc = 0;
149 for (size_t x = 0; x < ARRAYSIZE(types); x++)
150 {
151 const enum WINPR_KBD_TYPE type = types[x];
152 if (!testKeyboardTypes(type))
153 rc--;
154 }
155 return rc;
156}