src/gui/kernel/qcursor_x11.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <qdatastream.h>
       
    43 #include <private/qcursor_p.h>
       
    44 #include <private/qt_x11_p.h>
       
    45 #include <qbitmap.h>
       
    46 #include <qcursor.h>
       
    47 #include <X11/cursorfont.h>
       
    48 
       
    49 #include <qlibrary.h>
       
    50 
       
    51 #ifndef QT_NO_XCURSOR
       
    52 #  include <X11/Xcursor/Xcursor.h>
       
    53 #endif // QT_NO_XCURSOR
       
    54 
       
    55 #ifndef QT_NO_XFIXES
       
    56 #  include <X11/extensions/Xfixes.h>
       
    57 #endif // QT_NO_XFIXES
       
    58 
       
    59 #include "qx11info_x11.h"
       
    60 
       
    61 QT_BEGIN_NAMESPACE
       
    62 
       
    63 // Define QT_USE_APPROXIMATE_CURSORS when compiling if you REALLY want to
       
    64 // use the ugly X11 cursors.
       
    65 
       
    66 /*****************************************************************************
       
    67   Internal QCursorData class
       
    68  *****************************************************************************/
       
    69 
       
    70 QCursorData::QCursorData(Qt::CursorShape s)
       
    71     : cshape(s), bm(0), bmm(0), hx(0), hy(0), hcurs(0), pm(0), pmm(0)
       
    72 {
       
    73     ref = 1;
       
    74 }
       
    75 
       
    76 QCursorData::~QCursorData()
       
    77 {
       
    78     Display *dpy = X11 ? X11->display : (Display*)0;
       
    79 
       
    80     // Add in checking for the display too as on HP-UX
       
    81     // we seem to get a core dump as the cursor data is
       
    82     // deleted again from main() on exit...
       
    83     if (hcurs && dpy)
       
    84         XFreeCursor(dpy, hcurs);
       
    85     if (pm && dpy)
       
    86         XFreePixmap(dpy, pm);
       
    87     if (pmm && dpy)
       
    88         XFreePixmap(dpy, pmm);
       
    89     delete bm;
       
    90     delete bmm;
       
    91 }
       
    92 
       
    93 #ifndef QT_NO_CURSOR
       
    94 QCursor::QCursor(Qt::HANDLE cursor)
       
    95 {
       
    96     if (!QCursorData::initialized)
       
    97         QCursorData::initialize();
       
    98     d = new QCursorData(Qt::CustomCursor);
       
    99     d->hcurs = cursor;
       
   100 }
       
   101 
       
   102 #endif
       
   103 
       
   104 QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
       
   105 {
       
   106     if (!QCursorData::initialized)
       
   107         QCursorData::initialize();
       
   108     if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
       
   109         qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
       
   110         QCursorData *c = qt_cursorTable[0];
       
   111         c->ref.ref();
       
   112         return c;
       
   113     }
       
   114     QCursorData *d = new QCursorData;
       
   115     d->ref = 1;
       
   116 
       
   117     extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
       
   118     d->bm  = new QBitmap(qt_toX11Pixmap(bitmap));
       
   119     d->bmm = new QBitmap(qt_toX11Pixmap(mask));
       
   120 
       
   121     d->hcurs = 0;
       
   122     d->cshape = Qt::BitmapCursor;
       
   123     d->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
       
   124     d->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
       
   125     d->fg.red   = 0x0000;
       
   126     d->fg.green = 0x0000;
       
   127     d->fg.blue  = 0x0000;
       
   128     d->bg.red   = 0xffff;
       
   129     d->bg.green = 0xffff;
       
   130     d->bg.blue  = 0xffff;
       
   131     return d;
       
   132 }
       
   133 
       
   134 
       
   135 
       
   136 #ifndef QT_NO_CURSOR
       
   137 Qt::HANDLE QCursor::handle() const
       
   138 {
       
   139     if (!QCursorData::initialized)
       
   140         QCursorData::initialize();
       
   141     if (!d->hcurs)
       
   142         d->update();
       
   143     return d->hcurs;
       
   144 }
       
   145 #endif
       
   146 
       
   147 QPoint QCursor::pos()
       
   148 {
       
   149     Window root;
       
   150     Window child;
       
   151     int root_x, root_y, win_x, win_y;
       
   152     uint buttons;
       
   153     Display* dpy = X11->display;
       
   154     for (int i = 0; i < ScreenCount(dpy); ++i) {
       
   155         if (XQueryPointer(dpy, QX11Info::appRootWindow(i), &root, &child, &root_x, &root_y,
       
   156                           &win_x, &win_y, &buttons))
       
   157 
       
   158             return QPoint(root_x, root_y);
       
   159     }
       
   160     return QPoint();
       
   161 }
       
   162 
       
   163 /*! \internal
       
   164 */
       
   165 #ifndef QT_NO_CURSOR
       
   166 int QCursor::x11Screen()
       
   167 {
       
   168     Window root;
       
   169     Window child;
       
   170     int root_x, root_y, win_x, win_y;
       
   171     uint buttons;
       
   172     Display* dpy = X11->display;
       
   173     for (int i = 0; i < ScreenCount(dpy); ++i) {
       
   174         if (XQueryPointer(dpy, QX11Info::appRootWindow(i), &root, &child, &root_x, &root_y,
       
   175                           &win_x, &win_y, &buttons))
       
   176             return i;
       
   177     }
       
   178     return -1;
       
   179 }
       
   180 #endif
       
   181 
       
   182 void QCursor::setPos(int x, int y)
       
   183 {
       
   184     QPoint current, target(x, y);
       
   185 
       
   186     // this is copied from pos(), since we need the screen number for the correct
       
   187     // root window in the XWarpPointer call
       
   188     Window root;
       
   189     Window child;
       
   190     int root_x, root_y, win_x, win_y;
       
   191     uint buttons;
       
   192     Display* dpy = X11->display;
       
   193     int screen;
       
   194     for (screen = 0; screen < ScreenCount(dpy); ++screen) {
       
   195         if (XQueryPointer(dpy, QX11Info::appRootWindow(screen), &root, &child, &root_x, &root_y,
       
   196                           &win_x, &win_y, &buttons)) {
       
   197             current = QPoint(root_x, root_y);
       
   198             break;
       
   199         }
       
   200     }
       
   201 
       
   202     if (screen >= ScreenCount(dpy))
       
   203         return;
       
   204 
       
   205     // Need to check, since some X servers generate null mouse move
       
   206     // events, causing looping in applications which call setPos() on
       
   207     // every mouse move event.
       
   208     //
       
   209     if (current == target)
       
   210         return;
       
   211 
       
   212     XWarpPointer(X11->display, XNone, QX11Info::appRootWindow(screen), 0, 0, 0, 0, x, y);
       
   213 }
       
   214 
       
   215 
       
   216 /*!
       
   217     \internal
       
   218 
       
   219     Creates the cursor.
       
   220 */
       
   221 
       
   222 void QCursorData::update()
       
   223 {
       
   224     if (!QCursorData::initialized)
       
   225         QCursorData::initialize();
       
   226     if (hcurs)
       
   227         return;
       
   228 
       
   229     Display *dpy = X11->display;
       
   230     Window rootwin = QX11Info::appRootWindow();
       
   231 
       
   232     if (cshape == Qt::BitmapCursor) {
       
   233         extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
       
   234 #ifndef QT_NO_XRENDER
       
   235         if (!pixmap.isNull() && X11->use_xrender) {
       
   236             pixmap = qt_toX11Pixmap(pixmap);
       
   237             hcurs = XRenderCreateCursor (X11->display, pixmap.x11PictureHandle(), hx, hy);
       
   238         } else
       
   239 #endif
       
   240         {
       
   241             hcurs = XCreatePixmapCursor(dpy, bm->handle(), bmm->handle(), &fg, &bg, hx, hy);
       
   242         }
       
   243         return;
       
   244     }
       
   245 
       
   246     static const char *cursorNames[] = {
       
   247         "left_ptr",
       
   248         "up_arrow",
       
   249         "cross",
       
   250         "wait",
       
   251         "ibeam",
       
   252         "size_ver",
       
   253         "size_hor",
       
   254         "size_bdiag",
       
   255         "size_fdiag",
       
   256         "size_all",
       
   257         "blank",
       
   258         "split_v",
       
   259         "split_h",
       
   260         "pointing_hand",
       
   261         "forbidden",
       
   262         "whats_this",
       
   263         "left_ptr_watch",
       
   264         "openhand",
       
   265         "closedhand"
       
   266     };
       
   267 
       
   268 #ifndef QT_NO_XCURSOR
       
   269     if (X11->ptrXcursorLibraryLoadCursor)
       
   270         hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, cursorNames[cshape]);
       
   271     if (hcurs)
       
   272         return;
       
   273 #endif // QT_NO_XCURSOR
       
   274 
       
   275     static const char cur_blank_bits[] = {
       
   276         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   277         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   278         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
       
   279 
       
   280     // Non-standard X11 cursors are created from bitmaps
       
   281 
       
   282 #ifndef QT_USE_APPROXIMATE_CURSORS
       
   283     static const char cur_ver_bits[] = {
       
   284         0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
       
   285         0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
       
   286         0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
       
   287     static const char mcur_ver_bits[] = {
       
   288         0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
       
   289         0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
       
   290         0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
       
   291     static const char cur_hor_bits[] = {
       
   292         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
       
   293         0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
       
   294         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
       
   295     static const char mcur_hor_bits[] = {
       
   296         0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
       
   297         0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
       
   298         0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
       
   299     static const char cur_bdiag_bits[] = {
       
   300         0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
       
   301         0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
       
   302         0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
       
   303     static const char mcur_bdiag_bits[] = {
       
   304         0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
       
   305         0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
       
   306         0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
       
   307     static const char cur_fdiag_bits[] = {
       
   308         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
       
   309         0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
       
   310         0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
       
   311     static const char mcur_fdiag_bits[] = {
       
   312         0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
       
   313         0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
       
   314         0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
       
   315     static const char *cursor_bits16[] = {
       
   316         cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
       
   317         cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
       
   318         0, 0, cur_blank_bits, cur_blank_bits };
       
   319 
       
   320     static const char vsplit_bits[] = {
       
   321         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   322         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   323         0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
       
   324         0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
       
   325         0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
       
   326         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
       
   327         0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
       
   328         0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
       
   329         0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   330         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   331         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
       
   332     static const char vsplitm_bits[] = {
       
   333         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   334         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
       
   335         0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
       
   336         0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
       
   337         0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
       
   338         0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
       
   339         0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
       
   340         0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
       
   341         0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
       
   342         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   343         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
       
   344     static const char hsplit_bits[] = {
       
   345         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   346         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   347         0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
       
   348         0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
       
   349         0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
       
   350         0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
       
   351         0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
       
   352         0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   353         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   354         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   355         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
       
   356     static const char hsplitm_bits[] = {
       
   357         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   358         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   359         0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
       
   360         0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
       
   361         0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
       
   362         0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
       
   363         0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
       
   364         0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   365         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   366         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   367         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
       
   368     static const char whatsthis_bits[] = {
       
   369         0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
       
   370         0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
       
   371         0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
       
   372         0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
       
   373         0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
       
   374         0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
       
   375         0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   376         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   377         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   378         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   379         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
       
   380     static const char whatsthism_bits[] = {
       
   381         0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
       
   382         0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
       
   383         0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
       
   384         0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
       
   385         0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
       
   386         0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
       
   387         0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   388         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   389         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   390         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   391         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
       
   392     static const char busy_bits[] = {
       
   393         0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
       
   394         0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
       
   395         0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
       
   396         0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
       
   397         0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
       
   398         0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
       
   399         0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
       
   400         0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   401         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   402         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   403         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
       
   404     static const char busym_bits[] = {
       
   405         0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
       
   406         0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
       
   407         0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
       
   408         0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
       
   409         0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
       
   410         0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
       
   411         0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
       
   412         0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   413         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   414         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
   415         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
       
   416 
       
   417     static const char * const cursor_bits32[] = {
       
   418         vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
       
   419         0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
       
   420     };
       
   421 
       
   422     static const char forbidden_bits[] = {
       
   423         0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
       
   424         0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
       
   425         0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
       
   426         0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
       
   427 
       
   428     static const char forbiddenm_bits[] = {
       
   429         0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
       
   430         0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
       
   431         0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
       
   432         0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
       
   433 
       
   434     static const char openhand_bits[] = {
       
   435         0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
       
   436         0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
       
   437         0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
       
   438     static const char openhandm_bits[] = {
       
   439        0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
       
   440        0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
       
   441        0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
       
   442     static const char closedhand_bits[] = {
       
   443         0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
       
   444         0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
       
   445         0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
       
   446     static const char closedhandm_bits[] = {
       
   447         0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
       
   448         0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
       
   449         0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
       
   450 
       
   451     static const char * const cursor_bits20[] = {
       
   452         forbidden_bits, forbiddenm_bits
       
   453     };
       
   454 
       
   455     if ((cshape >= Qt::SizeVerCursor && cshape < Qt::SizeAllCursor)
       
   456         || cshape == Qt::BlankCursor) {
       
   457         XColor bg, fg;
       
   458         bg.red   = 255 << 8;
       
   459         bg.green = 255 << 8;
       
   460         bg.blue  = 255 << 8;
       
   461         fg.red   = 0;
       
   462         fg.green = 0;
       
   463         fg.blue  = 0;
       
   464         int i = (cshape - Qt::SizeVerCursor) * 2;
       
   465         pm  = XCreateBitmapFromData(dpy, rootwin, cursor_bits16[i], 16, 16);
       
   466         pmm = XCreateBitmapFromData(dpy, rootwin, cursor_bits16[i + 1], 16, 16);
       
   467         hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
       
   468     } else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
       
   469                || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) {
       
   470         XColor bg, fg;
       
   471         bg.red   = 255 << 8;
       
   472         bg.green = 255 << 8;
       
   473         bg.blue  = 255 << 8;
       
   474         fg.red   = 0;
       
   475         fg.green = 0;
       
   476         fg.blue  = 0;
       
   477         int i = (cshape - Qt::SplitVCursor) * 2;
       
   478         pm  = XCreateBitmapFromData(dpy, rootwin, cursor_bits32[i], 32, 32);
       
   479         pmm = XCreateBitmapFromData(dpy, rootwin, cursor_bits32[i + 1], 32, 32);
       
   480         int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
       
   481                   || cshape == Qt::BusyCursor) ? 0 : 16;
       
   482         hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, hs, hs);
       
   483     } else if (cshape == Qt::ForbiddenCursor) {
       
   484         XColor bg, fg;
       
   485         bg.red   = 255 << 8;
       
   486         bg.green = 255 << 8;
       
   487         bg.blue  = 255 << 8;
       
   488         fg.red   = 0;
       
   489         fg.green = 0;
       
   490         fg.blue  = 0;
       
   491         int i = (cshape - Qt::ForbiddenCursor) * 2;
       
   492         pm  = XCreateBitmapFromData(dpy, rootwin, cursor_bits20[i], 20, 20);
       
   493         pmm = XCreateBitmapFromData(dpy, rootwin, cursor_bits20[i + 1], 20, 20);
       
   494         hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 10, 10);
       
   495     } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
       
   496         XColor bg, fg;
       
   497         bg.red   = 255 << 8;
       
   498         bg.green = 255 << 8;
       
   499         bg.blue  = 255 << 8;
       
   500         fg.red   = 0;
       
   501         fg.green = 0;
       
   502         fg.blue  = 0;
       
   503         bool open = cshape == Qt::OpenHandCursor;
       
   504         pm  = XCreateBitmapFromData(dpy, rootwin, open ? openhand_bits : closedhand_bits, 16, 16);
       
   505         pmm = XCreateBitmapFromData(dpy, rootwin, open ? openhandm_bits : closedhandm_bits, 16, 16);
       
   506         hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
       
   507     }
       
   508 
       
   509     if (hcurs)
       
   510     {
       
   511 #ifndef QT_NO_XFIXES
       
   512         if (X11->use_xfixes && X11->ptrXFixesSetCursorName)
       
   513             X11->ptrXFixesSetCursorName(dpy, hcurs, cursorNames[cshape]);
       
   514 #endif /* ! QT_NO_XFIXES */
       
   515         return;
       
   516     }
       
   517 
       
   518 #endif /* ! QT_USE_APPROXIMATE_CURSORS */
       
   519 
       
   520     uint sh;
       
   521     switch (cshape) {                        // map Q cursor to X cursor
       
   522     case Qt::ArrowCursor:
       
   523         sh = XC_left_ptr;
       
   524         break;
       
   525     case Qt::UpArrowCursor:
       
   526         sh = XC_center_ptr;
       
   527         break;
       
   528     case Qt::CrossCursor:
       
   529         sh = XC_crosshair;
       
   530         break;
       
   531     case Qt::WaitCursor:
       
   532         sh = XC_watch;
       
   533         break;
       
   534     case Qt::IBeamCursor:
       
   535         sh = XC_xterm;
       
   536         break;
       
   537     case Qt::SizeAllCursor:
       
   538         sh = XC_fleur;
       
   539         break;
       
   540     case Qt::PointingHandCursor:
       
   541         sh = XC_hand2;
       
   542         break;
       
   543 #ifdef QT_USE_APPROXIMATE_CURSORS
       
   544     case Qt::SizeBDiagCursor:
       
   545         sh = XC_top_right_corner;
       
   546         break;
       
   547     case Qt::SizeFDiagCursor:
       
   548         sh = XC_bottom_right_corner;
       
   549         break;
       
   550     case Qt::BlankCursor:
       
   551         XColor bg, fg;
       
   552         bg.red   = 255 << 8;
       
   553         bg.green = 255 << 8;
       
   554         bg.blue  = 255 << 8;
       
   555         fg.red   = 0;
       
   556         fg.green = 0;
       
   557         fg.blue  = 0;
       
   558         pm  = XCreateBitmapFromData(dpy, rootwin, cur_blank_bits, 16, 16);
       
   559         pmm = XCreateBitmapFromData(dpy, rootwin, cur_blank_bits, 16, 16);
       
   560         hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
       
   561         return;
       
   562         break;
       
   563     case Qt::SizeVerCursor:
       
   564     case Qt::SplitVCursor:
       
   565         sh = XC_sb_v_double_arrow;
       
   566         break;
       
   567     case Qt::SizeHorCursor:
       
   568     case Qt::SplitHCursor:
       
   569         sh = XC_sb_h_double_arrow;
       
   570         break;
       
   571     case Qt::WhatsThisCursor:
       
   572         sh = XC_question_arrow;
       
   573         break;
       
   574     case Qt::ForbiddenCursor:
       
   575         sh = XC_circle;
       
   576         break;
       
   577     case Qt::BusyCursor:
       
   578         sh = XC_watch;
       
   579         break;
       
   580 #endif /* QT_USE_APPROXIMATE_CURSORS */
       
   581     default:
       
   582         qWarning("QCursor::update: Invalid cursor shape %d", cshape);
       
   583         return;
       
   584     }
       
   585     hcurs = XCreateFontCursor(dpy, sh);
       
   586 
       
   587 #ifndef QT_NO_XFIXES
       
   588     if (X11->use_xfixes && X11->ptrXFixesSetCursorName)
       
   589         X11->ptrXFixesSetCursorName(dpy, hcurs, cursorNames[cshape]);
       
   590 #endif /* ! QT_NO_XFIXES */
       
   591 }
       
   592 
       
   593 QT_END_NAMESPACE