Skip to content

Commit

Permalink
Release 0.10.2
Browse files Browse the repository at this point in the history
  • Loading branch information
evilC committed Apr 13, 2019
2 parents 17f1764 + f734165 commit 2150fca
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 57 deletions.
15 changes: 12 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Removed
### Fixed

##0.10.1 - 2019-01-27
## 0.10.2 - 2019-03-13
### Added
- [DirectInput Provider] Duplicate devices now have #2, #3 etc after their name
### Fixed
- If a provider crashes on load, it no longer stops IOWrapper from loading
- [Interception Provider] Windows keys are now mappable. Previously, if the non-extended scancode did not have a key name, the extended version of the scancode was not checked
- [Interception Provider] F13-F24 are now mappable.
- [Interception Provider] Pause is now mappable.

## 0.10.1 - 2019-01-27
### Changed
- [MIDI Provider] Note path shortened, now selected note displays better in UI
- [MIDI Provider] CC now uses the full -32768..32767 range
Expand All @@ -21,7 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- [MIDI Provider] ProcessUpdate no longer crashes if preProcessedUpdates is null
- [Interception Provider] Left/Right Mouse Wheel labels are no longer switched

##0.10.0 - 2019-01-03
## 0.10.0 - 2019-01-03
### Changed
- Subscription and Bind Mode callbacks are now executed as Tasks and are an Action<short> rather than dynamic
- Default blocking to true while UCR GUI does not support selecting block
Expand Down Expand Up @@ -113,4 +122,4 @@ Difference between v0.9.9 and v0.9.6 is solely the "Fix Interception Bind Mode r
### Fixed
- Do not exit XI poll thread if device disconnected
- XInput LT reporting wrong scale
- Axes not being processed if previous ones were unsubscribed
- Axes not being processed if previous ones were unsubscribed
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<Compile Include="Helpers\HelperFunctions.cs" />
<Compile Include="DeviceLibrary\StaticData.cs" />
<Compile Include="DeviceLibrary\IceptDeviceLibrary.cs" />
<Compile Include="Helpers\KeyNameHelper.cs" />
<Compile Include="IceptKeyboardHandler.cs" />
<Compile Include="IceptMouseHandler.cs" />
<Compile Include="IceptUpdateProcessors.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,13 @@ private void InitMouseReports()
public BindingReport GetInputBindingReport(DeviceDescriptor deviceDescriptor, BindingDescriptor bindingDescriptor)
{
var id = GetDeviceIdentifier(deviceDescriptor);
var dict = HelperFunctions.IsKeyboard(id)
? _keyboardReports
: _mouseReports;
if (!dict.ContainsKey(bindingDescriptor))
{
throw new Exception($"Unknown Binding Index {bindingDescriptor.Index}, SubIndex {bindingDescriptor.SubIndex}, Type {bindingDescriptor.Type}");
}
return HelperFunctions.IsKeyboard(id)
? _keyboardReports[bindingDescriptor]
: _mouseReports[bindingDescriptor];
Expand Down Expand Up @@ -251,25 +258,8 @@ public BindingReport BuildMouseBindingReport(BindingDescriptor bindingDescriptor

public BindingReport BuildKeyboardBindingReport(BindingDescriptor bindingDescriptor)
{
var i = bindingDescriptor.Index;
uint lParam;
if (i > 255)
{
i -= 256;
lParam = (0x100 | ((uint)i + 1 & 0xff)) << 16;
}
else
{
lParam = (uint)(i + 1) << 16;
}

var sb = new StringBuilder(260);
if (ManagedWrapper.GetKeyNameTextW(lParam, sb, 260) == 0)
{
return null;
}
var keyName = sb.ToString().Trim();
if (keyName == "") return null;
var keyName = KeyNameHelper.GetNameFromScanCode(bindingDescriptor.Index + 1);
if (keyName == null) return null;
return new BindingReport
{
Title = keyName,
Expand All @@ -290,17 +280,19 @@ private void InitKeyReports()

for (var i = 0; i < 256; i++)
{
BindingReport report = null;
var bd = new BindingDescriptor
{
Type = BindingType.Button,
Index = i,
SubIndex = 0
};
var report = BuildKeyboardBindingReport(bd);
if (report == null) continue;
_keyboardList.Bindings.Add(report);
_keyboardReports.TryAdd(bd, report);

report = BuildKeyboardBindingReport(bd);
if (report != null)
{
_keyboardList.Bindings.Add(report);
_keyboardReports.TryAdd(bd, report);
}
// Check if this button has an extended (Right) variant
var altBd = new BindingDescriptor
{
Expand All @@ -309,9 +301,11 @@ private void InitKeyReports()
SubIndex = 0
};
var altReport = BuildKeyboardBindingReport(altBd);
if (altReport == null || report.Title == altReport.Title) continue;
_keyboardList.Bindings.Add(altReport);
_keyboardReports.TryAdd(altBd, altReport);
if (altReport != null && (report == null || report.Title != altReport.Title)) // If the alReport is not null, and is not the same as the report (if it exists)
{
_keyboardList.Bindings.Add(altReport);
_keyboardReports.TryAdd(altBd, altReport);
}
}
_keyboardList.Bindings.Sort((x, y) => string.Compare(x.Title, y.Title, StringComparison.Ordinal));
}
Expand Down
49 changes: 49 additions & 0 deletions Source/Core Providers/Core_Interception/Helpers/KeyNameHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Core_Interception.Helpers
{
public static class KeyNameHelper
{
[DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern int GetKeyNameTextW(uint lParam, StringBuilder lpString, int nSize);

// GetKeyNameTextW does not seem to return names for these ScanCodes
private static readonly Dictionary<int, string> MissingKeyNames = new Dictionary<int, string>
{
{ 100, "F13" }, { 101, "F14" }, { 102, "F15" }, { 103, "F16" }, { 104, "F17" }, { 105, "F18" },
{ 106, "F19" }, { 107, "F20" }, { 108, "F21" }, { 109, "F22" }, { 110, "F23" }, { 111, "F24" }
};

public static string GetNameFromScanCode(int code)
{
if (MissingKeyNames.ContainsKey(code))
{
return MissingKeyNames[code];
}
uint lParam;
if (code > 255)
{
code -= 256;
lParam = (0x100 | ((uint)code & 0xff)) << 16;
}
else
{
lParam = (uint)(code) << 16;
}

var sb = new StringBuilder(260);
if (GetKeyNameTextW(lParam, sb, 260) == 0)
{
return null;
}
var keyName = sb.ToString().Trim();
if (keyName == "") return null;
return keyName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ protected override BindingUpdate[] PreProcessUpdate(ManagedWrapper.Stroke update
// If state is shifted up by 2 (1 or 2 instead of 0 or 1), then this is an "Extended" key code
if (state > 1)
{
if (code == 42)
if (code == 42 || state > 3)
{
// Code == 42
// Shift (42/0x2a) with extended flag = the key after this one is extended.
// Example case is Delete (The one above the arrow keys, not on numpad)...
// ... this generates a stroke of 0x2a (Shift) with *extended flag set* (Normal shift does not do this)...
Expand All @@ -44,6 +45,10 @@ protected override BindingUpdate[] PreProcessUpdate(ManagedWrapper.Stroke update
// ... it will have code 0x53, which we shift to 0x153 (Adding 256 Dec) to signify extended version...
// ... as this is how AHK behaves with GetKeySC()

// state > 3
// Pause sends code 69 normally as state 0/1, but also LCtrl (29) as state 4/5
// Ignore the LCtrl in this case

// return false to not block this stroke
return new BindingUpdate[0];
}
Expand Down
3 changes: 0 additions & 3 deletions Source/Core Providers/Core_Interception/Lib/ManagedWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,6 @@ public static string GetHardwareStr(IntPtr context, int device, int chars = 0)
int INTERCEPTION_API interception_is_mouse(InterceptionDevice device);
*/

[DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int GetKeyNameTextW(uint lParam, StringBuilder lpString, int nSize);

#endregion

}
Expand Down
4 changes: 3 additions & 1 deletion Source/Core Providers/Core_Tobii_Interaction/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Adds support for the [Tobii Eye Tracker](https://tobiigaming.com/)
Eye position and head tracking data
Eye position and head tracking data

Requires the [Visual C++ Redistributable for Visual Studio 2012](https://www.microsoft.com/en-us/download/details.aspx?id=30679)
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public DeviceReport GetInputDeviceReport(DeviceDescriptor deviceDescriptor, Guid
var deviceReport = new DeviceReport
{
DeviceDescriptor = deviceDescriptor,
DeviceName = joystick.Information.ProductName,
DeviceName = $"{joystick.Information.ProductName}{(deviceDescriptor.DeviceInstance > 0 ? $" # {deviceDescriptor.DeviceInstance + 1}" : "")}",
HidPath = joystick.Properties.InterfacePath
};

Expand Down
9 changes: 4 additions & 5 deletions Source/Core/GenericMEFPluginLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ You may obtain a copy of the License at
limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
Expand All @@ -23,10 +24,8 @@ namespace HidWizards.IOWrapper.Core
{
public class GenericMEFPluginLoader<T>
{
private CompositionContainer _Container;

[ImportMany]
public IEnumerable<T> Plugins
public Lazy<T>[] Plugins
{
get;
set;
Expand All @@ -46,8 +45,8 @@ public GenericMEFPluginLoader(string basePath)
}
}

_Container = new CompositionContainer(catalog);
_Container.ComposeParts(this);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
}
44 changes: 28 additions & 16 deletions Source/Core/IOController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Collections.Generic;
using System;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Linq;
using HidWizards.IOWrapper.DataTransferObjects;
using HidWizards.IOWrapper.ProviderInterface;
using HidWizards.IOWrapper.ProviderInterface.Interfaces;
Expand All @@ -12,20 +14,30 @@ public enum InputTypes { Button, Axis }
public class IOController : IDisposable
{
bool disposed;
private Dictionary<string, IProvider> _Providers;
private Dictionary<Guid, InputSubscriptionRequest> ActiveInputSubscriptions = new Dictionary<Guid, InputSubscriptionRequest>();
private Dictionary<Guid, OutputSubscriptionRequest> ActiveOutputSubscriptions = new Dictionary<Guid, OutputSubscriptionRequest>();
private Dictionary<string, IProvider> _providers;
private readonly Dictionary<Guid, InputSubscriptionRequest> ActiveInputSubscriptions = new Dictionary<Guid, InputSubscriptionRequest>();
private readonly Dictionary<Guid, OutputSubscriptionRequest> ActiveOutputSubscriptions = new Dictionary<Guid, OutputSubscriptionRequest>();

public IOController()
{
GenericMEFPluginLoader<IProvider> loader = new GenericMEFPluginLoader<IProvider>("Providers");
_Providers = new Dictionary<string, IProvider>();
IEnumerable<IProvider> providers = loader.Plugins;
var loader = new GenericMEFPluginLoader<IProvider>("Providers");
_providers = new Dictionary<string, IProvider>();
var providers = loader.Plugins;
Log("Initializing...");
foreach (var provider in providers)
foreach (var lazyProvider in providers)
{
_Providers[provider.ProviderName] = provider;
Log("Initialized Provider {0}", provider.ProviderName);
try
{
var provider = lazyProvider.Value;
_providers[provider.ProviderName] = provider;
Log("Initialized Provider {0}", provider.ProviderName);
}
catch(CompositionException ex)
{
// Plugin failed to load
Log(ex.RootCauses.First().Message);
}

}
Log("Initialization complete");
}
Expand All @@ -46,11 +58,11 @@ protected virtual void Dispose(bool disposing)
return;
if (disposing)
{
foreach (var provider in _Providers.Values)
foreach (var provider in _providers.Values)
{
provider.Dispose();
}
_Providers = null;
_providers = null;
}
disposed = true;
Log("Disposed");
Expand All @@ -64,7 +76,7 @@ private static void Log(string formatStr, params object[] arguments)
public SortedDictionary<string, ProviderReport> GetInputList()
{
var list = new SortedDictionary<string, ProviderReport>();
foreach (var provider in _Providers.Values)
foreach (var provider in _providers.Values)
{
if (!(provider is IInputProvider prov)) continue;
var report = prov.GetInputList();
Expand All @@ -79,7 +91,7 @@ public SortedDictionary<string, ProviderReport> GetInputList()
public SortedDictionary<string, ProviderReport> GetOutputList()
{
var list = new SortedDictionary<string, ProviderReport>();
foreach (var provider in _Providers.Values)
foreach (var provider in _providers.Values)
{
if (!(provider is IOutputProvider prov)) continue;
var report = prov.GetOutputList();
Expand Down Expand Up @@ -245,7 +257,7 @@ public bool IsProviderLive(string providerName)

public void RefreshDevices()
{
foreach (var provider in _Providers.Values)
foreach (var provider in _providers.Values)
{
provider.RefreshDevices();
}
Expand All @@ -259,8 +271,8 @@ public void RefreshDevices(string providerName)

public IProvider GetProvider(string providerName)
{
if (!_Providers.ContainsKey(providerName)) throw new Exception($"Provider {providerName} Not found");
return _Providers[providerName];
if (!_providers.ContainsKey(providerName)) throw new Exception($"Provider {providerName} Not found");
return _providers[providerName];
}

public TInterface GetProvider<TInterface>(IProvider provider)
Expand Down
2 changes: 2 additions & 0 deletions Source/TestApp/Library/Devices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public static class Interception
public static DeviceDescriptor DellKeyboard2 = new DeviceDescriptor { DeviceHandle = "Keyboard\\HID\\VID_413C&PID_2107&REV_0178", DeviceInstance = 1};
public static DeviceDescriptor LogitechWeelMouseUSB = new DeviceDescriptor { DeviceHandle = "Mouse\\HID\\VID_046D&PID_C00C&REV_0620" };
public static DeviceDescriptor LogitechReceiverMouse = new DeviceDescriptor { DeviceHandle = "Mouse\\HID\\VID_046D&PID_C531&REV_2100&MI_00" };
public static DeviceDescriptor LogitechMouseKeyboard = new DeviceDescriptor { DeviceHandle = "Keyboard\\HID\\VID_046D&PID_C531&REV_2100&MI_01&Col01" };

}

/// <summary>
Expand Down

0 comments on commit 2150fca

Please sign in to comment.