# 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