typedef int (CEC_CDECL* CBCecConfigurationChangedType)(void *param, const libcec_configuration &);
typedef int (CEC_CDECL* CBCecAlertType)(void *param, const libcec_alert, const libcec_parameter &);
typedef int (CEC_CDECL* CBCecMenuStateChangedType)(void *param, const cec_menu_state);
+typedef void (CEC_CDECL* CBCecSourceActivatedType)(void *param, const cec_logical_address, const uint8_t);
typedef struct ICECCallbacks
{
*/
CBCecMenuStateChangedType CBCecMenuStateChanged;
+ /*!
+ * @brief Called when a source that's handled by this client is activated.
+ * @param logicalAddress The address that was just activated.
+ * @param bActivated 1 when activated, 0 when deactivated.
+ */
+ CBCecSourceActivatedType CBCecSourceActivated;
+
#ifdef __cplusplus
ICECCallbacks(void) { Clear(); }
~ICECCallbacks(void) { Clear(); };
CBCecConfigurationChanged = NULL;
CBCecAlert = NULL;
CBCecMenuStateChanged = NULL;
+ CBCecSourceActivated = NULL;
}
#endif
} ICECCallbacks;
typedef int (__stdcall *CONFIGCB) (const CEC::libcec_configuration &config);
typedef int (__stdcall *ALERTCB) (const CEC::libcec_alert, const CEC::libcec_parameter &data);
typedef int (__stdcall *MENUCB) (const CEC::cec_menu_state newVal);
+ typedef void (__stdcall *ACTICB) (const CEC::cec_logical_address logicalAddress, const uint8_t bActivated);
static LOGCB g_logCB;
static KEYCB g_keyCB;
static CONFIGCB g_configCB;
static ALERTCB g_alertCB;
static MENUCB g_menuCB;
+ static ACTICB g_sourceActivatedCB;
static CEC::ICECCallbacks g_cecCallbacks;
int CecLogMessageCB(void *cbParam, const CEC::cec_log_message &message)
return 0;
}
+ void CecSourceActivatedCB(void *cbParam, const CEC::cec_logical_address logicalAddress, const uint8_t bActivated)
+ {
+ if (g_sourceActivatedCB)
+ g_sourceActivatedCB(logicalAddress, bActivated);
+ }
+
#pragma managed
// delegates for the unmanaged callback methods
public delegate int CecLogMessageManagedDelegate(const CEC::cec_log_message &);
public delegate int CecConfigManagedDelegate(const CEC::libcec_configuration &);
public delegate int CecAlertManagedDelegate(const CEC::libcec_alert, const CEC::libcec_parameter &);
public delegate int CecMenuManagedDelegate(const CEC::cec_menu_state newVal);
+ public delegate void CecSourceActivatedManagedDelegate(const CEC::cec_logical_address logicalAddress, const uint8_t bActivated);
// callback method interface
public ref class CecCallbackMethods
return 0;
}
+ virtual void SourceActivated(CecLogicalAddress logicalAddress, bool bActivated)
+ {
+ }
+
protected:
// managed callback methods
int CecLogMessageManaged(const CEC::cec_log_message &message)
return iReturn;
}
+ void CecSourceActivatedManaged(const CEC::cec_logical_address logicalAddress, const uint8_t bActivated)
+ {
+ if (m_bHasCallbacks)
+ m_callbacks->SourceActivated((CecLogicalAddress)logicalAddress, bActivated == 1);
+ }
+
void DestroyDelegates()
{
m_bHasCallbacks = false;
m_commandGCHandle.Free();
m_alertGCHandle.Free();
m_menuGCHandle.Free();
+ m_sourceActivatedGCHandle.Free();
}
}
g_menuCB = static_cast<MENUCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_menuDelegate).ToPointer());
g_cecCallbacks.CBCecMenuStateChanged = CecMenuCB;
+ // create the delegate method for the source activated callback
+ m_sourceActivatedDelegate = gcnew CecSourceActivatedManagedDelegate(this, &CecCallbackMethods::CecSourceActivatedManaged);
+ m_sourceActivatedGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_sourceActivatedDelegate);
+ g_sourceActivatedCB = static_cast<ACTICB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_sourceActivatedDelegate).ToPointer());
+ g_cecCallbacks.CBCecSourceActivated = CecSourceActivatedCB;
+
delete context;
m_bDelegatesCreated = true;
}
static System::Runtime::InteropServices::GCHandle m_menuGCHandle;
MENUCB m_menuCallback;
+ CecSourceActivatedManagedDelegate ^ m_sourceActivatedDelegate;
+ static System::Runtime::InteropServices::GCHandle m_sourceActivatedGCHandle;
+ ACTICB m_sourceActivatedCallback;
+
CecCallbackMethods ^ m_callbacks;
bool m_bHasCallbacks;
bool m_bDelegatesCreated;
return 0;
}
+void CCECClient::SourceActivated(const cec_logical_address logicalAddress)
+{
+ CLockObject lock(m_mutex);
+
+ LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> source activated: %s (%x)", ToString(logicalAddress), logicalAddress);
+
+ if (m_configuration.callbacks &&
+ m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_7_1 &&
+ m_configuration.callbacks->CBCecSourceActivated)
+ m_configuration.callbacks->CBCecSourceActivated(m_configuration.callbackParam, logicalAddress, 1);
+}
+
+void CCECClient::SourceDeactivated(const cec_logical_address logicalAddress)
+{
+ CLockObject lock(m_mutex);
+
+ LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> source deactivated: %s (%x)", ToString(logicalAddress), logicalAddress);
+
+ if (m_configuration.callbacks &&
+ m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_7_1 &&
+ m_configuration.callbacks->CBCecSourceActivated)
+ m_configuration.callbacks->CBCecSourceActivated(m_configuration.callbackParam, logicalAddress, 0);
+}
+
void CCECClient::Alert(const libcec_alert type, const libcec_parameter ¶m)
{
CLockObject lock(m_mutex);
virtual void AddKey(const cec_keypress &key);
virtual void SetCurrentButton(const cec_user_control_code iButtonCode);
virtual void CheckKeypressTimeout(void);
+ virtual void SourceActivated(const cec_logical_address logicalAddress);
+ virtual void SourceDeactivated(const cec_logical_address logicalAddress);
protected:
/*!
#include "CECBusDevice.h"
#include "../CECProcessor.h"
+#include "../CECClient.h"
#include "../implementations/ANCommandHandler.h"
#include "../implementations/CECCommandHandler.h"
#include "../implementations/SLCommandHandler.h"
void CCECBusDevice::MarkAsActiveSource(void)
{
- CLockObject lock(m_mutex);
- if (!m_bActiveSource)
- LIB_CEC->AddLog(CEC_LOG_DEBUG, "making %s (%x) the active source", GetLogicalAddressName(), m_iLogicalAddress);
- else
- LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%x) was already marked as active source", GetLogicalAddressName(), m_iLogicalAddress);
+ bool bWasActivated(false);
+
+ // set the power status to powered on
+ SetPowerStatus(CEC_POWER_STATUS_ON);
+
+ // mark this device as active source
+ {
+ CLockObject lock(m_mutex);
+ if (!m_bActiveSource)
+ {
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "making %s (%x) the active source", GetLogicalAddressName(), m_iLogicalAddress);
+ bWasActivated = true;
+ }
+ else
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%x) was already marked as active source", GetLogicalAddressName(), m_iLogicalAddress);
+ m_bActiveSource = true;
+ }
+
+ // mark other devices as inactive sources
CECDEVICEVEC devices;
m_processor->GetDevices()->Get(devices);
for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++)
if ((*it)->GetLogicalAddress() != m_iLogicalAddress)
(*it)->MarkAsInactiveSource();
- m_bActiveSource = true;
- SetPowerStatus(CEC_POWER_STATUS_ON);
+ if (bWasActivated)
+ {
+ CCECClient *client = GetClient();
+ if (client)
+ client->SourceActivated(m_iLogicalAddress);
+ }
}
void CCECBusDevice::MarkAsInactiveSource(void)
{
+ bool bWasDeactivated(false);
{
CLockObject lock(m_mutex);
if (m_bActiveSource)
+ {
LIB_CEC->AddLog(CEC_LOG_DEBUG, "marking %s (%X) as inactive source", GetLogicalAddressName(), m_iLogicalAddress);
+ bWasDeactivated = true;
+ }
m_bActiveSource = false;
}
+
+ if (bWasDeactivated)
+ {
+ CCECClient *client = GetClient();
+ if (client)
+ client->SourceDeactivated(m_iLogicalAddress);
+ }
}
bool CCECBusDevice::TransmitActiveSource(void)