Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
spreedated committed Jun 28, 2019
2 parents 1ab9b47 + 8f513b9 commit a08966d
Show file tree
Hide file tree
Showing 7 changed files with 403 additions and 12 deletions.
76 changes: 76 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at wackermann@nexn.systems. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
Binary file removed DirectInputCSharpWrapper.dll
Binary file not shown.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Markus Karl Wackermann

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
240 changes: 240 additions & 0 deletions test_x56_led/Classes/DirectOutput.vb
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
Imports System
Imports System.Collections.Generic
Imports System.Runtime.InteropServices
Imports Microsoft.Win32

Imports HResult = System.Int32

Namespace DirectOutputVBWrapper
Public Structure SRequestStatus
Public headerError As Integer
Public headerInfo As Integer
Public requestError As Integer
Public requestInfo As Integer
End Structure

Public Class RegistryKeyNotFound : Inherits Exception
Public Sub New()
MyBase.New("HKEY_LOCAL_MACHINE\SOFTWARE\Saitek\DirectOutput key not found.")
End Sub
End Class

Public Class RegistryValueNotFound : Inherits Exception
Public Sub New()
MyBase.New("DirectOutput value in key HKEY_LOCAL_MACHINE\SOFTWARE\Saitek\DirectOutput not found.")
End Sub
End Class


Public Class HResultException : Inherits Exception
Public Const S_OK As HResult = &H0
Public Const E_OUTOFMEMORY As HResult = CType(&H8007000E, HResult)
Public Const E_NOTIMPL As HResult = CType(&H80004001, HResult)
Public Const E_INVALIDARG As HResult = CType(&H80070057, HResult)
Public Const E_PAGENOTACTIVE As HResult = CType(&HFF040001, HResult)
Public Const E_HANDLE As HResult = CType(&H80070006, HResult)
Public Const E_UNKNOWN_1 As HResult = CType(&H51B87CE3, HResult)

Public Sub New(ByVal result As HResult, ByVal errorsMap As Dictionary(Of HResult, String))
MyBase.New(errorsMap(result))
HResult = result
End Sub
End Class
End Namespace

Public Class DirectOutputVB
Public Const IsActive As Integer = &H1

'Callbacks
Public Delegate Sub EnumarateCallback(ByVal device As IntPtr, ByVal target As IntPtr)
Public Delegate Sub DeviceCallback(ByVal device As IntPtr, ByVal added As Boolean, ByVal target As IntPtr)
Public Delegate Sub SoftButtonCallback(ByVal device As IntPtr, ByVal buttons As UInteger, ByVal target As IntPtr)
Public Delegate Sub PageCallback(ByVal device As IntPtr, ByVal page As UInteger, ByVal activated As Boolean, ByVal target As IntPtr)

'Library functions
Private Delegate Function DirectOutput_Initialize(<MarshalAsAttribute(UnmanagedType.LPWStr)> ByVal appName As String) As HResult
Private Delegate Function DirectOutput_Deinitialize() As HResult
Private Delegate Function DirectOutput_RegisterDeviceCallback(<MarshalAs(UnmanagedType.FunctionPtr)> ByVal callback As DeviceCallback, ByVal target As IntPtr) As HResult


Private Delegate Function DirectOutput_Enumerate(<MarshalAs(UnmanagedType.FunctionPtr)> ByVal callback As EnumarateCallback, ByVal target As IntPtr) As HResult
Private Delegate Function DirectOutput_GetDeviceType(ByVal device As IntPtr, <Out> ByRef guidType As Guid) As HResult
Private Delegate Function DirectOutput_GetDeviceInstance(ByVal device As IntPtr, <Out> ByRef guidInstance As Guid) As HResult

Private Delegate Function DirectOutput_AddPage(ByVal device As IntPtr, ByVal page As Int32, ByVal flags As Int32) As HResult
Private Delegate Function DirectOutput_RemovePage(ByVal device As IntPtr, ByVal page As Int32) As HResult
Private Delegate Function DirectOutput_SetLed(ByVal device As IntPtr, ByVal page As Int32, ByVal index As Int32, ByVal value As Int32) As HResult

