added methods to get the audiostatus and toggle the mute status
[deb_libcec.git] / src / lib / implementations / CECCommandHandler.cpp
index ad2488750b129cbe784fa3f186757d3cf46f47d0..1274dd2e8e17e8c997a9ffd75e45a8d6a7b7d158 100644 (file)
@@ -209,10 +209,12 @@ int CCECCommandHandler::HandleActiveSource(const cec_command &command)
   if (command.parameters.size == 2)
   {
     uint16_t iAddress = ((uint16_t)command.parameters[0] << 8) | ((uint16_t)command.parameters[1]);
-    m_processor->GetDevices()->SetActiveSource(iAddress);
-    CCECBusDevice *device = m_processor->GetDeviceByPhysicalAddress(iAddress);
+    CCECBusDevice *device = m_processor->GetDevice(command.initiator);
     if (device)
+    {
+      device->SetPhysicalAddress(iAddress);
       device->MarkAsActiveSource();
+    }
 
     m_processor->GetDevices()->SignalAll(command.opcode);
     return COMMAND_HANDLED;
@@ -573,11 +575,21 @@ int CCECCommandHandler::HandleSetStreamPath(const cec_command &command)
 
     /* one of the device handled by libCEC has been made active */
     CCECBusDevice *device = GetDeviceByPhysicalAddress(iStreamAddress);
-    if (device && device->IsHandledByLibCEC())
+    if (device)
     {
-      device->ActivateSource();
+      if (device->IsHandledByLibCEC() && !device->IsActiveSource())
+        device->ActivateSource();
+      else
+        device->MarkAsActiveSource();
       return COMMAND_HANDLED;
     }
+    else
+    {
+      cec_logical_address previousSource = m_processor->GetActiveSource(false);
+      CCECBusDevice* device = m_processor->GetDevice(previousSource);
+      if (device && device->GetCurrentPhysicalAddress() != iStreamAddress)
+        device->MarkAsInactiveSource();
+    }
   }
 
   return CEC_ABORT_REASON_INVALID_OPERAND;
@@ -804,13 +816,17 @@ void CCECCommandHandler::SetPhysicalAddress(cec_logical_address iAddress, uint16
     if (device)
       device->SetPhysicalAddress(iNewAddress);
     else
-    {
       LIB_CEC->AddLog(CEC_LOG_DEBUG, "device with logical address %X not found", iAddress);
-    }
 
     /* another device reported the same physical address as ours */
     if (client)
+    {
+      libcec_parameter param;
+      param.paramType = CEC_PARAMETER_TYPE_STRING;
+      param.paramData = (void*)"Physical address in use by another device. Please verify your settings";
+      client->Alert(CEC_ALERT_PHYSICAL_ADDRESS_ERROR, param);
       client->ResetPhysicalAddress();
+    }
   }
   else
   {
@@ -882,6 +898,14 @@ bool CCECCommandHandler::TransmitRequestOSDName(const cec_logical_address iIniti
   return Transmit(command, !bWaitForResponse, false);
 }
 
+bool CCECCommandHandler::TransmitRequestAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */)
+{
+  cec_command command;
+  cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_AUDIO_STATUS);
+
+  return Transmit(command, !bWaitForResponse, false);
+}
+
 bool CCECCommandHandler::TransmitRequestPhysicalAddress(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */)
 {
   cec_command command;
@@ -990,7 +1014,7 @@ bool CCECCommandHandler::TransmitPhysicalAddress(const cec_logical_address iInit
   return Transmit(command, false, bIsReply);
 }
 
-bool CCECCommandHandler::TransmitSetMenuLanguage(const cec_logical_address iInitiator, const char lang[3], bool bIsReply)
+bool CCECCommandHandler::TransmitSetMenuLanguage(const cec_logical_address iInitiator, const char lang[4], bool bIsReply)
 {
   cec_command command;
   command.Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_SET_MENU_LANGUAGE);
@@ -1018,7 +1042,7 @@ bool CCECCommandHandler::TransmitPowerState(const cec_logical_address iInitiator
   return Transmit(command, false, bIsReply);
 }
 
-bool CCECCommandHandler::TransmitVendorID(const cec_logical_address iInitiator, uint64_t iVendorId, bool bIsReply)
+bool CCECCommandHandler::TransmitVendorID(const cec_logical_address iInitiator, const cec_logical_address UNUSED(iDestination), uint64_t iVendorId, bool bIsReply)
 {
   cec_command command;
   cec_command::Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_DEVICE_VENDOR_ID);
@@ -1126,11 +1150,15 @@ bool CCECCommandHandler::Transmit(cec_command &command, bool bSuppressWait, bool
       LIB_CEC->AddLog(CEC_LOG_DEBUG, "not sending command '%s': destination device '%s' marked as handled by libCEC", ToString(command.opcode),ToString(command.destination));
       return bReturn;
     }
+    else if (destinationDevice->IsUnsupportedFeature(command.opcode))
+    {
+      return true;
+    }
   }
 
   {
     uint8_t iTries(0), iMaxTries(!command.opcode_set ? 1 : m_iTransmitRetries + 1);
-    while (!bReturn && ++iTries <= iMaxTries && !m_busDevice->IsUnsupportedFeature(command.opcode))
+    while (!bReturn && ++iTries <= iMaxTries)
     {
       if ((bReturn = m_processor->Transmit(command, bIsReply)) == true)
       {