added a callback for clients that is called when a source is (de)activated, so the...
authorLars Op den Kamp <lars@opdenkamp.eu>
Sat, 23 Jun 2012 08:12:38 +0000 (10:12 +0200)
committerLars Op den Kamp <lars@opdenkamp.eu>
Sat, 23 Jun 2012 09:00:16 +0000 (11:00 +0200)
include/cectypes.h
src/LibCecSharp/CecSharpTypes.h
src/lib/CECClient.cpp
src/lib/CECClient.h
src/lib/devices/CECBusDevice.cpp

index bb9dc32fa69ce62b73faaa9385901524682ecbc2..df59193f594aeb3de04777afd6705132d5e7c876 100644 (file)
@@ -1124,6 +1124,7 @@ typedef int (CEC_CDECL* CBCecCommandType)(void *param, const cec_command &);
 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
 {
@@ -1174,6 +1175,13 @@ 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(); };
@@ -1186,6 +1194,7 @@ typedef struct ICECCallbacks
     CBCecConfigurationChanged = NULL;
     CBCecAlert                = NULL;
     CBCecMenuStateChanged     = NULL;
+    CBCecSourceActivated      = NULL;
   }
 #endif
 } ICECCallbacks;
index 2eec98e5132ccf02e105df2ed76de0ad2b3feb8d..09cdae1560bc42218cf69f1e3ff3b0591db26c37 100644 (file)
@@ -698,6 +698,7 @@ namespace CecSharp
        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;
@@ -705,6 +706,7 @@ namespace CecSharp
        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)
@@ -749,6 +751,12 @@ namespace CecSharp
                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 &);
@@ -757,6 +765,7 @@ namespace CecSharp
        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
@@ -828,6 +837,10 @@ namespace CecSharp
                        return 0;
                }
 
+               virtual void SourceActivated(CecLogicalAddress logicalAddress, bool bActivated)
+               {
+               }
+
        protected:
                // managed callback methods
                int CecLogMessageManaged(const CEC::cec_log_message &message)
@@ -897,6 +910,12 @@ namespace CecSharp
                        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;
@@ -908,6 +927,7 @@ namespace CecSharp
                                m_commandGCHandle.Free();
                                m_alertGCHandle.Free();
                                m_menuGCHandle.Free();
+                               m_sourceActivatedGCHandle.Free();
                        }
                }
 
@@ -955,6 +975,12 @@ namespace CecSharp
         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;
       }
@@ -984,6 +1010,10 @@ namespace CecSharp
                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;
index d2a3dcc6a5ec7a0c4637dffe7e32da56af620c73..accd5659fe9427d1cb9612da836208dcf8fada14 100644 (file)
@@ -906,6 +906,30 @@ int CCECClient::MenuStateChanged(const cec_menu_state newState)
   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 &param)
 {
   CLockObject lock(m_mutex);
index 87a4b7fbaf071d9067ea897dc1ca8f9ac1fb7233..fccb083e4dd49a3d3b85bc2706b17c4fbb6b209e 100644 (file)
@@ -182,6 +182,8 @@ namespace CEC
     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:
     /*!
index 88d6b46c35cea9ddd00dc8e19df40faf18089acf..f01d47ce8eff19e003fe06d369f3952a441d366a 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "CECBusDevice.h"
 #include "../CECProcessor.h"
+#include "../CECClient.h"
 #include "../implementations/ANCommandHandler.h"
 #include "../implementations/CECCommandHandler.h"
 #include "../implementations/SLCommandHandler.h"
@@ -916,30 +917,59 @@ bool CCECBusDevice::RequestActiveSource(bool bWaitForResponse /* = true */)
 
 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)