Skip to content

Commit b3f76fb

Browse files
authored
Merge pull request #86 from evilC/wait-with-timeout-zero
Extended keycode fixes
2 parents b0bccf3 + 65d2702 commit b3f76fb

28 files changed

Lines changed: 1129 additions & 269 deletions

C#/AutoHotInterception.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dependencies", "Dependencie
1212
Dependencies\Readme.md = Dependencies\Readme.md
1313
EndProjectSection
1414
EndProject
15+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{8EDF4429-251A-416D-BB68-93F227191BCF}"
16+
EndProject
1517
Global
1618
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1719
Debug|Any CPU = Debug|Any CPU
@@ -26,6 +28,10 @@ Global
2628
{02CBCBB9-C17F-4C6A-8F93-D7EAF038CAED}.Debug|Any CPU.Build.0 = Debug|Any CPU
2729
{02CBCBB9-C17F-4C6A-8F93-D7EAF038CAED}.Release|Any CPU.ActiveCfg = Release|Any CPU
2830
{02CBCBB9-C17F-4C6A-8F93-D7EAF038CAED}.Release|Any CPU.Build.0 = Release|Any CPU
31+
{8EDF4429-251A-416D-BB68-93F227191BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32+
{8EDF4429-251A-416D-BB68-93F227191BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
33+
{8EDF4429-251A-416D-BB68-93F227191BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
34+
{8EDF4429-251A-416D-BB68-93F227191BCF}.Release|Any CPU.Build.0 = Release|Any CPU
2935
EndGlobalSection
3036
GlobalSection(SolutionProperties) = preSolution
3137
HideSolutionNode = FALSE

C#/AutoHotInterception/AutoHotInterception.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<Compile Include="DeviceHandlers\MouseHandler.cs" />
4747
<Compile Include="Helpers\HelperFunctions.cs" />
4848
<Compile Include="Helpers\ManagedWrapper.cs" />
49+
<Compile Include="Helpers\ScanCodeHelper.cs" />
4950
<Compile Include="MappingOptions.cs" />
5051
<Compile Include="ScanCodeChecker.cs" />
5152
<Compile Include="Manager.cs" />

C#/AutoHotInterception/DeviceHandlers/DeviceHandler.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using AutoHotInterception.Helpers;
22
using System;
33
using System.Collections.Concurrent;
4+
using System.Collections.Generic;
45

56
namespace AutoHotInterception.DeviceHandlers
67
{
@@ -37,7 +38,6 @@ public void SubscribeSingleButton(ushort code, MappingOptions mappingOptions)
3738
if (!mappingOptions.Concurrent && !WorkerThreads.ContainsKey(code))
3839
{
3940
WorkerThreads.TryAdd(code, new WorkerThread());
40-
WorkerThreads[code].Start();
4141
}
4242
_isFiltered = true;
4343
}
@@ -68,7 +68,6 @@ public void SubscribeAllButtons(MappingOptions mappingOptions)
6868
if (!mappingOptions.Concurrent && DeviceWorkerThread == null)
6969
{
7070
DeviceWorkerThread = new WorkerThread();
71-
DeviceWorkerThread.Start();
7271
}
7372
_isFiltered = true;
7473
}
@@ -83,6 +82,7 @@ public void UnsubscribeAllButtons()
8382
if (!AllButtonsMapping.Concurrent && DeviceWorkerThread != null)
8483
{
8584
DeviceWorkerThread.Dispose();
85+
DeviceWorkerThread = null;
8686
}
8787
AllButtonsMapping = null;
8888
DisableFilterIfNeeded();
@@ -120,9 +120,9 @@ public int IsFiltered()
120120
public abstract void DisableFilterIfNeeded();
121121

122122
/// <summary>
123-
/// Process an incoming stroke
123+
/// Process an incoming stroke, or a pair of extended keycode strokes
124124
/// </summary>
125-
/// <param name="stroke">The stroke to process</param>
126-
public abstract void ProcessStroke(ManagedWrapper.Stroke stroke);
125+
/// <param name="strokes">The stroke(s) to process</param>
126+
public abstract void ProcessStroke(List<ManagedWrapper.Stroke> strokes);
127127
}
128128
}

C#/AutoHotInterception/DeviceHandlers/IDeviceHandler.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using AutoHotInterception.Helpers;
2+
using System.Collections.Generic;
23

34
namespace AutoHotInterception.DeviceHandlers
45
{
@@ -53,9 +54,9 @@ interface IDeviceHandler
5354
void DisableFilterIfNeeded();
5455

5556
/// <summary>
56-
/// Process an incoming stroke
57+
/// Process an incoming stroke, or a pair of extended keycode strokes
5758
/// </summary>
58-
/// <param name="stroke">The stroke to process</param>
59-
void ProcessStroke(ManagedWrapper.Stroke stroke);
59+
/// <param name="strokes">The stroke(s) to process</param>
60+
void ProcessStroke(List<ManagedWrapper.Stroke> strokes);
6061
}
6162
}

