source: trunk/src/gui/image/qpixmap_pm.cpp@ 260

Last change on this file since 260 was 260, checked in by Dmitry A. Kuminov, 16 years ago

gui: QPixmap: Created OS/2 specific methods for converting pixmaps to HBITMAPs and HPOINTERs.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Date Revision Author Id
File size: 8.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** Copyright (C) 2009 netlabs.org. OS/2 parts.
7**
8** This file is part of the QtGui module of the Qt Toolkit.
9**
10** $QT_BEGIN_LICENSE:LGPL$
11** Commercial Usage
12** Licensees holding valid Qt Commercial licenses may use this file in
13** accordance with the Qt Commercial License Agreement provided with the
14** Software or, alternatively, in accordance with the terms contained in
15** a written agreement between you and Nokia.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Nokia gives you certain
26** additional rights. These rights are described in the Nokia Qt LGPL
27** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
28** package.
29**
30** GNU General Public License Usage
31** Alternatively, this file may be used under the terms of the GNU
32** General Public License version 3.0 as published by the Free Software
33** Foundation and appearing in the file LICENSE.GPL included in the
34** packaging of this file. Please review the following information to
35** ensure the GNU General Public License version 3.0 requirements will be
36** met: http://www.gnu.org/copyleft/gpl.html.
37**
38** If you are unsure which license is appropriate for your use, please
39** contact the sales department at [email protected].
40** $QT_END_LICENSE$
41**
42****************************************************************************/
43
44#include "qpixmap.h"
45#include "qpixmap_raster_p.h"
46
47#include "qicon.h"
48
49#include "qt_os2.h"
50
51QT_BEGIN_NAMESPACE
52
53HPS qt_alloc_mem_ps(int w, int h, HPS compat = 0)
54{
55 HDC hdcCompat = NULLHANDLE;
56 if (compat)
57 hdcCompat = GpiQueryDevice(compat);
58
59 static const PSZ hdcData[4] = { "Display", NULL, NULL, NULL };
60 HDC hdc = DevOpenDC(0, OD_MEMORY, "*", 4, (PDEVOPENDATA) hdcData, hdcCompat);
61 if (!hdc) {
62 qWarning( "alloc_mem_dc: DevOpenDC failed with %08lX!", WinGetLastError(0));
63 return NULLHANDLE;
64 }
65 SIZEL size = { w, h };
66 HPS hps = GpiCreatePS(0, hdc, &size, PU_PELS | GPIA_ASSOC | GPIT_MICRO);
67 if (hps == NULLHANDLE) {
68 qWarning("alloc_mem_dc: GpiCreatePS failed wit %08lX!", WinGetLastError(0));
69 return NULLHANDLE;
70 }
71 // @todo later
72// if (QColor::hPal()) {
73// GpiSelectPalette(hps, QColor::hPal());
74// } else {
75 // direct RGB mode
76 GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL);
77// }
78 return hps;
79}
80
81void qt_free_mem_ps(HPS hps)
82{
83 HDC hdc = GpiQueryDevice(hps);
84 GpiAssociate(hps, NULLHANDLE);
85 GpiDestroyPS(hps);
86 DevCloseDC(hdc);
87}
88
89/*!
90 Creates a \c HBITMAP equivalent to the QPixmap. Returns the \c HBITMAP
91 handle.
92
93 If \a mask is not NULL, the mask mode is turned. In this mode, the bitmap
94 mask is also created from the QPixmap's mask and returned in the given
95 variable. This bitmap mask will contain two vertically adjacent sections,
96 the first of which is the AND mask and the second one is the XOR mask
97 (according to WinCreatePointer() specification). Also, in mask mode, the
98 HBITMAP returned for the pixmap itself will be prepared for masking (with
99 transparent pixels made black). This mode is useful for creating system
100 icons and pointers (\sa toPmHPOINTER()).
101
102 Note that if the pixmap does neither have a maks nor the alpha channel but
103 \a mask is not NULL, a NULLHANDLE value will be stored there.
104
105 It is the caller's responsibility to free both returned \c HBITMAP handes
106 after use.
107
108 \warning This function is only available on OS/2.
109*/
110HBITMAP QPixmap::toPmHBITMAP(HBITMAP *mask) const
111{
112 if (data->classId() != QPixmapData::RasterClass) {
113 QPixmapData *data = new QRasterPixmapData(depth() == 1 ?
114 QPixmapData::BitmapType : QPixmapData::PixmapType);
115 data->fromImage(toImage(), Qt::AutoColor);
116 return QPixmap(data).toPmHBITMAP(mask);
117 }
118
119 QRasterPixmapData* d = static_cast<QRasterPixmapData*>(data);
120 int w = d->image.width();
121 int h = d->image.height();
122
123 HPS hps = qt_alloc_mem_ps(w, h);
124 if (hps == NULLHANDLE)
125 return NULLHANDLE;
126
127 HBITMAP hbm = NULLHANDLE;
128 HBITMAP hbmMask = NULLHANDLE;
129
130 QImage image = d->image.convertToFormat(QImage::Format_ARGB32).mirrored();
131
132 // bitmap header + 2 palette entries (for the mask)
133 char bmi[sizeof(BITMAPINFOHEADER2) + 4 * 2];
134 memset(bmi, 0, sizeof(bmi));
135 BITMAPINFOHEADER2 &bmh = *(PBITMAPINFOHEADER2)bmi;
136 bmh.cbFix = sizeof(BITMAPINFOHEADER2);
137 PULONG pal = (PULONG)(bmi + sizeof(BITMAPINFOHEADER2));
138
139 // create the normal bitmap from the pixmap data
140 bmh.cx = w;
141 bmh.cy = h;
142 bmh.cPlanes = 1;
143 bmh.cBitCount = 32;
144 hbm = GpiCreateBitmap(hps, &bmh, CBM_INIT, (PBYTE)(const uchar *)image.bits(),
145 (PBITMAPINFO2)&bmi);
146
147 if (mask && hasAlpha()) {
148 // get the mask. We prefer QImage::createAlphaMask() over QPixmap::mask()
149 // since the former will dither while the latter will convert any
150 // non-zero alpha value to an opaque pixel
151 QImage mask = image.createAlphaMask().mirrored();
152
153 // create the mask bitmap (AND and XOR stripes)
154 bmh.cbFix = sizeof(BITMAPINFOHEADER2);
155 bmh.cx = w;
156 bmh.cy = h;
157 bmh.cPlanes = 1;
158 bmh.cBitCount = 1;
159 bmh.cclrUsed = 2;
160 pal[0] = 0;
161 pal[1] = 0x00FFFFFF;
162 hbmMask = GpiCreateBitmap(hps, &bmh, 0, NULL, NULL);
163
164 // create AND mask (XOR mask is left zeroed -- it's okay)
165 GpiSetBitmap(hps, hbmMask);
166
167 POINTL ptls[] = {
168 { 0, h }, { w - 1, h * 2 - 1 }, // dst: inclusive-inclusive
169 { 0, 0 }, { w, h }, // src: inclusive-exclusive
170 };
171 GpiDrawBits(hps, (PBYTE)(const uchar *)mask.bits(), (PBITMAPINFO2)&bmi,
172 4, ptls, ROP_NOTSRCCOPY, BBO_IGNORE);
173
174 // prepare the bitmap for masking by setting transparent pixels to black
175 GpiSetBitmap(hps, hbmMask);
176
177 ptls[0].y -= h;
178 ptls[1].y -= h;
179 enum { AllImageAttrs = IBB_COLOR | IBB_BACK_COLOR |
180 IBB_MIX_MODE | IBB_BACK_MIX_MODE };
181 IMAGEBUNDLE ib = { CLR_TRUE, CLR_FALSE, FM_OVERPAINT, BM_OVERPAINT };
182 GpiSetAttrs(hps, PRIM_IMAGE, AllImageAttrs, 0, (PBUNDLE)&ib);
183 GpiDrawBits(hps, (PBYTE)(const uchar *)mask.bits(), (PBITMAPINFO2)&bmi,
184 4, ptls, ROP_SRCAND, BBO_IGNORE);
185 }
186
187 qt_free_mem_ps(hps);
188
189 if (mask)
190 *mask = hbmMask;
191
192 return hbm;
193}
194
195/*!
196 Creates a \c HPOINTER from the given QIcon. Returns the \c HPOINTER handle.
197
198 If \a isPointer is \c true, an icon size closest to the system pointer size
199 is chosen, otherwise to the system icon size. \a hotX and \a hotY define the
200 hot spot.
201
202 It is the caller's responsibility to free the \c HPOINTER data
203 after use.
204
205 \warning This function is only available on OS/2.
206*/
207// static
208HPOINTER QPixmap::toPmHPOINTER(const QIcon &icon, bool isPointer,
209 int hotX, int hotY)
210{
211 if (icon.isNull())
212 return NULLHANDLE;
213
214 int w = WinQuerySysValue(HWND_DESKTOP, isPointer ? SV_CXPOINTER : SV_CXICON);
215 int h = WinQuerySysValue(HWND_DESKTOP, isPointer ? SV_CYPOINTER : SV_CYICON);
216 QSize size = icon.actualSize(QSize(w, h));
217 QSize sizeMini = icon.actualSize(QSize(w / 2, h / 2));
218
219 QPixmap pm = icon.pixmap(size);
220 QPixmap pmMini = icon.pixmap(sizeMini);
221 if (pm.isNull() && pmMini.isNull())
222 return NULLHANDLE;
223
224 if (pm.isNull()) {
225 // if we only have the mini icon, use it as a normal one;
226 // WinCreatePointerIndirect() will figure that and not scale it
227 pm = pmMini;
228 pmMini = QPixmap();
229 }
230
231 POINTERINFO info;
232 info.fPointer = isPointer;
233 info.xHotspot = hotX;
234 info.yHotspot = hotY;
235 info.hbmColor = pm.toPmHBITMAP(&info.hbmPointer);
236 if (!pmMini.isNull())
237 info.hbmMiniColor = pmMini.toPmHBITMAP(&info.hbmMiniPointer);
238
239 HPOINTER hIcon = WinCreatePointerIndirect(HWND_DESKTOP, &info);
240
241 GpiDeleteBitmap(info.hbmPointer);
242 GpiDeleteBitmap(info.hbmColor);
243 GpiDeleteBitmap(info.hbmMiniPointer);
244 GpiDeleteBitmap(info.hbmMiniColor);
245
246 return hIcon;
247}
248
249QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h )
250{
251 // @todo implement
252 return QPixmap();
253}
254
255QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.