cec: added a C++ CLR wrapper for libCEC, so libCEC can be used by any .NET language...
authorLars Op den Kamp <lars@opdenkamp.eu>
Sun, 13 Nov 2011 19:47:14 +0000 (20:47 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Sun, 13 Nov 2011 20:04:56 +0000 (21:04 +0100)
16 files changed:
.gitignore
README
project/CecSharpClient.sln [new file with mode: 0644]
project/LibCecSharp.vcxproj [new file with mode: 0644]
project/LibCecSharp.vcxproj.filters [new file with mode: 0644]
project/libCEC.nsi
project/libcec.sln
src/CecSharpTester/AssemblyInfo.cs [new file with mode: 0644]
src/CecSharpTester/CecSharpClient.cs [new file with mode: 0644]
src/CecSharpTester/CecSharpClient.csproj [new file with mode: 0644]
src/LibCecSharp/AssemblyInfo.cpp [new file with mode: 0644]
src/LibCecSharp/LibCecSharp.cpp [new file with mode: 0644]
src/LibCecSharp/LibCecSharp.suo [new file with mode: 0644]
src/LibCecSharp/Stdafx.cpp [new file with mode: 0644]
src/LibCecSharp/Stdafx.h [new file with mode: 0644]
src/LibCecSharp/resource.h [new file with mode: 0644]

index e196aa93c1abec77ca760b5e01a2aad495bc0892..2ad44d538bcec269395fe1118fe4b0393a5eac47 100644 (file)
@@ -1,5 +1,6 @@
 .project
 .cproject
+*.manifest
 
 aclocal.m4
 autom4te.cache
@@ -25,18 +26,28 @@ libcec.pdb
 cec-client.exe
 cec-client.ilk
 cec-client.pdb
+CecSharpClient.exe
+CecSharpClient.pdb
+CecSharpClient.vshost.exe
+CecSharpClient.vshost.exe.manifest
+
+LibCecSharp.dll
+LibCecSharp.ilk
+LibCecSharp.pdb
 
 build
 
 include/boost
 
-project/boost-1_46_1-xbmc-win32
+project/bin
 project/Debug/
+project/Release/
 project/ipch/
 project/libcec.sdf
 project/libcec.suo
-project/libcec.vcxproj.user
-project/testclient.vcxproj.user
+project/obj
+project/Properties
+project/*.user
 
 src/lib/.deps
 src/lib/.libs
@@ -59,6 +70,7 @@ src/testclient/.libs
 src/testclient/cec-client
 src/testclient/*.o
 
+src/CecSharpTester/obj
 
 /dpinst-x86.exe
 /dpinst-amd64.exe
diff --git a/README b/README
index 6c23712ff3c8a82c0c22f15d54e653ab231a3f41..5ef90e3c5f830551c79b8b23a4c46ab7ed973df1 100644 (file)
--- a/README
+++ b/README
@@ -22,6 +22,12 @@ Test the device:
 
 For developers:
 * see /include/cec.h for the C++ API and /include/cecc.h for the C version.
+* see src/testclient/main.cpp for an example
+
+For .NET developers:
+* build project/libcec.sln first
+* add a reference to LibCecSharp.dll
+* see src\CecSharpTester\CecSharpClient.cs for an example
 
 If you wish to contribute to this project, you must first sign our contributors agreement
 Please see http://www.pulse-eight.net/contributors for more information
\ No newline at end of file
diff --git a/project/CecSharpClient.sln b/project/CecSharpClient.sln
new file mode 100644 (file)
index 0000000..0a4d822
--- /dev/null
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CecSharpClient", "..\src\CecSharpTester\CecSharpClient.csproj", "{47EF8EFE-5758-4E82-B9BA-F9B002F9C0D4}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|x86 = Debug|x86
+               Release|x86 = Release|x86
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {47EF8EFE-5758-4E82-B9BA-F9B002F9C0D4}.Debug|x86.ActiveCfg = Debug|x86
+               {47EF8EFE-5758-4E82-B9BA-F9B002F9C0D4}.Debug|x86.Build.0 = Debug|x86
+               {47EF8EFE-5758-4E82-B9BA-F9B002F9C0D4}.Release|x86.ActiveCfg = Release|x86
+               {47EF8EFE-5758-4E82-B9BA-F9B002F9C0D4}.Release|x86.Build.0 = Release|x86
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/project/LibCecSharp.vcxproj b/project/LibCecSharp.vcxproj
new file mode 100644 (file)
index 0000000..2ced898
--- /dev/null
@@ -0,0 +1,101 @@
+<?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>{1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}</ProjectGuid>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <Keyword>ManagedCProj</Keyword>
+    <RootNamespace>LibCecSharp</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CLRSupport>true</CLRSupport>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <CLRSupport>true</CLRSupport>
+    <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>$(SolutionDir)\..\include;$(IncludePath)</IncludePath>
+    <TargetName>$(ProjectName)</TargetName>
+    <OutDir>$(SolutionDir)..\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>$(SolutionDir)\..\include;$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>
+      </AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>
+      </AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\include\cec.h" />
+    <ClInclude Include="..\include\cectypes.h" />
+    <ClInclude Include="..\src\LibCecSharp\resource.h" />
+    <ClInclude Include="..\src\LibCecSharp\Stdafx.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\src\LibCecSharp\AssemblyInfo.cpp" />
+    <ClCompile Include="..\src\LibCecSharp\LibCecSharp.cpp" />
+    <ClCompile Include="..\src\LibCecSharp\Stdafx.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="libcec.vcxproj">
+      <Project>{c04b0fb1-667d-4f1c-bdae-a07cdffaaaa0}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/project/LibCecSharp.vcxproj.filters b/project/LibCecSharp.vcxproj.filters
new file mode 100644 (file)
index 0000000..cdfa851
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\src\LibCecSharp\resource.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\src\LibCecSharp\Stdafx.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\cec.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\cectypes.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\src\LibCecSharp\AssemblyInfo.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\src\LibCecSharp\LibCecSharp.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\src\LibCecSharp\Stdafx.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
index eaf10932e36d54215ddbf196183116a5d6561b98..ee6df6e1561a47f71bae74834b6f8c6624d208c9 100644 (file)
@@ -52,6 +52,7 @@ Section "libCEC" SecLibCEC
   File "..\COPYING"
   File "..\libcec.dll"
   File "..\libcec.lib"
+  File "..\LibCecSharp.dll"
   File "..\pthreadVC2.dll"
   File "..\README"
 
@@ -130,6 +131,7 @@ Section "Uninstall"
   Delete "$INSTDIR\libcec.dll"
   Delete "$INSTDIR\libcec.lib"
   Delete "$INSTDIR\libcec.pdb"
+  Delete "$INSTDIR\LibCecSharp.dll"
   Delete "$INSTDIR\pthreadVC2.dll"
   Delete "$INSTDIR\README"
   Delete "$INSTDIR\driver\OEM001.inf"
index 2255a1b0f0f9362ea2ac5c53b70d8b2e0f5d2644..facfeceea5b7e2141020f2bb1cbbd1003b8f8714 100644 (file)
@@ -8,20 +8,59 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testclient", "testclient.vc
                {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0} = {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}
        EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibCecSharp", "LibCecSharp.vcxproj", "{1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}"
+       ProjectSection(ProjectDependencies) = postProject
+               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0} = {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Debug|Mixed Platforms = Debug|Mixed Platforms
                Debug|Win32 = Debug|Win32
+               Debug|x86 = Debug|x86
+               Release|Any CPU = Release|Any CPU
+               Release|Mixed Platforms = Release|Mixed Platforms
                Release|Win32 = Release|Win32
+               Release|x86 = Release|x86
        EndGlobalSection
        GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Debug|Any CPU.ActiveCfg = Debug|Win32
+               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Debug|Mixed Platforms.Build.0 = Debug|Win32
                {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Debug|Win32.ActiveCfg = Debug|Win32
                {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Debug|Win32.Build.0 = Debug|Win32
+               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Debug|x86.ActiveCfg = Debug|Win32
+               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Release|Any CPU.ActiveCfg = Release|Win32
+               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Release|Mixed Platforms.Build.0 = Release|Win32
                {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Release|Win32.ActiveCfg = Release|Win32
                {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Release|Win32.Build.0 = Release|Win32
+               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}.Release|x86.ActiveCfg = Release|Win32
+               {F01222BF-6B3D-43BD-B254-434031CB9887}.Debug|Any CPU.ActiveCfg = Debug|Win32
+               {F01222BF-6B3D-43BD-B254-434031CB9887}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+               {F01222BF-6B3D-43BD-B254-434031CB9887}.Debug|Mixed Platforms.Build.0 = Debug|Win32
                {F01222BF-6B3D-43BD-B254-434031CB9887}.Debug|Win32.ActiveCfg = Debug|Win32
                {F01222BF-6B3D-43BD-B254-434031CB9887}.Debug|Win32.Build.0 = Debug|Win32
+               {F01222BF-6B3D-43BD-B254-434031CB9887}.Debug|x86.ActiveCfg = Debug|Win32
+               {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|Any CPU.ActiveCfg = Release|Win32
+               {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+               {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|Mixed Platforms.Build.0 = Release|Win32
                {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|Win32.ActiveCfg = Release|Win32
                {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|Win32.Build.0 = Release|Win32
+               {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|x86.ActiveCfg = Release|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Debug|Any CPU.ActiveCfg = Debug|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Debug|Win32.ActiveCfg = Debug|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Debug|Win32.Build.0 = Debug|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Debug|x86.ActiveCfg = Debug|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Release|Any CPU.ActiveCfg = Release|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Release|Mixed Platforms.Build.0 = Release|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Release|Win32.ActiveCfg = Release|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Release|Win32.Build.0 = Release|Win32
+               {1AC27FBD-653A-4F5F-ADBC-2A8FD074EEB7}.Release|x86.ActiveCfg = Release|Win32
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
diff --git a/src/CecSharpTester/AssemblyInfo.cs b/src/CecSharpTester/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..058bbb9
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CecSharpClient")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Pulse-Eight Ltd.")]
+[assembly: AssemblyProduct("CecSharpClient")]
+[assembly: AssemblyCopyright("Copyright © Pulse-Eight Ltd. 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("fb8d5961-9ba9-4e56-8706-ac150183706f")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/CecSharpTester/CecSharpClient.cs b/src/CecSharpTester/CecSharpClient.cs
new file mode 100644 (file)
index 0000000..0cd6aeb
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace CecSharpClient
+{
+  class CecSharpClient
+  {
+    public CecSharpClient()
+    {
+      CecDeviceTypeList types = new CecDeviceTypeList();
+      types.Types[0] = CecDeviceType.PlaybackDevice;
+
+      Lib = new LibCecSharp("CEC Tester", types);
+      LogLevel = (int) CecLogLevel.All;
+
+      Console.WriteLine("CEC Parser created - libcec version " + Lib.GetLibVersionMajor() + "." + Lib.GetLibVersionMinor());
+    }
+
+    void FlushLog()
+    {
+      CecLogMessage message = Lib.GetNextLogMessage();
+      bool bGotMessage = !message.Empty;
+      while (bGotMessage)
+      {
+        if (((int)message.Level & LogLevel) == (int)message.Level)
+        {
+          string strLevel = "";
+          switch (message.Level)
+          {
+            case CecLogLevel.Error:
+              strLevel = "ERROR:   ";
+              break;
+            case CecLogLevel.Warning:
+              strLevel = "WARNING: ";
+              break;
+            case CecLogLevel.Notice:
+              strLevel = "NOTICE:  ";
+              break;
+            case CecLogLevel.Traffic:
+              strLevel = "TRAFFIC: ";
+              break;
+            case CecLogLevel.Debug:
+              strLevel = "DEBUG:   ";
+              break;
+            default:
+              break;
+          }
+          string strLog = string.Format("{0} {1,16} {2}", strLevel, message.Time, message.Message);
+          Console.WriteLine(strLog);
+        }
+
+        message = Lib.GetNextLogMessage();
+        bGotMessage = !message.Empty;
+      }
+    }
+
+    public bool Connect(int timeout)
+    {
+      CecAdapter[] adapters = Lib.FindAdapters(string.Empty);
+      if (adapters.Length > 0)
+        return Connect(adapters[0].ComPort, timeout);
+      else
+      {
+        Console.WriteLine("Did not find any CEC adapters");
+        return false;
+      }
+    }
+
+    public bool Connect(string port, int timeout)
+    {
+      return Lib.Open(port, timeout);
+    }
+
+    public void Close()
+    {
+      Lib.Close();
+    }
+
+    public void ListDevices()
+    {
+      int iAdapter = 0;
+      foreach (CecAdapter adapter in Lib.FindAdapters(string.Empty))
+      {
+        Console.WriteLine("Adapter:  " + iAdapter++);
+        Console.WriteLine("Path:     " + adapter.Path);
+        Console.WriteLine("Com port: " + adapter.ComPort);
+      }
+    }
+
+    void ShowConsoleHelp()
+    {
+      Console.WriteLine(
+        "================================================================================" + System.Environment.NewLine +
+        "Available commands:" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "tx {bytes}                transfer bytes over the CEC line." + System.Environment.NewLine +
+        "txn {bytes}               transfer bytes but don't wait for transmission ACK." + System.Environment.NewLine +
+        "[tx 40 00 FF 11 22 33]    sends bytes 0x40 0x00 0xFF 0x11 0x22 0x33" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "on {address}              power on the device with the given logical address." + System.Environment.NewLine +
+        "[on 5]                    power on a connected audio system" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "standby {address}         put the device with the given address in standby mode." + System.Environment.NewLine +
+        "[standby 0]               powers off the TV" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "la {logical_address}      change the logical address of the CEC adapter." + System.Environment.NewLine +
+        "[la 4]                    logical address 4" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "pa {physical_address}     change the physical address of the CEC adapter." + System.Environment.NewLine +
+        "[pa 1000]                 physical address 1.0.0.0" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "osd {addr} {string}       set OSD message on the specified device." + System.Environment.NewLine +
+        "[osd 0 Test Message]      displays 'Test Message' on the TV" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "ver {addr}                get the CEC version of the specified device." + System.Environment.NewLine +
+        "[ver 0]                   get the CEC version of the TV" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "ven {addr}                get the vendor ID of the specified device." + System.Environment.NewLine +
+        "[ven 0]                   get the vendor ID of the TV" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "lang {addr}               get the menu language of the specified device." + System.Environment.NewLine +
+        "[lang 0]                  get the menu language of the TV" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "pow {addr}                get the power status of the specified device." + System.Environment.NewLine +
+        "[pow 0]                   get the power status of the TV" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "poll {addr}               poll the specified device." + System.Environment.NewLine +
+        "[poll 0]                  sends a poll message to the TV" + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "[mon] {1|0}               enable or disable CEC bus monitoring." + System.Environment.NewLine +
+        "[log] {1 - 31}            change the log level. see cectypes.h for values." + System.Environment.NewLine +
+        System.Environment.NewLine +
+        "[ping]                    send a ping command to the CEC adapter." + System.Environment.NewLine +
+        "[bl]                      to let the adapter enter the bootloader, to upgrade" + System.Environment.NewLine +
+        "                          the flash rom." + System.Environment.NewLine +
+        "[r]                       reconnect to the CEC adapter." + System.Environment.NewLine +
+        "[h] or [help]             show this help." + System.Environment.NewLine +
+        "[q] or [quit]             to quit the CEC test client and switch off all" + System.Environment.NewLine +
+        "                          connected CEC devices." + System.Environment.NewLine +
+        "================================================================================");
+    }
+
+    public void MainLoop()
+    {
+      Lib.PowerOnDevices(CecLogicalAddress.Tv);
+      FlushLog();
+
+      Lib.SetActiveSource(CecDeviceType.PlaybackDevice);
+      FlushLog();
+
+      bool bContinue = true;
+      string command;
+      while (bContinue)
+      {
+        Console.WriteLine("waiting for input");
+
+        command = Console.ReadLine();
+        if (command.Length == 0)
+          continue;
+        string[] splitCommand = command.Split(' ');
+        if (splitCommand[0] == "tx" || splitCommand[0] == "txn")
+        {
+          CecCommand bytes = new CecCommand();
+          for (int iPtr = 1; iPtr < splitCommand.Length; iPtr++)
+          {
+            bytes.PushBack(byte.Parse(splitCommand[iPtr], System.Globalization.NumberStyles.HexNumber));
+          }
+
+          if (command == "txn")
+            bytes.TransmitTimeout = 0;
+
+          Lib.Transmit(bytes);
+        }
+        else if (splitCommand[0] == "on")
+        {
+          if (splitCommand.Length > 1)
+            Lib.PowerOnDevices((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
+          else
+            Lib.PowerOnDevices(CecLogicalAddress.Broadcast);
+        }
+        else if (splitCommand[0] == "standby")
+        {
+          if (splitCommand.Length > 1)
+            Lib.StandbyDevices((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
+          else
+            Lib.StandbyDevices(CecLogicalAddress.Broadcast);
+        }
+        else if (splitCommand[0] == "poll")
+        {
+          bool bSent = false;
+          if (splitCommand.Length > 1)
+            bSent = Lib.PollDevice((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
+          else
+            bSent = Lib.PollDevice(CecLogicalAddress.Broadcast);
+          if (bSent)
+            Console.WriteLine("POLL message sent");
+          else
+            Console.WriteLine("POLL message not sent");
+        }
+        else if (splitCommand[0] == "la")
+        {
+          if (splitCommand.Length > 1)
+            Lib.SetLogicalAddress((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
+        }
+        else if (splitCommand[0] == "pa")
+        {
+          if (splitCommand.Length > 1)
+            Lib.SetPhysicalAddress(short.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
+        }
+        else if (splitCommand[0] == "osd")
+        {
+          if (splitCommand.Length > 2)
+          {
+            StringBuilder osdString = new StringBuilder();
+            for (int iPtr = 1; iPtr < splitCommand.Length; iPtr++)
+            {
+              osdString.Append(splitCommand[iPtr]);
+              if (iPtr != splitCommand.Length - 1)
+                osdString.Append(" ");
+            }
+            Lib.SetOSDString((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber), CecDisplayControl.DisplayForDefaultTime, osdString.ToString());
+          }
+        }
+        else if (splitCommand[0] == "ping")
+        {
+          Lib.PingAdapter();
+        }
+        else if (splitCommand[0] == "mon")
+        {
+          bool enable = splitCommand.Length > 1 ? splitCommand[1] == "1" : false;
+          Lib.SwitchMonitoring(enable);
+        }
+        else if (splitCommand[0] == "bl")
+        {
+          Lib.StartBootloader();
+        }
+        else if (splitCommand[0] == "lang")
+        {
+          if (splitCommand.Length > 1)
+          {
+            string language = Lib.GetDeviceMenuLanguage((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
+            Console.WriteLine("Menu language: " + language);
+          }
+        }
+        else if (splitCommand[0] == "ven")
+        {
+          if (splitCommand.Length > 1)
+          {
+            ulong vendor = Lib.GetDeviceVendorId((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
+            Console.WriteLine("Vendor ID: " + vendor);
+          }
+        }
+        else if (splitCommand[0] == "ver")
+        {
+          if (splitCommand.Length > 1)
+          {
+            CecVersion version = Lib.GetDeviceCecVersion((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
+            switch (version)
+            {
+              case CecVersion.V1_2:
+                Console.WriteLine("CEC version 1.2");
+                break;
+              case CecVersion.V1_2A:
+                Console.WriteLine("CEC version 1.2a");
+                break;
+              case CecVersion.V1_3:
+                Console.WriteLine("CEC version 1.3");
+                break;
+              case CecVersion.V1_3A:
+                Console.WriteLine("CEC version 1.3a");
+                break;
+              case CecVersion.V1_4:
+                Console.WriteLine("CEC version 1.4");
+                break;
+              default:
+                Console.WriteLine("unknown CEC version");
+                break;
+            }
+          }
+        }
+        else if (splitCommand[0] == "pow")
+        {
+          if (splitCommand.Length > 1)
+          {
+            CecPowerStatus power = Lib.GetDevicePowerStatus((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
+            switch (power)
+            {
+              case CecPowerStatus.On:
+                Console.WriteLine("powered on");
+                break;
+              case CecPowerStatus.InTransitionOnToStandby:
+                Console.WriteLine("on -> standby");
+                break;
+              case CecPowerStatus.InTransitionStandbyToOn:
+                Console.WriteLine("standby -> on");
+                break;
+              case CecPowerStatus.Standby:
+                Console.WriteLine("standby");
+                break;
+              default:
+                Console.WriteLine("unknown power status");
+                break;
+            }
+          }
+        }
+        else if (splitCommand[0] == "r")
+        {
+          Console.WriteLine("closing the connection");
+          Lib.Close();
+          FlushLog();
+
+          Console.WriteLine("opening a new connection");
+          Connect(10000);
+          FlushLog();
+
+          Console.WriteLine("setting active source");
+          Lib.SetActiveSource(CecDeviceType.PlaybackDevice);
+        }
+        else if (splitCommand[0] == "h" || splitCommand[0] == "help")
+          ShowConsoleHelp();
+        else if (splitCommand[0] == "q" || splitCommand[0] == "quit")
+          bContinue = false;
+        else if (splitCommand[0] == "log" && splitCommand.Length > 1)
+          LogLevel = int.Parse(splitCommand[1]);
+
+        FlushLog();
+      }
+    }
+
+    static void Main(string[] args)
+    {
+      CecSharpClient p = new CecSharpClient();
+      if (p.Connect(10000))
+      {
+        p.MainLoop();
+      }
+      else
+      {
+        Console.WriteLine("Could not open a connection to the CEC adapter");
+      }
+      p.FlushLog();
+    }
+
+    private int         LogLevel;
+    private LibCecSharp Lib;
+  }
+}
diff --git a/src/CecSharpTester/CecSharpClient.csproj b/src/CecSharpTester/CecSharpClient.csproj
new file mode 100644 (file)
index 0000000..eff98ef
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{47EF8EFE-5758-4E82-B9BA-F9B002F9C0D4}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>CecSharpClient</RootNamespace>
+    <AssemblyName>CecSharpClient</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="LibCecSharp, Version=1.0.4334.36379, Culture=neutral, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\LibCecSharp.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="CecSharpClient.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/src/LibCecSharp/AssemblyInfo.cpp b/src/LibCecSharp/AssemblyInfo.cpp
new file mode 100644 (file)
index 0000000..459ae9f
--- /dev/null
@@ -0,0 +1,40 @@
+#include "stdafx.h"
+
+using namespace System;
+using namespace System::Reflection;
+using namespace System::Runtime::CompilerServices;
+using namespace System::Runtime::InteropServices;
+using namespace System::Security::Permissions;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly:AssemblyTitleAttribute("LibCecSharp")];
+[assembly:AssemblyDescriptionAttribute("")];
+[assembly:AssemblyConfigurationAttribute("")];
+[assembly:AssemblyCompanyAttribute("Pulse-Eight Ltd.")];
+[assembly:AssemblyProductAttribute("LibCecSharp")];
+[assembly:AssemblyCopyrightAttribute("Copyright (c) Pulse-Eight Ltd. 2011")];
+[assembly:AssemblyTrademarkAttribute("")];
+[assembly:AssemblyCultureAttribute("")];
+
+//
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the value or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly:AssemblyVersionAttribute("1.0.*")];
+
+[assembly:ComVisible(false)];
+
+[assembly:CLSCompliantAttribute(true)];
+
+[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
diff --git a/src/LibCecSharp/LibCecSharp.cpp b/src/LibCecSharp/LibCecSharp.cpp
new file mode 100644 (file)
index 0000000..c72e0dd
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is an original work, containing original code.
+ *
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
+ *
+ * This program is dual-licensed; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Alternatively, you can license this library under a commercial license,
+ * please contact Pulse-Eight Licensing for more information.
+ *
+ * For more information contact:
+ * Pulse-Eight Licensing       <license@pulse-eight.com>
+ *     http://www.pulse-eight.com/
+ *     http://www.pulse-eight.net/
+ */
+
+#include "stdafx.h"
+#include <windows.h>
+#include <vcclr.h>
+#include <msclr/marshal.h>
+#include <cec.h>
+#using <System.dll>
+
+using namespace System;
+using namespace CEC;
+using namespace msclr::interop;
+
+public enum class CecDeviceType
+{
+  Tv              = 0,
+  RecordingDevice = 1,
+  Reserved        = 2,
+  Tuner           = 3,
+  PlaybackDevice  = 4,
+  AudioSystem     = 5
+};
+
+public enum class CecLogLevel
+{
+  None    = 0,
+  Error   = 1,
+  Warning = 2,
+  Notice  = 4,
+  Traffic = 8,
+  Debug   = 16,
+  All     = 31
+};
+
+public enum class CecLogicalAddress
+{
+  Unknown          = -1, //not a valid logical address
+  Tv               = 0,
+  RecordingDevice1 = 1,
+  RecordingDevice2 = 2,
+  Tuner1           = 3,
+  PlaybackDevice1  = 4,
+  AudioSystem      = 5,
+  Tuner2           = 6,
+  Tuner3           = 7,
+  PlaybackDevice2  = 8,
+  RecordingDevice3 = 9,
+  Tuner4           = 10,
+  PlaybackDevice3  = 11,
+  Reserved1        = 12,
+  Reserved2        = 13,
+  FreeUse          = 14,
+  Unregistered     = 15,
+  Broadcast        = 15
+};
+
+public enum class CecPowerStatus
+{
+  On                      = 0x00,
+  Standby                 = 0x01,
+  InTransitionStandbyToOn = 0x02,
+  InTransitionOnToStandby = 0x03,
+  Unknown                 = 0x99
+};
+
+public enum class CecVersion
+{
+  Unknown = 0x00,
+  V1_2    = 0x01,
+  V1_2A   = 0x02,
+  V1_3    = 0x03,
+  V1_3A   = 0x04,
+  V1_4    = 0x05
+};
+
+public enum class CecDisplayControl
+{
+  DisplayForDefaultTime = 0x00,
+  DisplayUntilCleared   = 0x40,
+  ClearPreviousMessage  = 0x80,
+  ReservedForFutureUse  = 0xC0
+};
+
+public enum class CecMenuState
+{
+  Activated   = 0,
+  Deactivated = 1
+};
+
+public enum class CecDeckControlMode
+{
+  SkipForwardWind   = 1,
+  SkipReverseRewind = 2,
+  Stop              = 3,
+  Eject             = 4
+};
+
+public enum class CecDeckInfo
+{
+  Play               = 0x11,
+  Record             = 0x12,
+  Reverse            = 0x13,
+  Still              = 0x14,
+  Slow               = 0x15,
+  SlowReverse        = 0x16,
+  FastForward        = 0x17,
+  FastReverse        = 0x18,
+  NoMedia            = 0x19,
+  Stop               = 0x1A,
+  SkipForwardWind    = 0x1B,
+  SkipReverseRewind  = 0x1C,
+  IndexSearchForward = 0x1D,
+  IndexSearchReverse = 0x1E,
+  OtherStatus        = 0x1F
+};
+
+public ref class CecAdapter
+{
+public:
+  CecAdapter(String ^ strPath, String ^ strComPort)
+  {
+    Path = strPath;
+    ComPort = strComPort;
+  }
+
+  property String ^ Path;
+  property String ^ ComPort;
+};
+
+public ref class CecDeviceTypeList
+{
+public:
+  CecDeviceTypeList(void)
+  {
+    Types = gcnew array<CecDeviceType>(5);
+    for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
+      Types[iPtr] = CecDeviceType::Reserved;
+  }
+
+  property array<CecDeviceType> ^ Types;
+};
+
+public ref class CecDatapacket
+{
+public:
+  CecDatapacket(void)
+  {
+    Data = gcnew array<uint8_t>(100);
+    Size = 0;
+  }
+
+  void PushBack(uint8_t data)
+  {
+    if (Size < 100)
+    {
+      Data[Size] = data;
+      Size++;
+    }
+  }
+
+  property array<uint8_t> ^ Data;
+  property uint8_t          Size;
+};
+
+public ref class CecCommand
+{
+public:
+  CecCommand(CecLogicalAddress iInitiator, CecLogicalAddress iDestination, bool bAck, bool bEom, int8_t iOpcode, int32_t iTransmitTimeout)
+  {
+    Initiator       = iInitiator;
+    Destination     = iDestination;
+    Ack             = bAck;
+    Eom             = bEom;
+    Opcode          = iOpcode;
+    OpcodeSet       = true;
+    TransmitTimeout = iTransmitTimeout;
+    Parameters      = gcnew CecDatapacket;
+    Empty           = false;
+  }
+
+  CecCommand(void)
+  {
+    Initiator       = CecLogicalAddress::Unknown;
+    Destination     = CecLogicalAddress::Unknown;
+    Ack             = false;
+    Eom             = false;
+    Opcode          = 0;
+    OpcodeSet       = false;
+    TransmitTimeout = 0;
+    Parameters      = gcnew CecDatapacket;
+    Empty           = true;
+  }
+
+  void PushBack(uint8_t data)
+  {
+    if (Initiator == CecLogicalAddress::Unknown && Destination == CecLogicalAddress::Unknown)
+    {
+      Initiator   = (CecLogicalAddress) (data >> 4);
+      Destination = (CecLogicalAddress) (data & 0xF);
+    }
+    else if (!OpcodeSet)
+    {
+      OpcodeSet = true;
+      Opcode    = data;
+    }
+    else
+    {
+      Parameters->PushBack(data);
+    }
+  }
+
+  property bool               Empty;
+  property CecLogicalAddress  Initiator;
+  property CecLogicalAddress  Destination;
+  property bool               Ack;
+  property bool               Eom;
+  property int8_t             Opcode;
+  property CecDatapacket ^    Parameters;
+  property bool               OpcodeSet;
+  property int32_t            TransmitTimeout;
+};
+
+public ref class CecKeypress
+{
+public:
+  CecKeypress(int iKeycode, unsigned int iDuration)
+  {
+    Keycode  = iKeycode;
+    Duration = iDuration;
+    Empty    = false;
+  }
+
+  CecKeypress(void)
+  {
+    Keycode  = 0;
+    Duration = 0;
+    Empty    = true;
+  }
+
+  property bool         Empty;
+  property int          Keycode;
+  property unsigned int Duration;
+};
+
+public ref class CecLogMessage
+{
+public:
+  CecLogMessage(String ^ strMessage, CecLogLevel iLevel, int64_t iTime)
+  {
+    Message = strMessage;
+    Level   = iLevel;
+    Time    = iTime;
+    Empty   = false;
+  }
+
+  CecLogMessage(void)
+  {
+    Message = "";
+    Level   = CecLogLevel::None;
+    Time    = 0;
+    Empty   = true;
+  }
+
+  property bool        Empty;
+  property String ^    Message;
+  property CecLogLevel Level;
+  property int64_t     Time;
+};
+
+public ref class LibCecSharp
+{
+public:
+   LibCecSharp(String ^ strDeviceName, CecDeviceTypeList ^ deviceTypes)
+   {
+     marshal_context ^ context = gcnew marshal_context();
+
+     const char* strDeviceNameC = context->marshal_as<const char*>(strDeviceName);
+
+     cec_device_type_list types;
+     for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
+       types.types[iPtr] = (cec_device_type)deviceTypes->Types[iPtr];
+     m_libCec = (ICECAdapter *) CECInit(strDeviceNameC, types);
+     delete context;
+   }
+   
+   ~LibCecSharp(void)
+   {
+     CECDestroy(m_libCec);
+     m_libCec = NULL;
+   }
+
+protected:
+   !LibCecSharp(void)
+   {
+     CECDestroy(m_libCec);
+     m_libCec = NULL;
+   }
+
+public:
+  array<CecAdapter ^> ^ FindAdapters(String ^ path)
+  {
+    cec_adapter *devices = new cec_adapter[10];
+
+    marshal_context ^ context = gcnew marshal_context();
+    const char* strPathC = path->Length > 0 ? context->marshal_as<const char*>(path) : NULL;
+
+    uint8_t iDevicesFound = m_libCec->FindAdapters(devices, 10, NULL);
+
+    array<CecAdapter ^> ^ adapters = gcnew array<CecAdapter ^>(iDevicesFound);
+    for (unsigned int iPtr = 0; iPtr < iDevicesFound; iPtr++)
+      adapters[iPtr] = gcnew CecAdapter(gcnew String(devices[iPtr].path), gcnew String(devices[iPtr].comm));
+
+    delete devices;
+    delete context;
+    return adapters;
+  }
+
+  bool Open(String ^ strPort, int iTimeoutMs)
+  {
+    marshal_context ^ context = gcnew marshal_context();
+    const char* strPortC = context->marshal_as<const char*>(strPort);
+    bool bReturn = m_libCec->Open(strPortC, iTimeoutMs);
+    delete context;
+    return bReturn;
+  }
+
+  void Close(void)
+  {
+    m_libCec->Close();
+  }
+
+  bool PingAdapter(void)
+  {
+    return m_libCec->PingAdapter();
+  }
+
+  bool StartBootloader(void)
+  {
+    return m_libCec->StartBootloader();
+  }
+
+  int GetMinLibVersion(void)
+  {
+    return m_libCec->GetMinLibVersion();
+  }
+
+  int GetLibVersionMajor(void)
+  {
+    return m_libCec->GetLibVersionMajor();
+  }
+
+  int GetLibVersionMinor(void)
+  {
+    return m_libCec->GetLibVersionMinor();
+  }
+
+  CecLogMessage ^ GetNextLogMessage(void)
+  {
+    cec_log_message msg;
+    if (m_libCec->GetNextLogMessage(&msg))
+    {
+      return gcnew CecLogMessage(gcnew String(msg.message), (CecLogLevel)msg.level, msg.time);
+    }
+
+    return gcnew CecLogMessage();
+  }
+
+  CecKeypress ^ GetNextKeypress(void)
+  {
+    cec_keypress key;
+    if (m_libCec->GetNextKeypress(&key))
+    {
+      return gcnew CecKeypress(key.keycode, key.duration);
+    }
+
+    return gcnew CecKeypress();
+  }
+
+  CecCommand ^ GetNextCommand(void)
+  {
+    cec_command command;
+    if (m_libCec->GetNextCommand(&command))
+    {
+      // TODO parameters
+      return gcnew CecCommand((CecLogicalAddress)command.initiator, (CecLogicalAddress)command.destination, command.ack == 1 ? true : false, command.eom == 1 ? true : false, command.opcode, command.transmit_timeout);
+    }
+
+    return gcnew CecCommand();
+  }
+
+  bool Transmit(CecCommand ^ command)
+  {
+    cec_command ccommand;
+    cec_command::format(ccommand, (cec_logical_address)command->Initiator, (cec_logical_address)command->Destination, (cec_opcode)command->Opcode);
+    ccommand.transmit_timeout = command->TransmitTimeout;
+    ccommand.eom              = command->Eom;
+    ccommand.ack              = command->Ack;
+    for (unsigned int iPtr = 0; iPtr < command->Parameters->Size; iPtr++)
+      ccommand.parameters.push_back(command->Parameters->Data[iPtr]);
+
+    return m_libCec->Transmit(ccommand);
+  }
+
+  bool SetLogicalAddress(CecLogicalAddress logicalAddress)
+  {
+    return m_libCec->SetLogicalAddress((cec_logical_address) logicalAddress);
+  }
+
+  bool SetPhysicalAddress(int16_t physicalAddress)
+  {
+    return m_libCec->SetPhysicalAddress(physicalAddress);
+  }
+
+  bool PowerOnDevices(CecLogicalAddress logicalAddress)
+  {
+    return m_libCec->PowerOnDevices((cec_logical_address) logicalAddress);
+  }
+
+  bool StandbyDevices(CecLogicalAddress logicalAddress)
+  {
+    return m_libCec->StandbyDevices((cec_logical_address) logicalAddress);
+  }
+
+  bool PollDevice(CecLogicalAddress logicalAddress)
+  {
+    return m_libCec->PollDevice((cec_logical_address) logicalAddress);
+  }
+
+  bool SetActiveSource(CecDeviceType type)
+  {
+    return m_libCec->SetActiveSource((cec_device_type) type);
+  }
+
+  bool SetDeckControlMode(CecDeckControlMode mode, bool sendUpdate)
+  {
+    return m_libCec->SetDeckControlMode((cec_deck_control_mode) mode, sendUpdate);
+  }
+
+  bool SetDeckInfo(CecDeckInfo info, bool sendUpdate)
+  {
+    return m_libCec->SetDeckInfo((cec_deck_info) info, sendUpdate);
+  }
+
+  bool SetInactiveView(void)
+  {
+    return m_libCec->SetInactiveView();
+  }
+
+  bool SetMenuState(CecMenuState state, bool sendUpdate)
+  {
+    return m_libCec->SetMenuState((cec_menu_state) state, sendUpdate);
+  }
+
+  bool SetOSDString(CecLogicalAddress logicalAddress, CecDisplayControl duration, String ^ message)
+  {
+    marshal_context ^ context = gcnew marshal_context();
+    const char* strMessageC = context->marshal_as<const char*>(message);
+
+    bool bReturn = m_libCec->SetOSDString((cec_logical_address) logicalAddress, (cec_display_control) duration, strMessageC);
+
+    delete context;
+    return bReturn;
+  }
+
+  bool SwitchMonitoring(bool enable)
+  {
+    return m_libCec->SwitchMonitoring(enable);
+  }
+
+  CecVersion GetDeviceCecVersion(CecLogicalAddress logicalAddress)
+  {
+    return (CecVersion) m_libCec->GetDeviceCecVersion((cec_logical_address) logicalAddress);
+  }
+
+  String ^ GetDeviceMenuLanguage(CecLogicalAddress logicalAddress)
+  {
+    cec_menu_language lang;
+    if (m_libCec->GetDeviceMenuLanguage((cec_logical_address) logicalAddress, &lang))
+    {
+      return gcnew String(lang.language);
+    }
+
+    return gcnew String("");
+  }
+
+  uint64_t GetDeviceVendorId(CecLogicalAddress logicalAddress)
+  {
+    return m_libCec->GetDeviceVendorId((cec_logical_address) logicalAddress);
+  }
+
+  CecPowerStatus GetDevicePowerStatus(CecLogicalAddress logicalAddress)
+  {
+    return (CecPowerStatus) m_libCec->GetDevicePowerStatus((cec_logical_address) logicalAddress);
+  }
+
+private:
+   ICECAdapter *     m_libCec;
+};
diff --git a/src/LibCecSharp/LibCecSharp.suo b/src/LibCecSharp/LibCecSharp.suo
new file mode 100644 (file)
index 0000000..0b75e65
Binary files /dev/null and b/src/LibCecSharp/LibCecSharp.suo differ
diff --git a/src/LibCecSharp/Stdafx.cpp b/src/LibCecSharp/Stdafx.cpp
new file mode 100644 (file)
index 0000000..70d5258
--- /dev/null
@@ -0,0 +1,5 @@
+// stdafx.cpp : source file that includes just the standard includes
+// LibCecSharp.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
diff --git a/src/LibCecSharp/Stdafx.h b/src/LibCecSharp/Stdafx.h
new file mode 100644 (file)
index 0000000..3cc4c24
--- /dev/null
@@ -0,0 +1,7 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+
diff --git a/src/LibCecSharp/resource.h b/src/LibCecSharp/resource.h
new file mode 100644 (file)
index 0000000..d5ac7c4
--- /dev/null
@@ -0,0 +1,3 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by app.rc