desktop/mythtv/libcec-2-support.2.patch
2015-03-15 13:51:59 +00:00

461 lines
17 KiB
Diff

diff --git a/mythtv/configure b/mythtv/configure
index 7ab8aa7..7d5e39d 100755
--- a/mythtv/configure
+++ b/mythtv/configure
@@ -5178,10 +5178,12 @@ using namespace std;
using namespace CEC;
#include <libcec/cecloader.h>
int main(void) {
+ if (CEC_LIB_VERSION_MAJOR == 2)
+ return 1;
if (CEC_LIB_VERSION_MAJOR < 1 || (CEC_LIB_VERSION_MAJOR == 1 &&
CEC_LIB_VERSION_MINOR < 5))
return 0;
- return (long) LibCecInit;
+ return 1;
}
EOF
fi
diff --git a/mythtv/libs/libmythui/cecadapter.cpp b/mythtv/libs/libmythui/cecadapter.cpp
index edad8f6..5987d5d 100644
--- a/mythtv/libs/libmythui/cecadapter.cpp
+++ b/mythtv/libs/libmythui/cecadapter.cpp
@@ -14,9 +14,28 @@
#include "cecadapter.h"
#include <vector>
-#define MIN_LIBCEC_VERSION 1
+#ifdef CEC_CLIENT_VERSION_CURRENT // 2.0.3 and up
+#define CEC_CONFIG_VERSION CEC_CLIENT_VERSION_CURRENT;
+#else
+#ifdef LIBCEC_VERSION_CURRENT // 1.6.2 and up
+#define CEC_CONFIG_VERSION LIBCEC_VERSION_CURRENT;
+#else
+#define CEC_CONFIG_VERSION 0;
+#endif
+#endif
+
#define MAX_CEC_DEVICES 10
#define LOC QString("CECAdapter: ")
+#define OSDNAME "MythTv"
+
+// TODO remove if we have a ui.
+// hard code logical and physical address
+#define CEC_DEFAULT_DEVICE_TYPE CEC_DEVICE_TYPE_RECORDING_DEVICE
+#undef CEC_DEFAULT_HDMI_PORT
+#define CEC_DEFAULT_HDMI_PORT 2
+#undef CEC_DEFAULT_BASE_DEVICE
+#define CEC_DEFAULT_BASE_DEVICE CECDEVICE_AUDIOSYSTEM
+#define CEC_DEFAULT_PHYSICALADDRESS (quint16)0x2200
#include <libcec/cec.h>
#include <iostream>
@@ -25,17 +44,26 @@ using namespace std;
#include <libcec/cecloader.h>
QMutex* CECAdapter::gLock = new QMutex(QMutex::Recursive);
+bool resetSafe = false;
class CECAdapterPriv
{
public:
CECAdapterPriv()
- : adapter(NULL), defaultDevice("auto"), defaultHDMIPort(1),
- defaultDeviceID(CECDEVICE_PLAYBACKDEVICE1), timer(NULL), valid(false),
+ : adapter(NULL), defaultDevice("auto"), defaultHDMIPort(CEC_DEFAULT_HDMI_PORT),
+ defaultDeviceID(CEC_DEFAULT_DEVICE_TYPE), timer(NULL), valid(false),
powerOffTV(false), powerOffTVAllowed(false), powerOffTVOnExit(false),
powerOnTV(false), powerOnTVAllowed(false), powerOnTVOnStart(false),
switchInput(false), switchInputAllowed(true)
{
+ callbacks.Clear();
+ callbacks.CBCecLogMessage = LogMessages;
+ callbacks.CBCecKeyPress = HandleKeyPresses;
+ callbacks.CBCecCommand = HandleCommands;
+ callbacks.CBCecConfigurationChanged = HandleConfigurationChanged;
+ callbacks.CBCecAlert = HandleAlerts;
+ callbacks.CBCecMenuStateChanged = HandleMenuStateChanged;
+ callbacks.CBCecSourceActivated = HandleSourceActivated;
}
static QString addressToString(enum cec_logical_address addr, bool source)
@@ -69,14 +97,15 @@ class CECAdapterPriv
static QStringList GetDeviceList(void)
{
QStringList results;
- cec_device_type_list list;
- list.Clear();
- list.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
- ICECAdapter *adapter = LibCecInit("MythTV", list);
+ libcec_configuration configuration;
+ configuration.Clear();
+ ICECAdapter *adapter = LibCecInitialise(&configuration);
if (!adapter)
return results;
cec_adapter *devices = new cec_adapter[MAX_CEC_DEVICES];
uint8_t num_devices = adapter->FindAdapters(devices, MAX_CEC_DEVICES, NULL);
+ LOG(VB_GENERAL, LOG_INFO, LOC + QString("GetDeviceList() found %1 devices(s).")
+ .arg(num_devices));
if (num_devices < 1)
return results;
for (uint8_t i = 0; i < num_devices; i++)
@@ -89,39 +118,112 @@ class CECAdapterPriv
{
// get settings
// N.B. these do not currently work as there is no UI
+
+ // There is no way current CEC adapters can find their physical address
+ // on their own. The are only connected to the CEC pin of the HDMI connector.
+ // To construct a valid physical address libCEC needs:
+ // - the HDMI port (number) Myth is connected to
+ // - the HDMI device (TV, Receiver) Myth is connected to (the logical address)
+
+ //The CEC adapter we want to connect to
defaultDevice = gCoreContext->GetSetting(LIBCEC_DEVICE, "auto").trimmed();
+ // The number of the HDMI port Myth is connected to
QString hdmi_port = gCoreContext->GetSetting(LIBCEC_PORT, "auto");
+ // The logical address of the HDMI device Myth is connected to
+ QString base_dev = gCoreContext->GetSetting(LIBCEC_BASE, "auto");
+ // Device type we want Myth to use
QString device_id = gCoreContext->GetSetting(LIBCEC_DEVICEID, "auto");
powerOffTVAllowed = (bool)gCoreContext->GetNumSetting(POWEROFFTV_ALLOWED, 1);
powerOffTVOnExit = (bool)gCoreContext->GetNumSetting(POWEROFFTV_ONEXIT, 1);
powerOnTVAllowed = (bool)gCoreContext->GetNumSetting(POWERONTV_ALLOWED, 1);
powerOnTVOnStart = (bool)gCoreContext->GetNumSetting(POWERONTV_ONSTART, 1);
- defaultHDMIPort = 1;
if ("auto" != hdmi_port)
{
defaultHDMIPort = hdmi_port.toInt();
- if (defaultHDMIPort < 1 || defaultHDMIPort > 3)
- defaultHDMIPort = 1;
+ if (defaultHDMIPort < CEC_MIN_HDMI_PORTNUMBER || defaultHDMIPort > CEC_MAX_HDMI_PORTNUMBER)
+ defaultHDMIPort = CEC_DEFAULT_HDMI_PORT;
+ }
+ else
+ {
+ defaultHDMIPort = CEC_DEFAULT_HDMI_PORT;
}
- defaultHDMIPort = defaultHDMIPort << 12;
- defaultDeviceID = CECDEVICE_PLAYBACKDEVICE1;
if ("auto" != device_id)
{
int id = device_id.toInt();
- if (id < 1 || id > 3)
- id = 1;
- defaultDeviceID = (id == 1) ? CECDEVICE_PLAYBACKDEVICE1 :
- ((id == 2) ? CECDEVICE_PLAYBACKDEVICE2 :
- CECDEVICE_PLAYBACKDEVICE3);
+ switch (id)
+ {
+ case CEC_DEVICE_TYPE_TV:
+ case CEC_DEVICE_TYPE_RECORDING_DEVICE:
+ case CEC_DEVICE_TYPE_RESERVED:
+ case CEC_DEVICE_TYPE_TUNER:
+ case CEC_DEVICE_TYPE_PLAYBACK_DEVICE:
+ case CEC_DEVICE_TYPE_AUDIO_SYSTEM:
+ defaultDeviceID = (cec_device_type)id;
+ break;
+ default:
+ defaultDeviceID = CEC_DEFAULT_DEVICE_TYPE;
+ break;
+ }
+ }
+ else
+ {
+ defaultDeviceID = CEC_DEFAULT_DEVICE_TYPE;
}
+ LOG(VB_GENERAL, LOG_INFO, LOC + QString("base_dev= %1.")
+ .arg(base_dev));
+ if ("auto" != base_dev)
+ {
+ base_device = (cec_logical_address)base_dev.toInt();
+ LOG(VB_GENERAL, LOG_INFO, LOC + QString("base_device= %1.")
+ .arg(base_device));
+ switch (base_device)
+ {
+ case CECDEVICE_TV:
+ case CECDEVICE_RECORDINGDEVICE1:
+ case CECDEVICE_RECORDINGDEVICE2:
+ case CECDEVICE_TUNER1:
+ case CECDEVICE_PLAYBACKDEVICE1:
+ case CECDEVICE_AUDIOSYSTEM:
+ case CECDEVICE_TUNER2:
+ case CECDEVICE_TUNER3:
+ case CECDEVICE_PLAYBACKDEVICE2:
+ case CECDEVICE_RECORDINGDEVICE3:
+ case CECDEVICE_TUNER4:
+ case CECDEVICE_PLAYBACKDEVICE3:
+ case CECDEVICE_FREEUSE:
+ break;
+ case CECDEVICE_UNKNOWN:
+ case CECDEVICE_RESERVED1:
+ case CECDEVICE_RESERVED2:
+ case CECDEVICE_BROADCAST:
+ default:
+ base_device = (cec_logical_address)CEC_DEFAULT_BASE_DEVICE;
+ break;
+ }
+ }
+ else
+ {
+ base_device = (cec_logical_address)CEC_DEFAULT_BASE_DEVICE;
+ }
+
// create adapter interface
- cec_device_type_list list;
- list.Clear();
- list.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
- adapter = LibCecInit("MythTV", list);
+ libcec_configuration configuration;
+ configuration.Clear();
+ configuration.clientVersion = LIBCEC_VERSION_CURRENT;
+ snprintf(configuration.strDeviceName, 13, "MythTV");
+ configuration.deviceTypes.Add(defaultDeviceID);
+ configuration.iPhysicalAddress = CEC_DEFAULT_PHYSICALADDRESS;
+ configuration.iHDMIPort = defaultHDMIPort;
+ LOG(VB_GENERAL, LOG_INFO, LOC + QString("using HDMI port %1.")
+ .arg(defaultHDMIPort));
+ configuration.baseDevice = base_device;
+ LOG(VB_GENERAL, LOG_INFO, LOC + QString("using base device %1.")
+ .arg(configuration.baseDevice));
+ configuration.callbacks = &callbacks;
+ ICECAdapter *adapter = LibCecInitialise(&configuration);
if (!adapter)
{
@@ -129,12 +231,12 @@ class CECAdapterPriv
return false;
}
- if (adapter->GetMinLibVersion() > MIN_LIBCEC_VERSION)
+ if ((configuration.serverVersion >> 12) > CEC_MIN_LIB_VERSION)
{
LOG(VB_GENERAL, LOG_ERR, LOC +
QString("The installed libCEC supports version %1 and above. "
"This version of MythTV only supports version %2.")
- .arg(adapter->GetMinLibVersion()).arg(MIN_LIBCEC_VERSION));
+ .arg(configuration.serverVersion).arg(CEC_MIN_LIB_VERSION));
return false;
}
@@ -185,12 +287,6 @@ class CECAdapterPriv
// get the vendor ID (for non-standard implementations)
adapter->GetDeviceVendorId(CECDEVICE_TV);
- // set the physical address
- adapter->SetPhysicalAddress(defaultHDMIPort);
-
- // set the logical address
- adapter->SetLogicalAddress(defaultDeviceID);
-
// switch input (if configured)
switchInput = true;
HandleActions();
@@ -210,7 +306,6 @@ class CECAdapterPriv
// delete adapter
adapter->Close();
- LogMessages();
UnloadLibCec(adapter);
LOG(VB_GENERAL, LOG_INFO, LOC + "Closing down CEC.");
@@ -219,14 +314,12 @@ class CECAdapterPriv
adapter = NULL;
}
- void LogMessages(void)
+ #if CEC_LIB_VERSION_MAJOR < 2
+ static int LogMessages(void *, const cec_log_message &message)
+ #else
+ static int LogMessages(void *, const cec_log_message message)
+ #endif
{
- if (!adapter || !valid)
- return;
-
- cec_log_message message;
- while (adapter->GetNextLogMessage(&message))
- {
QString msg(message.message);
int lvl = LOG_UNKNOWN;
switch (message.level)
@@ -237,19 +330,15 @@ class CECAdapterPriv
case CEC_LOG_DEBUG: lvl = LOG_DEBUG; break;
}
LOG(VB_GENERAL, lvl, LOC + QString("%1").arg(msg));
- }
+ return 0;
}
- void HandleCommands(void)
+ #if CEC_LIB_VERSION_MAJOR < 2
+ static int HandleCommands(void * /*cbParam*/, const cec_command &command)
+ #else
+ static int HandleCommands(void * /*cbParam*/, const cec_command command)
+ #endif
{
- if (!adapter || !valid)
- return;
-
- LogMessages();
-
- cec_command command;
- while (adapter->GetNextCommand(&command))
- {
LOG(VB_GENERAL, LOG_DEBUG, LOC +
QString("Command %1 from '%2' (%3) - destination '%4' (%5)")
.arg(command.opcode)
@@ -260,27 +349,76 @@ class CECAdapterPriv
switch (command.opcode)
{
- // TODO
+ // TODO handle CEC commands.
default:
break;
}
- }
+ return 0;
+ }
- LogMessages();
+ #if CEC_LIB_VERSION_MAJOR < 2
+ static int HandleConfigurationChanged(void * /*cbParam*/, const libcec_configuration &config)
+ #else
+ static int HandleConfigurationChanged(void * /*cbParam*/, const libcec_configuration config)
+ #endif
+ {
+ LOG(VB_GENERAL, LOG_INFO, LOC + "Adapter configuration changed.");
+ return 1;
}
- void HandleKeyPresses(void)
+ #if CEC_LIB_VERSION_MAJOR < 2
+ static int HandleAlerts(void * /*cbParam*/, const libcec_alert type, const libcec_parameter & /*param*/)
+ #else
+ static int HandleAlerts(void * /*cbParam*/, const libcec_alert type, const libcec_parameter /*param*/)
+ #endif
{
- if (!adapter || !valid)
- return;
+ switch (type) // TODO Handle alerts.
+ {
+ case CEC_ALERT_CONNECTION_LOST:
+ LOG(VB_GENERAL, LOG_ERR, LOC + "Connection lost - TODO: need to handle this!");
+ break;
+ default:
+ LOG(VB_GENERAL, LOG_ERR, LOC + "Received unknown alert.");
+ break;
+ }
+ return 0;
+ }
- cec_keypress key;
- if (!adapter->GetNextKeypress(&key))
- return;
+ #if CEC_LIB_VERSION_MAJOR < 2
+ static int HandleMenuStateChanged(void * /*cbParam*/, const cec_menu_state &state)
+ #else
+ static int HandleMenuStateChanged(void * /*cbParam*/, const cec_menu_state state)
+ #endif
+ {
+ LOG(VB_GENERAL, LOG_INFO, LOC + QString("CEC menu state %1")
+ .arg(state == CEC_MENU_STATE_ACTIVATED ? "Activated" : "Deactivated"));
+ return 1;
+ }
+ #if CEC_LIB_VERSION_MAJOR < 2
+ static void HandleSourceActivated(void * /*cbParam*/, const cec_logical_address &address, const &uint8_t activated)
+ #else
+ static void HandleSourceActivated(void * /*cbParam*/, const cec_logical_address address, const uint8_t activated)
+ #endif
+ {
+ LOG(VB_GENERAL, LOG_INFO, LOC + QString("Source %1 %2")
+ .arg(address).arg(activated ? "Activated" : "Deactivated"));
+
+ if (activated && resetSafe)
+ GetMythUI()->ResetScreensaver();
+ else
+ resetSafe = true;
+ }
+
+ #if CEC_LIB_VERSION_MAJOR < 2
+ static int HandleKeyPresses(void * /*cbParam*/, const cec_keypress &key)
+ #else
+ static int HandleKeyPresses(void * /*cbParam*/, const cec_keypress key)
+ #endif
+ {
// Ignore key down events and wait for the key 'up'
if (key.duration < 1)
- return;
+ return 0;
QString code;
int action = 0;
@@ -595,13 +733,12 @@ class CECAdapterPriv
.arg(code).arg(0 == action ? "(Not actioned)" : ""));
if (0 == action)
- return;
+ return 0;
GetMythUI()->ResetScreensaver();
QKeyEvent* ke = new QKeyEvent(QEvent::KeyPress, action, Qt::NoModifier);
qApp->postEvent(GetMythMainWindow(), (QEvent*)ke);
-
- LogMessages();
+ return 0;
}
void HandleActions(void)
@@ -629,7 +766,7 @@ class CECAdapterPriv
// HDMI input
if (switchInput && switchInputAllowed)
{
- if (adapter->SetActiveView())
+ if (adapter->SetActiveSource())
LOG(VB_GENERAL, LOG_INFO, LOC + "Asked TV to switch to this input.");
else
LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to switch to this input.");
@@ -638,14 +775,14 @@ class CECAdapterPriv
powerOffTV = false;
powerOnTV = false;
switchInput = false;
-
- LogMessages();
}
ICECAdapter *adapter;
+ ICECCallbacks callbacks;
QString defaultDevice;
int defaultHDMIPort;
- cec_logical_address defaultDeviceID;
+ cec_device_type defaultDeviceID;
+ cec_logical_address base_device;
QTimer *timer;
bool valid;
bool powerOffTV;
@@ -728,8 +865,6 @@ void CECAdapter::Action(const QString &action)
void CECAdapter::Process(void)
{
gLock->lock();
- m_priv->HandleCommands();
- m_priv->HandleKeyPresses();
m_priv->HandleActions();
gLock->unlock();
}
diff --git a/mythtv/libs/libmythui/cecadapter.h b/mythtv/libs/libmythui/cecadapter.h
index e9cf6d6..bb5eba8 100644
--- a/mythtv/libs/libmythui/cecadapter.h
+++ b/mythtv/libs/libmythui/cecadapter.h
@@ -7,6 +7,7 @@
#define LIBCEC_ENABLED QString("libCECEnabled")
#define LIBCEC_DEVICE QString("libCECDevice")
#define LIBCEC_PORT QString("libCECPort")
+#define LIBCEC_BASE QString("libCECBase")
#define LIBCEC_DEVICEID QString("libCECDeviceID")
#define POWEROFFTV_ALLOWED QString("PowerOffTVAllowed")
#define POWEROFFTV_ONEXIT QString("PowerOffTVOnExit")