cec: added cec-config, a libCEC configuration wizard. WIP. currently only detects...
authorLars Op den Kamp <lars@opdenkamp.eu>
Thu, 9 Feb 2012 13:07:26 +0000 (14:07 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Thu, 9 Feb 2012 13:07:26 +0000 (14:07 +0100)
Makefile.am
project/cec-config.rc [new file with mode: 0644]
project/cec-config.vcxproj [new file with mode: 0644]
project/cec-config.vcxproj.filters [new file with mode: 0644]
project/libcec.sln
src/cec-config/Makefile.am [new file with mode: 0644]
src/cec-config/cec-config.cpp [new file with mode: 0644]

index c68f68b351a764c885c80a3988d7d1b7a6773640..471d2bd027c580df4edd448ac8952ee6eb52249e 100644 (file)
@@ -1 +1 @@
-SUBDIRS = src/lib src/testclient
\ No newline at end of file
+SUBDIRS = src/lib src/testclient src/cec-config
\ No newline at end of file
diff --git a/project/cec-config.rc b/project/cec-config.rc
new file mode 100644 (file)
index 0000000..37783a2
Binary files /dev/null and b/project/cec-config.rc differ
diff --git a/project/cec-config.vcxproj b/project/cec-config.vcxproj
new file mode 100644 (file)
index 0000000..2243ff9
--- /dev/null
@@ -0,0 +1,183 @@
+<?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="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{00EE7081-9EEE-485C-B7CE-699A7BCA40C1}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>cec-config</RootNamespace>
+    <ProjectName>cec-config</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <CharacterSet>MultiByte</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 Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <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>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <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'">
+    <OutDir>$(SolutionDir)..\build\</OutDir>
+    <TargetName>cec-config</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>$(SolutionDir)..\build\</OutDir>
+    <TargetName>cec-config.x64</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>$(SolutionDir)..\build\</OutDir>
+    <TargetName>cec-config</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>$(SolutionDir)..\build\</OutDir>
+    <TargetName>cec-config.x64</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_USE_32BIT_TIME_T;_DEBUG;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DisableSpecificWarnings>
+      </DisableSpecificWarnings>
+      <AdditionalIncludeDirectories>$(SolutiontDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <Version>
+      </Version>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level4</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_WIN64;_DEBUG;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DisableSpecificWarnings>
+      </DisableSpecificWarnings>
+      <AdditionalIncludeDirectories>$(SolutiontDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>
+      </AdditionalDependencies>
+      <Version>
+      </Version>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>Full</Optimization>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_USE_32BIT_TIME_T;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DisableSpecificWarnings>
+      </DisableSpecificWarnings>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <Version>
+      </Version>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level4</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>Full</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_WIN64;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DisableSpecificWarnings>
+      </DisableSpecificWarnings>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>
+      </AdditionalDependencies>
+      <Version>
+      </Version>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\include\cec.h" />
+    <ClInclude Include="..\include\cecloader.h" />
+    <ClInclude Include="..\src\lib\platform\threads\mutex.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\src\cec-config\cec-config.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="cec-config.rc" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/project/cec-config.vcxproj.filters b/project/cec-config.vcxproj.filters
new file mode 100644 (file)
index 0000000..0d3f647
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="exports">
+      <UniqueIdentifier>{cc0a01c1-e1e7-4af8-9656-fa9463140613}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="platform">
+      <UniqueIdentifier>{f08c0a80-22d9-4bdd-90de-b9cf5fa88f99}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\include\cec.h">
+      <Filter>exports</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\cecloader.h">
+      <Filter>exports</Filter>
+    </ClInclude>
+    <ClInclude Include="..\src\lib\platform\threads\mutex.h">
+      <Filter>platform</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\src\cec-config\cec-config.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="cec-config.rc" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
index 83d6d89a119dce27f3818cadc30679e0c58e6e05..dbb86c9fb8e6be5013a36feefac4187a2f3b60da 100644 (file)
@@ -8,6 +8,11 @@ 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}") = "cec-config", "cec-config.vcxproj", "{00EE7081-9EEE-485C-B7CE-699A7BCA40C1}"
+       ProjectSection(ProjectDependencies) = postProject
+               {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0} = {C04B0FB1-667D-4F1C-BDAE-A07CDFFAAAA0}
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Win32 = Debug|Win32
@@ -32,6 +37,14 @@ Global
                {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|Win32.Build.0 = Release|Win32
                {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|x64.ActiveCfg = Release|x64
                {F01222BF-6B3D-43BD-B254-434031CB9887}.Release|x64.Build.0 = Release|x64
+               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Debug|Win32.ActiveCfg = Debug|Win32
+               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Debug|Win32.Build.0 = Debug|Win32
+               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Debug|x64.ActiveCfg = Debug|x64
+               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Debug|x64.Build.0 = Debug|x64
+               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Release|Win32.ActiveCfg = Release|Win32
+               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Release|Win32.Build.0 = Release|Win32
+               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Release|x64.ActiveCfg = Release|x64
+               {00EE7081-9EEE-485C-B7CE-699A7BCA40C1}.Release|x64.Build.0 = Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE
diff --git a/src/cec-config/Makefile.am b/src/cec-config/Makefile.am
new file mode 100644 (file)
index 0000000..33650c5
--- /dev/null
@@ -0,0 +1,5 @@
+bin_PROGRAMS = cec-config
+cec_client_SOURCES = cec-config.cpp
+
+cec_client_CPPFLAGS = -I@abs_top_srcdir@/include
+cec_client_LDFLAGS = @LIBS_DL@
\ No newline at end of file
diff --git a/src/cec-config/cec-config.cpp b/src/cec-config/cec-config.cpp
new file mode 100644 (file)
index 0000000..c36bb6a
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * This file is part of the libCEC(R) library.
+ *
+ * libCEC(R) is Copyright (C) 2011-2012 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 "../../include/cec.h"
+
+#include <cstdio>
+#include <fcntl.h>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <sstream>
+#include "../lib/platform/threads/mutex.h"
+#include "../lib/platform/util/timeutils.h"
+#include "../lib/implementations/CECCommandHandler.h"
+
+using namespace CEC;
+using namespace std;
+using namespace PLATFORM;
+
+#include <cecloader.h>
+
+CMutex                g_outputMutex;
+
+CMutex                g_responseMutex;
+CCondition            g_responseCondtion;
+cec_opcode            g_lastCommand = CEC_OPCODE_NONE;
+
+CMutex                g_keyMutex;
+CCondition            g_keyCondtion;
+cec_user_control_code g_lastKey = CEC_USER_CONTROL_CODE_UNKNOWN;
+
+ICECCallbacks         g_callbacks;
+ICECAdapter *         g_parser;
+cec_logical_address   g_primaryAddress;
+
+inline void PrintToStdOut(const char *strFormat, ...)
+{
+  CStdString strLog;
+
+  va_list argList;
+  va_start(argList, strFormat);
+  strLog.FormatV(strFormat, argList);
+  va_end(argList);
+
+  CLockObject lock(g_outputMutex);
+  cout << strLog << endl;
+}
+
+//get the first word (separated by whitespace) from string data and place that in word
+//then remove that word from string data
+bool GetWord(string& data, string& word)
+{
+  stringstream datastream(data);
+  string end;
+
+  datastream >> word;
+  if (datastream.fail())
+  {
+    data.clear();
+    return false;
+  }
+
+  size_t pos = data.find(word) + word.length();
+
+  if (pos >= data.length())
+  {
+    data.clear();
+    return true;
+  }
+
+  data = data.substr(pos);
+
+  datastream.clear();
+  datastream.str(data);
+
+  datastream >> end;
+  if (datastream.fail())
+    data.clear();
+
+  return true;
+}
+
+int CecLogMessage(void *UNUSED(cbParam), const cec_log_message &message)
+{
+  switch (message.level)
+  {
+  case CEC_LOG_ERROR:
+    PrintToStdOut("ERROR:\t%s", message.message);
+    break;
+  case CEC_LOG_WARNING:
+    PrintToStdOut("ERROR:\t%s", message.message);
+    break;
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+int CecKeyPress(void *UNUSED(cbParam), const cec_keypress &key)
+{
+  CLockObject lock(g_keyMutex);
+  g_lastKey = key.keycode;
+  g_keyCondtion.Signal();
+  return 0;
+}
+
+int CecCommand(void *UNUSED(cbParam), const cec_command &command)
+{
+  CLockObject lock(g_responseMutex);
+  g_lastCommand = command.opcode;
+  g_responseCondtion.Signal();
+  return 0;
+}
+
+void EnableCallbacks(ICECAdapter *adapter)
+{
+  g_callbacks.CBCecLogMessage = &CecLogMessage;
+  g_callbacks.CBCecKeyPress   = &CecKeyPress;
+  g_callbacks.CBCecCommand    = &CecCommand;
+  adapter->EnableCallbacks(NULL, &g_callbacks);
+}
+
+ICECAdapter *CreateParser(cec_device_type_list typeList)
+{
+  ICECAdapter *parser = LibCecInit("ButtonConfig", typeList);
+  if (!parser)
+  {
+  #ifdef __WINDOWS__
+    PrintToStdOut("Cannot load libcec.dll");
+  #else
+    PrintToStdOut("Cannot load libcec.so");
+  #endif
+    return NULL;
+  }
+
+  PrintToStdOut("CEC Parser created - libcec version %d.%d", parser->GetLibVersionMajor(), parser->GetLibVersionMinor());
+
+  return parser;
+}
+
+bool ProcessConsoleCommand(string &input)
+{
+  if (!input.empty())
+  {
+    string command;
+    if (GetWord(input, command))
+    {
+      if (command == "q" || command == "quit")
+        return false;
+    }
+  }
+  return true;
+}
+
+bool OpenConnection(cec_device_type type = CEC_DEVICE_TYPE_RECORDING_DEVICE)
+{
+  cec_device_type_list types;
+  types.clear();
+  types.add(type);
+
+  g_parser = CreateParser(types);
+  if (!g_parser)
+    return false;
+
+  CStdString strPort;
+  cec_adapter devices[10];
+  uint8_t iDevicesFound = g_parser->FindAdapters(devices, 10, NULL);
+  if (iDevicesFound <= 0)
+  {
+    PrintToStdOut("autodetect FAILED");
+    UnloadLibCec(g_parser);
+    return false;
+  }
+  else
+  {
+    strPort = devices[0].comm;
+  }
+
+  EnableCallbacks(g_parser);
+
+  // start with HDMI1 on the TV
+  g_parser->SetHDMIPort(CECDEVICE_TV, 1);
+  PrintToStdOut("opening a connection to the CEC adapter...");
+
+  if (!g_parser->Open(strPort.c_str()))
+  {
+    PrintToStdOut("unable to open the device on port %s", strPort.c_str());
+    UnloadLibCec(g_parser);
+    return false;
+  }
+
+  cec_logical_addresses addr = g_parser->GetLogicalAddresses();
+  g_primaryAddress = addr.primary;
+
+  PrintToStdOut("cec device opened. using logical address %X", g_primaryAddress);
+  return true;
+}
+
+int8_t FindPhysicalAddressPortNumber(void)
+{
+  PrintToStdOut("Enter the HDMI port number to which you connected your CEC adapter, followed by <enter>. Only port 1, 2, 3 or 4 are supported. Anything else will cancel this wizard.");
+  string input;
+  getline(cin, input);
+  cin.clear();
+  if (input.empty() || (input != "1" && input != "2" && input != "3" && input != "4"))
+    return -1;
+  return (int8_t)atoi(input.c_str());
+}
+
+cec_logical_address FindPhysicalAddressBaseDevice(void)
+{
+  PrintToStdOut("Press 1 of your CEC adapter is connected to your TV or\npress 2 if it's connected to an AVR, followed by <enter>. Anything else will cancel this wizard.");
+
+  string input;
+  getline(cin, input);
+  cin.clear();
+  if (input.empty() || (input != "1" && input != "2"))
+  {
+    PrintToStdOut("Exiting...");
+    return CECDEVICE_UNKNOWN;
+  }
+  return (input == "2") ?
+    CECDEVICE_AUDIOSYSTEM :
+    CECDEVICE_TV;
+}
+
+uint16_t FindPhysicalAddress(void)
+{
+  PrintToStdOut("=== Physical Address Configuration ===\n");
+  uint16_t iAddress(0xFFFF);
+
+  PrintToStdOut("Do you want to let libCEC try to autodetect the address (y/n)?");
+  string input;
+  getline(cin, input);
+  cin.clear();
+  if (input == "y" || input == "Y")
+  {
+    cec_logical_address baseDevice = FindPhysicalAddressBaseDevice();
+    if (baseDevice == CECDEVICE_UNKNOWN)
+      return iAddress;
+
+    int8_t iPortNumber = FindPhysicalAddressPortNumber();
+    if (iPortNumber == -1)
+      return iAddress;
+
+    PrintToStdOut("Trying to detect the physical address...");
+    if (!g_parser->SetHDMIPort(baseDevice, iPortNumber))
+      PrintToStdOut("Failed. Please enter the address manually, or restart this wizard and use different settings.");
+    else
+    {
+      iAddress = g_parser->GetDevicePhysicalAddress(g_primaryAddress);
+      if (iAddress == 0 || iAddress == 0xFFFF)
+        PrintToStdOut("Failed. Please enter the address manually, or restart this wizard and use different settings.");
+    }
+  }
+
+  if (iAddress == 0 || iAddress == 0xFFFF)
+  {
+    PrintToStdOut("Please enter the physical address (0000 - FFFF), followed by <enter>.");
+    getline(cin, input);
+    cin.clear();
+
+    int iAddressTmp;
+    if (sscanf(input.c_str(), "%x", &iAddressTmp) == 1)
+    {
+      if (iAddressTmp < 0 || iAddressTmp > 0xFFFF)
+        iAddressTmp = 0xFFFF;
+      iAddress = (uint16_t)iAddressTmp;
+    }
+  }
+
+  return iAddress;
+}
+
+bool PowerOnTV(uint64_t iTimeout = 60000, unsigned iTries = 2)
+{
+  cec_power_status currentTvPower(CEC_POWER_STATUS_UNKNOWN);
+  uint64_t iNow = GetTimeMs();
+  uint64_t iTarget = iNow + iTimeout;
+  unsigned iTry(0);
+
+  while (currentTvPower != CEC_POWER_STATUS_ON && iTarget > iNow && iTry < iTries)
+  {
+    currentTvPower = g_parser->GetDevicePowerStatus(CECDEVICE_TV);
+    if (currentTvPower != CEC_POWER_STATUS_ON)
+    {
+      PrintToStdOut("Sending 'power on' command to the TV");
+      g_parser->PowerOnDevices(CECDEVICE_TV);
+      while (iTarget > iNow)
+      {
+        CLockObject lock(g_responseMutex);
+        g_responseCondtion.Wait(g_responseMutex, (uint32_t)((iTarget - iNow)/iTries));
+        if (g_lastCommand == CEC_OPCODE_REQUEST_ACTIVE_SOURCE)
+          break;
+        iNow = GetTimeMs();
+      }
+    }
+  }
+
+  currentTvPower = g_parser->GetDevicePowerStatus(CECDEVICE_TV);
+
+  if (currentTvPower != CEC_POWER_STATUS_ON)
+    PrintToStdOut("Failed to power on the TV, or the TV does not respond properly");
+
+  return currentTvPower == CEC_POWER_STATUS_ON;
+}
+
+int main (int argc, char *argv[])
+{
+  PrintToStdOut("=== USB-CEC Adapter Configuration ===\n");
+  if (!OpenConnection())
+    return 1;
+
+  if (!PowerOnTV())
+    return 1;
+
+  bool bAddressOk(false);
+  uint16_t iAddress(0xFFF);
+  while (!bAddressOk)
+  {
+    iAddress = FindPhysicalAddress();
+
+    PrintToStdOut("Physical address: %4X", iAddress);
+    PrintToStdOut("Is this correct (y/n)?");
+    string input;
+    getline(cin, input);
+    cin.clear();
+    bAddressOk = (input == "y" || input == "Y");
+  }
+
+  PrintToStdOut("=== USB-CEC Adapter Configuration Summary ===\n");
+  PrintToStdOut("Physical address: %4X", iAddress);
+
+  g_parser->StandbyDevices();
+  g_parser->Close();
+  UnloadLibCec(g_parser);
+
+  PrintToStdOut("Press enter to close this wizard.");
+  string input;
+  getline(cin, input);
+  return 0;
+}