wxOS2 with Open Watcom: correct PCH usage, missing headers, warning fixes, source...
[wxWidgets.git] / src / os2 / icon.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: icon.cpp
3 // Purpose: wxIcon class
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/09/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/defs.h"
21 #include "wx/list.h"
22 #include "wx/utils.h"
23 #include "wx/app.h"
24 #include "wx/icon.h"
25 #include "wx/log.h"
26 #endif
27
28 #include "wx/os2/private.h"
29 #include "assert.h"
30
31 #include "wx/icon.h"
32
33 IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxGDIObject)
34
35 // ============================================================================
36 // implementation
37 // ============================================================================
38
39 // ----------------------------------------------------------------------------
40 // wxIconRefData
41 // ----------------------------------------------------------------------------
42
43 void wxIconRefData::Free()
44 {
45 if (m_hIcon)
46 ::WinFreeFileIcon((HPOINTER)m_hIcon);
47 }
48
49 // ----------------------------------------------------------------------------
50 // wxIcon
51 // ----------------------------------------------------------------------------
52
53 wxIcon::wxIcon()
54 : m_bIsXpm(FALSE)
55 {
56 }
57
58 wxIcon::wxIcon(
59 const char WXUNUSED(bits)[]
60 , int WXUNUSED(nWidth)
61 , int WXUNUSED(nHeight)
62 )
63 : m_bIsXpm(FALSE)
64 {
65 }
66
67 wxIcon::wxIcon(
68 const wxString& rIconFile
69 , long lFlags
70 , int nDesiredWidth
71 , int nDesiredHeight
72 )
73 : m_bIsXpm(FALSE)
74 {
75 //
76 // A very poor hack, but we have to have separate icon files from windows
77 // So we have a modified name where replace the last three characters
78 // with os2. Also need the extension.
79 //
80 wxString sOs2Name = rIconFile.Mid(0, rIconFile.Length() - 3);
81
82 sOs2Name += wxT("Os2.ico");
83 LoadFile( sOs2Name
84 ,lFlags
85 ,nDesiredWidth
86 ,nDesiredHeight
87 );
88 }
89
90 wxIcon::~wxIcon()
91 {
92 }
93
94 void wxIcon::CreateIconFromXpm(
95 const char** ppData
96 )
97 {
98 wxBitmap vBmp(ppData);
99
100 CopyFromBitmap(vBmp);
101 if (GetHICON())
102 {
103 m_bIsXpm = true;
104 m_vXpmSrc = vBmp;
105 }
106 } // end of wxIcon::CreateIconFromXpm
107
108 void wxIcon::CopyFromBitmap( const wxBitmap& rBmp )
109 {
110 wxMask* pMask = rBmp.GetMask();
111 HBITMAP hBmp = NULLHANDLE;
112 HBITMAP hBmpMask = NULLHANDLE;
113 HBITMAP hOldBitmap = NULLHANDLE;
114 ERRORID vError;
115 wxString sError;
116 LONG lHits;
117
118 if (!pMask)
119 {
120 //
121 // We must have a mask for an icon, so even if it's probably incorrect,
122 // do create it (grey is the "standard" transparent colour)
123 //
124 pMask = new wxMask( rBmp
125 ,*wxLIGHT_GREY
126 );
127 }
128
129 BITMAPINFOHEADER2 vHeader;
130 SIZEL vSize = {0, 0};
131 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
132 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
133 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
134 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
135 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
136 POINTL vPoint[4] = { {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight()},
137 {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight()}
138 };
139 POINTL vPointMask[4] = { {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight() * 2},
140 {0, 0}, {rBmp.GetWidth(), rBmp.GetHeight()}
141 };
142
143 POINTERINFO vIconInfo;
144
145 memset(&vIconInfo, '\0', sizeof(POINTERINFO));
146 vIconInfo.fPointer = FALSE; // we want an icon, not a pointer
147
148 memset(&vHeader, '\0', 16);
149 vHeader.cbFix = 16;
150 vHeader.cx = (ULONG)rBmp.GetWidth();
151 vHeader.cy = (ULONG)rBmp.GetHeight();
152 vHeader.cPlanes = 1L;
153 vHeader.cBitCount = 24;
154
155 hBmp = ::GpiCreateBitmap( hPSDst
156 ,&vHeader
157 ,0L
158 ,NULL
159 ,NULL
160 );
161
162 if ((hOldBitmap = ::GpiSetBitmap(hPSDst, hBmp)) == HBM_ERROR)
163 {
164 vError = ::WinGetLastError(vHabmain);
165 sError = wxPMErrorToStr(vError);
166 }
167 if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, (HBITMAP)rBmp.GetHBITMAP())) == HBM_ERROR)
168 {
169 vError = ::WinGetLastError(vHabmain);
170 sError = wxPMErrorToStr(vError);
171 }
172 if ((lHits = ::GpiBitBlt( hPSDst
173 ,hPSSrc
174 ,4L
175 ,vPoint
176 ,ROP_SRCCOPY
177 ,BBO_IGNORE
178 )) == GPI_ERROR)
179 {
180 vError = ::WinGetLastError(vHabmain);
181 sError = wxPMErrorToStr(vError);
182 }
183 if ((hOldBitmap = ::GpiSetBitmap(hPSDst, NULLHANDLE)) == HBM_ERROR)
184 {
185 vError = ::WinGetLastError(vHabmain);
186 sError = wxPMErrorToStr(vError);
187 }
188 if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, NULLHANDLE)) == HBM_ERROR)
189 {
190 vError = ::WinGetLastError(vHabmain);
191 sError = wxPMErrorToStr(vError);
192 }
193 vIconInfo.hbmColor = hBmp;
194
195 vHeader.cy = (ULONG)rBmp.GetHeight() * 2;
196 hBmpMask = ::GpiCreateBitmap( hPSDst
197 ,&vHeader
198 ,0L
199 ,NULL
200 ,NULL
201 );
202
203 if ((hOldBitmap = ::GpiSetBitmap(hPSDst, hBmpMask)) == HBM_ERROR)
204 {
205 vError = ::WinGetLastError(vHabmain);
206 sError = wxPMErrorToStr(vError);
207 }
208 if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, (HBITMAP)pMask->GetMaskBitmap())) == HBM_ERROR)
209 {
210 vError = ::WinGetLastError(vHabmain);
211 sError = wxPMErrorToStr(vError);
212 }
213 if ((lHits = ::GpiBitBlt( hPSDst
214 ,hPSSrc
215 ,4L
216 ,vPointMask
217 ,ROP_SRCCOPY
218 ,BBO_IGNORE
219 )) == GPI_ERROR)
220 {
221 vError = ::WinGetLastError(vHabmain);
222 sError = wxPMErrorToStr(vError);
223 }
224 if ((hOldBitmap = ::GpiSetBitmap(hPSSrc, NULLHANDLE)) == HBM_ERROR)
225 {
226 vError = ::WinGetLastError(vHabmain);
227 sError = wxPMErrorToStr(vError);
228 }
229 if ((hOldBitmap = ::GpiSetBitmap(hPSDst, NULLHANDLE)) == HBM_ERROR)
230 {
231 vError = ::WinGetLastError(vHabmain);
232 sError = wxPMErrorToStr(vError);
233 }
234
235 vIconInfo.hbmPointer = hBmpMask;
236
237 #ifndef __WATCOMC__
238 // FIXME: incomplete headers ???
239
240 HICON hIcon = ::WinCreatePointerIndirect( HWND_DESKTOP, &vIconInfo);
241
242 if (!hIcon)
243 {
244 wxLogLastError(wxT("WinCreatePointerIndirect"));
245 vError = ::WinGetLastError(vHabmain);
246 sError = wxPMErrorToStr(vError);
247 }
248 else
249 {
250 SetHICON((WXHICON)hIcon);
251 SetSize( rBmp.GetWidth()
252 ,rBmp.GetHeight()
253 );
254 }
255 #endif
256
257 if (!rBmp.GetMask())
258 {
259 //
260 // We created the mask, now delete it
261 //
262 delete pMask;
263 }
264 ::GpiSetBitmap(hPSSrc, NULL);
265 ::GpiSetBitmap(hPSDst, NULL);
266 ::GpiDestroyPS(hPSSrc);
267 ::GpiDestroyPS(hPSDst);
268 ::DevCloseDC(hDCSrc);
269 ::DevCloseDC(hDCDst);
270 } // end of wxIcon::CopyFromBitmap
271
272 bool wxIcon::LoadFile(
273 const wxString& rFilename
274 , long lType
275 , int nDesiredWidth
276 , int nDesiredHeight
277 )
278 {
279 HPS hPs = NULLHANDLE;
280
281 UnRef();
282
283 wxGDIImageHandler* pHandler = FindHandler(lType);
284
285 if (pHandler)
286 return(pHandler->Load( this
287 ,rFilename
288 ,hPs
289 ,lType
290 ,nDesiredWidth
291 ,nDesiredHeight
292 ));
293 else
294 return(FALSE);
295 }