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