]> git.saurik.com Git - wxWidgets.git/blame - src/os2/gdiimage.cpp
Fix memory leak if wxDC::DrawBitmap() fails in wxOS2.
[wxWidgets.git] / src / os2 / gdiimage.cpp
CommitLineData
b4eb4c6b 1///////////////////////////////////////////////////////////////////////////////
63a3cd7a 2// Name: src/os2/gdiimage.cpp
b4eb4c6b
DW
3// Purpose: wxGDIImage implementation
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 20.11.99
7// RCS-ID: $Id$
8// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
65571936 9// Licence: wxWindows licence
b4eb4c6b
DW
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23
24#ifndef WX_PRECOMP
25 #include "wx/string.h"
670f9935 26 #include "wx/app.h"
b4eb4c6b
DW
27#endif // WX_PRECOMP
28
29#include "wx/os2/private.h"
b4eb4c6b
DW
30#include "wx/os2/gdiimage.h"
31
258f5b3e 32#include "wx/listimpl.cpp"
412e0d47 33WX_DEFINE_LIST(wxGDIImageHandlerList)
258f5b3e 34
b4eb4c6b
DW
35// ----------------------------------------------------------------------------
36// private classes
37// ----------------------------------------------------------------------------
38
39// all image handlers are declared/defined in this file because the outside
40// world doesn't have to know about them (but only about wxBITMAP_TYPE_XXX ids)
41
42class WXDLLEXPORT wxBMPFileHandler : public wxBitmapHandler
43{
44public:
9a83f860 45 wxBMPFileHandler() : wxBitmapHandler(wxT("Windows bitmap file"), wxT("bmp"),
b4eb4c6b
DW
46 wxBITMAP_TYPE_BMP)
47 {
48 }
49
50 virtual bool LoadFile( wxBitmap* pBitmap
51 ,const wxString& rName
52 ,HPS hPs
6b5c2d52 53 ,wxBitmapType lFlags
b4eb4c6b
DW
54 ,int nDesiredWidth
55 ,int nDesiredHeight
56 );
57 virtual bool SaveFile( wxBitmap* pBitmap
58 ,const wxString& rName
6b5c2d52 59 ,wxBitmapType lType
b4eb4c6b
DW
60 ,const wxPalette* pPalette = NULL
61 );
62
63private:
3029781e
DW
64 inline virtual bool LoadFile( wxBitmap* pBitmap
65 ,int nId
6b5c2d52 66 ,wxBitmapType lFlags
3029781e
DW
67 ,int nDesiredWidth
68 ,int nDesiredHeight
69 )
70 {
71 return wxBitmapHandler::LoadFile( pBitmap
72 ,nId
73 ,lFlags
74 ,nDesiredWidth
75 ,nDesiredHeight
76 );
77 }
b4eb4c6b
DW
78 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
79};
80
81class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
82{
83public:
9a83f860 84 wxBMPResourceHandler() : wxBitmapHandler(wxT("Windows bitmap resource"),
b4eb4c6b
DW
85 wxEmptyString,
86 wxBITMAP_TYPE_BMP_RESOURCE)
87 {
88 }
89
90 virtual bool LoadFile( wxBitmap* pBitmap
3029781e 91 ,int nId
6b5c2d52 92 ,wxBitmapType lFlags
b4eb4c6b
DW
93 ,int nDesiredWidth
94 ,int nDesiredHeight
95 );
96
97private:
98 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
99};
100
101class WXDLLEXPORT wxIconHandler : public wxGDIImageHandler
102{
103public:
104 wxIconHandler( const wxString& rName
105 ,const wxString& rExt
6b5c2d52 106 ,wxBitmapType lType
b4eb4c6b
DW
107 ) : wxGDIImageHandler( rName
108 ,rExt
109 ,lType
110 )
111 {
112 }
113
114 // creating and saving icons is not supported
115 virtual bool Create( wxGDIImage* WXUNUSED(pImage)
452418c4 116 ,const void* WXUNUSED(pData)
6b5c2d52 117 ,wxBitmapType WXUNUSED(lFlags)
b4eb4c6b
DW
118 ,int WXUNUSED(nWidth)
119 ,int WXUNUSED(nHeight)
120 ,int WXUNUSED(nDepth) = 1
121 )
122 {
63a3cd7a 123 return false;
b4eb4c6b
DW
124 }
125
6b5c2d52
SN
126 virtual bool Save( const wxGDIImage* WXUNUSED(pImage)
127 ,const wxString& WXUNUSED(rName)
128 ,wxBitmapType WXUNUSED(nType)
129 ) const
b4eb4c6b 130 {
63a3cd7a 131 return false;
b4eb4c6b
DW
132 }
133 virtual bool Load( wxGDIImage* pImage
134 ,const wxString& rName
135 ,HPS hPs
6b5c2d52 136 ,wxBitmapType lFlags
b4eb4c6b
DW
137 ,int nDesiredWidth
138 ,int nDesiredHeight
139 )
140 {
141 wxIcon* pIcon = wxDynamicCast(pImage, wxIcon);
9a83f860 142 wxCHECK_MSG(pIcon, false, wxT("wxIconHandler only works with icons"));
b4eb4c6b
DW
143
144 return LoadIcon( pIcon
145 ,rName
146 ,hPs
147 ,lFlags
148 ,nDesiredWidth
149 ,nDesiredHeight
150 );
151 }
152
153protected:
154 virtual bool LoadIcon( wxIcon* pIcon
155 ,const wxString& rName
156 ,HPS hPs
6b5c2d52 157 ,wxBitmapType lFlags
b4eb4c6b
DW
158 ,int nDesiredWidth = -1
159 ,int nDesiredHeight = -1
160 ) = 0;
3029781e 161private:
6670f564
WS
162 inline virtual bool Load( wxGDIImage* WXUNUSED(pImage),
163 int WXUNUSED(nId),
6b5c2d52 164 wxBitmapType WXUNUSED(lFlags),
6670f564
WS
165 int WXUNUSED(nDesiredWidth),
166 int WXUNUSED(nDesiredHeight) )
3029781e 167 {
6670f564 168 return false;
3029781e 169 }
b4eb4c6b
DW
170};
171
172class WXDLLEXPORT wxICOFileHandler : public wxIconHandler
173{
174public:
9a83f860
VZ
175 wxICOFileHandler() : wxIconHandler(wxT("ICO icon file"),
176 wxT("ico"),
b4eb4c6b
DW
177 wxBITMAP_TYPE_ICO)
178 {
179 }
180
181 virtual bool LoadIcon( wxIcon * pIcon
182 ,const wxString& rName
183 ,HPS hPs
6b5c2d52 184 ,wxBitmapType lFlags
b4eb4c6b
DW
185 ,int nDesiredWidth = -1
186 ,int nDesiredHeight = -1
187 );
188
189private:
190 DECLARE_DYNAMIC_CLASS(wxICOFileHandler)
191};
192
193class WXDLLEXPORT wxICOResourceHandler: public wxIconHandler
194{
195public:
9a83f860
VZ
196 wxICOResourceHandler() : wxIconHandler(wxT("ICO resource"),
197 wxT("ico"),
b4eb4c6b
DW
198 wxBITMAP_TYPE_ICO_RESOURCE)
199 {
200 }
201
202 virtual bool LoadIcon( wxIcon* pIcon
203 ,const wxString& rName
204 ,HPS hPs
6b5c2d52 205 ,wxBitmapType lFlags
b4eb4c6b
DW
206 ,int nDesiredWidth = -1
207 ,int nDesiredHeight = -1
208 );
209
210private:
211 DECLARE_DYNAMIC_CLASS(wxICOResourceHandler)
212};
213
214// ----------------------------------------------------------------------------
215// wxWin macros
216// ----------------------------------------------------------------------------
217
62f864c3
VZ
218IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
219IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
220IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxObject)
221IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxObject)
b4eb4c6b 222
b4eb4c6b
DW
223// ============================================================================
224// implementation
225// ============================================================================
226
258f5b3e 227wxGDIImageHandlerList wxGDIImage::ms_handlers;
b4eb4c6b
DW
228
229// ----------------------------------------------------------------------------
230// wxGDIImage functions forwarded to wxGDIImageRefData
231// ----------------------------------------------------------------------------
232
6670f564 233bool wxGDIImage::FreeResource( bool WXUNUSED(bForce) )
b4eb4c6b
DW
234{
235 if ( !IsNull() )
236 {
237 GetGDIImageData()->Free();
238 GetGDIImageData()->m_hHandle = 0;
239 }
240
6670f564 241 return true;
b4eb4c6b
DW
242}
243
17b1d76b 244WXHANDLE wxGDIImage::GetResourceHandle() const
b4eb4c6b
DW
245{
246 return GetHandle();
247}
248
249// ----------------------------------------------------------------------------
250// wxGDIImage handler stuff
251// ----------------------------------------------------------------------------
252
6670f564 253void wxGDIImage::AddHandler( wxGDIImageHandler* pHandler )
b4eb4c6b
DW
254{
255 ms_handlers.Append(pHandler);
256}
257
6670f564 258void wxGDIImage::InsertHandler( wxGDIImageHandler* pHandler )
b4eb4c6b
DW
259{
260 ms_handlers.Insert(pHandler);
261}
262
6670f564 263bool wxGDIImage::RemoveHandler( const wxString& rName )
b4eb4c6b
DW
264{
265 wxGDIImageHandler* pHandler = FindHandler(rName);
266
267 if (pHandler)
268 {
269 ms_handlers.DeleteObject(pHandler);
6670f564 270 return true;
b4eb4c6b
DW
271 }
272 else
6670f564 273 return false;
b4eb4c6b
DW
274}
275
276wxGDIImageHandler* wxGDIImage::FindHandler(
277 const wxString& rName
278)
279{
53ac3021
DW
280 wxGDIImageHandlerList::compatibility_iterator pNode = ms_handlers.GetFirst();
281
282 while ( pNode )
b4eb4c6b 283 {
53ac3021
DW
284 wxGDIImageHandler* pHandler = pNode->GetData();
285
286 if ( pHandler->GetName() == rName )
287 return pHandler;
288 pNode = pNode->GetNext();
b4eb4c6b 289 }
d3b9f782 290 return(NULL);
b4eb4c6b
DW
291}
292
293wxGDIImageHandler* wxGDIImage::FindHandler(
294 const wxString& rExtension
6b5c2d52 295, wxBitmapType lType
b4eb4c6b
DW
296)
297{
53ac3021
DW
298 wxGDIImageHandlerList::compatibility_iterator pNode = ms_handlers.GetFirst();
299 while ( pNode )
b4eb4c6b 300 {
53ac3021
DW
301 wxGDIImageHandler* pHandler = pNode->GetData();
302
96ad3e4e 303 if ( (pHandler->GetExtension() == rExtension) &&
53ac3021 304 (lType == -1 || pHandler->GetType() == lType) )
b4eb4c6b 305 {
53ac3021 306 return pHandler;
b4eb4c6b 307 }
53ac3021 308 pNode = pNode->GetNext();
b4eb4c6b 309 }
d3b9f782 310 return(NULL);
b4eb4c6b
DW
311}
312
313wxGDIImageHandler* wxGDIImage::FindHandler(
6b5c2d52 314 wxBitmapType lType
b4eb4c6b
DW
315)
316{
53ac3021
DW
317 wxGDIImageHandlerList::compatibility_iterator pNode = ms_handlers.GetFirst();
318
319 while ( pNode )
b4eb4c6b 320 {
53ac3021 321 wxGDIImageHandler* pHandler = pNode->GetData();
b4eb4c6b 322
53ac3021
DW
323 if ( pHandler->GetType() == lType )
324 return pHandler;
325 pNode = pNode->GetNext();
b4eb4c6b 326 }
d3b9f782 327 return(NULL);
b4eb4c6b
DW
328}
329
330void wxGDIImage::CleanUpHandlers()
331{
53ac3021
DW
332 wxGDIImageHandlerList::compatibility_iterator pNode = ms_handlers.GetFirst();
333
334 while ( pNode )
b4eb4c6b 335 {
53ac3021
DW
336 wxGDIImageHandler* pHandler = pNode->GetData();
337 wxGDIImageHandlerList::compatibility_iterator pNext = pNode->GetNext();
338
339 delete pHandler;
340 ms_handlers.Erase( pNode );
341 pNode = pNext;
b4eb4c6b
DW
342 }
343}
344
345void wxGDIImage::InitStandardHandlers()
346{
347 AddHandler(new wxBMPResourceHandler);
348 AddHandler(new wxBMPFileHandler);
b4eb4c6b
DW
349 AddHandler(new wxICOResourceHandler);
350 AddHandler(new wxICOFileHandler);
351}
352
353// ----------------------------------------------------------------------------
354// wxBitmap handlers
355// ----------------------------------------------------------------------------
356
6670f564
WS
357bool wxBMPResourceHandler::LoadFile( wxBitmap* pBitmap,
358 int nId,
6b5c2d52 359 wxBitmapType WXUNUSED(lFlags),
6670f564
WS
360 int WXUNUSED(nDesiredWidth),
361 int WXUNUSED(nDesiredHeight) )
b4eb4c6b 362{
3029781e
DW
363 SIZEL vSize = {0, 0};
364 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
365 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
366 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
367
368 pBitmap->SetHBITMAP((WXHBITMAP)::GpiLoadBitmap( hPS
369 ,NULLHANDLE
370 ,nId
371 ,0
372 ,0
373 ));
374 ::GpiDestroyPS(hPS);
375 ::DevCloseDC(hDC);
376
377 wxBitmapRefData* pData = pBitmap->GetBitmapData();
378
379 if ( pBitmap->Ok() )
b4eb4c6b 380 {
3029781e 381 BITMAPINFOHEADER vBmph;
b4eb4c6b 382
3029781e
DW
383 ::GpiQueryBitmapParameters(GetHbitmapOf(*pBitmap), &vBmph);
384 pData->m_nWidth = vBmph.cx;
385 pData->m_nHeight = vBmph.cy;
386 pData->m_nDepth = vBmph.cBitCount;
b4eb4c6b 387 }
3029781e
DW
388 return(pBitmap->Ok());
389} // end of wxBMPResourceHandler::LoadFile
b4eb4c6b 390
6670f564
WS
391bool wxBMPFileHandler::LoadFile( wxBitmap* pBitmap,
392 const wxString& WXUNUSED(rName),
393 HPS WXUNUSED(hPs),
6b5c2d52 394 wxBitmapType WXUNUSED(lFlags),
6670f564
WS
395 int WXUNUSED(nDesiredWidth),
396 int WXUNUSED(nDesiredHeight) )
b4eb4c6b 397{
63a3cd7a 398#if defined(wxUSE_IMAGE_LOADING_IN_OS2) && wxUSE_IMAGE_LOADING_IN_OS2
6670f564 399 wxPalette* pPalette = NULL;
b4eb4c6b 400
6670f564
WS
401 bool bSuccess = false; /* wxLoadIntoBitmap( WXSTRINGCAST rName
402 ,pBitmap
403 ,&pPalette
404 ) != 0; */
b4eb4c6b
DW
405 if (bSuccess && pPalette)
406 {
407 pBitmap->SetPalette(*pPalette);
408 }
409
410 // it was copied by the bitmap if it was loaded successfully
411 delete pPalette;
412
413 return(bSuccess);
414#else
6670f564
WS
415 wxUnusedVar(pBitmap);
416 return false;
b4eb4c6b
DW
417#endif
418}
419
6670f564
WS
420bool wxBMPFileHandler::SaveFile( wxBitmap* pBitmap,
421 const wxString& WXUNUSED(rName),
6b5c2d52 422 wxBitmapType WXUNUSED(nType),
6670f564 423 const wxPalette* pPal )
b4eb4c6b 424{
63a3cd7a 425#if defined(wxUSE_IMAGE_LOADING_IN_OS2) && wxUSE_IMAGE_LOADING_IN_OS2
6670f564 426 wxPalette* pActualPalette = (wxPalette *)pPal;
b4eb4c6b
DW
427
428 if (!pActualPalette)
429 pActualPalette = pBitmap->GetPalette();
430 /* return(wxSaveBitmap( WXSTRINGCAST rName
431 ,pBitmap
432 ,pActualPalette
433 ) != 0); */
6670f564 434 return false;
b4eb4c6b 435#else
6670f564
WS
436 wxUnusedVar(pBitmap);
437 wxUnusedVar(pPal);
438 return false;
b4eb4c6b
DW
439#endif
440}
441
442// ----------------------------------------------------------------------------
443// wxIcon handlers
444// ----------------------------------------------------------------------------
445
6670f564
WS
446bool wxICOFileHandler::LoadIcon( wxIcon* pIcon,
447 const wxString& WXUNUSED(rName),
448 HPS WXUNUSED(hPs),
6b5c2d52 449 wxBitmapType WXUNUSED(lFlags),
6670f564
WS
450 int WXUNUSED(nDesiredWidth),
451 int WXUNUSED(nDesiredHeight) )
b4eb4c6b 452{
63a3cd7a 453#if defined(wxUSE_RESOURCE_LOADING_IN_OS2) && wxUSE_RESOURCE_LOADING_IN_OS2
b4eb4c6b
DW
454 pIcon->UnRef();
455
6670f564 456 return false;
b4eb4c6b 457#else
6670f564
WS
458 wxUnusedVar(pIcon);
459 return false;
b4eb4c6b
DW
460#endif
461}
462
6670f564
WS
463bool wxICOResourceHandler::LoadIcon( wxIcon* pIcon,
464 const wxString& rName,
465 HPS WXUNUSED(hPs),
6b5c2d52 466 wxBitmapType WXUNUSED(lFlags),
6670f564
WS
467 int WXUNUSED(nDesiredWidth),
468 int WXUNUSED(nDesiredHeight) )
b4eb4c6b 469{
22e90769 470 HPOINTER hIcon;
b4eb4c6b 471
96ad3e4e 472 hIcon = ::WinLoadFileIcon( rName.c_str()
22e90769
DW
473 ,TRUE // load for private use
474 );
b4eb4c6b 475
22e90769 476 pIcon->SetSize(32, 32); // all OS/2 icons are 32 x 32
b4eb4c6b 477
22e90769 478 pIcon->SetHICON((WXHICON)hIcon);
b4eb4c6b 479
22e90769
DW
480 return pIcon->Ok();
481} // end of wxICOResourceHandler::LoadIcon