]> git.saurik.com Git - wxWidgets.git/blob - src/os2/gdiimage.cpp
another segfault fix
[wxWidgets.git] / src / os2 / gdiimage.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/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 license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "gdiimage.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27
28 #ifndef WX_PRECOMP
29 #include "wx/string.h"
30 #endif // WX_PRECOMP
31
32 #include "wx/os2/private.h"
33 #include "wx/app.h"
34 #include "wx/xpmhand.h"
35 #include "wx/os2/gdiimage.h"
36
37 // ----------------------------------------------------------------------------
38 // private classes
39 // ----------------------------------------------------------------------------
40
41 // all image handlers are declared/defined in this file because the outside
42 // world doesn't have to know about them (but only about wxBITMAP_TYPE_XXX ids)
43
44 class WXDLLEXPORT wxBMPFileHandler : public wxBitmapHandler
45 {
46 public:
47 wxBMPFileHandler() : wxBitmapHandler(_T("Windows bitmap file"), _T("bmp"),
48 wxBITMAP_TYPE_BMP)
49 {
50 }
51
52 virtual bool LoadFile( wxBitmap* pBitmap
53 ,const wxString& rName
54 ,HPS hPs
55 ,long lFlags
56 ,int nDesiredWidth
57 ,int nDesiredHeight
58 );
59 virtual bool SaveFile( wxBitmap* pBitmap
60 ,const wxString& rName
61 ,int lType
62 ,const wxPalette* pPalette = NULL
63 );
64
65 private:
66 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
67 };
68
69 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
70 {
71 public:
72 wxBMPResourceHandler() : wxBitmapHandler(_T("Windows bitmap resource"),
73 wxEmptyString,
74 wxBITMAP_TYPE_BMP_RESOURCE)
75 {
76 }
77
78 virtual bool LoadFile( wxBitmap* pBitmap
79 ,const wxString& rName
80 ,HPS hPs
81 ,long lFlags
82 ,int nDesiredWidth
83 ,int nDesiredHeight
84 );
85
86 private:
87 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
88 };
89
90 class WXDLLEXPORT wxIconHandler : public wxGDIImageHandler
91 {
92 public:
93 wxIconHandler( const wxString& rName
94 ,const wxString& rExt
95 ,long lType
96 ) : wxGDIImageHandler( rName
97 ,rExt
98 ,lType
99 )
100 {
101 }
102
103 // creating and saving icons is not supported
104 virtual bool Create( wxGDIImage* WXUNUSED(pImage)
105 ,void* WXUNUSED(pData)
106 ,long WXUNUSED(lFlags)
107 ,int WXUNUSED(nWidth)
108 ,int WXUNUSED(nHeight)
109 ,int WXUNUSED(nDepth) = 1
110 )
111 {
112 return(FALSE);
113 }
114
115 virtual bool Save( wxGDIImage* WXUNUSED(pImage)
116 ,const wxString& WXUNUSED(rName)
117 ,int WXUNUSED(nType)
118 )
119 {
120 return(FALSE);
121 }
122 virtual bool Load( wxGDIImage* pImage
123 ,const wxString& rName
124 ,HPS hPs
125 ,long lFlags
126 ,int nDesiredWidth
127 ,int nDesiredHeight
128 )
129 {
130 wxIcon* pIcon = wxDynamicCast(pImage, wxIcon);
131 wxCHECK_MSG(pIcon, FALSE, _T("wxIconHandler only works with icons"));
132
133 return LoadIcon( pIcon
134 ,rName
135 ,hPs
136 ,lFlags
137 ,nDesiredWidth
138 ,nDesiredHeight
139 );
140 }
141
142 protected:
143 virtual bool LoadIcon( wxIcon* pIcon
144 ,const wxString& rName
145 ,HPS hPs
146 ,long lFlags
147 ,int nDesiredWidth = -1
148 ,int nDesiredHeight = -1
149 ) = 0;
150 };
151
152 class WXDLLEXPORT wxICOFileHandler : public wxIconHandler
153 {
154 public:
155 wxICOFileHandler() : wxIconHandler(_T("ICO icon file"),
156 _T("ico"),
157 wxBITMAP_TYPE_ICO)
158 {
159 }
160
161 virtual bool LoadIcon( wxIcon * pIcon
162 ,const wxString& rName
163 ,HPS hPs
164 ,long lFlags
165 ,int nDesiredWidth = -1
166 ,int nDesiredHeight = -1
167 );
168
169 private:
170 DECLARE_DYNAMIC_CLASS(wxICOFileHandler)
171 };
172
173 class WXDLLEXPORT wxICOResourceHandler: public wxIconHandler
174 {
175 public:
176 wxICOResourceHandler() : wxIconHandler(_T("ICO resource"),
177 _T("ico"),
178 wxBITMAP_TYPE_ICO_RESOURCE)
179 {
180 }
181
182 virtual bool LoadIcon( wxIcon* pIcon
183 ,const wxString& rName
184 ,HPS hPs
185 ,long lFlags
186 ,int nDesiredWidth = -1
187 ,int nDesiredHeight = -1
188 );
189
190 private:
191 DECLARE_DYNAMIC_CLASS(wxICOResourceHandler)
192 };
193
194 // ----------------------------------------------------------------------------
195 // wxWin macros
196 // ----------------------------------------------------------------------------
197
198 #if !USE_SHARED_LIBRARIES
199 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
200 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
201 IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxGDIImageHandler)
202 IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxGDIImageHandler)
203 #endif
204
205 // ----------------------------------------------------------------------------
206 // private functions
207 // ----------------------------------------------------------------------------
208
209 static wxSize GetHiconSize(WXHICON hicon);
210
211 // ============================================================================
212 // implementation
213 // ============================================================================
214
215 wxList wxGDIImage::ms_handlers;
216
217 // ----------------------------------------------------------------------------
218 // wxGDIImage functions forwarded to wxGDIImageRefData
219 // ----------------------------------------------------------------------------
220
221 bool wxGDIImage::FreeResource(
222 bool WXUNUSED(bForce)
223 )
224 {
225 if ( !IsNull() )
226 {
227 GetGDIImageData()->Free();
228 GetGDIImageData()->m_hHandle = 0;
229 }
230
231 return(TRUE);
232 }
233
234 WXHANDLE wxGDIImage::GetResourceHandle()
235 {
236 return GetHandle();
237 }
238
239 // ----------------------------------------------------------------------------
240 // wxGDIImage handler stuff
241 // ----------------------------------------------------------------------------
242
243 void wxGDIImage::AddHandler(
244 wxGDIImageHandler* pHandler
245 )
246 {
247 ms_handlers.Append(pHandler);
248 }
249
250 void wxGDIImage::InsertHandler(
251 wxGDIImageHandler* pHandler
252 )
253 {
254 ms_handlers.Insert(pHandler);
255 }
256
257 bool wxGDIImage::RemoveHandler(
258 const wxString& rName
259 )
260 {
261 wxGDIImageHandler* pHandler = FindHandler(rName);
262
263 if (pHandler)
264 {
265 ms_handlers.DeleteObject(pHandler);
266 return(TRUE);
267 }
268 else
269 return(FALSE);
270 }
271
272 wxGDIImageHandler* wxGDIImage::FindHandler(
273 const wxString& rName
274 )
275 {
276 wxNode* pNode = ms_handlers.First();
277
278 while (pNode)
279 {
280 wxGDIImageHandler* pHandler = (wxGDIImageHandler *)pNode->Data();
281
282 if (pHandler->GetName() == rName)
283 return(pHandler);
284 pNode = pNode->Next();
285 }
286 return(NULL);
287 }
288
289 wxGDIImageHandler* wxGDIImage::FindHandler(
290 const wxString& rExtension
291 , long lType
292 )
293 {
294 wxNode* pNode = ms_handlers.First();
295
296 while (pNode)
297 {
298 wxGDIImageHandler* pHandler = (wxGDIImageHandler *)pNode->Data();
299
300 if ((pHandler->GetExtension() = rExtension) &&
301 (lType == -1 || pHandler->GetType() == lType))
302 {
303 return(pHandler);
304 }
305 pNode = pNode->Next();
306 }
307 return(NULL);
308 }
309
310 wxGDIImageHandler* wxGDIImage::FindHandler(
311 long lType
312 )
313 {
314 wxNode* pNode = ms_handlers.First();
315
316 while (pNode)
317 {
318 wxGDIImageHandler* pHandler = (wxGDIImageHandler *)pNode->Data();
319
320 if (pHandler->GetType() == lType)
321 return pHandler;
322 pNode = pNode->Next();
323 }
324 return(NULL);
325 }
326
327 void wxGDIImage::CleanUpHandlers()
328 {
329 wxNode* pNode = ms_handlers.First();
330
331 while (pNode)
332 {
333 wxGDIImageHandler* pHandler = (wxGDIImageHandler *)pNode->Data();
334 wxNode* pNext = pNode->Next();
335
336 delete pHandler;
337 #if (!(defined(__VISAGECPP__) && (__IBMCPP__ < 400 || __IBMC__ < 400 )))
338 delete pNode;
339 #endif
340 pNode = pNext;
341 }
342 }
343
344 void wxGDIImage::InitStandardHandlers()
345 {
346 AddHandler(new wxBMPResourceHandler);
347 AddHandler(new wxBMPFileHandler);
348
349 #if wxUSE_XPM_IN_OS2
350 AddHandler(new wxXPMFileHandler);
351 AddHandler(new wxXPMDataHandler);
352 #endif
353
354 AddHandler(new wxICOResourceHandler);
355 AddHandler(new wxICOFileHandler);
356 }
357
358 // ----------------------------------------------------------------------------
359 // wxBitmap handlers
360 // ----------------------------------------------------------------------------
361
362 bool wxBMPResourceHandler::LoadFile(
363 wxBitmap* pBitmap
364 , const wxString& rName
365 , HPS hPs
366 , long lFlags
367 , int nDesiredWidth
368 , int nDesiredHeight
369 )
370 {
371 // TODO: load a bitmap from a file
372 /*
373 rBitmap->SetHBITMAP((WXHBITMAP)::LoadBitmap(wxGetInstance(), rName));
374
375 wxBitmapRefData* pData = bitmap->GetBitmapData();
376
377 if (pBitmap->Ok())
378 {
379 BITMAP bm;
380
381 if ( !::GetObject(GetHbitmapOf(*pBitmap), sizeof(BITMAP), (LPSTR) &bm) )
382 {
383 wxLogLastError("GetObject(HBITMAP)");
384 }
385
386 data->m_width = bm.bmWidth;
387 data->m_height = bm.bmHeight;
388 data->m_depth = bm.bmBitsPixel;
389 }
390 else
391 {
392 // it's probably not found
393 wxLogError(wxT("Can't load bitmap '%s' from resources! Check .rc file."),
394 name.c_str());
395 }
396
397 return bitmap->Ok();
398 */
399 return(FALSE);
400 }
401
402 bool wxBMPFileHandler::LoadFile(
403 wxBitmap* pBitmap
404 , const wxString& rName
405 , HPS hPs
406 , long WXUNUSED(lFlags)
407 , int WXUNUSED(nDesiredWidth)
408 , int WXUNUSED(nDesiredHeight)
409 )
410 {
411 #if wxUSE_IMAGE_LOADING_IN_OS2
412 wxPalette* pPalette = NULL;
413
414 bool bSuccess = FALSE; /* wxLoadIntoBitmap( WXSTRINGCAST rName
415 ,pBitmap
416 ,&pPalette
417 ) != 0; */
418 if (bSuccess && pPalette)
419 {
420 pBitmap->SetPalette(*pPalette);
421 }
422
423 // it was copied by the bitmap if it was loaded successfully
424 delete pPalette;
425
426 return(bSuccess);
427 #else
428 return(FALSE);
429 #endif
430 }
431
432 bool wxBMPFileHandler::SaveFile(
433 wxBitmap* pBitmap
434 , const wxString& rName
435 , int WXUNUSED(nType)
436 , const wxPalette* pPal
437 )
438 {
439 #if wxUSE_IMAGE_LOADING_IN_OS2
440 wxPalette* pActualPalette = (wxPalette *)pPal;
441
442 if (!pActualPalette)
443 pActualPalette = pBitmap->GetPalette();
444 /* return(wxSaveBitmap( WXSTRINGCAST rName
445 ,pBitmap
446 ,pActualPalette
447 ) != 0); */
448 return(FALSE);
449 #else
450 return(FALSE);
451 #endif
452 }
453
454 // ----------------------------------------------------------------------------
455 // wxIcon handlers
456 // ----------------------------------------------------------------------------
457
458 bool wxICOFileHandler::LoadIcon(
459 wxIcon* pIcon
460 , const wxString& rName
461 , HPS hPs
462 , long lFlags
463 , int nDesiredWidth
464 , int nDesiredHeight
465 )
466 {
467 #if wxUSE_RESOURCE_LOADING_IN_OS2
468 pIcon->UnRef();
469
470 // actual size
471 wxSize vSize;
472
473 // TODO: load icon directly from a file
474 /*
475 #ifdef __WIN32__
476 HICON hicon = ::ExtractIcon(wxGetInstance(), name, first);
477 if ( !hicon )
478 {
479 wxLogSysError(_T("Failed to load icon from the file '%s'"),
480 name.c_str());
481
482 return FALSE;
483 }
484
485 size = GetHiconSize(hicon);
486 #else // Win16
487 HICON hicon = ReadIconFile((wxChar *)name.c_str(),
488 wxGetInstance(),
489 &size.x, &size.y);
490 #endif // Win32/Win16
491
492 if ( (desiredWidth != -1 && desiredWidth != size.x) ||
493 (desiredHeight != -1 && desiredHeight != size.y) )
494 {
495 wxLogDebug(_T("Returning FALSE from wxICOFileHandler::Load because "
496 "of the size mismatch: actual (%d, %d), "
497 "requested (%d, %d)"),
498 size.x, size.y,
499 desiredWidth, desiredHeight);
500
501 ::DestroyIcon(hicon);
502
503 return FALSE;
504 }
505
506 icon->SetHICON((WXHICON)hicon);
507 icon->SetSize(size.x, size.y);
508
509 return icon->Ok();
510 */
511 return(FALSE);
512 #else
513 return(FALSE);
514 #endif
515 }
516
517 bool wxICOResourceHandler::LoadIcon(
518 wxIcon* pIcon
519 , const wxString& rName
520 , HPS hPs
521 , long lFlags
522 , int WXUNUSED(nDesiredWidth)
523 , int WXUNUSED(nDesiredHeight)
524 )
525 {
526 HPOINTER hIcon;
527
528 hIcon = ::WinLoadFileIcon( (PSZ)rName.c_str()
529 ,TRUE // load for private use
530 );
531
532 pIcon->SetSize(32, 32); // all OS/2 icons are 32 x 32
533
534
535 pIcon->SetHICON((WXHICON)hIcon);
536
537 return pIcon->Ok();
538 } // end of wxICOResourceHandler::LoadIcon
539
540 // ----------------------------------------------------------------------------
541 // private functions
542 // ----------------------------------------------------------------------------
543
544 static wxSize GetHiconSize(
545 WXHICON hicon
546 )
547 {
548 wxSize vSize(32, 32); // default
549
550 // all OS/2 icons are 32x32
551 return(vSize);
552 }
553