[directfb] Make QDirectFBInput a QThread to allow proper exits

Without this patch the application will get stuck waiting for the
IDFBEventBuffer to report an event. We will use the
IDFBEventBuffer::WakeUp function to interrupt the waiting but this
produces the below error on exit:
QEventLoop: Cannot be used without QApplication
QThread: Destroyed while thread is still running

This is solved by making the QDirectFBInput a QThread, reimplement
the run() method to handle the events. It should work as this is
only posting events to the QApplication event loop.

Change-Id: I24adf2b080f96c72ede6a5499f484ac33fdd44fc
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
This commit is contained in:
Holger Hans Peter Freyther 2011-09-19 00:11:24 +02:00 committed by Qt by Nokia
parent acd09c21f7
commit 405894fc39
3 changed files with 18 additions and 29 deletions

View File

@ -50,35 +50,29 @@
#include <directfb.h>
QDirectFbInput::QDirectFbInput(QObject *parent)
: QObject(parent), m_shouldStop(false)
QDirectFbInput::QDirectFbInput()
: m_dfbInterface(QDirectFbConvenience::dfbInterface())
, m_shouldStop(false)
{
m_dfbInterface = QDirectFbConvenience::dfbInterface();
DFBResult ok = m_dfbInterface->CreateEventBuffer(m_dfbInterface,&m_eventBuffer);
if (ok != DFB_OK)
DirectFBError("Failed to initialise eventbuffer", ok);
m_dfbInterface->GetDisplayLayer(m_dfbInterface,DLID_PRIMARY, &m_dfbDisplayLayer);
}
void QDirectFbInput::runInputEventLoop()
void QDirectFbInput::run()
{
while (true) {
m_eventBuffer->WaitForEvent(m_eventBuffer);
if (m_shouldStop) {
m_waitStop.release();
break;
}
handleEvents();
while (!m_shouldStop) {
if (m_eventBuffer->WaitForEvent(m_eventBuffer) == DFB_OK)
handleEvents();
}
}
void QDirectFbInput::stopInputEventLoop()
{
m_shouldStop = true;
m_waitStop.acquire();
m_eventBuffer->WakeUp(m_eventBuffer);
}
void QDirectFbInput::addWindow(DFBWindowID id, QWindow *qt_window)

View File

@ -42,8 +42,7 @@
#ifndef QDIRECTFBINPUT_H
#define QDIRECTFBINPUT_H
#include <QSemaphore>
#include <QObject>
#include <QThread>
#include <QHash>
#include <QPoint>
#include <QEvent>
@ -52,20 +51,21 @@
#include <directfb.h>
class QDirectFbInput : public QObject
class QDirectFbInput : public QThread
{
Q_OBJECT
public:
QDirectFbInput(QObject *parent);
QDirectFbInput();
void addWindow(DFBWindowID id, QWindow *window);
void removeWindow(WId wId);
public slots:
void runInputEventLoop();
void stopInputEventLoop();
void handleEvents();
protected:
void run();
private:
void handleEvents();
void handleMouseEvents(const DFBEvent &event);
void handleWheelEvent(const DFBEvent &event);
void handleKeyEvents(const DFBEvent &event);
@ -78,8 +78,6 @@ private:
IDirectFBEventBuffer *m_eventBuffer; // XXX: TODO: FIXME: leaked!!! (but it is a singleton)
bool m_shouldStop;
QSemaphore m_waitStop;
QHash<DFBWindowID,QWindow *>m_tlwMap;
};

View File

@ -106,17 +106,14 @@ QDirectFbIntegration::QDirectFbIntegration()
QDirectFbScreen *primaryScreen = new QDirectFbScreen(0);
screenAdded(primaryScreen);
m_inputRunner.reset(new QThread);
m_input.reset(new QDirectFbInput(0));
m_input->moveToThread(m_inputRunner.data());
QObject::connect(m_inputRunner.data(), SIGNAL(started()),
m_input.data(), SLOT(runInputEventLoop()));
m_inputRunner->start();
m_input.reset(new QDirectFbInput());
m_input->start();
}
QDirectFbIntegration::~QDirectFbIntegration()
{
m_input->stopInputEventLoop();
m_input->wait();
}
QPlatformPixmap *QDirectFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const