don't mark a device as inactive when receiving a routing change message, only when...
[deb_libcec.git] / src / lib / devices / CECBusDevice.cpp
index b304cb9c3e1a902b9a0ae2c0652fa93857bbb8ac..4d9c56a2f380d87ebcf774f410c903eda26d42ee 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.
@@ -186,7 +186,7 @@ bool CCECBusDevice::HandleCommand(const cec_command &command)
   bHandled = m_handler->HandleCommand(command);
 
   /* change status to present */
-  if (bHandled && GetLogicalAddress() != CECDEVICE_BROADCAST)
+  if (bHandled && GetLogicalAddress() != CECDEVICE_BROADCAST && command.opcode_set == 1)
   {
     CLockObject lock(m_mutex);
     if (m_deviceStatus != CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC)
@@ -227,7 +227,9 @@ void CCECBusDevice::SetUnsupportedFeature(cec_opcode opcode)
       opcode == CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP ||
       opcode == CEC_OPCODE_ABORT ||
       opcode == CEC_OPCODE_FEATURE_ABORT ||
-      opcode == CEC_OPCODE_NONE)
+      opcode == CEC_OPCODE_NONE ||
+      opcode == CEC_OPCODE_USER_CONTROL_PRESSED ||
+      opcode == CEC_OPCODE_USER_CONTROL_RELEASE)
     return;
 
   {
@@ -391,12 +393,13 @@ bool CCECBusDevice::TransmitSetMenuLanguage(const cec_logical_address destinatio
     language = m_menuLanguage;
   }
 
-  char lang[3];
+  char lang[4];
   {
     CLockObject lock(m_mutex);
     lang[0] = language.language[0];
     lang[1] = language.language[1];
     lang[2] = language.language[2];
+    lang[3] = (char)0;
   }
 
   MarkBusy();
@@ -643,6 +646,8 @@ bool CCECBusDevice::RequestPowerStatus(const cec_logical_address initiator, bool
   {
     MarkBusy();
     bReturn = m_handler->TransmitRequestPowerStatus(initiator, m_iLogicalAddress, bWaitForResponse);
+    if (!bReturn)
+      SetPowerStatus(CEC_POWER_STATUS_UNKNOWN);
     MarkReady();
   }
   return bReturn;
@@ -746,7 +751,7 @@ bool CCECBusDevice::TransmitVendorID(const cec_logical_address destination, bool
   else
   {
     LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): vendor id %s (%x)", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, ToString((cec_vendor_id)iVendorId), iVendorId);
-    bReturn = m_handler->TransmitVendorID(m_iLogicalAddress, iVendorId, bIsReply);
+    bReturn = m_handler->TransmitVendorID(m_iLogicalAddress, destination, iVendorId, bIsReply);
   }
   MarkReady();
   return bReturn;
@@ -1128,23 +1133,22 @@ void CCECBusDevice::SetActiveRoute(uint16_t iRoute)
   if (!map)
     return;
 
-  CCECBusDevice* previouslyActive = map->GetActiveSource();
-  if (!previouslyActive)
-    return;
-
-  CECDEVICEVEC devices;
-  m_processor->GetDevices()->GetChildrenOf(devices, this);
-
-  for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++)
+  CCECBusDevice* newRoute = m_processor->GetDeviceByPhysicalAddress(iRoute, true);
+  if (newRoute)
   {
-    if (!CCECTypeUtils::PhysicalAddressIsIncluded(iRoute, (*it)->GetCurrentPhysicalAddress()))
-      (*it)->MarkAsInactiveSource();
+    // we were made the active source, send notification
+    if (newRoute->IsHandledByLibCEC())
+      newRoute->ActivateSource();
+    // another device was made active
+    else
+      newRoute->MarkAsActiveSource();
   }
 }
 
 void CCECBusDevice::SetStreamPath(uint16_t iNewAddress, uint16_t iOldAddress /* = CEC_INVALID_PHYSICAL_ADDRESS */)
 {
-  SetPowerStatus(CEC_POWER_STATUS_ON);
+  if (iNewAddress != CEC_INVALID_PHYSICAL_ADDRESS)
+    SetPowerStatus(CEC_POWER_STATUS_ON);
 
   CLockObject lock(m_mutex);
   if (iNewAddress != m_iStreamPath)