2 * This file is part of the libCEC(R) library.
4 * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
9 * This program is dual-licensed; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
27 * For more information contact:
28 * Pulse-Eight Licensing <license@pulse-eight.com>
29 * http://www.pulse-eight.com/
30 * http://www.pulse-eight.net/
34 #include "PHCommandHandler.h"
36 #include "lib/devices/CECBusDevice.h"
37 #include "lib/CECProcessor.h"
38 #include "lib/LibCEC.h"
39 #include "lib/CECClient.h"
42 using namespace PLATFORM
;
44 #define LIB_CEC m_busDevice->GetProcessor()->GetLib()
45 #define ToString(p) LIB_CEC->ToString(p)
47 #define TV_ON_CHECK_TIME_MS 5000
49 CImageViewOnCheck::~CImageViewOnCheck(void)
56 void* CImageViewOnCheck::Process(void)
58 CCECBusDevice
* tv
= m_handler
->m_processor
->GetDevice(CECDEVICE_TV
);
59 cec_power_status
status(CEC_POWER_STATUS_UNKNOWN
);
60 while (status
!= CEC_POWER_STATUS_ON
)
62 m_event
.Wait(TV_ON_CHECK_TIME_MS
);
66 status
= tv
->GetPowerStatus(m_handler
->m_busDevice
->GetLogicalAddress());
68 if (status
!= CEC_POWER_STATUS_ON
&&
69 status
!= CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON
)
71 CLockObject
lock(m_handler
->m_mutex
);
72 tv
->OnImageViewOnSent(false);
73 m_handler
->m_iActiveSourcePending
= GetTimeMs();
79 CPHCommandHandler::CPHCommandHandler(CCECBusDevice
*busDevice
,
80 int32_t iTransmitTimeout
/* = CEC_DEFAULT_TRANSMIT_TIMEOUT */,
81 int32_t iTransmitWait
/* = CEC_DEFAULT_TRANSMIT_WAIT */,
82 int8_t iTransmitRetries
/* = CEC_DEFAULT_TRANSMIT_RETRIES */,
83 int64_t iActiveSourcePending
/* = 0 */) :
84 CCECCommandHandler(busDevice
, iTransmitTimeout
, iTransmitWait
, iTransmitRetries
, iActiveSourcePending
),
85 m_iLastKeyCode(CEC_USER_CONTROL_CODE_UNKNOWN
)
87 m_imageViewOnCheck
= new CImageViewOnCheck(this);
88 m_vendorId
= CEC_VENDOR_PHILIPS
;
91 CPHCommandHandler::~CPHCommandHandler(void)
93 delete m_imageViewOnCheck
;
96 bool CPHCommandHandler::InitHandler(void)
98 CCECBusDevice
*primary
= m_processor
->GetPrimaryDevice();
99 if (primary
&& primary
->GetLogicalAddress() != CECDEVICE_UNREGISTERED
)
101 //XXX hack to use this handler for the primary device
102 if (m_busDevice
->GetLogicalAddress() == CECDEVICE_TV
&&
103 primary
&& m_busDevice
->GetLogicalAddress() != primary
->GetLogicalAddress())
105 primary
->SetVendorId(CEC_VENDOR_PHILIPS
);
106 primary
->ReplaceHandler(false);
110 return CCECCommandHandler::InitHandler();
113 bool CPHCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly
/* = false */)
116 CCECBusDevice
* tv
= m_processor
->GetDevice(CECDEVICE_TV
);
117 if (m_busDevice
->IsActiveSource() &&
118 m_busDevice
->IsHandledByLibCEC() &&
119 tv
&& tv
->GetCurrentPowerStatus() != CEC_POWER_STATUS_ON
&&
120 !bTransmitDelayedCommandsOnly
)
122 // tv sometimes ignores image view on. check the power status of the tv in 5 seconds, and retry when it failed to power up
123 if (m_imageViewOnCheck
&& !m_imageViewOnCheck
->IsRunning())
124 m_imageViewOnCheck
->CreateThread(false);
127 return CCECCommandHandler::ActivateSource(bTransmitDelayedCommandsOnly
);
130 int CPHCommandHandler::HandleUserControlPressed(const cec_command
& command
)
132 // TV sometimes keeps sending key presses without releases
133 if (m_iLastKeyCode
== command
.parameters
[0])
134 return COMMAND_HANDLED
;
136 m_iLastKeyCode
= command
.parameters
[0];
138 return CCECCommandHandler::HandleUserControlPressed(command
);
141 int CPHCommandHandler::HandleUserControlRelease(const cec_command
& command
)
143 m_iLastKeyCode
= CEC_USER_CONTROL_CODE_UNKNOWN
;
145 return CCECCommandHandler::HandleUserControlRelease(command
);
148 int CPHCommandHandler::HandleDeviceVendorId(const cec_command
& command
)
150 m_busDevice
->SetPowerStatus(CEC_POWER_STATUS_ON
);
151 return CCECCommandHandler::HandleDeviceVendorId(command
);
154 int CPHCommandHandler::HandleGiveDeviceVendorId(const cec_command
& command
)
156 LIB_CEC
->AddLog(CEC_LOG_DEBUG
, "<< %s (%X) -> %s (%X): vendor id feature abort", ToString(command
.destination
), command
.destination
, ToString(command
.initiator
), command
.initiator
);
157 m_processor
->TransmitAbort(command
.destination
, command
.initiator
, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID
);
158 return COMMAND_HANDLED
;