]> git.saurik.com Git - wxWidgets.git/blame - src/msw/bitmap.cpp
many fixes to wxTextCrtl, wxTreeCrtl, wxListBox,
[wxWidgets.git] / src / msw / bitmap.cpp
CommitLineData
2bda0e17
KB
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
1d792928 9// Licence: wxWindows license
2bda0e17
KB
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"
1d792928
VZ
35#include "wx/log.h"
36
2bda0e17
KB
37#include "assert.h"
38
39#if USE_XPM_IN_MSW
40#define FOR_MSW 1
1d792928 41#include "../../contrib/wxxpm/libxpm.34b/lib/xpm34.h"
2bda0e17
KB
42#endif
43
44#include "wx/msw/dib.h"
45
46#if !USE_SHARED_LIBRARIES
47IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
48IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
49#endif
50
51wxBitmapRefData::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
64wxBitmapRefData::~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
83wxList wxBitmap::sm_handlers;
84
85wxBitmap::wxBitmap(void)
86{
87 m_refData = NULL; // new wxBitmapRefData;
88
89 if ( wxTheBitmapList )
90 wxTheBitmapList->AddBitmap(this);
91}
92
93wxBitmap::~wxBitmap(void)
94{
95 if (wxTheBitmapList)
96 wxTheBitmapList->DeleteObject(this);
97}
98
99bool wxBitmap::FreeResource(bool force)
100{
101 if ( !M_BITMAPDATA )
1d792928 102 return FALSE;
2bda0e17
KB
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
debe6624 127wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
2bda0e17
KB
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
debe6624 149wxBitmap::wxBitmap(int w, int h, int d)
2bda0e17
KB
150{
151 (void)Create(w, h, d);
152
153 if ( wxTheBitmapList )
154 wxTheBitmapList->AddBitmap(this);
155}
156
debe6624 157wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
2bda0e17
KB
158{
159 (void) Create(data, type, width, height, depth);
160
161 if ( wxTheBitmapList )
162 wxTheBitmapList->AddBitmap(this);
163}
164
debe6624 165wxBitmap::wxBitmap(const wxString& filename, long type)
2bda0e17
KB
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
175wxBitmap::wxBitmap(const char **data, wxItem *WXUNUSED(anItem))
176{
1d792928 177 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
2bda0e17
KB
178}
179#endif
180
debe6624 181bool wxBitmap::Create(int w, int h, int d)
2bda0e17
KB
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
debe6624 209bool wxBitmap::LoadFile(const wxString& filename, long type)
2bda0e17
KB
210{
211 UnRef();
212
213 m_refData = new wxBitmapRefData;
214
215 wxBitmapHandler *handler = FindHandler(type);
216
1d792928
VZ
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);
2bda0e17
KB
224}
225
debe6624 226bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
2bda0e17
KB
227{
228 UnRef();
229
230 m_refData = new wxBitmapRefData;
231
232 wxBitmapHandler *handler = FindHandler(type);
233
1d792928
VZ
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);
2bda0e17
KB
241}
242
debe6624 243bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
2bda0e17
KB
244{
245 wxBitmapHandler *handler = FindHandler(type);
246
1d792928
VZ
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);
2bda0e17
KB
254}
255
256void wxBitmap::SetWidth(int w)
257{
258 if (!M_BITMAPDATA)
1d792928 259 m_refData = new wxBitmapRefData;
2bda0e17
KB
260
261 M_BITMAPDATA->m_width = w;
262}
263
264void wxBitmap::SetHeight(int h)
265{
266 if (!M_BITMAPDATA)
1d792928 267 m_refData = new wxBitmapRefData;
2bda0e17
KB
268
269 M_BITMAPDATA->m_height = h;
270}
271
272void wxBitmap::SetDepth(int d)
273{
274 if (!M_BITMAPDATA)
1d792928 275 m_refData = new wxBitmapRefData;
2bda0e17
KB
276
277 M_BITMAPDATA->m_depth = d;
278}
279
280void wxBitmap::SetQuality(int q)
281{
282 if (!M_BITMAPDATA)
1d792928 283 m_refData = new wxBitmapRefData;
2bda0e17
KB
284
285 M_BITMAPDATA->m_quality = q;
286}
287
288void wxBitmap::SetOk(bool isOk)
289{
290 if (!M_BITMAPDATA)
1d792928 291 m_refData = new wxBitmapRefData;
2bda0e17
KB
292
293 M_BITMAPDATA->m_ok = isOk;
294}
295
296void wxBitmap::SetPalette(const wxPalette& palette)
297{
298 if (!M_BITMAPDATA)
1d792928 299 m_refData = new wxBitmapRefData;
2bda0e17
KB
300
301 M_BITMAPDATA->m_bitmapPalette = palette ;
302}
303
304void wxBitmap::SetMask(wxMask *mask)
305{
306 if (!M_BITMAPDATA)
1d792928 307 m_refData = new wxBitmapRefData;
2bda0e17
KB
308
309 M_BITMAPDATA->m_bitmapMask = mask ;
310}
311
312void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
313{
314 if (!M_BITMAPDATA)
1d792928 315 m_refData = new wxBitmapRefData;
2bda0e17
KB
316
317 M_BITMAPDATA->m_hBitmap = bmp;
318}
319
320void wxBitmap::AddHandler(wxBitmapHandler *handler)
321{
1d792928 322 sm_handlers.Append(handler);
2bda0e17
KB
323}
324
325void wxBitmap::InsertHandler(wxBitmapHandler *handler)
326{
1d792928 327 sm_handlers.Insert(handler);
2bda0e17
KB
328}
329
330bool wxBitmap::RemoveHandler(const wxString& name)
331{
1d792928
VZ
332 wxBitmapHandler *handler = FindHandler(name);
333 if ( handler )
334 {
335 sm_handlers.DeleteObject(handler);
336 return TRUE;
337 }
338 else
339 return FALSE;
2bda0e17
KB
340}
341
342wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
343{
1d792928
VZ
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;
2bda0e17
KB
353}
354
355wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
356{
1d792928
VZ
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;
2bda0e17
KB
367}
368
369wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
370{
1d792928
VZ
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;
2bda0e17
KB
380}
381
382/*
383 * wxMask
384 */
385
386wxMask::wxMask(void)
387{
388 m_maskBitmap = 0;
389}
390
391// Construct a mask from a bitmap and a colour indicating
392// the transparent area
393wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
394{
395 m_maskBitmap = 0;
1d792928 396 Create(bitmap, colour);
2bda0e17
KB
397}
398
399// Construct a mask from a bitmap and a palette index indicating
400// the transparent area
debe6624 401wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
2bda0e17
KB
402{
403 m_maskBitmap = 0;
1d792928 404 Create(bitmap, paletteIndex);
2bda0e17
KB
405}
406
407// Construct a mask from a mono bitmap (copies the bitmap).
408wxMask::wxMask(const wxBitmap& bitmap)
409{
410 m_maskBitmap = 0;
1d792928 411 Create(bitmap);
2bda0e17
KB
412}
413
414wxMask::~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).
421bool wxMask::Create(const wxBitmap& bitmap)
422{
423 if ( m_maskBitmap )
1d792928
VZ
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;
2bda0e17
KB
447}
448
449// Create a mask from a bitmap and a palette index indicating
450// the transparent area
debe6624 451bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
2bda0e17
KB
452{
453 if ( m_maskBitmap )
1d792928
VZ
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;
2bda0e17
KB
468}
469
470// Create a mask from a bitmap and a colour indicating
471// the transparent area
472bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
473{
474 if ( m_maskBitmap )
1d792928
VZ
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;
2bda0e17
KB
520}
521
522/*
523 * wxBitmapHandler
524 */
525
526IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
527
debe6624 528bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
2bda0e17 529{
1d792928 530 return FALSE;
2bda0e17
KB
531}
532
debe6624 533bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type,
2bda0e17
KB
534 int desiredWidth, int desiredHeight)
535{
1d792928 536 return FALSE;
2bda0e17
KB
537}
538
debe6624 539bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
2bda0e17 540{
1d792928 541 return FALSE;
2bda0e17
KB
542}
543
544/*
545 * Standard handlers
546 */
547
548class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
549{
550 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
551public:
552 inline wxBMPResourceHandler(void)
553 {
1d792928
VZ
554 m_name = "Windows bitmap resource";
555 m_extension = "";
556 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
2bda0e17
KB
557 };
558
debe6624 559 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2bda0e17
KB
560 int desiredWidth, int desiredHeight);
561};
562IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
563
debe6624 564bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2bda0e17
KB
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 }
1d792928
VZ
579
580 // it's probably not found
dabeb021 581 wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name.c_str());
1d792928
VZ
582
583 return FALSE;
2bda0e17
KB
584}
585
586class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
587{
588 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
589public:
590 inline wxBMPFileHandler(void)
591 {
1d792928
VZ
592 m_name = "Windows bitmap file";
593 m_extension = "bmp";
594 m_type = wxBITMAP_TYPE_BMP;
2bda0e17
KB
595 };
596
debe6624 597 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2bda0e17 598 int desiredWidth, int desiredHeight);
debe6624 599 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
2bda0e17
KB
600};
601IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
602
debe6624 603bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2bda0e17
KB
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
1d792928 624 return FALSE;
2bda0e17
KB
625#endif
626}
627
debe6624 628bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *pal)
2bda0e17
KB
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
1d792928 636 return FALSE;
2bda0e17
KB
637#endif
638}
639
640class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
641{
642 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
643public:
644 inline wxXPMFileHandler(void)
645 {
1d792928
VZ
646 m_name = "XPM bitmap file";
647 m_extension = "xpm";
648 m_type = wxBITMAP_TYPE_XPM;
2bda0e17
KB
649 };
650
debe6624 651 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2bda0e17 652 int desiredWidth = -1, int desiredHeight = -1);
debe6624 653 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
2bda0e17
KB
654};
655IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
656
debe6624 657bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2bda0e17
KB
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 {
1d792928 674 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap;
2bda0e17 675
1d792928
VZ
676 BITMAP bm;
677 GetObject((HBITMAP)M_BITMAPHANDLERDATA->m_hBitmap, sizeof(bm), (LPSTR) & bm);
2bda0e17 678
1d792928
VZ
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;
2bda0e17 683 XpmFreeAttributes(&xpmAttr);
1d792928
VZ
684 XImageFree(ximage);
685
686 M_BITMAPHANDLERDATA->m_ok = TRUE;
687 return TRUE;
2bda0e17
KB
688 }
689 else
690 {
691 M_BITMAPHANDLERDATA->m_ok = FALSE;
692 return FALSE;
693 }
694 }
2bda0e17 695#endif
1d792928
VZ
696
697 return FALSE;
2bda0e17
KB
698}
699
debe6624 700bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
2bda0e17
KB
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' */
1d792928
VZ
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);
2bda0e17
KB
720
721 if (dc)
1d792928 722 DeleteDC(dc);
2bda0e17 723
1d792928
VZ
724 if (errorStatus == XpmSuccess)
725 return TRUE; /* no error */
726 else
727 return FALSE;
2bda0e17
KB
728 } else return FALSE;
729 } else return FALSE;
730#else
1d792928 731 return FALSE;
2bda0e17
KB
732#endif
733}
734
735class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
736{
737 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
738public:
739 inline wxXPMDataHandler(void)
740 {
1d792928
VZ
741 m_name = "XPM bitmap data";
742 m_extension = "xpm";
743 m_type = wxBITMAP_TYPE_XPM_DATA;
2bda0e17
KB
744 };
745
debe6624 746 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
2bda0e17
KB
747};
748IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
749
debe6624 750bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth)
2bda0e17
KB
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
1d792928 761 dc = CreateCompatibleDC(NULL); /* memory DC */
2bda0e17
KB
762
763 if (dc)
764 {
1d792928 765 xpmAttr.valuemask = XpmReturnInfos; /* get infos back */
2bda0e17
KB
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
1d792928
VZ
783 XImageFree(ximage); // releases the malloc, but does not detroy
784 // the bitmap
2bda0e17
KB
785 M_BITMAPHANDLERDATA->m_ok = TRUE;
786 DeleteDC(dc);
787
1d792928
VZ
788 return TRUE;
789 }
790 else
2bda0e17
KB
791 {
792 M_BITMAPHANDLERDATA->m_ok = FALSE;
793// XpmDebugError(ErrorStatus, NULL);
794 DeleteDC(dc);
1d792928 795 return FALSE;
2bda0e17
KB
796 }
797 }
2bda0e17 798#endif
1d792928
VZ
799
800 return FALSE;
2bda0e17
KB
801}
802
803void wxBitmap::CleanUpHandlers(void)
804{
1d792928
VZ
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 }
2bda0e17
KB
814}
815
816void wxBitmap::InitStandardHandlers(void)
817{
1d792928
VZ
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}