~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/image/qpixmap_x11.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

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