00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Win32/Win32InputManager.h"
00024 #include "Win32/Win32KeyBoard.h"
00025 #include "OISException.h"
00026 #include "OISEvents.h"
00027 #include <sstream>
00028
00029 using namespace OIS;
00030
00031
00032 Win32Keyboard::Win32Keyboard( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings )
00033 {
00034 mCreator = creator;
00035 mBuffered = buffered;
00036 mKeyboard = 0;
00037 mDirectInput = pDI;
00038 coopSetting = coopSettings;
00039 mType = OISKeyboard;
00040 listener = 0;
00041
00042
00043 memset( &KeyBuffer, 0, 256 );
00044 deadKey = '\0';
00045 }
00046
00047
00048 void Win32Keyboard::_initialize()
00049 {
00050 mModifiers = 0;
00051 deadKey = '\0';
00052
00053 if(FAILED(mDirectInput->CreateDevice(GUID_SysKeyboard, &mKeyboard, NULL)))
00054 OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> Could not init device!");
00055
00056 if(FAILED(mKeyboard->SetDataFormat(&c_dfDIKeyboard)))
00057 OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> format error!");
00058
00059 HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle();
00060
00061 if(FAILED(mKeyboard->SetCooperativeLevel( hwin, coopSetting)))
00062 OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> coop error!");
00063
00064 if( mBuffered )
00065 {
00066 DIPROPDWORD dipdw;
00067 dipdw.diph.dwSize = sizeof(DIPROPDWORD);
00068 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
00069 dipdw.diph.dwObj = 0;
00070 dipdw.diph.dwHow = DIPH_DEVICE;
00071 dipdw.dwData = KEYBOARD_DX_BUFFERSIZE;
00072
00073 if (FAILED(mKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph )))
00074 OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> buffer error!");
00075 }
00076
00077 HRESULT hr = mKeyboard->Acquire();
00078 if(FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO)
00079 OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> aquire error!");
00080 }
00081
00082
00083 Win32Keyboard::~Win32Keyboard()
00084 {
00085 if(mKeyboard)
00086 {
00087 mKeyboard->Unacquire();
00088 mKeyboard->Release();
00089 mKeyboard = 0;
00090 }
00091 }
00092
00093
00094 void Win32Keyboard::capture()
00095 {
00096 if( mBuffered )
00097 _readBuffered();
00098 else
00099 _read();
00100 }
00101
00102
00103 void Win32Keyboard::_readBuffered()
00104 {
00105 DIDEVICEOBJECTDATA diBuff[KEYBOARD_DX_BUFFERSIZE];
00106 DWORD entries = KEYBOARD_DX_BUFFERSIZE;
00107 HRESULT hr;
00108
00109 hr = mKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
00110 if( hr != DI_OK )
00111 {
00112 hr = mKeyboard->Acquire();
00113 while( hr == DIERR_INPUTLOST )
00114 hr = mKeyboard->Acquire();
00115 return;
00116 }
00117
00118 if( FAILED(hr) )
00119 OIS_EXCEPT( E_General, "Win32Keyboard::_readBuffered() >> Problem with Device!" );
00120
00121
00122 for(unsigned int i = 0; i < entries; ++i )
00123 {
00124
00125
00126 bool ret = true;
00127 KeyCode kc = (KeyCode)diBuff[ i ].dwOfs;
00128
00129
00130 KeyBuffer[kc] = static_cast<unsigned char>(diBuff[ i ].dwData);
00131
00132 if( diBuff[ i ].dwData & 0x80 )
00133 {
00134
00135 if( kc == KC_LCONTROL || kc == KC_RCONTROL )
00136 mModifiers |= Ctrl;
00137 else if( kc == KC_LSHIFT || kc == KC_RSHIFT )
00138 mModifiers |= Shift;
00139 else if( kc == KC_LMENU || kc == KC_RMENU )
00140 mModifiers |= Alt;
00141
00142 if( listener )
00143 ret = listener->keyPressed( KeyEvent( this, kc, _translateText(kc) ) );
00144 }
00145 else
00146 {
00147
00148 if( kc == KC_LCONTROL || kc == KC_RCONTROL )
00149 mModifiers &= ~Ctrl;
00150 else if( kc == KC_LSHIFT || kc == KC_RSHIFT )
00151 mModifiers &= ~Shift;
00152 else if( kc == KC_LMENU || kc == KC_RMENU )
00153 mModifiers &= ~Alt;
00154
00155
00156 if( listener )
00157 ret = listener->keyReleased( KeyEvent( this, kc, 0 ) );
00158 }
00159
00160 if(ret == false)
00161 break;
00162 }
00163 }
00164
00165
00166 void Win32Keyboard::_read()
00167 {
00168 HRESULT hr = mKeyboard->GetDeviceState( sizeof(KeyBuffer), &KeyBuffer );
00169
00170 if( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED )
00171 {
00172 hr = mKeyboard->Acquire();
00173 if (hr != DIERR_OTHERAPPHASPRIO)
00174 mKeyboard->GetDeviceState(sizeof(KeyBuffer), &KeyBuffer);
00175 }
00176
00177
00178 mModifiers = 0;
00179 if( isKeyDown(KC_LCONTROL) || isKeyDown(KC_RCONTROL) )
00180 mModifiers |= Ctrl;
00181 if( isKeyDown(KC_LSHIFT) || isKeyDown(KC_RSHIFT) )
00182 mModifiers |= Shift;
00183 if( isKeyDown(KC_LMENU) || isKeyDown(KC_RMENU) )
00184 mModifiers |= Alt;
00185 }
00186
00187
00188 int Win32Keyboard::_translateText( KeyCode kc )
00189 {
00190 if( mTextMode == Off )
00191 return 0;
00192
00193 BYTE keyState[256];
00194 HKL layout = GetKeyboardLayout(0);
00195 if( GetKeyboardState(keyState) == 0 )
00196 return 0;
00197
00198 unsigned int vk = MapVirtualKeyEx(kc, 3, layout);
00199 if( vk == 0 )
00200 return 0;
00201
00202 unsigned char buff[3] = {0,0,0};
00203 int ascii = ToAsciiEx(vk, kc, keyState, (LPWORD) buff, 0, layout);
00204
00205
00206 if(ascii == 1 && deadKey != '\0' )
00207 {
00208
00209
00210 WCHAR wcBuff[3] = {buff[0], deadKey, '\0'};
00211 WCHAR out[3];
00212
00213 deadKey = '\0';
00214 if(FoldStringW(MAP_PRECOMPOSED, (LPWSTR)wcBuff, 3, (LPWSTR)out, 3))
00215 return out[0];
00216 }
00217 else if (ascii == 1)
00218 {
00219 deadKey = '\0';
00220 return buff[0];
00221 }
00222 else if(ascii == 2)
00223 {
00224
00225
00226 switch(buff[0]) {
00227 case 0x5E:
00228 deadKey = 0x302; break;
00229 case 0x60:
00230 deadKey = 0x300; break;
00231 case 0xA8:
00232 deadKey = 0x308; break;
00233 case 0xB4:
00234 deadKey = 0x301; break;
00235 case 0xB8:
00236 deadKey = 0x327; break;
00237 default:
00238 deadKey = buff[0]; break;
00239 }
00240 }
00241
00242 return 0;
00243 }
00244
00245
00246 bool Win32Keyboard::isKeyDown( KeyCode key )
00247 {
00248 return (KeyBuffer[key] & 0x80) != 0;
00249 }
00250
00251
00252 const std::string& Win32Keyboard::getAsString( KeyCode kc )
00253 {
00254 char temp[256];
00255
00256 DIPROPSTRING prop;
00257 prop.diph.dwSize = sizeof(DIPROPSTRING);
00258 prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
00259 prop.diph.dwObj = static_cast<DWORD>(kc);
00260 prop.diph.dwHow = DIPH_BYOFFSET;
00261
00262 if ( SUCCEEDED( mKeyboard->GetProperty( DIPROP_KEYNAME, &prop.diph ) ) )
00263 {
00264
00265 if ( WideCharToMultiByte( CP_ACP, 0, prop.wsz, -1, temp, sizeof(temp), NULL, NULL) )
00266 return mGetString.assign( temp );
00267 }
00268
00269 std::stringstream ss;
00270 ss << "Key_" << (int)kc;
00271 return mGetString.assign( ss.str() );
00272 }
00273
00274
00275 void Win32Keyboard::copyKeyStates( char keys[256] )
00276 {
00277 for(int i = 0; i < 256; ++i)
00278 keys[i] = KeyBuffer[i] > 0;
00279 }
00280
00281
00282 void Win32Keyboard::setBuffered(bool buffered)
00283 {
00284 if( buffered != mBuffered )
00285 {
00286 if(mKeyboard)
00287 {
00288 mKeyboard->Unacquire();
00289 mKeyboard->Release();
00290 mKeyboard = 0;
00291 }
00292
00293 mBuffered = buffered;
00294 _initialize();
00295 }
00296 }