OSDN Git Service

最初のコミット
[winaudioj/stedx.git] / win32_key.cpp
1 /*
2   win32_key.cpp
3   screen driver for win32
4
5   Made by Studio Breeze. 2002
6
7   Permission is hereby granted, free of charge, to any person obtaining a copy
8   of this software and associated documentation files (the "Software"), to deal
9   in the Software without restriction, including without limitation the rights
10   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11   copies of the Software, and to permit persons to whom the Software is
12   furnished to do so, subject to the following conditions:
13
14   The above copyright notice and this permission notice shall be included in
15   all copies or substantial portions of the Software.
16
17   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23   THE SOFTWARE.
24  */
25 #include "stdafx.h"
26
27 #include "sted_screen_win32.h"
28
29 // nofitication from main window
30 void
31 CSTedScreenWin32::NotifyKeyPressed(int in_key)
32 {
33   fKeyEventNotified = TRUE;
34
35   if (in_key == fKeyConv[EShift])
36     fKeyShiftPressed = TRUE;
37   else if (in_key == fKeyConv[EControl])
38     fKeyControlPressed = TRUE;
39   else if (in_key == fKeyConv[EOPT1])
40     fKeyOPT1Pressed = TRUE;
41   else if (in_key == fKeyConv[EOPT2])
42     fKeyOPT2Pressed = TRUE;
43   else if (in_key == fKeyConv[EKana])
44     fKeyKanaPressed = TRUE;
45   else if (in_key == fKeyConv[EInsert])
46     fKeyInsertPressed = TRUE;
47
48   else {
49           switch (in_key) {
50                   case VK_PRIOR:
51                   case VK_NEXT:
52                   case VK_HOME:
53                   case VK_END:
54                   case VK_UP:
55                   case VK_DOWN:
56                   case VK_LEFT:
57                   case VK_RIGHT:
58                   case VK_F1:
59                   case VK_F2:
60                   case VK_F3:
61                   case VK_F4:
62                   case VK_F5:
63                   case VK_F6:
64                   case VK_F7:
65                   case VK_F8:
66                   case VK_F9:
67                   case VK_F10:
68                   case VK_F11:
69                   case VK_F12:
70                   case VK_LMENU:
71                   case VK_RMENU:
72                   case VK_LCONTROL:
73                   case VK_RCONTROL:
74                   case VK_NONCONVERT:
75                   case 0xd8: // for Kigo
76                   case 0xd9: // for Toroku
77                         fKeyBuffer[fKeyBufferEndPtr] = (in_key | 0x100);
78                         fKeyBufferEndPtr = (fKeyBufferEndPtr+1)%fKeyBufferLen;
79                         if (fKeyBufferEndPtr==fKeyBufferStartPtr) {
80                                 fKeyBufferStartPtr = (fKeyBufferStartPtr+1)%fKeyBufferLen;
81                         }
82                         fKeyBufferAvailable++;
83                         if (fKeyBufferAvailable>=fKeyBufferLen) {
84                                 fKeyBufferAvailable = fKeyBufferLen;
85                         }
86                         break;
87                   default:
88                           fKeyEventNotified = FALSE;
89                           break;
90           }
91   }
92 }
93
94 void
95 CSTedScreenWin32::NotifyKeyReleased(int in_key)
96 {
97   fKeyEventNotified = TRUE;
98
99   if (in_key == fKeyConv[EShift])
100     fKeyShiftPressed = FALSE;
101   else if (in_key == fKeyConv[EControl])
102     fKeyControlPressed = FALSE;
103   else if (in_key == fKeyConv[EOPT1])
104     fKeyOPT1Pressed = FALSE;
105   else if (in_key == fKeyConv[EOPT2])
106     fKeyOPT2Pressed = FALSE;
107   else if (in_key == fKeyConv[EKana])
108     fKeyKanaPressed = FALSE;
109   else if (in_key == fKeyConv[EInsert])
110     fKeyInsertPressed = FALSE;
111 }
112
113 void
114 CSTedScreenWin32::NotifyChar(int in_char)
115 {
116         int len=0;
117         WCHAR buf[2];
118         unsigned char str[6];
119         int ptr;
120
121         fKeyEventNotified = TRUE;
122
123         buf[0] = in_char;
124         buf[1] = '\0';
125
126 #ifdef _UNICODE
127         len = ::WideCharToMultiByte(932, 0, (LPCWSTR)buf, 1, (LPSTR)str, 6, NULL, NULL);
128 #else
129         len = 1;
130         str[0] = (unsigned char)in_char;
131 #endif
132
133         ptr=0;
134         while (len>0) {
135                 fKeyBuffer[fKeyBufferEndPtr] = str[ptr++];
136                 fKeyBufferEndPtr = (fKeyBufferEndPtr+1)%fKeyBufferLen;
137                 if (fKeyBufferEndPtr==fKeyBufferStartPtr) {
138                         fKeyBufferStartPtr = (fKeyBufferStartPtr+1)%fKeyBufferLen;
139                 }
140                 fKeyBufferAvailable++;
141                 if (fKeyBufferAvailable>=fKeyBufferLen) {
142                         fKeyBufferAvailable = fKeyBufferLen;
143                 }
144                 len--;
145         }
146 }
147
148 // key
149 int 
150 CSTedScreenWin32::KeyInit(void)
151 {
152   fKeyBufferStartPtr = 0;
153   fKeyBufferEndPtr = 0;
154   fKeyBufferAvailable = 0;
155
156   fKeyShiftPressed = FALSE;
157   fKeyControlPressed = FALSE;
158   fKeyOPT1Pressed = FALSE;
159   fKeyOPT2Pressed = FALSE;
160   fKeyKanaPressed = FALSE;
161   fKeyInsertPressed = FALSE;
162
163   fKeyEventNotified = FALSE;
164
165   // default configuration for IBM-106
166
167   fKeyConv[EShift] = VK_SHIFT;
168   fKeyConv[EControl] = VK_CONTROL;
169   fKeyConv[EOPT1] = VK_F11;
170   fKeyConv[EOPT2] = VK_F12;
171   fKeyConv[EXF1] = VK_LMENU;
172   fKeyConv[EXF2] = VK_NONCONVERT;
173   fKeyConv[EXF3] = VK_CONVERT;
174   fKeyConv[EXF4] = VK_KANA;
175   fKeyConv[EXF5] = VK_RMENU;
176   fKeyConv[EKana] = VK_LCONTROL;
177   fKeyConv[EKigo] = 0xd8; // unassigned
178   fKeyConv[EToroku] = 0xd9; // unassigned
179   fKeyConv[EInsert] = VK_INSERT;
180   fKeyConv[EDel] = VK_DELETE;
181   fKeyConv[EHome] = VK_HOME;
182   fKeyConv[EUndo] = VK_END;
183   fKeyConv[ERollUp] = VK_PRIOR;
184   fKeyConv[ERollDown] = VK_NEXT;
185   fKeyConv[EF1] = VK_F1;
186   fKeyConv[EF2] = VK_F2;
187   fKeyConv[EF3] = VK_F3;
188   fKeyConv[EF4] = VK_F4;
189   fKeyConv[EF5] = VK_F5;
190   fKeyConv[EF6] = VK_F6;
191   fKeyConv[EF7] = VK_F7;
192   fKeyConv[EF8] = VK_F8;
193   fKeyConv[EF9] = VK_F9;
194   fKeyConv[EF10] = VK_F10;
195
196   return 0;
197 }
198
199 // blocking
200 int 
201 CSTedScreenWin32::KeyIn(int in_code)
202 {
203   int result;
204   int key;
205
206  loop:
207   if (fKeyBufferAvailable<=0) return 0;
208
209   key = fKeyBuffer[fKeyBufferStartPtr];
210   result = ConvertWinKeyToX68Key(key);
211
212   if (result<=0) {
213     fKeyBufferAvailable--;
214         fKeyBufferStartPtr = (fKeyBufferStartPtr+1)%fKeyBufferLen;
215         goto loop;
216   }
217
218
219   if (in_code!=0xfe) {
220     fKeyBufferAvailable--;
221         fKeyBufferStartPtr = (fKeyBufferStartPtr+1)%fKeyBufferLen;
222   }
223
224   return result;
225 }
226
227
228 // キー入力blockingモード
229 int
230 CSTedScreenWin32::KeyInp(void)
231 {
232   BOOL result;
233   int ascii, code;
234   int key;
235
236 loop:
237   do {
238           if (!fKeyEventNotified) 
239           {
240                   DoMessageLoop();
241           }
242           fKeyEventNotified = FALSE;
243   } while(fKeyBufferAvailable <= 0);
244
245   key = fKeyBuffer[fKeyBufferStartPtr];
246   result = ConvertWinKeyToX68Key(key, &ascii, &code);
247   if (!result) {
248     fKeyBufferAvailable--;
249         fKeyBufferStartPtr = (fKeyBufferStartPtr+1)%fKeyBufferLen;
250         if (fKeyBufferAvailable>0)
251                 fKeyEventNotified = TRUE;
252     goto loop;
253   }
254
255   fKeyBufferAvailable--;
256   fKeyBufferStartPtr = (fKeyBufferStartPtr+1)%fKeyBufferLen;
257   if (fKeyBufferAvailable>0) fKeyEventNotified = TRUE;
258
259   return (ascii | code<<8);
260 }
261
262 int
263 CSTedScreenWin32::SftSense(void)
264 {
265   int ret=0;
266
267   if (fKeyShiftPressed) ret|=1;
268   if (fKeyControlPressed) ret|=2;
269   if (fKeyOPT1Pressed) ret|=4;
270   if (fKeyOPT2Pressed) ret|=8;
271   if (fKeyKanaPressed) ret|=16+256;
272   if (fKeyInsertPressed) ret|=4096;
273
274   if (!(::GetKeyState(VK_SHIFT)&0xff00)) {
275           fKeyShiftPressed = FALSE;
276   }
277
278   return ret;
279 }
280
281 BOOL
282 CSTedScreenWin32::CheckKeyBuffer(int in_key)
283 {
284     int val;
285     val = ::GetKeyState(in_key);
286     if (val&0xff00) return TRUE;
287     return FALSE;
288 }
289
290 int 
291 CSTedScreenWin32::BitSense(int in_group)
292 {
293   int ret = 0;
294
295   switch ( in_group ) {
296   case 0:  /* 1 - 6 */
297     if (CheckKeyBuffer('1')) ret|=4;
298     if (CheckKeyBuffer('2')) ret|=8;
299     if (CheckKeyBuffer('3')) ret|=16;
300     if (CheckKeyBuffer('4')) ret|=32;
301     if (CheckKeyBuffer('5')) ret|=64;
302     if (CheckKeyBuffer('6')) ret|=128;
303     break;
304
305   case 1:
306     if (CheckKeyBuffer('7')) ret|=1;
307     if (CheckKeyBuffer('8')) ret|=2;
308     if (CheckKeyBuffer('9')) ret|=4;
309     if (CheckKeyBuffer('0')) ret|=8;
310     if (CheckKeyBuffer('-')) ret|=16;
311     if (CheckKeyBuffer('^')) ret|=32;
312     if (CheckKeyBuffer('\\')) ret|=64;
313     if (CheckKeyBuffer(VK_BACK)) ret|=128;
314     break;
315
316   case 2:
317     if (CheckKeyBuffer(VK_TAB)) ret|=1;
318     if (CheckKeyBuffer('Q')) ret|=2;
319     if (CheckKeyBuffer('W')) ret|=4;
320     if (CheckKeyBuffer('E')) ret|=8;
321     if (CheckKeyBuffer('R')) ret|=16;
322     if (CheckKeyBuffer('T')) ret|=32;
323     if (CheckKeyBuffer('Y')) ret|=64;
324     if (CheckKeyBuffer('U')) ret|=128;
325     break;
326
327   case 3:
328     if (CheckKeyBuffer('I')) ret|=1;
329     if (CheckKeyBuffer('O')) ret|=2;
330     if (CheckKeyBuffer('P')) ret|=4;
331     if (CheckKeyBuffer('@')) ret|=8;
332     if (CheckKeyBuffer('[')) ret|=16;
333     if (CheckKeyBuffer(VK_RETURN)) ret|=32;
334     if (CheckKeyBuffer('A')) ret|=64;
335     if (CheckKeyBuffer('S')) ret|=128;
336     break;
337
338   case 4:
339     if (CheckKeyBuffer('D')) ret|=1;
340     if (CheckKeyBuffer('F')) ret|=2;
341     if (CheckKeyBuffer('G')) ret|=4;
342     if (CheckKeyBuffer('H')) ret|=8;
343     if (CheckKeyBuffer('J')) ret|=16;
344     if (CheckKeyBuffer('K')) ret|=32;
345     if (CheckKeyBuffer('L')) ret|=64;
346     if (CheckKeyBuffer(';')) ret|=128;
347     break;
348
349   case 5:
350     if (CheckKeyBuffer(':')) ret|=1;
351     if (CheckKeyBuffer(']')) ret|=2;
352     if (CheckKeyBuffer('Z')) ret|=4;
353     if (CheckKeyBuffer('X')) ret|=8;
354     if (CheckKeyBuffer('C')) ret|=16;
355     if (CheckKeyBuffer('V')) ret|=32;
356     if (CheckKeyBuffer('B')) ret|=64;
357     if (CheckKeyBuffer('N')) ret|=128;
358     break;
359
360   case 6:
361     if (CheckKeyBuffer('M')) ret|=1;
362     if (CheckKeyBuffer(',')) ret|=2;
363     if (CheckKeyBuffer('.')) ret|=4;
364     if (CheckKeyBuffer('/')) ret|=8;
365     if (CheckKeyBuffer('\\')) ret|=16;
366     if (CheckKeyBuffer(' ')) ret|=32;
367     break;
368
369   case 7: /* R_UP,R_DOWN, Cursors */
370     if (CheckKeyBuffer(VK_PRIOR)) ret|=1;
371     if (CheckKeyBuffer(VK_NEXT)) ret|=2;
372     if (CheckKeyBuffer(VK_END)) ret|=4;
373     if (CheckKeyBuffer(VK_LEFT)) ret|=8;
374     if (CheckKeyBuffer(VK_UP)) ret|=16;
375     if (CheckKeyBuffer(VK_RIGHT)) ret|=32;
376     if (CheckKeyBuffer(VK_DOWN)) ret|=64;
377     break;
378 #if 0
379   case 0x0a: /* XF1-XF3 */
380     if (check_keycode(k_xf1      , key_buffer)) ret|=32;
381     if (check_keycode(k_xf2      , key_buffer)) ret|=64;
382     if (check_keycode(k_xf3      , key_buffer)) ret|=128;
383     break;
384
385   case 0x0b: /* XF4-XF5 */
386     if (check_keycode(k_xf4      , key_buffer)) ret|=1;
387     if (check_keycode(k_xf5      , key_buffer)) ret|=2;
388     break;
389 #endif
390   case 0x0c: /* F0-F4 */
391     if (CheckKeyBuffer(VK_F1)) ret|=8;
392     if (CheckKeyBuffer(VK_F2)) ret|=16;
393     if (CheckKeyBuffer(VK_F3)) ret|=32;
394     if (CheckKeyBuffer(VK_F4)) ret|=64;
395     if (CheckKeyBuffer(VK_F5)) ret|=128;
396     break;
397
398   case 0x0d: /* F5-F9 */
399     if (CheckKeyBuffer(VK_F6)) ret|=1;
400     if (CheckKeyBuffer(VK_F7)) ret|=2;
401     if (CheckKeyBuffer(VK_F8)) ret|=4;
402     if (CheckKeyBuffer(VK_F9)) ret|=8;
403     if (CheckKeyBuffer(VK_F10)) ret|=16;
404     break;
405
406   case 0x0e: /* OPT.1-OPT.2 */
407     if (CheckKeyBuffer(VK_F11)) ret|=4;
408     if (CheckKeyBuffer(VK_F12)) ret|=8;
409     break;
410
411   default:
412     break;
413   }
414
415   return ret;
416 }
417
418 int
419 CSTedScreenWin32::KeySense(void)
420 {
421         if (fKeyBufferAvailable==0) return 0;
422         return 1;
423 }
424
425 void
426 CSTedScreenWin32::KeyWait(void)
427 {
428         while (!fKeyEventNotified && fKeyBufferAvailable==0) {
429                 DoMessageLoop();
430         }
431         fKeyEventNotified = FALSE;
432 }
433
434 void
435 CSTedScreenWin32::LedMode(int in_code, int in_onoff)
436 {
437 }
438
439 void
440 CSTedScreenWin32::ClearKeyBuffer(void)
441 {
442         fKeyBufferAvailable = 0;
443         fKeyBufferStartPtr = 0;
444         fKeyBufferEndPtr = 0;
445 }
446
447 // key conversion
448 int
449 CSTedScreenWin32::ConvertWinKeyToX68Key(int in_winkey)
450 {
451   int result;
452
453   if (in_winkey<0x100) { // char
454           return in_winkey;
455   }
456
457   in_winkey&=0xff;
458   switch (in_winkey) {
459   case VK_UP:
460     result = fFncKey[4][0];
461     break;
462   case VK_DOWN:
463     result = fFncKey[7][0];
464     break;
465   case VK_LEFT:
466     result = fFncKey[5][0];
467     break;
468   case VK_RIGHT:
469     result = fFncKey[6][0];
470     break;
471   case VK_BACK:
472     result = 0x08;
473     break;
474   default:
475     if (in_winkey == fKeyConv[EHome])
476       result = fFncKey[10][0];
477     else if (in_winkey == fKeyConv[EUndo])
478       result = fFncKey[11][0];
479     else if (in_winkey == fKeyConv[EDel])
480       result = fFncKey[3][0];
481     else if (in_winkey == fKeyConv[EInsert])
482       result = fFncKey[2][0];
483     else if (in_winkey == fKeyConv[ERollDown])
484       result = fFncKey[0][0];
485     else if (in_winkey == fKeyConv[ERollUp])
486       result = fFncKey[1][0];
487     else {
488       result = in_winkey;
489     }
490     break;
491   }
492
493   return result;
494 }
495
496 int
497 CSTedScreenWin32::ConvertWinKeyToX68Key(int in_winkey, int* out_ascii, int* out_code)
498 {
499   int ascii=0, code=0;
500   int result=1;
501
502   if (in_winkey<0x100) {
503           if (in_winkey>=0x20 && in_winkey<=0x7f) {
504                   code = fX68ScanCode[in_winkey-0x20];
505           } else {
506                   switch (in_winkey) {
507                           case 0x1b: code = 0x01;break;
508                           case 0x0d: code = 0x1d;break;
509                           case 0x09: code = 0x10;break;
510                           default: code = 0; break;
511                   }
512           }
513           if (out_ascii) *out_ascii = in_winkey;
514           if (out_code) *out_code = code;
515           return 1;
516   }
517
518   in_winkey&=0xff;
519
520   switch (in_winkey) {
521   case VK_UP:
522     ascii=0; code=0x3c; break;
523     break;
524   case VK_DOWN:
525     ascii=0; code=0x3e; break;
526     break;
527   case VK_LEFT:
528     ascii=0; code=0x3b; break;
529     break;
530   case VK_RIGHT:
531     ascii=0; code=0x3d; break;
532     break;
533   case VK_BACK:
534     ascii=0; code=0x0f; break;
535     break;
536   case VK_RETURN:
537     ascii=0x0d; code=0x1d; break;
538     break;
539   case VK_ESCAPE:
540     ascii=0x1b; code=0x01; break;
541     break;
542   case VK_TAB:
543     ascii=0x09; code=0x10; break;
544     break;
545
546   case VK_SHIFT:
547     ascii=0x00; code=fKeyShiftPressed?0x70:0xf0; break;
548     break;
549   case VK_CONTROL:
550     ascii=0x00; code=fKeyControlPressed?0x71:0xf1; break;
551     break;
552   default:
553     if (in_winkey == fKeyConv[EF1]) {
554       ascii=0x00; code=0x63;
555     } else if (in_winkey == fKeyConv[EF2]) {
556       ascii=0x00; code=0x64;
557     } else if (in_winkey == fKeyConv[EF3]) {
558       ascii=0x00; code=0x65;
559     } else if (in_winkey == fKeyConv[EF4]) {
560       ascii=0x00; code=0x66;
561     } else if (in_winkey == fKeyConv[EF5]) {
562       ascii=0x00; code=0x67;
563     } else if (in_winkey == fKeyConv[EF6]) {
564       ascii=0x00; code=0x68;
565     } else if (in_winkey == fKeyConv[EF7]) {
566       ascii=0x00; code=0x69;
567     } else if (in_winkey == fKeyConv[EF8]) {
568       ascii=0x00; code=0x6a;
569     } else if (in_winkey == fKeyConv[EF9]) {
570       ascii=0x00; code=0x6b;
571     } else if (in_winkey == fKeyConv[EF10]) {
572       ascii=0x00; code=0x6c;
573
574     } else if (in_winkey == fKeyConv[EKigo]) {
575       ascii=0x00; code=0x52;
576     } else if (in_winkey == fKeyConv[EToroku]) {
577       ascii=0x00; code=0x53;
578
579     } else if (in_winkey == fKeyConv[EXF1]) {
580       ascii=0x00; code=0x55;
581     } else if (in_winkey == fKeyConv[EXF2]) {
582       ascii=0x00; code=0x56;
583     } else if (in_winkey == fKeyConv[EXF3]) {
584       ascii=0x00; code=0x57;
585     } else if (in_winkey == fKeyConv[EXF4]) {
586       ascii=0x00; code=0x58;
587     } else if (in_winkey == fKeyConv[EXF5]) {
588       ascii=0x00; code=0x59;
589
590     } else if (in_winkey == fKeyConv[EHome]) {
591       ascii=0x00; code=0x36;
592     } else if (in_winkey == fKeyConv[EDel]) {
593       ascii=0x00; code=0x37;
594     } else if (in_winkey == fKeyConv[EInsert]) {
595       ascii=0x00; code=0x5e;
596     } else if (in_winkey == fKeyConv[ERollDown]) {
597       ascii=0x00; code=0x38;
598     } else if (in_winkey == fKeyConv[ERollUp]) {
599       ascii=0x00; code=0x39;
600     } else if (in_winkey == fKeyConv[EUndo]) {
601       ascii=0x00; code=0x3a;
602     } else if (in_winkey == fKeyConv[EOPT1]) {
603       ascii=0x00; code=(fKeyOPT1Pressed)?0x72:0xf2;
604     } else if (in_winkey == fKeyConv[EOPT2]) {
605       ascii=0x00; code=(fKeyOPT2Pressed)?0x72:0xf2;
606
607     } else if (in_winkey == VK_NUMPAD0) {
608       ascii='0'; code=0x4f;
609     } else if (in_winkey == VK_NUMPAD1) {
610       ascii='1'; code=0x4b;
611     } else if (in_winkey == VK_NUMPAD2) {
612       ascii='2'; code=0x4c;
613     } else if (in_winkey == VK_NUMPAD3) {
614       ascii='3'; code=0x4d;
615     } else if (in_winkey == VK_NUMPAD4) {
616       ascii='4'; code=0x47;
617     } else if (in_winkey == VK_NUMPAD5) {
618       ascii='5'; code=0x48;
619     } else if (in_winkey == VK_NUMPAD6) {
620       ascii='6'; code=0x49;
621     } else if (in_winkey == VK_NUMPAD7) {
622       ascii='7'; code=0x43;
623     } else if (in_winkey == VK_NUMPAD8) {
624       ascii='8'; code=0x44;
625     } else if (in_winkey == VK_NUMPAD9) {
626       ascii='9'; code=0x45;
627     } else if (in_winkey == VK_DECIMAL) {
628       ascii='.'; code=0x51;
629     } else if (in_winkey == VK_DIVIDE) {
630       ascii='/'; code=0x40;
631     } else if (in_winkey == VK_MULTIPLY) {
632       ascii='*'; code=0x41;
633     } else if (in_winkey == VK_SUBTRACT) {
634       ascii='-'; code=0x42;
635     } else if (in_winkey == VK_ADD) {
636       ascii='+'; code=0x46;
637
638         } else if (in_winkey == VK_OEM_2) {
639                 ascii='/'; code=fX68ScanCode[ascii-0x20];
640         } else if (in_winkey == VK_OEM_102) {
641                 ascii='\\'; code=fX68ScanCode[ascii-0x20];
642
643     } else if (in_winkey>=0x20 && in_winkey<0x7f) {
644       ascii = in_winkey;
645       code = fX68ScanCode[in_winkey-0x20];
646
647     } else {
648       ascii=0; code=0;
649           result = 0;
650     }
651     break;
652   }
653
654   if (out_ascii) *out_ascii = ascii;
655   if (out_code) *out_code = code;
656   return result;
657 }