diff options
author | Lars Op den Kamp <lars@opdenkamp.eu> | 2012-03-19 16:45:55 +0100 |
---|---|---|
committer | Lars Op den Kamp <lars@opdenkamp.eu> | 2012-03-27 16:05:12 +0200 |
commit | 4ae83c3e0004c4bea08110f26e963d21c5e9b896 (patch) | |
tree | 99051b2ad2f9e69e37ef3d25c90c1a961555cb2f | |
parent | ed34efe4667e2500fdbd4ecdeada8ff7eec02d9b (diff) |
cec: updated to libCEC 1.5. uses struct libcec_configuration to get and set the config in libCEC.
-rwxr-xr-x | configure.in | 2 | ||||
-rw-r--r-- | language/Dutch/strings.xml | 13 | ||||
-rw-r--r-- | language/English/strings.xml | 13 | ||||
-rw-r--r-- | lib/libcec/Makefile | 2 | ||||
-rw-r--r-- | project/BuildDependencies/scripts/libcec_d.bat | 3 | ||||
-rw-r--r-- | project/BuildDependencies/scripts/libcec_d.txt | 2 | ||||
-rw-r--r-- | system/peripherals.xml | 24 | ||||
-rw-r--r-- | tools/darwin/depends/libcec/Makefile | 2 | ||||
-rw-r--r-- | xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 422 | ||||
-rw-r--r-- | xbmc/peripherals/devices/PeripheralCecAdapter.h | 17 |
10 files changed, 321 insertions, 179 deletions
diff --git a/configure.in b/configure.in index bca9239e33..e6f04dfbe6 100755 --- a/configure.in +++ b/configure.in @@ -1173,7 +1173,7 @@ if test "x$use_libcec" != "xno"; then # libcec is dyloaded, so we need to check for its headers and link any depends. if test "x$use_libcec" != "xno"; then - PKG_CHECK_MODULES([CEC],[libcec >= 1.1.0],,[use_libcec="no";AC_MSG_RESULT($libcec_disabled)]) + PKG_CHECK_MODULES([CEC],[libcec >= 1.5.0],,[use_libcec="no";AC_MSG_RESULT($libcec_disabled)]) if test "x$use_libcec" != "xno"; then INCLUDES="$INCLUDES $CEC_CFLAGS" diff --git a/language/Dutch/strings.xml b/language/Dutch/strings.xml index fd863718b8..545cc333c8 100644 --- a/language/Dutch/strings.xml +++ b/language/Dutch/strings.xml @@ -2391,17 +2391,20 @@ <string id="36004">Druk op "user" knop commando</string> <string id="36005">Schakel commando's in bij het wisselen van kant</string> <string id="36006">Kon de adapter niet openen</string> - <string id="36007">Schakel de TV in bij het opstarten van XBMC</string> + <string id="36007">Schakel apparatuur in bij het opstarten van XBMC</string> <string id="36008">Schakel apparatuur uit bij het stoppen van XBMC</string> <string id="36009">Schakel app. uit zolang de schermbeveiliging actief is</string> <string id="36010"></string> - <string id="36011">Kon de CEC poort niet detecteren. Stel het manueel in.</string> - <string id="36012">Kon de CEC adapter niet detecteren.</string> - <string id="36013">Versie %d van de libcec interface version wordt niet ondersteund door XBMC (> %d)</string> + <string id="36011">Kon de COM poort niet detecteren. Stel het manueel in.</string> + <string id="36012">Kon de CEC adapter niet initialiseren.</string> + <string id="36013">Versie %d van de libCEC interface version wordt niet ondersteund door XBMC (> %d)</string> <string id="36014">Zet XBMC in standby wanneer de TV uitgeschakeld wordt</string> <string id="36015">HDMI poort nummer</string> <string id="36016">Verbonden</string> <!-- max. 13 characters --> - <string id="36017">Adapter gevonden, maar libcec is niet beschikbaar</string> + <string id="36017">Adapter gevonden, maar libCEC is niet beschikbaar</string> <string id="36018">Gebruik de taalinstelling van de TV</string> <string id="36019">Verbonden met HDMI apparaat</string> + <string id="36020">Maak XBMC de actieve bron bij het opstarten</string> + <string id="36021">Physiek adres (overschrijft HDMI poort)</string> + <string id="36022">COM poort (laat leeg, tenzij noodzakelijk)</string> </strings>
\ No newline at end of file diff --git a/language/English/strings.xml b/language/English/strings.xml index c978ed106e..12e1c606ac 100644 --- a/language/English/strings.xml +++ b/language/English/strings.xml @@ -2396,17 +2396,20 @@ <string id="36004">Press "user" button command</string> <string id="36005">Enable switch side commands</string> <string id="36006">Could not open the adapter</string> - <string id="36007">Power on the TV when starting XBMC</string> - <string id="36008">Power off devices when stopping XBMC</string> + <string id="36007">Devices to power on the TV when starting XBMC</string> + <string id="36008">Devices to power off devices when stopping XBMC</string> <string id="36009">Put devices in standby mode when activating screensaver</string> <string id="36010"></string> <string id="36011">Could not detect the CEC port. Set it up manually.</string> - <string id="36012">Could not detect the CEC adapter.</string> - <string id="36013">Unsupported libcec interface version. %d is greater than the version XBMC supports (%d)</string> + <string id="36012">Could not initialise the CEC adapter. Check your settings.</string> + <string id="36013">Unsupported libCEC interface version. %d is greater than the version XBMC supports (%d)</string> <string id="36014">Put this PC in standby mode when the TV is switched off</string> <string id="36015">HDMI port number</string> <string id="36016">Connected</string> <!-- max. 13 characters --> - <string id="36017">Adapter found, but libcec is not available</string> + <string id="36017">Adapter found, but libCEC is not available</string> <string id="36018">Use the TV's language setting</string> <string id="36019">Connected to HDMI device</string> + <string id="36020">Make XBMC the active source when starting</string> + <string id="36021">Physical address (overrules HDMI port)</string> + <string id="36022">COM port (leave empty unless needed)</string> </strings> diff --git a/lib/libcec/Makefile b/lib/libcec/Makefile index 8776161c97..d9af68808a 100644 --- a/lib/libcec/Makefile +++ b/lib/libcec/Makefile @@ -7,7 +7,7 @@ # lib name, version LIBNAME=libcec -VERSION=1.2.0 +VERSION=1.5.0 SOURCE=$(LIBNAME)-$(VERSION) # download location and format diff --git a/project/BuildDependencies/scripts/libcec_d.bat b/project/BuildDependencies/scripts/libcec_d.bat index 27160b4503..86a2797ec8 100644 --- a/project/BuildDependencies/scripts/libcec_d.bat +++ b/project/BuildDependencies/scripts/libcec_d.bat @@ -7,7 +7,8 @@ CALL dlextract.bat libcec %FILES% cd %TMP_PATH% -xcopy libcec\include\* "%CUR_PATH%\include" /E /Q /I /Y +mkdir "%CUR_PATH%\include\libcec" +xcopy libcec\include\* "%CUR_PATH%\include\libcec\." /E /Q /I /Y copy libcec\libcec.dll "%XBMC_PATH%\system\." copy libcec\pthreadVC2.dll "%XBMC_PATH%\system\." diff --git a/project/BuildDependencies/scripts/libcec_d.txt b/project/BuildDependencies/scripts/libcec_d.txt index ec9df80543..0f7046189b 100644 --- a/project/BuildDependencies/scripts/libcec_d.txt +++ b/project/BuildDependencies/scripts/libcec_d.txt @@ -1,3 +1,3 @@ ; filename source of the file -libcec1.2.zip http://packages.pulse-eight.net/windows/ +libcec1.5.0.zip http://packages.pulse-eight.net/windows/ diff --git a/system/peripherals.xml b/system/peripherals.xml index 4e2142d436..1df6f1a461 100644 --- a/system/peripherals.xml +++ b/system/peripherals.xml @@ -8,15 +8,21 @@ <setting key="key_user" value="" label="36004" order="5" /> </peripheral> - <peripheral vendor_product="2548:1001" bus="usb" name="Pulse-Eight CEC Adaptor" mapTo="cec"> + <peripheral vendor_product="2548:1001" bus="usb" name="Pulse-Eight CEC Adapter" mapTo="cec"> <setting key="enabled" type="bool" value="1" label="305" order="1" /> - <setting key="cec_hdmi_port" type="int" value="1" min="1" max="16" label="36015" order="2" /> - <setting key="connected_device" type="int" label="36019" value="0" min="0" max="15" step="1" order="3" /> - <setting key="use_tv_menu_language" type="bool" value="1" label="36018" order="4" /> - <setting key="cec_power_on_startup" type="bool" value="1" label="36007" order="5" /> - <setting key="cec_power_off_shutdown" type="bool" value="1" label="36008" order="6" /> - <setting key="cec_standby_screensaver" type="bool" value="1" label="36009" order="7" /> - <setting key="standby_pc_on_tv_standby" type="bool" value="1" label="36014" order="8" /> - <setting key="port" type="string" value="" label="792" order="9" /> + <setting key="activate_source" type="bool" value="1" label="36020" order="2" /> + <setting key="wake_devices" type="string" value="0" label="36007" order="3" /> + <setting key="standby_devices" type="string" value="0" label="36008" order="4" /> + <setting key="cec_standby_screensaver" type="bool" value="1" label="36009" order="5" /> + <setting key="standby_pc_on_tv_standby" type="bool" value="1" label="36014" order="6" /> + <setting key="use_tv_menu_language" type="bool" value="1" label="36018" order="7" /> + <setting key="physical_address" type="string" label="36021" value="0" order="8" /> + <setting key="cec_hdmi_port" type="int" value="1" min="1" max="16" label="36015" order="9" /> + <setting key="connected_device" type="int" label="36019" value="0" min="0" max="15" step="1" order="10" /> + <setting key="port" type="string" value="" label="36022" order="11" /> + + <setting key="tv_vendor" type="int" value="0" configurable="0" /> + <setting key="device_name" type="string" value="XBMC" configurable="0" /> + <setting key="device_type" type="int" value="1" configurable="0" /> </peripheral> </peripherals> diff --git a/tools/darwin/depends/libcec/Makefile b/tools/darwin/depends/libcec/Makefile index c6b44c0e35..be4ee35648 100644 --- a/tools/darwin/depends/libcec/Makefile +++ b/tools/darwin/depends/libcec/Makefile @@ -2,7 +2,7 @@ include ../Makefile.include # lib name, version LIBNAME=libcec -VERSION=1.2.0 +VERSION=1.5.0 SOURCE=$(LIBNAME)-$(VERSION) ARCHIVE=$(SOURCE).tar.gz diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp index 5afe70b36a..2ac42517f9 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp @@ -18,8 +18,8 @@ * http://www.gnu.org/copyleft/gpl.html * */ -#include "system.h" +#include "system.h" #if defined(HAVE_LIBCEC) #include "PeripheralCecAdapter.h" #include "input/XBIRRemote.h" @@ -34,13 +34,13 @@ #include "settings/Settings.h" #include "utils/log.h" -#include <cec.h> +#include <libcec/cec.h> using namespace PERIPHERALS; using namespace ANNOUNCEMENT; using namespace CEC; -#define CEC_LIB_SUPPORTED_VERSION 1 +#define CEC_LIB_SUPPORTED_VERSION 0x1500 /* time in seconds to ignore standby commands from devices after the screensaver has been activated */ #define SCREENSAVER_TIMEOUT 10 @@ -51,19 +51,19 @@ class DllLibCECInterface { public: virtual ~DllLibCECInterface() {} - virtual ICECAdapter* CECInit(const char *interfaceName, cec_device_type_list types)=0; - virtual void* CECDestroy(ICECAdapter *adapter)=0; + virtual ICECAdapter* CECInitialise(libcec_configuration *configuration)=0; + virtual void* CECDestroy(ICECAdapter *adapter)=0; }; class DllLibCEC : public DllDynamic, DllLibCECInterface { DECLARE_DLL_WRAPPER(DllLibCEC, DLL_PATH_LIBCEC) - DEFINE_METHOD2(ICECAdapter*, CECInit, (const char *p1, cec_device_type_list p2)) - DEFINE_METHOD1(void* , CECDestroy, (ICECAdapter *p1)) + DEFINE_METHOD1(ICECAdapter*, CECInitialise, (libcec_configuration *p1)) + DEFINE_METHOD1(void* , CECDestroy, (ICECAdapter *p1)) BEGIN_METHOD_RESOLVE() - RESOLVE_METHOD_RENAME(CECInit, CECInit) + RESOLVE_METHOD_RENAME(CECInitialise, CECInitialise) RESOLVE_METHOD_RENAME(CECDestroy, CECDestroy) END_METHOD_RESOLVE() }; @@ -82,35 +82,9 @@ CPeripheralCecAdapter::CPeripheralCecAdapter(const PeripheralType type, const Pe m_button.iButton = 0; m_button.iDuration = 0; m_screensaverLastActivated.SetValid(false); - m_dll = new DllLibCEC; - if (m_dll->Load() && m_dll->IsLoaded()) - { - cec_device_type_list typeList; - typeList.clear(); - typeList.add(CEC_DEVICE_TYPE_RECORDING_DEVICE); - m_cecAdapter = m_dll->CECInit("XBMC", typeList); - } - else - m_cecAdapter = NULL; - - if (!m_cecAdapter || m_cecAdapter->GetMinLibVersion() > CEC_LIB_SUPPORTED_VERSION) - { - /* unsupported libcec version */ - CLog::Log(LOGERROR, g_localizeStrings.Get(36013).c_str(), CEC_LIB_SUPPORTED_VERSION, m_cecAdapter ? m_cecAdapter->GetMinLibVersion() : -1); - CStdString strMessage; - strMessage.Format(g_localizeStrings.Get(36013).c_str(), CEC_LIB_SUPPORTED_VERSION, m_cecAdapter ? m_cecAdapter->GetMinLibVersion() : -1); - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), strMessage); - m_bError = true; - if (m_cecAdapter) - m_dll->CECDestroy(m_cecAdapter); - m_cecAdapter = NULL; - } - else - { - CLog::Log(LOGDEBUG, "%s - using libCEC v%d.%d", __FUNCTION__, m_cecAdapter->GetLibVersionMajor(), m_cecAdapter->GetLibVersionMinor()); - m_features.push_back(FEATURE_CEC); - } + m_configuration.Clear(); + m_features.push_back(FEATURE_CEC); } CPeripheralCecAdapter::~CPeripheralCecAdapter(void) @@ -133,53 +107,60 @@ void CPeripheralCecAdapter::Announce(AnnouncementFlag flag, const char *sender, { if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "OnQuit") && m_bIsReady) { - if (GetSettingBool("cec_power_off_shutdown")) - m_cecAdapter->StandbyDevices(); - else - m_cecAdapter->SetInactiveView(); + // only send power off and inactive source command when we're currently active + if (m_cecAdapter->IsLibCECActiveSource()) + { + // if there are any devices to power off set, power them off + if (!m_configuration.powerOffDevices.IsEmpty()) + m_cecAdapter->StandbyDevices(CECDEVICE_BROADCAST); + // send an inactive source command otherwise + else + m_cecAdapter->SetInactiveView(); + } } - else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverDeactivated") && GetSettingBool("cec_standby_screensaver") && m_bIsReady) + else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverDeactivated") && m_bIsReady) { - m_cecAdapter->PowerOnDevices(); + if (m_configuration.bPowerOffScreensaver == 1) + { + // power off/on on screensaver is set, and devices to wake are set + if (!m_configuration.wakeDevices.IsEmpty()) + m_cecAdapter->PowerOnDevices(CECDEVICE_BROADCAST); + + // the option to make XBMC the active source is set + if (m_configuration.bActivateSource == 1) + m_cecAdapter->SetActiveSource(); + } } - else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && GetSettingBool("cec_standby_screensaver")) + else if (flag == GUI && !strcmp(sender, "xbmc") && !strcmp(message, "OnScreensaverActivated") && m_bIsReady) { // Don't put devices to standby if application is currently playing - if (!g_application.IsPlaying() || g_application.IsPaused()) + if ((!g_application.IsPlaying() || g_application.IsPaused()) && m_configuration.bPowerOffScreensaver == 1) { m_screensaverLastActivated = CDateTime::GetCurrentDateTime(); - m_cecAdapter->StandbyDevices(); + // only power off when we're the active source + if (m_cecAdapter->IsLibCECActiveSource()) + m_cecAdapter->StandbyDevices(CECDEVICE_BROADCAST); } } else if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "OnSleep")) { - if (GetSettingBool("cec_power_off_shutdown") && m_bIsReady) - m_cecAdapter->StandbyDevices(); + // this will also power off devices when we're the active source CSingleLock lock(m_critSection); m_bStop = true; WaitForThreadExit(0); } else if (flag == System && !strcmp(sender, "xbmc") && !strcmp(message, "OnWake")) { + // reconnect to the device CSingleLock lock(m_critSection); CLog::Log(LOGDEBUG, "%s - reconnecting to the CEC adapter after standby mode", __FUNCTION__); + + // close the previous connection m_cecAdapter->Close(); - CStdString strPort = GetComPort(); - if (!strPort.empty()) - { - if (!m_cecAdapter->Open(strPort.c_str(), 10000)) - { - CLog::Log(LOGERROR, "%s - failed to reconnect to the CEC adapter", __FUNCTION__); - m_bStop = true; - } - else - { - if (GetSettingBool("cec_power_on_startup")) - PowerOnCecDevices(CECDEVICE_TV); - m_cecAdapter->SetActiveView(); - } - } + // and open a new one + m_bStop = false; + Create(); } } @@ -187,6 +168,41 @@ bool CPeripheralCecAdapter::InitialiseFeature(const PeripheralFeature feature) { if (feature == FEATURE_CEC && !m_bStarted) { + SetConfigurationFromSettings(); + m_callbacks.CBCecLogMessage = &CecLogMessage; + m_callbacks.CBCecKeyPress = &CecKeyPress; + m_callbacks.CBCecCommand = &CecCommand; + m_callbacks.CBCecConfigurationChanged = &CecConfiguration; + m_configuration.callbackParam = this; + m_configuration.callbacks = &m_callbacks; + + m_dll = new DllLibCEC; + if (m_dll->Load() && m_dll->IsLoaded()) + m_cecAdapter = m_dll->CECInitialise(&m_configuration); + else + return false; + + if (m_configuration.serverVersion < CEC_LIB_SUPPORTED_VERSION) + { + /* unsupported libcec version */ + CLog::Log(LOGERROR, g_localizeStrings.Get(36013).c_str(), CEC_LIB_SUPPORTED_VERSION, m_cecAdapter ? m_configuration.serverVersion : -1); + + CStdString strMessage; + strMessage.Format(g_localizeStrings.Get(36013).c_str(), CEC_LIB_SUPPORTED_VERSION, m_cecAdapter ? m_configuration.serverVersion : -1); + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), strMessage); + m_bError = true; + if (m_cecAdapter) + m_dll->CECDestroy(m_cecAdapter); + m_cecAdapter = NULL; + + m_features.clear(); + return false; + } + else + { + CLog::Log(LOGDEBUG, "%s - using libCEC v%s", __FUNCTION__, m_cecAdapter->ToString((cec_server_version)m_configuration.serverVersion)); + } + m_bStarted = true; Create(); } @@ -225,25 +241,20 @@ CStdString CPeripheralCecAdapter::GetComPort(void) return strPort; } -void CPeripheralCecAdapter::Process(void) +bool CPeripheralCecAdapter::OpenConnection(void) { + bool bIsOpen(false); + if (!GetSettingBool("enabled")) { CLog::Log(LOGDEBUG, "%s - CEC adapter is disabled in peripheral settings", __FUNCTION__); m_bStarted = false; - return; + return bIsOpen; } CStdString strPort = GetComPort(); if (strPort.empty()) - return; - - EnableCallbacks(); - - // set correct physical address from peripheral settings - int iDevice = GetSettingInt("connected_device"); - int iHdmiPort = GetSettingInt("cec_hdmi_port"); - m_cecAdapter->SetHDMIPort((cec_logical_address)iDevice, iHdmiPort); + return bIsOpen; // open the CEC adapter CLog::Log(LOGDEBUG, "%s - opening a connection to the CEC adapter: %s", __FUNCTION__, strPort.c_str()); @@ -253,24 +264,43 @@ void CPeripheralCecAdapter::Process(void) strMessage.Format(g_localizeStrings.Get(21336), g_localizeStrings.Get(36000)); CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(36000), strMessage); - if (!m_cecAdapter->Open(strPort.c_str(), 10000)) + bool bConnectionFailedDisplayed(false); + + while (!m_bStop && !bIsOpen) { - CLog::Log(LOGERROR, "%s - could not opening a connection to the CEC adapter", __FUNCTION__); - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), g_localizeStrings.Get(36012)); - m_bStarted = false; - return; - } + if ((bIsOpen = m_cecAdapter->Open(strPort.c_str(), 10000)) == false) + { + CLog::Log(LOGERROR, "%s - could not opening a connection to the CEC adapter", __FUNCTION__); + if (!bConnectionFailedDisplayed) + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(36000), g_localizeStrings.Get(36012)); + bConnectionFailedDisplayed = true; - CAnnouncementManager::AddAnnouncer(this); - CLog::Log(LOGDEBUG, "%s - connection to the CEC adapter opened", __FUNCTION__); + Sleep(10000); + } + } - if (GetSettingBool("cec_power_on_startup")) + if (bIsOpen) { - PowerOnCecDevices(CECDEVICE_TV); - m_cecAdapter->SetActiveSource(); + CLog::Log(LOGDEBUG, "%s - connection to the CEC adapter opened", __FUNCTION__); + + if (!m_configuration.wakeDevices.IsEmpty()) + m_cecAdapter->PowerOnDevices(CECDEVICE_BROADCAST); + + if (m_configuration.bActivateSource == 1) + m_cecAdapter->SetActiveSource(); } - m_queryThread = new CPeripheralCecAdapterQueryThread(this); + return bIsOpen; +} + +void CPeripheralCecAdapter::Process(void) +{ + if (!OpenConnection()) + return; + + CAnnouncementManager::AddAnnouncer(this); + + m_queryThread = new CPeripheralCecAdapterQueryThread(this, m_configuration.bUseTVMenuLanguage == 1); m_queryThread->Create(false); while (!m_bStop) @@ -283,62 +313,19 @@ void CPeripheralCecAdapter::Process(void) } delete m_queryThread; - m_cecAdapter->Close(); - - CLog::Log(LOGDEBUG, "%s - CEC adapter processor thread ended", __FUNCTION__); - m_bStarted = false; -} - -bool CPeripheralCecAdapter::PowerOnCecDevices(cec_logical_address iLogicalAddress) -{ - bool bReturn(false); - - if (m_cecAdapter && m_bIsReady) - { - CLog::Log(LOGDEBUG, "%s - powering on CEC capable device with address %1x", __FUNCTION__, iLogicalAddress); - bReturn = m_cecAdapter->PowerOnDevices(iLogicalAddress); - } - - return bReturn; -} - -bool CPeripheralCecAdapter::StandbyCecDevices(cec_logical_address iLogicalAddress) -{ - bool bReturn(false); - - if (m_cecAdapter && m_bIsReady) - { - CLog::Log(LOGDEBUG, "%s - putting CEC capable devices with address %1x in standby mode", __FUNCTION__, iLogicalAddress); - bReturn = m_cecAdapter->StandbyDevices(iLogicalAddress); - } - - return bReturn; -} -bool CPeripheralCecAdapter::SendPing(void) -{ - bool bReturn(false); - if (m_cecAdapter && m_bIsReady) + if (m_cecAdapter->IsLibCECActiveSource()) { - CLog::Log(LOGDEBUG, "%s - sending ping to the CEC adapter", __FUNCTION__); - bReturn = m_cecAdapter->PingAdapter(); + if (m_configuration.bPowerOffOnStandby == 1) + m_cecAdapter->StandbyDevices(); + else + m_cecAdapter->SetInactiveView(); } - return bReturn; -} - -bool CPeripheralCecAdapter::SetHdmiPort(int iDevice, int iHdmiPort) -{ - bool bReturn(false); - if (m_cecAdapter && m_bIsReady) - { - if (iHdmiPort <= 0 || iHdmiPort > 16) - iHdmiPort = 1; - CLog::Log(LOGDEBUG, "%s - changing active HDMI port to %d on device %d", __FUNCTION__, iHdmiPort, iDevice); - bReturn = m_cecAdapter->SetHDMIPort((cec_logical_address)iDevice, iHdmiPort); - } + m_cecAdapter->Close(); - return bReturn; + CLog::Log(LOGDEBUG, "%s - CEC adapter processor thread ended", __FUNCTION__); + m_bStarted = false; } bool CPeripheralCecAdapter::HasConnectedAudioSystem(void) @@ -543,7 +530,7 @@ int CPeripheralCecAdapter::CecCommand(void *cbParam, const cec_command &command) case CEC_OPCODE_STANDBY: /* a device was put in standby mode */ CLog::Log(LOGDEBUG, "%s - device %1x was put in standby mode", __FUNCTION__, command.initiator); - if (command.initiator == CECDEVICE_TV && adapter->GetSettingBool("standby_pc_on_tv_standby") && + if (command.initiator == CECDEVICE_TV && adapter->m_configuration.bPowerOffOnStandby == 1 && (!adapter->m_screensaverLastActivated.IsValid() || CDateTime::GetCurrentDateTime() - adapter->m_screensaverLastActivated > CDateTimeSpan(0, 0, 0, SCREENSAVER_TIMEOUT))) { adapter->m_bStarted = false; @@ -551,7 +538,7 @@ int CPeripheralCecAdapter::CecCommand(void *cbParam, const cec_command &command) } break; case CEC_OPCODE_SET_MENU_LANGUAGE: - if (adapter->GetSettingBool("use_tv_menu_language") && command.initiator == CECDEVICE_TV && command.parameters.size == 3) + if (adapter->m_configuration.bUseTVMenuLanguage == 1 && command.initiator == CECDEVICE_TV && command.parameters.size == 3) { char strNewLanguage[4]; for (int iPtr = 0; iPtr < 3; iPtr++) @@ -610,6 +597,17 @@ int CPeripheralCecAdapter::CecCommand(void *cbParam, const cec_command &command) return 1; } +int CPeripheralCecAdapter::CecConfiguration(void *cbParam, const libcec_configuration &config) +{ + CPeripheralCecAdapter *adapter = (CPeripheralCecAdapter *)cbParam; + if (!adapter) + return 0; + + CSingleLock lock(adapter->m_critSection); + adapter->SetConfigurationFromLibCEC(config); + return 1; +} + int CPeripheralCecAdapter::CecKeyPress(void *cbParam, const cec_keypress &key) { CPeripheralCecAdapter *adapter = (CPeripheralCecAdapter *)cbParam; @@ -870,9 +868,10 @@ void CPeripheralCecAdapter::OnSettingChanged(const CStdString &strChangedSetting else if (bEnabled && !m_cecAdapter && m_bStarted) InitialiseFeature(FEATURE_CEC); } - else if (strChangedSetting.Equals("connected_device") || strChangedSetting.Equals("cec_hdmi_port")) + else { - SetHdmiPort(GetSettingInt("connected_device"), GetSettingInt("cec_hdmi_port")); + SetConfigurationFromSettings(); + m_cecAdapter->SetConfiguration(&m_configuration); } } @@ -920,9 +919,10 @@ bool CPeripheralCecAdapter::TranslateComPort(CStdString &strLocation) return false; } -CPeripheralCecAdapterQueryThread::CPeripheralCecAdapterQueryThread(CPeripheralCecAdapter *adapter) : +CPeripheralCecAdapterQueryThread::CPeripheralCecAdapterQueryThread(CPeripheralCecAdapter *adapter, bool bGetMenuLanguage) : CThread("CEC Adapter Query Thread"), - m_adapter(adapter) + m_adapter(adapter), + m_bGetMenuLanguage(bGetMenuLanguage) { m_event.Reset(); } @@ -948,7 +948,7 @@ void CPeripheralCecAdapterQueryThread::Process(void) return; }while (m_adapter->m_cecAdapter->GetDevicePowerStatus(CECDEVICE_TV) != CEC_POWER_STATUS_ON); - if (m_adapter->GetSettingBool("use_tv_menu_language")) + if (m_bGetMenuLanguage) { cec_menu_language language; if (m_adapter->m_cecAdapter->GetDeviceMenuLanguage(CECDEVICE_TV, &language)) @@ -978,12 +978,140 @@ void CPeripheralCecAdapterQueryThread::Process(void) CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(36000), strNotification); } -void CPeripheralCecAdapter::EnableCallbacks(void) +void CPeripheralCecAdapter::SetConfigurationFromLibCEC(const CEC::libcec_configuration &config) +{ + // set the primary device type + m_configuration.deviceTypes.Clear(); + m_configuration.deviceTypes.Add(config.deviceTypes[0]); + SetSetting("device_type", (int)config.deviceTypes[0]); + + // set the connected device + m_configuration.baseDevice = config.baseDevice; + SetSetting("connected_device", (int)config.baseDevice); + + // set the HDMI port number + m_configuration.iHDMIPort = config.iHDMIPort; + SetSetting("cec_hdmi_port", config.iHDMIPort); + + // set the physical address, when baseDevice or iHDMIPort are not set + if (m_configuration.baseDevice == CECDEVICE_UNKNOWN || + m_configuration.iHDMIPort == 0 || m_configuration.iHDMIPort > 4) + { + m_configuration.iPhysicalAddress = config.iPhysicalAddress; + CStdString strPhysicalAddress; + strPhysicalAddress.Format("%x", config.iPhysicalAddress); + SetSetting("physical_address", strPhysicalAddress); + } + + // set the tv vendor override + m_configuration.tvVendor = config.tvVendor; + SetSetting("tv_vendor", (int)config.tvVendor); + + // set the devices to wake when starting + m_configuration.wakeDevices = config.wakeDevices; + CStdString strWakeDevices; + for (unsigned int iPtr = 0; iPtr <= 16; iPtr++) + if (config.wakeDevices[iPtr]) + strWakeDevices.AppendFormat(" %X", iPtr); + SetSetting("wake_devices", strWakeDevices.Trim()); + + // set the devices to power off when stopping + m_configuration.powerOffDevices = config.powerOffDevices; + CStdString strPowerOffDevices; + for (unsigned int iPtr = 0; iPtr <= 16; iPtr++) + if (config.powerOffDevices[iPtr]) + strPowerOffDevices.AppendFormat(" %X", iPtr); + SetSetting("wake_devices", strPowerOffDevices.Trim()); + + // set the boolean settings + m_configuration.bUseTVMenuLanguage = m_configuration.bUseTVMenuLanguage; + SetSetting("use_tv_menu_language", m_configuration.bUseTVMenuLanguage == 1); + + m_configuration.bActivateSource = m_configuration.bActivateSource; + SetSetting("activate_source", m_configuration.bActivateSource == 1); + + m_configuration.bPowerOffScreensaver = m_configuration.bPowerOffScreensaver; + SetSetting("cec_standby_screensaver", m_configuration.bPowerOffScreensaver == 1); + + m_configuration.bPowerOffOnStandby = m_configuration.bPowerOffOnStandby; + SetSetting("standby_pc_on_tv_standby", m_configuration.bPowerOffOnStandby == 1); +} + +void CPeripheralCecAdapter::SetConfigurationFromSettings(void) { - m_callbacks.CBCecLogMessage = &CecLogMessage; - m_callbacks.CBCecKeyPress = &CecKeyPress; - m_callbacks.CBCecCommand = &CecCommand; - m_cecAdapter->EnableCallbacks(this, &m_callbacks); + // client version 1.5.0 + m_configuration.clientVersion = CEC_CLIENT_VERSION_1_5_0; + + // device name 'XBMC' + snprintf(m_configuration.strDeviceName, 13, "%s", GetSettingString("device_name").c_str()); + + // set the primary device type + m_configuration.deviceTypes.Clear(); + int iDeviceType = GetSettingInt("device_type"); + if (iDeviceType != (int)CEC_DEVICE_TYPE_RECORDING_DEVICE && + iDeviceType != (int)CEC_DEVICE_TYPE_PLAYBACK_DEVICE && + iDeviceType != (int)CEC_DEVICE_TYPE_TUNER) + iDeviceType = (int)CEC_DEVICE_TYPE_RECORDING_DEVICE; + m_configuration.deviceTypes.Add((cec_device_type)iDeviceType); + + // always try to autodetect the address. + // when the firmware supports this, it will override the physical address, connected device and hdmi port settings + m_configuration.bAutodetectAddress = 1; + + // set the physical address + // when set, it will override the connected device and hdmi port settings + CStdString strPhysicalAddress = GetSettingString("physical_address"); + int iPhysicalAddress; + if (sscanf(strPhysicalAddress.c_str(), "%x", &iPhysicalAddress) == 1 && iPhysicalAddress > 0 && iPhysicalAddress < 0xFFFF) + m_configuration.iPhysicalAddress = iPhysicalAddress; + + // set the connected device + int iConnectedDevice = GetSettingInt("connected_device"); + if (iConnectedDevice == 0 || iConnectedDevice == 5) + m_configuration.baseDevice = (cec_logical_address)iConnectedDevice; + + // set the HDMI port number + int iHDMIPort = GetSettingInt("cec_hdmi_port"); + if (iHDMIPort >= 0 && iHDMIPort <= 4) + m_configuration.iHDMIPort = iHDMIPort; + + // set the tv vendor override + int iVendor = GetSettingInt("tv_vendor"); + if (iVendor > 0 && iVendor < 0xFFFFFF) + m_configuration.tvVendor = iVendor; + + // read the devices to wake when starting + CStdString strWakeDevices = CStdString(GetSettingString("wake_devices")).Trim(); + m_configuration.wakeDevices.Clear(); + ReadLogicalAddresses(strWakeDevices, m_configuration.wakeDevices); + + // read the devices to power off when stopping + CStdString strStandbyDevices = CStdString(GetSettingString("standby_devices")).Trim(); + m_configuration.powerOffDevices.Clear(); + ReadLogicalAddresses(strStandbyDevices, m_configuration.powerOffDevices); + + // always get the settings from the rom, when supported by the firmware + m_configuration.bGetSettingsFromROM = 1; + + // read the boolean settings + m_configuration.bUseTVMenuLanguage = GetSettingBool("use_tv_menu_language") ? 1 : 0; + m_configuration.bActivateSource = GetSettingBool("activate_source") ? 1 : 0; + m_configuration.bPowerOffScreensaver = GetSettingBool("cec_standby_screensaver") ? 1 : 0; + m_configuration.bPowerOffOnStandby = GetSettingBool("standby_pc_on_tv_standby") ? 1 : 0; +} + +void CPeripheralCecAdapter::ReadLogicalAddresses(const CStdString &strString, cec_logical_addresses &addresses) +{ + for (size_t iPtr = 0; iPtr < strString.size(); iPtr++) + { + CStdString strDevice = CStdString(strString.substr(iPtr, 1)).Trim(); + if (!strDevice.IsEmpty()) + { + int iDevice(0); + if (sscanf(strDevice.c_str(), "%x", &iDevice) == 1 && iDevice >= 0 && iDevice <= 0xF) + addresses.Set((cec_logical_address)iDevice); + } + } } #endif diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.h b/xbmc/peripherals/devices/PeripheralCecAdapter.h index 07adeb3731..d19b07fd3e 100644 --- a/xbmc/peripherals/devices/PeripheralCecAdapter.h +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.h @@ -32,7 +32,7 @@ #ifdef isset #undef isset #endif -#include <cectypes.h> +#include <libcec/cectypes.h> class DllLibCEC; @@ -68,8 +68,6 @@ namespace PERIPHERALS virtual ~CPeripheralCecAdapter(void); virtual void Announce(ANNOUNCEMENT::AnnouncementFlag flag, const char *sender, const char *message, const CVariant &data); - virtual bool PowerOnCecDevices(CEC::cec_logical_address iLogicalAddress); - virtual bool StandbyCecDevices(CEC::cec_logical_address iLogicalAddress); virtual bool HasConnectedAudioSystem(void); virtual void SetAudioSystemConnected(bool bSetTo); virtual void ScheduleVolumeUp(void); @@ -79,9 +77,6 @@ namespace PERIPHERALS virtual void ScheduleMute(void); virtual void Mute(void); - virtual bool SendPing(void); - virtual bool SetHdmiPort(int iDevice, int iHdmiPort); - virtual void OnSettingChanged(const CStdString &strChangedSetting); virtual WORD GetButton(void); @@ -90,10 +85,14 @@ namespace PERIPHERALS virtual CStdString GetComPort(void); protected: - virtual void EnableCallbacks(void); + virtual bool OpenConnection(void); + virtual void SetConfigurationFromSettings(void); + virtual void SetConfigurationFromLibCEC(const CEC::libcec_configuration &config); + static void ReadLogicalAddresses(const CStdString &strString, CEC::cec_logical_addresses &addresses); static int CecKeyPress(void *cbParam, const CEC::cec_keypress &key); static int CecLogMessage(void *cbParam, const CEC::cec_log_message &message); static int CecCommand(void *cbParam, const CEC::cec_command &command); + static int CecConfiguration(void *cbParam, const CEC::libcec_configuration &config); virtual bool GetNextKey(void); virtual bool GetNextCecKey(CEC::cec_keypress &key); @@ -120,12 +119,13 @@ namespace PERIPHERALS CPeripheralCecAdapterQueryThread *m_queryThread; CEC::ICECCallbacks m_callbacks; CCriticalSection m_critSection; + CEC::libcec_configuration m_configuration; }; class CPeripheralCecAdapterQueryThread : public CThread { public: - CPeripheralCecAdapterQueryThread(CPeripheralCecAdapter *adapter); + CPeripheralCecAdapterQueryThread(CPeripheralCecAdapter *adapter, bool bGetMenuLanguage); virtual ~CPeripheralCecAdapterQueryThread(void); virtual void Signal(void); @@ -135,6 +135,7 @@ namespace PERIPHERALS CPeripheralCecAdapter *m_adapter; CEvent m_event; + bool m_bGetMenuLanguage; }; } |