Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
403 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
#include "unity/main.h" | ||
#include "unity/file.h" | ||
|
||
class Program : public ProgramBase | ||
{ | ||
public: | ||
int run() | ||
{ | ||
_com.set(CreateFile( | ||
L"COM3", | ||
GENERIC_READ | GENERIC_WRITE, | ||
0, // must be opened with exclusive-access | ||
NULL, // default security attributes | ||
OPEN_EXISTING, // must use OPEN_EXISTING | ||
0, // not overlapped I/O | ||
NULL)); // hTemplate must be NULL for comm devices | ||
|
||
DCB deviceControlBlock; | ||
SecureZeroMemory(&deviceControlBlock, sizeof(DCB)); | ||
|
||
IF_ZERO_THROW(GetCommState(_com, &deviceControlBlock)); | ||
|
||
deviceControlBlock.DCBlength = sizeof(DCB); | ||
deviceControlBlock.BaudRate = CBR_9600; | ||
//deviceControlBlock.fBinary = TRUE; | ||
//deviceControlBlock.fParity = FALSE; | ||
deviceControlBlock.fOutxCtsFlow = FALSE; | ||
deviceControlBlock.fOutxDsrFlow = FALSE; | ||
// DTR_CONTROL_ENABLE causes Arduino to reset on connect | ||
//deviceControlBlock.fDtrControl = DTR_CONTROL_ENABLE; | ||
deviceControlBlock.fDtrControl = DTR_CONTROL_DISABLE; | ||
//deviceControlBlock.fDsrSensitivity = FALSE; | ||
//deviceControlBlock.fTXContinueOnXoff = TRUE; | ||
deviceControlBlock.fOutX = TRUE; | ||
deviceControlBlock.fInX = TRUE; | ||
//deviceControlBlock.fErrorChar = FALSE; | ||
deviceControlBlock.fNull = FALSE; | ||
//deviceControlBlock.fRtsControl = RTS_CONTROL_DISABLE; | ||
//deviceControlBlock.fAbortOnError = FALSE; | ||
//deviceControlBlock.wReserved = 0; | ||
deviceControlBlock.ByteSize = 8; | ||
deviceControlBlock.Parity = NOPARITY; | ||
deviceControlBlock.StopBits = ONESTOPBIT; | ||
deviceControlBlock.XonChar = 17; | ||
deviceControlBlock.XoffChar = 19; | ||
|
||
IF_ZERO_THROW(SetCommState(_com, &deviceControlBlock)); | ||
|
||
sendByte(0x7f); // Put Arduino in raw mode | ||
|
||
Window::Params wp(&_windows, L"Virtual keyboard"); | ||
typedef RootWindow<Window> RootWindow; | ||
RootWindow::Params rwp(wp); | ||
typedef KeyboardWindow<RootWindow> KeyboardWindow; | ||
KeyboardWindow::Params kwp(rwp, this); | ||
KeyboardWindow window(kwp); | ||
|
||
window.show(_nCmdShow); | ||
return pumpMessages(); | ||
} | ||
private: | ||
template<class Base> class KeyboardWindow : public Base | ||
{ | ||
public: | ||
class Params | ||
{ | ||
friend class KeyboardWindow; | ||
public: | ||
Params(typename Base::Params bp, Program* program) | ||
: _bp(bp), _program(program) { } | ||
private: | ||
typename Base::Params _bp; | ||
Program* _program; | ||
}; | ||
|
||
KeyboardWindow(Params p) : Base(p._bp), _program(p._program), | ||
_lShift(false), _rShift(false) { } | ||
protected: | ||
virtual LRESULT handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) | ||
{ | ||
switch (uMsg) { | ||
case WM_KEYDOWN: | ||
case WM_SYSKEYDOWN: | ||
doKey(wParam, false); | ||
return 0; | ||
case WM_KEYUP: | ||
case WM_SYSKEYUP: | ||
doKey(wParam, true); | ||
return 0; | ||
} | ||
return Base::handleMessage(uMsg, wParam, lParam); | ||
} | ||
private: | ||
|
||
void doKey(int key, bool up) | ||
{ | ||
int scanCode = 0; | ||
switch (key) { | ||
case VK_BACK: scanCode = 0x0e; break; | ||
case VK_TAB: scanCode = 0x0f; break; | ||
case VK_RETURN: scanCode = 0x1c; break; | ||
case VK_CONTROL: scanCode = 0x1d; break; | ||
case VK_MENU: scanCode = 0x38; break; | ||
case VK_CAPITAL: scanCode = 0x3a; break; | ||
case VK_ESCAPE: scanCode = 0x01; break; | ||
case VK_SPACE: scanCode = 0x39; break; | ||
case VK_PRIOR: scanCode = 0x49; break; | ||
case VK_NEXT: scanCode = 0x51; break; | ||
case VK_END: scanCode = 0x4f; break; | ||
case VK_HOME: scanCode = 0x47; break; | ||
case VK_LEFT: scanCode = 0x4b; break; | ||
case VK_UP: scanCode = 0x48; break; | ||
case VK_RIGHT: scanCode = 0x4d; break; | ||
case VK_DOWN: scanCode = 0x50; break; | ||
case VK_SNAPSHOT: scanCode = 0x37; break; | ||
case VK_INSERT: scanCode = 0x52; break; | ||
case VK_DELETE: scanCode = 0x53; break; | ||
case '0': scanCode = 0x0b; break; | ||
case '1': scanCode = 0x02; break; | ||
case '2': scanCode = 0x03; break; | ||
case '3': scanCode = 0x04; break; | ||
case '4': scanCode = 0x05; break; | ||
case '5': scanCode = 0x06; break; | ||
case '6': scanCode = 0x07; break; | ||
case '7': scanCode = 0x08; break; | ||
case '8': scanCode = 0x09; break; | ||
case '9': scanCode = 0x0a; break; | ||
case 'A': scanCode = 0x1e; break; | ||
case 'B': scanCode = 0x30; break; | ||
case 'C': scanCode = 0x2e; break; | ||
case 'D': scanCode = 0x20; break; | ||
case 'E': scanCode = 0x12; break; | ||
case 'F': scanCode = 0x21; break; | ||
case 'G': scanCode = 0x22; break; | ||
case 'H': scanCode = 0x23; break; | ||
case 'I': scanCode = 0x17; break; | ||
case 'J': scanCode = 0x24; break; | ||
case 'K': scanCode = 0x25; break; | ||
case 'L': scanCode = 0x26; break; | ||
case 'M': scanCode = 0x32; break; | ||
case 'N': scanCode = 0x31; break; | ||
case 'O': scanCode = 0x18; break; | ||
case 'P': scanCode = 0x19; break; | ||
case 'Q': scanCode = 0x10; break; | ||
case 'R': scanCode = 0x13; break; | ||
case 'S': scanCode = 0x1f; break; | ||
case 'T': scanCode = 0x14; break; | ||
case 'U': scanCode = 0x16; break; | ||
case 'V': scanCode = 0x2f; break; | ||
case 'W': scanCode = 0x11; break; | ||
case 'X': scanCode = 0x2d; break; | ||
case 'Y': scanCode = 0x15; break; | ||
case 'Z': scanCode = 0x2c; break; | ||
case VK_NUMPAD0: scanCode = 0x52; break; | ||
case VK_NUMPAD1: scanCode = 0x4f; break; | ||
case VK_NUMPAD2: scanCode = 0x50; break; | ||
case VK_NUMPAD3: scanCode = 0x51; break; | ||
case VK_NUMPAD4: scanCode = 0x4b; break; | ||
case VK_NUMPAD5: scanCode = 0x4c; break; | ||
case VK_NUMPAD6: scanCode = 0x4d; break; | ||
case VK_NUMPAD7: scanCode = 0x47; break; | ||
case VK_NUMPAD8: scanCode = 0x48; break; | ||
case VK_NUMPAD9: scanCode = 0x49; break; | ||
case VK_MULTIPLY: scanCode = 0x37; break; | ||
case VK_ADD: scanCode = 0x4e; break; | ||
case VK_SUBTRACT: scanCode = 0x4a; break; | ||
case VK_DECIMAL: scanCode = 0x53; break; | ||
case VK_DIVIDE: scanCode = 0x35; break; | ||
case VK_F1: scanCode = 0x3b; break; | ||
case VK_F2: scanCode = 0x3c; break; | ||
case VK_F3: scanCode = 0x3d; break; | ||
case VK_F4: scanCode = 0x3e; break; | ||
case VK_F5: scanCode = 0x3f; break; | ||
case VK_F6: scanCode = 0x40; break; | ||
case VK_F7: scanCode = 0x41; break; | ||
case VK_F8: scanCode = 0x42; break; | ||
case VK_F9: scanCode = 0x43; break; | ||
case VK_F10: scanCode = 0x44; break; | ||
case VK_NUMLOCK: scanCode = 0x45; break; | ||
case VK_SCROLL: scanCode = 0x46; break; | ||
case VK_SHIFT: | ||
{ | ||
bool lShift = ((GetKeyState(VK_LSHIFT) & 0x80000000) != 0); | ||
bool rShift = ((GetKeyState(VK_RSHIFT) & 0x80000000) != 0); | ||
if (lShift != _lShift) { | ||
_program->sendByte(lShift ? 0x2a : 0xaa); | ||
_lShift = lShift; | ||
} | ||
if (rShift != _rShift) { | ||
_program->sendByte(rShift ? 0x36 : 0xb6); | ||
_rShift = rShift; | ||
} | ||
} | ||
return; | ||
case VK_OEM_1: scanCode = 0x27; break; | ||
case VK_OEM_PLUS: scanCode = 0x0d; break; | ||
case VK_OEM_COMMA: scanCode = 0x33; break; | ||
case VK_OEM_MINUS: scanCode = 0x0c; break; | ||
case VK_OEM_PERIOD: scanCode = 0x34; break; | ||
case VK_OEM_2: scanCode = 0x35; break; | ||
case VK_OEM_3: scanCode = 0x29; break; | ||
case VK_OEM_4: scanCode = 0x1a; break; | ||
case VK_OEM_5: scanCode = 0x2b; break; | ||
case VK_OEM_6: scanCode = 0x1b; break; | ||
case VK_OEM_7: scanCode = 0x28; break; | ||
default: return; | ||
} | ||
_program->sendByte(scanCode | (up ? 0x80 : 0)); | ||
} | ||
Program* _program; | ||
bool _lShift; | ||
bool _rShift; | ||
}; | ||
void sendByte(Byte value) | ||
{ | ||
// Escape for XON/XOFF | ||
if (value == 0 || value == 17 || value == 19) | ||
_com.write<Byte>(0); | ||
_com.write<Byte>(value); | ||
} | ||
|
||
AutoHandle _com; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 11.00 | ||
# Visual Studio 2010 | ||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "keyboard", "keyboard.vcxproj", "{1F483CB5-3767-41E6-BC98-81C575AAA53C}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Win32 = Debug|Win32 | ||
Release|Win32 = Release|Win32 | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{1F483CB5-3767-41E6-BC98-81C575AAA53C}.Debug|Win32.ActiveCfg = Debug|Win32 | ||
{1F483CB5-3767-41E6-BC98-81C575AAA53C}.Debug|Win32.Build.0 = Debug|Win32 | ||
{1F483CB5-3767-41E6-BC98-81C575AAA53C}.Release|Win32.ActiveCfg = Release|Win32 | ||
{1F483CB5-3767-41E6-BC98-81C575AAA53C}.Release|Win32.Build.0 = Release|Win32 | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<ItemGroup Label="ProjectConfigurations"> | ||
<ProjectConfiguration Include="Debug|Win32"> | ||
<Configuration>Debug</Configuration> | ||
<Platform>Win32</Platform> | ||
</ProjectConfiguration> | ||
<ProjectConfiguration Include="Release|Win32"> | ||
<Configuration>Release</Configuration> | ||
<Platform>Win32</Platform> | ||
</ProjectConfiguration> | ||
</ItemGroup> | ||
<PropertyGroup Label="Globals"> | ||
<ProjectGuid>{1F483CB5-3767-41E6-BC98-81C575AAA53C}</ProjectGuid> | ||
<Keyword>Win32Proj</Keyword> | ||
<RootNamespace>keyboard</RootNamespace> | ||
</PropertyGroup> | ||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||
<ConfigurationType>Application</ConfigurationType> | ||
<UseDebugLibraries>true</UseDebugLibraries> | ||
<CharacterSet>Unicode</CharacterSet> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||
<ConfigurationType>Application</ConfigurationType> | ||
<UseDebugLibraries>false</UseDebugLibraries> | ||
<WholeProgramOptimization>true</WholeProgramOptimization> | ||
<CharacterSet>Unicode</CharacterSet> | ||
</PropertyGroup> | ||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||
<ImportGroup Label="ExtensionSettings"> | ||
</ImportGroup> | ||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||
</ImportGroup> | ||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||
</ImportGroup> | ||
<PropertyGroup Label="UserMacros" /> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||
<LinkIncremental>true</LinkIncremental> | ||
<IncludePath>D:\t\reenigne\include;$(IncludePath)</IncludePath> | ||
</PropertyGroup> | ||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||
<LinkIncremental>false</LinkIncremental> | ||
<IncludePath>D:\t\reenigne\include;$(IncludePath)</IncludePath> | ||
</PropertyGroup> | ||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||
<ClCompile> | ||
<PrecompiledHeader> | ||
</PrecompiledHeader> | ||
<WarningLevel>Level3</WarningLevel> | ||
<Optimization>Disabled</Optimization> | ||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
</ClCompile> | ||
<Link> | ||
<SubSystem>Windows</SubSystem> | ||
<GenerateDebugInformation>true</GenerateDebugInformation> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||
<ClCompile> | ||
<WarningLevel>Level3</WarningLevel> | ||
<PrecompiledHeader> | ||
</PrecompiledHeader> | ||
<Optimization>MaxSpeed</Optimization> | ||
<FunctionLevelLinking>true</FunctionLevelLinking> | ||
<IntrinsicFunctions>true</IntrinsicFunctions> | ||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
</ClCompile> | ||
<Link> | ||
<SubSystem>Windows</SubSystem> | ||
<GenerateDebugInformation>true</GenerateDebugInformation> | ||
<EnableCOMDATFolding>true</EnableCOMDATFolding> | ||
<OptimizeReferences>true</OptimizeReferences> | ||
</Link> | ||
</ItemDefinitionGroup> | ||
<ItemGroup> | ||
<ClCompile Include="keyboard.cpp" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ClInclude Include="..\..\..\include\unity\file.h" /> | ||
<ClInclude Include="..\..\..\include\unity\main.h" /> | ||
<ClInclude Include="..\..\..\include\unity\user.h" /> | ||
</ItemGroup> | ||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||
<ImportGroup Label="ExtensionTargets"> | ||
</ImportGroup> | ||
</Project> |
Oops, something went wrong.