cec: added GetDeviceMenuLanguage()/cec_get_device_menu_language()
authorLars Op den Kamp <lars@opdenkamp.eu>
Sun, 30 Oct 2011 12:26:37 +0000 (13:26 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Sun, 30 Oct 2011 12:30:24 +0000 (13:30 +0100)
13 files changed:
include/cec.h
include/cecc.h
include/cectypes.h
src/lib/CECProcessor.cpp
src/lib/CECProcessor.h
src/lib/LibCEC.cpp
src/lib/LibCEC.h
src/lib/LibCECC.cpp
src/lib/devices/CECBusDevice.cpp
src/lib/devices/CECBusDevice.h
src/lib/implementations/CECCommandHandler.cpp
src/lib/implementations/CECCommandHandler.h
src/testclient/main.cpp

index 68652b16feb83c5fc17013d30546e43fb01aea88..9be8d21980e77306605abf32669a97f4bf925d82 100644 (file)
@@ -144,6 +144,11 @@ namespace CEC
      * @see cec_get_device_cec_version
      */
     virtual cec_version GetDeviceCecVersion(cec_logical_address iAddress) = 0;
+
+    /*!
+     * @see cec_get_device_menu_language
+     */
+    virtual bool GetDeviceMenuLanguage(cec_logical_address iAddress, cec_menu_language *language) = 0;
   };
 };
 
index f897e13632380e36e8931e17385a13a211f4fdae..a76ac0f05a43e16648ded6acd924313d70be1963 100644 (file)
@@ -232,6 +232,17 @@ extern DECLSPEC CEC::cec_version cec_get_device_cec_version(CEC::cec_logical_add
 extern DECLSPEC cec_version cec_get_device_cec_version(cec_logical_address iLogicalAddress);
 #endif
 
+/*!
+ * @brief Get the menu language of the device with the given logical address
+ * @param iLogicalAddress The device to get the menu language for.
+ * @param language The requested menu language.
+ * @return True when fetched succesfully, false otherwise.
+ */
+#ifdef __cplusplus
+extern DECLSPEC int cec_get_device_menu_language(CEC::cec_logical_address iLogicalAddress, CEC::cec_menu_language *language);
+#else
+extern DECLSPEC cec_version cec_get_device_menu_language(cec_logical_address iLogicalAddress, cec_menu_language *language);
+#endif
 #ifdef __cplusplus
 };
 #endif
index 6bad7692c803ff9dd3d7482736b68b55be783147..2ae9043e6d1824605e893a8e59e44d2bd3f71407 100644 (file)
@@ -538,6 +538,12 @@ typedef enum cec_log_level
   CEC_LOG_ALL     = 31
 } cec_log_level;
 
+typedef struct cec_menu_language
+{
+  char                language[4];
+  cec_logical_address device;
+} cec_menu_language;
+
 typedef struct cec_log_message
 {
   char          message[1024];
index ce2432db179270fd0edadbf6792ce6d824a6e88c..279c79ff5dbc9535ad038fa3facf31c65cb19e2f 100644 (file)
@@ -207,6 +207,12 @@ cec_version CCECProcessor::GetDeviceCecVersion(cec_logical_address iAddress)
   return m_busDevices[iAddress]->GetCecVersion();
 }
 
+bool CCECProcessor::GetDeviceMenuLanguage(cec_logical_address iAddress, cec_menu_language *language)
+{
+  *language = m_busDevices[iAddress]->GetMenuLanguage();
+  return (strcmp(language->language, "???"));
+}
+
 bool CCECProcessor::Transmit(const cec_command &data)
 {
   bool bReturn(false);
index 5362bfceaedca0362c20f492e8559f28f61a3801..94c796c73681bee0a87113d910c79109a806c8da 100644 (file)
@@ -62,6 +62,7 @@ namespace CEC
       virtual bool SetPhysicalAddress(uint16_t iPhysicalAddress);
       virtual bool SwitchMonitoring(bool bEnable);
       virtual cec_version GetDeviceCecVersion(cec_logical_address iAddress);
+      virtual bool GetDeviceMenuLanguage(cec_logical_address iAddress, cec_menu_language *language);
 
       virtual cec_logical_address GetLogicalAddress(void) const { return m_iLogicalAddress; }
       virtual uint16_t GetPhysicalAddress(void) const;
index eecde162bcd0080970536edd48871b2bf5443cee..6790c3c1d1184775a86666c936ad2ccf852f344c 100644 (file)
@@ -211,6 +211,13 @@ cec_version CLibCEC::GetDeviceCecVersion(cec_logical_address iAddress)
   return CEC_VERSION_UNKNOWN;
 }
 
