1 /**
2 * @namespace biewlib
3 * @file biewlib/sysdep/ia32/win32/keyboard.c
4 * @brief This file contains implementation of keyboard handles for Win32s.
5 * @version -
6 * @remark this source file is part of Binary vIEW project (BIEW).
7 * The Binary vIEW (BIEW) is copyright (C) 1995 Nickols_K.
8 * All rights reserved. This software is redistributable under the
9 * licence given in the file "Licence.en" ("Licence.ru" in russian
10 * translation) distributed in the BIEW archive.
11 * @note Requires POSIX compatible development system
12 *
13 * @author Nickols_K
14 * @since 1999
15 * @note Development, fixes and improvements
16 * @author Alexander Lokhan'ko <alex@eunet.lt>
17 * @date 28.03.2000
18 * @note fixing code for workaround of console input bug under Win9x
19 * tested on Win95 PE, OSR2, Win98
20 * @author Alexander Lokhan'ko <alex@eunet.lt>
21 * @date 04.04.2000
22 * @note removed slight delay in win9x console bug workaround code
23 * @warning May not work propertly under some Win32 releases
24 * @author Sergey Oblomov <hoopoepg@mail.ru>
25 * @date 28.05.2003
26 * @note reworked console's reader to enable clipboard pasting
27 * through SysMenu->Edit->Paste facility of window.
28 * @warning May not work propertly under some Win32 releases
29 * @bug Under WinNT does not return correct values for some
30 * combinations of keys (like CtrlBkSpace)
31 * @note added mouse wheel support for Win2k+ (emit Up/Down key event)
32 * @warning ONE WHEEL SUPPORTED ONLY :-/
33 * @bug Some wheel processing freezing found
34 * @author Andrew Golovnia
35 * @date 19.12.2003
36 **/
37 /* for cygwin - remove unnecessary includes */
38 #define _OLE_H
39 #define _OLE2_H
40 #include <windows.h>
41 #include <limits.h>
42 #include <string.h>
43 #include <stdlib.h>
44
45 #include "biewlib/kbd_code.h"
46 #include "biewlib/biewlib.h"
47
48 static int KB_Buff[64];
49 static unsigned char KB_freq = 0;
50 static int shiftkeys = 0;
51
52 #ifndef MOUSE_WHEELED
53 #define MOUSE_WHEELED 4 /*Windows NT and Windows Me/98/95: This value is not supported.*/
54 #endif
55
56 HANDLE hIn;
57 tBool hInputTrigger = False;
58 extern OSVERSIONINFO win32_verinfo;
59 static int is_win9x;
60 extern void __FASTCALL__ win32_readNextMessage( void );
61
62 static int __mou_nbtns;
63
is_VKCtrl(int code)64 static int __FASTCALL__ is_VKCtrl(int code)
65 {
66 return code == VK_MENU ||
67 code == VK_CONTROL ||
68 code == VK_SHIFT;
69 }
70
71 extern tAbsCoord win32_mx,win32_my;
72 extern int win32_mbuttons;
73
win32_readNextMessage(void)74 void __FASTCALL__ win32_readNextMessage( void )
75 {
76 //DWORD total_nread,i;
77 int vkeycode,keycode;
78 INPUT_RECORD ir;
79 DWORD nread;
80 hInputTrigger=False;
81
82 PeekConsoleInput( hIn, &ir, 1, &nread );
83 if( nread )
84 {
85 ReadConsoleInput(hIn,&ir,1,&nread);
86 //if(!nread) break; /* sometimes happen */
87 switch(ir.EventType)
88 {
89 case MOUSE_EVENT:
90 {
91 static int buttons = 0;
92 win32_mbuttons = ir.Event.MouseEvent.dwButtonState & 0xffff;
93 if( buttons != win32_mbuttons )
94 {
95 win32_mx = ir.Event.MouseEvent.dwMousePosition.X;
96 win32_my = ir.Event.MouseEvent.dwMousePosition.Y;
97 if(KB_freq < sizeof(KB_Buff)/sizeof(int)) KB_Buff[KB_freq++] = KE_MOUSE;
98 buttons = win32_mbuttons & 0xffff;
99 }
100 if( ir.Event.MouseEvent.dwEventFlags & MOUSE_WHEELED )
101 {
102 int wheel = ( (int)ir.Event.MouseEvent.dwButtonState ) >> 16;
103 if( wheel < 0 ) KB_Buff[KB_freq++] = KE_DOWNARROW;
104 if( wheel > 0 ) KB_Buff[KB_freq++] = KE_UPARROW;
105 }
106 }
107 return;
108 case KEY_EVENT:
109 {
110 shiftkeys = ir.Event.KeyEvent.dwControlKeyState;
111 vkeycode = ir.Event.KeyEvent.wVirtualKeyCode;
112
113 if( ir.Event.KeyEvent.wVirtualKeyCode == 27 && ir.Event.KeyEvent.wVirtualScanCode == 1 &&
114 !ir.Event.KeyEvent.uChar.AsciiChar )
115 ir.Event.KeyEvent.uChar.AsciiChar = ir.Event.KeyEvent.wVirtualKeyCode;
116
117 if(is_VKCtrl(vkeycode))
118 {
119 if(KB_freq < sizeof(KB_Buff)/sizeof(int)) KB_Buff[KB_freq++] = KE_SHIFTKEYS;
120 }
121 else
122 {
123 if( vkeycode < ' ' )
124 vkeycode = 0;
125 keycode = ((ir.Event.KeyEvent.wVirtualScanCode << 8) & 0xFF00) |
126 (ir.Event.KeyEvent.uChar.AsciiChar & 0xFF);
127 if(shiftkeys & SHIFT_PRESSED) keycode |= ADD_SHIFT;
128 else
129 if(shiftkeys & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) keycode |= ADD_CONTROL;
130 else
131 if(shiftkeys & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) keycode |= ADD_ALT;
132 if(keycode && ir.Event.KeyEvent.bKeyDown)
133 {if(KB_freq < sizeof(KB_Buff)/sizeof(int)) KB_Buff[KB_freq++] = keycode;}
134 else
135 if(KB_freq < sizeof(KB_Buff)/sizeof(int)) KB_Buff[KB_freq++] = KE_SHIFTKEYS;
136 }
137 }
138 return;
139 default: break;
140 }
141 // if(is_win9x && !is_read) ReadConsoleInput(hIn,&ir,1,&nread);
142 }
143 else if( win32_mbuttons )
144 {
145 if(KB_freq < sizeof(KB_Buff)/sizeof(int)) KB_Buff[KB_freq++] = KE_MOUSE;
146 }
147 else
148 Sleep( 1 );
149 }
150
__init_keyboard(const char * user_cp)151 void __FASTCALL__ __init_keyboard( const char *user_cp )
152 {
153 hIn = GetStdHandle(STD_INPUT_HANDLE);
154 is_win9x = win32_verinfo.dwMajorVersion == 4 &&
155 win32_verinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS;
156 if((__mou_nbtns = __init_mouse()) != INT_MAX)
157 {
158 __MsSetState(True);
159 }
160 }
161
__term_keyboard(void)162 void __FASTCALL__ __term_keyboard( void )
163 {
164 if(__mou_nbtns != INT_MAX)
165 {
166 __MsSetState(False);
167 __term_mouse();
168 }
169 }
170
__kbdTestKey(unsigned long flg)171 int __FASTCALL__ __kbdTestKey( unsigned long flg )
172 {
173 if(__MsGetBtns() && flg == KBD_NONSTOP_ON_MOUSE_PRESS) return KE_MOUSE;
174 if(hInputTrigger) win32_readNextMessage();
175 return KB_freq;
176 }
177
__kbdGetShiftsKey(void)178 int __FASTCALL__ __kbdGetShiftsKey( void )
179 {
180 int ret;
181 ret = 0;
182 if(hInputTrigger) win32_readNextMessage();
183 if(shiftkeys & SHIFT_PRESSED) ret |= KS_SHIFT;
184 if((shiftkeys & LEFT_ALT_PRESSED) || (shiftkeys & RIGHT_ALT_PRESSED)) ret |= KS_ALT;
185 if((shiftkeys & LEFT_CTRL_PRESSED) || (shiftkeys & RIGHT_CTRL_PRESSED)) ret |= KS_CTRL;
186 if(shiftkeys & CAPSLOCK_ON) ret |= KS_CAPSLOCK;
187 if(shiftkeys & NUMLOCK_ON) ret |= KS_NUMLOCK;
188 if(shiftkeys & SCROLLLOCK_ON) ret |= KS_SCRLOCK;
189 return ret;
190 }
191
__kbdGetKey(unsigned long flg)192 int __FASTCALL__ __kbdGetKey ( unsigned long flg )
193 {
194 int ret;
195 if(__MsGetBtns() && flg == KBD_NONSTOP_ON_MOUSE_PRESS) return KE_MOUSE;
196 while(!KB_freq) { /*__OsYield()*/; win32_readNextMessage(); }
197 ret = KB_Buff[0];
198 --KB_freq;
199 if(KB_freq) memmove(KB_Buff,&KB_Buff[1],KB_freq*sizeof(int));
200 return ret;
201 }
202