source: trunk/synergy/birdhacks/dumpchars.c

Last change on this file was 2769, checked in by bird, 19 years ago

messing about.

File size: 16.0 KB
Line 
1/* $Id: $ */
2/** @file
3 *
4 * dumpchar - dump scancodes, virtual keys, and character conversions.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird@anduin.net>
7 *
8 * GPL
9 *
10 */
11
12/*******************************************************************************
13* Header Files *
14*******************************************************************************/
15#define INCL_PM
16#define INCL_ERRORS
17#define INCL_DOS
18#include <os2.h>
19#include <stdio.h>
20#include <string.h>
21#include <ctype.h>
22
23
24/** The WinTranlateChar2 operation. */
25typedef enum WINTCOP
26{
27 TC_CHARTOSCANCODE = 0,
28 TC_SCANCODETOCHAR,
29 TC_VIRTUALKEYTOSCANCODE,
30 TC_SCANCODETOVIRTUALKEY,
31 TC_SCANTOOEMSCAN,
32 TC_OEMSCANTOSCAN,
33 TC_SIZE_HACK = 0x7fff
34} WINTCOP;
35
36/** @name WinTranslateChar2 shift state.
37 * This state goes with scancode input/output.
38 * @{ */
39#define TCF_LSHIFT 0x1
40#define TCF_RSHIFT 0x2
41#define TCF_SHIFT (TCF_LSHIFT | TCF_RSHIFT)
42#define TCF_LCONTROL 0x4
43#define TCF_RCONTROL 0x8
44#define TCF_CONTROL (TCF_LCONTROL | TCF_RCONTROL)
45#define TCF_ALT 0x10
46#define TCF_ALTGR 0x20
47#define TCF_CAPSLOCK 0x40
48#define TCF_NUMLOCK 0x80
49#define TCF_MAX_BITS 8 /**< bits 0-7 are real shift states */
50#define TCF_OEMSCANCODE 0x100
51#define TCF_EXTENDEDKEY 0x200
52/** @} */
53
54/**
55 * Char to/from keyboard code translator.
56 *
57 * @returns A combination of some of the KC_* values.
58 * @param usCodePage The code page. Anything goes, apparently ignored.
59 * @param pusCharInOut Where to get the char/code to be translated and to
60 * put the output upon return.
61 * @param pulDeadKeyInfo Previous, dead key.
62 * @param enmOperation The kind of translation.
63 * @param pfShiftState Where to read/store the shift state. Used when
64 * translating from/to scancodes.
65 */
66USHORT APIENTRY WinTranslateChar2(USHORT usCodePage,
67 PUSHORT pusCharInOut,
68 PULONG pulDeadKeyInfo,
69 WINTCOP enmOperation,
70 PUSHORT pfShiftState);
71
72
73/**
74 * Get the name of a virtual key.
75 * @returns the key name (readonly).
76 * @param ulVirtualKey The virtual key.
77 */
78const char *GetVirtualKeyName(ULONG ulVirtualKey)
79{
80 switch (ulVirtualKey) {
81#define CASE(vk) case vk: return #vk
82 CASE(VK_BUTTON1);
83 CASE(VK_BUTTON2);
84 CASE(VK_BUTTON3);
85 CASE(VK_BREAK);
86 CASE(VK_BACKSPACE);
87 CASE(VK_TAB);
88 CASE(VK_BACKTAB);
89 CASE(VK_NEWLINE);
90 CASE(VK_SHIFT);
91 CASE(VK_CTRL);
92 CASE(VK_ALT);
93 CASE(VK_ALTGRAF);
94 CASE(VK_PAUSE);
95 CASE(VK_CAPSLOCK);
96 CASE(VK_ESC);
97 CASE(VK_SPACE);
98 CASE(VK_PAGEUP);
99 CASE(VK_PAGEDOWN);
100 CASE(VK_END);
101 CASE(VK_HOME);
102 CASE(VK_LEFT);
103 CASE(VK_UP);
104 CASE(VK_RIGHT);
105 CASE(VK_DOWN);
106 CASE(VK_PRINTSCRN);
107 CASE(VK_INSERT);
108 CASE(VK_DELETE);
109 CASE(VK_SCRLLOCK);
110 CASE(VK_NUMLOCK);
111 CASE(VK_ENTER);
112 CASE(VK_SYSRQ);
113 CASE(VK_F1);
114 CASE(VK_F2);
115 CASE(VK_F3);
116 CASE(VK_F4);
117 CASE(VK_F5);
118 CASE(VK_F6);
119 CASE(VK_F7);
120 CASE(VK_F8);
121 CASE(VK_F9);
122 CASE(VK_F10);
123 CASE(VK_F11);
124 CASE(VK_F12);
125 CASE(VK_F13);
126 CASE(VK_F14);
127 CASE(VK_F15);
128 CASE(VK_F16);
129 CASE(VK_F17);
130 CASE(VK_F18);
131 CASE(VK_F19);
132 CASE(VK_F20);
133 CASE(VK_F21);
134 CASE(VK_F22);
135 CASE(VK_F23);
136 CASE(VK_F24);
137 CASE(VK_ENDDRAG);
138 CASE(VK_CLEAR);
139 CASE(VK_EREOF);
140 CASE(VK_PA1);
141 CASE(VK_ATTN);
142 CASE(VK_CRSEL);
143 CASE(VK_EXSEL);
144 CASE(VK_COPY);
145 CASE(VK_BLK1);
146 CASE(VK_BLK2);
147#undef CASE
148 default:
149 return "";
150 }
151}
152
153char GetChar(unsigned ch)
154{
155 if (ch < 128 && isprint(ch)) {
156 return ch;
157 }
158 return '.';
159}
160
161int main()
162{
163 /*
164 * PM prolog.
165 */
166 PPIB pPib;
167 DosGetInfoBlocks(NULL, &pPib);
168 pPib->pib_ultype = 3;
169 HAB hab = WinInitialize(0);
170 HMQ hmq = WinCreateMsgQueue(hab, 0); (void)hmq;
171
172 /*
173 * char to scancode to virtual key.
174 */
175 printf("char -> scancode -> virtual key\n");
176 for (unsigned iChar = 0; iChar < 256; iChar++) {
177 /* to scancode */
178 USHORT usScanCode = iChar;
179 ULONG ulScanCodeDeadKeyInfo = 0;
180 USHORT fScanCodeShiftState = 0;
181 USHORT fScanCodeRc = WinTranslateChar2(0, &usScanCode, &ulScanCodeDeadKeyInfo, TC_CHARTOSCANCODE, &fScanCodeShiftState);
182 if (usScanCode) {
183 /* to virtual key */
184 USHORT usVirtualKey = usScanCode;
185 ULONG ulVirtualKeyDeadKeyInfo = ulScanCodeDeadKeyInfo;
186 USHORT fVirtualKeyShiftState = fScanCodeShiftState;
187 USHORT fVirtualKeyRc = WinTranslateChar2(0, &usVirtualKey, &ulVirtualKeyDeadKeyInfo, TC_SCANCODETOVIRTUALKEY, &fVirtualKeyShiftState);
188 printf("%d/%#x/[%c]: %04x %lx %04x %04x | %04x %lx %04x %04x (%s)\n",
189 iChar, iChar, GetChar(iChar),
190 usScanCode, ulScanCodeDeadKeyInfo, fScanCodeShiftState, fScanCodeRc,
191 usVirtualKey, ulVirtualKeyDeadKeyInfo, fVirtualKeyShiftState, fVirtualKeyRc, GetVirtualKeyName(usVirtualKey));
192 }
193 }
194
195 /*
196 * virtual key to scancode and char.
197 */
198 printf("\n"
199 "\n"
200 "\n"
201 "virtual key -> scancode -> char\n");
202 for (unsigned iVirtualKey = 0; iVirtualKey < 512; iVirtualKey++) {
203 /* to scancode */
204 USHORT usScanCode = iVirtualKey;
205 ULONG ulScanCodeDeadKeyInfo = 0;
206 USHORT fScanCodeShiftState = 0;
207 USHORT fScanCodeRc = WinTranslateChar2(0, &usScanCode, &ulScanCodeDeadKeyInfo, TC_VIRTUALKEYTOSCANCODE, &fScanCodeShiftState);
208 if (usScanCode) {
209 /* to char */
210 USHORT usChar = usScanCode;
211 ULONG ulCharDeadKeyInfo = 0;
212 USHORT fCharShiftState = fScanCodeShiftState;
213 USHORT fCharRc = WinTranslateChar2(0, &usChar, &ulCharDeadKeyInfo, TC_SCANCODETOCHAR, &fCharShiftState);
214 if (usChar) {
215 printf("%3d/%#04x: %04x %lx %04x %04x | %04x[%c] %lx %04x %04x [%s]\n",
216 iVirtualKey, iVirtualKey,
217 usScanCode, ulScanCodeDeadKeyInfo, fScanCodeShiftState, fScanCodeRc,
218 usChar, GetChar(usChar), ulCharDeadKeyInfo, fCharShiftState, fCharRc,
219 GetVirtualKeyName(iVirtualKey));
220 } else {
221 printf("%3d/%#04x: %04x %lx %04x %04x [%s]\n",
222 iVirtualKey, iVirtualKey,
223 usScanCode, ulScanCodeDeadKeyInfo, fScanCodeShiftState, fScanCodeRc,
224 GetVirtualKeyName(iVirtualKey));
225 }
226 }
227 }
228
229 printf("\n"
230 "\n"
231 "\n"
232 "scan code -> oem scan code -> scan code\n");
233 for (unsigned iScanCode = 0; iScanCode < 256; iScanCode++) {
234 USHORT usOemScanCode = iScanCode;
235 ULONG ulOemScanCodeDeadKeyInfo = 0;
236 USHORT fOemScanCodeShiftState = 0;
237 USHORT fOemScanCodeRc = WinTranslateChar2(0, &usOemScanCode, &ulOemScanCodeDeadKeyInfo, TC_SCANTOOEMSCAN, &fOemScanCodeShiftState);
238 if (usOemScanCode) {
239 printf("%3d/%#04x: %04x %lx %04x %04x",
240 iScanCode, iScanCode,
241 usOemScanCode, ulOemScanCodeDeadKeyInfo, fOemScanCodeShiftState, fOemScanCodeRc);
242 /* the other way */
243 fOemScanCodeRc = WinTranslateChar2(0, &usOemScanCode, &ulOemScanCodeDeadKeyInfo, TC_SCANTOOEMSCAN, &fOemScanCodeShiftState);
244 printf(" -> %04x %lx %04x %04x%s\n",
245 usOemScanCode, ulOemScanCodeDeadKeyInfo, fOemScanCodeShiftState, fOemScanCodeRc,
246 usOemScanCode != iScanCode ? " *" :"");
247 }
248 }
249
250 printf("\n"
251 "\n"
252 "\n"
253 "oem scan code -> scan code\n");
254 for (unsigned iOemScanCode = 0; iOemScanCode < 128; iOemScanCode++) {
255 USHORT usScanCode = iOemScanCode;
256 ULONG ulScanCodeDeadKeyInfo = 0;
257 USHORT fScanCodeShiftState = 0;
258 USHORT fScanCodeRc = WinTranslateChar2(0, &usScanCode, &ulScanCodeDeadKeyInfo, TC_OEMSCANTOSCAN, &fScanCodeShiftState);
259 if (usScanCode) {
260 printf("%3d/%#04x: %04x %lx %04x %04x\n",
261 iOemScanCode, iOemScanCode,
262 usScanCode, ulScanCodeDeadKeyInfo, fScanCodeShiftState, fScanCodeRc);
263 }
264 }
265
266 printf("\n"
267 "\n"
268 "\n"
269 "scan code -> extended oem scan code -> scan code\n");
270 for (unsigned iScanCode = 0; iScanCode < 256; iScanCode++) {
271 USHORT usOemScanCode = iScanCode;
272 ULONG ulOemScanCodeDeadKeyInfo = 0;
273 USHORT fOemScanCodeShiftState = TCF_EXTENDEDKEY;
274 USHORT fOemScanCodeRc = WinTranslateChar2(0, &usOemScanCode, &ulOemScanCodeDeadKeyInfo, TC_SCANTOOEMSCAN, &fOemScanCodeShiftState);
275 if (usOemScanCode) {
276 printf("%3d/%#04x: %04x %lx %04x %04x",
277 iScanCode, iScanCode,
278 usOemScanCode, ulOemScanCodeDeadKeyInfo, fOemScanCodeShiftState, fOemScanCodeRc);
279 /* the other way */
280 fOemScanCodeRc = WinTranslateChar2(0, &usOemScanCode, &ulOemScanCodeDeadKeyInfo, TC_SCANTOOEMSCAN, &fOemScanCodeShiftState);
281 printf(" -> %04x %lx %04x %04x%s\n",
282 usOemScanCode, ulOemScanCodeDeadKeyInfo, fOemScanCodeShiftState, fOemScanCodeRc,
283 usOemScanCode != iScanCode ? " *" :"");
284 }
285 }
286
287 printf("\n"
288 "\n"
289 "\n"
290 "extended oem scan code -> scan code\n");
291 for (unsigned iOemScanCode = 0; iOemScanCode < 128; iOemScanCode++) {
292 USHORT usScanCode = iOemScanCode;
293 ULONG ulScanCodeDeadKeyInfo = 0;
294 USHORT fScanCodeShiftState = TCF_EXTENDEDKEY;
295 USHORT fScanCodeRc = WinTranslateChar2(0, &usScanCode, &ulScanCodeDeadKeyInfo, TC_OEMSCANTOSCAN, &fScanCodeShiftState);
296 if (usScanCode) {
297 printf("%3d/%#04x: %04x %lx %04x %04x\n",
298 iOemScanCode, iOemScanCode,
299 usScanCode, ulScanCodeDeadKeyInfo, fScanCodeShiftState, fScanCodeRc);
300 }
301 }
302
303
304 /*
305 * scancode to char and virtual key.
306 */
307 printf("\n"
308 "\n"
309 "\n"
310 "scancode -> char + virtual key \n");
311 for (unsigned iScanCode = 0; iScanCode < 256; iScanCode++) {
312 struct {
313 USHORT usVirtualKey;
314 USHORT usChar;
315 USHORT fCharRc;
316 } aCombinations[1 << TCF_MAX_BITS];
317 for (unsigned fShiftState = 0; fShiftState < (1 << TCF_MAX_BITS); fShiftState++) {
318 /* to char */
319 USHORT usChar = iScanCode;
320 ULONG ulCharDeadKeyInfo = 0;
321 USHORT fCharShiftState = fShiftState;
322 USHORT fCharRc = WinTranslateChar2(0, &usChar, &ulCharDeadKeyInfo, TC_SCANCODETOCHAR, &fCharShiftState);
323 aCombinations[fShiftState].usChar = usChar;
324 aCombinations[fShiftState].fCharRc = fCharRc;
325
326 /* to virtual key */
327 USHORT usVirtualKey = iScanCode;
328 ULONG ulVirtualKeyDeadKeyInfo = 0;
329 USHORT fVirtualKeyShiftState = fShiftState;
330 USHORT fVirtualKeyRc = WinTranslateChar2(0, &usVirtualKey, &ulVirtualKeyDeadKeyInfo, TC_SCANCODETOVIRTUALKEY, &fVirtualKeyShiftState);
331 aCombinations[fShiftState].usVirtualKey = usVirtualKey;
332
333 /* display the result */
334 printf(" %3d/%#04x+%02x[%c%c%c%c%c%c%c%c]: ",
335 iScanCode, iScanCode, fShiftState,
336 fShiftState & TCF_LSHIFT ? 'L' : '-',
337 fShiftState & TCF_RSHIFT ? 'R' : '-',
338 fShiftState & TCF_LCONTROL ? 'l' : '-',
339 fShiftState & TCF_RCONTROL ? 'r' : '-',
340 fShiftState & TCF_ALT ? 'A' : '-',
341 fShiftState & TCF_ALTGR ? 'G' : '-',
342 fShiftState & TCF_CAPSLOCK ? 'C' : '-',
343 fShiftState & TCF_NUMLOCK ? 'N' : '-');
344 if (usChar && usVirtualKey) {
345 printf("%04x[%c] %lx %04x %04x | %04x %lx %04x %04x (%s)\n",
346 usChar, GetChar(usChar), ulCharDeadKeyInfo, fCharShiftState, fCharRc,
347 usVirtualKey, ulVirtualKeyDeadKeyInfo, fVirtualKeyShiftState, fVirtualKeyRc, GetVirtualKeyName(usVirtualKey));
348 } else if (usChar) {
349 printf("%04x[%c] %lx %04x %04x\n",
350 usChar, GetChar(usChar), ulCharDeadKeyInfo, fCharShiftState, fCharRc);
351 } else if (usVirtualKey) {
352 printf(" | %04x %lx %04x %04x (%s)\n",
353 usVirtualKey, ulVirtualKeyDeadKeyInfo, fVirtualKeyShiftState, fVirtualKeyRc, GetVirtualKeyName(usVirtualKey));
354 } else {
355 printf("\n");
356 }
357 }
358#if 0
359 /* 2. Eliminate duplicates. */
360 for (unsigned j = 0; j < sizeof(aCombinations) / sizeof(aCombinations[0]); j++) {
361 unsigned iBest = j;
362 for (unsigned k = j + 1; k < sizeof(aCombinations) / sizeof(aCombinations[0]); k++) {
363 if ( aCombinations[iBest].usChar == aCombinations[k].usChar
364 && aCombinations[iBest].usVirtualKey == aCombinations[k].usVirtualKey) {
365 // check if one of these is a subset of the other.
366 if ((iBest & k) == k) {
367 aCombinations[iBest].usChar = aCombinations[iBest].usVirtualKey = 0;
368 iBest = k;
369 } else if ( (iBest & k) == iBest
370 /*|| iBest == k - when we can ignore L/R keys */) {
371 aCombinations[k].usChar = aCombinations[k].usVirtualKey = 0;
372 }
373 }
374 }
375 }
376
377 // 3. Print the remainders.
378 for (unsigned fShiftState = 0; fShiftState < sizeof(aCombinations) / sizeof(aCombinations[0]); fShiftState++) {
379 if (aCombinations[fShiftState].usChar || aCombinations[fShiftState].usVirtualKey) {
380 const USHORT usChar = aCombinations[fShiftState].usChar;
381 const USHORT fCharRc = aCombinations[fShiftState].fCharRc;
382 const USHORT usVirtualKey = aCombinations[fShiftState].usVirtualKey;
383
384 printf("*%3d/%#04x+%02x[%c%c%c%c%c%c%c%c]: ",
385 iScanCode, iScanCode, fShiftState,
386 fShiftState & TCF_LSHIFT ? 'L' : '-',
387 fShiftState & TCF_RSHIFT ? 'R' : '-',
388 fShiftState & TCF_LCONTROL ? 'l' : '-',
389 fShiftState & TCF_RCONTROL ? 'r' : '-',
390 fShiftState & TCF_ALT ? 'A' : '-',
391 fShiftState & TCF_ALTGR ? 'G' : '-',
392 fShiftState & TCF_CAPSLOCK ? 'C' : '-',
393 fShiftState & TCF_NUMLOCK ? 'N' : '-');
394 if (usChar && usVirtualKey) {
395 printf("%04x[%c] %04x | %04x (%s)\n", usChar, GetChar(usChar), fCharRc, usVirtualKey, GetVirtualKeyName(usVirtualKey));
396 } else if (usChar) {
397 printf("%04x[%c] %04x \n", usChar, GetChar(usChar), fCharRc);
398 } else if (usVirtualKey) {
399 printf(" | %04x (%s)\n", usVirtualKey, GetVirtualKeyName(usVirtualKey));
400 } else {
401 printf("\n");
402 }
403 }
404 }
405#endif
406 }
407
408 return 0;
409}
410
Note: See TracBrowser for help on using the repository browser.