cec: added a callback to handle menu state changes. if the callback method returns...
authorLars Op den Kamp <lars@opdenkamp.eu>
Fri, 20 Apr 2012 11:25:48 +0000 (13:25 +0200)
committerLars Op den Kamp <lars@opdenkamp.eu>
Fri, 20 Apr 2012 11:29:29 +0000 (13:29 +0200)
include/cectypes.h
src/cec-config/cec-config.cpp
src/lib/LibCEC.cpp
src/lib/LibCEC.h
src/lib/implementations/CECCommandHandler.cpp
src/testclient/main.cpp

index a1bafacf446db589fcd26423d999ebb024c5a253..296e267fb7a410f9c01d54febfadbc7dd455997a 100644 (file)
@@ -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.
    */
index 1e6c96fd9272e6763b7fd265294019710f433202..76c91660adb27aea935d02e12277e6a116445476 100644 (file)
@@ -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);
 }
 
index 20c670d3a6c028f020f80d055804076f8f4c1d3e..9b200a6556316a31aa803bc712dc22cacf44b90b 100644 (file)
@@ -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);
index 46973711bed2269cadba69e9c678515cfe973ea3..834ab1d6971141d72c70b8d464d7e933bbd5d3c5 100644 (file)
@@ -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);
index eed60878d8231244346e80756ef45f39081f9d5d..7e4b5478aa7123e05a5021e2713e6da23ca67be2 100644 (file)
@@ -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);
     }
   }
 
index 0e7387487564a4779cd58cd4444f39f5a0befdeb..d91432e8e55fa6833bc8b114da7d1437e965996c 100644 (file)
@@ -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);
 }