~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): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/****************************************************************************
2
2
**
3
3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
 
4
** All rights reserved.
4
5
** Contact: Nokia Corporation (qt-info@nokia.com)
5
6
**
6
7
** This file is part of the QtGui module of the Qt Toolkit.
7
8
**
8
9
** $QT_BEGIN_LICENSE:LGPL$
9
 
** Commercial Usage
10
 
** Licensees holding valid Qt Commercial licenses may use this file in
11
 
** accordance with the Qt Commercial License Agreement provided with the
12
 
** Software or, alternatively, in accordance with the terms contained in
13
 
** a written agreement between you and Nokia.
 
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.
14
15
**
15
16
** GNU Lesser General Public License Usage
16
17
** Alternatively, this file may be used under the terms of the GNU Lesser
20
21
** ensure the GNU Lesser General Public License version 2.1 requirements
21
22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22
23
**
23
 
** In addition, as a special exception, Nokia gives you certain
24
 
** additional rights. These rights are described in the Nokia Qt LGPL
25
 
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26
 
** package.
27
 
**
28
 
** GNU General Public License Usage
29
 
** Alternatively, this file may be used under the terms of the GNU
30
 
** General Public License version 3.0 as published by the Free Software
31
 
** Foundation and appearing in the file LICENSE.GPL included in the
32
 
** packaging of this file.  Please review the following information to
33
 
** ensure the GNU General Public License version 3.0 requirements will be
34
 
** met: http://www.gnu.org/copyleft/gpl.html.
35
 
**
36
 
** If you are unsure which license is appropriate for your use, please
37
 
** contact the sales department at http://www.qtsoftware.com/contact.
 
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
38
** $QT_END_LICENSE$
39
39
**
40
40
****************************************************************************/
67
67
#include <private/qt_x11_p.h>
68
68
#include "qx11info_x11.h"
69
69
#include <private/qdrawhelper_p.h>
 
70
#include <private/qimage_p.h>
70
71
 
71
72
#include <stdlib.h>
72
73
 
312
313
int Q_GUI_EXPORT qt_x11_preferred_pixmap_depth = 0;
313
314
 
314
315
QX11PixmapData::QX11PixmapData(PixelType type)
315
 
    : QPixmapData(type, X11Class), hd(0), w(0), h(0), d(0),
316
 
      uninit(true), read_only(false), x11_mask(0), picture(0), mask_picture(0), hd2(0),
 
316
    : QPixmapData(type, X11Class), hd(0),
 
317
      flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0), gl_surface(0),
317
318
      share_mode(QPixmap::ImplicitlyShared), pengine(0)
318
319
{
319
320
}
324
325
 
325
326
    w = width;
326
327
    h = height;
 
328
    is_null = (w <= 0 || h <= 0);
327
329
 
328
330
    if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
329
331
        QX11InfoData* xd = xinfo.getX11Data(true);
347
349
    if (make_null || d == 0) {
348
350
        w = 0;
349
351
        h = 0;
 
352
        is_null = true;
350
353
        hd = 0;
351
354
        picture = 0;
352
355
        d = 0;
367
370
#endif // QT_NO_XRENDER
368
371
}
369
372
 
 
373
struct QX11AlphaDetector
 
374
{
 
375
    bool hasAlpha() const {
 
376
        if (checked)
 
377
            return has;
 
378
        // Will implicitly also check format and return quickly for opaque types...
 
379
        checked = true;
 
380
        has = const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
 
381
        return has;
 
382
    }
 
383
 
 
384
    bool hasXRenderAndAlpha() const {
 
385
        if (!X11->use_xrender)
 
386
            return false;
 
387
        return hasAlpha();
 
388
    }
 
389
 
 
390
    QX11AlphaDetector(const QImage *i) : image(i), checked(false), has(false) { }
 
391
 
 
392
    const QImage *image;
 
393
    mutable bool checked;
 
394
    mutable bool has;
 
395
};
 
396
 
370
397
void QX11PixmapData::fromImage(const QImage &img,
371
398
                               Qt::ImageConversionFlags flags)
