9#include <qpa/qwindowsysteminterface.h>
10#include <QtGui/QOpenGLContext>
11#include <QtGui/QOpenGLFunctions>
12#include <QtCore/QFile>
13#include <QtCore/QJsonDocument>
14#include <QtCore/QJsonArray>
15#include <QtCore/QJsonObject>
17#include <QtGui/private/qguiapplication_p.h>
18#include <QtOpenGL/private/qopenglvertexarrayobject_p.h>
20#ifndef GL_VERTEX_ARRAY_BINDING
21#define GL_VERTEX_ARRAY_BINDING 0x85B5
33 m_updateRequested(
false)
37 m_visible = hideCursorVal.
toInt() == 0;
43 m_rotationMatrix.rotate(rotation, 0, 0, 1);
61QEglFSCursor::~QEglFSCursor()
64 delete m_deviceListener;
67void QEglFSCursor::updateMouseStatus()
69 m_visible = m_deviceListener->hasMouse();
80 m_cursor->updateMouseStatus();
83void QEglFSCursor::resetResources()
85 m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull();
88void QEglFSCursor::createShaderPrograms()
90 static const char *textureVertexProgram =
91 "attribute highp vec2 vertexCoordEntry;\n"
92 "attribute highp vec2 textureCoordEntry;\n"
93 "varying highp vec2 textureCoord;\n"
94 "uniform highp mat4 mat;\n"
96 " textureCoord = textureCoordEntry;\n"
97 " gl_Position = mat * vec4(vertexCoordEntry, 1.0, 1.0);\n"
100 static const char *textureFragmentProgram =
101 "uniform sampler2D texture;\n"
102 "varying highp vec2 textureCoord;\n"
104 " gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
111 gfx.program->bindAttributeLocation(
"vertexCoordEntry", 0);
112 gfx.program->bindAttributeLocation(
"textureCoordEntry", 1);
115 gfx.textureEntry = gfx.program->uniformLocation(
"texture");
116 gfx.matEntry = gfx.program->uniformLocation(
"mat");
125 f->glBindTexture(GL_TEXTURE_2D, *
texture);
126 f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
127 f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
135void QEglFSCursor::initCursorAtlas()
139 json =
":/cursor.json";
150 QString atlas =
object.value(
"image"_L1).toString();
153 const int cursorsPerRow =
object.value(
"cursorsPerRow"_L1).toDouble();
155 m_cursorAtlas.cursorsPerRow = cursorsPerRow;
157 const QJsonArray hotSpots =
object.value(
"hotSpots"_L1).toArray();
159 for (
int i = 0;
i < hotSpots.
count();
i++) {
161 m_cursorAtlas.hotSpots << hotSpot;
165 m_cursorAtlas.cursorWidth =
image.width() / m_cursorAtlas.cursorsPerRow;
166 m_cursorAtlas.cursorHeight =
image.height() / ((
Qt::LastCursor + cursorsPerRow) / cursorsPerRow);
167 m_cursorAtlas.width =
image.width();
168 m_cursorAtlas.height =
image.height();
169 m_cursorAtlas.image =
image;
176 const QRect oldCursorRect = cursorRect();
177 if (setCurrentCursor(
cursor))
178 update(oldCursorRect | cursorRect(),
false);
191 m_cursor.customCursorImage =
QImage();
192 m_cursor.customCursorPending =
false;
194 m_cursor.shape = newShape;
196 const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width,
197 hs = (
float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height;
198 m_cursor.textureRect =
QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow),
199 hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow),
201 m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape];
202 m_cursor.useCustomCursor =
false;
203 m_cursor.size =
QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight);
206 m_cursor.textureRect =
QRectF(0, 0, 1, 1);
208 m_cursor.useCustomCursor =
false;
209 m_cursor.size =
image.size();
210 m_cursor.customCursorImage =
image;
211 m_cursor.customCursorPending =
true;
212 m_cursor.customCursorKey = m_cursor.customCursorImage.cacheKey();
238bool QEglFSCursor::event(
QEvent *
e)
242 m_updateRequested =
false;
259void QEglFSCursor::update(
const QRect &
rect,
bool allScreens)
261 if (!m_updateRequested) {
265 m_updateRequested =
true;
270QRect QEglFSCursor::cursorRect()
const
272 return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size);
275QPoint QEglFSCursor::pos()
const
280void QEglFSCursor::setPos(
const QPoint &
pos)
283 const QRect oldCursorRect = cursorRect();
285 update(oldCursorRect | cursorRect(),
false);
294 const QRect oldCursorRect = cursorRect();
295 m_cursor.pos =
event.globalPosition().toPoint();
296 update(oldCursorRect | cursorRect(),
false);
301void QEglFSCursor::paintOnScreen()
327 if (
screen != m_activeScreen) {
330 update(cursorRect(),
true);
348 static bool windowsChecked =
false;
349 static bool shouldSave =
true;
350 if (!windowsChecked) {
351 windowsChecked =
true;
353 if (!windows.
isEmpty() && windows[0]->inherits(
"QQuickWindow"))
361 f->glGetIntegerv(GL_TEXTURE_BINDING_2D, &
texture);
364 cull =
f->glIsEnabled(GL_CULL_FACE);
366 blend =
f->glIsEnabled(GL_BLEND);
371 scissor =
f->glIsEnabled(GL_SCISSOR_TEST);
372 stencil =
f->glIsEnabled(GL_STENCIL_TEST);
378 for (
int i = 0;
i < 2; ++
i) {
391 f->glBindTexture(GL_TEXTURE_2D,
texture);
395 f->glEnable(GL_CULL_FACE);
397 f->glEnable(GL_DEPTH_TEST);
399 f->glDisable(GL_BLEND);
402 f->glEnable(GL_SCISSOR_TEST);
404 f->glEnable(GL_STENCIL_TEST);
408 for (
int i = 0;
i < 2; ++
i) {
410 f->glEnableVertexAttribArray(
i);
412 f->glDisableVertexAttribArray(
i);
436void QEglFSCursor::draw(
const QRectF &
r)
444 createShaderPrograms();
446 if (!gfx.atlasTexture) {
447 createCursorTexture(&gfx.atlasTexture, m_cursorAtlas.image);
450 m_cursor.useCustomCursor =
false;
454 if (m_cursor.shape ==
Qt::BitmapCursor && (m_cursor.customCursorPending || m_cursor.customCursorKey != gfx.customCursorKey)) {
456 createCursorTexture(&gfx.customCursorTexture, m_cursor.customCursorImage);
457 m_cursor.useCustomCursor =
true;
458 m_cursor.customCursorPending =
false;
459 gfx.customCursorKey = m_cursor.customCursorKey;
462 GLuint cursorTexture = !m_cursor.useCustomCursor ? gfx.atlasTexture : gfx.customCursorTexture;
471 const GLfloat cursorCoordinates[] = {
478 const GLfloat s1 = m_cursor.textureRect.left();
479 const GLfloat s2 = m_cursor.textureRect.right();
480 const GLfloat t1 = m_cursor.textureRect.top();
481 const GLfloat t2 = m_cursor.textureRect.bottom();
482 const GLfloat textureCoordinates[] = {
490 f->glBindTexture(GL_TEXTURE_2D, cursorTexture);
492 if (stateSaver.vaoHelper->isValid())
493 stateSaver.vaoHelper->glBindVertexArray(0);
497 gfx.program->enableAttributeArray(0);
498 gfx.program->enableAttributeArray(1);
499 gfx.program->setAttributeArray(0, cursorCoordinates, 2);
500 gfx.program->setAttributeArray(1, textureCoordinates, 2);
502 gfx.program->setUniformValue(gfx.textureEntry, 0);
503 gfx.program->setUniformValue(gfx.matEntry, m_rotationMatrix);
505 f->glDisable(GL_CULL_FACE);
506 f->glFrontFace(GL_CCW);
507 f->glEnable(GL_BLEND);
508 f->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
509 f->glDisable(GL_DEPTH_TEST);
510 f->glDisable(GL_SCISSOR_TEST);
511 f->glDisable(GL_STENCIL_TEST);
513 f->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
515 gfx.program->disableAttributeArray(0);
516 gfx.program->disableAttributeArray(1);
517 gfx.program->release();
522#include "moc_qeglfscursor_p.cpp"
CursorUpdateEvent(const QPoint &pos, const QRect &rect, bool allScreens)
int toInt(bool *ok=nullptr, int base=10) const
Returns the byte array converted to an int using base base, which is ten by default.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
The QCursor class provides a mouse cursor with an arbitrary shape.
QPixmap pixmap() const
Returns the cursor pixmap.
Qt::CursorShape shape() const
Returns the cursor shape identifier.
QPoint hotSpot() const
Returns the cursor hot spot, or (0, 0) if it is one of the standard cursors.
void onDeviceListChanged(QInputDeviceManager::DeviceType type)
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
static QInputDeviceManager * inputDeviceManager()
static QWindowList allWindows()
Returns a list of all the windows in the application.
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
@ Format_ARGB32_Premultiplied
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const &
\inmodule QtCore\reentrant
qsizetype count() const
Same as size().
\inmodule QtCore\reentrant
QJsonObject object() const
Returns the QJsonObject contained in the document.
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=nullptr)
Parses json as a UTF-8 encoded JSON document, and creates a QJsonDocument from it.
\inmodule QtCore\reentrant
bool isEmpty() const noexcept
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
QPlatformOpenGLContext * handle() const
Returns the underlying platform context.
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
QOpenGLFunctions * functions() const
Get the QOpenGLFunctions instance for this context.
The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
void glGenTextures(GLsizei n, GLuint *textures)
Convenience function that calls glGenTextures(n, textures).
The QOpenGLShaderProgram class allows OpenGL shader programs to be linked and used.
void glBindVertexArray(GLuint array) const
static Q_OPENGL_EXPORT QOpenGLVertexArrayObjectHelper * vertexArrayObjectHelperForContext(QOpenGLContext *context)
QImage toImage() const
Converts the pixmap to a QImage.
\inmodule QtCore\reentrant
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr qreal left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr QPointF topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
constexpr void translate(qreal dx, qreal dy) noexcept
Moves the rectangle dx along the x-axis and dy along the y-axis, relative to the current position.
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
\inmodule QtCore\reentrant
constexpr QPoint topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr QSize size() const noexcept
Returns the size of the rectangle.
The QRegion class specifies a clip region for a painter.
QRect geometry
the screen's geometry in pixels
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
The QWindowSystemInterface provides an event queue for the QPA platform.
static bool flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
Make Qt Gui process all events on the event queue immediately.
static bool handleExposeEvent(QWindow *window, const QRegion ®ion)
Combined button and popup list for selecting options.
QTextStream & ws(QTextStream &stream)
Calls \l {QTextStream::}{skipWhiteSpace()} on stream and returns stream.
#define GL_VERTEX_ARRAY_BINDING
typedef GLint(GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)(GLuint program
typedef GLfloat(GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC)(GLuint path
GLfloat GLfloat GLfloat w
[0]
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLfloat GLfloat GLfloat x1
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
[4]
const void GLsizei GLsizei stride
#define GL_BLEND_DST_ALPHA
#define GL_VERTEX_ATTRIB_ARRAY_SIZE
#define GL_CURRENT_PROGRAM
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
GLfixed GLfixed GLfixed y2
#define GL_VERTEX_ATTRIB_ARRAY_POINTER
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED
#define GL_ARRAY_BUFFER_BINDING
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
#define GL_ACTIVE_TEXTURE
#define GL_VERTEX_ATTRIB_ARRAY_TYPE
GLsizei const void * pointer
GLint GLenum GLboolean normalized
GLint GLfloat GLint stencil
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE
#define GL_BLEND_SRC_ALPHA
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
static double toDouble(Value v)
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
myFilter draw(painter, QPoint(0, 0), originalPixmap)
StateSaver(QOpenGLFunctions *func)
QOpenGLVertexArrayObjectHelper * vaoHelper
struct StateSaver::@428 va[2]