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