Ticket #11338: libcec2.patch

File libcec2.patch, 21.4 KB (added by bbaetz@…, 8 years ago)

Updated patch

  • mythtv/configure

    diff --git a/mythtv/configure b/mythtv/configure
    index 519d352..aa086c5 100755
    a b int main(void) { 
    54775477    if (CEC_LIB_VERSION_MAJOR < 1 || (CEC_LIB_VERSION_MAJOR == 1 &&
    54785478                                      CEC_LIB_VERSION_MINOR < 5))
    54795479        return 0;
    5480     return (long) LibCecInit;
     5480    return 1;
    54815481}
    54825482EOF
    54835483fi
  • mythtv/libs/libmythui/cecadapter.cpp

    diff --git a/mythtv/libs/libmythui/cecadapter.cpp b/mythtv/libs/libmythui/cecadapter.cpp
    index edad8f6..61ffb72 100644
    a b  
    11// Qt
    22#include <QApplication>
    3 #include <QTimer>
    43#include <QKeyEvent>
    54#include <QString>
    65
     
    1413#include "cecadapter.h"
    1514#include <vector>
    1615
    17 #define MIN_LIBCEC_VERSION 1
    1816#define MAX_CEC_DEVICES 10
    1917#define LOC QString("CECAdapter: ")
    2018
    using namespace CEC; 
    2422using namespace std;
    2523#include <libcec/cecloader.h>
    2624
    27 QMutex* CECAdapter::gLock = new QMutex(QMutex::Recursive);
     25QMutex*         CECAdapter::gLock = new QMutex(QMutex::Recursive);
     26QMutex*         CECAdapter::gHandleActionsLock = new QMutex();
     27QWaitCondition* CECAdapter::gActionsReady = new QWaitCondition();
     28
     29#if CEC_LIB_VERSION_MAJOR < 2
     30// A few defines taken from libcec.h v2
     31#define CEC_MIN_HDMI_PORTNUMBER      1
     32#define CEC_MAX_HDMI_PORTNUMBER      15
     33// libcec1's callback parameters are pass-by-ref
     34#define CEC_CALLBACK_PARAM_TYPE &
     35#else
     36// libcec2's callback parameters are pass-by-value
     37#define CEC_CALLBACK_PARAM_TYPE
     38#endif
     39
     40// The libCEC callback functions
     41static int CECLogMessageCallback(void *adapter, const cec_log_message CEC_CALLBACK_PARAM_TYPE message);
     42static int CECKeyPressCallback(void *adapter, const cec_keypress CEC_CALLBACK_PARAM_TYPE keypress);
     43static int CECCommandCallback(void *adapter, const cec_command CEC_CALLBACK_PARAM_TYPE command);
     44
     45#if CEC_LIB_VERSION_MAJOR >= 2
     46static int CECAlertCallback(void *adapter, const libcec_alert alert, const libcec_parameter CEC_CALLBACK_PARAM_TYPE data);
     47static void CECSourceActivatedCallback(void *adapter, const cec_logical_address address, const uint8_t activated);
     48#endif
    2849
    2950class CECAdapterPriv
    3051{
    3152  public:
    3253    CECAdapterPriv()
    33       : adapter(NULL), defaultDevice("auto"), defaultHDMIPort(1),
    34         defaultDeviceID(CECDEVICE_PLAYBACKDEVICE1), timer(NULL), valid(false),
     54      : adapter(NULL), valid(false),
    3555        powerOffTV(false),  powerOffTVAllowed(false), powerOffTVOnExit(false),
    3656        powerOnTV(false),   powerOnTVAllowed(false),  powerOnTVOnStart(false),
    3757        switchInput(false), switchInputAllowed(true)
    3858    {
    39     }
    40 
    41     static QString addressToString(enum cec_logical_address addr, bool source)
    42     {
    43         switch (addr)
    44         {
    45             case CECDEVICE_UNKNOWN:          return QString("Unknown");
    46             case CECDEVICE_TV:               return QString("TV");
    47             case CECDEVICE_RECORDINGDEVICE1: return QString("RecordingDevice1");
    48             case CECDEVICE_RECORDINGDEVICE2: return QString("RecordingDevice2");
    49             case CECDEVICE_RECORDINGDEVICE3: return QString("RecordingDevice3");
    50             case CECDEVICE_TUNER1:           return QString("Tuner1");
    51             case CECDEVICE_TUNER2:           return QString("Tuner2");
    52             case CECDEVICE_TUNER3:           return QString("Tuner3");
    53             case CECDEVICE_TUNER4:           return QString("Tuner4");
    54             case CECDEVICE_PLAYBACKDEVICE1:  return QString("PlaybackDevice1");
    55             case CECDEVICE_PLAYBACKDEVICE2:  return QString("PlaybackDevice2");
    56             case CECDEVICE_PLAYBACKDEVICE3:  return QString("PlaybackDevice3");
    57             case CECDEVICE_AUDIOSYSTEM:      return QString("Audiosystem");
    58             case CECDEVICE_RESERVED1:        return QString("Reserved1");
    59             case CECDEVICE_RESERVED2:        return QString("Reserved2");
    60             case CECDEVICE_FREEUSE:          return QString("FreeUse");
    61             case CECDEVICE_UNREGISTERED:
    62             //case CECDEVICE_BROADCAST:
    63                 return source ? QString("Unregistered") : QString("Broadcast");
    64         }
    65         return QString("Invalid");
    66     }
    67 
    68     // N.B. This may need revisiting when the UI is added
    69     static QStringList GetDeviceList(void)
    70     {
    71         QStringList results;
    72         cec_device_type_list list;
    73         list.Clear();
    74         list.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
    75         ICECAdapter *adapter = LibCecInit("MythTV", list);
    76         if (!adapter)
    77             return results;
    78         cec_adapter *devices = new cec_adapter[MAX_CEC_DEVICES];
    79         uint8_t num_devices = adapter->FindAdapters(devices, MAX_CEC_DEVICES, NULL);
    80         if (num_devices < 1)
    81             return results;
    82         for (uint8_t i = 0; i < num_devices; i++)
    83             results << QString::fromAscii(devices[i].comm);
    84         UnloadLibCec(adapter);
    85         return results;
     59#if CEC_LIB_VERSION_MAJOR < 2
     60        // libcec1 has this as a POD struct, with no
     61        // automatic initialisation.
     62        // And no .Clear() method...
     63        memset(&callbacks, 0, sizeof(callbacks));
     64#endif
    8665    }
    8766
    8867    bool Open(void)
    8968    {
    9069        // get settings
    91         // N.B. these do not currently work as there is no UI
    92         defaultDevice     = gCoreContext->GetSetting(LIBCEC_DEVICE, "auto").trimmed();
    93         QString hdmi_port = gCoreContext->GetSetting(LIBCEC_PORT, "auto");
    94         QString device_id = gCoreContext->GetSetting(LIBCEC_DEVICEID, "auto");
     70        // N.B. these need to be set manually since there is no UI
     71        QString defaultDevice   = gCoreContext->GetSetting(LIBCEC_DEVICE, "auto").trimmed();
     72        // Note - if libcec supports automatic detection via EDID then
     73        // these settings are not used
     74        // The logical address of the HDMI device Myth is connected to
     75        QString base_dev        = gCoreContext->GetSetting(LIBCEC_BASE, "auto").trimmed();
     76        // The number of the HDMI port Myth is connected to
     77        QString hdmi_port       = gCoreContext->GetSetting(LIBCEC_PORT, "auto").trimmed();
     78
    9579        powerOffTVAllowed = (bool)gCoreContext->GetNumSetting(POWEROFFTV_ALLOWED, 1);
    9680        powerOffTVOnExit  = (bool)gCoreContext->GetNumSetting(POWEROFFTV_ONEXIT, 1);
    9781        powerOnTVAllowed  = (bool)gCoreContext->GetNumSetting(POWERONTV_ALLOWED, 1);
    9882        powerOnTVOnStart  = (bool)gCoreContext->GetNumSetting(POWERONTV_ONSTART, 1);
    9983
    100         defaultHDMIPort = 1;
    101         if ("auto" != hdmi_port)
     84        // create adapter interface
     85        libcec_configuration configuration;
     86#if CEC_LIB_VERSION_MAJOR < 2
     87        // libcec1 has this as a POD struct, with no
     88        // automatic initialisation
     89        configuration.Clear();
     90#endif
     91        strcpy(configuration.strDeviceName, "MythTV");
     92        configuration.deviceTypes.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
     93
     94        if ("auto" != base_dev)
    10295        {
    103             defaultHDMIPort = hdmi_port.toInt();
    104             if (defaultHDMIPort < 1 || defaultHDMIPort > 3)
    105                 defaultHDMIPort = 1;
     96            int base = base_dev.toInt();
     97            if (base >= 0 && base < CECDEVICE_BROADCAST) {
     98                configuration.baseDevice = (cec_logical_address)base;
     99            }
    106100        }
    107         defaultHDMIPort = defaultHDMIPort << 12;
    108101
    109         defaultDeviceID = CECDEVICE_PLAYBACKDEVICE1;
    110         if ("auto" != device_id)
     102        if ("auto" != hdmi_port)
    111103        {
    112             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);
     104            int defaultHDMIPort = hdmi_port.toInt();
     105            if (defaultHDMIPort >= CEC_MIN_HDMI_PORTNUMBER && defaultHDMIPort <= CEC_MAX_HDMI_PORTNUMBER) {
     106                configuration.iHDMIPort = defaultHDMIPort;
     107            }
    118108        }
    119109
    120         // 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);
     110        // Set up the callbacks
     111        callbacks.CBCecLogMessage = &CECLogMessageCallback;
     112        callbacks.CBCecKeyPress   = &CECKeyPressCallback;
     113        callbacks.CBCecCommand    = &CECCommandCallback;
     114#if CEC_LIB_VERSION_MAJOR >= 2
     115        callbacks.CBCecAlert      = &CECAlertCallback;
     116        callbacks.CBCecSourceActivated = &CECSourceActivatedCallback;
     117#endif
     118        configuration.callbackParam = this;
     119        configuration.callbacks = &callbacks;
     120
     121        // and initialise
     122        adapter = LibCecInitialise(&configuration);
    125123
    126124        if (!adapter)
    127125        {
    class CECAdapterPriv 
    129127            return false;
    130128        }
    131129
    132         if (adapter->GetMinLibVersion() > MIN_LIBCEC_VERSION)
    133         {
    134             LOG(VB_GENERAL, LOG_ERR, LOC +
    135                 QString("The installed libCEC supports version %1 and above. "
    136                         "This version of MythTV only supports version %2.")
    137                 .arg(adapter->GetMinLibVersion()).arg(MIN_LIBCEC_VERSION));
    138             return false;
    139         }
    140 
    141130        // find adapters
    142131        cec_adapter *devices = new cec_adapter[MAX_CEC_DEVICES];
    143132        uint8_t num_devices = adapter->FindAdapters(devices, MAX_CEC_DEVICES, NULL);
    class CECAdapterPriv 
    178167
    179168        LOG(VB_GENERAL, LOG_INFO, LOC + "Opened CEC device.");
    180169
     170        // all good to go
     171        valid = true;
     172
    181173        // turn on tv (if configured)
    182174        powerOnTV = powerOnTVOnStart;
    183         HandleActions();
    184 
    185         // get the vendor ID (for non-standard implementations)
    186         adapter->GetDeviceVendorId(CECDEVICE_TV);
    187 
    188         // set the physical address
    189         adapter->SetPhysicalAddress(defaultHDMIPort);
    190 
    191         // set the logical address
    192         adapter->SetLogicalAddress(defaultDeviceID);
    193175
    194176        // switch input (if configured)
    195177        switchInput = true;
     178
    196179        HandleActions();
    197180
    198         valid = true;
    199181        return true;
    200182    }
    201183
    class CECAdapterPriv 
    210192
    211193            // delete adapter
    212194            adapter->Close();
    213             LogMessages();
    214195            UnloadLibCec(adapter);
    215196
    216197            LOG(VB_GENERAL, LOG_INFO, LOC + "Closing down CEC.");
    class CECAdapterPriv 
    219200        adapter = NULL;
    220201    }
    221202
    222     void LogMessages(void)
     203    int LogMessage(const cec_log_message &message)
    223204    {
    224         if (!adapter || !valid)
    225             return;
    226 
    227         cec_log_message message;
    228         while (adapter->GetNextLogMessage(&message))
     205        QString msg(message.message);
     206        int lvl = LOG_UNKNOWN;
     207        switch (message.level)
    229208        {
    230             QString msg(message.message);
    231             int lvl = LOG_UNKNOWN;
    232             switch (message.level)
    233             {
    234209            case CEC_LOG_ERROR:   lvl = LOG_ERR;     break;
    235210            case CEC_LOG_WARNING: lvl = LOG_WARNING; break;
    236211            case CEC_LOG_NOTICE:  lvl = LOG_INFO;    break;
    237212            case CEC_LOG_DEBUG:   lvl = LOG_DEBUG;   break;
    238             }
    239             LOG(VB_GENERAL, lvl, LOC + QString("%1").arg(msg));
    240213        }
     214        LOG(VB_GENERAL, lvl, LOC + QString("%1").arg(msg));
     215        return 1;
    241216    }
    242217
    243     void HandleCommands(void)
     218    // NOTE - libcec2 changes the callbacks
     219    // to be pass-by-value.
     220    // For simplicity, this function remains as pass-by-ref
     221    int HandleCommand(const cec_command &command)
    244222    {
    245223        if (!adapter || !valid)
    246             return;
     224            return 0;
    247225
    248         LogMessages();
     226        LOG(VB_GENERAL, LOG_DEBUG, LOC +
     227            QString("Command %1 from '%2' (%3) - destination '%4' (%5)")
     228            .arg(command.opcode)
     229            .arg(adapter->ToString(command.initiator))
     230            .arg(command.initiator)
     231            .arg(adapter->ToString(command.destination))
     232            .arg(command.destination));
    249233
    250         cec_command command;
    251         while (adapter->GetNextCommand(&command))
     234        switch (command.opcode)
    252235        {
    253             LOG(VB_GENERAL, LOG_DEBUG, LOC +
    254                 QString("Command %1 from '%2' (%3) - destination '%4' (%5)")
    255                 .arg(command.opcode)
    256                 .arg(addressToString(command.initiator, true))
    257                 .arg(command.initiator)
    258                 .arg(addressToString(command.destination, false))
    259                 .arg(command.destination));
    260 
    261             switch (command.opcode)
    262             {
    263                 // TODO
    264                 default:
    265                     break;
    266             }
     236            // TODO
     237            default:
     238                break;
    267239        }
    268 
    269         LogMessages();
     240        return 1;
    270241    }
    271242
    272     void HandleKeyPresses(void)
     243    int HandleKeyPress(const cec_keypress &key)
    273244    {
    274245        if (!adapter || !valid)
    275             return;
    276 
    277         cec_keypress key;
    278         if (!adapter->GetNextKeypress(&key))
    279             return;
     246            return 0;
    280247
    281248        // Ignore key down events and wait for the key 'up'
    282249        if (key.duration < 1)
    283             return;
     250            return 1;
    284251
    285252        QString code;
    286253        int action = 0;
    class CECAdapterPriv 
    595562            .arg(code).arg(0 == action ? "(Not actioned)" : ""));
    596563
    597564        if (0 == action)
    598             return;
     565            return 1;
    599566
    600567        GetMythUI()->ResetScreensaver();
    601568        QKeyEvent* ke = new QKeyEvent(QEvent::KeyPress, action, Qt::NoModifier);
    602569        qApp->postEvent(GetMythMainWindow(), (QEvent*)ke);
    603570
    604         LogMessages();
     571        return 1;
    605572    }
    606573
     574#if CEC_LIB_VERSION_MAJOR >= 2
     575    int HandleAlert(const libcec_alert alert, const libcec_parameter &data)
     576    {
     577        // These aren't handled yet
     578        // Note that we *DON'T* want to just show these
     579        // to the user in a popup, because some (eg prompting about firmware
     580        // upgrades) aren't appropriate.
     581        // Ideally we'd try to handle this, eg by reopening the adapter
     582        // in a separate thread if it lost the connection....
     583
     584        QString param;
     585        switch (data.paramType)
     586        {
     587            case CEC_PARAMETER_TYPE_STRING:
     588                param = QString(": %1").arg((char*)data.paramData);
     589                break;
     590            case CEC_PARAMETER_TYPE_UNKOWN: /* libcec typo */
     591            default:
     592                if (data.paramData != NULL)
     593                {
     594                    param = QString(": UNKNOWN param has type %1").arg(data.paramType);
     595                }
     596                break;
     597        }
     598
     599        // There is no ToString method for libcec_alert...
     600        // Plus libcec adds new values in minor releases (eg 2.1.1)
     601        // but doesn't provide a #define for the last digit...
     602        // Besides, it makes sense to do this, since we could be compiling
     603        // against an older version than we're running against
     604#if CEC_LIB_VERSION_MAJOR == 2 && CEC_LIB_VERSION_MINOR < 1
     605// since 2.0.4
     606#define CEC_ALERT_PHYSICAL_ADDRESS_ERROR        4
     607#endif
     608#if CEC_LIB_VERSION_MAJOR == 2 && CEC_LIB_VERSION_MINOR < 2
     609// since 2.1.1
     610#define CEC_ALERT_TV_POLL_FAILED                5
     611#endif
     612        switch (alert)
     613        {
     614            case CEC_ALERT_SERVICE_DEVICE:
     615                LOG(VB_GENERAL, LOG_INFO, LOC + QString("CEC device service message") + param);
     616                break;
     617            case CEC_ALERT_CONNECTION_LOST:
     618                LOG(VB_GENERAL, LOG_ERR, LOC + QString("CEC device connection list") + param);
     619                break;
     620            case CEC_ALERT_PERMISSION_ERROR:
     621            case CEC_ALERT_PORT_BUSY:
     622                /* Don't log due to possible false positives on the initial
     623                 * open. libcec will log via the logging callback anyway
     624                 */
     625                break;
     626            case CEC_ALERT_PHYSICAL_ADDRESS_ERROR:
     627                LOG(VB_GENERAL, LOG_ERR, LOC + QString("CEC physical address error") + param);
     628                break;
     629            case CEC_ALERT_TV_POLL_FAILED:
     630                LOG(VB_GENERAL, LOG_WARNING, LOC + QString("CEC device can't poll TV") + param);
     631                break;
     632            default:
     633                LOG(VB_GENERAL, LOG_WARNING, LOC + QString("UNKNOWN CEC device alert %1").arg(alert) + param);
     634                break;
     635        }
     636
     637        return 1;
     638    }
     639
     640    void HandleSourceActivated(const cec_logical_address address, const uint8_t activated)
     641    {
     642        if (!adapter || !valid)
     643            return;
     644
     645        LOG(VB_GENERAL, LOG_INFO, LOC + QString("Source %1 %2").arg(adapter->ToString(address)).arg(activated ? "Activated" : "Deactivated"));
     646
     647        if (activated)
     648            GetMythUI()->ResetScreensaver();
     649    }
     650#endif
     651
     652    ICECAdapter *adapter;
    607653    void HandleActions(void)
    608654    {
    609655        if (!adapter || !valid)
    class CECAdapterPriv 
    629675        // HDMI input
    630676        if (switchInput && switchInputAllowed)
    631677        {
    632             if (adapter->SetActiveView())
     678            if (adapter->SetActiveSource())
    633679                LOG(VB_GENERAL, LOG_INFO, LOC + "Asked TV to switch to this input.");
    634680            else
    635681                LOG(VB_GENERAL, LOG_ERR,  LOC + "Failed to switch to this input.");
    class CECAdapterPriv 
    638684        powerOffTV  = false;
    639685        powerOnTV   = false;
    640686        switchInput = false;
    641 
    642         LogMessages();
    643687    }
    644688
    645     ICECAdapter *adapter;
    646     QString      defaultDevice;
    647     int          defaultHDMIPort;
    648     cec_logical_address defaultDeviceID;
    649     QTimer      *timer;
     689    ICECCallbacks callbacks;
    650690    bool         valid;
    651691    bool         powerOffTV;
    652692    bool         powerOffTVAllowed;
    class CECAdapterPriv 
    658698    bool         switchInputAllowed;
    659699};
    660700
    661 QStringList CECAdapter::GetDeviceList(void)
    662 {
    663     QMutexLocker lock(gLock);
    664     return CECAdapterPriv::GetDeviceList();
    665 }
    666 
    667701CECAdapter::CECAdapter() : MThread("CECAdapter"), m_priv(new CECAdapterPriv)
    668702{
    669703    QMutexLocker lock(gLock);
    CECAdapter::CECAdapter() : MThread("CECAdapter"), m_priv(new CECAdapterPriv) 
    679713    if (!m_priv->Open())
    680714        return;
    681715
    682     // create process timer
    683     m_priv->timer = new QTimer(this);
    684     QObject::connect(m_priv->timer, SIGNAL(timeout()), this, SLOT(Process()));
    685     m_priv->timer->start(10);
    686 
    687716    // start thread
    688717    LOG(VB_GENERAL, LOG_DEBUG, LOC + "Starting thread.");
    689718    start();
    690719}
    691720
     721void CECAdapter::run()
     722{
     723    for (;;) {
     724        // Note that a lock is used because the QWaitCondition needs it
     725        // None of the other HandleActions callers need the lock because
     726        // they call HandleActions at open/close time, when
     727        // nothing else can be calling it....
     728        gHandleActionsLock->lock();
     729        gActionsReady->wait(gHandleActionsLock);
     730        m_priv->HandleActions();
     731        gHandleActionsLock->unlock();
     732    }
     733}
     734
    692735CECAdapter::~CECAdapter()
    693736{
    694737    QMutexLocker lock(gLock);
    695738
    696     // delete process timer
    697     if (m_priv->timer)
    698         m_priv->timer->stop();
    699     delete m_priv->timer;
    700     m_priv->timer = NULL;
    701 
    702739    // stop thread
    703740    if (isRunning())
    704741    {
    void CECAdapter::Action(const QString &action) 
    723760        m_priv->powerOnTV = true;
    724761    else if (ACTION_TVPOWEROFF == action)
    725762        m_priv->powerOffTV = true;
     763        gActionsReady->wakeAll();
     764}
     765
     766static int CECLogMessageCallback(void *adapter, const cec_log_message CEC_CALLBACK_PARAM_TYPE message)
     767{
     768    return ((CECAdapterPriv*)adapter)->LogMessage(message);
     769}
     770
     771static int CECKeyPressCallback(void *adapter, const cec_keypress CEC_CALLBACK_PARAM_TYPE keypress)
     772{
     773    return ((CECAdapterPriv*)adapter)->HandleKeyPress(keypress);
     774}
     775
     776static int CECCommandCallback(void *adapter, const cec_command CEC_CALLBACK_PARAM_TYPE command)
     777{
     778    return ((CECAdapterPriv*)adapter)->HandleCommand(command);
     779}
     780
     781#if CEC_LIB_VERSION_MAJOR >= 2
     782static int CECAlertCallback(void *adapter, const libcec_alert alert, const libcec_parameter CEC_CALLBACK_PARAM_TYPE data)
     783{
     784    return ((CECAdapterPriv*)adapter)->HandleAlert(alert, data);
    726785}
    727786
    728 void CECAdapter::Process(void)
     787static void CECSourceActivatedCallback(void *adapter, const cec_logical_address address, const uint8_t activated)
    729788{
    730     gLock->lock();
    731     m_priv->HandleCommands();
    732     m_priv->HandleKeyPresses();
    733     m_priv->HandleActions();
    734     gLock->unlock();
     789    ((CECAdapterPriv*)adapter)->HandleSourceActivated(address, activated);
    735790}
     791#endif
  • mythtv/libs/libmythui/cecadapter.h

    diff --git a/mythtv/libs/libmythui/cecadapter.h b/mythtv/libs/libmythui/cecadapter.h
    index e9cf6d6..06e55d2 100644
    a b  
    22#define CECADAPTER_H_
    33
    44#include <QMutex>
     5#include <QWaitCondition>
    56#include "mthread.h"
    67
    78#define LIBCEC_ENABLED     QString("libCECEnabled")
    89#define LIBCEC_DEVICE      QString("libCECDevice")
     10#define LIBCEC_BASE        QString("libCECBase")
    911#define LIBCEC_PORT        QString("libCECPort")
    10 #define LIBCEC_DEVICEID    QString("libCECDeviceID")
    1112#define POWEROFFTV_ALLOWED QString("PowerOffTVAllowed")
    1213#define POWEROFFTV_ONEXIT  QString("PowerOffTVOnExit")
    1314#define POWERONTV_ALLOWED  QString("PowerOnTVAllowed")
    class CECAdapter : public QObject, public MThread 
    2021  Q_OBJECT
    2122
    2223  public:
    23     static QStringList GetDeviceList(void);
    24 
    2524    CECAdapter();
    2625    virtual ~CECAdapter();
    2726    bool IsValid();
    2827    void Action(const QString &action);
    2928
    30   public slots:
    31     void Process();
     29  protected:
     30    virtual void run();
    3231
    3332  private:
    3433    CECAdapterPriv *m_priv;
    3534    static QMutex  *gLock;
     35    static QMutex  *gHandleActionsLock;
     36    static QWaitCondition *gActionsReady;
    3637};
    3738
    3839#endif