cec: also send a menu state update when activating the source in CVLCommandHandler...
[deb_libcec.git] / src / lib / implementations / VLCommandHandler.cpp
1 /*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
6 *
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
8 *
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.
13 *
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.
18 *
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.
22 *
23 *
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
26 *
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/
31 */
32
33 #include "VLCommandHandler.h"
34 #include "../devices/CECBusDevice.h"
35 #include "../CECProcessor.h"
36 #include "../LibCEC.h"
37 #include "../CECClient.h"
38
39 #define VL_POWER_CHANGE 0x20
40 #define VL_POWERED_UP 0x00
41 #define VL_POWERED_DOWN 0x01
42
43 using namespace CEC;
44 using namespace PLATFORM;
45
46 #define LIB_CEC m_busDevice->GetProcessor()->GetLib()
47 #define ToString(p) LIB_CEC->ToString(p)
48
49 CVLCommandHandler::CVLCommandHandler(CCECBusDevice *busDevice) :
50 CCECCommandHandler(busDevice),
51 m_bActiveSourcePending(false),
52 m_bPowerUpEventReceived(false)
53 {
54 m_vendorId = CEC_VENDOR_PANASONIC;
55
56 /* use the VL commandhandler for the primary device that is handled by libCEC */
57 if (busDevice->GetLogicalAddress() == CECDEVICE_TV)
58 {
59 CCECBusDevice *primary = m_processor->GetPrimaryDevice();
60 if (primary && m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress())
61 {
62 primary->SetVendorId(CEC_VENDOR_PANASONIC);
63 primary->ReplaceHandler(false);
64 }
65 }
66 }
67
68 bool CVLCommandHandler::InitHandler(void)
69 {
70 CCECBusDevice *primary = m_processor->GetPrimaryDevice();
71 if (primary->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE)
72 return m_processor->GetPrimaryClient()->ChangeDeviceType(CEC_DEVICE_TYPE_RECORDING_DEVICE, CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
73
74 return CCECCommandHandler::InitHandler();
75 }
76
77 bool CVLCommandHandler::HandleDeviceVendorCommandWithId(const cec_command &command)
78 {
79 if (command.initiator == CECDEVICE_TV &&
80 command.destination == CECDEVICE_BROADCAST &&
81 command.parameters.At(3) == VL_POWER_CHANGE)
82 {
83 if (command.parameters.At(4) == VL_POWERED_UP)
84 {
85 LIB_CEC->AddLog(CEC_LOG_DEBUG, "TV powered up");
86 {
87 CLockObject lock(m_mutex);
88 m_bPowerUpEventReceived = true;
89 }
90 m_processor->TransmitPendingActiveSourceCommands();
91 }
92 else if (command.parameters.At(4) == VL_POWERED_DOWN)
93 LIB_CEC->AddLog(CEC_LOG_DEBUG, "TV powered down");
94 else if (command.parameters.At(4) == VL_POWERED_DOWN)
95 LIB_CEC->AddLog(CEC_LOG_DEBUG, "unknown vendor command");
96
97 return true;
98 }
99
100 return CCECCommandHandler::HandleDeviceVendorCommandWithId(command);
101 }
102
103 bool CVLCommandHandler::TransmitActiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress)
104 {
105 bool bPowerUpEventReceived(false);
106
107 CCECBusDevice *tv = m_processor->GetDevice(CECDEVICE_TV);
108 if (tv && tv->GetCurrentVendorId() == CEC_VENDOR_PANASONIC)
109 {
110 CVLCommandHandler *handler = static_cast<CVLCommandHandler *>(tv->GetHandler());
111 bPowerUpEventReceived = handler ? handler->PowerUpEventReceived() : false;
112 }
113
114 if (!bPowerUpEventReceived)
115 {
116 CLockObject lock(m_mutex);
117 // wait until we received the event
118 m_bActiveSourcePending = true;
119 return true;
120 }
121 else
122 {
123 // transmit standard active source message
124 return CCECCommandHandler::TransmitActiveSource(iInitiator, iPhysicalAddress) &&
125 TransmitMenuState(iInitiator, CECDEVICE_TV, CEC_MENU_STATE_ACTIVATED);
126 }
127 }
128
129 bool CVLCommandHandler::TransmitPendingActiveSourceCommands(void)
130 {
131 bool bTransmitCommand(false);
132 {
133 CLockObject lock(m_mutex);
134 bTransmitCommand = m_bActiveSourcePending;
135 m_bActiveSourcePending = false;
136 }
137
138 if (bTransmitCommand)
139 {
140 LIB_CEC->AddLog(CEC_LOG_DEBUG, "transmitting delayed activate source command");
141 return CCECCommandHandler::TransmitActiveSource(m_busDevice->GetLogicalAddress(), m_busDevice->GetCurrentPhysicalAddress()) &&
142 TransmitMenuState(m_busDevice->GetLogicalAddress(), CECDEVICE_TV, CEC_MENU_STATE_ACTIVATED);
143 }
144 return true;
145 }
146
147 bool CVLCommandHandler::PowerUpEventReceived(void)
148 {
149 {
150 CLockObject lock(m_mutex);
151 if (m_bPowerUpEventReceived)
152 return true;
153 }
154
155 cec_power_status powerStatus = m_busDevice->GetCurrentPowerStatus();
156
157 CLockObject lock(m_mutex);
158 m_bPowerUpEventReceived = (powerStatus == CEC_POWER_STATUS_ON);
159 return m_bPowerUpEventReceived;
160 }