From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/di__keyboard__device_8cpp-source.html | 698 +++++++++++++++++++++ 1 file changed, 698 insertions(+) create mode 100644 docs/doxygen/nel/di__keyboard__device_8cpp-source.html (limited to 'docs/doxygen/nel/di__keyboard__device_8cpp-source.html') diff --git a/docs/doxygen/nel/di__keyboard__device_8cpp-source.html b/docs/doxygen/nel/di__keyboard__device_8cpp-source.html new file mode 100644 index 00000000..ca578d45 --- /dev/null +++ b/docs/doxygen/nel/di__keyboard__device_8cpp-source.html @@ -0,0 +1,698 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

di_keyboard_device.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000-2002 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 
+00027 
+00028 #include "stdmisc.h"
+00029 #include "misc/di_keyboard_device.h"
+00030 
+00031 #ifdef NL_OS_WINDOWS
+00032 
+00033 #include "nel/misc/win_event_emitter.h"
+00034 #include <memory>
+00035 #include <dinput.h>
+00036 #include <Winuser.h>
+00037 
+00038 #include "Mmsystem.h"
+00039 
+00040 
+00041 #ifdef min
+00042 #undef min
+00043 #endif
+00044 
+00045 #ifdef max
+00046 #undef max
+00047 #endif
+00048 
+00049 namespace NLMISC 
+00050 {
+00051 
+00052 // used to do a conversion from DX key code to Nel keys enums
+00053 struct CKeyConv
+00054 {
+00055         uint DIKey;
+00056         TKey NelKey;
+00057         const char *KeyName;
+00058         bool Repeatable;
+00059 };
+00060 
+00061 // this is used to build a conversion table
+00062 static const CKeyConv DIToNel[] =
+00063 {       
+00064         //
+00065         {DIK_F1, KeyF1, "F1", true},
+00066         {DIK_F2, KeyF2, "F2", true},
+00067         {DIK_F3, KeyF3, "F3", true},
+00068         {DIK_F4, KeyF4, "F4", true},
+00069         {DIK_F5, KeyF5, "F5", true},
+00070         {DIK_F6, KeyF6, "F6", true},
+00071         {DIK_F7, KeyF7, "F7", true},
+00072         {DIK_F8, KeyF8, "F8", true},
+00073         {DIK_F9, KeyF9, "F9", true},
+00074         {DIK_F10, KeyF10, "F10", true},
+00075         {DIK_F11, KeyF11, "F11", true},
+00076         {DIK_F12, KeyF12, "F12", true},
+00077         {DIK_F13, KeyF13, "F13", true},
+00078         {DIK_F14, KeyF14, "F14", true},
+00079         {DIK_F15, KeyF15, "F15", true},
+00080         //
+00081         {DIK_NUMPAD0, KeyNUMPAD0, "NUMPAD0", true},
+00082         {DIK_NUMPAD1, KeyNUMPAD1, "NUMPAD1", true},
+00083         {DIK_NUMPAD2, KeyNUMPAD2, "NUMPAD2", true},
+00084         {DIK_NUMPAD3, KeyNUMPAD3, "NUMPAD3", true},
+00085         {DIK_NUMPAD4, KeyNUMPAD4, "NUMPAD4", true},
+00086         {DIK_NUMPAD5, KeyNUMPAD5, "NUMPAD5", true},
+00087         {DIK_NUMPAD6, KeyNUMPAD6, "NUMPAD6", true},
+00088         {DIK_NUMPAD7, KeyNUMPAD7, "NUMPAD7", true},
+00089         {DIK_NUMPAD8, KeyNUMPAD8, "NUMPAD8", true},
+00090         {DIK_NUMPAD9, KeyNUMPAD9, "NUMPAD9", true},
+00091         //
+00092         {DIK_DIVIDE, KeyDIVIDE, "/", true},     
+00093         {DIK_DECIMAL, KeyDECIMAL, "NUMPAD .", true},
+00094         //
+00095         {DIK_LSHIFT, KeyLSHIFT, "LEFT SHIFT", false},
+00096         {DIK_RSHIFT, KeyRSHIFT, "RIGHT SHIFT", false},  
+00097         //
+00098         {DIK_LCONTROL, KeyLCONTROL, "LEFT CONTROL", false},
+00099         {DIK_RCONTROL, KeyRCONTROL, "RIGHT CONTROL", false},
+00100         //
+00101         {DIK_LMENU, KeyLMENU, "ALT", false},
+00102         {DIK_RMENU, KeyRMENU, "ALT GR", false},
+00103         //
+00104         {DIK_UP, KeyUP, "UP", true},
+00105         {DIK_PRIOR, KeyPRIOR, "PRIOR", true},
+00106         {DIK_LEFT, KeyLEFT, "LEFT", true},
+00107         {DIK_RIGHT, KeyRIGHT, "RIGHT", true},
+00108         {DIK_END, KeyEND, "END", true},
+00109         {DIK_DOWN, KeyDOWN, "DOWN", true},
+00110         {DIK_NEXT, KeyNEXT, "NEXT", true},
+00111         {DIK_INSERT, KeyINSERT, "INSERT", true},
+00112         {DIK_DELETE, KeyDELETE, "DELETE", true},
+00113         {DIK_HOME, KeyHOME, "HOME", true},
+00114         {DIK_LWIN, KeyLWIN, "LEFT WIN", false},
+00115         {DIK_RWIN, KeyRWIN, "RIGHT WIN", false},
+00116         {DIK_APPS, KeyAPPS, "APPS", false},             
+00117         //
+00118         {DIK_SYSRQ, KeySNAPSHOT, "SNAPSHOT", false},
+00119         {DIK_SCROLL, KeySCROLL, "SCROLL", false},
+00120         {DIK_PAUSE, KeyPAUSE, "PAUSE", false},
+00121         //      
+00122         {DIK_NUMLOCK, KeyNUMLOCK, "NUMLOCK", false},            
+00123         //
+00124         //{DIK_NUMPADENTER, KeyRETURN, "ENTER", true},
+00125         //
+00126         {DIK_CONVERT, KeyCONVERT, "CONVERT", false},
+00127         {DIK_NOCONVERT, KeyNONCONVERT, "NOCONVERT", true},
+00128         //
+00129         {DIK_KANA, KeyKANA, false},
+00130         {DIK_KANJI, KeyKANJI, false},
+00131 };
+00132 
+00133 
+00135 const CKeyConv  *CDIKeyboard::DIKeyToNelKeyTab[CDIKeyboard::NumKeys];
+00136 
+00138 CDIKeyboard::CDIKeyboard(CWinEventEmitter *we, HWND hwnd)       
+00139 :       _Keyboard(NULL),                
+00140         _WE(we),
+00141         ShiftPressed(false),
+00142         CtrlPressed(false),
+00143         AltPressed(false),
+00144         _CapsLockToggle(true),
+00145         _hWnd(hwnd),
+00146         _RepeatDelay(250),
+00147         _RepeatPeriod(200),
+00148         _FirstPressDate(-1),
+00149         _LastDIKeyPressed(0)
+00150 {               
+00151         if (::GetKeyboardState((PBYTE) _VKKeyState) == FALSE)
+00152         {
+00153                 std::fill(_VKKeyState, _VKKeyState + NumKeys, 0);
+00154         }
+00155         //      test wether the user toggle its keyboard with shift or not..
+00156         HKEY hKey;
+00157         if (::RegOpenKeyEx(HKEY_CURRENT_USER, "Keyboard Layout", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+00158         {
+00159                 DWORD type = REG_DWORD;
+00160                 DWORD value;
+00161                 DWORD size = sizeof(DWORD);
+00162                 if (::RegQueryValueEx(hKey, "Attributes", NULL, &type, (LPBYTE) &value, &size) == ERROR_SUCCESS)
+00163                 {
+00164                         _CapsLockToggle = (value & (1 << 16)) == 0;
+00165                 }
+00166                 ::RegCloseKey(hKey);
+00167         }
+00168         // get repeat delay and period
+00169         int keybDelay;
+00170         if (::SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &keybDelay, 0) != 0)
+00171         {
+00172                 _RepeatDelay = 250 + 250 * keybDelay;
+00173         }
+00174         DWORD keybSpeed;
+00175         if (::SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &keybSpeed, 0) != 0)
+00176         {
+00177                 _RepeatPeriod = (uint) (1000.f / (keybSpeed * (27.5f / 31.f) + 2.5f));
+00178         }
+00179         // get keyboard layout
+00180         _KBLayout = ::GetKeyboardLayout(NULL);
+00181 
+00182         _RepetitionDisabled.resize(NumKeys);    
+00183         _RepetitionDisabled.clearAll();
+00184 }
+00185 
+00187 void    CDIKeyboard::updateVKKeyState(uint diKey, bool pressed, TKey &keyValue, TKey &charValue)
+00188 {
+00189         bool extKey;
+00190         bool repeatable;
+00191         keyValue = DIKeyToNelKey(diKey, extKey, repeatable);
+00192         //
+00193         if (keyValue == 0)
+00194         {
+00195                 charValue = keyValue;
+00196                 return;
+00197         }
+00198         //
+00199         if (pressed)
+00200         {
+00201                 // check for toggle key 
+00202                 switch (keyValue)
+00203                 {                                               
+00204                         case KeyPAUSE:                  
+00205                         case KeyKANA:                   
+00206                         case KeyKANJI:                          
+00207                                 _VKKeyState[keyValue] ^= 0x01; // toggle first bit      
+00208                         break;
+00209                         case KeyCAPITAL:
+00210                                 if (_CapsLockToggle)
+00211                                 {
+00212                                         _VKKeyState[keyValue] ^= 0x01;
+00213                                         //toggleCapsLock(false);
+00214                                 }
+00215                                 else
+00216                                 {
+00217                                         if ((_VKKeyState[keyValue] & 0x01) == 0)
+00218                                         {
+00219                                                 _VKKeyState[keyValue] |= 0x01;
+00220                                                 //toggleCapsLock(false);
+00221                                         }
+00222                                 }
+00223                         break;
+00224                         case KeyNUMLOCK:
+00225                                 _VKKeyState[keyValue] ^= 0x01;
+00226                                 //setNumLock((_VKKeyState[keyValue] & 0x01) != 0);
+00227                         break;
+00228                         case KeySCROLL:
+00229                                 _VKKeyState[keyValue] ^= 0x01;
+00230                                 //toggleScrollLock();
+00231                         break;
+00232 
+00233                 }
+00234 
+00235                 _VKKeyState[keyValue] |= 0x80;
+00236         }
+00237         else
+00238         {
+00239                 _VKKeyState[keyValue] &= ~0x80;
+00240         }       
+00241         //
+00242         switch (keyValue)
+00243         {
+00244                 case KeyLSHIFT: charValue = KeySHIFT; break;
+00245                 case KeyRSHIFT: charValue = KeySHIFT; break;
+00246                 case KeyLCONTROL: charValue = KeyCONTROL; break;
+00247                 case KeyRCONTROL: charValue = KeyCONTROL; break;
+00248                 case KeyLMENU: charValue = KeyMENU; break;
+00249                 case KeyRMENU: charValue = KeyMENU; break;
+00250                 default: charValue = keyValue; break;
+00251         }
+00252         //
+00253         if (charValue == KeySHIFT && !_CapsLockToggle)
+00254         {
+00255                 if (_VKKeyState[KeyCAPITAL] & 0x01)
+00256                 {
+00257                         _VKKeyState[KeyCAPITAL] &= ~0x01;               
+00258                         //toggleCapsLock(true);
+00259                 }
+00260         }
+00261         //
+00262         if (charValue != keyValue)
+00263         {
+00264                 _VKKeyState[charValue] = _VKKeyState[keyValue];
+00265         }
+00266         //
+00267         updateCtrlAltShiftValues();     
+00268 }
+00269 
+00271 void    CDIKeyboard::updateCtrlAltShiftValues()
+00272 {
+00273         ShiftPressed = (_VKKeyState[KeySHIFT] & 0x80) != 0;
+00274         CtrlPressed = (_VKKeyState[KeyCONTROL] & 0x80) != 0;
+00275         AltPressed = (_VKKeyState[KeyMENU] & 0x80) != 0;
+00276 }
+00277 
+00279 CDIKeyboard::~CDIKeyboard()
+00280 {
+00281         if (_Keyboard) 
+00282         {
+00283                 _Keyboard->Unacquire();
+00284                 _Keyboard->Release();
+00285         }
+00286 }
+00287 
+00289 CDIKeyboard *CDIKeyboard::createKeyboardDevice(IDirectInput8 *di8,
+00290                                                                                            HWND hwnd,
+00291                                                                                            CDIEventEmitter *diEventEmitter,
+00292                                                                                            CWinEventEmitter *we
+00293                                                                                           ) throw(EDirectInput)
+00294 {
+00295         std::auto_ptr<CDIKeyboard> kb(new CDIKeyboard(we, hwnd));
+00296         kb->_DIEventEmitter = diEventEmitter;
+00297         HRESULT result = di8->CreateDevice(GUID_SysKeyboard, &kb->_Keyboard, NULL);
+00298         if (result != DI_OK) throw EDirectInputNoKeyboard();
+00299         result = kb->_Keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
+00300         if (result != DI_OK) throw EDirectInputCooperativeLevelFailed();
+00301         result = kb->_Keyboard->SetDataFormat(&c_dfDIKeyboard);
+00302         kb->setBufferSize(16);
+00303         kb->_Keyboard->Acquire();               
+00304         return kb.release();
+00305 }
+00306 
+00308 void CDIKeyboard::poll(CInputDeviceServer *dev)
+00309 {
+00310         nlassert(_Keyboard);
+00311         nlassert(_KeyboardBufferSize > 0);
+00312         static std::vector<DIDEVICEOBJECTDATA> datas;
+00313         datas.resize(_KeyboardBufferSize);
+00314         DWORD numElements = _KeyboardBufferSize;
+00315         HRESULT result = _Keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &datas[0], &numElements, 0);
+00316         if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
+00317         {
+00318                 result = _Keyboard->Acquire();
+00319                 if (result != DI_OK) return;
+00320                 // get device state
+00321                 ::GetKeyboardState((unsigned char *) _VKKeyState);
+00322                 _LastDIKeyPressed = 0;          
+00323                 updateCtrlAltShiftValues();
+00324                 result = _Keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &datas[0], &numElements, 0);
+00325                 if (result != DI_OK) return;
+00326         }
+00327         else if (result != DI_OK)
+00328         {       
+00329                 return;
+00330         }
+00331         
+00332         _PollTime = (uint32) CTime::getLocalTime();
+00333                 
+00334 
+00335         // process each message in the list
+00336         for     (uint k = 0; k < numElements; ++k)
+00337         {
+00338                 CDIEvent *die = new CDIEvent;
+00339                 die->Emitter = this;
+00340                 die->Datas = datas[k];
+00341                 dev->submitEvent(die);
+00342         }
+00343 }
+00344 
+00346 void    CDIKeyboard::transitionOccured(CEventServer *server, const IInputDeviceEvent *nextMessage)
+00347 {       
+00348         repeatKey(buildDateFromEvent(nextMessage), server);
+00349 }
+00350 
+00352 TKeyButton CDIKeyboard::buildKeyButtonsFlags() const
+00353 {
+00354         return (TKeyButton) ( (ShiftPressed   ? shiftKeyButton : 0)
+00355                                                   | (CtrlPressed  ? altKeyButton   : 0)
+00356                                                   | (AltPressed   ? ctrlKeyButton  : 0)
+00357                                                 );
+00358 }
+00359 
+00361 void CDIKeyboard::keyTriggered(bool pressed, uint dikey, CEventServer *server, uint32 date)
+00362 {
+00363         #if 0           
+00364                 const uint numPairs = sizeof(DIToNel) / sizeof(CKeyConv);
+00365                 for (uint k = 0; k < numPairs; ++k)
+00366                 {
+00367                         if (DIToNel[k].DIKey == key)
+00368                         {
+00369                                 nlinfo(DIToNel[k].KeyName);
+00370                         }
+00371                 }
+00372         #endif
+00373         
+00374         
+00375         TKey keyValue, charValue;               
+00376         updateVKKeyState(dikey, pressed, keyValue, charValue);
+00377         if (keyValue == 0) return;
+00378 
+00379         CEventKey *ek;
+00380         if (pressed ) ek = new CEventKeyDown(keyValue, buildKeyButtonsFlags(), false, _DIEventEmitter);
+00381                                  else ek = new CEventKeyUp(keyValue, buildKeyButtonsFlags(), _DIEventEmitter);
+00382         server->postEvent(ek);
+00383 
+00384         if (pressed)
+00385         {
+00386                 if (_RepetitionDisabled[(uint) keyValue] == false)
+00387                 {
+00388                         _LastEmitDate = _FirstPressDate = date;
+00389                         _LastDIKeyPressed = dikey;
+00390                 }
+00391                 else // not a repeatable key
+00392                 {
+00393                         _LastDIKeyPressed = 0;
+00394                         return;
+00395                 }
+00396         }
+00397         else
+00398         {
+00399                 // key released ?
+00400                 if (dikey == _LastDIKeyPressed)
+00401                 {
+00402                         _LastDIKeyPressed = 0;
+00403                 }
+00404                 
+00405                 if (_RepetitionDisabled[(uint) keyValue] == true)
+00406                 {
+00407                         return;
+00408                 }
+00409         }
+00410 
+00411         // first char event (if repetition not disabled)        
+00412         if (keyValue >= KeyNUMPAD0 && keyValue <= KeyNUMPAD9 || keyValue == KeyDECIMAL)
+00413         {
+00414                 if ((_VKKeyState[KeyNUMLOCK] & 0x01) != 0)
+00415                 {
+00416                         sendUnicode(charValue, dikey, server, pressed);
+00417                 }
+00418         }
+00419         else
+00420         {
+00421                 sendUnicode(charValue, dikey, server, pressed);
+00422         }       
+00423         
+00424         _FirstPressDate  = date;        
+00425 }
+00426 
+00428 void CDIKeyboard::submit(IInputDeviceEvent *deviceEvent, CEventServer *server)
+00429 {
+00430         CDIEvent *die = safe_cast<CDIEvent *>(deviceEvent);
+00431         bool pressed = (die->Datas.dwData & 0x80) != 0; 
+00432         keyTriggered(pressed, (uint) die->Datas.dwOfs, server, die->Datas.dwTimeStamp);                 
+00433 }
+00434 
+00436 TMouseButton    CDIKeyboard::buildKeyboardButtonFlags() const
+00437 {
+00438         nlassert(_Keyboard);
+00439         return _DIEventEmitter->buildKeyboardButtonFlags();
+00440 }
+00441 
+00443 bool    CDIKeyboard::setBufferSize(uint size)
+00444 {
+00445         nlassert(size > 0);
+00446         nlassert(_Keyboard);
+00447         _Keyboard->Unacquire(); 
+00448         DIPROPDWORD dipdw;
+00449     dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
+00450     dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+00451     dipdw.diph.dwObj        = 0;
+00452     dipdw.diph.dwHow        = DIPH_DEVICE;
+00453     dipdw.dwData            = size;
+00454         HRESULT                                 r = _Keyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph );
+00455         if (r != DI_OK)                 return false;   
+00456         _KeyboardBufferSize = size;
+00457         return true;
+00458 }
+00459 
+00461 uint    CDIKeyboard::getBufferSize() const
+00462 {
+00463         return _KeyboardBufferSize;
+00464 }
+00465 
+00467 TKey CDIKeyboard::DIKeyToNelKey(uint diKey, bool &extKey, bool &repeatable)
+00468 {       
+00469         // some key are not handled by MapVirtualKeyEx so we need to convert them ourselves
+00470         static tableBuilt = false;
+00471 
+00472         if (!tableBuilt)
+00473         {
+00474                 uint k;
+00475                 for (k = 0; k < NumKeys; ++k)
+00476                 {
+00477                         DIKeyToNelKeyTab[k] = NULL; // set as not a valid key by default
+00478                 }
+00479                 const uint numPairs = sizeof(DIToNel) / sizeof(CKeyConv);
+00480                 for (k = 0; k < numPairs; ++k)
+00481                 {       
+00482                         DIKeyToNelKeyTab[DIToNel[k].DIKey] = &DIToNel[k];
+00483                 }                       
+00484                 tableBuilt = true;
+00485         }
+00486         
+00487 
+00488         //
+00489         if (DIKeyToNelKeyTab[diKey] != NULL)
+00490         {                       
+00491                 const CKeyConv &keyConv = *DIKeyToNelKeyTab[diKey];             
+00492                 extKey     = true;
+00493                 repeatable = keyConv.Repeatable;
+00494                 return keyConv.NelKey;
+00495         }       
+00496 
+00497 
+00498 
+00499         // try doing the conversion using MapVirtualKey         
+00500         TKey key = (TKey) ::MapVirtualKeyEx(diKey, 1, _KBLayout);       
+00501         extKey = false;
+00502         return key;
+00503 }
+00504         
+00506 void    CDIKeyboard::sendUnicode(TKey vkey, uint dikey, CEventServer *server, bool pressed)
+00507 {       
+00508         const uint maxNumKeys = 8;
+00509         WCHAR keyUnicodes[maxNumKeys];                                  
+00510         uint8 oldShift = _VKKeyState[KeySHIFT];
+00512         if (!_CapsLockToggle && _VKKeyState[KeyCAPITAL] & 0x01)
+00513         {               
+00514                 _VKKeyState[KeySHIFT] = 0;
+00515         }
+00516         //
+00517         int res = ::ToUnicodeEx(vkey, dikey | (pressed ? 0 : (1 << 15)), (unsigned char *) _VKKeyState, keyUnicodes, maxNumKeys, 0, _KBLayout);
+00518         //
+00519         _VKKeyState[KeySHIFT] = oldShift;
+00520         //
+00521         for (sint k = 0; k < res; ++k)
+00522         {
+00523                 CEventChar *evc = new CEventChar((ucchar) keyUnicodes[k], buildKeyButtonsFlags(), _DIEventEmitter);
+00524                 server->postEvent(evc);
+00525         }
+00526 }
+00527 
+00529 void    CDIKeyboard::repeatKey(uint32 currentDate, CEventServer *server)
+00530 {       
+00531         if (_LastDIKeyPressed == 0 || _LastDIKeyPressed == DIK_INSERT) return;
+00532         bool extKey;
+00533         bool repeatable;
+00534         TKey vkey = DIKeyToNelKey(_LastDIKeyPressed, extKey, repeatable);
+00535         if (vkey == 0) return;  
+00536         if (currentDate - _FirstPressDate < _RepeatDelay) return;       
+00537 
+00538         sint32 firstDate = _LastEmitDate - (_FirstPressDate + _RepeatDelay);
+00539         sint32 lastDate = currentDate - (_FirstPressDate + _RepeatDelay);
+00540         if (firstDate < 0) firstDate = 0;
+00541 
+00542         if (lastDate < firstDate) return;
+00543         
+00544         uint numRep = (uint) ((lastDate + _RepeatPeriod - 1) / _RepeatPeriod  - (firstDate + _RepeatPeriod - 1) / _RepeatPeriod);       
+00545         numRep = std::min(16u, numRep); // too much repetitions don't make sense...
+00546         if ((sint) numRep < 0) return; // 50 days loop..
+00547 
+00548         
+00549         // numpad case
+00550         if (vkey >= KeyNUMPAD0 && vkey <= KeyNUMPAD9 || vkey == KeyDECIMAL)
+00551         {
+00552                 // check wether numlock is activated
+00553                 if ((_VKKeyState[KeyNUMLOCK] & 0x01) != 0)
+00554                 {
+00555                         for (uint k = 0; k < numRep; ++k)
+00556                         {       
+00557                                 sendUnicode(vkey, _LastDIKeyPressed, server, true);
+00558                         }
+00559                 }
+00560                 else
+00561                 {
+00562                         // arrow, home, end.. events
+00563                         for (uint k = 0; k < numRep; ++k)
+00564                         {       
+00565                                 CEventKey *ek = new CEventKeyDown(vkey, buildKeyButtonsFlags(), true, _DIEventEmitter);
+00566                                 server->postEvent(ek);
+00567                         }
+00568                 }
+00569         }
+00570         else
+00571         {
+00572                 for (uint k = 0; k < numRep; ++k)
+00573                 {
+00574                         // if it is an extended key, repetition won't be managed by sendUnicode
+00575                         if (extKey && repeatable)
+00576                         {
+00577                                 CEventKey *ek = new CEventKeyDown(vkey, buildKeyButtonsFlags(), true, _DIEventEmitter);
+00578                                 server->postEvent(ek);
+00579                         }
+00580                         else
+00581                         {
+00582                                 sendUnicode(vkey, _LastDIKeyPressed, server, true);
+00583                         }                       
+00584                 }
+00585         }
+00586         
+00587         _LastEmitDate = currentDate;
+00588 }
+00589 
+00591 uint32  CDIKeyboard::buildDateFromEvent(const IInputDeviceEvent *deviceEvent)
+00592 {
+00593         if (deviceEvent)
+00594         {
+00595                 const CDIEvent *die = safe_cast<const CDIEvent *>(deviceEvent);
+00596                 return (uint32) die->Datas.dwData;
+00597         }
+00598         else
+00599         {
+00600                 return _PollTime;       
+00601         }
+00602 }
+00603 
+00605 void CDIKeyboard::disableRepetition(const TKey *keyTab, uint numKey)
+00606 {
+00607         _RepetitionDisabled.clearAll();
+00608         for (uint k = 0; k < numKey; ++k)
+00609         {
+00610                 _RepetitionDisabled.set((sint) keyTab[k]);
+00611         }
+00612 
+00613         if (_LastDIKeyPressed != 0)
+00614         {
+00615                 bool extKey;
+00616                 bool repeatable;
+00617                 TKey key = DIKeyToNelKey(_LastDIKeyPressed, extKey, repeatable);
+00618                 if (_RepetitionDisabled[(uint) key])
+00619                 {
+00620                         // disable this key repetition
+00621                         _LastDIKeyPressed = 0;
+00622                 }
+00623         }
+00624 }
+00625 
+00627 uint CDIKeyboard::getNumDisabledRepetition() const
+00628 {
+00629         uint numKey = 0;
+00630         for (uint k = 0; k < NumKeys; ++k)
+00631         {
+00632                 if (_RepetitionDisabled[k]) ++numKey;
+00633         }
+00634         return numKey;
+00635 }
+00636 
+00638 void CDIKeyboard::getDisabledRepetitions(TKey *destTab) const
+00639 {
+00640         for (uint k = 0; k < NumKeys; ++k)
+00641         {
+00642                 if (_RepetitionDisabled[k]) *destTab++ = (TKey) k;
+00643         }
+00644 }
+00645 
+00646 
+00647 
+00648 } // NLMISC
+00649 
+00650 
+00651 #endif NL_OS_WINDOWS
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1