virtual void Close(void) = 0;
/*!
- * @brief Try to find all connected CEC adapters. Only implemented on Linux at the moment.
+ * @brief Set and enable the callback methods. If this method is not called, the GetNext...() methods will have to be used.
+ * @param callbacks The callbacks to set.
+ * @return True when enabled, false otherwise.
+ */
+ virtual bool EnableCallbacks(ICECCallbacks *callbacks) = 0;
+
+ /*!
+ * @brief Try to find all connected CEC adapters. Only implemented on Linux and Windows at the moment.
* @param deviceList The vector to store device descriptors in.
* @param iBufSize The size of the deviceList buffer.
* @param strDevicePath Optional device path. Only adds device descriptors that match the given device path.
virtual const char *ToString(const cec_system_audio_status mode) = 0;
virtual const char *ToString(const cec_audio_status status) = 0;
virtual const char *ToString(const cec_vendor_id vendor) = 0;
-
};
};
extern DECLSPEC void cec_close(void);
+#ifdef __cplusplus
+extern DECLSPEC int cec_enable_callbacks(CEC::ICECCallbacks *callbacks);
+#else
+extern DECLSPEC int cec_enable_callbacks(ICECCallbacks *callbacks);
+#endif
+
#ifdef __cplusplus
extern DECLSPEC int8_t cec_find_adapters(CEC::cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath);
#else
#endif
} cec_logical_addresses;
+struct ICECCallbacks
+{
+ /*!
+ * @brief Transfer a log message from libCEC to the client.
+ * @param message The message to transfer.
+ * @return 1 when ok, 0 otherwise.
+ */
+ int (*CecLogMessage)(const cec_log_message &message);
+
+ /*!
+ * @brief Transfer a keypress from libCEC to the client.
+ * @param key The keypress to transfer.
+ * @return 1 when ok, 0 otherwise.
+ */
+ int (*CecKeyPress)(const cec_keypress &key);
+
+ /*!
+ * @brief Transfer a CEC command from libCEC to the client.
+ * @param command The command to transfer.
+ * @return 1 when ok, 0 otherwise.
+ */
+ int (*CecCommand)(const cec_command &command);
+};
+
#ifdef UNUSED
#elif defined(__GNUC__)
#define UNUSED(x) UNUSED_ ## x __attribute__((unused))
CLibCEC::CLibCEC(const char *strDeviceName, cec_device_type_list types) :
m_iStartTime(GetTimeMs()),
m_iCurrentButton(CEC_USER_CONTROL_CODE_UNKNOWN),
- m_buttontime(0)
+ m_buttontime(0),
+ m_callbacks(NULL)
{
m_cec = new CCECProcessor(this, strDeviceName, types);
}
CLibCEC::CLibCEC(const char *strDeviceName, cec_logical_address iLogicalAddress /* = CECDEVICE_PLAYBACKDEVICE1 */, uint16_t iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS */) :
m_iStartTime(GetTimeMs()),
m_iCurrentButton(CEC_USER_CONTROL_CODE_UNKNOWN),
- m_buttontime(0)
+ m_buttontime(0),
+ m_callbacks(NULL)
{
m_cec = new CCECProcessor(this, strDeviceName, iLogicalAddress, iPhysicalAddress);
}
m_cec->StopThread();
}
+bool CLibCEC::EnableCallbacks(ICECCallbacks *callbacks)
+{
+ CLockObject lock(&m_mutex);
+ if (m_cec)
+ m_callbacks = callbacks;
+ return false;
+}
+
int8_t CLibCEC::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */)
{
CStdString strDebug;
void CLibCEC::AddLog(cec_log_level level, const string &strMessage)
{
+ CLockObject lock(&m_mutex);
if (m_cec)
{
cec_log_message message;
message.level = level;
message.time = GetTimeMs() - m_iStartTime;
snprintf(message.message, sizeof(message.message), "%s", strMessage.c_str());
- m_logBuffer.Push(message);
+
+ if (m_callbacks)
+ m_callbacks->CecLogMessage(message);
+ else
+ m_logBuffer.Push(message);
}
}
void CLibCEC::AddKey(cec_keypress &key)
{
- m_keyBuffer.Push(key);
+ CLockObject lock(&m_mutex);
+ if (m_callbacks)
+ m_callbacks->CecKeyPress(key);
+ else
+ m_keyBuffer.Push(key);
m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN;
m_buttontime = 0;
}
void CLibCEC::AddKey(void)
{
+ CLockObject lock(&m_mutex);
if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN)
{
cec_keypress key;
key.duration = (unsigned int) (GetTimeMs() - m_buttontime);
key.keycode = m_iCurrentButton;
- m_keyBuffer.Push(key);
+
+ if (m_callbacks)
+ m_callbacks->CecKeyPress(key);
+ else
+ m_keyBuffer.Push(key);
m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN;
}
m_buttontime = 0;
void CLibCEC::AddCommand(const cec_command &command)
{
- if (m_commandBuffer.Push(command))
+ CLockObject lock(&m_mutex);
+ if (m_callbacks)
+ {
+ m_callbacks->CecCommand(command);
+ }
+ else if (m_commandBuffer.Push(command))
{
CStdString strDebug;
strDebug.Format("stored command '%2x' in the command buffer. buffer size = %d", command.opcode, m_commandBuffer.Size());
virtual bool Open(const char *strPort, uint32_t iTimeout = 10000);
virtual void Close(void);
+ virtual bool EnableCallbacks(ICECCallbacks *callbacks);
virtual int8_t FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath = NULL);
virtual bool PingAdapter(void);
virtual bool StartBootloader(void);
CecBuffer<cec_log_message> m_logBuffer;
CecBuffer<cec_keypress> m_keyBuffer;
CecBuffer<cec_command> m_commandBuffer;
+ ICECCallbacks *m_callbacks;
+ CMutex m_mutex;
};
};
cec_parser->Close();
}
+int cec_enable_callbacks(ICECCallbacks *callbacks)
+{
+ if (cec_parser)
+ return cec_parser->EnableCallbacks(callbacks) ? 1 : 0;
+ return -1;
+}
+
int8_t cec_find_adapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */)
{
if (cec_parser)