C#/AutoHotInterception/DeviceHandlers/KeyboardHandler.cs

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using AutoHotInterception.Helpers;
22
using System;
33
using System.Collections.Concurrent;
4+
using System.Collections.Generic;
45
using System.Threading;
56

67
namespace AutoHotInterception.DeviceHandlers
@@ -34,25 +35,18 @@ public override void DisableFilterIfNeeded()
3435
/// <param name="state">The State to send (1 = pressed, 0 = released)</param>
3536
public void SendKeyEvent(ushort code, int state)
3637
{
37-
var st = 1 - state;
38-
var stroke = new ManagedWrapper.Stroke();
39-
if (code > 255)
38+
var strokes = ScanCodeHelper.TranslateAhkCode(code, state);
39+
for (int i = 0; i < strokes.Count; i++)
4040
{
41-
code -= 256;
42-
if (code != 54) // RShift has > 256 code, but state is 0/1
43-
st += 2;
41+
var stroke = strokes[i];
42+
ManagedWrapper.Send(DeviceContext, DeviceId, ref stroke, 1);
4443
}
45-
46-
stroke.key.code = code;
47-
stroke.key.state = (ushort)st;
48-
ManagedWrapper.Send(DeviceContext, DeviceId, ref stroke, 1);
4944
}
5045
#endregion
5146

5247
// ScanCode notes: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
53-
public override void ProcessStroke(ManagedWrapper.Stroke stroke)
48+
public override void ProcessStroke(List<ManagedWrapper.Stroke> strokes)
5449
{
55-
//ManagedWrapper.Send(DeviceContext, _deviceId, ref stroke, 1);
5650
var hasSubscription = false;
5751
var hasContext = ContextCallback != null;
5852

@@ -62,7 +56,7 @@ public override void ProcessStroke(ManagedWrapper.Stroke stroke)
6256
if (_isFiltered)
6357
{
6458
var isKeyMapping = false; // True if this is a mapping to a single key, else it would be a mapping to a whole device
65-
var processedState = HelperFunctions.KeyboardStrokeToKeyboardState(stroke);
59+
var processedState = ScanCodeHelper.TranslateScanCodes(strokes);
6660
var code = processedState.Code;
6761
var state = processedState.State;
6862
MappingOptions mapping = null;
@@ -81,41 +75,30 @@ public override void ProcessStroke(ManagedWrapper.Stroke stroke)
8175

8276
if (mapping != null)
8377
{
84-
// Begin translation of incoming key code, state, extended flag etc...
85-
var processMappings = true;
86-
if (processedState.Ignore)
78+
hasSubscription = true;
79+
80+
if (mapping.Block) block = true;
81+
if (mapping.Concurrent)
8782
{
88-
// Set flag to stop Context Mode from firing
89-
hasSubscription = true;
90-
// Set flag to indicate disable mapping processing
91-
processMappings = false;
83+
if (isKeyMapping)
84+
{
85+
ThreadPool.QueueUserWorkItem(threadProc => mapping.Callback(state));
86+
}
87+
else
88+
{
89+
ThreadPool.QueueUserWorkItem(threadProc => mapping.Callback(code, state));
90+
}
9291
}
93-
if (processMappings)
92+
else
9493
{
95-
hasSubscription = true;
96-
97-
if (mapping.Block) block = true;
98-
if (mapping.Concurrent)
94+
//mapping.Callback(code, state);
95+
if (isKeyMapping)
9996
{
100-
if (isKeyMapping)
101-
{
102-
ThreadPool.QueueUserWorkItem(threadProc => mapping.Callback(state));
103-
}
104-
else
105-
{
106-
ThreadPool.QueueUserWorkItem(threadProc => mapping.Callback(code, state));
107-
}
97+
WorkerThreads[code]?.Actions.Add(() => mapping.Callback(state));
10898
}
10999
else
110100
{
111-
if (isKeyMapping)
112-
{
113-
WorkerThreads[code]?.Actions.Add(() => mapping.Callback(state));
114-
}
115-
else
116-
{
117-
DeviceWorkerThread?.Actions.Add(() => mapping.Callback(code, state));
118-
}
101+
DeviceWorkerThread?.Actions.Add(() => mapping.Callback(code, state));
119102
}
120103
}
121104

@@ -127,8 +110,12 @@ public override void ProcessStroke(ManagedWrapper.Stroke stroke)
127110
// ... then set the Context before sending the key
128111
if (!hasSubscription && hasContext) ContextCallback(1);
129112

130-
// Pass the key through to the OS.
131-
ManagedWrapper.Send(DeviceContext, DeviceId, ref stroke, 1);
113+
// Pass the key(s) through to the OS.
114+
for (int i = 0; i < strokes.Count; i++)
115+
{
116+
var stroke = strokes[i];
117+
ManagedWrapper.Send(DeviceContext, DeviceId, ref stroke, 1);
118+
}
132119

133120
// If we are processing Context Mode, then Unset the context variable after sending the key
134121
if (!hasSubscription && hasContext) ContextCallback(0);

0 commit comments

Comments
 (0)