cec: don't send 'image view on' to LG unless needed, or the tv will get caught in...
[deb_libcec.git] / src / lib / devices / CECBusDevice.cpp
index c68fc0584b9ca744244965c26f175c06804df774..87954228bda9fe6e514b75628f55697a53612731 100644 (file)
@@ -605,45 +605,57 @@ void CCECBusDevice::MarkReady(void)
 
 bool CCECBusDevice::ReplaceHandler(bool bActivateSource /* = true */)
 {
-  CTryLockObject lock(m_mutex);
-  if (!lock.IsLocked())
-    return false;
+  bool bInitHandler(false);
+  {
+    CTryLockObject lock(m_mutex);
+    if (!lock.IsLocked())
+      return false;
 
-  CLockObject handlerLock(m_handlerMutex);
-  if (m_iHandlerUseCount > 0)
-    return false;
+    CLockObject handlerLock(m_handlerMutex);
+    if (m_iHandlerUseCount > 0)
+      return false;
 
-  if (m_vendor != m_handler->GetVendorId())
-  {
-    if (CCECCommandHandler::HasSpecificHandler(m_vendor))
-    {
-      CLibCEC::AddLog(CEC_LOG_DEBUG, "replacing the command handler for device '%s' (%x)", GetLogicalAddressName(), GetLogicalAddress());
-      delete m_handler;
+    MarkBusy();
 
-      switch (m_vendor)
+    if (m_vendor != m_handler->GetVendorId())
+    {
+      if (CCECCommandHandler::HasSpecificHandler(m_vendor))
       {
-      case CEC_VENDOR_SAMSUNG:
-        m_handler = new CANCommandHandler(this);
-        break;
-      case CEC_VENDOR_LG:
-        m_handler = new CSLCommandHandler(this);
-        break;
-      case CEC_VENDOR_PANASONIC:
-        m_handler = new CVLCommandHandler(this);
-        break;
-      default:
-        m_handler = new CCECCommandHandler(this);
-        break;
+        CLibCEC::AddLog(CEC_LOG_DEBUG, "replacing the command handler for device '%s' (%x)", GetLogicalAddressName(), GetLogicalAddress());
+        delete m_handler;
+
+        switch (m_vendor)
+        {
+        case CEC_VENDOR_SAMSUNG:
+          m_handler = new CANCommandHandler(this);
+          break;
+        case CEC_VENDOR_LG:
+          m_handler = new CSLCommandHandler(this);
+          break;
+        case CEC_VENDOR_PANASONIC:
+          m_handler = new CVLCommandHandler(this);
+          break;
+        default:
+          m_handler = new CCECCommandHandler(this);
+          break;
+        }
+
+        m_handler->SetVendorId(m_vendor);
+        bInitHandler = true;
       }
+    }
+  }
 
-      m_handler->SetVendorId(m_vendor);
-      m_handler->InitHandler();
+  if (bInitHandler)
+  {
+    m_handler->InitHandler();
 
-      if (bActivateSource && m_processor->GetLogicalAddresses().IsSet(m_iLogicalAddress) && m_processor->IsInitialised() && IsActiveSource())
-        m_handler->ActivateSource();
-    }
+    if (bActivateSource && m_processor->GetLogicalAddresses().IsSet(m_iLogicalAddress) && m_processor->IsInitialised() && IsActiveSource())
+      m_handler->ActivateSource();
   }
 
+  MarkReady();
+
   return true;
 }
 
@@ -671,7 +683,7 @@ bool CCECBusDevice::TransmitActiveSource(void)
 
   {
     CLockObject lock(m_mutex);
-    if (m_powerStatus != CEC_POWER_STATUS_ON)
+    if (m_powerStatus != CEC_POWER_STATUS_ON && m_powerStatus != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON)
       CLibCEC::AddLog(CEC_LOG_DEBUG, "<< %s (%X) is not powered on", GetLogicalAddressName(), m_iLogicalAddress);
     else if (m_bActiveSource)
     {
@@ -685,7 +697,6 @@ bool CCECBusDevice::TransmitActiveSource(void)
   if (bSendActiveSource)
   {
     MarkBusy();
-    m_handler->TransmitImageViewOn(m_iLogicalAddress, CECDEVICE_TV);
     m_handler->TransmitActiveSource(m_iLogicalAddress, m_iPhysicalAddress);
     MarkReady();
     return true;
@@ -709,6 +720,23 @@ bool CCECBusDevice::TransmitCECVersion(cec_logical_address dest)
   return bReturn;
 }
 
+bool CCECBusDevice::TransmitImageViewOn(void)
+{
+  CLockObject lock(m_mutex);
+  if (m_powerStatus != CEC_POWER_STATUS_ON && m_powerStatus != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON)
+  {
+    CLibCEC::AddLog(CEC_LOG_DEBUG, "<< %s (%X) is not powered on", GetLogicalAddressName(), m_iLogicalAddress);
+    return false;
+  }
+  else
+  {
+    MarkBusy();
+    m_handler->TransmitImageViewOn(m_iLogicalAddress, CECDEVICE_TV);
+    MarkReady();
+    return true;
+  }
+}
+
 bool CCECBusDevice::TransmitInactiveSource(void)
 {
   uint16_t iPhysicalAddress;