'Functions placeholders
Private _initialize As DirectOutput_Initialize
Private _deinitialize As DirectOutput_Deinitialize
Private _registerDeviceCallback As DirectOutput_RegisterDeviceCallback

Private _enumerate As DirectOutput_Enumerate
Private _getDeviceType As DirectOutput_GetDeviceType
Private _getDeviceInstance As DirectOutput_GetDeviceInstance

Private _addPage As DirectOutput_AddPage
Private _removePage As DirectOutput_RemovePage
Private _setLed As DirectOutput_SetLed

Private Const directOutputKey As String = "SOFTWARE\Saitek\DirectOutput"
Private hModule As IntPtr

Public Sub New(ByVal Optional libPath As String = Nothing)
If libPath Is Nothing Then
Dim key As RegistryKey = Registry.LocalMachine.OpenSubKey(directOutputKey)
If key Is Nothing Then
Throw New Exception
End If

Dim value As String = key.GetValue("DirectOutput")
If (value Is Nothing) OrElse Not (TypeOf value Is String) Then
Throw New Exception
End If

libPath = value.ToString
End If

hModule = DirectOutputVBWrapper.DllHelper.LoadLibrary(libPath)

InitializeLibraryFunctions()
End Sub

Private Sub InitializeLibraryFunctions()
_initialize = DirectOutputVBWrapper.DllHelper.GetFunction(Of DirectOutput_Initialize)(hModule, "DirectOutput_Initialize")
_deinitialize = DirectOutputVBWrapper.DllHelper.GetFunction(Of DirectOutput_Deinitialize)(hModule, "DirectOutput_Deinitialize")
_registerDeviceCallback = DirectOutputVBWrapper.DllHelper.GetFunction(Of DirectOutput_RegisterDeviceCallback)(hModule, "DirectOutput_RegisterDeviceCallback")

_enumerate = DirectOutputVBWrapper.DllHelper.GetFunction(Of DirectOutput_Enumerate)(hModule, "DirectOutput_Enumerate")
_getDeviceType = DirectOutputVBWrapper.DllHelper.GetFunction(Of DirectOutput_GetDeviceType)(hModule, "DirectOutput_GetDeviceType")
_getDeviceInstance = DirectOutputVBWrapper.DllHelper.GetFunction(Of DirectOutput_GetDeviceInstance)(hModule, "DirectOutput_GetDeviceInstance")

_addPage = DirectOutputVBWrapper.DllHelper.GetFunction(Of DirectOutput_AddPage)(hModule, "DirectOutput_AddPage")
_removePage = DirectOutputVBWrapper.DllHelper.GetFunction(Of DirectOutput_RemovePage)(hModule, "DirectOutput_RemovePage")
_setLed = DirectOutputVBWrapper.DllHelper.GetFunction(Of DirectOutput_SetLed)(hModule, "DirectOutput_SetLed")
End Sub

''' <summary>
''' Initialize the DirectOutput library.
''' </summary>
''' <param name="appName">String that specifies the name of the application. Optional</param>
''' <remarks>
''' This function must be called before calling any others. Call this function when you want to initialize the DirectOutput library.
''' </remarks>
''' <exception cref="DirectOutputVBWrapper.HResultException"></exception>
Public Sub Initialize(ByVal Optional appName As String = "DirectOutputCSharpWrapper")
Dim retVal As HResult = _initialize(appName)

If retVal <> DirectOutputVBWrapper.HResultException.S_OK Then
Dim errorsMap As Dictionary(Of HResult, String) = New Dictionary(Of HResult, String)() From {
{DirectOutputVBWrapper.HResultException.E_OUTOFMEMORY, "There was insufficient memory to complete this call."},
{DirectOutputVBWrapper.HResultException.E_INVALIDARG, "The argument is invalid."},
{DirectOutputVBWrapper.HResultException.E_HANDLE, "The DirectOutputManager prcess could not be found."}
}
Throw New DirectOutputVBWrapper.HResultException(retVal, errorsMap)
End If
End Sub

