source: trunk/src/gui/image/qnativeimage.cpp@ 858

Last change on this file since 858 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 8.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** 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 have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <qdebug.h>
43#include "qnativeimage_p.h"
44#include "qcolormap.h"
45
46#include "private/qpaintengine_raster_p.h"
47
48#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
49#include <qx11info_x11.h>
50#include <sys/ipc.h>
51#include <sys/shm.h>
52#include <qwidget.h>
53#endif
54
55#ifdef Q_WS_MAC
56#include <private/qpaintengine_mac_p.h>
57#endif
58
59QT_BEGIN_NAMESPACE
60
61#ifdef Q_WS_WIN
62typedef struct {
63 BITMAPINFOHEADER bmiHeader;
64 DWORD redMask;
65 DWORD greenMask;
66 DWORD blueMask;
67} BITMAPINFO_MASK;
68
69
70QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool isTextBuffer, QWidget *)
71{
72#ifndef Q_WS_WINCE
73 Q_UNUSED(isTextBuffer);
74#endif
75 BITMAPINFO_MASK bmi;
76 memset(&bmi, 0, sizeof(bmi));
77 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
78 bmi.bmiHeader.biWidth = width;
79 bmi.bmiHeader.biHeight = -height;
80 bmi.bmiHeader.biPlanes = 1;
81 bmi.bmiHeader.biSizeImage = 0;
82
83 if (format == QImage::Format_RGB16) {
84 bmi.bmiHeader.biBitCount = 16;
85#ifdef Q_WS_WINCE
86 if (isTextBuffer) {
87 bmi.bmiHeader.biCompression = BI_RGB;
88 bmi.redMask = 0;
89 bmi.greenMask = 0;
90 bmi.blueMask = 0;
91 } else
92#endif
93 {
94 bmi.bmiHeader.biCompression = BI_BITFIELDS;
95 bmi.redMask = 0xF800;
96 bmi.greenMask = 0x07E0;
97 bmi.blueMask = 0x001F;
98 }
99 } else {
100 bmi.bmiHeader.biBitCount = 32;
101 bmi.bmiHeader.biCompression = BI_RGB;
102 bmi.redMask = 0;
103 bmi.greenMask = 0;
104 bmi.blueMask = 0;
105 }
106
107 HDC display_dc = GetDC(0);
108 hdc = CreateCompatibleDC(display_dc);
109 ReleaseDC(0, display_dc);
110 Q_ASSERT(hdc);
111
112 uchar *bits = 0;
113 bitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO *>(&bmi), DIB_RGB_COLORS, (void**) &bits, 0, 0);
114 Q_ASSERT(bitmap);
115 Q_ASSERT(bits);
116
117 null_bitmap = (HBITMAP)SelectObject(hdc, bitmap);
118 image = QImage(bits, width, height, format);
119
120 Q_ASSERT(image.paintEngine()->type() == QPaintEngine::Raster);
121 static_cast<QRasterPaintEngine *>(image.paintEngine())->setDC(hdc);
122
123#ifndef Q_WS_WINCE
124 GdiFlush();
125#endif
126}
127
128QNativeImage::~QNativeImage()
129{
130 if (bitmap || hdc) {
131 Q_ASSERT(hdc);
132 Q_ASSERT(bitmap);
133 if (null_bitmap)
134 SelectObject(hdc, null_bitmap);
135 DeleteDC(hdc);
136 DeleteObject(bitmap);
137 }
138}
139
140QImage::Format QNativeImage::systemFormat()
141{
142 if (QColormap::instance().depth() == 16)
143 return QImage::Format_RGB16;
144 return QImage::Format_RGB32;
145}
146
147#elif defined(Q_WS_PM)
148
149QNativeImage::QNativeImage(int width, int height, QImage::Format format,
150 bool isTextBuffer, QWidget *widget)
151{
152 image = QImage(width, height, format);
153}
154
155QNativeImage::~QNativeImage()
156{
157}
158
159QImage::Format QNativeImage::systemFormat()
160{
161 // @todo support 8-bit indexed colors?
162// if (QColormap::instance().depth() == 16)
163// return QImage::Format_RGB16;
164 return QImage::Format_RGB32;
165}
166
167#elif defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
168
169QNativeImage::QNativeImage(int width, int height, QImage::Format format,bool /* isTextBuffer */, QWidget *widget)
170 : xshmimg(0), xshmpm(0)
171{
172 if (!X11->use_mitshm) {
173 image = QImage(width, height, format);
174 // follow good coding practice and set xshminfo attributes, though values not used in this case
175 xshminfo.readOnly = true;
176 xshminfo.shmaddr = 0;
177 xshminfo.shmid = 0;
178 xshminfo.shmseg = 0;
179 return;
180 }
181
182 QX11Info info = widget->x11Info();
183
184 int dd = info.depth();
185 Visual *vis = (Visual*) info.visual();
186
187 xshmimg = XShmCreateImage(X11->display, vis, dd, ZPixmap, 0, &xshminfo, width, height);
188 if (!xshmimg) {
189 qWarning("QNativeImage: Unable to create shared XImage.");
190 return;
191 }
192
193 bool ok;
194 xshminfo.shmid = shmget(IPC_PRIVATE, xshmimg->bytes_per_line * xshmimg->height,
195 IPC_CREAT | 0777);
196 ok = xshminfo.shmid != -1;
197 if (ok) {
198 xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0);
199 xshminfo.shmaddr = xshmimg->data;
200 if (shmctl(xshminfo.shmid, IPC_RMID, 0) == -1)
201 qWarning() << "Error while marking the shared memory segment to be destroyed";
202 ok = (xshminfo.shmaddr != (char*)-1);
203 if (ok)
204 image = QImage((uchar *)xshmimg->data, width, height, format);
205 }
206 xshminfo.readOnly = false;
207 if (ok)
208 ok = XShmAttach(X11->display, &xshminfo);
209 if (!ok) {
210 qWarning() << "QNativeImage: Unable to attach to shared memory segment.";
211 if (xshmimg->data) {
212 free(xshmimg->data);
213 xshmimg->data = 0;
214 }
215 XDestroyImage(xshmimg);
216 xshmimg = 0;
217 if (xshminfo.shmaddr)
218 shmdt(xshminfo.shmaddr);
219 if (xshminfo.shmid != -1)
220 shmctl(xshminfo.shmid, IPC_RMID, 0);
221 return;
222 }
223 if (X11->use_mitshm_pixmaps) {
224 xshmpm = XShmCreatePixmap(X11->display, DefaultRootWindow(X11->display), xshmimg->data,
225 &xshminfo, width, height, dd);
226 if (!xshmpm) {
227 qWarning() << "QNativeImage: Unable to create shared Pixmap.";
228 }
229 }
230}
231
232
233QNativeImage::~QNativeImage()
234{
235 if (!xshmimg)
236 return;
237
238 if (xshmpm) {
239 XFreePixmap(X11->display, xshmpm);
240 xshmpm = 0;
241 }
242 XShmDetach(X11->display, &xshminfo);
243 xshmimg->data = 0;
244 XDestroyImage(xshmimg);
245 xshmimg = 0;
246 shmdt(xshminfo.shmaddr);
247 shmctl(xshminfo.shmid, IPC_RMID, 0);
248}
249
250QImage::Format QNativeImage::systemFormat()
251{
252 if (QX11Info::appDepth() == 16)
253 return QImage::Format_RGB16;
254 return QImage::Format_RGB32;
255}
256
257#elif defined(Q_WS_MAC)
258
259QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* isTextBuffer */, QWidget *widget)
260 : image(width, height, format)
261{
262
263
264 uint cgflags = kCGImageAlphaNoneSkipFirst;
265
266#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
267 cgflags |= kCGBitmapByteOrder32Host;
268#endif
269
270 cg = CGBitmapContextCreate(image.bits(), width, height, 8, image.bytesPerLine(),
271 QCoreGraphicsPaintEngine::macDisplayColorSpace(widget), cgflags);
272 CGContextTranslateCTM(cg, 0, height);
273 CGContextScaleCTM(cg, 1, -1);
274
275 Q_ASSERT(image.paintEngine()->type() == QPaintEngine::Raster);
276 static_cast<QRasterPaintEngine *>(image.paintEngine())->setCGContext(cg);
277}
278
279
280QNativeImage::~QNativeImage()
281{
282 CGContextRelease(cg);
283}
284
285QImage::Format QNativeImage::systemFormat()
286{
287 return QImage::Format_RGB32;
288}
289
290
291#else // other platforms...
292
293QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* isTextBuffer */, QWidget *)
294 : image(width, height, format)
295{
296
297}
298
299
300QNativeImage::~QNativeImage()
301{
302}
303
304QImage::Format QNativeImage::systemFormat()
305{
306 return QImage::Format_RGB32;
307}
308
309#endif // platforms
310
311QT_END_NAMESPACE
312
Note: See TracBrowser for help on using the repository browser.