From e1804a4e359f5e188a02705c85e7e666d1d1482e Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Fri, 20 Apr 2012 13:25:48 +0200 Subject: [PATCH] cec: added a callback to handle menu state changes. if the callback method returns 1, then the change is processed by the CCECBusDevice too. if 0, then the CCECBusDevice will always have menu state 'activated', so keypresses are routed. bugzid: 724 --- include/cectypes.h | 29 +++++++++++++++++++ src/cec-config/cec-config.cpp | 8 ++--- src/lib/LibCEC.cpp | 22 ++++++++++++++ src/lib/LibCEC.h | 1 + src/lib/implementations/CECCommandHandler.cpp | 17 ++++++++--- src/testclient/main.cpp | 8 ++--- 6 files changed, 71 insertions(+), 14 deletions(-) diff --git a/include/cectypes.h b/include/cectypes.h index a1bafac..296e267 100644 --- a/include/cectypes.h +++ b/include/cectypes.h @@ -1038,6 +1038,7 @@ typedef int (CEC_CDECL* CBCecKeyPressType)(void *param, const cec_keypress &); 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* CBCecMenuStatusChangedType)(void *param, const cec_menu_state newVal); typedef struct ICECCallbacks { @@ -1076,6 +1077,31 @@ typedef struct ICECCallbacks * @return 1 when ok, 0 otherwise */ CBCecAlertType CBCecAlert; + + /*! + * @brief Transfer a menu status change to the client. + * Transfer a menu status change to the client. If the command returns 1, then the change will be processed by + * the busdevice. If 0, then the state of the busdevice won't be changed, and will always be kept 'activated', + * so keypresses are always routed. + * @param newVal The new value. + * @return 1 when this change should be pr + */ + CBCecMenuStatusChangedType CBMenuStatusChanged; + +#ifdef __cplusplus + ICECCallbacks(void) { Clear(); } + ~ICECCallbacks(void) { Clear(); }; + + void Clear(void) + { + CBCecLogMessage = NULL; + CBCecKeyPress = NULL; + CBCecCommand = NULL; + CBCecConfigurationChanged = NULL; + CBCecAlert = NULL; + CBMenuStatusChanged = NULL; + } +#endif } ICECCallbacks; typedef enum cec_client_version @@ -1134,6 +1160,9 @@ typedef struct libcec_configuration char strDeviceLanguage[3]; /*!< the menu language used by the client. 3 character ISO 639-2 country code. see http://http://www.loc.gov/standards/iso639-2/ */ #ifdef __cplusplus + libcec_configuration(void) { Clear(); } + ~libcec_configuration(void) { Clear(); } + /*! * @brief Reset this configution struct to the default values. */ diff --git a/src/cec-config/cec-config.cpp b/src/cec-config/cec-config.cpp index 1e6c96f..76c9166 100644 --- a/src/cec-config/cec-config.cpp +++ b/src/cec-config/cec-config.cpp @@ -141,11 +141,9 @@ int CecCommand(void *UNUSED(cbParam), const cec_command &command) void EnableCallbacks(ICECAdapter *adapter) { - g_callbacks.CBCecLogMessage = &CecLogMessage; - g_callbacks.CBCecKeyPress = &CecKeyPress; - g_callbacks.CBCecCommand = &CecCommand; - g_callbacks.CBCecConfigurationChanged = NULL; - g_callbacks.CBCecAlert = NULL; + g_callbacks.CBCecLogMessage = &CecLogMessage; + g_callbacks.CBCecKeyPress = &CecKeyPress; + g_callbacks.CBCecCommand = &CecCommand; adapter->EnableCallbacks(NULL, &g_callbacks); } diff --git a/src/lib/LibCEC.cpp b/src/lib/LibCEC.cpp index 20c670d..9b200a6 100644 --- a/src/lib/LibCEC.cpp +++ b/src/lib/LibCEC.cpp @@ -456,6 +456,28 @@ void CLibCEC::CheckKeypressTimeout(void) } } +int CLibCEC::MenuStateChanged(const cec_menu_state newState) +{ + int iReturn(0); + + CLibCEC *instance = CLibCEC::GetInstance(); + if (!instance) + return iReturn; + CLockObject lock(instance->m_mutex); + + AddLog(CEC_LOG_NOTICE, ">> %s: %s", instance->m_cec->ToString(CEC_OPCODE_MENU_REQUEST), instance->m_cec->ToString(newState)); + + libcec_configuration config; + instance->GetCurrentConfiguration(&config); + + if (instance->m_callbacks && + config.clientVersion >= CEC_CLIENT_VERSION_1_6_2 && + instance->m_callbacks->CBMenuStatusChanged) + iReturn = instance->m_callbacks->CBMenuStatusChanged(instance->m_cbParam, newState); + + return iReturn; +} + bool CLibCEC::SetStreamPath(cec_logical_address iAddress) { uint16_t iPhysicalAddress = GetDevicePhysicalAddress(iAddress); diff --git a/src/lib/LibCEC.h b/src/lib/LibCEC.h index 4697371..834ab1d 100644 --- a/src/lib/LibCEC.h +++ b/src/lib/LibCEC.h @@ -137,6 +137,7 @@ namespace CEC static void ConfigurationChanged(const libcec_configuration &config); static void SetCurrentButton(cec_user_control_code iButtonCode); virtual void CheckKeypressTimeout(void); + static int MenuStateChanged(const cec_menu_state newState); static CLibCEC *GetInstance(void); static void SetInstance(CLibCEC *instance); diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index eed6087..7e4b547 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -379,11 +379,20 @@ bool CCECCommandHandler::HandleMenuRequest(const cec_command &command) { if (m_processor->IsRunning() && m_busDevice->MyLogicalAddressContains(command.destination)) { - if (command.parameters[0] == CEC_MENU_REQUEST_TYPE_QUERY) + CCECBusDevice *device = GetDevice(command.destination); + if (device) { - CCECBusDevice *device = GetDevice(command.destination); - if (device) - return device->TransmitMenuState(command.initiator); + if (command.parameters[0] == CEC_MENU_REQUEST_TYPE_ACTIVATE) + { + if (CLibCEC::MenuStateChanged(CEC_MENU_STATE_ACTIVATED) == 1) + device->SetMenuState(CEC_MENU_STATE_ACTIVATED); + } + else if (command.parameters[0] == CEC_MENU_REQUEST_TYPE_DEACTIVATE) + { + if (CLibCEC::MenuStateChanged(CEC_MENU_STATE_DEACTIVATED) == 1) + device->SetMenuState(CEC_MENU_STATE_DEACTIVATED); + } + return device->TransmitMenuState(command.initiator); } } diff --git a/src/testclient/main.cpp b/src/testclient/main.cpp index 0e73874..d91432e 100644 --- a/src/testclient/main.cpp +++ b/src/testclient/main.cpp @@ -177,11 +177,9 @@ int CecCommand(void *UNUSED(cbParam), const cec_command &UNUSED(command)) void EnableCallbacks(ICECAdapter *adapter) { - g_callbacks.CBCecLogMessage = &CecLogMessage; - g_callbacks.CBCecKeyPress = &CecKeyPress; - g_callbacks.CBCecCommand = &CecCommand; - g_callbacks.CBCecConfigurationChanged = NULL; - g_callbacks.CBCecAlert = NULL; + g_callbacks.CBCecLogMessage = &CecLogMessage; + g_callbacks.CBCecKeyPress = &CecKeyPress; + g_callbacks.CBCecCommand = &CecCommand; adapter->EnableCallbacks(NULL, &g_callbacks); } -- 2.34.1