eglfs: Add support for cursor hotspots
authorGirish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
Thu, 17 May 2012 22:53:14 +0000 (15:53 -0700)
committerQt by Nokia <qt-info@nokia.com>
Fri, 18 May 2012 13:28:09 +0000 (15:28 +0200)
Cursor information is now loaded from cursor.json.

Done-with: Johannes Zellner

Change-Id: I093cf8e944d495269973e777d0b444ae4ececee1
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
src/plugins/platforms/eglfs/cursor.json [new file with mode: 0644]
src/plugins/platforms/eglfs/cursor.qrc
src/plugins/platforms/eglfs/qeglfscursor.cpp
src/plugins/platforms/eglfs/qeglfscursor.h

diff --git a/src/plugins/platforms/eglfs/cursor.json b/src/plugins/platforms/eglfs/cursor.json
new file mode 100644 (file)
index 0000000..7b6b6d9
--- /dev/null
@@ -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]
+    ]
+}
+
index 64d9b2b..8ea6e86 100644 (file)
@@ -1,6 +1,7 @@
 <!DOCTYPE RCC><RCC version="1.0">
 <qresource>
    <file>cursor-atlas.png</file>
+   <file>cursor.json</file>
 </qresource>
 </RCC>
 
index 20cd7b9..0d068f3 100644 (file)
 #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;
index a580404..43f6b68 100644 (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