+libcec (2.0.5-1) unstable; urgency=low
+
+ * changed:
+ * also try polls at least twice when it failed
+ * added methods to get the audiostatus and toggle the mute status from the
+ amplifier (if connected)
+ * added comboKey and iComboKeyTimeoutMs to libcec_configuration
+ * force cec_user_control_code_unknown to 0xFF
+ * fixed:
+ * check unsupported features properly
+ * only send an active source message when the stream path changed and we
+ weren't the active source yet
+ * don't mark as inactive source on routing changes
+ * press & hold
+ * never mark user control opcodes as unsupported
+ * report our OSD name to the TV, since some TVs don't request it
+ * initial audiostatus value
+ * don't log a no longer relevant FIXME
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com> Thu, 6 Dec 2012 20:58:00 +0100
+
libcec (2.0.4-1) unstable; urgency=low
* changed:
+libcec (2.0.5-1) unstable; urgency=low
+
+ * changed:
+ * also try polls at least twice when it failed
+ * added methods to get the audiostatus and toggle the mute status from the
+ amplifier (if connected)
+ * added comboKey and iComboKeyTimeoutMs to libcec_configuration
+ * force cec_user_control_code_unknown to 0xFF
+ * fixed:
+ * check unsupported features properly
+ * only send an active source message when the stream path changed and we
+ weren't the active source yet
+ * don't mark as inactive source on routing changes
+ * press & hold
+ * never mark user control opcodes as unsupported
+ * report our OSD name to the TV, since some TVs don't request it
+ * initial audiostatus value
+ * don't log a no longer relevant FIXME
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com> Thu, 6 Dec 2012 20:58:00 +0100
+
libcec (2.0.4-1) unstable; urgency=low
* changed:
virtual uint8_t VolumeDown(bool bSendRelease = true) = 0;
/*!
+ * @deprecated Use AudioToggleMute() instead
* @brief Sends a mute keypress to an audiosystem if it's present.
* @param bSendRelease Send a key release after the keypress.
* @return The new audio status.
virtual const char *ToString(const cec_server_version version) = 0;
virtual const char *ToString(const cec_user_control_code key) = 0;
virtual const char *ToString(const cec_adapter_type type) = 0;
+
+ /*!
+ * @brief Toggle the mute status of the AVR (if present)
+ * @return The new audio status.
+ */
+ virtual uint8_t AudioToggleMute(void) = 0;
+
+ /*!
+ * @brief Mute the AVR (if present)
+ * @return The new audio status.
+ */
+ virtual uint8_t AudioMute(void) = 0;
+
+ /*!
+ * @brief Mute the AVR (if connected)
+ * @return The new audio status.
+ */
+ virtual uint8_t AudioUnmute(void) = 0;
+
+ /*!
+ * @brief Get the current audio status (if an AVR is connected)
+ * @return The current audio status, or cec_audio_status if unknown.
+ */
+ virtual uint8_t AudioStatus(void) = 0;
};
};
extern DECLSPEC uint16_t cec_get_adapter_product_id(void);
+extern DECLSPEC uint8_t cec_audio_toggle_mute(void);
+
+extern DECLSPEC uint8_t cec_audio_mute(void);
+
+extern DECLSPEC uint8_t cec_audio_unmute(void);
+
+extern DECLSPEC uint8_t cec_audio_status(void);
+
#ifdef __cplusplus
};
#endif
*/
#define CEC_FORWARD_STANDBY_MIN_INTERVAL 10000
+/*!
+ * default timeout in milliseconds for combo keys
+ */
+#define CEC_DEFAULT_COMBO_TIMEOUT_MS 1000
+
/*!
* the virtual device path to use for the Raspberry Pi's CEC wire
*/
#define MSGESC 0xFD
#define ESCOFFSET 3
+// defines to make compile time checks for certain features easy
+#define CEC_FEATURE_CONFIGURABLE_COMBO_KEY 1
typedef enum cec_abort_reason
{
CEC_USER_CONTROL_CODE_AN_RETURN = 0x91,
CEC_USER_CONTROL_CODE_AN_CHANNELS_LIST = 0x96,
CEC_USER_CONTROL_CODE_MAX = 0x96,
- CEC_USER_CONTROL_CODE_UNKNOWN
+ CEC_USER_CONTROL_CODE_UNKNOWN = 0xFF
} cec_user_control_code;
typedef enum cec_logical_address
CEC_CLIENT_VERSION_2_0_2 = 0x2002,
CEC_CLIENT_VERSION_2_0_3 = 0x2003,
CEC_CLIENT_VERSION_2_0_4 = 0x2004,
- CEC_CLIENT_VERSION_CURRENT = 0x2004
+ CEC_CLIENT_VERSION_2_0_5 = 0x2005,
+ CEC_CLIENT_VERSION_CURRENT = 0x2005
} cec_client_version;
typedef enum cec_server_version
CEC_SERVER_VERSION_2_0_2 = 0x2002,
CEC_SERVER_VERSION_2_0_3 = 0x2003,
CEC_SERVER_VERSION_2_0_4 = 0x2004,
- CEC_SERVER_VERSION_CURRENT = 0x2004
+ CEC_SERVER_VERSION_2_0_5 = 0x2005,
+ CEC_SERVER_VERSION_CURRENT = 0x2005
} cec_server_version;
struct libcec_configuration
cec_version cecVersion; /*!< CEC spec version to use by libCEC. defaults to v1.4. added in 1.8.0 */
cec_adapter_type adapterType; /*!< type of the CEC adapter that we're connected to. added in 1.8.2 */
uint8_t iDoubleTapTimeoutMs; /*!< prevent double taps withing this timeout. defaults to 200ms. added in 2.0.0 */
+ cec_user_control_code comboKey; /*!< key code that initiates combo keys. defaults to CEC_USER_CONTROL_CODE_F1_BLUE. CEC_USER_CONTROL_CODE_UNKNOWN to disable. added in 2.0.5 */
+ uint32_t iComboKeyTimeoutMs; /*!< timeout until the combo key is sent as normal keypress */
#ifdef __cplusplus
libcec_configuration(void) { Clear(); }
bMonitorOnly == other.bMonitorOnly &&
cecVersion == other.cecVersion &&
adapterType == other.adapterType &&
- iDoubleTapTimeoutMs == other.iDoubleTapTimeoutMs);
+ iDoubleTapTimeoutMs == other.iDoubleTapTimeoutMs &&
+ (other.clientVersion <= CEC_CLIENT_VERSION_2_0_4 || comboKey == other.comboKey) &&
+ (other.clientVersion <= CEC_CLIENT_VERSION_2_0_4 || iComboKeyTimeoutMs == other.iComboKeyTimeoutMs));
}
bool operator!=(const libcec_configuration &other) const
baseDevice = (cec_logical_address)CEC_DEFAULT_BASE_DEVICE;
iHDMIPort = CEC_DEFAULT_HDMI_PORT;
tvVendor = (uint64_t)CEC_VENDOR_UNKNOWN;
- clientVersion = (uint32_t)CEC_CLIENT_VERSION_2_0_0;
- serverVersion = (uint32_t)CEC_SERVER_VERSION_2_0_0;
+ clientVersion = (uint32_t)CEC_CLIENT_VERSION_CURRENT;
+ serverVersion = (uint32_t)CEC_SERVER_VERSION_CURRENT;
bAutodetectAddress = 0;
bGetSettingsFromROM = CEC_DEFAULT_SETTING_GET_SETTINGS_FROM_ROM;
bUseTVMenuLanguage = CEC_DEFAULT_SETTING_USE_TV_MENU_LANGUAGE;
cecVersion = (cec_version)CEC_DEFAULT_SETTING_CEC_VERSION;
adapterType = ADAPTERTYPE_UNKNOWN;
iDoubleTapTimeoutMs = CEC_DOUBLE_TAP_TIMEOUT_MS;
+ comboKey = CEC_USER_CONTROL_CODE_STOP;
+ iComboKeyTimeoutMs = CEC_DEFAULT_COMBO_TIMEOUT_MS;
memset(strDeviceName, 0, 13);
deviceTypes.Clear();
!include "LogicLib.nsh"
!include "x64.nsh"
-Name "Pulse-Eight libCEC version 2.0.4"
+Name "Pulse-Eight libCEC version 2.0.5"
OutFile "..\build\libCEC-installer.exe"
XPStyle on
Config = new LibCECConfiguration();
Config.DeviceTypes.Types[0] = CecDeviceType.RecordingDevice;
Config.DeviceName = "CEC Tester";
- Config.ClientVersion = CecClientVersion.Version2_0_4;
+ Config.ClientVersion = CecClientVersion.Version2_0_5;
Config.SetCallbacks(this);
LogLevel = (int)CecLogLevel.All;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.0.4.0")]
-[assembly: AssemblyFileVersion("2.0.4.0")]
+[assembly: AssemblyVersion("2.0.5.0")]
+[assembly: AssemblyFileVersion("2.0.5.0")]
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
-[assembly:AssemblyVersionAttribute("2.0.4.0")];
+[assembly:AssemblyVersionAttribute("2.0.5.0")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
/// <summary>
/// v2.0.4
/// </summary>
- Version2_0_4 = 0x2004
+ Version2_0_4 = 0x2004,
+ /// <summary>
+ /// v2.0.5
+ /// </summary>
+ Version2_0_5 = 0x2005
};
/// <summary>
/// <summary>
/// v2.0.4
/// </summary>
- Version2_0_4 = 0x2004
+ Version2_0_4 = 0x2004,
+ /// <summary>
+ /// v2.0.5
+ /// </summary>
+ Version2_0_5 = 0x2005
};
/// <summary>
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.0.4.0")]
-[assembly: AssemblyFileVersion("2.0.4.0")]
+[assembly: AssemblyVersion("2.0.5.0")]
+[assembly: AssemblyFileVersion("2.0.5.0")]
{
if (_config == null)
{
- _config = new LibCECConfiguration { DeviceName = "CEC Tray", ClientVersion = CecClientVersion.Version2_0_4 };
+ _config = new LibCECConfiguration { DeviceName = "CEC Tray", ClientVersion = CecClientVersion.Version2_0_5 };
_config.DeviceTypes.Types[0] = CecDeviceType.RecordingDevice;
_config.SetCallbacks(this);
#define LIB_CEC m_processor->GetLib()
#define ToString(x) CCECTypeUtils::ToString(x)
-#define COMBO_KEY CEC_USER_CONTROL_CODE_STOP
-#define COMBO_TIMEOUT_MS 1000
-
CCECClient::CCECClient(CCECProcessor *processor, const libcec_configuration &configuration) :
m_processor(processor),
m_bInitialised(false),
(uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
}
+uint8_t CCECClient::AudioToggleMute(void)
+{
+ CCECBusDevice *device = GetPrimaryDevice();
+ CCECAudioSystem *audio = m_processor->GetAudioSystem();
+
+ return device && audio && audio->IsPresent() ?
+ audio->MuteAudio(device->GetLogicalAddress()) :
+ (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t CCECClient::AudioMute(void)
+{
+ CCECBusDevice *device = GetPrimaryDevice();
+ CCECAudioSystem *audio = m_processor->GetAudioSystem();
+ uint8_t iStatus = device && audio && audio->IsPresent() ? audio->GetAudioStatus(device->GetLogicalAddress()) : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+ if ((iStatus & CEC_AUDIO_MUTE_STATUS_MASK) != CEC_AUDIO_MUTE_STATUS_MASK)
+ iStatus = audio->MuteAudio(device->GetLogicalAddress());
+
+ return iStatus;
+}
+
+uint8_t CCECClient::AudioUnmute(void)
+{
+ CCECBusDevice *device = GetPrimaryDevice();
+ CCECAudioSystem *audio = m_processor->GetAudioSystem();
+ uint8_t iStatus = device && audio && audio->IsPresent() ? audio->GetAudioStatus(device->GetLogicalAddress()) : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+ if ((iStatus & CEC_AUDIO_MUTE_STATUS_MASK) == CEC_AUDIO_MUTE_STATUS_MASK)
+ iStatus = audio->MuteAudio(device->GetLogicalAddress());
+
+ return iStatus;
+}
+
+uint8_t CCECClient::AudioStatus(void)
+{
+ CCECBusDevice *device = GetPrimaryDevice();
+ CCECAudioSystem *audio = m_processor->GetAudioSystem();
+ return device && audio && audio->IsPresent() ? audio->GetAudioStatus(device->GetLogicalAddress()) : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
bool CCECClient::SendKeypress(const cec_logical_address iDestination, const cec_user_control_code key, bool bWait /* = true */)
{
CCECBusDevice *dest = m_processor->GetDevice(iDestination);
bool CCECClient::SetConfiguration(const libcec_configuration &configuration)
{
+ libcec_configuration defaultSettings;
bool bIsRunning(m_processor && m_processor->CECInitialised());
CCECBusDevice *primary = bIsRunning ? GetPrimaryDevice() : NULL;
uint16_t iPA = primary ? primary->GetCurrentPhysicalAddress() : CEC_INVALID_PHYSICAL_ADDRESS;
m_configuration.bMonitorOnly = configuration.bMonitorOnly;
m_configuration.cecVersion = configuration.cecVersion;
m_configuration.adapterType = configuration.adapterType;
- m_configuration.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
+ m_configuration.iDoubleTapTimeoutMs = configuration.iDoubleTapTimeoutMs;
+ m_configuration.deviceTypes.Add(configuration.deviceTypes[0]);
+
+ if (m_configuration.clientVersion >= CEC_CLIENT_VERSION_2_0_5)
+ {
+ m_configuration.comboKey = configuration.comboKey;
+ m_configuration.iComboKeyTimeoutMs = configuration.iComboKeyTimeoutMs;
+ }
+ else
+ {
+ m_configuration.comboKey = defaultSettings.comboKey;
+ m_configuration.iComboKeyTimeoutMs = defaultSettings.iComboKeyTimeoutMs;
+ }
}
bool bNeedReinit(false);
{
key.duration = (unsigned int) (GetTimeMs() - m_buttontime);
- if (key.duration > COMBO_TIMEOUT_MS || m_iCurrentButton != COMBO_KEY || bSendComboKey)
+ cec_user_control_code comboKey(m_configuration.comboKey);
+ uint32_t iTimeoutMs(m_configuration.iComboKeyTimeoutMs);
+
+ if (key.duration > iTimeoutMs || m_iCurrentButton != comboKey || bSendComboKey)
{
key.keycode = m_iCurrentButton;
void CCECClient::AddKey(const cec_keypress &key)
{
- // send back the previous key if there is one
- AddKey();
-
if (key.keycode > CEC_USER_CONTROL_CODE_MAX &&
key.keycode < CEC_USER_CONTROL_CODE_SELECT)
+ {
+ // send back the previous key if there is one
+ AddKey();
return;
+ }
cec_keypress transmitKey(key);
+ cec_user_control_code comboKey(m_configuration.clientVersion >= CEC_CLIENT_VERSION_2_0_5 ?
+ m_configuration.comboKey : CEC_USER_CONTROL_CODE_STOP);
{
CLockObject lock(m_mutex);
- if (m_iCurrentButton == COMBO_KEY && key.duration == 0)
+ if (m_iCurrentButton == comboKey && key.duration == 0)
{
// stop + ok -> exit
if (key.keycode == CEC_USER_CONTROL_CODE_SELECT)
AddKey(true);
}
- if (key.duration == 0)
+ if (m_iCurrentButton == key.keycode)
+ {
+ m_buttontime = GetTimeMs();
+ }
+ else
{
- m_iCurrentButton = transmitKey.keycode;
- m_buttontime = m_iCurrentButton == CEC_USER_CONTROL_CODE_UNKNOWN || key.duration > 0 ? 0 : GetTimeMs();
+ AddKey();
+ if (key.duration == 0)
+ {
+ m_iCurrentButton = transmitKey.keycode;
+ m_buttontime = m_iCurrentButton == CEC_USER_CONTROL_CODE_UNKNOWN || key.duration > 0 ? 0 : GetTimeMs();
+ }
}
}
- if (key.keycode != COMBO_KEY || key.duration > 0)
+ if (key.keycode != comboKey || key.duration > 0)
{
LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x)", ToString(transmitKey.keycode), transmitKey.keycode);
CallbackAddKey(transmitKey);
{
CLockObject lock(m_mutex);
uint64_t iNow = GetTimeMs();
+ cec_user_control_code comboKey(m_configuration.clientVersion >= CEC_CLIENT_VERSION_2_0_5 ?
+ m_configuration.comboKey : CEC_USER_CONTROL_CODE_STOP);
+ uint32_t iTimeoutMs(m_configuration.clientVersion >= CEC_CLIENT_VERSION_2_0_5 ?
+ m_configuration.iComboKeyTimeoutMs : CEC_DEFAULT_COMBO_TIMEOUT_MS);
if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
- ((m_iCurrentButton == COMBO_KEY && iNow - m_buttontime > COMBO_TIMEOUT_MS) ||
- (m_iCurrentButton != COMBO_KEY && iNow - m_buttontime > CEC_BUTTON_TIMEOUT)))
+ ((m_iCurrentButton == comboKey && iNow - m_buttontime > iTimeoutMs) ||
+ (m_iCurrentButton != comboKey && iNow - m_buttontime > CEC_BUTTON_TIMEOUT)))
{
key.duration = (unsigned int) (iNow - m_buttontime);
key.keycode = m_iCurrentButton;
virtual uint8_t SendVolumeUp(bool bSendRelease = true);
virtual uint8_t SendVolumeDown(bool bSendRelease = true);
virtual uint8_t SendMuteAudio(void);
+ virtual uint8_t AudioToggleMute(void);
+ virtual uint8_t AudioMute(void);
+ virtual uint8_t AudioUnmute(void);
+ virtual uint8_t AudioStatus(void);
virtual bool SendKeypress(const cec_logical_address iDestination, const cec_user_control_code key, bool bWait = true);
virtual bool SendKeyRelease(const cec_logical_address iDestination, bool bWait = true);
virtual cec_osd_name GetDeviceOSDName(const cec_logical_address iAddress);
GetTV()->MarkHandlerReady();
}
+ // report our OSD name to the TV, since some TVs don't request it
+ client->GetPrimaryDevice()->TransmitOSDName(CECDEVICE_TV, false);
+
// request the power status of the TV
tv->RequestPowerStatus(sourceAddress, true);
return "2.0.3";
case CEC_CLIENT_VERSION_2_0_4:
return "2.0.4";
+ case CEC_CLIENT_VERSION_2_0_5:
+ return "2.0.5";
default:
return "Unknown";
}
return "2.0.3";
case CEC_SERVER_VERSION_2_0_4:
return "2.0.4";
+ case CEC_SERVER_VERSION_2_0_5:
+ return "2.0.5";
default:
return "Unknown";
}
uint8_t CLibCEC::MuteAudio(bool UNUSED(bSendRelease) /* = true */)
{
+ AddLog(CEC_LOG_WARNING, "deprecated function called: %s", __FUNCTION__);
return m_client ? m_client->SendMuteAudio() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
}
{
return m_cec && m_cec->IsRunning() ? m_cec->GetAdapterProductId() : 0;
}
+
+uint8_t CLibCEC::AudioToggleMute(void)
+{
+ return m_client ? m_client->AudioToggleMute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t CLibCEC::AudioMute(void)
+{
+ return m_client ? m_client->AudioMute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t CLibCEC::AudioUnmute(void)
+{
+ return m_client ? m_client->AudioUnmute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t CLibCEC::AudioStatus(void)
+{
+ return m_client ? m_client->AudioStatus() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
uint16_t GetAdapterVendorId(void) const;
uint16_t GetAdapterProductId(void) const;
+ uint8_t AudioToggleMute(void);
+ uint8_t AudioMute(void);
+ uint8_t AudioUnmute(void);
+ uint8_t AudioStatus(void);
+
CCECProcessor * m_cec;
protected:
return cec_parser ? cec_parser->GetAdapterProductId() : 0;
}
+uint8_t cec_audio_toggle_mute(void)
+{
+ return cec_parser ? cec_parser->AudioToggleMute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t cec_audio_mute(void)
+{
+ return cec_parser ? cec_parser->AudioMute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t cec_audio_unmute(void)
+{
+ return cec_parser ? cec_parser->AudioUnmute() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
+uint8_t cec_audio_status(void)
+{
+ return cec_parser ? cec_parser->AudioStatus() : (uint8_t)CEC_AUDIO_VOLUME_STATUS_UNKNOWN;
+}
+
//@}
return thisMsgCode == msgResponse;
if (!m_message->IsTranmission())
- {
- m_queue->m_com->m_callback->GetLib()->AddLog(CEC_LOG_WARNING, "FIXME! not a transmission: %s", msg.ToString().c_str());
return false;
- }
return ((msgCode == MSGCODE_COMMAND_ACCEPTED || msgCode == MSGCODE_COMMAND_REJECTED) &&
(msgResponse == MSGCODE_TRANSMIT_ACK_POLARITY || msgResponse == MSGCODE_TRANSMIT || msgResponse == MSGCODE_TRANSMIT_EOM)) ||
CCECAudioSystem::CCECAudioSystem(CCECProcessor *processor, cec_logical_address address, uint16_t iPhysicalAddress /* = CEC_INVALID_PHYSICAL_ADDRESS */) :
CCECBusDevice(processor, address, iPhysicalAddress),
m_systemAudioStatus(CEC_SYSTEM_AUDIO_STATUS_ON),
- m_audioStatus(CEC_AUDIO_MUTE_STATUS_MASK)
+ m_audioStatus(CEC_AUDIO_VOLUME_STATUS_UNKNOWN)
{
m_type = CEC_DEVICE_TYPE_AUDIO_SYSTEM;
}
TransmitKeypress(source, CEC_USER_CONTROL_CODE_MUTE);
TransmitKeyRelease(source);
+ return GetAudioStatus(source, true);
+}
+
+bool CCECAudioSystem::RequestAudioStatus(const cec_logical_address initiator, bool bWaitForResponse /* = true */)
+{
+ bool bReturn(false);
+
+ if (!IsHandledByLibCEC() &&
+ !IsUnsupportedFeature(CEC_OPCODE_GIVE_AUDIO_STATUS))
+ {
+ MarkBusy();
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "<< requesting audio status of '%s' (%X)", GetLogicalAddressName(), m_iLogicalAddress);
+ bReturn = m_handler->TransmitRequestAudioStatus(initiator, m_iLogicalAddress, bWaitForResponse);
+ MarkReady();
+ }
+ return bReturn;
+}
+
+uint8_t CCECAudioSystem::GetAudioStatus(const cec_logical_address initiator, bool bUpdate /* = false */)
+{
+ bool bIsPresent(GetStatus() == CEC_DEVICE_STATUS_PRESENT);
+ bool bRequestUpdate(false);
+ {
+ CLockObject lock(m_mutex);
+ bRequestUpdate = bIsPresent &&
+ (bUpdate || m_audioStatus == CEC_AUDIO_VOLUME_STATUS_UNKNOWN);
+ }
+
+ if (bRequestUpdate)
+ {
+ CheckVendorIdRequested(initiator);
+ RequestAudioStatus(initiator);
+ }
+
CLockObject lock(m_mutex);
return m_audioStatus;
}
uint8_t VolumeUp(const cec_logical_address source, bool bSendRelease = true);
uint8_t VolumeDown(const cec_logical_address source, bool bSendRelease = true);
uint8_t MuteAudio(const cec_logical_address source);
+ uint8_t GetAudioStatus(const cec_logical_address initiator, bool bUpdate = false);
bool TransmitActiveSource(void) { return false; }
protected:
+ bool RequestAudioStatus(const cec_logical_address initiator, bool bWaitForResponse = true);
+
cec_system_audio_status m_systemAudioStatus;
uint8_t m_audioStatus;
};
opcode == CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP ||
opcode == CEC_OPCODE_ABORT ||
opcode == CEC_OPCODE_FEATURE_ABORT ||
- opcode == CEC_OPCODE_NONE)
+ opcode == CEC_OPCODE_NONE ||
+ opcode == CEC_OPCODE_USER_CONTROL_PRESSED ||
+ opcode == CEC_OPCODE_USER_CONTROL_RELEASE)
return;
{
CCECBusDevice* newRoute = m_processor->GetDeviceByPhysicalAddress(iRoute, true);
if (newRoute && newRoute->IsHandledByLibCEC())
- {
newRoute->ActivateSource();
- return;
- }
-
- CECDEVICEVEC devices;
- m_processor->GetDevices()->GetChildrenOf(devices, this);
-
- for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++)
- {
- if ((*it)->GetCurrentPhysicalAddress() == iRoute && (*it)->IsHandledByLibCEC())
- (*it)->ActivateSource();
- else if (!CCECTypeUtils::PhysicalAddressIsIncluded(iRoute, (*it)->GetCurrentPhysicalAddress()))
- (*it)->MarkAsInactiveSource();
- }
}
void CCECBusDevice::SetStreamPath(uint16_t iNewAddress, uint16_t iOldAddress /* = CEC_INVALID_PHYSICAL_ADDRESS */)
CCECBusDevice *device = GetDeviceByPhysicalAddress(iStreamAddress);
if (device)
{
- if (device->IsHandledByLibCEC())
+ if (device->IsHandledByLibCEC() && !device->IsActiveSource())
device->ActivateSource();
else
device->MarkAsActiveSource();
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;
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))
+ uint8_t iTries(0), iMaxTries(m_iTransmitRetries + 1);
+ while (!bReturn && ++iTries <= iMaxTries)
{
if ((bReturn = m_processor->Transmit(command, bIsReply)) == true)
{
virtual bool TransmitRequestCecVersion(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
virtual bool TransmitRequestMenuLanguage(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
virtual bool TransmitRequestOSDName(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
+ virtual bool TransmitRequestAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
virtual bool TransmitRequestPhysicalAddress(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
virtual bool TransmitRequestPowerStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);
virtual bool TransmitRequestVendorId(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true);