Skip to content

Commit

Permalink
Added support for Logitech LEDs
Browse files Browse the repository at this point in the history
  • Loading branch information
noorus committed Feb 4, 2014
1 parent 11b555f commit 7eb264a
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 16 deletions.
25 changes: 23 additions & 2 deletions include/nil.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace nil {

namespace Logitech {
class GKeySDK;
class LedSDK;
}

//! \struct Button
Expand Down Expand Up @@ -90,7 +91,7 @@ namespace nil {
enum Type: int {
Device_Keyboard = 0, //!< I'm a keyboard
Device_Mouse, //!< I'm a mouse
Device_Controller //!< No, I'm a controller
Device_Controller //!< I'm a controller
};
enum Status: int {
Status_Disconnected = 0, //!< Disconnected but not forgotten
Expand Down Expand Up @@ -390,6 +391,25 @@ namespace nil {
typedef map<HANDLE,RawInputMouse*> RawMouseMap;
typedef map<HANDLE,RawInputKeyboard*> RawKeyboardMap;

//! \class ExternalModule
//! Base class for an external, optional module supported by the system.
class ExternalModule {
protected:
HMODULE mModule;
bool mInitialized;
public:
enum InitReturn: unsigned int {
Initialization_OK = 0,
Initialization_ModuleNotFound,
Initialization_MissingExports,
Initialization_Unavailable
};
ExternalModule();
virtual InitReturn initialize() = 0;
virtual void shutdown() = 0;
virtual bool isInitialized() const;
};

//! \class System
//! The input system root.
class System: public PnPListener, public RawListener {
Expand All @@ -409,7 +429,8 @@ namespace nil {
bool mInitializing; //!< Are we initializing?
RawMouseMap mMouseMapping; //!< Mouse events mapping
RawKeyboardMap mKeyboardMapping; //!< Keyboard events mapping
Logitech::GKeySDK* mLogitechGKeys;
Logitech::GKeySDK* mLogitechGKeys; //!< External module for Logitech G-Keys
Logitech::LedSDK* mLogitechLEDs; //!< External module for Logitech LEDs
void initializeDevices();
void refreshDevices();
void identifyXInputDevices();
Expand Down
35 changes: 32 additions & 3 deletions include/nilLogitech.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#pragma once
#include <windows.h>
#include <LogitechGkey.h>
#include <LogitechLed.h>

namespace nil {

namespace Logitech {

// G-Key SDK
// G-Key SDK (1.02.004)

typedef unsigned int GKey;

Expand All @@ -25,9 +26,8 @@ namespace nil {

typedef queue<GkeyCode> GKeyQueue;

class GKeySDK {
class GKeySDK: public ExternalModule {
protected:
HMODULE mModule;
struct Functions {
fnLogiGkeyInit pfnLogiGkeyInit;
fnLogiGkeyGetMouseButtonString pfnLogiGkeyGetMouseButtonString;
Expand All @@ -42,10 +42,39 @@ namespace nil {
static void __cdecl keyCallback( GkeyCode key, const wchar_t* name, void* context );
public:
GKeySDK();
virtual InitReturn initialize();
void update();
virtual void shutdown();
~GKeySDK();
};

// LED SDK (1.01.005.1)

typedef BOOL (*fnLogiLedInit)();
typedef BOOL (*fnLogiLedSaveCurrentLighting)( int deviceType );
typedef BOOL (*fnLogiLedSetLighting)( int deviceType, int redPercentage, int greenPercentage, int bluePercentage );
typedef BOOL (*fnLogiLedRestoreLighting)( int deviceType );
typedef void (*fnLogiLedShutdown)();

class LedSDK: public ExternalModule {
protected:
struct Functions {
fnLogiLedInit pfnLogiLedInit;
fnLogiLedSaveCurrentLighting pfnLogiLedSaveCurrentLighting;
fnLogiLedSetLighting pfnLogiLedSetLighting;
fnLogiLedRestoreLighting pfnLogiLedRestoreLighting;
fnLogiLedShutdown pfnLogiLedShutdown;
Functions();
} mFunctions;
bool mSavedOriginal;
public:
LedSDK();
virtual InitReturn initialize();
void setLighting( const Color& color );
virtual void shutdown();
~LedSDK();
};

}

}
9 changes: 9 additions & 0 deletions include/nilTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ namespace nil {
const static Vector3i ZERO;
};

//! \struct Color
//! A color value.
struct Color {
public:
Real r; //!< Red color component amount in {0..1}
Real g; //!< Green color component amount in {0..1}
Real b; //!< Blue color component amount in {0..1}
};

//! \struct Vector2f
//! Two-dimensional floating point vector.
struct Vector2f {
Expand Down
6 changes: 4 additions & 2 deletions nil.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>include;external\LogitechGkeySDK_1.02.004\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>include;external\LogitechGkeySDK_1.02.004\Include;external\LogitechLEDSDK_1.01.005.1\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ShowIncludes>false</ShowIncludes>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
</ClCompile>
Expand Down Expand Up @@ -131,7 +131,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>include;external\LogitechGkeySDK_1.02.004\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>include;external\LogitechGkeySDK_1.02.004\Include;external\LogitechLEDSDK_1.01.005.1\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ShowIncludes>false</ShowIncludes>
<DebugInformationFormat>None</DebugInformationFormat>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
Expand Down Expand Up @@ -167,10 +167,12 @@
<ClCompile Include="src\DirectInputController.cpp" />
<ClCompile Include="src\DirectInputDevice.cpp" />
<ClCompile Include="src\Exception.cpp" />
<ClCompile Include="src\ExternalModule.cpp" />
<ClCompile Include="src\HIDManager.cpp" />
<ClCompile Include="src\HIDRecord.cpp" />
<ClCompile Include="src\Keyboard.cpp" />
<ClCompile Include="src\LogitechGkeySDK.cpp" />
<ClCompile Include="src\LogitechLedSDK.cpp" />
<ClCompile Include="src\Mouse.cpp" />
<ClCompile Include="src\PnPMonitor.cpp" />
<ClCompile Include="src\RawInputDevice.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions nil.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,11 @@
<ClCompile Include="src\LogitechGkeySDK.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\LogitechLedSDK.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ExternalModule.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
14 changes: 14 additions & 0 deletions src/ExternalModule.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "nil.h"

namespace nil {

ExternalModule::ExternalModule(): mModule( NULL ), mInitialized( false )
{
}

bool ExternalModule::isInitialized() const
{
return mInitialized;
}

}
28 changes: 22 additions & 6 deletions src/LogitechGkeySDK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,18 @@ namespace nil {
{
}

GKeySDK::GKeySDK(): mModule( NULL )
GKeySDK::GKeySDK(): ExternalModule()
{
InitializeSRWLock( &mLock );

mListeners.push_back( &gDummyGKeyListener );
}

GKeySDK::InitReturn GKeySDK::initialize()
{
mModule = LoadLibraryW( cLogitechGKeyModuleName );
if ( !mModule )
NIL_EXCEPT_WINAPI( L"Couldn't load Logitech GKey module" );
return Initialization_ModuleNotFound;

NIL_LOAD_SDK_FUNC( LogiGkeyInit );
NIL_LOAD_SDK_FUNC( LogiGkeyGetMouseButtonString );
Expand All @@ -51,13 +54,17 @@ namespace nil {
|| !mFunctions.pfnLogiGkeyGetMouseButtonString
|| !mFunctions.pfnLogiGkeyGetKeyboardGkeyString
|| !mFunctions.pfnLogiGkeyShutdown )
NIL_EXCEPT( L"Couldn't load Logitech GKey module" );
return Initialization_MissingExports;

mContext.gkeyContext = this;
mContext.gkeyCallBack = keyCallback;

if ( !mFunctions.pfnLogiGkeyInit( &mContext ) )
NIL_EXCEPT( L"Couldn't initialize Logitech GKey module" );
return Initialization_Unavailable;

mInitialized = true;

return Initialization_OK;
}

void GKeySDK::keyCallback( GkeyCode key, const wchar_t* name, void* context )
Expand Down Expand Up @@ -85,14 +92,23 @@ namespace nil {
ReleaseSRWLockExclusive( &mLock );
}

GKeySDK::~GKeySDK()
void GKeySDK::shutdown()
{
AcquireSRWLockExclusive( &mLock );
if ( mModule )
{
if ( mFunctions.pfnLogiGkeyShutdown )
if ( mInitialized )
mFunctions.pfnLogiGkeyShutdown();
FreeLibrary( mModule );
mModule = NULL;
}
mInitialized = false;
ReleaseSRWLockExclusive( &mLock );
}

GKeySDK::~GKeySDK()
{
shutdown();
}

}
Expand Down
91 changes: 91 additions & 0 deletions src/LogitechLedSDK.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include "nil.h"
#include "nilLogitech.h"
#include "nilUtil.h"

# define NIL_LOAD_SDK_FUNC(x) mFunctions.pfn##x##=(fn##x##)GetProcAddress(mModule,#x)

namespace nil {

namespace Logitech {

const wchar_t* cLogitechLedModuleName = L"LogitechLed.dll";

LedSDK::Functions::Functions():
pfnLogiLedInit( nullptr ),
pfnLogiLedSaveCurrentLighting( nullptr ),
pfnLogiLedSetLighting( nullptr ),
pfnLogiLedRestoreLighting( nullptr ),
pfnLogiLedShutdown( nullptr )
{
}

LedSDK::LedSDK(): ExternalModule(), mSavedOriginal( false )
{
//
}

LedSDK::InitReturn LedSDK::initialize()
{
mModule = LoadLibraryW( cLogitechLedModuleName );
if ( !mModule )
return Initialization_ModuleNotFound;

NIL_LOAD_SDK_FUNC( LogiLedInit );
NIL_LOAD_SDK_FUNC( LogiLedSaveCurrentLighting );
NIL_LOAD_SDK_FUNC( LogiLedSetLighting );
NIL_LOAD_SDK_FUNC( LogiLedRestoreLighting );
NIL_LOAD_SDK_FUNC( LogiLedShutdown );

if ( !mFunctions.pfnLogiLedInit
|| !mFunctions.pfnLogiLedSaveCurrentLighting
|| !mFunctions.pfnLogiLedSetLighting
|| !mFunctions.pfnLogiLedRestoreLighting
|| !mFunctions.pfnLogiLedShutdown )
return Initialization_MissingExports;

if ( !mFunctions.pfnLogiLedInit() )
return Initialization_Unavailable;

if ( mFunctions.pfnLogiLedSaveCurrentLighting( LOGITECH_LED_ALL ) )
mSavedOriginal = true;

mInitialized = true;

return Initialization_OK;
}

void LedSDK::setLighting( const Color& color )
{
if ( !mInitialized )
return;

int r = (int)( color.r * 100.0f );
int g = (int)( color.g * 100.0f );
int b = (int)( color.b * 100.0f );

mFunctions.pfnLogiLedSetLighting( LOGITECH_LED_ALL, r, g, b );
}

void LedSDK::shutdown()
{
if ( mModule )
{
if ( mSavedOriginal )
mFunctions.pfnLogiLedRestoreLighting( LOGITECH_LED_ALL );
if ( mInitialized )
mFunctions.pfnLogiLedShutdown();
FreeLibrary( mModule );
mModule = NULL;
}
mInitialized = false;
mSavedOriginal = false;
}

LedSDK::~LedSDK()
{
shutdown();
}

}

}
11 changes: 8 additions & 3 deletions src/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ namespace nil {
System::System( HINSTANCE instance, HWND window ): mWindow( window ),
mInstance( instance ), mDirectInput( nullptr ), mMonitor( nullptr ),
mIDPool( 0 ), mInitializing( true ), mHIDManager( nullptr ),
mLogitechGKeys( nullptr )
mLogitechGKeys( nullptr ), mLogitechLEDs( nullptr )
{
// Validate the passes window handle
if ( !IsWindow( mWindow ) )
NIL_EXCEPT( L"Window handle is invalid" );

mLogitechGKeys = new Logitech::GKeySDK();
mLogitechLEDs = new Logitech::LedSDK();

// Create DirectInput instance
auto hr = DirectInput8Create( mInstance, DIRECTINPUT_VERSION,
Expand Down Expand Up @@ -273,14 +274,17 @@ namespace nil {
// Run PnP & raw events if there are any
mMonitor->update();

// First make sure that we disconnect failed devices
// Make sure that we disconnect failed devices,
// and update the rest
for ( Device* device : mDevices )
if ( device->isDisconnectFlagged() )
device->onDisconnect();
else
device->update();

mLogitechGKeys->update();
// Run queued G-key events if using the SDK
if ( mLogitechGKeys->isInitialized() )
mLogitechGKeys->update();
}

System::~System()
Expand All @@ -291,6 +295,7 @@ namespace nil {
SAFE_DELETE( mHIDManager );
SAFE_DELETE( mMonitor );
SAFE_RELEASE( mDirectInput );
SAFE_DELETE( mLogitechLEDs );
SAFE_DELETE( mLogitechGKeys );
}

Expand Down

0 comments on commit 7eb264a

Please sign in to comment.