diff options
Diffstat (limited to 'src/plugins/platforms/eglfs/qeglfsscreen.cpp')
-rw-r--r-- | src/plugins/platforms/eglfs/qeglfsscreen.cpp | 94 |
1 files changed, 92 insertions, 2 deletions
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 1b6e2307f8..22ec424451 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -32,7 +32,10 @@ ****************************************************************************/ #include <QtCore/qtextstream.h> -#include <QtGui/qpa/qplatformcursor.h> +#include <QtGui/qwindow.h> +#include <qpa/qwindowsysteminterface.h> +#include <qpa/qplatformcursor.h> +#include <QtPlatformSupport/private/qopenglcompositor_p.h> #include "qeglfsscreen.h" #include "qeglfswindow.h" @@ -41,7 +44,8 @@ QT_BEGIN_NAMESPACE QEglFSScreen::QEglFSScreen(EGLDisplay dpy) - : QEGLPlatformScreen(dpy), + : m_dpy(dpy), + m_pointerWindow(0), m_surface(EGL_NO_SURFACE), m_cursor(0) { @@ -51,6 +55,7 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy) QEglFSScreen::~QEglFSScreen() { delete m_cursor; + QOpenGLCompositor::destroy(); } QRect QEglFSScreen::geometry() const @@ -103,4 +108,89 @@ void QEglFSScreen::setPrimarySurface(EGLSurface surface) m_surface = surface; } +void QEglFSScreen::handleCursorMove(const QPoint &pos) +{ + const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); + + // Generate enter and leave events like a real windowing system would do. + if (windows.isEmpty()) + return; + + // First window is always fullscreen. + if (windows.count() == 1) { + QWindow *window = windows[0]->sourceWindow(); + if (m_pointerWindow != window) { + m_pointerWindow = window; + QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos); + } + return; + } + + QWindow *enter = 0, *leave = 0; + for (int i = windows.count() - 1; i >= 0; --i) { + QWindow *window = windows[i]->sourceWindow(); + const QRect geom = window->geometry(); + if (geom.contains(pos)) { + if (m_pointerWindow != window) { + leave = m_pointerWindow; + m_pointerWindow = window; + enter = window; + } + break; + } + } + + if (enter && leave) + QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); +} + +QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) const +{ + QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); + Q_ASSERT(!windows.isEmpty()); + + QImage img; + + if (static_cast<QEglFSWindow *>(windows.first()->sourceWindow()->handle())->isRaster()) { + // Request the compositor to render everything into an FBO and read it back. This + // is of course slow, but it's safe and reliable. It will not include the mouse + // cursor, which is a plus. + img = compositor->grab(); + } else { + // Just a single OpenGL window without compositing. Do not support this case for now. Doing + // glReadPixels is not an option since it would read from the back buffer which may have + // undefined content when calling right after a swapBuffers (unless preserved swap is + // available and enabled, but we have no support for that). + qWarning("grabWindow: Not supported for non-composited OpenGL content. Use QQuickWindow::grabWindow() instead."); + return QPixmap(); + } + + if (!wid) { + const QSize screenSize = geometry().size(); + if (width < 0) + width = screenSize.width() - x; + if (height < 0) + height = screenSize.height() - y; + return QPixmap::fromImage(img).copy(x, y, width, height); + } + + foreach (QOpenGLCompositorWindow *w, windows) { + const QWindow *window = w->sourceWindow(); + if (window->winId() == wid) { + const QRect geom = window->geometry(); + if (width < 0) + width = geom.width() - x; + if (height < 0) + height = geom.height() - y; + QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height)); + rect &= window->geometry(); + return QPixmap::fromImage(img).copy(rect); + } + } + + return QPixmap(); +} + QT_END_NAMESPACE |