+bool CLibCEC::GetDeviceMenuLanguage(cec_logical_address iAddress, cec_menu_language *language)
+{
+  if (m_cec && iAddress >= CECDEVICE_TV && iAddress < CECDEVICE_BROADCAST)
+    return m_cec->GetDeviceMenuLanguage(iAddress, language);
+  return false;
+}
+
 void CLibCEC::AddLog(cec_log_level level, const string &strMessage)
 {
   if (m_cec)
index 8d65a34c64324cd3ea559eb9df643066df019af8..1862a6e707eb359fc942c0a999ea431648016f4f 100644 (file)
@@ -74,6 +74,7 @@ namespace CEC
       virtual bool SetOSDString(cec_logical_address iLogicalAddress, cec_display_control duration, const char *strMessage);
       virtual bool SwitchMonitoring(bool bEnable);
       virtual cec_version GetDeviceCecVersion(cec_logical_address iAddress);
+      virtual bool GetDeviceMenuLanguage(cec_logical_address iAddress, cec_menu_language *language);
     //@}
 
       virtual void AddLog(cec_log_level level, const std::string &strMessage);
index cdc27783d018f2c1401ea4e1f94f4374310d9639..2e9f31df51b3421f1272bf922c32a987a5522d37 100644 (file)
@@ -194,4 +194,11 @@ cec_version cec_get_device_cec_version(cec_logical_address iLogicalAddress)
   return CEC_VERSION_UNKNOWN;
 }
 
+int cec_get_device_menu_language(cec_logical_address iLogicalAddress, cec_menu_language *language)
+{
+  if (cec_parser)
+    return cec_parser->GetDeviceMenuLanguage(iLogicalAddress, language) ? 1 : 0;
+  return -1;
+}
+
 //@}
index 5c73eb861db9fa64a82e8ce1ea1466283fbbba60..8aa5e4bf908f2465bf70b570b92fd6efa4f12aa0 100644 (file)
@@ -49,6 +49,10 @@ CCECBusDevice::CCECBusDevice(CCECProcessor *processor, cec_logical_address iLogi
   m_cecVersion(CEC_VERSION_UNKNOWN)
 {
   m_handler = new CCECCommandHandler(this);
+  for (unsigned int iPtr = 0; iPtr < 4; iPtr++)
+    m_menuLanguage.language[iPtr] = '?';
+  m_menuLanguage.language[3] = 0;
+  m_menuLanguage.device = iLogicalAddress;
 }
 
 CCECBusDevice::~CCECBusDevice(void)
@@ -72,6 +76,17 @@ void CCECBusDevice::AddLog(cec_log_level level, const CStdString &strMessage)
   m_processor->AddLog(level, strMessage);
 }
 
+void CCECBusDevice::SetMenuLanguage(const cec_menu_language &language)
+{
+  if (language.device == m_iLogicalAddress)
+  {
+    CStdString strLog;
+    strLog.Format("device %d menu language set to '%s'", m_iLogicalAddress, language.language);
+    m_processor->AddLog(CEC_LOG_DEBUG, strLog);
+    m_menuLanguage = language;
+  }
+}
+
 void CCECBusDevice::SetCecVersion(cec_version newVersion)
 {
   CStdString strLog;
@@ -358,6 +373,21 @@ cec_version CCECBusDevice::GetCecVersion(void)
   return m_cecVersion;
 }
 
+cec_menu_language &CCECBusDevice::GetMenuLanguage(void)
+{
+  if (!strcmp(m_menuLanguage.language, "???"))
+  {
+    AddLog(CEC_LOG_NOTICE, "<< requesting menu language");
+    cec_command command;
+    cec_command::format(command, GetMyLogicalAddress(), m_iLogicalAddress, CEC_OPCODE_GET_MENU_LANGUAGE);
+    CLockObject lock(&m_mutex);
+    if (m_processor->Transmit(command))
+      m_condition.Wait(&m_mutex, 1000);
+  }
+
+  return m_menuLanguage;
+}
+
 const char *CCECBusDevice::CECVendorIdToString(const uint64_t iVendorId)
 {
   switch (iVendorId)
index 4b6aa677e4254e6252498d01e713ec44188b9fc2..67a816f0e6c3468ca34f991113747c6856075c93 100644 (file)
@@ -54,6 +54,7 @@ namespace CEC
     virtual uint16_t GetMyPhysicalAddress(void) const;
 
     virtual void SetCecVersion(cec_version newVersion);
+    virtual void SetMenuLanguage(const cec_menu_language &menuLanguage);
     virtual void SetVendorId(const cec_datapacket &data);
     virtual void SetVendorId(uint64_t iVendorId, uint8_t iVendorClass = 0);
     virtual const char *GetVendorName(void) const { return CECVendorIdToString(m_iVendorId); }
@@ -69,6 +70,7 @@ namespace CEC
     virtual CCECCommandHandler *GetHandler(void) const { return m_handler; };
 
     virtual cec_version GetCecVersion(void);
+    virtual cec_menu_language &GetMenuLanguage(void);
     virtual void PollVendorId(void);
     virtual bool PowerOn(void);
     virtual bool Standby(void);
@@ -90,6 +92,7 @@ namespace CEC
   protected:
     uint16_t            m_iPhysicalAddress;
     cec_logical_address m_iLogicalAddress;
+    cec_menu_language   m_menuLanguage;
     CCECProcessor      *m_processor;
     CCECCommandHandler *m_handler;
     uint64_t            m_iVendorId;
index 790b631b25694b86a930fb7b996f413de2b49a51..f321a70889e71052999cd2db93cdf9e1c08a5ec7 100644 (file)
@@ -52,6 +52,9 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command)
     case CEC_OPCODE_CEC_VERSION:
       HandleDeviceCecVersion(command);
       break;
