Merge in from trunk r67662 to r64801
[wxWidgets.git] / src / os2 / gdiimage.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/gdiimage.cpp
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>
9 // Licence: wxWindows licence
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"
26 #include "wx/app.h"
27 #endif // WX_PRECOMP
28
29 #include "wx/os2/private.h"
30 #include "wx/os2/gdiimage.h"
31
32 #include "wx/listimpl.cpp"
33 WX_DEFINE_LIST(wxGDIImageHandlerList)
34
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
42 class WXDLLEXPORT wxBMPFileHandler : public wxBitmapHandler
43 {
44 public:
45 wxBMPFileHandler() : wxBitmapHandler(wxT("Windows bitmap file"), wxT("bmp"),
46 wxBITMAP_TYPE_BMP)
47 {
48 }
49
50 virtual bool LoadFile( wxBitmap* pBitmap
51 ,const wxString& rName
52 ,HPS hPs
53 ,wxBitmapType lFlags
54 ,int nDesiredWidth
55 ,int nDesiredHeight
56 );
57 virtual bool SaveFile( wxBitmap* pBitmap
58 ,const wxString& rName
59 ,wxBitmapType lType
60 ,const wxPalette* pPalette = NULL
61 );
62
63 private:
64 inline virtual bool LoadFile( wxBitmap* pBitmap
65 ,int nId
66 ,wxBitmapType lFlags
67 ,int nDesiredWidth
68 ,int nDesiredHeight
69 )
70 {
71 return wxBitmapHandler::LoadFile( pBitmap
72 ,nId
73 ,lFlags
74 ,nDesiredWidth
75 ,nDesiredHeight
76 );
77 }
78 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
79 };
80
81 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
82 {
83 public:
84 wxBMPResourceHandler() : wxBitmapHandler(wxT("Windows bitmap resource"),
85 wxEmptyString,
86 wxBITMAP_TYPE_BMP_RESOURCE)
87 {
88 }
89
90 virtual bool LoadFile( wxBitmap* pBitmap
91 ,int nId
92 ,wxBitmapType lFlags
93 ,int nDesiredWidth
94 ,int nDesiredHeight
95 );
96
97 private:
98 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
99 };
100
101 class WXDLLEXPORT wxIconHandler : public wxGDIImageHandler
102 {
103 public:
104 wxIconHandler( const wxString& rName
105 ,const wxString& rExt
106 ,wxBitmapType lType
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)
116 ,const void* WXUNUSED(pData)
117 ,wxBitmapType WXUNUSED(lFlags)
118 ,int WXUNUSED(nWidth)
119 ,int WXUNUSED(nHeight)
120 ,int WXUNUSED(nDepth) = 1
121 )
122 {
123 return false;
124 }
125
126 virtual bool Save( const wxGDIImage* WXUNUSED(pImage)
127 ,const wxString& WXUNUSED(rName)
128 ,wxBitmapType WXUNUSED(nType)
129 ) const
130 {
131 return false;
132 }
133 virtual bool Load( wxGDIImage* pImage
134 ,const wxString& rName
135 ,HPS hPs
136 ,wxBitmapType lFlags
137 ,int nDesiredWidth
138 ,int nDesiredHeight
139 )
140 {
141 wxIcon* pIcon = wxDynamicCast(pImage, wxIcon);
142 wxCHECK_MSG(pIcon, false, wxT("wxIconHandler only works with icons"));
143
144 return LoadIcon( pIcon
145 ,rName
146 ,hPs
147 ,lFlags
148 ,nDesiredWidth
149 ,nDesiredHeight
150 );
151 }
152
153 protected:
154 virtual bool LoadIcon( wxIcon* pIcon
155 ,const wxString& rName
156 ,HPS hPs
157 ,wxBitmapType lFlags
158 ,int nDesiredWidth = -1
159 ,int nDesiredHeight = -1
160 ) = 0;
161 private:
162 inline virtual bool Load( wxGDIImage* WXUNUSED(pImage),
163 int WXUNUSED(nId),
164 wxBitmapType WXUNUSED(lFlags),
165 int WXUNUSED(nDesiredWidth),
166 int WXUNUSED(nDesiredHeight) )
167 {
168 return false;
169 }
170 };
171
172 class WXDLLEXPORT wxICOFileHandler : public wxIconHandler
173 {
174 public:
175 wxICOFileHandler() : wxIconHandler(wxT("ICO icon file"),
176 wxT("ico"),
177 wxBITMAP_TYPE_ICO)
178 {
179 }
180
181 virtual bool LoadIcon( wxIcon * pIcon
182 ,const wxString& rName
183 ,HPS hPs
184 ,wxBitmapType lFlags
185 ,int nDesiredWidth = -1
186 ,int nDesiredHeight = -1
187 );
188
189 private:
190 DECLARE_DYNAMIC_CLASS(wxICOFileHandler)
191 };
192
193 class WXDLLEXPORT wxICOResourceHandler: public wxIconHandler
194 {
195 public:
196 wxICOResourceHandler() : wxIconHandler(wxT("ICO resource"),
197 wxT("ico"),
198 wxBITMAP_TYPE_ICO_RESOURCE)
199 {
200 }
201
202 virtual bool LoadIcon( wxIcon* pIcon
203 ,const wxString& rName
204 ,HPS hPs
205 ,wxBitmapType lFlags
206 ,int nDesiredWidth = -1
207 ,int nDesiredHeight = -1
208 );
209
210 private:
211 DECLARE_DYNAMIC_CLASS(wxICOResourceHandler)
212 };
213
214 // ----------------------------------------------------------------------------
215 // wxWin macros
216 // ----------------------------------------------------------------------------
217
218 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
219 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
220 IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxObject)
221 IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxObject)
222
223 // ============================================================================
224 // implementation
225 // ============================================================================
226
227 wxGDIImageHandlerList wxGDIImage::ms_handlers;
228
229 // ----------------------------------------------------------------------------
230 // wxGDIImage functions forwarded to wxGDIImageRefData
231 // ----------------------------------------------------------------------------
232
233 bool wxGDIImage::FreeResource( bool WXUNUSED(bForce) )
234 {
235 if ( !IsNull() )
236 {
237 GetGDIImageData()->Free();
238 GetGDIImageData()->m_hHandle = 0;
239 }
240
241 return true;
242 }
243
244 WXHANDLE wxGDIImage::GetResourceHandle() const
245 {
246 return GetHandle();
247 }
248
249 // ----------------------------------------------------------------------------
250 // wxGDIImage handler stuff
251 // ----------------------------------------------------------------------------
252
253 void wxGDIImage::AddHandler( wxGDIImageHandler* pHandler )
254 {
255 ms_handlers.Append(pHandler);
256 }
257
258 void wxGDIImage::InsertHandler( wxGDIImageHandler* pHandler )
259 {
260 ms_handlers.Insert(pHandler);
261 }
262
263 bool wxGDIImage::RemoveHandler( const wxString& rName )
264 {
265 wxGDIImageHandler* pHandler = FindHandler(rName);
266
267 if (pHandler)
268 {
269 ms_handlers.DeleteObject(pHandler);
270 return true;
271 }
272 else
273 return false;
274 }
275
276 wxGDIImageHandler* wxGDIImage::FindHandler(
277 const wxString& rName
278 )
279 {
280 wxGDIImageHandlerList::compatibility_iterator pNode = ms_handlers.GetFirst();
281
282 while ( pNode )
283 {
284 wxGDIImageHandler* pHandler = pNode->GetData();
285
286 if ( pHandler->GetName() == rName )
287 return pHandler;
288 pNode = pNode->GetNext();
289 }
290 return(NULL);
291 }
292
293 wxGDIImageHandler* wxGDIImage::FindHandler(
294 const wxString& rExtension
295 , wxBitmapType lType
296 )
297 {
298 wxGDIImageHandlerList::compatibility_iterator pNode = ms_handlers.GetFirst();
299 while ( pNode )
300 {
301 wxGDIImageHandler* pHandler = pNode->GetData();
302
303 if ( (pHandler->GetExtension() == rExtension) &&
304 (lType == -1 || pHandler->GetType() == lType) )
305 {
306 return pHandler;
307 }
308 pNode = pNode->GetNext();
309 }
310 return(NULL);
311 }
312
313 wxGDIImageHandler* wxGDIImage::FindHandler(
314 wxBitmapType lType
315 )
316 {
317 wxGDIImageHandlerList::compatibility_iterator pNode = ms_handlers.GetFirst();
318
319 while ( pNode )
320 {
321 wxGDIImageHandler* pHandler = pNode->GetData();
322
323 if ( pHandler->GetType() == lType )
324 return pHandler;
325 pNode = pNode->GetNext();
326 }
327 return(NULL);
328 }
329
330 void wxGDIImage::CleanUpHandlers()
331 {
332 wxGDIImageHandlerList::compatibility_iterator pNode = ms_handlers.GetFirst();
333
334 while ( pNode )
335 {
336 wxGDIImageHandler* pHandler = pNode->GetData();
337 wxGDIImageHandlerList::compatibility_iterator pNext = pNode->GetNext();
338
339 delete pHandler;
340 ms_handlers.Erase( pNode );
341 pNode = pNext;
342 }
343 }
344
345 void wxGDIImage::InitStandardHandlers()
346 {
347 AddHandler(new wxBMPResourceHandler);
348 AddHandler(new wxBMPFileHandler);
349 AddHandler(new wxICOResourceHandler);
350 AddHandler(new wxICOFileHandler);
351 }
352
353 // ----------------------------------------------------------------------------
354 // wxBitmap handlers
355 // ----------------------------------------------------------------------------
356
357 bool wxBMPResourceHandler::LoadFile( wxBitmap* pBitmap,
358 int nId,
359 wxBitmapType WXUNUSED(lFlags),
360 int WXUNUSED(nDesiredWidth),
361 int WXUNUSED(nDesiredHeight) )
362 {
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->IsOk() )
380 {
381 BITMAPINFOHEADER vBmph;
382
383 ::GpiQueryBitmapParameters(GetHbitmapOf(*pBitmap), &vBmph);
384 pData->m_nWidth = vBmph.cx;
385 pData->m_nHeight = vBmph.cy;
386 pData->m_nDepth = vBmph.cBitCount;
387 }
388 return(pBitmap->IsOk());
389 } // end of wxBMPResourceHandler::LoadFile
390
391 bool wxBMPFileHandler::LoadFile( wxBitmap* pBitmap,
392 const wxString& WXUNUSED(rName),
393 HPS WXUNUSED(hPs),
394 wxBitmapType WXUNUSED(lFlags),
395 int WXUNUSED(nDesiredWidth),
396 int WXUNUSED(nDesiredHeight) )
397 {
398 #if defined(wxUSE_IMAGE_LOADING_IN_OS2) && wxUSE_IMAGE_LOADING_IN_OS2
399 wxPalette* pPalette = NULL;
400
401 bool bSuccess = false; /* wxLoadIntoBitmap( WXSTRINGCAST rName
402 ,pBitmap
403 ,&pPalette
404 ) != 0; */
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
415 wxUnusedVar(pBitmap);
416 return false;
417 #endif
418 }
419
420 bool wxBMPFileHandler::SaveFile( wxBitmap* pBitmap,
421 const wxString& WXUNUSED(rName),
422 wxBitmapType WXUNUSED(nType),
423 const wxPalette* pPal )
424 {
425 #if defined(wxUSE_IMAGE_LOADING_IN_OS2) && wxUSE_IMAGE_LOADING_IN_OS2
426 wxPalette* pActualPalette = (wxPalette *)pPal;
427
428 if (!pActualPalette)
429 pActualPalette = pBitmap->GetPalette();
430 /* return(wxSaveBitmap( WXSTRINGCAST rName
431 ,pBitmap
432 ,pActualPalette
433 ) != 0); */
434 return false;
435 #else
436 wxUnusedVar(pBitmap);
437 wxUnusedVar(pPal);
438 return false;
439 #endif
440 }
441
442 // ----------------------------------------------------------------------------
443 // wxIcon handlers
444 // ----------------------------------------------------------------------------
445
446 bool wxICOFileHandler::LoadIcon( wxIcon* pIcon,
447 const wxString& WXUNUSED(rName),
448 HPS WXUNUSED(hPs),
449 wxBitmapType WXUNUSED(lFlags),
450 int WXUNUSED(nDesiredWidth),
451 int WXUNUSED(nDesiredHeight) )
452 {
453 #if defined(wxUSE_RESOURCE_LOADING_IN_OS2) && wxUSE_RESOURCE_LOADING_IN_OS2
454 pIcon->UnRef();
455
456 return false;
457 #else
458 wxUnusedVar(pIcon);
459 return false;
460 #endif
461 }
462
463 bool wxICOResourceHandler::LoadIcon( wxIcon* pIcon,
464 const wxString& rName,
465 HPS WXUNUSED(hPs),
466 wxBitmapType WXUNUSED(lFlags),
467 int WXUNUSED(nDesiredWidth),
468 int WXUNUSED(nDesiredHeight) )
469 {
470 HPOINTER hIcon;
471
472 hIcon = ::WinLoadFileIcon( rName.c_str()
473 ,TRUE // load for private use
474 );
475
476 pIcon->SetSize(32, 32); // all OS/2 icons are 32 x 32
477
478 pIcon->SetHICON((WXHICON)hIcon);
479
480 return pIcon->IsOk();
481 } // end of wxICOResourceHandler::LoadIcon