]> git.saurik.com Git - wxWidgets.git/blob - src/msw/bitmap.cpp
memdc and bitmap fixes
[wxWidgets.git] / src / msw / bitmap.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: bitmap.cpp
3 // Purpose: wxBitmap
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "bitmap.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include <stdio.h>
25 #include "wx/setup.h"
26 #include "wx/list.h"
27 #include "wx/utils.h"
28 #include "wx/app.h"
29 #include "wx/palette.h"
30 #include "wx/bitmap.h"
31 #include "wx/icon.h"
32 #endif
33
34 #include "wx/msw/private.h"
35 #include "wx/log.h"
36
37 #include "assert.h"
38
39 #if USE_XPM_IN_MSW
40 #define FOR_MSW 1
41 #include "../../contrib/wxxpm/libxpm.34b/lib/xpm34.h"
42 #endif
43
44 #include "wx/msw/dib.h"
45
46 #if !USE_SHARED_LIBRARIES
47 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
48 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
49 #endif
50
51 wxBitmapRefData::wxBitmapRefData(void)
52 {
53 m_ok = FALSE;
54 m_width = 0;
55 m_height = 0;
56 m_depth = 0;
57 m_quality = 0;
58 m_hBitmap = 0 ;
59 m_selectedInto = NULL;
60 m_numColors = 0;
61 m_bitmapMask = NULL;
62 }
63
64 wxBitmapRefData::~wxBitmapRefData(void)
65 {
66 if (m_selectedInto)
67 {
68 char buf[200];
69 sprintf(buf, "Bitmap was deleted without selecting out of wxMemoryDC %X.", (unsigned int) m_selectedInto);
70 wxFatalError(buf);
71 }
72 if (m_hBitmap)
73 {
74 DeleteObject((HBITMAP) m_hBitmap);
75 }
76 m_hBitmap = 0 ;
77
78 if (m_bitmapMask)
79 delete m_bitmapMask;
80 m_bitmapMask = NULL;
81 }
82
83 wxList wxBitmap::sm_handlers;
84
85 wxBitmap::wxBitmap(void)
86 {
87 m_refData = NULL; // new wxBitmapRefData;
88
89 if ( wxTheBitmapList )
90 wxTheBitmapList->AddBitmap(this);
91 }
92
93 wxBitmap::~wxBitmap(void)
94 {
95 if (wxTheBitmapList)
96 wxTheBitmapList->DeleteObject(this);
97 }
98
99 bool wxBitmap::FreeResource(bool force)
100 {
101 if ( !M_BITMAPDATA )
102 return FALSE;
103
104 if (M_BITMAPDATA->m_selectedInto)
105 {
106 char buf[200];
107 sprintf(buf, "Bitmap %X was deleted without selecting out of wxMemoryDC %X.", (unsigned int) this, (unsigned int) M_BITMAPDATA->m_selectedInto);
108 wxFatalError(buf);
109 }
110 if (M_BITMAPDATA->m_hBitmap)
111 {
112 DeleteObject((HBITMAP) M_BITMAPDATA->m_hBitmap);
113 }
114 M_BITMAPDATA->m_hBitmap = 0 ;
115
116 /*
117 if (M_BITMAPDATA->m_bitmapPalette)
118 delete M_BITMAPDATA->m_bitmapPalette;
119
120 M_BITMAPDATA->m_bitmapPalette = NULL ;
121 */
122
123 return TRUE;
124 }
125
126
127 wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
128 {
129 m_refData = new wxBitmapRefData;
130
131 M_BITMAPDATA->m_width = the_width ;
132 M_BITMAPDATA->m_height = the_height ;
133 M_BITMAPDATA->m_depth = no_bits ;
134 M_BITMAPDATA->m_numColors = 0;
135
136 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(the_width, the_height, no_bits, 1, bits);
137
138 if (M_BITMAPDATA->m_hBitmap)
139 M_BITMAPDATA->m_ok = TRUE;
140 else
141 M_BITMAPDATA->m_ok = FALSE;
142
143 M_BITMAPDATA->m_selectedInto = NULL;
144
145 if ( wxTheBitmapList )
146 wxTheBitmapList->AddBitmap(this);
147 }
148
149 wxBitmap::wxBitmap(int w, int h, int d)
150 {
151 (void)Create(w, h, d);
152
153 if ( wxTheBitmapList )
154 wxTheBitmapList->AddBitmap(this);
155 }
156
157 wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
158 {
159 (void) Create(data, type, width, height, depth);
160
161 if ( wxTheBitmapList )
162 wxTheBitmapList->AddBitmap(this);
163 }
164
165 wxBitmap::wxBitmap(const wxString& filename, long type)
166 {
167 LoadFile(filename, (int)type);
168
169 if ( wxTheBitmapList )
170 wxTheBitmapList->AddBitmap(this);
171 }
172
173 #if USE_XPM_IN_MSW
174 // Create from data
175 wxBitmap::wxBitmap(const char **data, wxItem *WXUNUSED(anItem))
176 {
177 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
178 }
179 #endif
180
181 bool wxBitmap::Create(int w, int h, int d)
182 {
183 UnRef();
184
185 m_refData = new wxBitmapRefData;
186
187 M_BITMAPDATA->m_width = w;
188 M_BITMAPDATA->m_height = h;
189 M_BITMAPDATA->m_depth = d;
190
191 if (d > 0)
192 {
193 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(w, h, d, 1, NULL);
194 }
195 else
196 {
197 HDC dc = GetDC(NULL);
198 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateCompatibleBitmap(dc, w, h);
199 ReleaseDC(NULL, dc);
200 M_BITMAPDATA->m_depth = wxDisplayDepth();
201 }
202 if (M_BITMAPDATA->m_hBitmap)
203 M_BITMAPDATA->m_ok = TRUE;
204 else
205 M_BITMAPDATA->m_ok = FALSE;
206 return M_BITMAPDATA->m_ok;
207 }
208
209 bool wxBitmap::LoadFile(const wxString& filename, long type)
210 {
211 UnRef();
212
213 m_refData = new wxBitmapRefData;
214
215 wxBitmapHandler *handler = FindHandler(type);
216
217 if ( handler == NULL ) {
218 wxLogWarning("no bitmap handler for type %d defined.", type);
219
220 return FALSE;
221 }
222
223 return handler->LoadFile(this, filename, type, -1, -1);
224 }
225
226 bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
227 {
228 UnRef();
229
230 m_refData = new wxBitmapRefData;
231
232 wxBitmapHandler *handler = FindHandler(type);
233
234 if ( handler == NULL ) {
235 wxLogWarning("no bitmap handler for type %d defined.", type);
236
237 return FALSE;
238 }
239
240 return handler->Create(this, data, type, width, height, depth);
241 }
242
243 bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
244 {
245 wxBitmapHandler *handler = FindHandler(type);
246
247 if ( handler == NULL ) {
248 wxLogWarning("no bitmap handler for type %d defined.", type);
249
250 return FALSE;
251 }
252
253 return handler->SaveFile(this, filename, type, palette);
254 }
255
256 void wxBitmap::SetWidth(int w)
257 {
258 if (!M_BITMAPDATA)
259 m_refData = new wxBitmapRefData;
260
261 M_BITMAPDATA->m_width = w;
262 }
263
264 void wxBitmap::SetHeight(int h)
265 {
266 if (!M_BITMAPDATA)
267 m_refData = new wxBitmapRefData;
268
269 M_BITMAPDATA->m_height = h;
270 }
271
272 void wxBitmap::SetDepth(int d)
273 {
274 if (!M_BITMAPDATA)
275 m_refData = new wxBitmapRefData;
276
277 M_BITMAPDATA->m_depth = d;
278 }
279
280 void wxBitmap::SetQuality(int q)
281 {
282 if (!M_BITMAPDATA)
283 m_refData = new wxBitmapRefData;
284
285 M_BITMAPDATA->m_quality = q;
286 }
287
288 void wxBitmap::SetOk(bool isOk)
289 {
290 if (!M_BITMAPDATA)
291 m_refData = new wxBitmapRefData;
292
293 M_BITMAPDATA->m_ok = isOk;
294 }
295
296 void wxBitmap::SetPalette(const wxPalette& palette)
297 {
298 if (!M_BITMAPDATA)
299 m_refData = new wxBitmapRefData;
300
301 M_BITMAPDATA->m_bitmapPalette = palette ;
302 }
303
304 void wxBitmap::SetMask(wxMask *mask)
305 {
306 if (!M_BITMAPDATA)
307 m_refData = new wxBitmapRefData;
308
309 M_BITMAPDATA->m_bitmapMask = mask ;
310 }
311
312 void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
313 {
314 if (!M_BITMAPDATA)
315 m_refData = new wxBitmapRefData;
316
317 M_BITMAPDATA->m_hBitmap = bmp;
318 }
319
320 void wxBitmap::AddHandler(wxBitmapHandler *handler)
321 {
322 sm_handlers.Append(handler);
323 }
324
325 void wxBitmap::InsertHandler(wxBitmapHandler *handler)
326 {
327 sm_handlers.Insert(handler);
328 }
329
330 bool wxBitmap::RemoveHandler(const wxString& name)
331 {
332 wxBitmapHandler *handler = FindHandler(name);
333 if ( handler )
334 {
335 sm_handlers.DeleteObject(handler);
336 return TRUE;
337 }
338 else
339 return FALSE;
340 }
341
342 wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
343 {
344 wxNode *node = sm_handlers.First();
345 while ( node )
346 {
347 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
348 if ( handler->GetName() == name )
349 return handler;
350 node = node->Next();
351 }
352 return NULL;
353 }
354
355 wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
356 {
357 wxNode *node = sm_handlers.First();
358 while ( node )
359 {
360 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
361 if ( handler->GetExtension() == extension &&
362 (bitmapType == -1 || handler->GetType() == bitmapType) )
363 return handler;
364 node = node->Next();
365 }
366 return NULL;
367 }
368
369 wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
370 {
371 wxNode *node = sm_handlers.First();
372 while ( node )
373 {
374 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
375 if (handler->GetType() == bitmapType)
376 return handler;
377 node = node->Next();
378 }
379 return NULL;
380 }
381
382 /*
383 * wxMask
384 */
385
386 wxMask::wxMask(void)
387 {
388 m_maskBitmap = 0;
389 }
390
391 // Construct a mask from a bitmap and a colour indicating
392 // the transparent area
393 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
394 {
395 m_maskBitmap = 0;
396 Create(bitmap, colour);
397 }
398
399 // Construct a mask from a bitmap and a palette index indicating
400 // the transparent area
401 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
402 {
403 m_maskBitmap = 0;
404 Create(bitmap, paletteIndex);
405 }
406
407 // Construct a mask from a mono bitmap (copies the bitmap).
408 wxMask::wxMask(const wxBitmap& bitmap)
409 {
410 m_maskBitmap = 0;
411 Create(bitmap);
412 }
413
414 wxMask::~wxMask(void)
415 {
416 if ( m_maskBitmap )
417 ::DeleteObject((HBITMAP) m_maskBitmap);
418 }
419
420 // Create a mask from a mono bitmap (copies the bitmap).
421 bool wxMask::Create(const wxBitmap& bitmap)
422 {
423 if ( m_maskBitmap )
424 {
425 ::DeleteObject((HBITMAP) m_maskBitmap);
426 m_maskBitmap = 0;
427 }
428 if (!bitmap.Ok() || bitmap.GetDepth() != 1)
429 {
430 return FALSE;
431 }
432 m_maskBitmap = (WXHBITMAP) CreateBitmap(
433 bitmap.GetWidth(),
434 bitmap.GetHeight(),
435 1, 1, 0
436 );
437 HDC srcDC = CreateCompatibleDC(0);
438 SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
439 HDC destDC = CreateCompatibleDC(0);
440 SelectObject(destDC, (HBITMAP) m_maskBitmap);
441 BitBlt(destDC, 0, 0, bitmap.GetWidth(), bitmap.GetHeight(), srcDC, 0, 0, SRCCOPY);
442 SelectObject(srcDC, 0);
443 DeleteDC(srcDC);
444 SelectObject(destDC, 0);
445 DeleteDC(destDC);
446 return TRUE;
447 }
448
449 // Create a mask from a bitmap and a palette index indicating
450 // the transparent area
451 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
452 {
453 if ( m_maskBitmap )
454 {
455 ::DeleteObject((HBITMAP) m_maskBitmap);
456 m_maskBitmap = 0;
457 }
458 if (bitmap.Ok() && bitmap.GetPalette()->Ok())
459 {
460 unsigned char red, green, blue;
461 if (bitmap.GetPalette()->GetRGB(paletteIndex, &red, &green, &blue))
462 {
463 wxColour transparentColour(red, green, blue);
464 return Create(bitmap, transparentColour);
465 }
466 }
467 return FALSE;
468 }
469
470 // Create a mask from a bitmap and a colour indicating
471 // the transparent area
472 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
473 {
474 if ( m_maskBitmap )
475 {
476 ::DeleteObject((HBITMAP) m_maskBitmap);
477 m_maskBitmap = 0;
478 }
479 if (!bitmap.Ok())
480 {
481 return FALSE;
482 }
483
484 // scan the bitmap for the transparent colour and set
485 // the corresponding pixels in the mask to BLACK and
486 // the rest to WHITE
487 COLORREF maskColour = RGB(colour.Red(), colour.Green(), colour.Blue());
488 m_maskBitmap = (WXHBITMAP) ::CreateBitmap(
489 bitmap.GetWidth(),
490 bitmap.GetHeight(),
491 1, 1, 0
492 );
493 HDC srcDC = ::CreateCompatibleDC(0);
494 ::SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
495 HDC destDC = ::CreateCompatibleDC(0);
496 ::SelectObject(destDC, (HBITMAP) m_maskBitmap);
497
498 // this is not very efficient, but I can't think
499 // of a better way of doing it
500 for (int w = 0; w < bitmap.GetWidth(); w++)
501 {
502 for (int h = 0; h < bitmap.GetHeight(); h++)
503 {
504 COLORREF col = GetPixel(srcDC, w, h);
505 if (col == maskColour)
506 {
507 ::SetPixel(destDC, w, h, RGB(0, 0, 0));
508 }
509 else
510 {
511 ::SetPixel(destDC, w, h, RGB(255, 255, 255));
512 }
513 }
514 }
515 ::SelectObject(srcDC, 0);
516 ::DeleteDC(srcDC);
517 ::SelectObject(destDC, 0);
518 ::DeleteDC(destDC);
519 return TRUE;
520 }
521
522 /*
523 * wxBitmapHandler
524 */
525
526 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
527
528 bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
529 {
530 return FALSE;
531 }
532
533 bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
534 int desiredWidth, int desiredHeight)
535 {
536 return FALSE;
537 }
538
539 bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
540 {
541 return FALSE;
542 }
543
544 /*
545 * Standard handlers
546 */
547
548 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
549 {
550 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
551 public:
552 inline wxBMPResourceHandler(void)
553 {
554 m_name = "Windows bitmap resource";
555 m_extension = "";
556 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
557 };
558
559 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
560 int desiredWidth, int desiredHeight);
561 };
562 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
563
564 bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
565 int desiredWidth, int desiredHeight)
566 {
567 // TODO: load colourmap.
568 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ::LoadBitmap(wxGetInstance(), name);
569 if (M_BITMAPHANDLERDATA->m_hBitmap)
570 {
571 M_BITMAPHANDLERDATA->m_ok = TRUE;
572 BITMAP bm;
573 GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(BITMAP), (LPSTR) &bm);
574 M_BITMAPHANDLERDATA->m_width = bm.bmWidth;
575 M_BITMAPHANDLERDATA->m_height = bm.bmHeight;
576 M_BITMAPHANDLERDATA->m_depth = bm.bmPlanes;
577 return TRUE;
578 }
579
580 // it's probably not found
581 wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name.c_str());
582
583 return FALSE;
584 }
585
586 class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
587 {
588 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
589 public:
590 inline wxBMPFileHandler(void)
591 {
592 m_name = "Windows bitmap file";
593 m_extension = "bmp";
594 m_type = wxBITMAP_TYPE_BMP;
595 };
596
597 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
598 int desiredWidth, int desiredHeight);
599 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
600 };
601 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
602
603 bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
604 int desiredWidth, int desiredHeight)
605 {
606 #if USE_IMAGE_LOADING_IN_MSW
607 wxPalette *palette = NULL;
608 bool success = FALSE;
609 /*
610 if (type & wxBITMAP_DISCARD_COLOURMAP)
611 success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap);
612 else
613 */
614 success = (wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0);
615 if (!success && palette)
616 {
617 delete palette;
618 palette = NULL;
619 }
620 if (palette)
621 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
622 return success;
623 #else
624 return FALSE;
625 #endif
626 }
627
628 bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *pal)
629 {
630 #if USE_IMAGE_LOADING_IN_MSW
631 wxPalette *actualPalette = (wxPalette *)pal;
632 if (!actualPalette && (!M_BITMAPHANDLERDATA->m_bitmapPalette.IsNull()))
633 actualPalette = & (M_BITMAPHANDLERDATA->m_bitmapPalette);
634 return (wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0);
635 #else
636 return FALSE;
637 #endif
638 }
639
640 class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
641 {
642 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
643 public:
644 inline wxXPMFileHandler(void)
645 {
646 m_name = "XPM bitmap file";
647 m_extension = "xpm";
648 m_type = wxBITMAP_TYPE_XPM;
649 };
650
651 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
652 int desiredWidth = -1, int desiredHeight = -1);
653 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
654 };
655 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
656
657 bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
658 int desiredWidth, int desiredHeight)
659 {
660 #if USE_XPM_IN_MSW
661 XImage *ximage;
662 XpmAttributes xpmAttr;
663 HDC dc;
664
665 M_BITMAPHANDLERDATA->m_ok = FALSE;
666 dc = CreateCompatibleDC(NULL);
667 if (dc)
668 {
669 xpmAttr.valuemask = XpmReturnPixels;
670 int errorStatus = XpmReadFileToImage(&dc, WXSTRINGCAST name, &ximage, (XImage **) NULL, &xpmAttr);
671 DeleteDC(dc);
672 if (errorStatus == XpmSuccess)
673 {
674 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap;
675
676 BITMAP bm;
677 GetObject((HBITMAP)M_BITMAPHANDLERDATA->m_hBitmap, sizeof(bm), (LPSTR) & bm);
678
679 M_BITMAPHANDLERDATA->m_width = (bm.bmWidth);
680 M_BITMAPHANDLERDATA->m_height = (bm.bmHeight);
681 M_BITMAPHANDLERDATA->m_depth = (bm.bmPlanes * bm.bmBitsPixel);
682 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
683 XpmFreeAttributes(&xpmAttr);
684 XImageFree(ximage);
685
686 M_BITMAPHANDLERDATA->m_ok = TRUE;
687 return TRUE;
688 }
689 else
690 {
691 M_BITMAPHANDLERDATA->m_ok = FALSE;
692 return FALSE;
693 }
694 }
695 #endif
696
697 return FALSE;
698 }
699
700 bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
701 {
702 #if USE_XPM_IN_MSW
703 HDC dc = NULL;
704
705 Visual *visual = NULL;
706 XImage ximage;
707
708 dc = CreateCompatibleDC(NULL);
709 if (dc)
710 {
711 if (SelectObject(dc, (HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap))
712 { /* for following SetPixel */
713 /* fill the XImage struct 'by hand' */
714 ximage.width = M_BITMAPHANDLERDATA->m_width;
715 ximage.height = M_BITMAPHANDLERDATA->m_height;
716 ximage.depth = M_BITMAPHANDLERDATA->m_depth;
717 ximage.bitmap = (void *)M_BITMAPHANDLERDATA->m_hBitmap;
718 int errorStatus = XpmWriteFileFromImage(&dc, WXSTRINGCAST name,
719 &ximage, (XImage *) NULL, (XpmAttributes *) NULL);
720
721 if (dc)
722 DeleteDC(dc);
723
724 if (errorStatus == XpmSuccess)
725 return TRUE; /* no error */
726 else
727 return FALSE;
728 } else return FALSE;
729 } else return FALSE;
730 #else
731 return FALSE;
732 #endif
733 }
734
735 class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
736 {
737 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
738 public:
739 inline wxXPMDataHandler(void)
740 {
741 m_name = "XPM bitmap data";
742 m_extension = "xpm";
743 m_type = wxBITMAP_TYPE_XPM_DATA;
744 };
745
746 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
747 };
748 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
749
750 bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
751 {
752 #if USE_XPM_IN_MSW
753 XImage *ximage;
754 int ErrorStatus;
755 XpmAttributes xpmAttr;
756 HDC dc;
757
758 M_BITMAPHANDLERDATA->m_ok = FALSE;
759 M_BITMAPHANDLERDATA->m_numColors = 0;
760
761 dc = CreateCompatibleDC(NULL); /* memory DC */
762
763 if (dc)
764 {
765 xpmAttr.valuemask = XpmReturnInfos; /* get infos back */
766 ErrorStatus = XpmCreateImageFromData(&dc, (char **)data,
767 &ximage, (XImage **) NULL, &xpmAttr);
768
769 if (ErrorStatus == XpmSuccess)
770 {
771 /* ximage is malloced and contains bitmap and attributes */
772 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap;
773
774 BITMAP bm;
775 GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(bm), (LPSTR) & bm);
776
777 M_BITMAPHANDLERDATA->m_width = (bm.bmWidth);
778 M_BITMAPHANDLERDATA->m_height = (bm.bmHeight);
779 M_BITMAPHANDLERDATA->m_depth = (bm.bmPlanes * bm.bmBitsPixel);
780 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
781 XpmFreeAttributes(&xpmAttr);
782
783 XImageFree(ximage); // releases the malloc, but does not detroy
784 // the bitmap
785 M_BITMAPHANDLERDATA->m_ok = TRUE;
786 DeleteDC(dc);
787
788 return TRUE;
789 }
790 else
791 {
792 M_BITMAPHANDLERDATA->m_ok = FALSE;
793 // XpmDebugError(ErrorStatus, NULL);
794 DeleteDC(dc);
795 return FALSE;
796 }
797 }
798 #endif
799
800 return FALSE;
801 }
802
803 void wxBitmap::CleanUpHandlers(void)
804 {
805 wxNode *node = sm_handlers.First();
806 while ( node )
807 {
808 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
809 wxNode *next = node->Next();
810 delete handler;
811 delete node;
812 node = next;
813 }
814 }
815
816 void wxBitmap::InitStandardHandlers(void)
817 {
818 AddHandler(new wxBMPResourceHandler);
819 AddHandler(new wxBMPFileHandler);
820 AddHandler(new wxXPMFileHandler);
821 AddHandler(new wxXPMDataHandler);
822 AddHandler(new wxICOResourceHandler);
823 AddHandler(new wxICOFileHandler);
824 }