+    case CEC_OPCODE_SET_MENU_LANGUAGE:
+      HandleSetMenuLanguage(command);
+      break;
     case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
       HandleGivePhysicalAddress(command);
       break;
@@ -96,6 +99,9 @@ bool CCECCommandHandler::HandleCommand(const cec_command &command)
     CStdString strLog;
     switch (command.opcode)
     {
+    case CEC_OPCODE_SET_MENU_LANGUAGE:
+      HandleSetMenuLanguage(command);
+      break;
     case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
       HandleRequestActiveSource(command);
       break;
@@ -248,6 +254,25 @@ bool CCECCommandHandler::HandleRoutingChange(const cec_command &command)
   return true;
 }
 
+bool CCECCommandHandler::HandleSetMenuLanguage(const cec_command &command)
+{
+  if (command.parameters.size == 3)
+  {
+    CCECBusDevice *device = GetDevice(command.initiator);
+    if (device)
+    {
+      cec_menu_language language;
+      language.device = command.initiator;
+      for (unsigned int iPtr = 0; iPtr < 4; iPtr++)
+        language.language[iPtr] = command.parameters[iPtr];
+      language.language[3] = 0;
+      device->SetMenuLanguage(language);
+    }
+  }
+  return true;
+}
+
+
 bool CCECCommandHandler::HandleSetStreamPath(const cec_command &command)
 {
   if (command.parameters.size >= 2)
index aa5940c47ed327691a3f5f4873c93d7a50540bd8..4eff90192db73d047bef378335168c316e63a6ef 100644 (file)
@@ -59,6 +59,7 @@ namespace CEC
     bool HandleMenuRequest(const cec_command &command);
     bool HandleRequestActiveSource(const cec_command &command);
     bool HandleRoutingChange(const cec_command &command);
+    bool HandleSetMenuLanguage(const cec_command &command);
     bool HandleSetStreamPath(const cec_command &command);
     bool HandleUserControlPressed(const cec_command &command);
     bool HandleUserControlRelease(const cec_command &command);
index b8482d7fd422f83593ba17ce8fbddff7ee3e008e..3117ee689d5564e20e30d71f06c361a948db5742 100644 (file)
@@ -221,6 +221,9 @@ void show_console_help(void)
   "ver {addr}                get the CEC version of the specified device." << endl <<
   "[ver 0]                   get the CEC version of the TV" << endl <<
   endl <<
+  "lang {addr                get the menu language of the specified device." << endl <<
+  "[lang 0]                  get the menu language of the TV" << endl <<
+  endl <<
   "[mon] {1|0}               enable or disable CEC bus monitoring." << endl <<
   "[log] {1 - 31}            change the log level. see cectypes.h for values." << endl <<
   "[ping]                    send a ping command to the CEC adapter." << endl <<
@@ -492,6 +495,24 @@ int main (int argc, char *argv[])
         {
           parser->StartBootloader();
         }
+        else if (command == "lang")
+        {
+          CStdString strDev;
+          if (GetWord(input, strDev))
+          {
+            int iDev = atoi(strDev);
+            if (iDev >= 0 && iDev < 15)
+            {
+              CStdString strLog;
+              cec_menu_language language;
+              if (parser->GetDeviceMenuLanguage((cec_logical_address) iDev, &language))
+                strLog.Format("menu language '%s'", language.language);
+              else
+                strLog = "failed!";
+              cout << strLog.c_str() << endl;
+            }
+          }
+        }
         else if (command == "ver")
         {
           CStdString strDev;