set the vendor id of devices handled by libCEC to our vendor id
[deb_libcec.git] / src / lib / implementations / PHCommandHandler.cpp
index f8505c7c883c7068bff6663d9129ba93c34dd70d..edb084c853af0fd7d0f6eda2c27b1872c09dbbe6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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 Copyright (C) 2011-2013 Pulse-Eight Limited.  All rights reserved.
  * libCEC(R) is an original work, containing original code.
  *
  * libCEC(R) is a trademark of Pulse-Eight Limited.
 #include "lib/CECClient.h"
 
 using namespace CEC;
+using namespace PLATFORM;
 
 #define LIB_CEC     m_busDevice->GetProcessor()->GetLib()
 #define ToString(p) LIB_CEC->ToString(p)
 
+#define TV_ON_CHECK_TIME_MS 5000
+
+CImageViewOnCheck::~CImageViewOnCheck(void)
+{
+  StopThread(-1);
+  m_event.Broadcast();
+  StopThread();
+}
+
+void* CImageViewOnCheck::Process(void)
+{
+  CCECBusDevice* tv = m_handler->m_processor->GetDevice(CECDEVICE_TV);
+  cec_power_status status(CEC_POWER_STATUS_UNKNOWN);
+  while (status != CEC_POWER_STATUS_ON)
+  {
+    m_event.Wait(TV_ON_CHECK_TIME_MS);
+    if (!IsRunning())
+      return NULL;
+
+    status = tv->GetPowerStatus(m_handler->m_busDevice->GetLogicalAddress());
+
+    if (status != CEC_POWER_STATUS_ON &&
+        status != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON)
+    {
+      CLockObject lock(m_handler->m_mutex);
+      tv->OnImageViewOnSent(false);
+      m_handler->m_iActiveSourcePending = GetTimeMs();
+    }
+  }
+  return NULL;
+}
+
 CPHCommandHandler::CPHCommandHandler(CCECBusDevice *busDevice,
                                      int32_t iTransmitTimeout /* = CEC_DEFAULT_TRANSMIT_TIMEOUT */,
                                      int32_t iTransmitWait /* = CEC_DEFAULT_TRANSMIT_WAIT */,
@@ -51,14 +84,54 @@ CPHCommandHandler::CPHCommandHandler(CCECBusDevice *busDevice,
     CCECCommandHandler(busDevice, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending),
     m_iLastKeyCode(CEC_USER_CONTROL_CODE_UNKNOWN)
 {
+  m_imageViewOnCheck = new CImageViewOnCheck(this);
   m_vendorId = CEC_VENDOR_PHILIPS;
+  m_bOPTSendDeckStatusUpdateOnActiveSource = false;
+}
+
+CPHCommandHandler::~CPHCommandHandler(void)
+{
+  delete m_imageViewOnCheck;
+}
+
+bool CPHCommandHandler::InitHandler(void)
+{
+  CCECBusDevice *primary = m_processor->GetPrimaryDevice();
+  if (primary && primary->GetLogicalAddress() != CECDEVICE_UNREGISTERED)
+  {
+    //XXX hack to use this handler for the primary device
+    if (m_busDevice->GetLogicalAddress() == CECDEVICE_TV &&
+        primary && m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress())
+    {
+      primary->SetVendorId(CEC_VENDOR_PHILIPS);
+      primary->ReplaceHandler(false);
+    }
+  }
+
+  return CCECCommandHandler::InitHandler();
+}
+
+bool CPHCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly /* = false */)
+{
+
+  CCECBusDevice* tv = m_processor->GetDevice(CECDEVICE_TV);
+  if (m_busDevice->IsActiveSource() &&
+      m_busDevice->IsHandledByLibCEC() &&
+      tv && tv->GetCurrentPowerStatus() != CEC_POWER_STATUS_ON &&
+      !bTransmitDelayedCommandsOnly)
+  {
+    // tv sometimes ignores image view on. check the power status of the tv in 5 seconds, and retry when it failed to power up
+    if (m_imageViewOnCheck && !m_imageViewOnCheck->IsRunning())
+      return m_imageViewOnCheck->CreateThread(false);
+  }
+
+  return CCECCommandHandler::ActivateSource(bTransmitDelayedCommandsOnly);
 }
 
 int CPHCommandHandler::HandleUserControlPressed(const cec_command& command)
 {
-  // tv keeps sending these until a button is pressed
-  if (command.parameters[0] == CEC_USER_CONTROL_CODE_DISPLAY_INFORMATION &&
-      m_iLastKeyCode == CEC_USER_CONTROL_CODE_DISPLAY_INFORMATION)
+  // TV sometimes keeps sending key presses without releases
+  if (m_iLastKeyCode == command.parameters[0])
     return COMMAND_HANDLED;
 
   m_iLastKeyCode = command.parameters[0];
@@ -72,3 +145,15 @@ int CPHCommandHandler::HandleUserControlRelease(const cec_command& command)
 
   return CCECCommandHandler::HandleUserControlRelease(command);
 }
+
+int CPHCommandHandler::HandleDeviceVendorId(const cec_command& command)
+{
+  m_busDevice->SetPowerStatus(CEC_POWER_STATUS_ON);
+  return CCECCommandHandler::HandleDeviceVendorId(command);
+}
+
+bool CPHCommandHandler::TransmitVendorID(const cec_logical_address iInitiator, const cec_logical_address iDestination, uint64_t UNUSED(iVendorId), bool bIsReply)
+{
+  // XXX hack around the hack in CPHCommandHandler::InitHandler
+  return CCECCommandHandler::TransmitVendorID(iInitiator, iDestination, CEC_VENDOR_PULSE_EIGHT, bIsReply);
+}