src/gui/kernel/qcursor_x11.cpp
changeset 30 5dc02b23752f
parent 18 2f34d5167611
--- a/src/gui/kernel/qcursor_x11.cpp	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/gui/kernel/qcursor_x11.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -39,9 +39,11 @@
 **
 ****************************************************************************/
 
+#include <qdebug.h>
 #include <qdatastream.h>
 #include <private/qcursor_p.h>
 #include <private/qt_x11_p.h>
+#include <private/qapplication_p.h>
 #include <qbitmap.h>
 #include <qcursor.h>
 #include <X11/cursorfont.h>
@@ -57,6 +59,7 @@
 #endif // QT_NO_XFIXES
 
 #include "qx11info_x11.h"
+#include <private/qpixmap_x11_p.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -262,17 +265,36 @@
         "whats_this",
         "left_ptr_watch",
         "openhand",
-        "closedhand"
+        "closedhand",
+        "copy",
+        "move",
+        "link"
     };
 
 #ifndef QT_NO_XCURSOR
-    if (X11->ptrXcursorLibraryLoadCursor)
-        hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, cursorNames[cshape]);
+    if (X11->ptrXcursorLibraryLoadCursor) {
+        // special case for non-standard dnd-* cursors
+        switch (cshape) {
+        case Qt::DragCopyCursor:
+            hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-copy");
+            break;
+        case Qt::DragMoveCursor:
+            hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-move");
+            break;
+        case Qt::DragLinkCursor:
+            hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-link");
+            break;
+        default:
+            break;
+        }
+        if (!hcurs)
+            hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, cursorNames[cshape]);
+    }
     if (hcurs)
         return;
 #endif // QT_NO_XCURSOR
 
