src/gui/image/qpixmap_x11.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
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 // Uncomment the next line to enable the MIT Shared Memory extension
       
    43 //
       
    44 // WARNING:  This has some problems:
       
    45 //
       
    46 //    1. Consumes a 800x600 pixmap
       
    47 //    2. Qt does not handle the ShmCompletion message, so you will
       
    48 //        get strange effects if you xForm() repeatedly.
       
    49 //
       
    50 // #define QT_MITSHM
       
    51 
       
    52 #if defined(Q_OS_WIN32) && defined(QT_MITSHM)
       
    53 #undef QT_MITSHM
       
    54 #endif
       
    55 
       
    56 #include "qplatformdefs.h"
       
    57 
       
    58 #include "qdebug.h"
       
    59 #include "qiodevice.h"
       
    60 #include "qpixmap_x11_p.h"
       
    61 #include "qbitmap.h"
       
    62 #include "qcolormap.h"
       
    63 #include "qimage.h"
       
    64 #include "qmatrix.h"
       
    65 #include "qapplication.h"
       
    66 #include <private/qpaintengine_x11_p.h>
       
    67 #include <private/qt_x11_p.h>
       
    68 #include "qx11info_x11.h"
       
    69 #include <private/qdrawhelper_p.h>
       
    70 #include <private/qimage_p.h>
       
    71 
       
    72 #include <stdlib.h>
       
    73 
       
    74 #if defined(Q_CC_MIPS)
       
    75 #  define for if(0){}else for
       
    76 #endif
       
    77 
       
    78 QT_BEGIN_NAMESPACE
       
    79 
       
    80 QPixmap qt_toX11Pixmap(const QImage &image)
       
    81 {
       
    82     QPixmapData *data =
       
    83         new QX11PixmapData(image.depth() == 1
       
    84                            ? QPixmapData::BitmapType
       
    85                            : QPixmapData::PixmapType);
       
    86 
       
    87     data->fromImage(image, Qt::AutoColor);
       
    88 
       
    89     return QPixmap(data);
       
    90 }
       
    91 
       
    92 QPixmap qt_toX11Pixmap(const QPixmap &pixmap)
       
    93 {
       
    94     if (pixmap.isNull())
       
    95         return QPixmap();
       
    96 
       
    97     if (QPixmap(pixmap).data_ptr()->classId() == QPixmapData::X11Class)
       
    98         return pixmap;
       
    99 
       
   100     return qt_toX11Pixmap(pixmap.toImage());
       
   101 }
       
   102 
       
   103 // For thread-safety:
       
   104 //   image->data does not belong to X11, so we must free it ourselves.
       
   105 
       
   106 inline static void qSafeXDestroyImage(XImage *x)
       
   107 {
       
   108     if (x->data) {
       
   109         free(x->data);
       
   110         x->data = 0;
       
   111     }
       
   112     XDestroyImage(x);
       
   113 }
       
   114 
       
   115 QBitmap QX11PixmapData::mask_to_bitmap(int screen) const
       
   116 {
       
   117     if (!x11_mask)
       
   118         return QBitmap();
       
   119     QPixmap::x11SetDefaultScreen(screen);
       
   120     QBitmap bm(w, h);
       
   121     GC gc = XCreateGC(X11->display, bm.handle(), 0, 0);
       
   122     XCopyArea(X11->display, x11_mask, bm.handle(), gc, 0, 0,
       
   123               bm.data->width(), bm.data->height(), 0, 0);
       
   124     XFreeGC(X11->display, gc);
       
   125     return bm;
       
   126 }
       
   127 
       
   128 Qt::HANDLE QX11PixmapData::bitmap_to_mask(const QBitmap &bitmap, int screen)
       
   129 {
       
   130     if (bitmap.isNull())
       
   131         return 0;
       
   132     QBitmap bm = bitmap;
       
   133     bm.x11SetScreen(screen);
       
   134 
       
   135     Pixmap mask = XCreatePixmap(X11->display, RootWindow(X11->display, screen),
       
   136                                 bm.data->width(), bm.data->height(), 1);
       
   137     GC gc = XCreateGC(X11->display, mask, 0, 0);
       
   138     XCopyArea(X11->display, bm.handle(), mask, gc, 0, 0,
       
   139               bm.data->width(), bm.data->height(), 0, 0);
       
   140     XFreeGC(X11->display, gc);
       
   141     return mask;
       
   142 }
       
   143 
       
   144 
       
   145 /*****************************************************************************
       
   146   MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
       
   147  *****************************************************************************/
       
   148 
       
   149 #if defined(QT_MITSHM)
       
   150 
       
   151 static bool               xshminit = false;
       
   152 static XShmSegmentInfo xshminfo;
       
   153 static XImage              *xshmimg = 0;
       
   154 static Pixmap               xshmpm  = 0;
       
   155 
       
   156 static void qt_cleanup_mitshm()
       
   157 {
       
   158     if (xshmimg == 0)
       
   159         return;
       
   160     Display *dpy = QX11Info::appDisplay();
       
   161     if (xshmpm) {
       
   162         XFreePixmap(dpy, xshmpm);
       
   163         xshmpm = 0;
       
   164     }
       
   165     XShmDetach(dpy, &xshminfo); xshmimg->data = 0;
       
   166     qSafeXDestroyImage(xshmimg); xshmimg = 0;
       
   167     shmdt(xshminfo.shmaddr);
       
   168     shmctl(xshminfo.shmid, IPC_RMID, 0);
       
   169 }
       
   170 
       
   171 static bool qt_create_mitshm_buffer(const QPaintDevice* dev, int w, int h)
       
   172 {
       
   173     static int major, minor;
       
   174     static Bool pixmaps_ok;
       
   175     Display *dpy = dev->data->xinfo->display();
       
   176     int dd         = dev->x11Depth();
       
   177     Visual *vis         = (Visual*)dev->x11Visual();
       
   178 
       
   179     if (xshminit) {
       
   180         qt_cleanup_mitshm();
       
   181     } else {
       
   182         if (!XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok))
       
   183             return false;                        // MIT Shm not supported
       
   184         qAddPostRoutine(qt_cleanup_mitshm);
       
   185         xshminit = true;
       
   186     }
       
   187 
       
   188     xshmimg = XShmCreateImage(dpy, vis, dd, ZPixmap, 0, &xshminfo, w, h);
       
   189     if (!xshmimg)
       
   190         return false;
       
   191 
       
   192     bool ok;
       
   193     xshminfo.shmid = shmget(IPC_PRIVATE,
       
   194                              xshmimg->bytes_per_line * xshmimg->height,
       
   195                              IPC_CREAT | 0777);
       
   196     ok = xshminfo.shmid != -1;
       
   197     if (ok) {
       
   198         xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0);
       
   199         xshminfo.shmaddr = xshmimg->data;
       
   200         ok = (xshminfo.shmaddr != (char*)-1);
       
   201     }
       
   202     xshminfo.readOnly = false;
       
   203     if (ok)
       
   204         ok = XShmAttach(dpy, &xshminfo);
       
   205     if (!ok) {
       
   206         qSafeXDestroyImage(xshmimg);
       
   207         xshmimg = 0;
       
   208         if (xshminfo.shmaddr)
       
   209             shmdt(xshminfo.shmaddr);
       
   210         if (xshminfo.shmid != -1)
       
   211             shmctl(xshminfo.shmid, IPC_RMID, 0);
       
   212         return false;
       
   213     }
       
   214     if (pixmaps_ok)
       
   215         xshmpm = XShmCreatePixmap(dpy, DefaultRootWindow(dpy), xshmimg->data,
       
   216                                    &xshminfo, w, h, dd);
       
   217 
       
   218     return true;
       
   219 }
       
   220 
       
   221 #else
       
   222 
       
   223 // If extern, need a dummy.
       
   224 //
       
   225 // static bool qt_create_mitshm_buffer(QPaintDevice*, int, int)
       
   226 // {
       
   227 //     return false;
       
   228 // }
       
   229 
       
   230 #endif // QT_MITSHM
       
   231 
       
   232 
       
   233 /*****************************************************************************
       
   234   Internal functions
       
   235  *****************************************************************************/
       
   236 
       
   237 extern const uchar *qt_get_bitflip_array();                // defined in qimage.cpp
       
   238 
       
   239 // Returns position of highest bit set or -1 if none
       
   240 static int highest_bit(uint v)
       
   241 {
       
   242     int i;
       
   243     uint b = (uint)1 << 31;
       
   244     for (i=31; ((b & v) == 0) && i>=0;         i--)
       
   245         b >>= 1;
       
   246     return i;
       
   247 }
       
   248 
       
   249 // Returns position of lowest set bit in 'v' as an integer (0-31), or -1
       
   250 static int lowest_bit(uint v)
       
   251 {
       
   252     int i;
       
   253     ulong lb;
       
   254     lb = 1;
       
   255     for (i=0; ((v & lb) == 0) && i<32;  i++, lb<<=1) {}
       
   256     return i==32 ? -1 : i;
       
   257 }
       
   258 
       
   259 // Counts the number of bits set in 'v'
       
   260 static uint n_bits(uint v)
       
   261 {
       
   262     int i = 0;
       
   263     while (v) {
       
   264         v = v & (v - 1);
       
   265         i++;
       
   266     }
       
   267     return i;
       
   268 }
       
   269 
       
   270 static uint *red_scale_table   = 0;
       
   271 static uint *green_scale_table = 0;
       
   272 static uint *blue_scale_table  = 0;
       
   273 
       
   274 static void cleanup_scale_tables()
       
   275 {
       
   276     delete[] red_scale_table;
       
   277     delete[] green_scale_table;
       
   278     delete[] blue_scale_table;
       
   279 }
       
   280 
       
   281 /*
       
   282   Could do smart bitshifting, but the "obvious" algorithm only works for
       
   283   nBits >= 4. This is more robust.
       
   284 */
       
   285 static void build_scale_table(uint **table, uint nBits)
       
   286 {
       
   287     if (nBits > 7) {
       
   288         qWarning("build_scale_table: internal error, nBits = %i", nBits);
       
   289         return;
       
   290     }
       
   291     if (!*table) {
       
   292         static bool firstTable = true;
       
   293         if (firstTable) {
       
   294             qAddPostRoutine(cleanup_scale_tables);
       
   295             firstTable = false;
       
   296         }
       
   297         *table = new uint[256];
       
   298     }
       
   299     int   maxVal   = (1 << nBits) - 1;
       
   300     int   valShift = 8 - nBits;
       
   301     int i;
       
   302     for(i = 0 ; i < maxVal + 1 ; i++)
       
   303         (*table)[i << valShift] = i*255/maxVal;
       
   304 }
       
   305 
       
   306 static int defaultScreen = -1;
       
   307 
       
   308 /*****************************************************************************
       
   309   QPixmap member functions
       
   310  *****************************************************************************/
       
   311 
       
   312 static int qt_pixmap_serial = 0;
       
   313 int Q_GUI_EXPORT qt_x11_preferred_pixmap_depth = 0;
       
   314 
       
   315 QX11PixmapData::QX11PixmapData(PixelType type)
       
   316     : QPixmapData(type, X11Class), hd(0),
       
   317       flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0), gl_surface(0),
       
   318       share_mode(QPixmap::ImplicitlyShared), pengine(0)
       
   319 {
       
   320 }
       
   321 
       
   322 QPixmapData *QX11PixmapData::createCompatiblePixmapData() const
       
   323 {
       
   324     return new QX11PixmapData(pixelType());
       
   325 }
       
   326 
       
   327 void QX11PixmapData::resize(int width, int height)
       
   328 {
       
   329     setSerialNumber(++qt_pixmap_serial);
       
   330 
       
   331     w = width;
       
   332     h = height;
       
   333     is_null = (w <= 0 || h <= 0);
       
   334 
       
   335     if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
       
   336         QX11InfoData* xd = xinfo.getX11Data(true);
       
   337         xd->screen = defaultScreen;
       
   338         xd->depth = QX11Info::appDepth(xd->screen);
       
   339         xd->cells = QX11Info::appCells(xd->screen);
       
   340         xd->colormap = QX11Info::appColormap(xd->screen);
       
   341         xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
       
   342         xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
       
   343         xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
       
   344         xinfo.setX11Data(xd);
       
   345     }
       
   346 
       
   347     int dd = xinfo.depth();
       
   348 
       
   349     if (qt_x11_preferred_pixmap_depth)
       
   350         dd = qt_x11_preferred_pixmap_depth;
       
   351 
       
   352     bool make_null = w <= 0 || h <= 0;                // create null pixmap
       
   353     d = (pixelType() == BitmapType ? 1 : dd);
       
   354     if (make_null || d == 0) {
       
   355         w = 0;
       
   356         h = 0;
       
   357         is_null = true;
       
   358         hd = 0;
       
   359         picture = 0;
       
   360         d = 0;
       
   361         if (!make_null)
       
   362             qWarning("QPixmap: Invalid pixmap parameters");
       
   363         return;
       
   364     }
       
   365     hd = (Qt::HANDLE)XCreatePixmap(X11->display,
       
   366                                    RootWindow(X11->display, xinfo.screen()),
       
   367                                    w, h, d);
       
   368 #ifndef QT_NO_XRENDER
       
   369     if (X11->use_xrender) {
       
   370         XRenderPictFormat *format = d == 1
       
   371                                     ? XRenderFindStandardFormat(X11->display, PictStandardA1)
       
   372                                     : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
       
   373         picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
       
   374     }
       
   375 #endif // QT_NO_XRENDER
       
   376 }
       
   377 
       
   378 struct QX11AlphaDetector
       
   379 {
       
   380     bool hasAlpha() const {
       
   381         if (checked)
       
   382             return has;
       
   383         // Will implicitly also check format and return quickly for opaque types...
       
   384         checked = true;
       
   385         has = const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
       
   386         return has;
       
   387     }
       
   388 
       
   389     bool hasXRenderAndAlpha() const {
       
   390         if (!X11->use_xrender)
       
   391             return false;
       
   392         return hasAlpha();
       
   393     }
       
   394 
       
   395     QX11AlphaDetector(const QImage *i, Qt::ImageConversionFlags flags)
       
   396         : image(i), checked(false), has(false)
       
   397     {
       
   398         if (flags & Qt::NoOpaqueDetection) {
       
   399             checked = true;
       
   400             has = image->hasAlphaChannel();
       
   401         }
       
   402     }
       
   403 
       
   404     const QImage *image;
       
   405     mutable bool checked;
       
   406     mutable bool has;
       
   407 };
       
   408 
       
   409 void QX11PixmapData::fromImage(const QImage &img,
       
   410                                Qt::ImageConversionFlags flags)
       
   411 {
       
   412     setSerialNumber(++qt_pixmap_serial);
       
   413 
       
   414     w = img.width();
       
   415     h = img.height();
       
   416     d = img.depth();
       
   417     is_null = (w <= 0 || h <= 0);
       
   418 
       
   419     if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
       
   420         QX11InfoData* xd = xinfo.getX11Data(true);
       
   421         xd->screen = defaultScreen;
       
   422         xd->depth = QX11Info::appDepth(xd->screen);
       
   423         xd->cells = QX11Info::appCells(xd->screen);
       
   424         xd->colormap = QX11Info::appColormap(xd->screen);
       
   425         xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
       
   426         xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
       
   427         xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
       
   428         xinfo.setX11Data(xd);
       
   429     }
       
   430 
       
   431     if (pixelType() == BitmapType) {
       
   432         bitmapFromImage(img);
       
   433         return;
       
   434     }
       
   435 
       
   436     if (uint(w) >= 32768 || uint(h) >= 32768) {
       
   437         w = h = 0;
       
   438         is_null = true;
       
   439         return;
       
   440     }
       
   441 
       
   442     QX11AlphaDetector alphaCheck(&img, flags);
       
   443     int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth();
       
   444 
       
   445     if (qt_x11_preferred_pixmap_depth)
       
   446         dd = qt_x11_preferred_pixmap_depth;
       
   447 
       
   448     QImage image = img;
       
   449 
       
   450     // must be monochrome
       
   451     if (dd == 1 || (flags & Qt::ColorMode_Mask) == Qt::MonoOnly) {
       
   452         if (d != 1) {
       
   453             // dither
       
   454             image = image.convertToFormat(QImage::Format_MonoLSB, flags);
       
   455             d = 1;
       
   456         }
       
   457     } else { // can be both
       
   458         bool conv8 = false;
       
   459         if (d > 8 && dd <= 8) { // convert to 8 bit
       
   460             if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither)
       
   461                 flags = (flags & ~Qt::DitherMode_Mask)
       
   462                         | Qt::PreferDither;
       
   463             conv8 = true;
       
   464         } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
       
   465             conv8 = (d == 1);                        // native depth wanted
       
   466         } else if (d == 1) {
       
   467             if (image.numColors() == 2) {
       
   468                 QRgb c0 = image.color(0);        // Auto: convert to best
       
   469                 QRgb c1 = image.color(1);
       
   470                 conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255);
       
   471             } else {
       
   472                 // eg. 1-color monochrome images (they do exist).
       
   473                 conv8 = true;
       
   474             }
       
   475         }
       
   476         if (conv8) {
       
   477             image = image.convertToFormat(QImage::Format_Indexed8, flags);
       
   478             d = 8;
       
   479         }
       
   480     }
       
   481 
       
   482     if (d == 1 || d == 16 || d == 24) {
       
   483         image = image.convertToFormat(QImage::Format_RGB32, flags);
       
   484         fromImage(image, Qt::AutoColor);
       
   485         return;
       
   486     }
       
   487 
       
   488     Display *dpy   = X11->display;
       
   489     Visual *visual = (Visual *)xinfo.visual();
       
   490     XImage *xi = 0;
       
   491     bool    trucol = (visual->c_class >= TrueColor);
       
   492     int     nbytes = image.numBytes();
       
   493     uchar  *newbits= 0;
       
   494 
       
   495 #ifndef QT_NO_XRENDER
       
   496     if (alphaCheck.hasXRenderAndAlpha()) {
       
   497         const QImage &cimage = image;
       
   498 
       
   499         d = 32;
       
   500 
       
   501         if (QX11Info::appDepth() != d) {
       
   502             if (xinfo.x11data) {
       
   503                 xinfo.x11data->depth = d;
       
   504             } else {
       
   505                 QX11InfoData *xd = xinfo.getX11Data(true);
       
   506                 xd->screen = QX11Info::appScreen();
       
   507                 xd->depth = d;
       
   508                 xd->cells = QX11Info::appCells();
       
   509                 xd->colormap = QX11Info::appColormap();
       
   510                 xd->defaultColormap = QX11Info::appDefaultColormap();
       
   511                 xd->visual = (Visual *)QX11Info::appVisual();
       
   512                 xd->defaultVisual = QX11Info::appDefaultVisual();
       
   513                 xinfo.setX11Data(xd);
       
   514             }
       
   515         }
       
   516 
       
   517         hd = (Qt::HANDLE)XCreatePixmap(dpy, RootWindow(dpy, xinfo.screen()),
       
   518                                        w, h, d);
       
   519         picture = XRenderCreatePicture(X11->display, hd,
       
   520                                        XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
       
   521 
       
   522         xi = XCreateImage(dpy, visual, d, ZPixmap, 0, 0, w, h, 32, 0);
       
   523         Q_CHECK_PTR(xi);
       
   524         newbits = (uchar *)malloc(xi->bytes_per_line*h);
       
   525         Q_CHECK_PTR(newbits);
       
   526         xi->data = (char *)newbits;
       
   527 
       
   528         switch(cimage.format()) {
       
   529         case QImage::Format_Indexed8: {
       
   530             QVector<QRgb> colorTable = cimage.colorTable();
       
   531             uint *xidata = (uint *)xi->data;
       
   532             for (int y = 0; y < h; ++y) {
       
   533                 const uchar *p = cimage.scanLine(y);
       
   534                 for (int x = 0; x < w; ++x) {
       
   535                     const QRgb rgb = colorTable[p[x]];
       
   536                     const int a = qAlpha(rgb);
       
   537                     if (a == 0xff)
       
   538                         *xidata = rgb;
       
   539                     else
       
   540                         // RENDER expects premultiplied alpha
       
   541                         *xidata = qRgba(qt_div_255(qRed(rgb) * a),
       
   542                                         qt_div_255(qGreen(rgb) * a),
       
   543                                         qt_div_255(qBlue(rgb) * a),
       
   544                                         a);
       
   545                     ++xidata;
       
   546                 }
       
   547             }
       
   548         }
       
   549             break;
       
   550         case QImage::Format_RGB32: {
       
   551             uint *xidata = (uint *)xi->data;
       
   552             for (int y = 0; y < h; ++y) {
       
   553                 const QRgb *p = (const QRgb *) cimage.scanLine(y);
       
   554                 for (int x = 0; x < w; ++x)
       
   555                     *xidata++ = p[x] | 0xff000000;
       
   556             }
       
   557         }
       
   558             break;
       
   559         case QImage::Format_ARGB32: {
       
   560             uint *xidata = (uint *)xi->data;
       
   561             for (int y = 0; y < h; ++y) {
       
   562                 const QRgb *p = (const QRgb *) cimage.scanLine(y);
       
   563                 for (int x = 0; x < w; ++x) {
       
   564                     const QRgb rgb = p[x];
       
   565                     const int a = qAlpha(rgb);
       
   566                     if (a == 0xff)
       
   567                         *xidata = rgb;
       
   568                     else
       
   569                         // RENDER expects premultiplied alpha
       
   570                         *xidata = qRgba(qt_div_255(qRed(rgb) * a),
       
   571                                         qt_div_255(qGreen(rgb) * a),
       
   572                                         qt_div_255(qBlue(rgb) * a),
       
   573                                         a);
       
   574                     ++xidata;
       
   575                 }
       
   576             }
       
   577 
       
   578         }
       
   579             break;
       
   580         case QImage::Format_ARGB32_Premultiplied: {
       
   581             uint *xidata = (uint *)xi->data;
       
   582             for (int y = 0; y < h; ++y) {
       
   583                 const QRgb *p = (const QRgb *) cimage.scanLine(y);
       
   584                 memcpy(xidata, p, w*sizeof(QRgb));
       
   585                 xidata += w;
       
   586             }
       
   587         }
       
   588             break;
       
   589         default:
       
   590             Q_ASSERT(false);
       
   591         }
       
   592 
       
   593         if ((xi->byte_order == MSBFirst) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
       
   594             uint *xidata = (uint *)xi->data;
       
   595             uint *xiend = xidata + w*h;
       
   596             while (xidata < xiend) {
       
   597                 *xidata = (*xidata >> 24)
       
   598                           | ((*xidata >> 8) & 0xff00)
       
   599                           | ((*xidata << 8) & 0xff0000)
       
   600                           | (*xidata << 24);
       
   601                 ++xidata;
       
   602             }
       
   603         }
       
   604 
       
   605         GC gc = XCreateGC(dpy, hd, 0, 0);
       
   606         XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
       
   607         XFreeGC(dpy, gc);
       
   608 
       
   609         qSafeXDestroyImage(xi);
       
   610 
       
   611         return;
       
   612     }
       
   613 #endif // QT_NO_XRENDER
       
   614 
       
   615     if (trucol) {                                // truecolor display
       
   616         if (image.format() == QImage::Format_ARGB32_Premultiplied)
       
   617             image = image.convertToFormat(QImage::Format_ARGB32);
       
   618 
       
   619         const QImage &cimage = image;
       
   620         QRgb  pix[256];                                // pixel translation table
       
   621         const bool  d8 = (d == 8);
       
   622         const uint  red_mask          = (uint)visual->red_mask;
       
   623         const uint  green_mask  = (uint)visual->green_mask;
       
   624         const uint  blue_mask          = (uint)visual->blue_mask;
       
   625         const int   red_shift          = highest_bit(red_mask)   - 7;
       
   626         const int   green_shift = highest_bit(green_mask) - 7;
       
   627         const int   blue_shift  = highest_bit(blue_mask)  - 7;
       
   628         const uint  rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1;
       
   629         const uint  gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1;
       
   630         const uint  bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1;
       
   631 
       
   632         if (d8) {                                // setup pixel translation
       
   633             QVector<QRgb> ctable = cimage.colorTable();
       
   634             for (int i=0; i < cimage.numColors(); i++) {
       
   635                 int r = qRed  (ctable[i]);
       
   636                 int g = qGreen(ctable[i]);
       
   637                 int b = qBlue (ctable[i]);
       
   638                 r = red_shift        > 0 ? r << red_shift   : r >> -red_shift;
       
   639                 g = green_shift > 0 ? g << green_shift : g >> -green_shift;
       
   640                 b = blue_shift        > 0 ? b << blue_shift  : b >> -blue_shift;
       
   641                 pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask)
       
   642                          | ~(blue_mask | green_mask | red_mask);
       
   643             }
       
   644         }
       
   645 
       
   646         xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
       
   647         Q_CHECK_PTR(xi);
       
   648         newbits = (uchar *)malloc(xi->bytes_per_line*h);
       
   649         Q_CHECK_PTR(newbits);
       
   650         if (!newbits)                                // no memory
       
   651             return;
       
   652         int bppc = xi->bits_per_pixel;
       
   653 
       
   654         bool contig_bits = n_bits(red_mask) == rbits &&
       
   655                            n_bits(green_mask) == gbits &&
       
   656                            n_bits(blue_mask) == bbits;
       
   657         bool dither_tc =
       
   658             // Want it?
       
   659             (flags & Qt::Dither_Mask) != Qt::ThresholdDither &&
       
   660             (flags & Qt::DitherMode_Mask) != Qt::AvoidDither &&
       
   661             // Need it?
       
   662             bppc < 24 && !d8 &&
       
   663             // Can do it? (Contiguous bits?)
       
   664             contig_bits;
       
   665 
       
   666         static bool init=false;
       
   667         static int D[16][16];
       
   668         if (dither_tc && !init) {
       
   669             // I also contributed this code to XV - WWA.
       
   670             /*
       
   671               The dither matrix, D, is obtained with this formula:
       
   672 
       
   673               D2 = [0 2]
       
   674               [3 1]
       
   675 
       
   676 
       
   677               D2*n = [4*Dn       4*Dn+2*Un]
       
   678               [4*Dn+3*Un  4*Dn+1*Un]
       
   679             */
       
   680             int n,i,j;
       
   681             init=1;
       
   682 
       
   683             /* Set D2 */
       
   684             D[0][0]=0;
       
   685             D[1][0]=2;
       
   686             D[0][1]=3;
       
   687             D[1][1]=1;
       
   688 
       
   689             /* Expand using recursive definition given above */
       
   690             for (n=2; n<16; n*=2) {
       
   691                 for (i=0; i<n; i++) {
       
   692                     for (j=0; j<n; j++) {
       
   693                         D[i][j]*=4;
       
   694                         D[i+n][j]=D[i][j]+2;
       
   695                         D[i][j+n]=D[i][j]+3;
       
   696                         D[i+n][j+n]=D[i][j]+1;
       
   697                     }
       
   698                 }
       
   699             }
       
   700             init=true;
       
   701         }
       
   702 
       
   703         enum { BPP8,
       
   704                BPP16_565, BPP16_555,
       
   705                BPP16_MSB, BPP16_LSB,
       
   706                BPP24_888,
       
   707                BPP24_MSB, BPP24_LSB,
       
   708                BPP32_8888,
       
   709                BPP32_MSB, BPP32_LSB
       
   710         } mode = BPP8;
       
   711 
       
   712         bool same_msb_lsb = (xi->byte_order == MSBFirst) == (QSysInfo::ByteOrder == QSysInfo::BigEndian);
       
   713 
       
   714         if(bppc == 8) // 8 bit
       
   715             mode = BPP8;
       
   716         else if(bppc == 16) { // 16 bit MSB/LSB
       
   717             if(red_shift == 8 && green_shift == 3 && blue_shift == -3 && !d8 && same_msb_lsb)
       
   718                 mode = BPP16_565;
       
   719             else if(red_shift == 7 && green_shift == 2 && blue_shift == -3 && !d8 && same_msb_lsb)
       
   720                 mode = BPP16_555;
       
   721             else
       
   722                 mode = (xi->byte_order == LSBFirst) ? BPP16_LSB : BPP16_MSB;
       
   723         } else if(bppc == 24) { // 24 bit MSB/LSB
       
   724             if (red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
       
   725                 mode = BPP24_888;
       
   726             else
       
   727                 mode = (xi->byte_order == LSBFirst) ? BPP24_LSB : BPP24_MSB;
       
   728         } else if(bppc == 32) { // 32 bit MSB/LSB
       
   729             if(red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
       
   730                 mode = BPP32_8888;
       
   731             else
       
   732                 mode = (xi->byte_order == LSBFirst) ? BPP32_LSB : BPP32_MSB;
       
   733         } else
       
   734             qFatal("Logic error 3");
       
   735 
       
   736 #define GET_PIXEL                                                       \
       
   737         uint pixel;                                                     \
       
   738         if (d8) pixel = pix[*src++];                                    \
       
   739         else {                                                          \
       
   740             int r = qRed  (*p);                                         \
       
   741             int g = qGreen(*p);                                         \
       
   742             int b = qBlue (*p++);                                       \
       
   743             r = red_shift   > 0                                         \
       
   744                 ? r << red_shift   : r >> -red_shift;                   \
       
   745             g = green_shift > 0                                         \
       
   746                 ? g << green_shift : g >> -green_shift;                 \
       
   747             b = blue_shift  > 0                                         \
       
   748                 ? b << blue_shift  : b >> -blue_shift;                  \
       
   749             pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask)   \
       
   750                     | ~(blue_mask | green_mask | red_mask);             \
       
   751         }
       
   752 
       
   753 #define GET_PIXEL_DITHER_TC                                             \
       
   754         int r = qRed  (*p);                                             \
       
   755         int g = qGreen(*p);                                             \
       
   756         int b = qBlue (*p++);                                           \
       
   757         const int thres = D[x%16][y%16];                                \
       
   758         if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255)             \
       
   759             > thres)                                                    \
       
   760             r += (1<<(8-rbits));                                        \
       
   761         if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255)             \
       
   762             > thres)                                                    \
       
   763             g += (1<<(8-gbits));                                        \
       
   764         if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255)             \
       
   765             > thres)                                                    \
       
   766             b += (1<<(8-bbits));                                        \
       
   767         r = red_shift   > 0                                             \
       
   768             ? r << red_shift   : r >> -red_shift;                       \
       
   769         g = green_shift > 0                                             \
       
   770             ? g << green_shift : g >> -green_shift;                     \
       
   771         b = blue_shift  > 0                                             \
       
   772             ? b << blue_shift  : b >> -blue_shift;                      \
       
   773         uint pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask);
       
   774 
       
   775 // again, optimized case
       
   776 // can't be optimized that much :(
       
   777 #define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \
       
   778                                 rbits,gbits,bbits)                      \
       
   779         const int thres = D[x%16][y%16];                                \
       
   780         int r = qRed  (*p);                                             \
       
   781         if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255)             \
       
   782             > thres)                                                    \
       
   783             r += (1<<(8-rbits));                                        \
       
   784         int g = qGreen(*p);                                             \
       
   785         if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255)             \
       
   786             > thres)                                                    \
       
   787             g += (1<<(8-gbits));                                        \
       
   788         int b = qBlue (*p++);                                           \
       
   789         if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255)             \
       
   790             > thres)                                                    \
       
   791             b += (1<<(8-bbits));                                        \
       
   792         uint pixel = ((r red_shift) & red_mask)                         \
       
   793                      | ((g green_shift) & green_mask)                   \
       
   794                      | ((b blue_shift) & blue_mask);
       
   795 
       
   796 #define CYCLE(body)                                             \
       
   797         for (int y=0; y<h; y++) {                               \
       
   798             const uchar* src = cimage.scanLine(y);              \
       
   799             uchar* dst = newbits + xi->bytes_per_line*y;        \
       
   800             const QRgb* p = (const QRgb *)src;                  \
       
   801             body                                                \
       
   802                 }
       
   803 
       
   804         if (dither_tc) {
       
   805             switch (mode) {
       
   806             case BPP16_565:
       
   807                 CYCLE(
       
   808                     quint16* dst16 = (quint16*)dst;
       
   809                     for (int x=0; x<w; x++) {
       
   810                         GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)
       
   811                             *dst16++ = pixel;
       
   812                     }
       
   813                     )
       
   814                     break;
       
   815             case BPP16_555:
       
   816                 CYCLE(
       
   817                     quint16* dst16 = (quint16*)dst;
       
   818                     for (int x=0; x<w; x++) {
       
   819                         GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)
       
   820                             *dst16++ = pixel;
       
   821                     }
       
   822                     )
       
   823                     break;
       
   824             case BPP16_MSB:                        // 16 bit MSB
       
   825                 CYCLE(
       
   826                     for (int x=0; x<w; x++) {
       
   827                         GET_PIXEL_DITHER_TC
       
   828                             *dst++ = (pixel >> 8);
       
   829                         *dst++ = pixel;
       
   830                     }
       
   831                     )
       
   832                     break;
       
   833             case BPP16_LSB:                        // 16 bit LSB
       
   834                 CYCLE(
       
   835                     for (int x=0; x<w; x++) {
       
   836                         GET_PIXEL_DITHER_TC
       
   837                             *dst++ = pixel;
       
   838                         *dst++ = pixel >> 8;
       
   839                     }
       
   840                     )
       
   841                     break;
       
   842             default:
       
   843                 qFatal("Logic error");
       
   844             }
       
   845         } else {
       
   846             switch (mode) {
       
   847             case BPP8:                        // 8 bit
       
   848                 CYCLE(
       
   849                     Q_UNUSED(p);
       
   850                     for (int x=0; x<w; x++)
       
   851                         *dst++ = pix[*src++];
       
   852                     )
       
   853                     break;
       
   854             case BPP16_565:
       
   855                 CYCLE(
       
   856                     quint16* dst16 = (quint16*)dst;
       
   857                     for (int x = 0; x < w; x++) {
       
   858                         *dst16++ = ((*p >> 8) & 0xf800)
       
   859                                    | ((*p >> 5) & 0x7e0)
       
   860                                    | ((*p >> 3) & 0x1f);
       
   861                         ++p;
       
   862                     }
       
   863                     )
       
   864                     break;
       
   865             case BPP16_555:
       
   866                 CYCLE(
       
   867                     quint16* dst16 = (quint16*)dst;
       
   868                     for (int x=0; x<w; x++) {
       
   869                         *dst16++ = ((*p >> 9) & 0x7c00)
       
   870                                    | ((*p >> 6) & 0x3e0)
       
   871                                    | ((*p >> 3) & 0x1f);
       
   872                         ++p;
       
   873                     }
       
   874                     )
       
   875                     break;
       
   876             case BPP16_MSB:                        // 16 bit MSB
       
   877                 CYCLE(
       
   878                     for (int x=0; x<w; x++) {
       
   879                         GET_PIXEL
       
   880                             *dst++ = (pixel >> 8);
       
   881                         *dst++ = pixel;
       
   882                     }
       
   883                     )
       
   884                     break;
       
   885             case BPP16_LSB:                        // 16 bit LSB
       
   886                 CYCLE(
       
   887                     for (int x=0; x<w; x++) {
       
   888                         GET_PIXEL
       
   889                             *dst++ = pixel;
       
   890                         *dst++ = pixel >> 8;
       
   891                     }
       
   892                     )
       
   893                     break;
       
   894             case BPP24_888:                        // 24 bit MSB
       
   895                 CYCLE(
       
   896                     for (int x=0; x<w; x++) {
       
   897                         *dst++ = qRed  (*p);
       
   898                         *dst++ = qGreen(*p);
       
   899                         *dst++ = qBlue (*p++);
       
   900                     }
       
   901                     )
       
   902                     break;
       
   903             case BPP24_MSB:                        // 24 bit MSB
       
   904                 CYCLE(
       
   905                     for (int x=0; x<w; x++) {
       
   906                         GET_PIXEL
       
   907                             *dst++ = pixel >> 16;
       
   908                         *dst++ = pixel >> 8;
       
   909                         *dst++ = pixel;
       
   910                     }
       
   911                     )
       
   912                     break;
       
   913             case BPP24_LSB:                        // 24 bit LSB
       
   914                 CYCLE(
       
   915                     for (int x=0; x<w; x++) {
       
   916                         GET_PIXEL
       
   917                             *dst++ = pixel;
       
   918                         *dst++ = pixel >> 8;
       
   919                         *dst++ = pixel >> 16;
       
   920                     }
       
   921                     )
       
   922                     break;
       
   923             case BPP32_8888:
       
   924                 CYCLE(
       
   925                     memcpy(dst, p, w * 4);
       
   926                     )
       
   927                     break;
       
   928             case BPP32_MSB:                        // 32 bit MSB
       
   929                 CYCLE(
       
   930                     for (int x=0; x<w; x++) {
       
   931                         GET_PIXEL
       
   932                             *dst++ = pixel >> 24;
       
   933                         *dst++ = pixel >> 16;
       
   934                         *dst++ = pixel >> 8;
       
   935                         *dst++ = pixel;
       
   936                     }
       
   937                     )
       
   938                     break;
       
   939             case BPP32_LSB:                        // 32 bit LSB
       
   940                 CYCLE(
       
   941                     for (int x=0; x<w; x++) {
       
   942                         GET_PIXEL
       
   943                             *dst++ = pixel;
       
   944                         *dst++ = pixel >> 8;
       
   945                         *dst++ = pixel >> 16;
       
   946                         *dst++ = pixel >> 24;
       
   947                     }
       
   948                     )
       
   949                     break;
       
   950             default:
       
   951                 qFatal("Logic error 2");
       
   952             }
       
   953         }
       
   954         xi->data = (char *)newbits;
       
   955     }
       
   956 
       
   957     if (d == 8 && !trucol) {                        // 8 bit pixmap
       
   958         int  pop[256];                                // pixel popularity
       
   959 
       
   960         if (image.numColors() == 0)
       
   961             image.setNumColors(1);
       
   962 
       
   963         const QImage &cimage = image;
       
   964         memset(pop, 0, sizeof(int)*256);        // reset popularity array
       
   965         for (int i = 0; i < h; i++) {                        // for each scanline...
       
   966             const uchar* p = cimage.scanLine(i);
       
   967             const uchar *end = p + w;
       
   968             while (p < end)                        // compute popularity
       
   969                 pop[*p++]++;
       
   970         }
       
   971 
       
   972         newbits = (uchar *)malloc(nbytes);        // copy image into newbits
       
   973         Q_CHECK_PTR(newbits);
       
   974         if (!newbits)                                // no memory
       
   975             return;
       
   976         uchar* p = newbits;
       
   977         memcpy(p, cimage.bits(), nbytes);        // copy image data into newbits
       
   978 
       
   979         /*
       
   980          * The code below picks the most important colors. It is based on the
       
   981          * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.
       
   982          */
       
   983 
       
   984         struct PIX {                                // pixel sort element
       
   985             uchar r,g,b,n;                        // color + pad
       
   986             int          use;                                // popularity
       
   987             int          index;                        // index in colormap
       
   988             int          mindist;
       
   989         };
       
   990         int ncols = 0;
       
   991         for (int i=0; i< cimage.numColors(); i++) { // compute number of colors
       
   992             if (pop[i] > 0)
       
   993                 ncols++;
       
   994         }
       
   995         for (int i = cimage.numColors(); i < 256; i++) // ignore out-of-range pixels
       
   996             pop[i] = 0;
       
   997 
       
   998         // works since we make sure above to have at least
       
   999         // one color in the image
       
  1000         if (ncols == 0)
       
  1001             ncols = 1;
       
  1002 
       
  1003         PIX pixarr[256];                        // pixel array
       
  1004         PIX pixarr_sorted[256];                        // pixel array (sorted)
       
  1005         memset(pixarr, 0, ncols*sizeof(PIX));
       
  1006         PIX *px                   = &pixarr[0];
       
  1007         int  maxpop = 0;
       
  1008         int  maxpix = 0;
       
  1009         uint j = 0;
       
  1010         QVector<QRgb> ctable = cimage.colorTable();
       
  1011         for (int i = 0; i < 256; i++) {                // init pixel array
       
  1012             if (pop[i] > 0) {
       
  1013                 px->r = qRed  (ctable[i]);
       
  1014                 px->g = qGreen(ctable[i]);
       
  1015                 px->b = qBlue (ctable[i]);
       
  1016                 px->n = 0;
       
  1017                 px->use = pop[i];
       
  1018                 if (pop[i] > maxpop) {        // select most popular entry
       
  1019                     maxpop = pop[i];
       
  1020                     maxpix = j;
       
  1021                 }
       
  1022                 px->index = i;
       
  1023                 px->mindist = 1000000;
       
  1024                 px++;
       
  1025                 j++;
       
  1026             }
       
  1027         }
       
  1028         pixarr_sorted[0] = pixarr[maxpix];
       
  1029         pixarr[maxpix].use = 0;
       
  1030 
       
  1031         for (int i = 1; i < ncols; i++) {                // sort pixels
       
  1032             int minpix = -1, mindist = -1;
       
  1033             px = &pixarr_sorted[i-1];
       
  1034             int r = px->r;
       
  1035             int g = px->g;
       
  1036             int b = px->b;
       
  1037             int dist;
       
  1038             if ((i & 1) || i<10) {                // sort on max distance
       
  1039                 for (int j=0; j<ncols; j++) {
       
  1040                     px = &pixarr[j];
       
  1041                     if (px->use) {
       
  1042                         dist = (px->r - r)*(px->r - r) +
       
  1043                                (px->g - g)*(px->g - g) +
       
  1044                                (px->b - b)*(px->b - b);
       
  1045                         if (px->mindist > dist)
       
  1046                             px->mindist = dist;
       
  1047                         if (px->mindist > mindist) {
       
  1048                             mindist = px->mindist;
       
  1049                             minpix = j;
       
  1050                         }
       
  1051                     }
       
  1052                 }
       
  1053             } else {                                // sort on max popularity
       
  1054                 for (int j=0; j<ncols; j++) {
       
  1055                     px = &pixarr[j];
       
  1056                     if (px->use) {
       
  1057                         dist = (px->r - r)*(px->r - r) +
       
  1058                                (px->g - g)*(px->g - g) +
       
  1059                                (px->b - b)*(px->b - b);
       
  1060                         if (px->mindist > dist)
       
  1061                             px->mindist = dist;
       
  1062                         if (px->use > mindist) {
       
  1063                             mindist = px->use;
       
  1064                             minpix = j;
       
  1065                         }
       
  1066                     }
       
  1067                 }
       
  1068             }
       
  1069             pixarr_sorted[i] = pixarr[minpix];
       
  1070             pixarr[minpix].use = 0;
       
  1071         }
       
  1072 
       
  1073         QColormap cmap = QColormap::instance(xinfo.screen());
       
  1074         uint pix[256];                                // pixel translation table
       
  1075         px = &pixarr_sorted[0];
       
  1076         for (int i = 0; i < ncols; i++) {                // allocate colors
       
  1077             QColor c(px->r, px->g, px->b);
       
  1078             pix[px->index] = cmap.pixel(c);
       
  1079             px++;
       
  1080         }
       
  1081 
       
  1082         p = newbits;
       
  1083         for (int i = 0; i < nbytes; i++) {                // translate pixels
       
  1084             *p = pix[*p];
       
  1085             p++;
       
  1086         }
       
  1087     }
       
  1088 
       
  1089     if (!xi) {                                // X image not created
       
  1090         xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
       
  1091         if (xi->bits_per_pixel == 16) {        // convert 8 bpp ==> 16 bpp
       
  1092             ushort *p2;
       
  1093             int            p2inc = xi->bytes_per_line/sizeof(ushort);
       
  1094             ushort *newerbits = (ushort *)malloc(xi->bytes_per_line * h);
       
  1095             Q_CHECK_PTR(newerbits);
       
  1096             if (!newerbits)                                // no memory
       
  1097                 return;
       
  1098             uchar* p = newbits;
       
  1099             for (int y = 0; y < h; y++) {                // OOPS: Do right byte order!!
       
  1100                 p2 = newerbits + p2inc*y;
       
  1101                 for (int x = 0; x < w; x++)
       
  1102                     *p2++ = *p++;
       
  1103             }
       
  1104             free(newbits);
       
  1105             newbits = (uchar *)newerbits;
       
  1106         } else if (xi->bits_per_pixel != 8) {
       
  1107             qWarning("QPixmap::fromImage: Display not supported "
       
  1108                      "(bpp=%d)", xi->bits_per_pixel);
       
  1109         }
       
  1110         xi->data = (char *)newbits;
       
  1111     }
       
  1112 
       
  1113     hd = (Qt::HANDLE)XCreatePixmap(X11->display,
       
  1114                                    RootWindow(X11->display, xinfo.screen()),
       
  1115                                    w, h, dd);
       
  1116 
       
  1117     GC gc = XCreateGC(dpy, hd, 0, 0);
       
  1118     XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
       
  1119     XFreeGC(dpy, gc);
       
  1120 
       
  1121     qSafeXDestroyImage(xi);
       
  1122     d = dd;
       
  1123 
       
  1124 #ifndef QT_NO_XRENDER
       
  1125     if (X11->use_xrender) {
       
  1126         XRenderPictFormat *format = d == 1
       
  1127                                     ? XRenderFindStandardFormat(X11->display, PictStandardA1)
       
  1128                                     : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
       
  1129         picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
       
  1130     }
       
  1131 #endif
       
  1132 
       
  1133     if (alphaCheck.hasAlpha()) {
       
  1134         QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));
       
  1135         setMask(m);
       
  1136     }
       
  1137 }
       
  1138 
       
  1139 void QX11PixmapData::bitmapFromImage(const QImage &image)
       
  1140 {
       
  1141     QImage img = image.convertToFormat(QImage::Format_MonoLSB);
       
  1142     const QRgb c0 = QColor(Qt::black).rgb();
       
  1143     const QRgb c1 = QColor(Qt::white).rgb();
       
  1144     if (img.color(0) == c0 && img.color(1) == c1) {
       
  1145         img.invertPixels();
       
  1146         img.setColor(0, c1);
       
  1147         img.setColor(1, c0);
       
  1148     }
       
  1149 
       
  1150     char  *bits;
       
  1151     uchar *tmp_bits;
       
  1152     w = img.width();
       
  1153     h = img.height();
       
  1154     d = 1;
       
  1155     is_null = (w <= 0 || h <= 0);
       
  1156     int bpl = (w + 7) / 8;
       
  1157     int ibpl = img.bytesPerLine();
       
  1158     if (bpl != ibpl) {
       
  1159         tmp_bits = new uchar[bpl*h];
       
  1160         bits = (char *)tmp_bits;
       
  1161         uchar *p, *b;
       
  1162         int y;
       
  1163         b = tmp_bits;
       
  1164         p = img.scanLine(0);
       
  1165         for (y = 0; y < h; y++) {
       
  1166             memcpy(b, p, bpl);
       
  1167             b += bpl;
       
  1168             p += ibpl;
       
  1169         }
       
  1170     } else {
       
  1171         bits = (char *)img.bits();
       
  1172         tmp_bits = 0;
       
  1173     }
       
  1174     hd = (Qt::HANDLE)XCreateBitmapFromData(xinfo.display(),
       
  1175                                            RootWindow(xinfo.display(), xinfo.screen()),
       
  1176                                            bits, w, h);
       
  1177 
       
  1178 #ifndef QT_NO_XRENDER
       
  1179     if (X11->use_xrender)
       
  1180         picture = XRenderCreatePicture(X11->display, hd,
       
  1181                                        XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
       
  1182 #endif // QT_NO_XRENDER
       
  1183 
       
  1184     if (tmp_bits)                                // Avoid purify complaint
       
  1185         delete [] tmp_bits;
       
  1186 }
       
  1187 
       
  1188 void QX11PixmapData::fill(const QColor &fillColor)
       
  1189 {
       
  1190     if (fillColor.alpha() != 255) {
       
  1191 #ifndef QT_NO_XRENDER
       
  1192         if (X11->use_xrender) {
       
  1193             if (!picture || d != 32)
       
  1194                 convertToARGB32(/*preserveContents = */false);
       
  1195 
       
  1196             ::Picture src  = X11->getSolidFill(xinfo.screen(), fillColor);
       
  1197             XRenderComposite(X11->display, PictOpSrc, src, 0, picture,
       
  1198                              0, 0, width(), height(),
       
  1199                              0, 0, width(), height());
       
  1200         } else
       
  1201 #endif
       
  1202         {
       
  1203             QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied);
       
  1204             im.fill(PREMUL(fillColor.rgba()));
       
  1205             release();
       
  1206             fromImage(im, Qt::AutoColor | Qt::OrderedAlphaDither);
       
  1207         }
       
  1208         return;
       
  1209     }
       
  1210 
       
  1211     GC gc = XCreateGC(X11->display, hd, 0, 0);
       
  1212     if (depth() == 1) {
       
  1213         XSetForeground(X11->display, gc, qGray(fillColor.rgb()) > 127 ? 0 : 1);
       
  1214     } else if (X11->use_xrender && d >= 24) {
       
  1215         XSetForeground(X11->display, gc, fillColor.rgba());
       
  1216     } else {
       
  1217         XSetForeground(X11->display, gc,
       
  1218                        QColormap::instance(xinfo.screen()).pixel(fillColor));
       
  1219     }
       
  1220     XFillRectangle(X11->display, hd, gc, 0, 0, width(), height());
       
  1221     XFreeGC(X11->display, gc);
       
  1222 }
       
  1223 
       
  1224 QX11PixmapData::~QX11PixmapData()
       
  1225 {
       
  1226     release();
       
  1227 }
       
  1228 
       
  1229 void QX11PixmapData::release()
       
  1230 {
       
  1231     delete pengine;
       
  1232     pengine = 0;
       
  1233 
       
  1234     if (!X11)
       
  1235         return;
       
  1236 
       
  1237     if (x11_mask) {
       
  1238 #ifndef QT_NO_XRENDER
       
  1239         if (mask_picture)
       
  1240             XRenderFreePicture(X11->display, mask_picture);
       
  1241         mask_picture = 0;
       
  1242 #endif
       
  1243         XFreePixmap(X11->display, x11_mask);
       
  1244         x11_mask = 0;
       
  1245     }
       
  1246 
       
  1247     if (hd) {
       
  1248 #ifndef QT_NO_XRENDER
       
  1249         if (picture) {
       
  1250             XRenderFreePicture(X11->display, picture);
       
  1251             picture = 0;
       
  1252         }
       
  1253 #endif // QT_NO_XRENDER
       
  1254 
       
  1255         if (hd2) {
       
  1256             XFreePixmap(xinfo.display(), hd2);
       
  1257             hd2 = 0;
       
  1258         }
       
  1259         if (!(flags & Readonly))
       
  1260             XFreePixmap(xinfo.display(), hd);
       
  1261         hd = 0;
       
  1262     }
       
  1263 }
       
  1264 
       
  1265 QPixmap QX11PixmapData::alphaChannel() const
       
  1266 {
       
  1267     if (!hasAlphaChannel()) {
       
  1268         QPixmap pm(w, h);
       
  1269         pm.fill(Qt::white);
       
  1270         return pm;
       
  1271     }
       
  1272     QImage im(toImage());
       
  1273     return QPixmap::fromImage(im.alphaChannel(), Qt::OrderedDither);
       
  1274 }
       
  1275 
       
  1276 void QX11PixmapData::setAlphaChannel(const QPixmap &alpha)
       
  1277 {
       
  1278     QImage image(toImage());
       
  1279     image.setAlphaChannel(alpha.toImage());
       
  1280     release();
       
  1281     fromImage(image, Qt::OrderedDither | Qt::OrderedAlphaDither);
       
  1282 }
       
  1283 
       
  1284 
       
  1285 QBitmap QX11PixmapData::mask() const
       
  1286 {
       
  1287     QBitmap mask;
       
  1288 #ifndef QT_NO_XRENDER
       
  1289     if (picture && d == 32) {
       
  1290         // #### slow - there must be a better way..
       
  1291         mask = QBitmap::fromImage(toImage().createAlphaMask());
       
  1292     } else
       
  1293 #endif
       
  1294     if (d == 1) {
       
  1295         QX11PixmapData *that = const_cast<QX11PixmapData*>(this);
       
  1296         mask = QPixmap(that);
       
  1297     } else {
       
  1298         mask = mask_to_bitmap(xinfo.screen());
       
  1299     }
       
  1300     return mask;
       
  1301 }
       
  1302 
       
  1303 
       
  1304 /*!
       
  1305     Sets a mask bitmap.
       
  1306 
       
  1307     The \a newmask bitmap defines the clip mask for this pixmap. Every
       
  1308     pixel in \a newmask corresponds to a pixel in this pixmap. Pixel
       
  1309     value 1 means opaque and pixel value 0 means transparent. The mask
       
  1310     must have the same size as this pixmap.
       
  1311 
       
  1312     \warning Setting the mask on a pixmap will cause any alpha channel
       
  1313     data to be cleared. For example:
       
  1314     \snippet doc/src/snippets/image/image.cpp 2
       
  1315     Now, alpha and alphacopy are visually different.
       
  1316 
       
  1317     Setting a null mask resets the mask.
       
  1318 
       
  1319     The effect of this function is undefined when the pixmap is being
       
  1320     painted on.
       
  1321 
       
  1322     \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap
       
  1323     Transformations}, QBitmap
       
  1324 */
       
  1325 void QX11PixmapData::setMask(const QBitmap &newmask)
       
  1326 {
       
  1327     if (newmask.isNull()) { // clear mask
       
  1328 #ifndef QT_NO_XRENDER
       
  1329         if (picture && d == 32) {
       
  1330             QX11PixmapData newData(pixelType());
       
  1331             newData.resize(w, h);
       
  1332             newData.fill(Qt::black);
       
  1333             XRenderComposite(X11->display, PictOpOver,
       
  1334                              picture, 0, newData.picture,
       
  1335                              0, 0, 0, 0, 0, 0, w, h);
       
  1336             release();
       
  1337             *this = newData;
       
  1338             // the new QX11PixmapData object isn't referenced yet, so
       
  1339             // ref it
       
  1340             ref.ref();
       
  1341 
       
  1342             // the below is to make sure the QX11PixmapData destructor
       
  1343             // doesn't delete our newly created render picture
       
  1344             newData.hd = 0;
       
  1345             newData.x11_mask = 0;
       
  1346             newData.picture = 0;
       
  1347             newData.mask_picture = 0;
       
  1348             newData.hd2 = 0;
       
  1349         } else
       
  1350 #endif
       
  1351             if (x11_mask) {
       
  1352 #ifndef QT_NO_XRENDER
       
  1353                 if (picture) {
       
  1354                     XRenderPictureAttributes attrs;
       
  1355                     attrs.alpha_map = 0;
       
  1356                     XRenderChangePicture(X11->display, picture, CPAlphaMap,
       
  1357                                          &attrs);
       
  1358                 }
       
  1359                 if (mask_picture)
       
  1360                     XRenderFreePicture(X11->display, mask_picture);
       
  1361                 mask_picture = 0;
       
  1362 #endif
       
  1363                 XFreePixmap(X11->display, x11_mask);
       
  1364                 x11_mask = 0;
       
  1365             }
       
  1366         return;
       
  1367     }
       
  1368 
       
  1369 #ifndef QT_NO_XRENDER
       
  1370     if (picture && d == 32) {
       
  1371         XRenderComposite(X11->display, PictOpSrc,
       
  1372                          picture, newmask.x11PictureHandle(),
       
  1373                          picture, 0, 0, 0, 0, 0, 0, w, h);
       
  1374     } else
       
  1375 #endif
       
  1376         if (depth() == 1) {
       
  1377             XGCValues vals;
       
  1378             vals.function = GXand;
       
  1379             GC gc = XCreateGC(X11->display, hd, GCFunction, &vals);
       
  1380             XCopyArea(X11->display, newmask.handle(), hd, gc, 0, 0,
       
  1381                       width(), height(), 0, 0);
       
  1382             XFreeGC(X11->display, gc);
       
  1383         } else {
       
  1384             // ##### should or the masks together
       
  1385             if (x11_mask) {
       
  1386                 XFreePixmap(X11->display, x11_mask);
       
  1387 #ifndef QT_NO_XRENDER
       
  1388                 if (mask_picture)
       
  1389                     XRenderFreePicture(X11->display, mask_picture);
       
  1390 #endif
       
  1391             }
       
  1392             x11_mask = QX11PixmapData::bitmap_to_mask(newmask, xinfo.screen());
       
  1393 #ifndef QT_NO_XRENDER
       
  1394             if (picture) {
       
  1395                 mask_picture = XRenderCreatePicture(X11->display, x11_mask,
       
  1396                                                     XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
       
  1397                 XRenderPictureAttributes attrs;
       
  1398                 attrs.alpha_map = mask_picture;
       
  1399                 XRenderChangePicture(X11->display, picture, CPAlphaMap, &attrs);
       
  1400             }
       
  1401 #endif
       
  1402         }
       
  1403 }
       
  1404 
       
  1405 int QX11PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
       
  1406 {
       
  1407     switch (metric) {
       
  1408     case QPaintDevice::PdmWidth:
       
  1409         return w;
       
  1410     case QPaintDevice::PdmHeight:
       
  1411         return h;
       
  1412     case QPaintDevice::PdmNumColors:
       
  1413         return 1 << d;
       
  1414     case QPaintDevice::PdmDepth:
       
  1415         return d;
       
  1416     case QPaintDevice::PdmWidthMM: {
       
  1417         const int screen = xinfo.screen();
       
  1418         const int mm = DisplayWidthMM(X11->display, screen) * w
       
  1419                        / DisplayWidth(X11->display, screen);
       
  1420         return mm;
       
  1421     }
       
  1422     case QPaintDevice::PdmHeightMM: {
       
  1423         const int screen = xinfo.screen();
       
  1424         const int mm = (DisplayHeightMM(X11->display, screen) * h)
       
  1425                        / DisplayHeight(X11->display, screen);
       
  1426         return mm;
       
  1427     }
       
  1428     case QPaintDevice::PdmDpiX:
       
  1429     case QPaintDevice::PdmPhysicalDpiX:
       
  1430         return QX11Info::appDpiX(xinfo.screen());
       
  1431     case QPaintDevice::PdmDpiY:
       
  1432     case QPaintDevice::PdmPhysicalDpiY:
       
  1433         return QX11Info::appDpiY(xinfo.screen());
       
  1434     default:
       
  1435         qWarning("QX11PixmapData::metric(): Invalid metric");
       
  1436         return 0;
       
  1437     }
       
  1438 }
       
  1439 
       
  1440 /*!
       
  1441     Converts the pixmap to a QImage. Returns a null image if the
       
  1442     conversion fails.
       
  1443 
       
  1444     If the pixmap has 1-bit depth, the returned image will also be 1
       
  1445     bit deep. If the pixmap has 2- to 8-bit depth, the returned image
       
  1446     has 8-bit depth. If the pixmap has greater than 8-bit depth, the
       
  1447     returned image has 32-bit depth.
       
  1448 
       
  1449     Note that for the moment, alpha masks on monochrome images are
       
  1450     ignored.
       
  1451 
       
  1452     \sa fromImage(), {QImage#Image Formats}{Image Formats}
       
  1453 */
       
  1454 
       
  1455 QImage QX11PixmapData::toImage() const
       
  1456 {
       
  1457     int d = depth();
       
  1458     Visual *visual = (Visual *)xinfo.visual();
       
  1459     bool trucol = (visual->c_class >= TrueColor) && d > 1;
       
  1460 
       
  1461     QImage::Format format = QImage::Format_Mono;
       
  1462     if (d > 1 && d <= 8) {
       
  1463         d = 8;
       
  1464         format = QImage::Format_Indexed8;
       
  1465     }
       
  1466     // we could run into the situation where d == 8 AND trucol is true, which can
       
  1467     // cause problems when converting to and from images.  in this case, always treat
       
  1468     // the depth as 32...
       
  1469     if (d > 8 || trucol) {
       
  1470         d = 32;
       
  1471         format = QImage::Format_RGB32;
       
  1472     }
       
  1473 
       
  1474     XImage *xi = XGetImage(X11->display, hd, 0, 0, w, h, AllPlanes,
       
  1475                            (d == 1) ? XYPixmap : ZPixmap);
       
  1476 
       
  1477     Q_CHECK_PTR(xi);
       
  1478     if (!xi)
       
  1479         return QImage();
       
  1480 
       
  1481     if (picture && depth() == 32) {
       
  1482         QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
       
  1483         memcpy(image.bits(), xi->data, xi->bytes_per_line * xi->height);
       
  1484 
       
  1485         // we may have to swap the byte order
       
  1486         if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)
       
  1487             || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))
       
  1488         {
       
  1489             for (int i=0; i < image.height(); i++) {
       
  1490                 uint *p = (uint*)image.scanLine(i);
       
  1491                 uint *end = p + image.width();
       
  1492                 if ((xi->byte_order == LSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)
       
  1493                     || (xi->byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) {
       
  1494                     while (p < end) {
       
  1495                         *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
       
  1496                              | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
       
  1497                         p++;
       
  1498                     }
       
  1499                 } else if (xi->byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian) {
       
  1500                     while (p < end) {
       
  1501                         *p = ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff)
       
  1502                              | ((*p ) & 0xff00ff00);
       
  1503                         p++;
       
  1504                     }
       
  1505                 }
       
  1506             }
       
  1507         }
       
  1508 
       
  1509         // throw away image data
       
  1510         qSafeXDestroyImage(xi);
       
  1511 
       
  1512         return image;
       
  1513     }
       
  1514 
       
  1515     if (d == 1 && xi->bitmap_bit_order == LSBFirst)
       
  1516         format = QImage::Format_MonoLSB;
       
  1517     if (x11_mask && format == QImage::Format_RGB32)
       
  1518         format = QImage::Format_ARGB32;
       
  1519 
       
  1520     QImage image(w, h, format);
       
  1521     if (image.isNull())                        // could not create image
       
  1522         return image;
       
  1523 
       
  1524     QImage alpha;
       
  1525     if (x11_mask) {
       
  1526         alpha = mask().toImage();
       
  1527     }
       
  1528     bool ale = alpha.format() == QImage::Format_MonoLSB;
       
  1529 
       
  1530     if (trucol) {                                // truecolor
       
  1531         const uint red_mask = (uint)visual->red_mask;
       
  1532         const uint green_mask = (uint)visual->green_mask;
       
  1533         const uint blue_mask = (uint)visual->blue_mask;
       
  1534         const int  red_shift = highest_bit(red_mask) - 7;
       
  1535         const int  green_shift = highest_bit(green_mask) - 7;
       
  1536         const int  blue_shift = highest_bit(blue_mask) - 7;
       
  1537 
       
  1538         const uint red_bits = n_bits(red_mask);
       
  1539         const uint green_bits = n_bits(green_mask);
       
  1540         const uint blue_bits = n_bits(blue_mask);
       
  1541 
       
  1542         static uint red_table_bits = 0;
       
  1543         static uint green_table_bits = 0;
       
  1544         static uint blue_table_bits = 0;
       
  1545 
       
  1546         if (red_bits < 8 && red_table_bits != red_bits) {
       
  1547             build_scale_table(&red_scale_table, red_bits);
       
  1548             red_table_bits = red_bits;
       
  1549         }
       
  1550         if (blue_bits < 8 && blue_table_bits != blue_bits) {
       
  1551             build_scale_table(&blue_scale_table, blue_bits);
       
  1552             blue_table_bits = blue_bits;
       
  1553         }
       
  1554         if (green_bits < 8 && green_table_bits != green_bits) {
       
  1555             build_scale_table(&green_scale_table, green_bits);
       
  1556             green_table_bits = green_bits;
       
  1557         }
       
  1558 
       
  1559         int  r, g, b;
       
  1560 
       
  1561         QRgb *dst;
       
  1562         uchar *src;
       
  1563         uint pixel;
       
  1564         int bppc = xi->bits_per_pixel;
       
  1565 
       
  1566         if (bppc > 8 && xi->byte_order == LSBFirst)
       
  1567             bppc++;
       
  1568 
       
  1569         for (int y = 0; y < h; ++y) {
       
  1570             uchar* asrc = x11_mask ? alpha.scanLine(y) : 0;
       
  1571             dst = (QRgb *)image.scanLine(y);
       
  1572             src = (uchar *)xi->data + xi->bytes_per_line*y;
       
  1573             for (int x = 0; x < w; x++) {
       
  1574                 switch (bppc) {
       
  1575                 case 8:
       
  1576                     pixel = *src++;
       
  1577                     break;
       
  1578                 case 16:                        // 16 bit MSB
       
  1579                     pixel = src[1] | (uint)src[0] << 8;
       
  1580                     src += 2;
       
  1581                     break;
       
  1582                 case 17:                        // 16 bit LSB
       
  1583                     pixel = src[0] | (uint)src[1] << 8;
       
  1584                     src += 2;
       
  1585                     break;
       
  1586                 case 24:                        // 24 bit MSB
       
  1587                     pixel = src[2] | (uint)src[1] << 8 | (uint)src[0] << 16;
       
  1588                     src += 3;
       
  1589                     break;
       
  1590                 case 25:                        // 24 bit LSB
       
  1591                     pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16;
       
  1592                     src += 3;
       
  1593                     break;
       
  1594                 case 32:                        // 32 bit MSB
       
  1595                     pixel = src[3] | (uint)src[2] << 8 | (uint)src[1] << 16 | (uint)src[0] << 24;
       
  1596                     src += 4;
       
  1597                     break;
       
  1598                 case 33:                        // 32 bit LSB
       
  1599                     pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16 | (uint)src[3] << 24;
       
  1600                     src += 4;
       
  1601                     break;
       
  1602                 default:                        // should not really happen
       
  1603                     x = w;                        // leave loop
       
  1604                     y = h;
       
  1605                     pixel = 0;                // eliminate compiler warning
       
  1606                     qWarning("QPixmap::convertToImage: Invalid depth %d", bppc);
       
  1607                 }
       
  1608                 if (red_shift > 0)
       
  1609                     r = (pixel & red_mask) >> red_shift;
       
  1610                 else
       
  1611                     r = (pixel & red_mask) << -red_shift;
       
  1612                 if (green_shift > 0)
       
  1613                     g = (pixel & green_mask) >> green_shift;
       
  1614                 else
       
  1615                     g = (pixel & green_mask) << -green_shift;
       
  1616                 if (blue_shift > 0)
       
  1617                     b = (pixel & blue_mask) >> blue_shift;
       
  1618                 else
       
  1619                     b = (pixel & blue_mask) << -blue_shift;
       
  1620 
       
  1621                 if (red_bits < 8)
       
  1622                     r = red_scale_table[r];
       
  1623                 if (green_bits < 8)
       
  1624                     g = green_scale_table[g];
       
  1625                 if (blue_bits < 8)
       
  1626                     b = blue_scale_table[b];
       
  1627 
       
  1628                 if (x11_mask) {
       
  1629                     if (ale) {
       
  1630                         *dst++ = (asrc[x >> 3] & (1 << (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
       
  1631                     } else {
       
  1632                         *dst++ = (asrc[x >> 3] & (0x80 >> (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
       
  1633                     }
       
  1634                 } else {
       
  1635                     *dst++ = qRgb(r, g, b);
       
  1636                 }
       
  1637             }
       
  1638         }
       
  1639     } else if (xi->bits_per_pixel == d) {        // compatible depth
       
  1640         char *xidata = xi->data;                // copy each scanline
       
  1641         int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line);
       
  1642         for (int y=0; y<h; y++) {
       
  1643             memcpy(image.scanLine(y), xidata, bpl);
       
  1644             xidata += xi->bytes_per_line;
       
  1645         }
       
  1646     } else {
       
  1647         /* Typically 2 or 4 bits display depth */
       
  1648         qWarning("QPixmap::convertToImage: Display not supported (bpp=%d)",
       
  1649                  xi->bits_per_pixel);
       
  1650         return QImage();
       
  1651     }
       
  1652 
       
  1653     if (d == 1) {                                // bitmap
       
  1654         image.setNumColors(2);
       
  1655         image.setColor(0, qRgb(255,255,255));
       
  1656         image.setColor(1, qRgb(0,0,0));
       
  1657     } else if (!trucol) {                        // pixmap with colormap
       
  1658         register uchar *p;
       
  1659         uchar *end;
       
  1660         uchar  use[256];                        // pixel-in-use table
       
  1661         uchar  pix[256];                        // pixel translation table
       
  1662         int    ncols, bpl;
       
  1663         memset(use, 0, 256);
       
  1664         memset(pix, 0, 256);
       
  1665         bpl = image.bytesPerLine();
       
  1666 
       
  1667         if (x11_mask) {                         // which pixels are used?
       
  1668             for (int i = 0; i < h; i++) {
       
  1669                 uchar* asrc = alpha.scanLine(i);
       
  1670                 p = image.scanLine(i);
       
  1671                 if (ale) {
       
  1672                     for (int x = 0; x < w; x++) {
       
  1673                         if (asrc[x >> 3] & (1 << (x & 7)))
       
  1674                             use[*p] = 1;
       
  1675                         ++p;
       
  1676                     }
       
  1677                 } else {
       
  1678                     for (int x = 0; x < w; x++) {
       
  1679                         if (asrc[x >> 3] & (0x80 >> (x & 7)))
       
  1680                             use[*p] = 1;
       
  1681                         ++p;
       
  1682                     }
       
  1683                 }
       
  1684             }
       
  1685         } else {
       
  1686             for (int i = 0; i < h; i++) {
       
  1687                 p = image.scanLine(i);
       
  1688                 end = p + bpl;
       
  1689                 while (p < end)
       
  1690                     use[*p++] = 1;
       
  1691             }
       
  1692         }
       
  1693         ncols = 0;
       
  1694         for (int i = 0; i < 256; i++) {                // build translation table
       
  1695             if (use[i])
       
  1696                 pix[i] = ncols++;
       
  1697         }
       
  1698         for (int i = 0; i < h; i++) {                        // translate pixels
       
  1699             p = image.scanLine(i);
       
  1700             end = p + bpl;
       
  1701             while (p < end) {
       
  1702                 *p = pix[*p];
       
  1703                 p++;
       
  1704             }
       
  1705         }
       
  1706         if (x11_mask) {
       
  1707             int trans;
       
  1708             if (ncols < 256) {
       
  1709                 trans = ncols++;
       
  1710                 image.setNumColors(ncols);        // create color table
       
  1711                 image.setColor(trans, 0x00000000);
       
  1712             } else {
       
  1713                 image.setNumColors(ncols);        // create color table
       
  1714                 // oh dear... no spare "transparent" pixel.
       
  1715                 // use first pixel in image (as good as any).
       
  1716                 trans = image.scanLine(0)[0];
       
  1717             }
       
  1718             for (int i = 0; i < h; i++) {
       
  1719                 uchar* asrc = alpha.scanLine(i);
       
  1720                 p = image.scanLine(i);
       
  1721                 if (ale) {
       
  1722                     for (int x = 0; x < w; x++) {
       
  1723                         if (!(asrc[x >> 3] & (1 << (x & 7))))
       
  1724                             *p = trans;
       
  1725                         ++p;
       
  1726                     }
       
  1727                 } else {
       
  1728                     for (int x = 0; x < w; x++) {
       
  1729                         if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))
       
  1730                             *p = trans;
       
  1731                         ++p;
       
  1732                     }
       
  1733                 }
       
  1734             }
       
  1735         } else {
       
  1736             image.setNumColors(ncols);        // create color table
       
  1737         }
       
  1738         QVector<QColor> colors = QColormap::instance(xinfo.screen()).colormap();
       
  1739         int j = 0;
       
  1740         for (int i=0; i<colors.size(); i++) {                // translate pixels
       
  1741             if (use[i])
       
  1742                 image.setColor(j++, 0xff000000 | colors.at(i).rgb());
       
  1743         }
       
  1744     }
       
  1745 
       
  1746     qSafeXDestroyImage(xi);
       
  1747 
       
  1748     return image;
       
  1749 }
       
  1750 
       
  1751 /*!
       
  1752     Returns a copy of the pixmap that is transformed using the given
       
  1753     transformation \a matrix and transformation \a mode. The original
       
  1754     pixmap is not changed.
       
  1755 
       
  1756     The transformation \a matrix is internally adjusted to compensate
       
  1757     for unwanted translation; i.e. the pixmap produced is the smallest
       
  1758     pixmap that contains all the transformed points of the original
       
  1759     pixmap. Use the trueMatrix() function to retrieve the actual
       
  1760     matrix used for transforming the pixmap.
       
  1761 
       
  1762     This function is slow because it involves transformation to a
       
  1763     QImage, non-trivial computations and a transformation back to a
       
  1764     QPixmap.
       
  1765 
       
  1766     \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap
       
  1767     Transformations}
       
  1768 */
       
  1769 QPixmap QX11PixmapData::transformed(const QTransform &transform,
       
  1770                                     Qt::TransformationMode mode ) const
       
  1771 {
       
  1772     if (mode == Qt::SmoothTransformation || transform.type() >= QTransform::TxProject) {
       
  1773         QImage image = toImage();
       
  1774         return QPixmap::fromImage(image.transformed(transform, mode));
       
  1775     }
       
  1776 
       
  1777     uint   w = 0;
       
  1778     uint   h = 0;                               // size of target pixmap
       
  1779     uint   ws, hs;                              // size of source pixmap
       
  1780     uchar *dptr;                                // data in target pixmap
       
  1781     uint   dbpl, dbytes;                        // bytes per line/bytes total
       
  1782     uchar *sptr;                                // data in original pixmap
       
  1783     int    sbpl;                                // bytes per line in original
       
  1784     int    bpp;                                 // bits per pixel
       
  1785     bool   depth1 = depth() == 1;
       
  1786     Display *dpy = X11->display;
       
  1787 
       
  1788     ws = width();
       
  1789     hs = height();
       
  1790 
       
  1791     QTransform mat(transform.m11(), transform.m12(), transform.m13(),
       
  1792                    transform.m21(), transform.m22(), transform.m23(),
       
  1793                    0., 0., 1);
       
  1794     bool complex_xform = false;
       
  1795     qreal scaledWidth;
       
  1796     qreal scaledHeight;
       
  1797 
       
  1798     if (mat.type() <= QTransform::TxScale) {
       
  1799         scaledHeight = qAbs(mat.m22()) * hs + 0.9999;
       
  1800         scaledWidth = qAbs(mat.m11()) * ws + 0.9999;
       
  1801         h = qAbs(int(scaledHeight));
       
  1802         w = qAbs(int(scaledWidth));
       
  1803     } else {                                        // rotation or shearing
       
  1804         QPolygonF a(QRectF(0, 0, ws, hs));
       
  1805         a = mat.map(a);
       
  1806         QRect r = a.boundingRect().toAlignedRect();
       
  1807         w = r.width();
       
  1808         h = r.height();
       
  1809         scaledWidth = w;
       
  1810         scaledHeight = h;
       
  1811         complex_xform = true;
       
  1812     }
       
  1813     mat = QPixmap::trueMatrix(mat, ws, hs); // true matrix
       
  1814 
       
  1815     bool invertible;
       
  1816     mat = mat.inverted(&invertible);  // invert matrix
       
  1817 
       
  1818     if (h == 0 || w == 0 || !invertible
       
  1819         || qAbs(scaledWidth) >= 32768 || qAbs(scaledHeight) >= 32768 )
       
  1820 	// error, return null pixmap
       
  1821         return QPixmap();
       
  1822 
       
  1823 #if defined(QT_MITSHM)
       
  1824     static bool try_once = true;
       
  1825     if (try_once) {
       
  1826         try_once = false;
       
  1827         if (!xshminit)
       
  1828             qt_create_mitshm_buffer(this, 800, 600);
       
  1829     }
       
  1830 
       
  1831     bool use_mitshm = xshmimg && !depth1 &&
       
  1832                       xshmimg->width >= w && xshmimg->height >= h;
       
  1833 #endif
       
  1834     XImage *xi = XGetImage(X11->display, handle(), 0, 0, ws, hs, AllPlanes,
       
  1835                            depth1 ? XYPixmap : ZPixmap);
       
  1836 
       
  1837     if (!xi)
       
  1838         return QPixmap();
       
  1839 
       
  1840     sbpl = xi->bytes_per_line;
       
  1841     sptr = (uchar *)xi->data;
       
  1842     bpp         = xi->bits_per_pixel;
       
  1843 
       
  1844     if (depth1)
       
  1845         dbpl = (w+7)/8;
       
  1846     else
       
  1847         dbpl = ((w*bpp+31)/32)*4;
       
  1848     dbytes = dbpl*h;
       
  1849 
       
  1850 #if defined(QT_MITSHM)
       
  1851     if (use_mitshm) {
       
  1852         dptr = (uchar *)xshmimg->data;
       
  1853         uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
       
  1854         for (int y=0; y<h; y++)
       
  1855             memset(dptr + y*xshmimg->bytes_per_line, fillbyte, dbpl);
       
  1856     } else {
       
  1857 #endif
       
  1858         dptr = (uchar *)malloc(dbytes);        // create buffer for bits
       
  1859         Q_CHECK_PTR(dptr);
       
  1860         if (depth1)                                // fill with zeros
       
  1861             memset(dptr, 0, dbytes);
       
  1862         else if (bpp == 8)                        // fill with background color
       
  1863             memset(dptr, WhitePixel(X11->display, xinfo.screen()), dbytes);
       
  1864         else
       
  1865             memset(dptr, 0, dbytes);
       
  1866 #if defined(QT_MITSHM)
       
  1867     }
       
  1868 #endif
       
  1869 
       
  1870     // #define QT_DEBUG_XIMAGE
       
  1871 #if defined(QT_DEBUG_XIMAGE)
       
  1872     qDebug("----IMAGE--INFO--------------");
       
  1873     qDebug("width............. %d", xi->width);
       
  1874     qDebug("height............ %d", xi->height);
       
  1875     qDebug("xoffset........... %d", xi->xoffset);
       
  1876     qDebug("format............ %d", xi->format);
       
  1877     qDebug("byte order........ %d", xi->byte_order);
       
  1878     qDebug("bitmap unit....... %d", xi->bitmap_unit);
       
  1879     qDebug("bitmap bit order.. %d", xi->bitmap_bit_order);
       
  1880     qDebug("depth............. %d", xi->depth);
       
  1881     qDebug("bytes per line.... %d", xi->bytes_per_line);
       
  1882     qDebug("bits per pixel.... %d", xi->bits_per_pixel);
       
  1883 #endif
       
  1884 
       
  1885     int type;
       
  1886     if (xi->bitmap_bit_order == MSBFirst)
       
  1887         type = QT_XFORM_TYPE_MSBFIRST;
       
  1888     else
       
  1889         type = QT_XFORM_TYPE_LSBFIRST;
       
  1890     int        xbpl, p_inc;
       
  1891     if (depth1) {
       
  1892         xbpl  = (w+7)/8;
       
  1893         p_inc = dbpl - xbpl;
       
  1894     } else {
       
  1895         xbpl  = (w*bpp)/8;
       
  1896         p_inc = dbpl - xbpl;
       
  1897 #if defined(QT_MITSHM)
       
  1898         if (use_mitshm)
       
  1899             p_inc = xshmimg->bytes_per_line - xbpl;
       
  1900 #endif
       
  1901     }
       
  1902 
       
  1903     if (!qt_xForm_helper(mat, xi->xoffset, type, bpp, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs)){
       
  1904         qWarning("QPixmap::transform: display not supported (bpp=%d)",bpp);
       
  1905         QPixmap pm;
       
  1906         return pm;
       
  1907     }
       
  1908 
       
  1909     qSafeXDestroyImage(xi);
       
  1910 
       
  1911     if (depth1) {                                // mono bitmap
       
  1912         QBitmap bm = QBitmap::fromData(QSize(w, h), dptr,
       
  1913                                        BitmapBitOrder(X11->display) == MSBFirst
       
  1914                                        ? QImage::Format_Mono
       
  1915                                        : QImage::Format_MonoLSB);
       
  1916         free(dptr);
       
  1917         return bm;
       
  1918     } else {                                        // color pixmap
       
  1919         QPixmap pm;
       
  1920         QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(pm.data.data());
       
  1921         x11Data->flags &= ~QX11PixmapData::Uninitialized;
       
  1922         x11Data->xinfo = xinfo;
       
  1923         x11Data->d = d;
       
  1924         x11Data->w = w;
       
  1925         x11Data->h = h;
       
  1926         x11Data->is_null = (w <= 0 || h <= 0);
       
  1927         x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,
       
  1928                                                 RootWindow(X11->display, xinfo.screen()),
       
  1929                                                 w, h, d);
       
  1930 #ifndef QT_NO_XRENDER
       
  1931         if (X11->use_xrender) {
       
  1932             XRenderPictFormat *format = x11Data->d == 32
       
  1933                                         ? XRenderFindStandardFormat(X11->display, PictStandardARGB32)
       
  1934                                         : XRenderFindVisualFormat(X11->display, (Visual *) x11Data->xinfo.visual());
       
  1935             x11Data->picture = XRenderCreatePicture(X11->display, x11Data->hd, format, 0, 0);
       
  1936         }
       
  1937 #endif // QT_NO_XRENDER
       
  1938 
       
  1939         GC gc = XCreateGC(X11->display, x11Data->hd, 0, 0);
       
  1940 #if defined(QT_MITSHM)
       
  1941         if (use_mitshm) {
       
  1942             XCopyArea(dpy, xshmpm, x11Data->hd, gc, 0, 0, w, h, 0, 0);
       
  1943         } else
       
  1944 #endif
       
  1945         {
       
  1946             xi = XCreateImage(dpy, (Visual*)x11Data->xinfo.visual(),
       
  1947                               x11Data->d,
       
  1948                               ZPixmap, 0, (char *)dptr, w, h, 32, 0);
       
  1949             XPutImage(dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
       
  1950             qSafeXDestroyImage(xi);
       
  1951         }
       
  1952         XFreeGC(X11->display, gc);
       
  1953 
       
  1954         if (x11_mask) { // xform mask, too
       
  1955             pm.setMask(mask_to_bitmap(xinfo.screen()).transformed(transform));
       
  1956         } else if (d != 32 && complex_xform) { // need a mask!
       
  1957             QBitmap mask(ws, hs);
       
  1958             mask.fill(Qt::color1);
       
  1959             pm.setMask(mask.transformed(transform));
       
  1960         }
       
  1961         return pm;
       
  1962     }
       
  1963 }
       
  1964 
       
  1965 int QPixmap::x11SetDefaultScreen(int screen)
       
  1966 {
       
  1967     int old = defaultScreen;
       
  1968     defaultScreen = screen;
       
  1969     return old;
       
  1970 }
       
  1971 
       
  1972 void QPixmap::x11SetScreen(int screen)
       
  1973 {
       
  1974     if (paintingActive()) {
       
  1975         qWarning("QPixmap::x11SetScreen(): Cannot change screens during painting");
       
  1976         return;
       
  1977     }
       
  1978 
       
  1979     if (data->classId() != QPixmapData::X11Class)
       
  1980         return;
       
  1981 
       
  1982     if (screen < 0)
       
  1983         screen = QX11Info::appScreen();
       
  1984 
       
  1985     QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(data.data());
       
  1986     if (screen == x11Data->xinfo.screen())
       
  1987         return; // nothing to do
       
  1988 
       
  1989     if (isNull()) {
       
  1990         QX11InfoData* xd = x11Data->xinfo.getX11Data(true);
       
  1991         xd->screen = screen;
       
  1992         xd->depth = QX11Info::appDepth(screen);
       
  1993         xd->cells = QX11Info::appCells(screen);
       
  1994         xd->colormap = QX11Info::appColormap(screen);
       
  1995         xd->defaultColormap = QX11Info::appDefaultColormap(screen);
       
  1996         xd->visual = (Visual *)QX11Info::appVisual(screen);
       
  1997         xd->defaultVisual = QX11Info::appDefaultVisual(screen);
       
  1998         x11Data->xinfo.setX11Data(xd);
       
  1999         return;
       
  2000     }
       
  2001 #if 0
       
  2002     qDebug("QPixmap::x11SetScreen for %p from %d to %d. Size is %d/%d", x11Data, x11Data->xinfo.screen(), screen, width(), height());
       
  2003 #endif
       
  2004 
       
  2005     x11SetDefaultScreen(screen);
       
  2006     *this = qt_toX11Pixmap(toImage());
       
  2007 }
       
  2008 
       
  2009 QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
       
  2010 {
       
  2011     if (w == 0 || h == 0)
       
  2012         return QPixmap();
       
  2013 
       
  2014     Display *dpy = X11->display;
       
  2015     XWindowAttributes window_attr;
       
  2016     if (!XGetWindowAttributes(dpy, window, &window_attr))
       
  2017         return QPixmap();
       
  2018 
       
  2019     if (w < 0)
       
  2020         w = window_attr.width - x;
       
  2021     if (h < 0)
       
  2022         h = window_attr.height - y;
       
  2023 
       
  2024     // determine the screen
       
  2025     int scr;
       
  2026     for (scr = 0; scr < ScreenCount(dpy); ++scr) {
       
  2027         if (window_attr.root == RootWindow(dpy, scr))        // found it
       
  2028             break;
       
  2029     }
       
  2030     if (scr >= ScreenCount(dpy))                // sanity check
       
  2031         return QPixmap();
       
  2032 
       
  2033 
       
  2034     // get the depth of the root window
       
  2035     XWindowAttributes root_attr;
       
  2036     if (!XGetWindowAttributes(dpy, window_attr.root, &root_attr))
       
  2037         return QPixmap();
       
  2038 
       
  2039     if (window_attr.depth == root_attr.depth) {
       
  2040         // if the depth of the specified window and the root window are the
       
  2041         // same, grab pixels from the root window (so that we get the any
       
  2042         // overlapping windows and window manager frames)
       
  2043 
       
  2044         // map x and y to the root window
       
  2045         WId unused;
       
  2046         if (!XTranslateCoordinates(dpy, window, window_attr.root, x, y,
       
  2047                                    &x, &y, &unused))
       
  2048             return QPixmap();
       
  2049 
       
  2050         window = window_attr.root;
       
  2051         window_attr = root_attr;
       
  2052     }
       
  2053 
       
  2054     QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType);
       
  2055 
       
  2056     void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a);
       
  2057     qt_x11_getX11InfoForWindow(&data->xinfo,window_attr);
       
  2058 
       
  2059     data->resize(w, h);
       
  2060 
       
  2061     QPixmap pm(data);
       
  2062 
       
  2063     data->flags &= ~QX11PixmapData::Uninitialized;
       
  2064     pm.x11SetScreen(scr);
       
  2065 
       
  2066     GC gc = XCreateGC(dpy, pm.handle(), 0, 0);
       
  2067     XSetSubwindowMode(dpy, gc, IncludeInferiors);
       
  2068     XCopyArea(dpy, window, pm.handle(), gc, x, y, w, h, 0, 0);
       
  2069     XFreeGC(dpy, gc);
       
  2070 
       
  2071     return pm;
       
  2072 }
       
  2073 
       
  2074 bool QX11PixmapData::hasAlphaChannel() const
       
  2075 {
       
  2076     return d == 32;
       
  2077 }
       
  2078 
       
  2079 const QX11Info &QPixmap::x11Info() const
       
  2080 {
       
  2081     if (data->classId() == QPixmapData::X11Class)
       
  2082         return static_cast<QX11PixmapData*>(data.data())->xinfo;
       
  2083     else {
       
  2084         static QX11Info nullX11Info;
       
  2085         return nullX11Info;
       
  2086     }
       
  2087 }
       
  2088 
       
  2089 #if !defined(QT_NO_XRENDER)
       
  2090 static XRenderPictFormat *qt_renderformat_for_depth(const QX11Info &xinfo, int depth)
       
  2091 {
       
  2092     if (depth == 1)
       
  2093         return XRenderFindStandardFormat(X11->display, PictStandardA1);
       
  2094     else if (depth == 32)
       
  2095         return XRenderFindStandardFormat(X11->display, PictStandardARGB32);
       
  2096     else
       
  2097         return XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
       
  2098 }
       
  2099 #endif
       
  2100 
       
  2101 QPaintEngine* QX11PixmapData::paintEngine() const
       
  2102 {
       
  2103     QX11PixmapData *that = const_cast<QX11PixmapData*>(this);
       
  2104 
       
  2105     if ((flags & Readonly) && share_mode == QPixmap::ImplicitlyShared) {
       
  2106         // if someone wants to draw onto us, copy the shared contents
       
  2107         // and turn it into a fully fledged QPixmap
       
  2108         ::Pixmap hd_copy = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
       
  2109                                          w, h, d);
       
  2110 #if !defined(QT_NO_XRENDER)
       
  2111         XRenderPictFormat *format = qt_renderformat_for_depth(xinfo, d);
       
  2112         ::Picture picture_copy = XRenderCreatePicture(X11->display, hd_copy, format, 0, 0);
       
  2113 
       
  2114         if (picture && d == 32) {
       
  2115             XRenderComposite(X11->display, PictOpSrc, picture, 0, picture_copy,
       
  2116                              0, 0, 0, 0, 0, 0, w, h);
       
  2117             XRenderFreePicture(X11->display, picture);
       
  2118             that->picture = picture_copy;
       
  2119         } else
       
  2120 #endif
       
  2121         {
       
  2122             GC gc = XCreateGC(X11->display, hd_copy, 0, 0);
       
  2123             XCopyArea(X11->display, hd, hd_copy, gc, 0, 0, w, h, 0, 0);
       
  2124             XFreeGC(X11->display, gc);
       
  2125         }
       
  2126         that->hd = hd_copy;
       
  2127         that->flags &= ~QX11PixmapData::Readonly;
       
  2128     }
       
  2129 
       
  2130     if (!that->pengine)
       
  2131         that->pengine = new QX11PaintEngine;
       
  2132     return that->pengine;
       
  2133 }
       
  2134 
       
  2135 Qt::HANDLE QPixmap::x11PictureHandle() const
       
  2136 {
       
  2137 #ifndef QT_NO_XRENDER
       
  2138     if (data->classId() == QPixmapData::X11Class)
       
  2139         return static_cast<const QX11PixmapData*>(data.data())->picture;
       
  2140     else
       
  2141         return 0;
       
  2142 #else
       
  2143     return 0;
       
  2144 #endif // QT_NO_XRENDER
       
  2145 }
       
  2146 
       
  2147 Qt::HANDLE QX11PixmapData::x11ConvertToDefaultDepth()
       
  2148 {
       
  2149 #ifndef QT_NO_XRENDER
       
  2150     if (d == QX11Info::appDepth() || !X11->use_xrender)
       
  2151         return hd;
       
  2152     if (!hd2) {
       
  2153         hd2 = XCreatePixmap(xinfo.display(), hd, w, h, QX11Info::appDepth());
       
  2154         XRenderPictFormat *format = XRenderFindVisualFormat(xinfo.display(),
       
  2155                                                             (Visual*) xinfo.visual());
       
  2156         Picture pic = XRenderCreatePicture(xinfo.display(), hd2, format, 0, 0);
       
  2157         XRenderComposite(xinfo.display(), PictOpSrc, picture,
       
  2158                          XNone, pic, 0, 0, 0, 0, 0, 0, w, h);
       
  2159         XRenderFreePicture(xinfo.display(), pic);
       
  2160     }
       
  2161     return hd2;
       
  2162 #else
       
  2163     return hd;
       
  2164 #endif
       
  2165 }
       
  2166 
       
  2167 void QX11PixmapData::copy(const QPixmapData *data, const QRect &rect)
       
  2168 {
       
  2169     if (data->pixelType() == BitmapType) {
       
  2170         fromImage(data->toImage().copy(rect), Qt::AutoColor);
       
  2171         return;
       
  2172     }
       
  2173 
       
  2174     const QX11PixmapData *x11Data = static_cast<const QX11PixmapData*>(data);
       
  2175 
       
  2176     setSerialNumber(++qt_pixmap_serial);
       
  2177 
       
  2178     flags &= ~Uninitialized;
       
  2179     xinfo = x11Data->xinfo;
       
  2180     d = x11Data->d;
       
  2181     w = rect.width();
       
  2182     h = rect.height();
       
  2183     is_null = (w <= 0 || h <= 0);
       
  2184     hd = (Qt::HANDLE)XCreatePixmap(X11->display,
       
  2185                                    RootWindow(X11->display, x11Data->xinfo.screen()),
       
  2186                                    w, h, d);
       
  2187 #ifndef QT_NO_XRENDER
       
  2188     if (X11->use_xrender) {
       
  2189         XRenderPictFormat *format = d == 32
       
  2190                                     ? XRenderFindStandardFormat(X11->display, PictStandardARGB32)
       
  2191                                     : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
       
  2192         picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
       
  2193     }
       
  2194 #endif // QT_NO_XRENDER
       
  2195     if (x11Data->x11_mask) {
       
  2196         x11_mask = XCreatePixmap(X11->display, hd, w, h, 1);
       
  2197 #ifndef QT_NO_XRENDER
       
  2198         if (X11->use_xrender) {
       
  2199             mask_picture = XRenderCreatePicture(X11->display, x11_mask,
       
  2200                                                 XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
       
  2201             XRenderPictureAttributes attrs;
       
  2202             attrs.alpha_map = x11Data->mask_picture;
       
  2203             XRenderChangePicture(X11->display, x11Data->picture, CPAlphaMap, &attrs);
       
  2204         }
       
  2205 #endif
       
  2206     }
       
  2207 
       
  2208 #if !defined(QT_NO_XRENDER)
       
  2209     if (x11Data->picture && x11Data->d == 32) {
       
  2210         XRenderComposite(X11->display, PictOpSrc,
       
  2211                          x11Data->picture, 0, picture,
       
  2212                          rect.x(), rect.y(), 0, 0, 0, 0, w, h);
       
  2213     } else
       
  2214 #endif
       
  2215     {
       
  2216         GC gc = XCreateGC(X11->display, hd, 0, 0);
       
  2217         XCopyArea(X11->display, x11Data->hd, hd, gc,
       
  2218                   rect.x(), rect.y(), w, h, 0, 0);
       
  2219         if (x11Data->x11_mask) {
       
  2220             GC monogc = XCreateGC(X11->display, x11_mask, 0, 0);
       
  2221             XCopyArea(X11->display, x11Data->x11_mask, x11_mask, monogc,
       
  2222                       rect.x(), rect.y(), w, h, 0, 0);
       
  2223             XFreeGC(X11->display, monogc);
       
  2224         }
       
  2225         XFreeGC(X11->display, gc);
       
  2226     }
       
  2227 }
       
  2228 
       
  2229 bool QX11PixmapData::scroll(int dx, int dy, const QRect &rect)
       
  2230 {
       
  2231     GC gc = XCreateGC(X11->display, hd, 0, 0);
       
  2232     XCopyArea(X11->display, hd, hd, gc,
       
  2233               rect.left(), rect.top(), rect.width(), rect.height(),
       
  2234               rect.left() + dx, rect.top() + dy);
       
  2235     XFreeGC(X11->display, gc);
       
  2236     return true;
       
  2237 }
       
  2238 
       
  2239 #if !defined(QT_NO_XRENDER)
       
  2240 void QX11PixmapData::convertToARGB32(bool preserveContents)
       
  2241 {
       
  2242     if (!X11->use_xrender)
       
  2243         return;
       
  2244 
       
  2245     // Q_ASSERT(count == 1);
       
  2246     if ((flags & Readonly) && share_mode == QPixmap::ExplicitlyShared)
       
  2247         return;
       
  2248 
       
  2249     Pixmap pm = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
       
  2250                               w, h, 32);
       
  2251     Picture p = XRenderCreatePicture(X11->display, pm,
       
  2252                                      XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
       
  2253     if (picture) {
       
  2254         if (preserveContents)
       
  2255             XRenderComposite(X11->display, PictOpSrc, picture, 0, p, 0, 0, 0, 0, 0, 0, w, h);
       
  2256         if (!(flags & Readonly))
       
  2257             XRenderFreePicture(X11->display, picture);
       
  2258     }
       
  2259     if (hd && !(flags & Readonly))
       
  2260         XFreePixmap(X11->display, hd);
       
  2261     if (x11_mask) {
       
  2262         XFreePixmap(X11->display, x11_mask);
       
  2263         if (mask_picture)
       
  2264             XRenderFreePicture(X11->display, mask_picture);
       
  2265         x11_mask = 0;
       
  2266         mask_picture = 0;
       
  2267     }
       
  2268     hd = pm;
       
  2269     picture = p;
       
  2270     d = 32;
       
  2271 }
       
  2272 #endif
       
  2273 
       
  2274 QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap, QPixmap::ShareMode mode)
       
  2275 {
       
  2276     Window root;
       
  2277     int x;
       
  2278     int y;
       
  2279     uint width;
       
  2280     uint height;
       
  2281     uint border_width;
       
  2282     uint depth;
       
  2283     XWindowAttributes win_attribs;
       
  2284     int num_screens = ScreenCount(X11->display);
       
  2285     int screen = 0;
       
  2286 
       
  2287     XGetGeometry(X11->display, pixmap, &root, &x, &y, &width, &height, &border_width, &depth);
       
  2288     XGetWindowAttributes(X11->display, root, &win_attribs);
       
  2289 
       
  2290     for (; screen < num_screens; ++screen) {
       
  2291         if (win_attribs.screen == ScreenOfDisplay(X11->display, screen))
       
  2292             break;
       
  2293     }
       
  2294 
       
  2295     QX11PixmapData *data = new QX11PixmapData(depth == 1 ? QPixmapData::BitmapType : QPixmapData::PixmapType);
       
  2296     data->setSerialNumber(++qt_pixmap_serial);
       
  2297     data->flags = QX11PixmapData::Readonly;
       
  2298     data->share_mode = mode;
       
  2299     data->w = width;
       
  2300     data->h = height;
       
  2301     data->is_null = (width <= 0 || height <= 0);
       
  2302     data->d = depth;
       
  2303     data->hd = pixmap;
       
  2304 
       
  2305     if (defaultScreen >= 0 && defaultScreen != screen) {
       
  2306         QX11InfoData* xd = data->xinfo.getX11Data(true);
       
  2307         xd->screen = defaultScreen;
       
  2308         xd->depth = QX11Info::appDepth(xd->screen);
       
  2309         xd->cells = QX11Info::appCells(xd->screen);
       
  2310         xd->colormap = QX11Info::appColormap(xd->screen);
       
  2311         xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
       
  2312         xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
       
  2313         xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
       
  2314         data->xinfo.setX11Data(xd);
       
  2315     }
       
  2316 
       
  2317 #ifndef QT_NO_XRENDER
       
  2318     if (X11->use_xrender) {
       
  2319         XRenderPictFormat *format = qt_renderformat_for_depth(data->xinfo, depth);
       
  2320         data->picture = XRenderCreatePicture(X11->display, data->hd, format, 0, 0);
       
  2321     }
       
  2322 #endif // QT_NO_XRENDER
       
  2323 
       
  2324     return QPixmap(data);
       
  2325 }
       
  2326 
       
  2327 
       
  2328 QT_END_NAMESPACE