Public Sub Deinitialize()
Dim retVal As HResult = _deinitialize()

If retVal <> DirectOutputVBWrapper.HResultException.S_OK Then
Dim errorsMap As Dictionary(Of HResult, String) = New Dictionary(Of HResult, String)() From {
{DirectOutputVBWrapper.HResultException.E_HANDLE, "DirectOutput was not initialized or was already deinitialized."}
}
Throw New DirectOutputVBWrapper.HResultException(retVal, errorsMap)
End If
End Sub

Public Sub RegisterDeviceCallback(ByVal callback As DeviceCallback)
Dim retVal As HResult = _registerDeviceCallback(callback, New IntPtr())

If retVal <> DirectOutputVBWrapper.HResultException.S_OK Then
Dim errorsMap As Dictionary(Of HResult, String) = New Dictionary(Of HResult, String)() From {
{DirectOutputVBWrapper.HResultException.E_HANDLE, "DirectOutput was not initialized."}
}
Throw New DirectOutputVBWrapper.HResultException(retVal, errorsMap)
End If
End Sub

Public Sub Enumerate(ByVal callback As EnumarateCallback)
Dim retVal As HResult = _enumerate(callback, New IntPtr())

If retVal <> DirectOutputVBWrapper.HResultException.S_OK Then
Dim errorsMap As Dictionary(Of HResult, String) = New Dictionary(Of HResult, String)() From {
{DirectOutputVBWrapper.HResultException.E_HANDLE, "DirectOutput was not initialized."}
}
Throw New DirectOutputVBWrapper.HResultException(retVal, errorsMap)
End If
End Sub

Public Function GetDeviceType(ByVal device As IntPtr) As Guid
Dim guidType As Guid
Dim retVal As HResult = _getDeviceType(device, guidType)

If retVal <> DirectOutputVBWrapper.HResultException.S_OK Then
Dim errorsMap As Dictionary(Of HResult, String) = New Dictionary(Of HResult, String)() From {
{DirectOutputVBWrapper.HResultException.E_INVALIDARG, "An argument is invalid."},
{DirectOutputVBWrapper.HResultException.E_HANDLE, "The device handle specified is invalid."}
}
Throw New DirectOutputVBWrapper.HResultException(retVal, errorsMap)
End If

Return guidType
End Function

Public Function GetDeviceInstance(ByVal device As IntPtr) As Guid
Dim guidType As Guid
Dim retVal As HResult = _getDeviceInstance(device, guidType)

If retVal <> DirectOutputVBWrapper.HResultException.S_OK Then
Dim errorsMap As Dictionary(Of HResult, String) = New Dictionary(Of HResult, String)() From {
{DirectOutputVBWrapper.HResultException.E_NOTIMPL, "This device does not support DirectInput."},
{DirectOutputVBWrapper.HResultException.E_INVALIDARG, "An argument is invalid."},
{DirectOutputVBWrapper.HResultException.E_HANDLE, "The device handle specified is invalid."}
}
Throw New DirectOutputVBWrapper.HResultException(retVal, errorsMap)
End If

Return guidType
End Function

Public Sub AddPage(ByVal device As IntPtr, ByVal page As Int32, ByVal flags As Int32)
Dim retVal As HResult = _addPage(device, page, flags)

If retVal <> DirectOutputVBWrapper.HResultException.S_OK Then
Dim errorsMap As Dictionary(Of HResult, String) = New Dictionary(Of HResult, String)() From {
{DirectOutputVBWrapper.HResultException.E_OUTOFMEMORY, "Insufficient memory to complete the request."},
{DirectOutputVBWrapper.HResultException.E_INVALIDARG, "The page parameter already exists."},
{DirectOutputVBWrapper.HResultException.E_HANDLE, "The device handle specified is invalid."}
}
Throw New DirectOutputVBWrapper.HResultException(retVal, errorsMap)
End If
End Sub

