summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/eglfs
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/eglfs')
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pri2
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks_stub.cpp4
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks_x11.cpp160
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp4
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp8
5 files changed, 165 insertions, 13 deletions
diff --git a/src/plugins/platforms/eglfs/eglfs.pri b/src/plugins/platforms/eglfs/eglfs.pri
index eb66e17479..44455ed3d8 100644
--- a/src/plugins/platforms/eglfs/eglfs.pri
+++ b/src/plugins/platforms/eglfs/eglfs.pri
@@ -7,7 +7,7 @@ DEFINES += MESA_EGL_NO_X11_HEADERS
#To test the hooks on x11 (xlib), comment the above define too
#EGLFS_PLATFORM_HOOKS_SOURCES += qeglfshooks_x11.cpp
-#LIBS += -lX11
+#LIBS += -lX11 -lX11-xcb -lxcb
SOURCES += $$PWD/qeglfsintegration.cpp \
$$PWD/qeglfswindow.cpp \
diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
index 5c264834b3..91a97ff977 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
+++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qeglfshooks.h"
+#include "qeglfscursor.h"
#include <fcntl.h>
#include <unistd.h>
@@ -249,8 +250,7 @@ bool QEglFSHooks::hasCapability(QPlatformIntegration::Capability cap) const
QEglFSCursor *QEglFSHooks::createCursor(QEglFSScreen *screen) const
{
- Q_UNUSED(screen);
- return 0;
+ return new QEglFSCursor(screen);
}
void QEglFSHooks::waitForVSync() const
diff --git a/src/plugins/platforms/eglfs/qeglfshooks_x11.cpp b/src/plugins/platforms/eglfs/qeglfshooks_x11.cpp
index f44107e830..0d8be66438 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks_x11.cpp
+++ b/src/plugins/platforms/eglfs/qeglfshooks_x11.cpp
@@ -41,13 +41,36 @@
#include "qeglfshooks.h"
+#include <qpa/qwindowsysteminterface.h>
+#include <QThread>
+
#include <X11/Xlib.h>
+#include <X11/Xlib-xcb.h>
+#include <xcb/xcb.h>
QT_BEGIN_NAMESPACE
+class EventReader : public QThread
+{
+public:
+ EventReader(xcb_connection_t *connection)
+ : m_connection(connection)
+ {
+ }
+
+ void run();
+
+ xcb_connection_t *connection() { return m_connection; }
+
+private:
+ xcb_connection_t *m_connection;
+};
+
class QEglFSX11Hooks : public QEglFSHooks
{
public:
+ QEglFSX11Hooks() : m_eventReader(0) {}
+
virtual void platformInit();
virtual void platformDestroy();
virtual EGLNativeDisplayType platformDisplay() const;
@@ -55,20 +78,151 @@ public:
virtual EGLNativeWindowType createNativeWindow(const QSize &size, const QSurfaceFormat &format);
virtual void destroyNativeWindow(EGLNativeWindowType window);
virtual bool hasCapability(QPlatformIntegration::Capability cap) const;
+
+private:
+ void sendConnectionEvent(xcb_atom_t a);
+
+ EventReader *m_eventReader;
+ xcb_connection_t *m_connection;
+ xcb_window_t m_connectionEventListener;
};
static Display *display = 0;
+QAtomicInt running;
+
+static Qt::MouseButtons translateMouseButtons(int s)
+{
+ Qt::MouseButtons ret = 0;
+ if (s & XCB_BUTTON_MASK_1)
+ ret |= Qt::LeftButton;
+ if (s & XCB_BUTTON_MASK_2)
+ ret |= Qt::MidButton;
+ if (s & XCB_BUTTON_MASK_3)
+ ret |= Qt::RightButton;
+ return ret;
+}
+
+static Qt::MouseButton translateMouseButton(xcb_button_t s)
+{
+ switch (s) {
+ case 1: return Qt::LeftButton;
+ case 2: return Qt::MidButton;
+ case 3: return Qt::RightButton;
+ // Button values 4-7 were already handled as Wheel events, and won't occur here.
+ case 8: return Qt::BackButton; // Also known as Qt::ExtraButton1
+ case 9: return Qt::ForwardButton; // Also known as Qt::ExtraButton2
+ case 10: return Qt::ExtraButton3;
+ case 11: return Qt::ExtraButton4;
+ case 12: return Qt::ExtraButton5;
+ case 13: return Qt::ExtraButton6;
+ case 14: return Qt::ExtraButton7;
+ case 15: return Qt::ExtraButton8;
+ case 16: return Qt::ExtraButton9;
+ case 17: return Qt::ExtraButton10;
+ case 18: return Qt::ExtraButton11;
+ case 19: return Qt::ExtraButton12;
+ case 20: return Qt::ExtraButton13;
+ case 21: return Qt::ExtraButton14;
+ case 22: return Qt::ExtraButton15;
+ case 23: return Qt::ExtraButton16;
+ case 24: return Qt::ExtraButton17;
+ case 25: return Qt::ExtraButton18;
+ case 26: return Qt::ExtraButton19;
+ case 27: return Qt::ExtraButton20;
+ case 28: return Qt::ExtraButton21;
+ case 29: return Qt::ExtraButton22;
+ case 30: return Qt::ExtraButton23;
+ case 31: return Qt::ExtraButton24;
+ default: return Qt::NoButton;
+ }
+}
+
+void EventReader::run()
+{
+ Qt::MouseButtons buttons;
+
+ xcb_generic_event_t *event;
+ while (running.load() && (event = xcb_wait_for_event(m_connection))) {
+ uint response_type = event->response_type & ~0x80;
+ switch (response_type) {
+ case XCB_BUTTON_PRESS: {
+ xcb_button_press_event_t *press = (xcb_button_press_event_t *)event;
+ QPoint p(press->event_x, press->event_y);
+ buttons = (buttons & ~0x7) | translateMouseButtons(press->state);
+ buttons |= translateMouseButton(press->detail);
+ QWindowSystemInterface::handleMouseEvent(0, press->time, p, p, buttons);
+ break;
+ }
+ case XCB_BUTTON_RELEASE: {
+ xcb_button_release_event_t *release = (xcb_button_release_event_t *)event;
+ QPoint p(release->event_x, release->event_y);
+ buttons = (buttons & ~0x7) | translateMouseButtons(release->state);
+ buttons &= ~translateMouseButton(release->detail);
+ QWindowSystemInterface::handleMouseEvent(0, release->time, p, p, buttons);
+ break;
+ }
+ case XCB_MOTION_NOTIFY: {
+ xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)event;
+ QPoint p(motion->event_x, motion->event_y);
+ QWindowSystemInterface::handleMouseEvent(0, motion->time, p, p, buttons);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+void QEglFSX11Hooks::sendConnectionEvent(xcb_atom_t a)
+{
+ xcb_client_message_event_t event;
+ memset(&event, 0, sizeof(event));
+
+ event.response_type = XCB_CLIENT_MESSAGE;
+ event.format = 32;
+ event.sequence = 0;
+ event.window = m_connectionEventListener;
+ event.type = a;
+
+ xcb_send_event(m_connection, false, m_connectionEventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+ xcb_flush(m_connection);
+}
+
void QEglFSX11Hooks::platformInit()
{
display = XOpenDisplay(NULL);
if (!display)
qFatal("Could not open display");
+ XSetEventQueueOwner(display, XCBOwnsEventQueue);
+
+ running.ref();
+
+ m_connection = XGetXCBConnection(display);
+
+ xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(m_connection));
+
+ m_connectionEventListener = xcb_generate_id(m_connection);
+ xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
+ m_connectionEventListener, it.data->root,
+ 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
+ it.data->root_visual, 0, 0);
+
+ m_eventReader = new EventReader(m_connection);
+ m_eventReader->start();
}
void QEglFSX11Hooks::platformDestroy()
{
+ running.deref();
+
+ sendConnectionEvent(XCB_ATOM_NONE);
+
XCloseDisplay(display);
+
+ m_eventReader->wait();
+ delete m_eventReader;
+ m_eventReader = 0;
}
EGLNativeDisplayType QEglFSX11Hooks::platformDisplay() const
@@ -91,10 +245,12 @@ EGLNativeWindowType QEglFSX11Hooks::createNativeWindow(const QSize &size, const
Window root = DefaultRootWindow(display);
XSetWindowAttributes swa;
memset(&swa, 0, sizeof(swa));
- Window win = XCreateWindow(display, root, 0, 0, size.width(), size.height(), 0, CopyFromParent,
- InputOutput, CopyFromParent, CWEventMask, &swa);
+ swa.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ButtonMotionMask;
+ Window win = XCreateWindow(display, root, 0, 0, size.width(), size.height(), 0, CopyFromParent,
+ InputOutput, CopyFromParent, CWEventMask, &swa);
XMapWindow(display, win);
XStoreName(display, win, "EGLFS");
+
return win;
}
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 615b69f7d9..cf1503b7f9 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -53,7 +53,7 @@
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
-#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID)
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
#include <QtPlatformSupport/private/qevdevtouch_p.h>
@@ -79,7 +79,7 @@ QEglFSIntegration::QEglFSIntegration()
{
QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher);
-#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID)
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index e104bd7f2b..6cb1f88c66 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -55,12 +55,8 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
#endif
static int hideCursor = qgetenv("QT_QPA_EGLFS_HIDECURSOR").toInt();
- if (!hideCursor) {
- if (QEglFSCursor *customCursor = QEglFSHooks::hooks()->createCursor(this))
- m_cursor = customCursor;
- else
- m_cursor = new QEglFSCursor(this);
- }
+ if (!hideCursor)
+ m_cursor = QEglFSHooks::hooks()->createCursor(this);
}
QEglFSScreen::~QEglFSScreen()