Skip to content

Commit

Permalink
Add cooperation modes, moving away from always-global input
Browse files Browse the repository at this point in the history
  • Loading branch information
noorus committed Jul 2, 2014
1 parent c9787dd commit 7a2e147
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 15 deletions.
8 changes: 6 additions & 2 deletions include/nil.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ namespace Nil {
DIDEVCAPS mDICapabilities; //!< DirectInput capabilities
size_t mAxisEnum; //!< Internal axis enumeration
size_t mSliderEnum; //!< Internal slider enumeration
const Cooperation mCooperation; //!< Cooperation mode

//! Axis value filter.
inline Real filterAxis( int val );
Expand All @@ -495,7 +496,7 @@ namespace Nil {
public:
//! Constructor.
//! \param device The device.
DirectInputController( DirectInputDevice* device );
DirectInputController( DirectInputDevice* device, const Cooperation coop );

virtual void update();

Expand Down Expand Up @@ -600,6 +601,7 @@ namespace Nil {
Logitech::GKeySDK* mLogitechGKeys; //!< External module for Logitech G-Keys
Logitech::LedSDK* mLogitechLEDs; //!< External module for Logitech LEDs
SystemListener* mListener; //!< Our single event listener
const Cooperation mCooperation; //!< Cooperation mode
void initializeDevices();
void refreshDevices();
void identifyXInputDevices();
Expand Down Expand Up @@ -638,8 +640,10 @@ namespace Nil {
//! Constructor.
//! \param instance Handle of the host instance.
//! \param window Handle of the host window.
//! \param coop Cooperation mode.
//! \param listener Listener for system events.
System( HINSTANCE instance, HWND window, SystemListener* listener );
System( HINSTANCE instance, HWND window, const Cooperation coop,
SystemListener* listener );

//! Updates this System.
//! All listened events get triggered from inside this call.
Expand Down
3 changes: 2 additions & 1 deletion include/nilPnP.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ namespace Nil {
RawListenerList mRawListeners; //!< Our raw listeners
void* mInputBuffer; //!< Buffer for input reads
unsigned int mInputBufferSize; //!< Size of input buffer
const Cooperation mCooperation; //!< Cooperation mode
protected:
//! \b Internal Register myself for event notifications.
void registerNotifications();
Expand Down Expand Up @@ -104,7 +105,7 @@ namespace Nil {
static LRESULT CALLBACK wndProc( HWND window, UINT message,
WPARAM wParam, LPARAM lParam );
public:
EventMonitor( HINSTANCE instance );
EventMonitor( HINSTANCE instance, const Cooperation coop );

//! Register a listener for Plug-n-Play events.
void registerPnPListener( PnPListener* listener );
Expand Down
5 changes: 5 additions & 0 deletions include/nilTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ namespace Nil {
typedef std::string utf8String; //!< UTF-8 string type.
typedef std::wstring String; //!< Wide string type.

enum Cooperation: int {
Cooperation_Foreground,
Cooperation_Background
};

using std::map;
using std::list;
using std::queue;
Expand Down
2 changes: 1 addition & 1 deletion src/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ namespace Nil {
NIL_EXCEPT( L"Dynamic cast failed for DirectInputDevice" );
if ( getType() == Device_Controller )
{
mInstance = new DirectInputController( diDevice );
mInstance = new DirectInputController( diDevice, mSystem->mCooperation );
mSystem->controllerEnabled( this, (Controller*)mInstance );
}
else
Expand Down
12 changes: 9 additions & 3 deletions src/DirectInputController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ namespace Nil {

const unsigned long cJoystickEvents = 64;

DirectInputController::DirectInputController( DirectInputDevice* device ):
Controller( device->getSystem(), device ), mDIDevice( nullptr ), mAxisEnum( 0 )
DirectInputController::DirectInputController( DirectInputDevice* device,
const Cooperation coop ):
Controller( device->getSystem(), device ), mDIDevice( nullptr ),
mAxisEnum( 0 ), mCooperation( coop )
{
HRESULT hr = device->getSystem()->mDirectInput->CreateDevice(
device->getInstanceID(), &mDIDevice, NULL );
Expand All @@ -26,7 +28,11 @@ namespace Nil {
if ( FAILED( hr ) )
NIL_EXCEPT_DINPUT( hr, L"Could not set DirectInput8 device data format" );

hr = mDIDevice->SetCooperativeLevel( device->getSystem()->mWindow, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE );
// Force feedback, to be implemented later, requires exclusive access.
hr = mDIDevice->SetCooperativeLevel( device->getSystem()->mWindow,
( mCooperation == Cooperation_Background )
? DISCL_BACKGROUND | DISCL_EXCLUSIVE
: DISCL_FOREGROUND | DISCL_EXCLUSIVE );
if ( FAILED( hr ) )
NIL_EXCEPT_DINPUT( hr, L"Could not set DirectInput8 device cooperation level" );

Expand Down
2 changes: 1 addition & 1 deletion src/DirectInputDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Nil {

Device::Type resolveDIDeviceType( unsigned long type )
inline Device::Type resolveDIDeviceType( unsigned long type )
{
type = GET_DIDEVICE_TYPE( type );

Expand Down
14 changes: 10 additions & 4 deletions src/EventMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ namespace Nil {

const wchar_t* cEventMonitorClass = L"NIL_MONITOR";

EventMonitor::EventMonitor( HINSTANCE instance ):
EventMonitor::EventMonitor( HINSTANCE instance, const Cooperation coop ):
mInstance( instance ), mClass( 0 ), mWindow( 0 ), mNotifications( 0 ),
mInputBuffer( nullptr ),
mInputBuffer( nullptr ), mCooperation( coop ),
mInputBufferSize( 10240 ) // 10KB default
{
WNDCLASSEXW wx = { 0 };
Expand Down Expand Up @@ -132,12 +132,18 @@ namespace Nil {

RAWINPUTDEVICE rawDevices[2];

rawDevices[0].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
rawDevices[0].dwFlags =
( mCooperation == Cooperation_Background )
? RIDEV_DEVNOTIFY | RIDEV_INPUTSINK
: RIDEV_DEVNOTIFY;
rawDevices[0].hwndTarget = mWindow;
rawDevices[0].usUsagePage = USBUsagePage_Desktop;
rawDevices[0].usUsage = USBDesktopUsage_Mice;

rawDevices[1].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
rawDevices[1].dwFlags =
( mCooperation == Cooperation_Background )
? RIDEV_DEVNOTIFY | RIDEV_INPUTSINK
: RIDEV_DEVNOTIFY;
rawDevices[1].hwndTarget = mWindow;
rawDevices[1].usUsagePage = USBUsagePage_Desktop;
rawDevices[1].usUsage = USBDesktopUsage_Keyboards;
Expand Down
5 changes: 3 additions & 2 deletions src/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

namespace Nil {

System::System( HINSTANCE instance, HWND window, SystemListener* listener ):
System::System( HINSTANCE instance, HWND window, const Cooperation coop,
SystemListener* listener ): mCooperation( coop ),
mWindow( window ), mInstance( instance ), mDirectInput( nullptr ),
mMonitor( nullptr ), mIDPool( 0 ), mInitializing( true ),
mHIDManager( nullptr ), mLogitechGKeys( nullptr ), mLogitechLEDs( nullptr ),
Expand All @@ -27,7 +28,7 @@ namespace Nil {
NIL_EXCEPT_DINPUT( hr, L"Could not instance DirectInput 8" );

// Initialize our event monitor
mMonitor = new EventMonitor( mInstance );
mMonitor = new EventMonitor( mInstance, mCooperation );

// Initialize our HID manager
mHIDManager = new HIDManager();
Expand Down
9 changes: 8 additions & 1 deletion test/Test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,14 @@ int wmain( int argc, wchar_t* argv[], wchar_t* envp[] )

// Init system
Nil::System* system = new Nil::System(
GetModuleHandleW( nullptr ), GetConsoleWindow(), &gMyListener );
GetModuleHandleW( nullptr ),
GetConsoleWindow(),
// Using background cooperation mode, because the default console window
// is actually not owned by our process (it is owned by cmd.exe) and thus
// we would not receive any mouse & keyboard events in foreground mode.
// For applications that own their own window foreground mode works fine.
Nil::Cooperation_Background,
&gMyListener );

// Init Logitech G-keys subsystem, if available
Nil::ExternalModule::InitReturn ret = system->getLogitechGKeys()->initialize();
Expand Down

0 comments on commit 7a2e147

Please sign in to comment.