Public Sub RemovePage(ByVal device As IntPtr, ByVal page As Int32)
Dim retVal As HResult = _removePage(device, page)

If retVal <> DirectOutputVBWrapper.HResultException.S_OK Then
Dim errorsMap As Dictionary(Of HResult, String) = New Dictionary(Of HResult, String)() From {
{DirectOutputVBWrapper.HResultException.E_INVALIDARG, "The page parameter argument does not reference a valid page id."},
{DirectOutputVBWrapper.HResultException.E_HANDLE, "The device handle specified is invalid."}
}
Throw New DirectOutputVBWrapper.HResultException(retVal, errorsMap)
End If
End Sub

Public Sub SetLed(ByVal device As IntPtr, ByVal page As Int32, ByVal index As Int32, ByVal value As Int32)
Dim retVal As HResult = _setLed(device, page, index, value)

If retVal <> DirectOutputVBWrapper.HResultException.S_OK Then
Dim errorsMap As Dictionary(Of HResult, String) = New Dictionary(Of HResult, String)() From {
{DirectOutputVBWrapper.HResultException.E_PAGENOTACTIVE, "The specified page is not active. Displaying information is not permitted when the page is not active."},
{DirectOutputVBWrapper.HResultException.E_INVALIDARG, "The dwPage argument does not reference a valid page id, or the dwIndex argument does not specifiy a valid LED id."},
{DirectOutputVBWrapper.HResultException.E_HANDLE, "The device handle specified is invalid."}
}
Throw New DirectOutputVBWrapper.HResultException(retVal, errorsMap)
End If
End Sub
End Class
58 changes: 58 additions & 0 deletions test_x56_led/Classes/DllHelper.vb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
Imports System
Imports System.ComponentModel
Imports System.Runtime.InteropServices

Namespace DirectOutputVBWrapper
Class DllHelper
<DllImport("kernel32.dll", EntryPoint:="LoadLibrary")>
Private Shared Function _LoadLibrary(ByVal dllPath As String) As IntPtr
End Function
<DllImport("kernel32.dll", EntryPoint:="GetProcAddress")>
Private Shared Function _GetProcAddress(ByVal hModule As IntPtr, ByVal procedureName As String) As IntPtr
End Function
<DllImport("kernel32.dll", EntryPoint:="FreeLibrary")>
Private Shared Function _FreeLibrary(ByVal hModule As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll", EntryPoint:="GetLastError")>
Private Shared Function _GetLastError() As Integer
End Function

Public Shared Function LoadLibrary(ByVal dllPath As String) As IntPtr
Dim moduleHandle As IntPtr = _LoadLibrary(dllPath)

If moduleHandle = New IntPtr(0) Then
Throw New OutOfMemoryException()
ElseIf moduleHandle = New IntPtr(2) Then
Throw New Exception
ElseIf moduleHandle = New IntPtr(3) Then
Throw New Exception
ElseIf moduleHandle = New IntPtr(11) Then
Throw New Exception
End If

Return moduleHandle
End Function

Public Shared Function GetFunction(Of T As Class)(ByVal hModule As IntPtr, ByVal procedureName As String) As T
Dim addressOfFunctionToCall As IntPtr = _GetProcAddress(hModule, procedureName)

If addressOfFunctionToCall = IntPtr.Zero Then
Throw New Win32Exception(_GetLastError())
End If

Dim functionDelegate As [Delegate] = Marshal.GetDelegateForFunctionPointer(addressOfFunctionToCall, GetType(T))
Return TryCast(functionDelegate, T)
End Function

Public Shared Sub FreeLibrary(ByVal hModule As IntPtr)
Dim isLibraryUnloadedSuccessfully As Boolean = _FreeLibrary(hModule)

If Not isLibraryUnloadedSuccessfully Then
Throw New Win32Exception(_GetLastError())
End If
End Sub
End Class

End Namespace


Loading

0 comments on commit a08966d

Please sign in to comment.