qeglfscursor.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/plugins/platforms/eglfs/qeglfscursor.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the plugins of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qeglfscursor.h"-
35#include "qeglfsintegration.h"-
36#include "qeglfsscreen.h"-
37-
38#include <qpa/qwindowsysteminterface.h>-
39#include <QtGui/QOpenGLContext>-
40#include <QtGui/QOpenGLShaderProgram>-
41#include <QtCore/QJsonDocument>-
42#include <QtCore/QJsonArray>-
43#include <QtCore/QJsonObject>-
44-
45#include <QtGui/private/qguiapplication_p.h>-
46#include <QtGui/private/qopenglvertexarrayobject_p.h>-
47-
48#ifndef GL_VERTEX_ARRAY_BINDING-
49#define GL_VERTEX_ARRAY_BINDING 0x85B5-
50#endif-
51-
52QT_BEGIN_NAMESPACE-
53-
54QEglFSCursor::QEglFSCursor(QPlatformScreen *screen)-
55 : m_visible(true),-
56 m_screen(static_cast<QEglFSScreen *>(screen)),-
57 m_program(0),-
58 m_textureEntry(0),-
59 m_deviceListener(0),-
60 m_updateRequested(false)-
61{-
62 QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");-
63 if (!hideCursorVal.isEmpty())
!hideCursorVal.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
64 m_visible = hideCursorVal.toInt() == 0;
never executed: m_visible = hideCursorVal.toInt() == 0;
0
65 if (!m_visible)
!m_visibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
66 return;
never executed: return;
0
67-
68 // Try to load the cursor atlas. If this fails, m_visible is set to false and-
69 // paintOnScreen() and setCurrentCursor() become no-ops.-
70 initCursorAtlas();-
71-
72 // initialize the cursor-
73#ifndef QT_NO_CURSOR-
74 QCursor cursor(Qt::ArrowCursor);-
75 setCurrentCursor(&cursor);-
76#endif-
77-
78 m_deviceListener = new QEglFSCursorDeviceListener(this);-
79 connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged,-
80 m_deviceListener, &QEglFSCursorDeviceListener::onDeviceListChanged);-
81 updateMouseStatus();-
82}
never executed: end of block
0
83-
84QEglFSCursor::~QEglFSCursor()-
85{-
86 resetResources();-
87 delete m_deviceListener;-
88}
never executed: end of block
0
89-
90void QEglFSCursor::updateMouseStatus()-
91{-
92 m_visible = m_deviceListener->hasMouse();-
93}
never executed: end of block
0
94-
95bool QEglFSCursorDeviceListener::hasMouse() const-
96{-
97 return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0;
never executed: return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0;
0
98}-
99-
100void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type)-
101{-
102 if (type == QInputDeviceManager::DeviceTypePointer)
type == QInput...iceTypePointerDescription
TRUEnever evaluated
FALSEnever evaluated
0
103 m_cursor->updateMouseStatus();
never executed: m_cursor->updateMouseStatus();
0
104}
never executed: end of block
0
105-
106void QEglFSCursor::resetResources()-
107{-
108 if (QOpenGLContext::currentContext()) {
QOpenGLContext...rrentContext()Description
TRUEnever evaluated
FALSEnever evaluated
0
109 delete m_program;-
110 glDeleteTextures(1, &m_cursor.customCursorTexture);-
111 glDeleteTextures(1, &m_cursorAtlas.texture);-
112 }
never executed: end of block
0
113 m_program = 0;-
114 m_cursor.customCursorTexture = 0;-
115 m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull();-
116 m_cursorAtlas.texture = 0;-
117}
never executed: end of block
0
118-
119void QEglFSCursor::createShaderPrograms()-
120{-
121 static const char *textureVertexProgram =-
122 "attribute highp vec2 vertexCoordEntry;\n"-
123 "attribute highp vec2 textureCoordEntry;\n"-
124 "varying highp vec2 textureCoord;\n"-
125 "void main() {\n"-
126 " textureCoord = textureCoordEntry;\n"-
127 " gl_Position = vec4(vertexCoordEntry, 1.0, 1.0);\n"-
128 "}\n";-
129-
130 static const char *textureFragmentProgram =-
131 "uniform sampler2D texture;\n"-
132 "varying highp vec2 textureCoord;\n"-
133 "void main() {\n"-
134 " gl_FragColor = texture2D(texture, textureCoord).bgra;\n"-
135 "}\n";-
136-
137 m_program = new QOpenGLShaderProgram;-
138 m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);-
139 m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);-
140 m_program->bindAttributeLocation("vertexCoordEntry", 0);-
141 m_program->bindAttributeLocation("textureCoordEntry", 1);-
142 m_program->link();-
143-
144 m_textureEntry = m_program->uniformLocation("texture");-
145}
never executed: end of block
0
146-
147void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image)-
148{-
149 if (!*texture)
!*textureDescription
TRUEnever evaluated
FALSEnever evaluated
0
150 glGenTextures(1, texture);
never executed: glGenTextures(1, texture);
0
151 glBindTexture(GL_TEXTURE_2D, *texture);-
152 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);-
153 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);-
154 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);-
155 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);-
156-
157 glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, image.width(), image.height(), 0 /* border */,-
158 GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());-
159}
never executed: end of block
0
160-
161void QEglFSCursor::initCursorAtlas()-
162{-
163 static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR");-
164 if (json.isEmpty())
json.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
165 json = ":/cursor.json";
never executed: json = ":/cursor.json";
0
166-
167 QFile file(QString::fromUtf8(json));-
168 if (!file.open(QFile::ReadOnly)) {
!file.open(QFile::ReadOnly)Description
TRUEnever evaluated
FALSEnever evaluated
0
169 m_visible = false;-
170 return;
never executed: return;
0
171 }-
172-
173 QJsonDocument doc = QJsonDocument::fromJson(file.readAll());-
174 QJsonObject object = doc.object();-
175-
176 QString atlas = object.value(QLatin1String("image")).toString();-
177 Q_ASSERT(!atlas.isEmpty());-
178-
179 const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble();-
180 Q_ASSERT(cursorsPerRow);-
181 m_cursorAtlas.cursorsPerRow = cursorsPerRow;-
182-
183 const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray();-
184 Q_ASSERT(hotSpots.count() == Qt::LastCursor + 1);-
185 for (int i = 0; i < hotSpots.count(); i++) {
i < hotSpots.count()Description
TRUEnever evaluated
FALSEnever evaluated
0
186 QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble());-
187 m_cursorAtlas.hotSpots << hotSpot;-
188 }
never executed: end of block
0
189-
190 QImage image = QImage(atlas).convertToFormat(QImage::Format_ARGB32_Premultiplied);-
191 m_cursorAtlas.cursorWidth = image.width() / m_cursorAtlas.cursorsPerRow;-
192 m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + cursorsPerRow) / cursorsPerRow);-
193 m_cursorAtlas.width = image.width();-
194 m_cursorAtlas.height = image.height();-
195 m_cursorAtlas.image = image;-
196}
never executed: end of block
0
197-
198#ifndef QT_NO_CURSOR-
199void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window)-
200{-
201 Q_UNUSED(window);-
202 const QRect oldCursorRect = cursorRect();-
203 if (setCurrentCursor(cursor))
setCurrentCursor(cursor)Description
TRUEnever evaluated
FALSEnever evaluated
0
204 update(oldCursorRect | cursorRect());
never executed: update(oldCursorRect | cursorRect());
0
205}
never executed: end of block
0
206-
207bool QEglFSCursor::setCurrentCursor(QCursor *cursor)-
208{-
209 if (!m_visible)
!m_visibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
210 return false;
never executed: return false;
0
211-
212 const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor;
cursorDescription
TRUEnever evaluated
FALSEnever evaluated
0
213 if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor)
m_cursor.shape == newShapeDescription
TRUEnever evaluated
FALSEnever evaluated
newShape != Qt::BitmapCursorDescription
TRUEnever evaluated
FALSEnever evaluated
0
214 return false;
never executed: return false;
0
215-
216 if (m_cursor.shape == Qt::BitmapCursor) {
m_cursor.shape...::BitmapCursorDescription
TRUEnever evaluated
FALSEnever evaluated
0
217 m_cursor.customCursorImage = QImage();-
218 m_cursor.customCursorPending = false;-
219 }
never executed: end of block
0
220 m_cursor.shape = newShape;-
221 if (newShape != Qt::BitmapCursor) { // standard cursor
newShape != Qt::BitmapCursorDescription
TRUEnever evaluated
FALSEnever evaluated
0
222 const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width,-
223 hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height;-
224 m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow),-
225 hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow),-
226 ws, hs);-
227 m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape];-
228 m_cursor.texture = m_cursorAtlas.texture;-
229 m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight);-
230 } else {
never executed: end of block
0
231 QImage image = cursor->pixmap().toImage();-
232 m_cursor.textureRect = QRectF(0, 0, 1, 1);-
233 m_cursor.hotSpot = cursor->hotSpot();-
234 m_cursor.texture = 0; // will get updated in the next render()-
235 m_cursor.size = image.size();-
236 m_cursor.customCursorImage = image;-
237 m_cursor.customCursorPending = true;-
238 }
never executed: end of block
0
239-
240 return true;
never executed: return true;
0
241}-
242#endif-
243-
244class CursorUpdateEvent : public QEvent-
245{-
246public:-
247 CursorUpdateEvent(const QPoint &pos, const QRegion &rgn)-
248 : QEvent(QEvent::Type(QEvent::User + 1)),-
249 m_pos(pos),-
250 m_region(rgn)-
251 { }
never executed: end of block
0
252 QPoint pos() const { return m_pos; }
never executed: return m_pos;
0
253 QRegion region() const { return m_region; }
never executed: return m_region;
0
254-
255private:-
256 QPoint m_pos;-
257 QRegion m_region;-
258};-
259-
260bool QEglFSCursor::event(QEvent *e)-
261{-
262 if (e->type() == QEvent::User + 1) {
e->type() == QEvent::User + 1Description
TRUEnever evaluated
FALSEnever evaluated
0
263 CursorUpdateEvent *ev = static_cast<CursorUpdateEvent *>(e);-
264 m_updateRequested = false;-
265 QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(ev->pos()), ev->region());-
266 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);-
267 return true;
never executed: return true;
0
268 }-
269 return QPlatformCursor::event(e);
never executed: return QPlatformCursor::event(e);
0
270}-
271-
272void QEglFSCursor::update(const QRegion &rgn)-
273{-
274 if (!m_updateRequested) {
!m_updateRequestedDescription
TRUEnever evaluated
FALSEnever evaluated
0
275 // Must not flush the window system events directly from here since we are likely to-
276 // be a called directly from QGuiApplication's processMouseEvents. Flushing events-
277 // could cause reentering by dispatching more queued mouse events.-
278 m_updateRequested = true;-
279 QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rgn));-
280 }
never executed: end of block
0
281}
never executed: end of block
0
282-
283QRect QEglFSCursor::cursorRect() const-
284{-
285 return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size);
never executed: return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size);
0
286}-
287-
288QPoint QEglFSCursor::pos() const-
289{-
290 return m_cursor.pos;
never executed: return m_cursor.pos;
0
291}-
292-
293void QEglFSCursor::setPos(const QPoint &pos)-
294{-
295 QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos);-
296 const QRect oldCursorRect = cursorRect();-
297 m_cursor.pos = pos;-
298 update(oldCursorRect | cursorRect());-
299 m_screen->handleCursorMove(m_cursor.pos);-
300}
never executed: end of block
0
301-
302void QEglFSCursor::pointerEvent(const QMouseEvent &event)-
303{-
304 if (event.type() != QEvent::MouseMove)
event.type() !...ent::MouseMoveDescription
TRUEnever evaluated
FALSEnever evaluated
0
305 return;
never executed: return;
0
306 const QRect oldCursorRect = cursorRect();-
307 m_cursor.pos = event.screenPos().toPoint();-
308 update(oldCursorRect | cursorRect());-
309 m_screen->handleCursorMove(m_cursor.pos);-
310}
never executed: end of block
0
311-
312void QEglFSCursor::paintOnScreen()-
313{-
314 if (!m_visible)
!m_visibleDescription
TRUEnever evaluated
FALSEnever evaluated
0
315 return;
never executed: return;
0
316-
317 const QRectF cr = cursorRect();-
318 const QRect screenRect(m_screen->geometry());-
319 const GLfloat x1 = 2 * (cr.left() / screenRect.width()) - 1;-
320 const GLfloat x2 = 2 * (cr.right() / screenRect.width()) - 1;-
321 const GLfloat y1 = 1 - (cr.top() / screenRect.height()) * 2;-
322 const GLfloat y2 = 1 - (cr.bottom() / screenRect.height()) * 2;-
323 QRectF r(QPointF(x1, y1), QPointF(x2, y2));-
324-
325 draw(r);-
326}
never executed: end of block
0
327-
328// In order to prevent breaking code doing custom OpenGL rendering while-
329// expecting the state in the context unchanged, save and restore all the state-
330// we touch. The exception is Qt Quick where the scenegraph is known to be able-
331// to deal with the changes we make.-
332struct StateSaver-
333{-
334 StateSaver() {-
335 f = QOpenGLContext::currentContext()->functions();-
336 vaoHelper = new QOpenGLVertexArrayObjectHelper(QOpenGLContext::currentContext());-
337-
338 static bool windowsChecked = false;-
339 static bool shouldSave = true;-
340 if (!windowsChecked) {
!windowsCheckedDescription
TRUEnever evaluated
FALSEnever evaluated
0
341 windowsChecked = true;-
342 QWindowList windows = QGuiApplication::allWindows();-
343 if (!windows.isEmpty() && windows[0]->inherits("QQuickWindow"))
!windows.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
windows[0]->in...QQuickWindow")Description
TRUEnever evaluated
FALSEnever evaluated
0
344 shouldSave = false;
never executed: shouldSave = false;
0
345 }
never executed: end of block
0
346 saved = shouldSave;-
347 if (!shouldSave)
!shouldSaveDescription
TRUEnever evaluated
FALSEnever evaluated
0
348 return;
never executed: return;
0
349-
350 f->glGetIntegerv(GL_CURRENT_PROGRAM, &program);-
351 f->glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture);-
352 f->glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);-
353 f->glGetIntegerv(GL_FRONT_FACE, &frontFace);-
354 cull = f->glIsEnabled(GL_CULL_FACE);-
355 depthTest = f->glIsEnabled(GL_DEPTH_TEST);-
356 blend = f->glIsEnabled(GL_BLEND);-
357 f->glGetIntegerv(GL_BLEND_SRC_RGB, blendFunc);-
358 f->glGetIntegerv(GL_BLEND_SRC_ALPHA, blendFunc + 1);-
359 f->glGetIntegerv(GL_BLEND_DST_RGB, blendFunc + 2);-
360 f->glGetIntegerv(GL_BLEND_DST_ALPHA, blendFunc + 3);-
361 f->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &arrayBuf);-
362 if (vaoHelper->isValid())
vaoHelper->isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
363 f->glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vao);
never executed: f->glGetIntegerv(0x85B5, &vao);
0
364 for (int i = 0; i < 2; ++i) {
i < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
365 f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &va[i].enabled);-
366 f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &va[i].size);-
367 f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &va[i].type);-
368 f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &va[i].normalized);-
369 f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &va[i].stride);-
370 f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &va[i].buffer);-
371 f->glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &va[i].pointer);-
372 }
never executed: end of block
0
373 }
never executed: end of block
0
374 ~StateSaver() {-
375 if (saved) {
savedDescription
TRUEnever evaluated
FALSEnever evaluated
0
376 f->glUseProgram(program);-
377 f->glBindTexture(GL_TEXTURE_2D, texture);-
378 f->glActiveTexture(activeTexture);-
379 f->glFrontFace(frontFace);-
380 if (cull)
cullDescription
TRUEnever evaluated
FALSEnever evaluated
0
381 f->glEnable(GL_CULL_FACE);
never executed: f->glEnable(0x0B44);
0
382 else-
383 f->glDisable(GL_CULL_FACE);
never executed: f->glDisable(0x0B44);
0
384 if (depthTest)
depthTestDescription
TRUEnever evaluated
FALSEnever evaluated
0
385 f->glEnable(GL_DEPTH_TEST);
never executed: f->glEnable(0x0B71);
0
386 else-
387 f->glDisable(GL_DEPTH_TEST);
never executed: f->glDisable(0x0B71);
0
388 if (blend)
blendDescription
TRUEnever evaluated
FALSEnever evaluated
0
389 f->glEnable(GL_BLEND);
never executed: f->glEnable(0x0BE2);
0
390 else-
391 f->glDisable(GL_BLEND);
never executed: f->glDisable(0x0BE2);
0
392 f->glBlendFuncSeparate(blendFunc[0], blendFunc[1], blendFunc[2], blendFunc[3]);-
393 f->glBindBuffer(GL_ARRAY_BUFFER, arrayBuf);-
394 if (vaoHelper->isValid())
vaoHelper->isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
395 vaoHelper->glBindVertexArray(vao);
never executed: vaoHelper->glBindVertexArray(vao);
0
396 for (int i = 0; i < 2; ++i) {
i < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
397 if (va[i].enabled)
va[i].enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
398 f->glEnableVertexAttribArray(i);
never executed: f->glEnableVertexAttribArray(i);
0
399 else-
400 f->glDisableVertexAttribArray(i);
never executed: f->glDisableVertexAttribArray(i);
0
401 f->glBindBuffer(GL_ARRAY_BUFFER, va[i].buffer);-
402 f->glVertexAttribPointer(i, va[i].size, va[i].type, va[i].normalized, va[i].stride, va[i].pointer);-
403 }
never executed: end of block
0
404 }
never executed: end of block
0
405 delete vaoHelper;-
406 }
never executed: end of block
0
407 QOpenGLFunctions *f;-
408 QOpenGLVertexArrayObjectHelper *vaoHelper;-
409 bool saved;-
410 GLint program;-
411 GLint texture;-
412 GLint activeTexture;-
413 GLint frontFace;-
414 bool cull;-
415 bool depthTest;-
416 bool blend;-
417 GLint blendFunc[4];-
418 GLint vao;-
419 GLint arrayBuf;-
420 struct { GLint enabled, type, size, normalized, stride, buffer; GLvoid *pointer; } va[2];-
421};-
422-
423void QEglFSCursor::draw(const QRectF &r)-
424{-
425 StateSaver stateSaver;-
426-
427 if (!m_program) {
!m_programDescription
TRUEnever evaluated
FALSEnever evaluated
0
428 // one time initialization-
429 initializeOpenGLFunctions();-
430-
431 createShaderPrograms();-
432-
433 if (!m_cursorAtlas.texture) {
!m_cursorAtlas.textureDescription
TRUEnever evaluated
FALSEnever evaluated
0
434 createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image);-
435-
436 if (m_cursor.shape != Qt::BitmapCursor)
m_cursor.shape...::BitmapCursorDescription
TRUEnever evaluated
FALSEnever evaluated
0
437 m_cursor.texture = m_cursorAtlas.texture;
never executed: m_cursor.texture = m_cursorAtlas.texture;
0
438 }
never executed: end of block
0
439 }
never executed: end of block
0
440-
441 if (m_cursor.shape == Qt::BitmapCursor && m_cursor.customCursorPending) {
m_cursor.shape...::BitmapCursorDescription
TRUEnever evaluated
FALSEnever evaluated
m_cursor.customCursorPendingDescription
TRUEnever evaluated
FALSEnever evaluated
0
442 // upload the custom cursor-
443 createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage);-
444 m_cursor.texture = m_cursor.customCursorTexture;-
445 m_cursor.customCursorPending = false;-
446 }
never executed: end of block
0
447-
448 Q_ASSERT(m_cursor.texture);-
449-
450 m_program->bind();-
451-
452 const GLfloat x1 = r.left();-
453 const GLfloat x2 = r.right();-
454 const GLfloat y1 = r.top();-
455 const GLfloat y2 = r.bottom();-
456 const GLfloat cursorCoordinates[] = {-
457 x1, y2,-
458 x2, y2,-
459 x1, y1,-
460 x2, y1-
461 };-
462-
463 const GLfloat s1 = m_cursor.textureRect.left();-
464 const GLfloat s2 = m_cursor.textureRect.right();-
465 const GLfloat t1 = m_cursor.textureRect.top();-
466 const GLfloat t2 = m_cursor.textureRect.bottom();-
467 const GLfloat textureCoordinates[] = {-
468 s1, t2,-
469 s2, t2,-
470 s1, t1,-
471 s2, t1-
472 };-
473-
474 glActiveTexture(GL_TEXTURE0);-
475 glBindTexture(GL_TEXTURE_2D, m_cursor.texture);-
476-
477 if (stateSaver.vaoHelper->isValid())
stateSaver.vao...per->isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
478 stateSaver.vaoHelper->glBindVertexArray(0);
never executed: stateSaver.vaoHelper->glBindVertexArray(0);
0
479-
480 glBindBuffer(GL_ARRAY_BUFFER, 0);-
481-
482 m_program->enableAttributeArray(0);-
483 m_program->enableAttributeArray(1);-
484 m_program->setAttributeArray(0, cursorCoordinates, 2);-
485 m_program->setAttributeArray(1, textureCoordinates, 2);-
486-
487 m_program->setUniformValue(m_textureEntry, 0);-
488-
489 glDisable(GL_CULL_FACE);-
490 glFrontFace(GL_CCW);-
491 glEnable(GL_BLEND);-
492 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);-
493 glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top-
494-
495 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);-
496-
497 m_program->disableAttributeArray(0);-
498 m_program->disableAttributeArray(1);-
499 m_program->release();-
500}
never executed: end of block
0
501-
502QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9