Home | History | Annotate | Download | only in win32
      1 /*
      2 The zlib/libpng License
      3 
      4 Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
      5 
      6 This software is provided 'as-is', without any express or implied warranty. In no event will
      7 the authors be held liable for any damages arising from the use of this software.
      8 
      9 Permission is granted to anyone to use this software for any purpose, including commercial
     10 applications, and to alter it and redistribute it freely, subject to the following
     11 restrictions:
     12 
     13     1. The origin of this software must not be misrepresented; you must not claim that
     14 		you wrote the original software. If you use this software in a product,
     15 		an acknowledgment in the product documentation would be appreciated but is
     16 		not required.
     17 
     18     2. Altered source versions must be plainly marked as such, and must not be
     19 		misrepresented as being the original software.
     20 
     21     3. This notice may not be removed or altered from any source distribution.
     22 */
     23 #include "win32/Win32InputManager.h"
     24 #include "win32/Win32KeyBoard.h"
     25 #include "win32/Win32Mouse.h"
     26 #include "win32/Win32JoyStick.h"
     27 #include "OISException.h"
     28 
     29 using namespace OIS;
     30 
     31 //--------------------------------------------------------------------------------//
     32 Win32InputManager::Win32InputManager() : InputManager("Win32InputManager")
     33 {
     34 	hWnd = 0;
     35 	mDirectInput = 0;
     36 
     37 	kbSettings    = 0;
     38 	mouseSettings = 0;
     39 	joySettings   = 0;
     40 
     41 	joySticks = 0;
     42 	keyboardUsed = mouseUsed = false;
     43 
     44 	//Setup our internal factories
     45 	mFactories.push_back(this);
     46 }
     47 
     48 //--------------------------------------------------------------------------------//
     49 Win32InputManager::~Win32InputManager()
     50 {
     51 	if( mDirectInput )
     52 	{
     53 		mDirectInput->Release();
     54 		mDirectInput = 0;
     55 	}
     56 }
     57 
     58 //--------------------------------------------------------------------------------//
     59 void Win32InputManager::_initialize( ParamList &paramList )
     60 {
     61 	HINSTANCE hInst = 0;
     62 	HRESULT hr;
     63 
     64 
     65 	//First of all, get the Windows Handle and Instance
     66 	ParamList::iterator i = paramList.find("WINDOW");
     67 	if( i == paramList.end() )
     68 		OIS_EXCEPT( E_InvalidParam, "Win32InputManager::Win32InputManager >> No HWND found!" );
     69 
     70 	// Get number as 64 bit and then convert. Handles the case of 32 or 64 bit HWND
     71 #ifdef _MSC_VER
     72 	unsigned __int64 handle = _strtoui64(i->second.c_str(), 0, 10);
     73 #else
     74 	unsigned __int64 handle = strtoull(i->second.c_str(), 0, 10);
     75 #endif
     76 	hWnd  = (HWND)handle;
     77 
     78 	if( IsWindow(hWnd) == 0 )
     79 		OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> The sent HWND is not valid!");
     80 
     81 	hInst = GetModuleHandle(0);
     82 
     83 	//Create the device
     84 	hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL );
     85     if (FAILED(hr))
     86 		OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> Not able to init DirectX8 Input!");
     87 
     88 	//Ok, now we have DirectInput, parse whatever extra settings were sent to us
     89 	_parseConfigSettings( paramList );
     90 
     91 	// Enumerate devices ...
     92 	_enumerateDevices();
     93 }
     94 
     95 //--------------------------------------------------------------------------------//
     96 void Win32InputManager::_parseConfigSettings( ParamList &paramList )
     97 {
     98 	//Here we pick up settings such as a device's cooperation mode
     99 	std::map<std::string, DWORD> temp;
    100 	temp["DISCL_BACKGROUND"]	= DISCL_BACKGROUND;
    101 	temp["DISCL_EXCLUSIVE"]		= DISCL_EXCLUSIVE;
    102 	temp["DISCL_FOREGROUND"]	= DISCL_FOREGROUND;
    103 	temp["DISCL_NONEXCLUSIVE"]	= DISCL_NONEXCLUSIVE;
    104 	temp["DISCL_NOWINKEY"]		= DISCL_NOWINKEY;
    105 
    106 	//Check for pairs: ie. ("w32_keyboard","DISCL_NOWINKEY")("w32_keyboard","DISCL_FOREGROUND")
    107 	ParamList::iterator i = paramList.begin(), e = paramList.end();
    108 	for( ; i != e; ++i )
    109 	{
    110 		if( i->first == "w32_keyboard" )
    111 				kbSettings |= temp[i->second];
    112 		else if( i->first == "w32_mouse" )
    113 				mouseSettings |= temp[i->second];
    114 		else if( i->first == "w32_joystick" )
    115 				joySettings |= temp[i->second];
    116 	}
    117 	if( kbSettings == 0 ) kbSettings = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY;
    118 	if( mouseSettings == 0 ) mouseSettings = DISCL_FOREGROUND | DISCL_EXCLUSIVE;
    119 	if( joySettings == 0 ) joySettings = DISCL_FOREGROUND | DISCL_EXCLUSIVE;
    120 }
    121 
    122 //--------------------------------------------------------------------------------//
    123 void Win32InputManager::_enumerateDevices()
    124 {
    125 	//Enumerate all attached devices
    126 	mDirectInput->EnumDevices(NULL, _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY);
    127 
    128 #ifdef OIS_WIN32_XINPUT_SUPPORT
    129 	//let's check how many possible XInput devices we may have (max 4)...
    130 	for(int i = 0; i < 3; ++i)
    131 	{
    132 		XINPUT_STATE state;
    133 		if(XInputGetState(i, &state) != ERROR_DEVICE_NOT_CONNECTED)
    134 		{	//Once we found 1, just check our whole list against devices
    135 			Win32JoyStick::CheckXInputDevices(unusedJoyStickList);
    136 			break;
    137 		}
    138 	}
    139 #endif
    140 }
    141 
    142 //--------------------------------------------------------------------------------//
    143 BOOL CALLBACK Win32InputManager::_DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
    144 {
    145 	Win32InputManager *_this_ = static_cast<Win32InputManager*>(pvRef);
    146 
    147 	// Register only game devices (keyboard and mouse are managed differently).
    148 	if( GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK ||
    149 		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD ||
    150 		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_1STPERSON ||
    151 		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_DRIVING ||
    152 		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_FLIGHT ||
    153 		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_SUPPLEMENTAL)
    154 	{
    155 		JoyStickInfo jsInfo;
    156 		jsInfo.isXInput = false;
    157 		jsInfo.productGuid = lpddi->guidProduct;
    158 		jsInfo.deviceID = lpddi->guidInstance;
    159 		jsInfo.vendor = lpddi->tszInstanceName;
    160 		jsInfo.devId = _this_->joySticks;
    161 
    162 		_this_->joySticks++;
    163 
    164 		_this_->unusedJoyStickList.push_back( jsInfo );
    165 	}
    166 
    167 	return DIENUM_CONTINUE;
    168 }
    169 
    170 //----------------------------------------------------------------------------//
    171 void Win32InputManager::_returnJoyStick(const JoyStickInfo& joystick)
    172 {
    173 	unusedJoyStickList.push_back(joystick);
    174 }
    175 
    176 //----------------------------------------------------------------------------//
    177 DeviceList Win32InputManager::freeDeviceList()
    178 {
    179 	DeviceList ret;
    180 
    181 	if( keyboardUsed == false )
    182 		ret.insert(std::make_pair(OISKeyboard, mInputSystemName));
    183 
    184 	if( mouseUsed == false )
    185 		ret.insert(std::make_pair(OISMouse, mInputSystemName));
    186 
    187 	for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
    188 		ret.insert(std::make_pair(OISJoyStick, i->vendor));
    189 
    190 	return ret;
    191 }
    192 
    193 //----------------------------------------------------------------------------//
    194 int Win32InputManager::totalDevices(Type iType)
    195 {
    196 	switch(iType)
    197 	{
    198 	case OISKeyboard: return 1;
    199 	case OISMouse: return 1;
    200 	case OISJoyStick: return joySticks;
    201 	default: return 0;
    202 	}
    203 }
    204 
    205 //----------------------------------------------------------------------------//
    206 int Win32InputManager::freeDevices(Type iType)
    207 {
    208 	switch(iType)
    209 	{
    210 	case OISKeyboard: return keyboardUsed ? 0 : 1;
    211 	case OISMouse: return mouseUsed ? 0 : 1;
    212 	case OISJoyStick: return (int)unusedJoyStickList.size();
    213 	default: return 0;
    214 	}
    215 }
    216 
    217 //----------------------------------------------------------------------------//
    218 bool Win32InputManager::vendorExist(Type iType, const std::string & vendor)
    219 {
    220 	if( (iType == OISKeyboard || iType == OISMouse) && vendor == mInputSystemName )
    221 	{
    222 		return true;
    223 	}
    224 	else if( iType == OISJoyStick )
    225 	{
    226 		for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
    227 			if(i->vendor == vendor)
    228 				return true;
    229 	}
    230 
    231 	return false;
    232 }
    233 
    234 //----------------------------------------------------------------------------//
    235 Object* Win32InputManager::createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor)
    236 {
    237 	Object *obj = 0;
    238 
    239 	switch(iType)
    240 	{
    241 	case OISKeyboard:
    242 	{
    243 		if( keyboardUsed == false )
    244 			obj = new Win32Keyboard(this, mDirectInput, bufferMode, kbSettings);
    245 		break;
    246 	}
    247 	case OISMouse:
    248 	{
    249 		if( mouseUsed == false )
    250 			obj = new Win32Mouse(this, mDirectInput, bufferMode, mouseSettings);
    251 		break;
    252 	}
    253 	case OISJoyStick:
    254 	{
    255 		for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
    256 		{
    257 			if(vendor == "" || i->vendor == vendor)
    258 			{
    259 				obj = new Win32JoyStick(this, mDirectInput, bufferMode, joySettings, *i);
    260 				unusedJoyStickList.erase(i);
    261 				break;
    262 			}
    263 		}
    264 		break;
    265 	}
    266 	default:
    267 		break;
    268 	}
    269 
    270 	if( obj == 0 )
    271 		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
    272 
    273 	return obj;
    274 }
    275 
    276 //----------------------------------------------------------------------------//
    277 void Win32InputManager::destroyObject(Object* obj)
    278 {
    279 	delete obj;
    280 }
    281