+ }
+
+ CCECBusDevice* tv = m_processor->GetDevice(CECDEVICE_TV);
+ if (!tv)
+ {
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s - couldn't get TV instance", __FUNCTION__);
+ return false;
+ }
+
+ if (tv->ImageViewOnSent())
+ {
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - 'image view on' already sent", __FUNCTION__);
+ return true;
+ }
+
+ bool bImageViewOnSent(false);
+ MarkBusy();
+ bImageViewOnSent = m_handler->TransmitImageViewOn(m_iLogicalAddress, CECDEVICE_TV);
+ MarkReady();
+
+ if (bImageViewOnSent)
+ tv->OnImageViewOnSent(true);
+
+ return bImageViewOnSent;
+}
+
+bool CCECBusDevice::TransmitInactiveSource(void)
+{
+ uint16_t iPhysicalAddress;
+ {
+ CLockObject lock(m_mutex);
+ LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> broadcast (F): inactive source", GetLogicalAddressName(), m_iLogicalAddress);
+ iPhysicalAddress = m_iPhysicalAddress;
+ }
+
+ MarkBusy();
+ bool bReturn = m_handler->TransmitInactiveSource(m_iLogicalAddress, iPhysicalAddress);
+ MarkReady();
+ return bReturn;
+}
+
+bool CCECBusDevice::TransmitPendingActiveSourceCommands(void)
+{
+ MarkBusy();
+ bool bReturn = m_handler->ActivateSource(true);
+ MarkReady();
+ return bReturn;
+}
+
+void CCECBusDevice::SetActiveRoute(uint16_t iRoute)
+{
+ SetPowerStatus(CEC_POWER_STATUS_ON);
+
+ CCECDeviceMap* map = m_processor->GetDevices();
+ if (!map)
+ return;
+
+ CCECBusDevice* newRoute = m_processor->GetDeviceByPhysicalAddress(iRoute, true);
+ if (newRoute && newRoute->IsHandledByLibCEC())
+ {
+ // we were made the active source, send notification
+ newRoute->ActivateSource();
+ }
+}
+
+void CCECBusDevice::SetStreamPath(uint16_t iNewAddress, uint16_t iOldAddress /* = CEC_INVALID_PHYSICAL_ADDRESS */)
+{
+ if (iNewAddress != CEC_INVALID_PHYSICAL_ADDRESS)
+ SetPowerStatus(CEC_POWER_STATUS_ON);
+
+ CLockObject lock(m_mutex);
+ if (iNewAddress != m_iStreamPath)
+ {
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%X): stream path changed from %04x to %04x", GetLogicalAddressName(), m_iLogicalAddress, iOldAddress == 0 ? m_iStreamPath : iOldAddress, iNewAddress);
+ m_iStreamPath = iNewAddress;
+ }
+
+ if (!LIB_CEC->IsValidPhysicalAddress(iNewAddress))
+ return;
+
+ CCECBusDevice *device = m_processor->GetDeviceByPhysicalAddress(iNewAddress);
+ if (device)
+ {
+ // if a device is found with the new physical address, mark it as active, which will automatically mark all other devices as inactive
+ device->MarkAsActiveSource();
+
+ // respond with an active source message if this device is handled by libCEC
+ if (device->IsHandledByLibCEC())
+ device->TransmitActiveSource(true);
+ }
+ else
+ {
+ // try to find the device with the old address, and mark it as inactive when found
+ device = m_processor->GetDeviceByPhysicalAddress(iOldAddress);
+ if (device)
+ device->MarkAsInactiveSource();
+ }
+}
+
+bool CCECBusDevice::PowerOn(const cec_logical_address initiator)
+{
+ bool bReturn(false);
+ GetVendorId(initiator); // ensure that we got the vendor id, because the implementations vary per vendor
+
+ MarkBusy();
+ cec_power_status currentStatus;
+ if (m_iLogicalAddress == CECDEVICE_TV ||
+ ((currentStatus = GetPowerStatus(initiator, false)) != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON &&
+ currentStatus != CEC_POWER_STATUS_ON))
+ {
+ LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< powering on '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
+ bReturn = m_handler->PowerOn(initiator, m_iLogicalAddress);
+ }
+ else
+ {
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "'%s' (%X) is already '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(currentStatus));
+ }
+
+ MarkReady();
+ return bReturn;
+}
+
+bool CCECBusDevice::Standby(const cec_logical_address initiator)
+{
+ GetVendorId(initiator); // ensure that we got the vendor id, because the implementations vary per vendor
+
+ LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< putting '%s' (%X) in standby mode", GetLogicalAddressName(), m_iLogicalAddress);
+ MarkBusy();
+ bool bReturn = m_handler->TransmitStandby(initiator, m_iLogicalAddress);
+ MarkReady();
+ return bReturn;
+}
+
+bool CCECBusDevice::NeedsPoll(void)
+{
+ bool bSendPoll(false);
+ cec_logical_address pollAddress(CECDEVICE_UNKNOWN);
+ switch (m_iLogicalAddress)
+ {
+ case CECDEVICE_PLAYBACKDEVICE3:
+ pollAddress = CECDEVICE_PLAYBACKDEVICE2;
+ break;
+ case CECDEVICE_PLAYBACKDEVICE2:
+ pollAddress = CECDEVICE_PLAYBACKDEVICE1;
+ break;
+ case CECDEVICE_RECORDINGDEVICE3:
+ pollAddress = CECDEVICE_RECORDINGDEVICE2;
+ break;
+ case CECDEVICE_RECORDINGDEVICE2:
+ pollAddress = CECDEVICE_RECORDINGDEVICE1;
+ break;
+ case CECDEVICE_TUNER4:
+ pollAddress = CECDEVICE_TUNER3;
+ break;
+ case CECDEVICE_TUNER3:
+ pollAddress = CECDEVICE_TUNER2;
+ break;
+ case CECDEVICE_TUNER2:
+ pollAddress = CECDEVICE_TUNER1;
+ break;
+ case CECDEVICE_AUDIOSYSTEM:
+ case CECDEVICE_PLAYBACKDEVICE1:
+ case CECDEVICE_RECORDINGDEVICE1:
+ case CECDEVICE_TUNER1:
+ case CECDEVICE_TV:
+ bSendPoll = true;
+ break;
+ default:
+ break;
+ }
+
+ if (!bSendPoll && pollAddress != CECDEVICE_UNKNOWN)
+ {
+ CCECBusDevice *device = m_processor->GetDevice(pollAddress);
+ if (device)
+ {
+ cec_bus_device_status status = device->GetStatus();
+ bSendPoll = (status == CEC_DEVICE_STATUS_PRESENT || status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC);
+ }