-    static const char cur_blank_bits[] = {
+    static const uchar cur_blank_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@@ -280,44 +302,44 @@
     // Non-standard X11 cursors are created from bitmaps
 
 #ifndef QT_USE_APPROXIMATE_CURSORS
-    static const char cur_ver_bits[] = {
+    static const uchar cur_ver_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
         0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
         0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
-    static const char mcur_ver_bits[] = {
+    static const uchar mcur_ver_bits[] = {
         0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
         0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
         0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
-    static const char cur_hor_bits[] = {
+    static const uchar cur_hor_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
         0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-    static const char mcur_hor_bits[] = {
+    static const uchar mcur_hor_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
         0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
         0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
-    static const char cur_bdiag_bits[] = {
+    static const uchar cur_bdiag_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
         0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
         0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-    static const char mcur_bdiag_bits[] = {
+    static const uchar mcur_bdiag_bits[] = {
         0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
         0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
         0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
-    static const char cur_fdiag_bits[] = {
+    static const uchar cur_fdiag_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
         0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
         0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
-    static const char mcur_fdiag_bits[] = {
+    static const uchar mcur_fdiag_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
         0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
         0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
-    static const char *cursor_bits16[] = {
+    static const uchar *cursor_bits16[] = {
         cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
         cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
         0, 0, cur_blank_bits, cur_blank_bits };
 
-    static const char vsplit_bits[] = {
+    static const uchar vsplit_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
@@ -329,7 +351,7 @@
         0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-    static const char vsplitm_bits[] = {
+    static const uchar vsplitm_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
         0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
@@ -341,7 +363,7 @@
         0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-    static const char hsplit_bits[] = {
+    static const uchar hsplit_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
@@ -353,7 +375,7 @@
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-    static const char hsplitm_bits[] = {
+    static const uchar hsplitm_bits[] = {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
@@ -365,7 +387,7 @@
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-    static const char whatsthis_bits[] = {
+    static const uchar whatsthis_bits[] = {
         0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
         0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
         0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
@@ -377,7 +399,7 @@
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
-    static const char whatsthism_bits[] = {
+    static const uchar whatsthism_bits[] = {
         0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
         0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
         0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
@@ -389,7 +411,7 @@
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
-    static const char busy_bits[] = {
+    static const uchar busy_bits[] = {
         0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
         0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
         0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
@@ -401,7 +423,7 @@
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-    static const char busym_bits[] = {
+    static const uchar busym_bits[] = {
         0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
         0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
         0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
@@ -414,41 +436,41 @@
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
-    static const char * const cursor_bits32[] = {
+    static const uchar * const cursor_bits32[] = {
         vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
         0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
     };
 
-    static const char forbidden_bits[] = {
+    static const uchar forbidden_bits[] = {
         0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
         0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
         0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
         0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
 
-    static const char forbiddenm_bits[] = {
+    static const uchar forbiddenm_bits[] = {
         0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
         0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
         0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
         0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
 
-    static const char openhand_bits[] = {
+    static const uchar openhand_bits[] = {
         0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
         0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
         0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
-    static const char openhandm_bits[] = {
+    static const uchar openhandm_bits[] = {
        0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
        0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
        0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
-    static const char closedhand_bits[] = {
+    static const uchar closedhand_bits[] = {
         0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
         0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
         0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
-    static const char closedhandm_bits[] = {
+    static const uchar closedhandm_bits[] = {
         0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
         0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
         0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
 
-    static const char * const cursor_bits20[] = {
+    static const uchar * const cursor_bits20[] = {
         forbidden_bits, forbiddenm_bits
     };
 
@@ -462,8 +484,8 @@
         fg.green = 0;
         fg.blue  = 0;
         int i = (cshape - Qt::SizeVerCursor) * 2;
-        pm  = XCreateBitmapFromData(dpy, rootwin, cursor_bits16[i], 16, 16);
-        pmm = XCreateBitmapFromData(dpy, rootwin, cursor_bits16[i + 1], 16, 16);
+        pm  = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i]), 16, 16);
+        pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i + 1]), 16, 16);
         hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
     } else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
                || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) {
@@ -475,8 +497,8 @@
         fg.green = 0;
         fg.blue  = 0;
         int i = (cshape - Qt::SplitVCursor) * 2;
-        pm  = XCreateBitmapFromData(dpy, rootwin, cursor_bits32[i], 32, 32);
-        pmm = XCreateBitmapFromData(dpy, rootwin, cursor_bits32[i + 1], 32, 32);
+        pm  = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i]), 32, 32);
+        pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i + 1]), 32, 32);
         int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
                   || cshape == Qt::BusyCursor) ? 0 : 16;
         hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, hs, hs);
@@ -489,8 +511,8 @@
         fg.green = 0;
         fg.blue  = 0;
         int i = (cshape - Qt::ForbiddenCursor) * 2;
-        pm  = XCreateBitmapFromData(dpy, rootwin, cursor_bits20[i], 20, 20);
-        pmm = XCreateBitmapFromData(dpy, rootwin, cursor_bits20[i + 1], 20, 20);
+        pm  = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i]), 20, 20);
+        pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i + 1]), 20, 20);
         hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 10, 10);
     } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
         XColor bg, fg;
@@ -501,8 +523,21 @@
         fg.green = 0;
         fg.blue  = 0;
         bool open = cshape == Qt::OpenHandCursor;
-        pm  = XCreateBitmapFromData(dpy, rootwin, open ? openhand_bits : closedhand_bits, 16, 16);
-        pmm = XCreateBitmapFromData(dpy, rootwin, open ? openhandm_bits : closedhandm_bits, 16, 16);
+        pm  = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhand_bits : closedhand_bits), 16, 16);
+        pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhandm_bits : closedhandm_bits), 16, 16);
+        hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
+    } else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor
+               || cshape == Qt::DragLinkCursor) {
+        XColor bg, fg;
+        bg.red   = 255 << 8;
+        bg.green = 255 << 8;
+        bg.blue  = 255 << 8;
+        fg.red   = 0;
+        fg.green = 0;
+        fg.blue  = 0;
+        QImage image = QApplicationPrivate::instance()->getPixmapCursor(cshape).toImage();
+        pm = QX11PixmapData::createBitmapFromImage(image);
+        pmm = QX11PixmapData::createBitmapFromImage(image.createAlphaMask().convertToFormat(QImage::Format_MonoLSB));
         hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
     }
 
@@ -577,6 +612,15 @@
     case Qt::BusyCursor:
         sh = XC_watch;
         break;
+    case Qt::DragCopyCursor:
+        sh = XC_tcross;
+        break;
+    case Qt::DragLinkCursor:
+        sh = XC_center_ptr;
+        break;
+    case Qt::DragMoveCursor:
+        sh = XC_top_left_arrow;
+        break;
 #endif /* QT_USE_APPROXIMATE_CURSORS */
     default:
         qWarning("QCursor::update: Invalid cursor shape %d", cshape);