Ticket #11338: libcec-2-support.patch

File libcec-2-support.patch, 13.3 KB (added by macarno@…, 10 years ago)

Patch for libCEC version 2 support

  • mythtv/configure

    diff --git a/mythtv/configure b/mythtv/configure
    index 7ab8aa7..7d5e39d 100755
    a b using namespace std; 
    51785178using namespace CEC;
    51795179#include <libcec/cecloader.h>
    51805180int main(void) {
     5181    if (CEC_LIB_VERSION_MAJOR == 2)
     5182        return 1;
    51815183    if (CEC_LIB_VERSION_MAJOR < 1 || (CEC_LIB_VERSION_MAJOR == 1 &&
    51825184                                      CEC_LIB_VERSION_MINOR < 5))
    51835185        return 0;
    5184     return (long) LibCecInit;
     5186    return 1;
    51855187}
    51865188EOF
    51875189fi
  • mythtv/libs/libmythui/cecadapter.cpp

    diff --git a/mythtv/libs/libmythui/cecadapter.cpp b/mythtv/libs/libmythui/cecadapter.cpp
    index edad8f6..ab6ecdd 100644
    a b  
    1414#include "cecadapter.h"
    1515#include <vector>
    1616
    17 #define MIN_LIBCEC_VERSION 1
    1817#define MAX_CEC_DEVICES 10
    1918#define LOC QString("CECAdapter: ")
    2019
    class CECAdapterPriv 
    3130  public:
    3231    CECAdapterPriv()
    3332      : adapter(NULL), defaultDevice("auto"), defaultHDMIPort(1),
    34         defaultDeviceID(CECDEVICE_PLAYBACKDEVICE1), timer(NULL), valid(false),
     33        defaultDeviceID(CEC_DEVICE_TYPE_PLAYBACK_DEVICE), timer(NULL), valid(false),
    3534        powerOffTV(false),  powerOffTVAllowed(false), powerOffTVOnExit(false),
    3635        powerOnTV(false),   powerOnTVAllowed(false),  powerOnTVOnStart(false),
    3736        switchInput(false), switchInputAllowed(true)
    class CECAdapterPriv 
    7271        cec_device_type_list list;
    7372        list.Clear();
    7473        list.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
    75         ICECAdapter *adapter = LibCecInit("MythTV", list);
     74        libcec_configuration configuration;
     75        configuration.Clear();
     76        snprintf(configuration.strDeviceName, 13, "MythTV");
     77        ICECAdapter *adapter = LibCecInitialise(&configuration);
    7678        if (!adapter)
    7779            return results;
    7880        cec_adapter *devices = new cec_adapter[MAX_CEC_DEVICES];
    7981        uint8_t num_devices = adapter->FindAdapters(devices, MAX_CEC_DEVICES, NULL);
     82        LOG(VB_GENERAL, LOG_INFO, LOC + QString("GetDeviceList() found %1 devices(s).")
     83            .arg(num_devices));
    8084        if (num_devices < 1)
    8185            return results;
    8286        for (uint8_t i = 0; i < num_devices; i++)
    class CECAdapterPriv 
    8993    {
    9094        // get settings
    9195        // N.B. these do not currently work as there is no UI
     96
     97        // There is no way current CEC adapters can find their physical address
     98        // on their own. The are only connected to the CEC pin of the HDMI connector.
     99        // To construct a valid physical address libCEC needs:
     100        // - the HDMI port (number) Myth is connected to
     101        // - the HDMI device (TV, Receiver) Myth is connected to (the logical address)
     102
     103        //The CEC adapter we want to connect to
    92104        defaultDevice     = gCoreContext->GetSetting(LIBCEC_DEVICE, "auto").trimmed();
     105        // The number of the HDMI port Myth is connected to
    93106        QString hdmi_port = gCoreContext->GetSetting(LIBCEC_PORT, "auto");
     107        // The logical address of the HDMI device Myth is connected to
     108        // TODO
     109        // Logical address we want Myth to use
    94110        QString device_id = gCoreContext->GetSetting(LIBCEC_DEVICEID, "auto");
    95111        powerOffTVAllowed = (bool)gCoreContext->GetNumSetting(POWEROFFTV_ALLOWED, 1);
    96112        powerOffTVOnExit  = (bool)gCoreContext->GetNumSetting(POWEROFFTV_ONEXIT, 1);
    97113        powerOnTVAllowed  = (bool)gCoreContext->GetNumSetting(POWERONTV_ALLOWED, 1);
    98114        powerOnTVOnStart  = (bool)gCoreContext->GetNumSetting(POWERONTV_ONSTART, 1);
    99115
    100         defaultHDMIPort = 1;
    101116        if ("auto" != hdmi_port)
    102117        {
    103118            defaultHDMIPort = hdmi_port.toInt();
    104             if (defaultHDMIPort < 1 || defaultHDMIPort > 3)
    105                 defaultHDMIPort = 1;
     119            if (defaultHDMIPort < CEC_MIN_HDMI_PORTNUMBER || defaultHDMIPort > CEC_MAX_HDMI_PORTNUMBER)
     120                defaultHDMIPort = CEC_MIN_HDMI_PORTNUMBER;
     121        }
     122        else
     123        {
     124            defaultHDMIPort = CEC_MIN_HDMI_PORTNUMBER;
    106125        }
    107         defaultHDMIPort = defaultHDMIPort << 12;
    108126
    109         defaultDeviceID = CECDEVICE_PLAYBACKDEVICE1;
    110127        if ("auto" != device_id)
    111128        {
    112129            int id = device_id.toInt();
    113             if (id < 1 || id > 3)
    114                 id = 1;
    115             defaultDeviceID = (id == 1) ? CECDEVICE_PLAYBACKDEVICE1 :
    116                              ((id == 2) ? CECDEVICE_PLAYBACKDEVICE2 :
    117                                           CECDEVICE_PLAYBACKDEVICE3);
     130            switch (id)
     131            {
     132                case CEC_DEVICE_TYPE_TV:
     133                case CEC_DEVICE_TYPE_RECORDING_DEVICE:
     134                case CEC_DEVICE_TYPE_RESERVED:
     135                case CEC_DEVICE_TYPE_TUNER:
     136                case CEC_DEVICE_TYPE_PLAYBACK_DEVICE:
     137                case CEC_DEVICE_TYPE_AUDIO_SYSTEM:
     138                    defaultDeviceID = (cec_device_type)id;
     139                    break;
     140                default:
     141                    defaultDeviceID = CEC_DEVICE_TYPE_PLAYBACK_DEVICE;
     142                    break;
     143            }
     144        }
     145        else
     146        {
     147            defaultDeviceID = CEC_DEVICE_TYPE_PLAYBACK_DEVICE;
     148        }
     149
     150        device_id = "auto"; //TODO
     151        if ("auto" == device_id)
     152        {
     153            base_device = (cec_logical_address)CEC_DEFAULT_BASE_DEVICE;
    118154        }
     155        else
     156        {
     157            base_device = (cec_logical_address)device_id.toInt();
     158            switch (base_device)
     159            {
     160                case CECDEVICE_UNKNOWN:
     161                case CECDEVICE_RESERVED1:
     162                case CECDEVICE_RESERVED2:
     163                case CECDEVICE_BROADCAST:
     164                default:
     165                    base_device = (cec_logical_address)CEC_DEFAULT_BASE_DEVICE;
     166                    break;
     167                case CECDEVICE_TV:
     168                case CECDEVICE_RECORDINGDEVICE1:
     169                case CECDEVICE_RECORDINGDEVICE2:
     170                case CECDEVICE_TUNER1:
     171                case CECDEVICE_PLAYBACKDEVICE1:
     172                case CECDEVICE_AUDIOSYSTEM:
     173                case CECDEVICE_TUNER2:
     174                case CECDEVICE_TUNER3:
     175                case CECDEVICE_PLAYBACKDEVICE2:
     176                case CECDEVICE_RECORDINGDEVICE3:
     177                case CECDEVICE_TUNER4:
     178                case CECDEVICE_PLAYBACKDEVICE3:
     179                case CECDEVICE_FREEUSE:
     180                    break;
     181            }
     182        }
     183 
     184        configuration.Clear();
     185        configuration.clientVersion = LIBCEC_VERSION_CURRENT;
     186        snprintf(configuration.strDeviceName, 13, "MythTV");
     187        configuration.deviceTypes.Add(defaultDeviceID);
     188        configuration.iHDMIPort = defaultHDMIPort;
     189        LOG(VB_GENERAL, LOG_INFO, LOC + QString("using HDMI port %1.")
     190            .arg(defaultHDMIPort));
     191        configuration.baseDevice = base_device;
     192        LOG(VB_GENERAL, LOG_INFO, LOC + QString("using base device %1.")
     193            .arg(configuration.baseDevice));
     194
     195        callbacks.Clear();
     196        callbacks.CBCecLogMessage  = LogMessages;
     197        callbacks.CBCecKeyPress    = HandleKeyPresses;
     198        callbacks.CBCecCommand     = HandleCommands;
     199        callbacks.CBCecAlert       = CecAlert;
     200        configuration.callbacks    = &callbacks;
    119201
    120202        // create adapter interface
    121         cec_device_type_list list;
    122         list.Clear();
    123         list.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
    124         adapter = LibCecInit("MythTV", list);
     203        ICECAdapter *adapter = LibCecInitialise(&configuration);
    125204
    126205        if (!adapter)
    127206        {
    class CECAdapterPriv 
    129208            return false;
    130209        }
    131210
    132         if (adapter->GetMinLibVersion() > MIN_LIBCEC_VERSION)
     211        if ((configuration.serverVersion >> 12) > CEC_MIN_LIB_VERSION)
    133212        {
    134213            LOG(VB_GENERAL, LOG_ERR, LOC +
    135214                QString("The installed libCEC supports version %1 and above. "
    136215                        "This version of MythTV only supports version %2.")
    137                 .arg(adapter->GetMinLibVersion()).arg(MIN_LIBCEC_VERSION));
    138             return false;
     216                .arg(configuration.serverVersion).arg(CEC_MIN_LIB_VERSION));
     217            // return false;
    139218        }
    140219
    141220        // find adapters
    class CECAdapterPriv 
    185264        // get the vendor ID (for non-standard implementations)
    186265        adapter->GetDeviceVendorId(CECDEVICE_TV);
    187266
    188         // set the physical address
    189         adapter->SetPhysicalAddress(defaultHDMIPort);
    190 
    191         // set the logical address
    192         adapter->SetLogicalAddress(defaultDeviceID);
    193 
    194267        // switch input (if configured)
    195268        switchInput = true;
    196269        HandleActions();
    class CECAdapterPriv 
    210283
    211284            // delete adapter
    212285            adapter->Close();
    213             LogMessages();
    214286            UnloadLibCec(adapter);
    215287
    216288            LOG(VB_GENERAL, LOG_INFO, LOC + "Closing down CEC.");
    class CECAdapterPriv 
    218290        valid = false;
    219291        adapter = NULL;
    220292    }
    221 
    222     void LogMessages(void)
     293    #if CEC_LIB_VERSION_MAJOR < 2
     294    static int LogMessages(void * /*cbParam*/, const cec_log_message &message)
     295    #else
     296    static int LogMessages(void * /*cbParam*/, const cec_log_message message)
     297    #endif
    223298    {
    224         if (!adapter || !valid)
    225             return;
    226 
    227         cec_log_message message;
    228         while (adapter->GetNextLogMessage(&message))
    229         {
    230299            QString msg(message.message);
    231300            int lvl = LOG_UNKNOWN;
    232301            switch (message.level)
    class CECAdapterPriv 
    237306            case CEC_LOG_DEBUG:   lvl = LOG_DEBUG;   break;
    238307            }
    239308            LOG(VB_GENERAL, lvl, LOC + QString("%1").arg(msg));
    240         }
     309            return 0;
    241310    }
    242311
    243     void HandleCommands(void)
     312    #if CEC_LIB_VERSION_MAJOR < 2
     313    static int HandleCommands(void * /*cbParam*/, const cec_command &command)
     314    #else
     315    static int HandleCommands(void * /*cbParam*/, const cec_command command)
     316    #endif
    244317    {
    245         if (!adapter || !valid)
    246             return;
    247 
    248         LogMessages();
    249 
    250         cec_command command;
    251         while (adapter->GetNextCommand(&command))
    252         {
    253318            LOG(VB_GENERAL, LOG_DEBUG, LOC +
    254319                QString("Command %1 from '%2' (%3) - destination '%4' (%5)")
    255320                .arg(command.opcode)
    class CECAdapterPriv 
    264329                default:
    265330                    break;
    266331            }
     332            return 0;
     333    }
     334    #if CEC_LIB_VERSION_MAJOR < 2
     335    static int CecAlert(void * /*cbParam*/, const libcec_alert type, const libcec_parameter & /*param*/)
     336    #else
     337    static int CecAlert(void * /*cbParam*/, const libcec_alert type, const libcec_parameter /*param*/)
     338    #endif
     339    {
     340        switch (type)
     341        {
     342        case CEC_ALERT_CONNECTION_LOST:
     343          LOG(VB_GENERAL, LOG_ERR, LOC + "Connection lost - TODO: need to handle this!");
     344          break;
     345        default:
     346          LOG(VB_GENERAL, LOG_ERR, LOC + "Received unknown alert.");
     347          break;
    267348        }
    268 
    269         LogMessages();
     349        return 0;
    270350    }
    271351
    272     void HandleKeyPresses(void)
     352    #if CEC_LIB_VERSION_MAJOR < 2
     353    static int HandleKeyPresses(void * /*cbParam*/, const cec_keypress &key)
     354    #else
     355    static int HandleKeyPresses(void * /*cbParam*/, const cec_keypress key)
     356    #endif
    273357    {
    274         if (!adapter || !valid)
    275             return;
    276 
    277         cec_keypress key;
    278         if (!adapter->GetNextKeypress(&key))
    279             return;
    280 
    281358        // Ignore key down events and wait for the key 'up'
    282359        if (key.duration < 1)
    283             return;
     360            return 0;
    284361
    285362        QString code;
    286363        int action = 0;
    class CECAdapterPriv 
    595672            .arg(code).arg(0 == action ? "(Not actioned)" : ""));
    596673
    597674        if (0 == action)
    598             return;
     675            return 0;
    599676
    600677        GetMythUI()->ResetScreensaver();
    601678        QKeyEvent* ke = new QKeyEvent(QEvent::KeyPress, action, Qt::NoModifier);
    602679        qApp->postEvent(GetMythMainWindow(), (QEvent*)ke);
    603 
    604         LogMessages();
     680        return 0;
    605681    }
    606682
    607683    void HandleActions(void)
    class CECAdapterPriv 
    629705        // HDMI input
    630706        if (switchInput && switchInputAllowed)
    631707        {
    632             if (adapter->SetActiveView())
     708            if (adapter->SetActiveSource())
    633709                LOG(VB_GENERAL, LOG_INFO, LOC + "Asked TV to switch to this input.");
    634710            else
    635711                LOG(VB_GENERAL, LOG_ERR,  LOC + "Failed to switch to this input.");
    class CECAdapterPriv 
    638714        powerOffTV  = false;
    639715        powerOnTV   = false;
    640716        switchInput = false;
    641 
    642         LogMessages();
    643717    }
    644718
    645719    ICECAdapter *adapter;
     720    ICECCallbacks        callbacks;
     721    libcec_configuration configuration;
    646722    QString      defaultDevice;
    647723    int          defaultHDMIPort;
    648     cec_logical_address defaultDeviceID;
     724    cec_device_type defaultDeviceID;
    649725    QTimer      *timer;
    650726    bool         valid;
    651727    bool         powerOffTV;
    class CECAdapterPriv 
    656732    bool         powerOnTVOnStart;
    657733    bool         switchInput;
    658734    bool         switchInputAllowed;
     735    cec_logical_address base_device;
    659736};
    660737
    661738QStringList CECAdapter::GetDeviceList(void)
    void CECAdapter::Action(const QString &action) 
    728805void CECAdapter::Process(void)
    729806{
    730807    gLock->lock();
    731     m_priv->HandleCommands();
    732     m_priv->HandleKeyPresses();
    733808    m_priv->HandleActions();
    734809    gLock->unlock();
    735810}