372
399
{
375
402
    w = img.width();
376
403
    h = img.height();
377
404
    d = img.depth();
 
405
    is_null = (w <= 0 || h <= 0);
378
406
 
379
407
    if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
380
408
        QX11InfoData* xd = xinfo.getX11Data(true);
395
423
 
396
424
    if (uint(w) >= 32768 || uint(h) >= 32768) {
397
425
        w = h = 0;
 
426
        is_null = true;
398
427
        return;
399
428
    }
400
429
 
401
 
    int dd = X11->use_xrender && img.hasAlphaChannel() ? 32 : xinfo.depth();
 
430
    QX11AlphaDetector alphaCheck(&img);
 
431
    int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth();
 
432
 
402
433
    if (qt_x11_preferred_pixmap_depth)
403
434
        dd = qt_x11_preferred_pixmap_depth;
404
435
 
450
481
    uchar  *newbits= 0;
451
482
 
452
483
#ifndef QT_NO_XRENDER
453
 
    if (X11->use_xrender && image.hasAlphaChannel()) {
 
484
    if (alphaCheck.hasXRenderAndAlpha()) {
454
485
        const QImage &cimage = image;
455
486
 
456
487
        d = 32;
1087
1118
    }
1088
1119
#endif
1089
1120
 
1090
 
    if (image.hasAlphaChannel()) {
 
1121
    if (alphaCheck.hasAlpha()) {
1091
1122
        QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));
1092
1123
        setMask(m);
1093
1124
    }
1109
1140
    w = img.width();
1110
1141
    h = img.height();
1111
1142
    d = 1;
 
1143
    is_null = (w <= 0 || h <= 0);
1112
1144
    int bpl = (w + 7) / 8;
1113
1145
    int ibpl = img.bytesPerLine();
1114
1146
    if (bpl != ibpl) {
1212
1244
            XFreePixmap(xinfo.display(), hd2);
1213
1245
            hd2 = 0;
1214
1246
        }
1215
 
        if (!read_only)
 
1247
        if (!(flags & Readonly))
1216
1248
            XFreePixmap(xinfo.display(), hd);
1217
1249
        hd = 0;
1218
1250
    }
1220
1252
 
1221
1253
QPixmap QX11PixmapData::alphaChannel() const
1222
1254
{
1223
 
    if (!hasAlphaChannel())
1224
 
        return QPixmap();
 
1255
    if (!hasAlphaChannel()) {
 
1256
        QPixmap pm(w, h);
 
1257
        pm.fill(Qt::white);
 
1258
        return pm;
 
1259
    }
1225
1260
    QImage im(toImage());
1226
1261
    return QPixmap::fromImage(im.alphaChannel(), Qt::OrderedDither);
1227
1262
}
1870
1905
        return bm;
1871
1906
    } else {                                        // color pixmap
1872
1907
        QPixmap pm;
1873
 
        QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(pm.data);
1874
 
        x11Data->uninit = false;
 
1908
        QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(pm.data.data());
 
1909
        x11Data->flags &= ~QX11PixmapData::Uninitialized;
1875
1910
        x11Data->xinfo = xinfo;
1876
1911
        x11Data->d = d;
1877
1912
        x11Data->w = w;
1878
1913
        x11Data->h = h;
 
1914
        x11Data->is_null = (w <= 0 || h <= 0);
1879
1915
        x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,
1880
1916
                                                RootWindow(X11->display, xinfo.screen()),
1881
1917
                                                w, h, d);
1934
1970
    if (screen < 0)
1935
1971
        screen = QX11Info::appScreen();
1936
1972
 
1937
 
    QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(data);
 
1973
    QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(data.data());
1938
1974
    if (screen == x11Data->xinfo.screen())
1939
1975
        return; // nothing to do
1940
1976
 
2012
2048
 
2013
2049
    QPixmap pm(data);
2014
2050
 
2015
 
    data->uninit = false;
 
2051
    data->flags &= ~QX11PixmapData::Uninitialized;
2016
2052
    pm.x11SetScreen(scr);
2017
2053
 
2018
2054
    GC gc = XCreateGC(dpy, pm.handle(), 0, 0);
