eglfs: Add support for cursor hotspots

Cursor information is now loaded from cursor.json.

Done-with: Johannes Zellner

Change-Id: I093cf8e944d495269973e777d0b444ae4ececee1
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
This commit is contained in:
Girish Ramakrishnan 2012-05-17 15:53:14 -07:00 committed by Qt by Nokia
parent f3a0422acb
commit 5672cbf131
4 changed files with 69 additions and 14 deletions

View File

@ -0,0 +1,28 @@
{
"image": ":/cursor-atlas.png",
"cursorsPerRow": 8,
"hotSpots": [
[7, 2],
[13, 3],
[13, 13],
[13, 13],
[14, 15],
[13, 13],
[13, 13],
[13, 13],
[13, 13],
[13, 13],
[13, 13],
[13, 13],
[13, 13],
[13, 13],
[13, 13],
[10, 1],
[13, 13],
[0, 0],
[0, 0],
[13, 13],
[13, 13]
]
}

View File

@ -1,6 +1,7 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>cursor-atlas.png</file>
<file>cursor.json</file>
</qresource>
</RCC>

View File

@ -43,12 +43,13 @@
#include <QtGui/qwindowsysteminterface_qpa.h>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLContext>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonObject>
#include <QtDebug>
QT_BEGIN_NAMESPACE
#define CURSORS_PER_ROW 8
QEglFSCursor::QEglFSCursor(QEglFSScreen *screen)
: m_screen(screen), m_pos(0, 0), m_program(0), m_vertexCoordEntry(0), m_textureCoordEntry(0), m_textureEntry(0)
{
@ -114,13 +115,32 @@ void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image)
void QEglFSCursor::initCursorAtlas()
{
static QByteArray atlas = qgetenv("QT_QPA_EGLFS_CURSORATLAS");
if (atlas.isEmpty())
atlas = ":/cursor-atlas.png";
static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR");
if (json.isEmpty())
json = ":/cursor.json";
QFile file(json);
file.open(QFile::ReadOnly);
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
QJsonObject object = doc.object();
QString atlas = object.value("image").toString();
Q_ASSERT(!atlas.isEmpty());
const int cursorsPerRow = object.value("cursorsPerRow").toDouble();
Q_ASSERT(cursorsPerRow);
m_cursorAtlas.cursorsPerRow = cursorsPerRow;
const QJsonArray hotSpots = object.value("hotSpots").toArray();
Q_ASSERT(hotSpots.count() == Qt::LastCursor);
for (int i = 0; i < hotSpots.count(); i++) {
QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble());
m_cursorAtlas.hotSpots << hotSpot;
}
QImage image = QImage(atlas).convertToFormat(QImage::Format_ARGB32_Premultiplied);
m_cursorAtlas.cursorWidth = image.width() / CURSORS_PER_ROW;
m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + CURSORS_PER_ROW - 1) / CURSORS_PER_ROW);
m_cursorAtlas.hotSpot = QPoint(m_cursorAtlas.cursorWidth/2, m_cursorAtlas.cursorHeight/2); // ## be smarter
m_cursorAtlas.cursorWidth = image.width() / m_cursorAtlas.cursorsPerRow;
m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + cursorsPerRow - 1) / cursorsPerRow);
m_cursorAtlas.width = image.width();
m_cursorAtlas.height = image.height();
createCursorTexture(&m_cursorAtlas.texture, image);
@ -137,10 +157,10 @@ void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window)
if (cursor->shape() != Qt::BitmapCursor) { // standard cursor
const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width,
hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height;
m_cursor.textureRect = QRectF(ws * (m_cursor.shape % CURSORS_PER_ROW),
hs * (m_cursor.shape / CURSORS_PER_ROW),
m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow),
hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow),
ws, hs);
m_cursor.hotSpot = m_cursorAtlas.hotSpot;
m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape];
m_cursor.texture = m_cursorAtlas.texture;
m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight);
} else {
@ -155,6 +175,11 @@ void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window)
QWindowSystemInterface::handleSynchronousExposeEvent(window, rgn);
}
QRect QEglFSCursor::cursorRect() const
{
return QRect(m_pos - m_cursor.hotSpot, m_cursor.size);
}
QPoint QEglFSCursor::pos() const
{
return m_pos;

View File

@ -61,7 +61,7 @@ public:
QPoint pos() const;
void setPos(const QPoint &pos);
QRect cursorRect() const { return QRect(m_pos, m_cursor.size); }
QRect cursorRect() const;
void render();
@ -74,11 +74,12 @@ private:
// cursor atlas information
struct CursorAtlas {
CursorAtlas() : texture(0), cursorWidth(0), cursorHeight(0) { }
CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { }
int cursorsPerRow;
uint texture;
int width, height; // width and height of the the atlas
int cursorWidth, cursorHeight; // width and height of cursors inside the atlas
QPoint hotSpot;
QList<QPoint> hotSpots;
} m_cursorAtlas;
// current cursor information