X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Flib%2Fimplementations%2FPHCommandHandler.cpp;h=a4e7129d44b22780b3523c19abb8978cd4ab8eb9;hb=6d5033117aacb1be07d93b99a82115146af4d623;hp=f8505c7c883c7068bff6663d9129ba93c34dd70d;hpb=ecc633c51b6c69bebaff4932e90245665ca06373;p=deb_libcec.git diff --git a/src/lib/implementations/PHCommandHandler.cpp b/src/lib/implementations/PHCommandHandler.cpp index f8505c7..a4e7129 100644 --- a/src/lib/implementations/PHCommandHandler.cpp +++ b/src/lib/implementations/PHCommandHandler.cpp @@ -39,10 +39,43 @@ #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,53 @@ 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; } +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()) + 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 +144,16 @@ 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); +} + +int CPHCommandHandler::HandleGiveDeviceVendorId(const cec_command& command) +{ + LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< %s (%X) -> %s (%X): vendor id feature abort", ToString(command.destination), command.destination, ToString(command.initiator), command.initiator); + m_processor->TransmitAbort(command.destination, command.initiator, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID); + return COMMAND_HANDLED; +}