2031
2067
const QX11Info &QPixmap::x11Info() const
2032
2068
{
2033
2069
    if (data->classId() == QPixmapData::X11Class)
2034
 
        return static_cast<QX11PixmapData*>(data)->xinfo;
 
2070
        return static_cast<QX11PixmapData*>(data.data())->xinfo;
2035
2071
    else {
2036
2072
        static QX11Info nullX11Info;
2037
2073
        return nullX11Info;
2054
2090
{
2055
2091
    QX11PixmapData *that = const_cast<QX11PixmapData*>(this);
2056
2092
 
2057
 
    if (read_only && share_mode == QPixmap::ImplicitlyShared) {
 
2093
    if ((flags & Readonly) && share_mode == QPixmap::ImplicitlyShared) {
2058
2094
        // if someone wants to draw onto us, copy the shared contents
2059
2095
        // and turn it into a fully fledged QPixmap
2060
2096
        ::Pixmap hd_copy = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
2076
2112
            XFreeGC(X11->display, gc);
2077
2113
        }
2078
2114
        that->hd = hd_copy;
2079
 
        that->read_only = false;
 
2115
        that->flags &= ~QX11PixmapData::Readonly;
2080
2116
    }
2081
2117
 
2082
2118
    if (!that->pengine)
2088
2124
{
2089
2125
#ifndef QT_NO_XRENDER
2090
2126
    if (data->classId() == QPixmapData::X11Class)
2091
 
        return static_cast<QX11PixmapData*>(data)->picture;
 
2127
        return static_cast<const QX11PixmapData*>(data.data())->picture;
2092
2128
    else
2093
2129
        return 0;
2094
2130
#else
2127
2163
 
2128
2164
    setSerialNumber(++qt_pixmap_serial);
2129
2165
 
2130
 
    uninit = false;
 
2166
    flags &= ~Uninitialized;
2131
2167
    xinfo = x11Data->xinfo;
2132
2168
    d = x11Data->d;
2133
2169
    w = rect.width();
2134
2170
    h = rect.height();
 
2171
    is_null = (w <= 0 || h <= 0);
2135
2172
    hd = (Qt::HANDLE)XCreatePixmap(X11->display,
2136
2173
                                   RootWindow(X11->display, x11Data->xinfo.screen()),
2137
2174
                                   w, h, d);
2177
2214
    }
2178
2215
}
2179
2216
 
 
2217
bool QX11PixmapData::scroll(int dx, int dy, const QRect &rect)
 
2218
{
 
2219
    GC gc = XCreateGC(X11->display, hd, 0, 0);
 
2220
    XCopyArea(X11->display, hd, hd, gc,
 
2221
              rect.left(), rect.top(), rect.width(), rect.height(),
 
2222
              rect.left() + dx, rect.top() + dy);
 
2223
    XFreeGC(X11->display, gc);
 
2224
    return true;
 
2225
}
 
2226
 
2180
2227
#if !defined(QT_NO_XRENDER)
2181
2228
void QX11PixmapData::convertToARGB32(bool preserveContents)
2182
2229
{
2184
2231
        return;
2185
2232
 
2186
2233
    // Q_ASSERT(count == 1);
2187
 
    if (read_only && share_mode == QPixmap::ExplicitlyShared)
 
2234
    if ((flags & Readonly) && share_mode == QPixmap::ExplicitlyShared)
2188
2235
        return;
2189
2236
 
2190
2237
    Pixmap pm = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
2194
2241
    if (picture) {
2195
2242
        if (preserveContents)
2196
2243
            XRenderComposite(X11->display, PictOpSrc, picture, 0, p, 0, 0, 0, 0, 0, 0, w, h);
2197
 
        if (!read_only)
 
2244
        if (!(flags & Readonly))
2198
2245
            XRenderFreePicture(X11->display, picture);
2199
2246
    }
2200
 
    if (hd && !read_only)
 
2247
    if (hd && !(flags & Readonly))
2201
2248
        XFreePixmap(X11->display, hd);
2202
2249
    if (x11_mask) {
2203
2250
        XFreePixmap(X11->display, x11_mask);
2235
2282
 
2236
2283
    QX11PixmapData *data = new QX11PixmapData(depth == 1 ? QPixmapData::BitmapType : QPixmapData::PixmapType);
2237
2284
    data->setSerialNumber(++qt_pixmap_serial);
2238
 
    data->read_only = true;
 
2285
    data->flags = QX11PixmapData::Readonly;
2239
2286
    data->share_mode = mode;
2240
 
    data->uninit = false;
2241
2287
    data->w = width;
2242
2288
    data->h = height;
 
2289
    data->is_null = (width <= 0 || height <= 0);
2243
2290
    data->d = depth;
2244
2291
    data->hd = pixmap;
2245
2292