From a3269a0a9e8973e29cfe073dd8e558aad173f984 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Sun, 30 Oct 2011 13:26:37 +0100 Subject: [PATCH] cec: added GetDeviceMenuLanguage()/cec_get_device_menu_language() --- include/cec.h | 5 ++++ include/cecc.h | 11 +++++++ include/cectypes.h | 6 ++++ src/lib/CECProcessor.cpp | 6 ++++ src/lib/CECProcessor.h | 1 + src/lib/LibCEC.cpp | 7 +++++ src/lib/LibCEC.h | 1 + src/lib/LibCECC.cpp | 7 +++++ src/lib/devices/CECBusDevice.cpp | 30 +++++++++++++++++++ src/lib/devices/CECBusDevice.h | 3 ++ src/lib/implementations/CECCommandHandler.cpp | 25 ++++++++++++++++ src/lib/implementations/CECCommandHandler.h | 1 + src/testclient/main.cpp | 21 +++++++++++++ 13 files changed, 124 insertions(+) diff --git a/include/cec.h b/include/cec.h index 68652b1..9be8d21 100644 --- a/include/cec.h +++ b/include/cec.h @@ -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; }; }; diff --git a/include/cecc.h b/include/cecc.h index f897e13..a76ac0f 100644 --- a/include/cecc.h +++ b/include/cecc.h @@ -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 diff --git a/include/cectypes.h b/include/cectypes.h index 6bad769..2ae9043 100644 --- a/include/cectypes.h +++ b/include/cectypes.h @@ -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]; diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index ce2432d..279c79f 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -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); diff --git a/src/lib/CECProcessor.h b/src/lib/CECProcessor.h index 5362bfc..94c796c 100644 --- a/src/lib/CECProcessor.h +++ b/src/lib/CECProcessor.h @@ -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; diff --git a/src/lib/LibCEC.cpp b/src/lib/LibCEC.cpp index eecde16..6790c3c 100644 --- a/src/lib/LibCEC.cpp +++ b/src/lib/LibCEC.cpp @@ -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) diff --git a/src/lib/LibCEC.h b/src/lib/LibCEC.h index 8d65a34..1862a6e 100644 --- a/src/lib/LibCEC.h +++ b/src/lib/LibCEC.h @@ -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); diff --git a/src/lib/LibCECC.cpp b/src/lib/LibCECC.cpp index cdc2778..2e9f31d 100644 --- a/src/lib/LibCECC.cpp +++ b/src/lib/LibCECC.cpp @@ -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; +} + //@} diff --git a/src/lib/devices/CECBusDevice.cpp b/src/lib/devices/CECBusDevice.cpp index 5c73eb8..8aa5e4b 100644 --- a/src/lib/devices/CECBusDevice.cpp +++ b/src/lib/devices/CECBusDevice.cpp @@ -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) diff --git a/src/lib/devices/CECBusDevice.h b/src/lib/devices/CECBusDevice.h index 4b6aa67..67a816f 100644 --- a/src/lib/devices/CECBusDevice.h +++ b/src/lib/devices/CECBusDevice.h @@ -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; diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index 790b631..f321a70 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -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) diff --git a/src/lib/implementations/CECCommandHandler.h b/src/lib/implementations/CECCommandHandler.h index aa5940c..4eff901 100644 --- a/src/lib/implementations/CECCommandHandler.h +++ b/src/lib/implementations/CECCommandHandler.h @@ -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); diff --git a/src/testclient/main.cpp b/src/testclient/main.cpp index b8482d7..3117ee6 100644 --- a/src/testclient/main.cpp +++ b/src/testclient/main.cpp @@ -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; -- 2.34.1