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

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