00001 #include "../pch.h"
00002
00003 #ifndef HID_USAGE_PAGE_GENERIC
00004 #define HID_USAGE_PAGE_GENERIC ((USHORT) 0x01)
00005 #endif
00006 #ifndef HID_USAGE_GENERIC_MOUSE
00007 #define HID_USAGE_GENERIC_MOUSE ((USHORT) 0x02)
00008 #endif
00009 #ifndef HID_USAGE_GENERIC_KEYBOARD
00010 #define HID_USAGE_GENERIC_KEYBOARD ((USHORT) 0x06)
00011 #endif
00012
00013 NAMESPACE_START
00014
00015 THREADFUNCTION(inputThreadFunction, window){
00016 ((InputWindow*)window)->loop();
00017 RETURN(0);
00018 }
00019
00020 InputWindow::InputWindow()
00021 : inputThread()
00022 {
00023 run = false;
00024 ended = true;
00025 initialized = 0;
00026 }
00027
00028 InputWindow::~InputWindow(){
00029 uninit();
00030 }
00031
00032 void InputWindow::init(void){
00033 if(initialized++ > 0)
00034 return;
00035 initMouseMap();
00036 initKeyboardMap();
00037 inputThread.start(inputThreadFunction, this, 128, 1);
00038 }
00039
00040 void InputWindow::uninit(void){
00041 if(--initialized == 0){
00042 close();
00043 if(inputThread.valid()){
00044 while(ended == false)
00045 ::wait(1);
00046 inputThread.end();
00047 }
00048 }
00049 }
00050
00051 void InputWindow::loop(void){
00052 MSG msg;
00053 memset(&msg,0,sizeof(MSG));
00054
00055 wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
00056 wndClass.lpfnWndProc = inputMessageHandler;
00057 wndClass.cbClsExtra = 0;
00058 wndClass.cbWndExtra = 0;
00059 wndClass.hInstance = 0;
00060 wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
00061 wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
00062 wndClass.hbrBackground = 0;
00063 wndClass.lpszMenuName = 0;
00064 wndClass.lpszClassName = TEXT("RVInputWindow");
00065 RegisterClass(&wndClass);
00066 inputWnd = CreateWindowEx(WS_EX_APPWINDOW, TEXT("RVInputWindow"), TEXT(""), WS_OVERLAPPED, 0, 0, 0, 0, 0, 0, 0, 0);
00067
00068 if(inputWnd == 0)
00069 return;
00070
00071 initKeyboardMap();
00072 run = true;
00073 ended = false;
00074
00075
00076 while(run){
00077 while(PeekMessage(&msg, inputWnd, 0, 0, PM_REMOVE)){
00078 if(msg.message == WM_INPUT){
00079 handleRawInput((HRAWINPUT)msg.lParam);
00080 }else{
00081 TranslateMessage(&msg);
00082 DispatchMessage(&msg);
00083 }
00084 }
00085 ::wait(1);
00086 }
00087
00088
00089 while(PeekMessage(&msg, inputWnd, 0, 0, PM_REMOVE)){
00090 TranslateMessage(&msg);
00091 DispatchMessage(&msg);
00092 ::wait(1);
00093 }
00094
00095 if(inputWnd){
00096 DestroyWindow(inputWnd);
00097 inputWnd = 0;
00098 }
00099 UnregisterClass(TEXT("RVInputWindow"), 0);
00100
00101 ended = true;
00102 }
00103
00104 void InputWindow::close(void){
00105 run = false;
00106 }
00107
00108 void InputWindow::initMouseMap(void){
00109 mouseMap.mouseNone = 0;
00110 mouseMap.mouseL = 1;
00111 mouseMap.mouseM = 2;
00112 mouseMap.mouseR = 3;
00113 mouseMap.mouse4 = 4;
00114 mouseMap.mouse5 = 5;
00115 }
00116
00117 void InputWindow::initKeyboardMap(void){
00118 keyboardMap.keyBackspace = ::KEYBTN(VK_BACK);
00119 keyboardMap.keyTab = ::KEYBTN(VK_TAB);
00120 keyboardMap.keyClear = ::KEYBTN(VK_CLEAR);
00121 keyboardMap.keyReturn = ::KEYBTN(VK_RETURN);
00122 keyboardMap.keyCapital = ::KEYBTN(VK_CAPITAL);
00123 keyboardMap.keyEsc = ::KEYBTN(VK_ESCAPE);
00124 keyboardMap.keyBegin = ::KEYBTN(VK_HOME);
00125 keyboardMap.keyEnd = ::KEYBTN(VK_END);
00126 keyboardMap.keyPageUp = ::KEYBTN(VK_PRIOR);
00127 keyboardMap.keyPageDown = ::KEYBTN(VK_NEXT);
00128 keyboardMap.keyLeft = ::KEYBTN(VK_LEFT);
00129 keyboardMap.keyUp = ::KEYBTN(VK_UP);
00130 keyboardMap.keyRight = ::KEYBTN(VK_RIGHT);
00131 keyboardMap.keyDown = ::KEYBTN(VK_DOWN);
00132 keyboardMap.keyPrint = ::KEYBTN(VK_SNAPSHOT);
00133 keyboardMap.keyInsert = ::KEYBTN(VK_INSERT);
00134 keyboardMap.keyDelete = ::KEYBTN(VK_DELETE);
00135 keyboardMap.keySpace = ::KEYBTN(VK_SPACE);
00136 keyboardMap.keyExclam = ::KEYBTN(0);
00137 keyboardMap.keyQuotedbl = ::KEYBTN(0);
00138 keyboardMap.keyNumbersign = ::KEYBTN(0);
00139 keyboardMap.keyAsterisk = ::KEYBTN(0);
00140 keyboardMap.keyPlus = ::KEYBTN(0);
00141 keyboardMap.keyComma = ::KEYBTN(0);
00142 keyboardMap.keyMinus = ::KEYBTN(0);
00143 keyboardMap.keyPeriod = ::KEYBTN(0);
00144 keyboardMap.keySlash = ::KEYBTN(0);
00145 keyboardMap.key0 = ::KEYBTN('0');
00146 keyboardMap.key1 = ::KEYBTN('1');
00147 keyboardMap.key2 = ::KEYBTN('2');
00148 keyboardMap.key3 = ::KEYBTN('3');
00149 keyboardMap.key4 = ::KEYBTN('4');
00150 keyboardMap.key5 = ::KEYBTN('5');
00151 keyboardMap.key6 = ::KEYBTN('6');
00152 keyboardMap.key7 = ::KEYBTN('7');
00153 keyboardMap.key8 = ::KEYBTN('8');
00154 keyboardMap.key9 = ::KEYBTN('9');
00155 keyboardMap.keyA = ::KEYBTN('A');
00156 keyboardMap.keyB = ::KEYBTN('B');
00157 keyboardMap.keyC = ::KEYBTN('C');
00158 keyboardMap.keyD = ::KEYBTN('D');
00159 keyboardMap.keyE = ::KEYBTN('E');
00160 keyboardMap.keyF = ::KEYBTN('F');
00161 keyboardMap.keyG = ::KEYBTN('G');
00162 keyboardMap.keyH = ::KEYBTN('H');
00163 keyboardMap.keyI = ::KEYBTN('I');
00164 keyboardMap.keyJ = ::KEYBTN('J');
00165 keyboardMap.keyK = ::KEYBTN('K');
00166 keyboardMap.keyL = ::KEYBTN('L');
00167 keyboardMap.keyM = ::KEYBTN('M');
00168 keyboardMap.keyN = ::KEYBTN('N');
00169 keyboardMap.keyO = ::KEYBTN('O');
00170 keyboardMap.keyP = ::KEYBTN('P');
00171 keyboardMap.keyQ = ::KEYBTN('Q');
00172 keyboardMap.keyR = ::KEYBTN('R');
00173 keyboardMap.keyS = ::KEYBTN('S');
00174 keyboardMap.keyT = ::KEYBTN('T');
00175 keyboardMap.keyU = ::KEYBTN('U');
00176 keyboardMap.keyV = ::KEYBTN('V');
00177 keyboardMap.keyW = ::KEYBTN('W');
00178 keyboardMap.keyX = ::KEYBTN('X');
00179 keyboardMap.keyY = ::KEYBTN('Y');
00180 keyboardMap.keyZ = ::KEYBTN('Z');
00181 keyboardMap.keyNum0 = ::KEYBTN(VK_NUMPAD0);
00182 keyboardMap.keyNum1 = ::KEYBTN(VK_NUMPAD1);
00183 keyboardMap.keyNum2 = ::KEYBTN(VK_NUMPAD2);
00184 keyboardMap.keyNum3 = ::KEYBTN(VK_NUMPAD3);
00185 keyboardMap.keyNum4 = ::KEYBTN(VK_NUMPAD4);
00186 keyboardMap.keyNum5 = ::KEYBTN(VK_NUMPAD5);
00187 keyboardMap.keyNum6 = ::KEYBTN(VK_NUMPAD6);
00188 keyboardMap.keyNum7 = ::KEYBTN(VK_NUMPAD7);
00189 keyboardMap.keyNum8 = ::KEYBTN(VK_NUMPAD8);
00190 keyboardMap.keyNum9 = ::KEYBTN(VK_NUMPAD9);
00191 keyboardMap.keyNumMul = ::KEYBTN(VK_MULTIPLY);
00192 keyboardMap.keyNumAdd = ::KEYBTN(VK_ADD);
00193 keyboardMap.keyNumSub = ::KEYBTN(VK_SUBTRACT);
00194 keyboardMap.keyNumDiv = ::KEYBTN(VK_DIVIDE);
00195 keyboardMap.keyNumDecimal = ::KEYBTN(VK_DECIMAL);
00196 keyboardMap.keyNumSeperator = ::KEYBTN(VK_SEPARATOR);
00197 keyboardMap.keyF1 = ::KEYBTN(VK_F1);
00198 keyboardMap.keyF2 = ::KEYBTN(VK_F2);
00199 keyboardMap.keyF3 = ::KEYBTN(VK_F3);
00200 keyboardMap.keyF4 = ::KEYBTN(VK_F4);
00201 keyboardMap.keyF5 = ::KEYBTN(VK_F5);
00202 keyboardMap.keyF6 = ::KEYBTN(VK_F6);
00203 keyboardMap.keyF7 = ::KEYBTN(VK_F7);
00204 keyboardMap.keyF8 = ::KEYBTN(VK_F8);
00205 keyboardMap.keyF9 = ::KEYBTN(VK_F9);
00206 keyboardMap.keyF10 = ::KEYBTN(VK_F10);
00207 keyboardMap.keyF11 = ::KEYBTN(VK_F11);
00208 keyboardMap.keyF12 = ::KEYBTN(VK_F12);
00209 keyboardMap.keyNumLock = ::KEYBTN(VK_NUMLOCK);
00210 keyboardMap.keyScroll = ::KEYBTN(VK_SCROLL);
00211 keyboardMap.keyLogoL = ::KEYBTN(VK_LWIN);
00212 keyboardMap.keyLogoR = ::KEYBTN(VK_RWIN);
00213 keyboardMap.keyShiftL = ::KEYBTN(VK_LSHIFT);
00214 keyboardMap.keyShiftR = ::KEYBTN(VK_RSHIFT);
00215 keyboardMap.keyCtrlL = ::KEYBTN(VK_LCONTROL);
00216 keyboardMap.keyCtrlR = ::KEYBTN(VK_RCONTROL);
00217 keyboardMap.keyMenuL = ::KEYBTN(VK_LMENU);
00218 keyboardMap.keyMenuR = ::KEYBTN(VK_RMENU);
00219 keyboardMap.keyAltL = ::KEYBTN(0);
00220 keyboardMap.keyAltR = ::KEYBTN(0);
00221 keyboardMap.keyMetaL = ::KEYBTN(0);
00222 keyboardMap.keyMetaR = ::KEYBTN(0);
00223 }
00224
00225 bool InputWindow::activateInput(::DEVICE type){
00226 uint numRID = 1;
00227 RAWINPUTDEVICE rid[2];
00228 switch(type){
00229 case ::deviceMouseHID:
00230 rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
00231 rid[0].usUsage = 0x01;
00232 rid[0].dwFlags = RIDEV_INPUTSINK;
00233 rid[0].hwndTarget = inputWnd;
00234 break;
00235 case ::deviceMouse:
00236 rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
00237 rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
00238 rid[0].dwFlags = RIDEV_INPUTSINK;
00239 rid[0].hwndTarget = inputWnd;
00240 rid[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
00241 rid[1].usUsage = HID_USAGE_GENERIC_MOUSE;
00242 rid[1].dwFlags = RIDEV_NOLEGACY;
00243 rid[1].hwndTarget = 0;
00244 numRID = 2;
00245 break;
00246 case ::deviceKeyboard:
00247 rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
00248 rid[0].usUsage = HID_USAGE_GENERIC_KEYBOARD;
00249 rid[0].dwFlags = RIDEV_INPUTSINK;
00250 rid[0].hwndTarget = inputWnd;
00251 rid[1].usUsagePage = HID_USAGE_PAGE_GENERIC;
00252 rid[1].usUsage = HID_USAGE_GENERIC_KEYBOARD;
00253 rid[1].dwFlags = RIDEV_NOLEGACY;
00254 rid[1].hwndTarget = 0;
00255 numRID = 2;
00256 break;
00257 case ::deviceKeypad:
00258 rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
00259 rid[0].usUsage = 0x07;
00260 rid[0].dwFlags = RIDEV_INPUTSINK;
00261 rid[0].hwndTarget = inputWnd;
00262 break;
00263
00264
00265
00266
00267 default: return false;
00268 }
00269 if(RegisterRawInputDevices(rid, 1, sizeof(RAWINPUTDEVICE)) == FALSE){
00270 LOGLN("Window::activateDevices: Device could not be activated!");
00271 return false;
00272 }
00273 return true;
00274 }
00275
00276 void InputWindow::deactivateInput(::DEVICE type){
00277 RAWINPUTDEVICE rid;
00278 switch(type){
00279 case ::deviceMouse:
00280 rid.usUsagePage = HID_USAGE_PAGE_GENERIC;
00281 rid.usUsage = 0x01;
00282 rid.dwFlags = RIDEV_REMOVE;
00283 rid.hwndTarget = 0;
00284 break;
00285 case ::deviceMouseHID:
00286 rid.usUsagePage = HID_USAGE_PAGE_GENERIC;
00287 rid.usUsage = HID_USAGE_GENERIC_MOUSE;
00288 rid.dwFlags = RIDEV_REMOVE;
00289 rid.hwndTarget = 0;
00290 break;
00291 case ::deviceKeyboard:
00292 rid.usUsagePage = HID_USAGE_PAGE_GENERIC;
00293 rid.usUsage = HID_USAGE_GENERIC_KEYBOARD;
00294 rid.dwFlags = RIDEV_REMOVE;
00295 rid.hwndTarget = 0;
00296 break;
00297 case ::deviceKeypad:
00298 rid.usUsagePage = HID_USAGE_PAGE_GENERIC;
00299 rid.usUsage = 0x07;
00300 rid.dwFlags = RIDEV_REMOVE;
00301 rid.hwndTarget = 0;
00302 break;
00303 default: return;
00304 }
00305 if(RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == FALSE)
00306 LOGLN("Window::activateDevices: Device could not be deactivated!");
00307 }
00308
00309 uint InputWindow::getDevices(::DeviceInfo* array, uint size){
00310 uint deviceCount = 0;
00311 uint dwSize = sizeof(RAWINPUTDEVICELIST);
00312
00313 if(GetRawInputDeviceList(0, &deviceCount, dwSize) != 0)
00314 return 0;
00315
00316 RAWINPUTDEVICELIST rid[16];
00317 deviceCount = deviceCount>16?16:deviceCount;
00318 GetRawInputDeviceList(rid, &deviceCount, dwSize);
00319
00320 uint i; for(i=0; i<deviceCount && i<size; i++){
00321 RID_DEVICE_INFO info;
00322 uint infoSize = 0;
00323
00324 array[i].ID = int(rid[i].hDevice);
00325
00326 GetRawInputDeviceInfo(rid[i].hDevice, RIDI_DEVICEINFO, 0, &infoSize);
00327 if(infoSize > 0){
00328 info.cbSize = sizeof(RID_DEVICE_INFO);
00329 if(GetRawInputDeviceInfo(rid[i].hDevice, RIDI_DEVICEINFO, &info, &infoSize) < 0){
00330 array[i].type = ::deviceUnknown;
00331 }else{
00332 switch(info.dwType){
00333 case RIM_TYPEHID: array[i].type = ::deviceHID; break;
00334 case RIM_TYPEKEYBOARD: array[i].type = ::deviceKeyboard; break;
00335 case RIM_TYPEMOUSE: array[i].type = ::deviceMouse; break;
00336 default: array[i].type = ::deviceUnknown; break;
00337 }
00338 }
00339 }
00340
00341 GetRawInputDeviceInfo(rid[i].hDevice, RIDI_DEVICENAME, 0, &infoSize);
00342 if(infoSize > 0){
00343 infoSize = infoSize>WindowDeviceNameLen?WindowDeviceNameLen:infoSize;
00344 if(GetRawInputDeviceInfo(rid[i].hDevice, RIDI_DEVICENAME, array[i].name, &infoSize) < 0)
00345 array[i].name[0] = 0;
00346 }
00347 }
00348
00349 return i;
00350 }
00351
00352 ::pDevice InputWindow::activateDevice(::DEVICE type, int ID){
00353 MouseDevice mouseDevice;
00354 KeyboardDevice keyboardDevice;
00355 switch(type){
00356 case ::deviceMouse:
00357 case ::deviceMouseHID:
00358 mouseDevice.ID = ID;
00359 if(mouseDevices.add(mouseDevice))
00360 return mouseDevices.getRef(mouseDevices.size()-1).asDevice();
00361 break;
00362 case ::deviceKeypad:
00363 case ::deviceKeyboard:
00364 keyboardDevice.ID = ID;
00365 if(keyboardDevices.add(keyboardDevice))
00366 return keyboardDevices.getRef(keyboardDevices.size()-1).asDevice();
00367 break;
00368 default:
00369 break;
00370 }
00371 return 0;
00372 }
00373
00374 void InputWindow::deactivateDevice(::pDevice device){
00375 if(device == 0)
00376 return;
00377
00378 if(device->isMouse()){
00379 mouseDevices.remove(*(MouseDevice*)device);
00380 }else if(device->isKeyboard()){
00381 keyboardDevices.remove(*(KeyboardDevice*)device);
00382 }
00383 }
00384
00385 LRESULT CALLBACK InputWindow::inputMessageHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
00386 return msg == WM_INPUT ? 0 : DefWindowProc(hWnd, msg, wParam, lParam);
00387 }
00388
00389 NAMESPACE_END