X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2FLibCecSharp%2FCecSharpTypes.h;h=52c0b2020797bfd702ddbc4aa293395f49947f27;hb=e3aabeacf9e2c2a7aab608ed173a7070af266e2b;hp=39ef0cb28db367bb2b50f9596130b02b8ddfa7e3;hpb=de90f347e13651ab1463bb2df4b19ff5ae46e3b0;p=deb_libcec.git diff --git a/src/LibCecSharp/CecSharpTypes.h b/src/LibCecSharp/CecSharpTypes.h index 39ef0cb..52c0b20 100644 --- a/src/LibCecSharp/CecSharpTypes.h +++ b/src/LibCecSharp/CecSharpTypes.h @@ -31,10 +31,11 @@ * http://www.pulse-eight.net/ */ -#include +#include "../lib/platform/threads/mutex.h" #include #include #include "../../include/cec.h" +#include #using @@ -83,6 +84,29 @@ namespace CecSharp Broadcast = 15 }; + public enum class CecAlert + { + ServiceDevice = 1 + }; + + public enum class CecParameterType + { + ParameterTypeString = 1 + }; + + public ref class CecParameter + { + public: + CecParameter(CecParameterType type, System::String ^ strData) + { + Type = type; + Data = strData; + } + + property CecParameterType Type; + property System::String ^ Data; + }; + public enum class CecPowerStatus { On = 0x00, @@ -224,19 +248,28 @@ namespace CecSharp F5 = 0x75, Data = 0x76, Max = 0x76, + SamsungReturn = 0x91, Unknown }; public enum class CecVendorId { - Samsung = 0x00F0, - LG = 0xE091, - Panasonic = 0x8045, - Pioneer = 0xE036, - Onkyo = 0x09B0, - Yamaha = 0xA0DE, - Philips = 0x903E, + Samsung = 0x0000F0, + LG = 0x00E091, + Panasonic = 0x008045, + Pioneer = 0x00E036, + Onkyo = 0x0009B0, + Yamaha = 0x00A0DE, + Philips = 0x00903E, Sony = 0x080046, + Toshiba = 0x000039, + Akai = 0x0020C7, + Benq = 0x8065E9, + Daewoo = 0x009053, + Grundig = 0x00D0D5, + Medion = 0x000CB8, + Sharp = 0x08001F, + Vizio = 0x6B746D, Unknown = 0 }; @@ -326,7 +359,41 @@ namespace CecSharp public enum class CecClientVersion { VersionPre1_5 = 0, - Version1_5_0 = 0x1500 + Version1_5_0 = 0x1500, + Version1_5_1 = 0x1501, + Version1_5_2 = 0x1502, + Version1_5_3 = 0x1503, + Version1_6_0 = 0x1600, + Version1_6_1 = 0x1601, + Version1_6_2 = 0x1602, + Version1_6_3 = 0x1603, + Version1_7_0 = 0x1700, + Version1_7_1 = 0x1701, + Version1_7_2 = 0x1702, + Version1_8_0 = 0x1800, + Version1_8_1 = 0x1801, + Version1_8_2 = 0x1802, + Version1_9_0 = 0x1900 + }; + + public enum class CecServerVersion + { + VersionPre1_5 = 0, + Version1_5_0 = 0x1500, + Version1_5_1 = 0x1501, + Version1_5_2 = 0x1502, + Version1_5_3 = 0x1503, + Version1_6_0 = 0x1600, + Version1_6_1 = 0x1601, + Version1_6_2 = 0x1602, + Version1_6_3 = 0x1603, + Version1_7_0 = 0x1700, + Version1_7_1 = 0x1701, + Version1_7_2 = 0x1702, + Version1_8_0 = 0x1800, + Version1_8_1 = 0x1801, + Version1_8_2 = 0x1802, + Version1_9_0 = 0x1900 }; public ref class CecAdapter @@ -366,18 +433,21 @@ namespace CecSharp void Clear(void) { + Primary = CecLogicalAddress::Unknown; for (unsigned int iPtr = 0; iPtr < 16; iPtr++) - Addresses[iPtr] = CecLogicalAddress::Unregistered; + Addresses[iPtr] = CecLogicalAddress::Unknown; } bool IsSet(CecLogicalAddress iAddress) { - return Addresses[(unsigned int)iAddress] != CecLogicalAddress::Unregistered; + return Addresses[(unsigned int)iAddress] != CecLogicalAddress::Unknown; } void Set(CecLogicalAddress iAddress) { Addresses[(unsigned int)iAddress] = iAddress; + if (Primary == CecLogicalAddress::Unknown) + Primary = iAddress; } property CecLogicalAddress Primary; @@ -467,7 +537,7 @@ namespace CecSharp public ref class CecKeypress { public: - CecKeypress(int iKeycode, unsigned int iDuration) + CecKeypress(CecUserControlCode iKeycode, unsigned int iDuration) { Keycode = iKeycode; Duration = iDuration; @@ -476,14 +546,14 @@ namespace CecSharp CecKeypress(void) { - Keycode = 0; + Keycode = CecUserControlCode::Unknown; Duration = 0; Empty = true; } - property bool Empty; - property int Keycode; - property unsigned int Duration; + property bool Empty; + property CecUserControlCode Keycode; + property unsigned int Duration; }; public ref class CecLogMessage @@ -519,10 +589,12 @@ namespace CecSharp { DeviceName = ""; DeviceTypes = gcnew CecDeviceTypeList(); + AutodetectAddress = true; PhysicalAddress = CEC_DEFAULT_PHYSICAL_ADDRESS; BaseDevice = (CecLogicalAddress)CEC_DEFAULT_BASE_DEVICE; HDMIPort = CEC_DEFAULT_HDMI_PORT; ClientVersion = CecClientVersion::VersionPre1_5; + ServerVersion = CecServerVersion::VersionPre1_5; TvVendor = CecVendorId::Unknown; GetSettingsFromROM = false; @@ -539,6 +611,13 @@ namespace CecSharp PowerOffScreensaver = CEC_DEFAULT_SETTING_POWER_OFF_SCREENSAVER == 1; PowerOffOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_ON_STANDBY == 1; + + SendInactiveSource = CEC_DEFAULT_SETTING_SEND_INACTIVE_SOURCE == 1; + LogicalAddresses = gcnew CecLogicalAddresses(); + FirmwareVersion = 1; + PowerOffDevicesOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_DEVICES_STANDBY == 1; + ShutdownOnStandby = CEC_DEFAULT_SETTING_SHUTDOWN_ON_STANDBY == 1; + DeviceLanguage = ""; } void SetCallbacks(CecCallbackMethods ^callbacks) @@ -546,12 +625,72 @@ namespace CecSharp Callbacks = callbacks; } + void Update(const CEC::libcec_configuration &config) + { + DeviceName = gcnew System::String(config.strDeviceName); + + for (unsigned int iPtr = 0; iPtr < 5; iPtr++) + DeviceTypes->Types[iPtr] = (CecDeviceType)config.deviceTypes.types[iPtr]; + + AutodetectAddress = config.bAutodetectAddress == 1; + PhysicalAddress = config.iPhysicalAddress; + BaseDevice = (CecLogicalAddress)config.baseDevice; + HDMIPort = config.iHDMIPort; + ClientVersion = (CecClientVersion)config.clientVersion; + ServerVersion = (CecServerVersion)config.serverVersion; + TvVendor = (CecVendorId)config.tvVendor; + + // player specific settings + GetSettingsFromROM = config.bGetSettingsFromROM == 1; + UseTVMenuLanguage = config.bUseTVMenuLanguage == 1; + ActivateSource = config.bActivateSource == 1; + + WakeDevices->Clear(); + for (uint8_t iPtr = 0; iPtr <= 16; iPtr++) + if (config.wakeDevices[iPtr]) + WakeDevices->Set((CecLogicalAddress)iPtr); + + PowerOffDevices->Clear(); + for (uint8_t iPtr = 0; iPtr <= 16; iPtr++) + if (config.powerOffDevices[iPtr]) + PowerOffDevices->Set((CecLogicalAddress)iPtr); + + PowerOffScreensaver = config.bPowerOffScreensaver == 1; + PowerOffOnStandby = config.bPowerOffOnStandby == 1; + + if (ServerVersion >= CecServerVersion::Version1_5_1) + SendInactiveSource = config.bSendInactiveSource == 1; + + if (ServerVersion >= CecServerVersion::Version1_5_3) + { + LogicalAddresses->Clear(); + for (uint8_t iPtr = 0; iPtr <= 16; iPtr++) + if (config.logicalAddresses[iPtr]) + LogicalAddresses->Set((CecLogicalAddress)iPtr); + } + + if (ServerVersion >= CecServerVersion::Version1_6_0) + { + FirmwareVersion = config.iFirmwareVersion; + PowerOffDevicesOnStandby = config.bPowerOffDevicesOnStandby == 1; + ShutdownOnStandby = config.bShutdownOnStandby == 1; + } + + if (ServerVersion >= CecServerVersion::Version1_6_2) + DeviceLanguage = gcnew System::String(config.strDeviceLanguage); + + if (ServerVersion >= CecServerVersion::Version1_6_3) + MonitorOnlyClient = config.bMonitorOnly == 1; + } + property System::String ^ DeviceName; property CecDeviceTypeList ^ DeviceTypes; + property bool AutodetectAddress; property uint16_t PhysicalAddress; property CecLogicalAddress BaseDevice; property uint8_t HDMIPort; property CecClientVersion ClientVersion; + property CecServerVersion ServerVersion; property CecVendorId TvVendor; // player specific settings @@ -562,7 +701,13 @@ namespace CecSharp property CecLogicalAddresses ^PowerOffDevices; property bool PowerOffScreensaver; property bool PowerOffOnStandby; - + property bool SendInactiveSource; + property CecLogicalAddresses ^LogicalAddresses; + property uint16_t FirmwareVersion; + property bool PowerOffDevicesOnStandby; + property bool ShutdownOnStandby; + property bool MonitorOnlyClient; + property System::String ^ DeviceLanguage; property CecCallbackMethods ^ Callbacks; }; @@ -573,89 +718,152 @@ namespace CecSharp typedef int (__stdcall *KEYCB) (const CEC::cec_keypress &key); typedef int (__stdcall *COMMANDCB)(const CEC::cec_command &command); 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 COMMANDCB g_commandCB; - static CONFIGCB g_configCB; - static CEC::ICECCallbacks g_cecCallbacks; + typedef struct + { + LOGCB logCB; + KEYCB keyCB; + COMMANDCB commandCB; + CONFIGCB configCB; + ALERTCB alertCB; + MENUCB menuCB; + ACTICB sourceActivatedCB; + } UnmanagedCecCallbacks; + + static PLATFORM::CMutex g_callbackMutex; + static std::vector g_unmanagedCallbacks; + static CEC::ICECCallbacks g_cecCallbacks; int CecLogMessageCB(void *cbParam, const CEC::cec_log_message &message) { - if (g_logCB) - return g_logCB(message); + if (cbParam) + { + size_t iPtr = (size_t)cbParam; + PLATFORM::CLockObject lock(g_callbackMutex); + if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size()) + return g_unmanagedCallbacks[iPtr].logCB(message); + } return 0; } int CecKeyPressCB(void *cbParam, const CEC::cec_keypress &key) { - if (g_keyCB) - return g_keyCB(key); + if (cbParam) + { + size_t iPtr = (size_t)cbParam; + PLATFORM::CLockObject lock(g_callbackMutex); + if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size()) + return g_unmanagedCallbacks[iPtr].keyCB(key); + } return 0; } int CecCommandCB(void *cbParam, const CEC::cec_command &command) { - if (g_commandCB) - return g_commandCB(command); + if (cbParam) + { + size_t iPtr = (size_t)cbParam; + PLATFORM::CLockObject lock(g_callbackMutex); + if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size()) + return g_unmanagedCallbacks[iPtr].commandCB(command); + } return 0; } int CecConfigCB(void *cbParam, const CEC::libcec_configuration &config) { - if (g_configCB) - return g_configCB(config); + if (cbParam) + { + size_t iPtr = (size_t)cbParam; + PLATFORM::CLockObject lock(g_callbackMutex); + if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size()) + return g_unmanagedCallbacks[iPtr].configCB(config); + } + return 0; + } + + int CecAlertCB(void *cbParam, const CEC::libcec_alert alert, const CEC::libcec_parameter &data) + { + if (cbParam) + { + size_t iPtr = (size_t)cbParam; + PLATFORM::CLockObject lock(g_callbackMutex); + if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size()) + return g_unmanagedCallbacks[iPtr].alertCB(alert, data); + } + return 0; + } + + int CecMenuCB(void *cbParam, const CEC::cec_menu_state newVal) + { + if (cbParam) + { + size_t iPtr = (size_t)cbParam; + PLATFORM::CLockObject lock(g_callbackMutex); + if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size()) + return g_unmanagedCallbacks[iPtr].menuCB(newVal); + } return 0; } + void CecSourceActivatedCB(void *cbParam, const CEC::cec_logical_address logicalAddress, const uint8_t bActivated) + { + if (cbParam) + { + size_t iPtr = (size_t)cbParam; + PLATFORM::CLockObject lock(g_callbackMutex); + if (iPtr >= 0 && iPtr < g_unmanagedCallbacks.size()) + g_unmanagedCallbacks[iPtr].sourceActivatedCB(logicalAddress, bActivated); + } + } + #pragma managed // delegates for the unmanaged callback methods - public delegate int CecLogMessageManagedDelegate(const CEC::cec_log_message &); - public delegate int CecKeyPressManagedDelegate(const CEC::cec_keypress &); - public delegate int CecCommandManagedDelegate(const CEC::cec_command &); - public delegate int CecConfigManagedDelegate(const CEC::libcec_configuration &); + public delegate int CecLogMessageManagedDelegate(const CEC::cec_log_message &); + public delegate int CecKeyPressManagedDelegate(const CEC::cec_keypress &); + public delegate int CecCommandManagedDelegate(const CEC::cec_command &); + 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); + + void AssignCallbacks() + { + g_cecCallbacks.CBCecLogMessage = CecLogMessageCB; + g_cecCallbacks.CBCecKeyPress = CecKeyPressCB; + g_cecCallbacks.CBCecCommand = CecCommandCB; + g_cecCallbacks.CBCecConfigurationChanged = CecConfigCB; + g_cecCallbacks.CBCecAlert = CecAlertCB; + g_cecCallbacks.CBCecMenuStateChanged = CecMenuCB; + g_cecCallbacks.CBCecSourceActivated = CecSourceActivatedCB; + } // callback method interface public ref class CecCallbackMethods { public: - CecCallbackMethods(void) + CecCallbackMethods(void) + { + m_iCallbackPtr = -1; + AssignCallbacks(); + m_bHasCallbacks = false; + m_bDelegatesCreated = false; + } + + ~CecCallbackMethods(void) + { + DestroyDelegates(); + } + + size_t GetCallbackPtr(void) { - m_bHasCallbacks = false; - msclr::interop::marshal_context ^ context = gcnew msclr::interop::marshal_context(); - - // create the delegate method for the log message callback - m_logMessageDelegate = gcnew CecLogMessageManagedDelegate(this, &CecCallbackMethods::CecLogMessageManaged); - m_logMessageGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_logMessageDelegate); - g_logCB = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_logMessageDelegate).ToPointer()); - g_cecCallbacks.CBCecLogMessage = CecLogMessageCB; - - // create the delegate method for the keypress callback - m_keypressDelegate = gcnew CecKeyPressManagedDelegate(this, &CecCallbackMethods::CecKeyPressManaged); - m_keypressGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_keypressDelegate); - g_keyCB = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_keypressDelegate).ToPointer()); - g_cecCallbacks.CBCecKeyPress = CecKeyPressCB; - - // create the delegate method for the command callback - m_commandDelegate = gcnew CecCommandManagedDelegate(this, &CecCallbackMethods::CecCommandManaged); - m_commandGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_commandDelegate); - g_commandCB = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_commandDelegate).ToPointer()); - g_cecCallbacks.CBCecCommand = CecCommandCB; - - // create the delegate method for the configuration change callback - m_configDelegate = gcnew CecConfigManagedDelegate(this, &CecCallbackMethods::CecConfigManaged); - m_configGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_configDelegate); - g_configCB = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_configDelegate).ToPointer()); - g_cecCallbacks.CBCecConfigurationChanged = CecConfigCB; - - delete context; + PLATFORM::CLockObject lock(g_callbackMutex); + return m_iCallbackPtr; } - ~CecCallbackMethods(void) - { - DestroyDelegates(); - } - protected: !CecCallbackMethods(void) { @@ -663,8 +871,14 @@ namespace CecSharp } public: + virtual void DisableCallbacks(void) + { + DestroyDelegates(); + } + virtual bool EnableCallbacks(CecCallbackMethods ^ callbacks) { + CreateDelegates(); if (!m_bHasCallbacks) { m_bHasCallbacks = true; @@ -694,6 +908,21 @@ namespace CecSharp { return 0; } + + virtual int ReceiveAlert(CecAlert alert, CecParameter ^ data) + { + return 0; + } + + virtual int ReceiveMenuStateChange(CecMenuState newVal) + { + return 0; + } + + virtual void SourceActivated(CecLogicalAddress logicalAddress, bool bActivated) + { + } + protected: // managed callback methods int CecLogMessageManaged(const CEC::cec_log_message &message) @@ -708,7 +937,7 @@ namespace CecSharp { int iReturn(0); if (m_bHasCallbacks) - iReturn = m_callbacks->ReceiveKeypress(gcnew CecKeypress(key.keycode, key.duration)); + iReturn = m_callbacks->ReceiveKeypress(gcnew CecKeypress((CecUserControlCode)key.keycode, key.duration)); return iReturn; } @@ -731,49 +960,120 @@ namespace CecSharp if (m_bHasCallbacks) { LibCECConfiguration ^netConfig = gcnew LibCECConfiguration(); - netConfig->DeviceName = gcnew System::String(config.strDeviceName); - for (unsigned int iPtr = 0; iPtr < 5; iPtr++) - netConfig->DeviceTypes->Types[iPtr] = (CecDeviceType)config.deviceTypes.types[iPtr]; - - netConfig->PhysicalAddress = config.iPhysicalAddress; - netConfig->BaseDevice = (CecLogicalAddress)config.baseDevice; - netConfig->HDMIPort = config.iHDMIPort; - netConfig->ClientVersion = (CecClientVersion)config.clientVersion; - netConfig->GetSettingsFromROM = config.bGetSettingsFromROM == 1; - netConfig->ActivateSource = config.bActivateSource == 1; - - netConfig->WakeDevices->Clear(); - int iDevices(0); - for (uint8_t iPtr = 0; iPtr <= 16; iPtr++) - if (config.wakeDevices[iPtr]) - netConfig->WakeDevices->Addresses[iDevices++] = (CecLogicalAddress)iPtr; - - netConfig->PowerOffDevices->Clear(); - iDevices = 0; - for (uint8_t iPtr = 0; iPtr <= 16; iPtr++) - if (config.powerOffDevices[iPtr]) - netConfig->PowerOffDevices->Addresses[iDevices++] = (CecLogicalAddress)iPtr; + netConfig->Update(config); + iReturn = m_callbacks->ConfigurationChanged(netConfig); + } + return iReturn; + } - netConfig->PowerOffScreensaver = config.bPowerOffScreensaver == 1; - netConfig->PowerOffOnStandby = config.bPowerOffOnStandby == 1; + int CecAlertManaged(const CEC::libcec_alert alert, const CEC::libcec_parameter &data) + { + int iReturn(0); + if (m_bHasCallbacks) + { + CecParameterType newType = (CecParameterType)data.paramType; + if (newType == CecParameterType::ParameterTypeString) + { + System::String ^ newData = gcnew System::String((const char *)data.paramData, 0, 128); + CecParameter ^ newParam = gcnew CecParameter(newType, newData); + iReturn = m_callbacks->ReceiveAlert((CecAlert)alert, newParam); + } + } + return iReturn; + } - iReturn = m_callbacks->ConfigurationChanged(netConfig); + int CecMenuManaged(const CEC::cec_menu_state newVal) + { + int iReturn(0); + if (m_bHasCallbacks) + { + iReturn = m_callbacks->ReceiveMenuStateChange((CecMenuState)newVal); } return iReturn; } - void DestroyDelegates() + 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; + if (m_bDelegatesCreated) { - m_bHasCallbacks = false; - delete m_callbacks; + m_bDelegatesCreated = false; m_logMessageGCHandle.Free(); m_keypressGCHandle.Free(); m_commandGCHandle.Free(); + m_alertGCHandle.Free(); + m_menuGCHandle.Free(); + m_sourceActivatedGCHandle.Free(); } } + void CreateDelegates() + { + DestroyDelegates(); + + if (!m_bDelegatesCreated) + { + msclr::interop::marshal_context ^ context = gcnew msclr::interop::marshal_context(); + + // create the delegate method for the log message callback + m_logMessageDelegate = gcnew CecLogMessageManagedDelegate(this, &CecCallbackMethods::CecLogMessageManaged); + m_logMessageGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_logMessageDelegate); + m_logMessageCallback = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_logMessageDelegate).ToPointer()); + + // create the delegate method for the keypress callback + m_keypressDelegate = gcnew CecKeyPressManagedDelegate(this, &CecCallbackMethods::CecKeyPressManaged); + m_keypressGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_keypressDelegate); + m_keypressCallback = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_keypressDelegate).ToPointer()); + + // create the delegate method for the command callback + m_commandDelegate = gcnew CecCommandManagedDelegate(this, &CecCallbackMethods::CecCommandManaged); + m_commandGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_commandDelegate); + m_commandCallback = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_commandDelegate).ToPointer()); + + // create the delegate method for the configuration change callback + m_configDelegate = gcnew CecConfigManagedDelegate(this, &CecCallbackMethods::CecConfigManaged); + m_configGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_configDelegate); + m_configCallback = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_configDelegate).ToPointer()); + + // create the delegate method for the alert callback + m_alertDelegate = gcnew CecAlertManagedDelegate(this, &CecCallbackMethods::CecAlertManaged); + m_alertGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_alertDelegate); + m_alertCallback = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_alertDelegate).ToPointer()); + + // create the delegate method for the menu callback + m_menuDelegate = gcnew CecMenuManagedDelegate(this, &CecCallbackMethods::CecMenuManaged); + m_menuGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_menuDelegate); + m_menuCallback = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_menuDelegate).ToPointer()); + + // 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); + m_sourceActivatedCallback = static_cast(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_sourceActivatedDelegate).ToPointer()); + + delete context; + + UnmanagedCecCallbacks unmanagedCallbacks; + unmanagedCallbacks.logCB = m_logMessageCallback; + unmanagedCallbacks.keyCB = m_keypressCallback; + unmanagedCallbacks.commandCB = m_commandCallback; + unmanagedCallbacks.configCB = m_configCallback; + unmanagedCallbacks.alertCB = m_alertCallback; + unmanagedCallbacks.menuCB = m_menuCallback; + unmanagedCallbacks.sourceActivatedCB = m_sourceActivatedCallback; + + PLATFORM::CLockObject lock(g_callbackMutex); + g_unmanagedCallbacks.push_back(unmanagedCallbacks); + m_iCallbackPtr = g_unmanagedCallbacks.size() - 1; + m_bDelegatesCreated = true; + } + } + CecLogMessageManagedDelegate ^ m_logMessageDelegate; static System::Runtime::InteropServices::GCHandle m_logMessageGCHandle; LOGCB m_logMessageCallback; @@ -790,7 +1090,21 @@ namespace CecSharp static System::Runtime::InteropServices::GCHandle m_configGCHandle; CONFIGCB m_configCallback; + CecAlertManagedDelegate ^ m_alertDelegate; + static System::Runtime::InteropServices::GCHandle m_alertGCHandle; + ALERTCB m_alertCallback; + + CecMenuManagedDelegate ^ m_menuDelegate; + 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; + size_t m_iCallbackPtr; }; }