+
+const char *CLibCEC::ToString(const cec_server_version version)
+{
+ return CCECTypeUtils::ToString(version);
+}
+
+void CLibCEC::CheckKeypressTimeout(void)
+{
+ // check all clients
+ for (vector<CCECClient *>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
+ (*it)->CheckKeypressTimeout();
+}
+
+void CLibCEC::AddLog(const cec_log_level level, const char *strFormat, ...)
+{
+ CStdString strLog;
+
+ // format the message
+ va_list argList;
+ va_start(argList, strFormat);
+ strLog.FormatV(strFormat, argList);
+ va_end(argList);
+
+ cec_log_message message;
+ message.level = level;
+ message.time = GetTimeMs() - m_iStartTime;
+ snprintf(message.message, sizeof(message.message), "%s", strLog.c_str());
+
+ // send the message to all clients
+ for (vector<CCECClient *>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
+ (*it)->AddLog(message);
+}
+
+void CLibCEC::AddCommand(const cec_command &command)
+{
+ // send the command to all clients
+ for (vector<CCECClient *>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
+ (*it)->AddCommand(command);
+}
+
+void CLibCEC::Alert(const libcec_alert type, const libcec_parameter ¶m)
+{
+ // send the alert to all clients
+ for (vector<CCECClient *>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
+ (*it)->Alert(type, param);
+}
+
+bool CLibCEC::SetActiveView(void)
+{
+ AddLog(CEC_LOG_WARNING, "deprecated method %s called", __FUNCTION__);
+ return SetActiveSource();
+}
+
+bool CLibCEC::EnablePhysicalAddressDetection(void)
+{
+ AddLog(CEC_LOG_WARNING, "deprecated method %s called", __FUNCTION__);
+ return true;
+}
+
+CCECClient *CLibCEC::RegisterClient(libcec_configuration &configuration)
+{
+ if (!m_cec)
+ return NULL;
+
+ // create a new client instance
+ CCECClient *newClient = new CCECClient(m_cec, configuration);
+ if (!newClient)
+ return NULL;
+ m_clients.push_back(newClient);
+
+ // if the default client isn't set, set it
+ if (!m_client)
+ m_client = newClient;
+
+ // register the new client
+ if (m_cec->CECInitialised())
+ m_cec->RegisterClient(newClient);
+
+ return newClient;
+}
+
+void CLibCEC::UnregisterClients(void)
+{
+ if (m_cec)
+ m_cec->UnregisterClients();
+
+ m_clients.clear();
+
+ DELETE_AND_NULL(m_client);
+}
+
+void * CECInitialise(libcec_configuration *configuration)
+{
+ if (!configuration)
+ return NULL;
+
+ // create a new libCEC instance
+ CLibCEC *lib = new CLibCEC(NULL);
+
+ // register a new client
+ CCECClient *client(NULL);
+ if (lib && configuration)
+ client = lib->RegisterClient(*configuration);
+
+ // update the current configuration
+ if (client)
+ client->GetCurrentConfiguration(*configuration);
+
+ // ensure that the correct server version is set
+ configuration->serverVersion = LIBCEC_VERSION_CURRENT;
+
+ return static_cast< void* > (lib);
+}
+
+void * CECInit(const char *strDeviceName, CEC::cec_device_type_list types)
+{
+ libcec_configuration configuration; configuration.Clear();
+
+ // client version < 1.5.0
+ snprintf(configuration.strDeviceName, 13, "%s", strDeviceName);
+ configuration.deviceTypes = types;
+ configuration.iPhysicalAddress = CEC_INVALID_PHYSICAL_ADDRESS;
+
+ if (configuration.deviceTypes.IsEmpty())
+ configuration.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
+
+ return CECInitialise(&configuration);
+}
+
+void * CECCreate(const char *strDeviceName, CEC::cec_logical_address iLogicalAddress /* = CEC::CECDEVICE_PLAYBACKDEVICE1 */, uint16_t iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS */)
+{
+ libcec_configuration configuration; configuration.Clear();
+
+ // client version < 1.5.0
+ snprintf(configuration.strDeviceName, 13, "%s", strDeviceName);
+ configuration.iPhysicalAddress = iPhysicalAddress;
+ configuration.deviceTypes.Add(CCECTypeUtils::GetType(iLogicalAddress));
+
+ return CECInitialise(&configuration);
+}
+
+bool CECStartBootloader(void)
+{
+ bool bReturn(false);
+ cec_adapter deviceList[1];
+ if (CAdapterFactory(NULL).FindAdapters(deviceList, 1, 0) > 0)
+ {
+ CAdapterFactory factory(NULL);
+ IAdapterCommunication *comm = factory.GetInstance(deviceList[0].comm);
+ if (comm)
+ {
+ CTimeout timeout(CEC_DEFAULT_CONNECT_TIMEOUT);
+ while (timeout.TimeLeft() > 0 &&
+ (bReturn = comm->Open(timeout.TimeLeft() / CEC_CONNECT_TRIES, true)) == false)
+ {
+ comm->Close();
+ CEvent::Sleep(500);
+ }
+ if (comm->IsOpen())
+ bReturn = comm->StartBootloader();
+
+ delete comm;
+ }
+ }
+
+ return bReturn;
+}
+
+void CECDestroy(CEC::ICECAdapter *instance)
+{
+ DELETE_AND_NULL(instance);
+}
+
+bool CLibCEC::GetDeviceInformation(const char *strPort, libcec_configuration *config, uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */)
+{
+ if (m_cec->IsRunning())
+ return false;
+
+ return m_cec->GetDeviceInformation(strPort, config, iTimeoutMs);
+}
+
+const char *CLibCEC::GetLibInfo(void)
+{
+#ifndef LIB_INFO
+#ifdef _WIN32
+#define FEATURES "'P8 USB' 'P8 USB detect'"
+#ifdef _WIN64
+#define HOST_TYPE "Windows (x64)"
+#else
+#define HOST_TYPE "Windows (x86)"
+#endif
+#else
+#define HOST_TYPE "unknown"
+#define FEATURES "unknown"
+#endif
+
+ return "host: " HOST_TYPE ", features: " FEATURES ", compiled: " __DATE__;
+#else
+ return LIB_INFO;
+#endif
+}
+
+const char *CLibCEC::ToString(const cec_user_control_code key)
+{
+ return CCECTypeUtils::ToString(key);
+}
+
+void CLibCEC::InitVideoStandalone(void)
+{
+ CAdapterFactory::InitVideoStandalone();
+}
+
+const char *CLibCEC::ToString(const cec_adapter_type type)
+{
+ return CCECTypeUtils::ToString(type);
+}
+
+// no longer being used
+void CLibCEC::AddKey(const cec_keypress &UNUSED(key)) {}
+void CLibCEC::ConfigurationChanged(const libcec_configuration &UNUSED(config)) {}
+void CLibCEC::SetCurrentButton(cec_user_control_code UNUSED(iButtonCode)) {}
+CLibCEC *CLibCEC::GetInstance(void) { return NULL; }
+void CLibCEC::SetInstance(CLibCEC *UNUSED(instance)) {}