]> git.saurik.com Git - wxWidgets.git/blame - src/motif/bitmap.cpp
Unicode compilation fixes for BC++ 5
[wxWidgets.git] / src / motif / bitmap.cpp
CommitLineData
4bb6408c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: bitmap.cpp
3// Purpose: wxBitmap
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "bitmap.h"
14#endif
15
16#include "wx/setup.h"
17#include "wx/utils.h"
18#include "wx/palette.h"
19#include "wx/bitmap.h"
20#include "wx/icon.h"
21#include "wx/log.h"
a4294b78 22#include "wx/control.h"
321db4b6 23#include "wx/dcmemory.h"
b75dd496 24#include "wx/image.h"
4bb6408c 25
338dd992
JJ
26#ifdef __VMS__
27#pragma message disable nosimpint
28#endif
f97c9854 29#include <Xm/Xm.h>
338dd992
JJ
30#ifdef __VMS__
31#pragma message enable nosimpint
32#endif
f97c9854
JS
33
34#include "wx/motif/private.h"
35
31528cd3
VZ
36#if wxHAVE_LIB_XPM
37 #include <X11/xpm.h>
f97c9854
JS
38#endif
39
e838cc14
VZ
40IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
41IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
4bb6408c
JS
42
43wxBitmapRefData::wxBitmapRefData()
44{
45 m_ok = FALSE;
46 m_width = 0;
47 m_height = 0;
48 m_depth = 0;
49 m_quality = 0;
50 m_numColors = 0;
51 m_bitmapMask = NULL;
31528cd3 52
16c1f7f3
JS
53 m_pixmap = (WXPixmap) 0;
54 m_display = (WXDisplay*) 0;
31528cd3 55
f97c9854
JS
56 m_freePixmap = TRUE; //TODO: necessary?
57 m_freeColors = (unsigned long*) 0;
58 m_freeColorsCount = 0;
31528cd3 59
f97c9854
JS
60 // These 5 variables are for wxControl
61 m_insensPixmap = (WXPixmap) 0;
62 m_labelPixmap = (WXPixmap) 0;
63 m_armPixmap = (WXPixmap) 0;
64 m_image = (WXImage*) 0;
65 m_insensImage = (WXImage*) 0;
4bb6408c
JS
66}
67
68wxBitmapRefData::~wxBitmapRefData()
69{
f97c9854
JS
70 if (m_labelPixmap)
71 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_labelPixmap);
31528cd3 72
f97c9854
JS
73 if (m_armPixmap)
74 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_armPixmap);
31528cd3 75
f97c9854
JS
76 if (m_insensPixmap)
77 XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) m_display), (Pixmap) m_insensPixmap);
31528cd3 78
f97c9854
JS
79 if (m_image)
80 {
81 XmUninstallImage ((XImage*) m_image);
82 XtFree ((char *) (XImage*) m_image);
83 }
31528cd3 84
f97c9854
JS
85 if (m_insensImage)
86 {
87 XmUninstallImage ((XImage*) m_insensImage);
88 delete[] ((XImage*) m_insensImage)->data;
89 XtFree ((char *) (XImage*) m_insensImage);
90 }
91 if (m_pixmap && m_freePixmap)
92 XFreePixmap ((Display*) m_display, (Pixmap) m_pixmap);
31528cd3 93
f97c9854
JS
94 if (m_freeColors)
95 {
2d120f83
JS
96 int screen = DefaultScreen((Display*) m_display);
97 Colormap cmp = DefaultColormap((Display*) m_display,screen);
98 long llp;
99 for(llp = 0;llp < m_freeColorsCount;llp++)
100 XFreeColors((Display*) m_display, cmp, &m_freeColors[llp], 1, 0L);
101 delete m_freeColors;
f97c9854 102 };
31528cd3 103
4bb6408c
JS
104 if (m_bitmapMask)
105 delete m_bitmapMask;
106 m_bitmapMask = NULL;
107}
108
109wxList wxBitmap::sm_handlers;
110
111wxBitmap::wxBitmap()
112{
113 m_refData = NULL;
31528cd3 114
4bb6408c
JS
115 if ( wxTheBitmapList )
116 wxTheBitmapList->AddBitmap(this);
117}
118
119wxBitmap::~wxBitmap()
120{
121 if (wxTheBitmapList)
122 wxTheBitmapList->DeleteObject(this);
123}
124
f97c9854 125wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
4bb6408c
JS
126{
127 m_refData = new wxBitmapRefData;
31528cd3 128
f97c9854 129 (void) Create((void*) bits, wxBITMAP_TYPE_XBM_DATA, width, height, depth);
31528cd3 130
4bb6408c
JS
131 if ( wxTheBitmapList )
132 wxTheBitmapList->AddBitmap(this);
133}
134
135wxBitmap::wxBitmap(int w, int h, int d)
136{
137 (void)Create(w, h, d);
31528cd3 138
4bb6408c
JS
139 if ( wxTheBitmapList )
140 wxTheBitmapList->AddBitmap(this);
141}
142
143wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
144{
145 (void) Create(data, type, width, height, depth);
31528cd3 146
4bb6408c
JS
147 if ( wxTheBitmapList )
148 wxTheBitmapList->AddBitmap(this);
149}
150
151wxBitmap::wxBitmap(const wxString& filename, long type)
152{
153 LoadFile(filename, (int)type);
31528cd3 154
4bb6408c
JS
155 if ( wxTheBitmapList )
156 wxTheBitmapList->AddBitmap(this);
157}
158
f97c9854
JS
159// Create from XPM data
160static wxControl* sg_Control = NULL;
a4294b78 161wxBitmap::wxBitmap(char **data, wxControl* control)
4bb6408c 162{
f97c9854
JS
163 // Pass the control to the Create function using a global
164 sg_Control = control;
31528cd3 165
4bb6408c 166 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
31528cd3 167
f97c9854 168 sg_Control = (wxControl*) NULL;
4bb6408c 169}
4bb6408c 170
e838cc14
VZ
171bool wxBitmap::CreateFromXpm(const char **bits)
172{
173 wxCHECK_MSG( bits, FALSE, _T("NULL pointer in wxBitmap::CreateFromXpm") );
174
175 return Create(bits, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
176}
177
4bb6408c
JS
178bool wxBitmap::Create(int w, int h, int d)
179{
180 UnRef();
31528cd3 181
4bb6408c 182 m_refData = new wxBitmapRefData;
31528cd3 183
f97c9854 184 if (d < 1)
2d120f83 185 d = wxDisplayDepth();
31528cd3 186
4bb6408c
JS
187 M_BITMAPDATA->m_width = w;
188 M_BITMAPDATA->m_height = h;
189 M_BITMAPDATA->m_depth = d;
f97c9854 190 M_BITMAPDATA->m_freePixmap = TRUE;
31528cd3 191
f97c9854 192 Display *dpy = (Display*) wxGetDisplay();
31528cd3 193
f97c9854 194 M_BITMAPDATA->m_display = dpy; /* MATTHEW: [4] Remember the display */
31528cd3 195
f97c9854 196 M_BITMAPDATA->m_pixmap = (WXPixmap) XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
2d120f83 197 w, h, d);
31528cd3 198
f97c9854 199 M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_pixmap != (WXPixmap) 0) ;
4bb6408c
JS
200 return M_BITMAPDATA->m_ok;
201}
202
203bool wxBitmap::LoadFile(const wxString& filename, long type)
204{
205 UnRef();
31528cd3 206
4bb6408c 207 m_refData = new wxBitmapRefData;
31528cd3 208
4bb6408c 209 wxBitmapHandler *handler = FindHandler(type);
31528cd3 210
4bb6408c 211 if ( handler == NULL ) {
b75dd496
VS
212 wxImage image;
213 if (!image.LoadFile( filename, type )) return FALSE;
214 if (image.Ok())
215 {
216 *this = image.ConvertToBitmap();
217 return TRUE;
218 }
219 else return FALSE;
4bb6408c 220 }
31528cd3 221
4bb6408c
JS
222 return handler->LoadFile(this, filename, type, -1, -1);
223}
224
225bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
226{
227 UnRef();
31528cd3 228
4bb6408c 229 m_refData = new wxBitmapRefData;
31528cd3 230
4bb6408c 231 wxBitmapHandler *handler = FindHandler(type);
31528cd3 232
4bb6408c 233 if ( handler == NULL ) {
7bcb11d3 234 wxLogWarning("no data bitmap handler for type %d defined.", type);
31528cd3 235
4bb6408c
JS
236 return FALSE;
237 }
31528cd3 238
4bb6408c
JS
239 return handler->Create(this, data, type, width, height, depth);
240}
241
242bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
243{
244 wxBitmapHandler *handler = FindHandler(type);
31528cd3 245
b75dd496
VS
246 if ( handler == NULL ) { // try wxImage
247 wxImage image( *this );
248 if (image.Ok()) return image.SaveFile( filename, type );
249 else return FALSE;
2d120f83 250 }
31528cd3 251
2d120f83 252 return handler->SaveFile(this, filename, type, palette);
4bb6408c
JS
253}
254
255void wxBitmap::SetWidth(int w)
256{
257 if (!M_BITMAPDATA)
258 m_refData = new wxBitmapRefData;
31528cd3 259
4bb6408c
JS
260 M_BITMAPDATA->m_width = w;
261}
262
263void wxBitmap::SetHeight(int h)
264{
265 if (!M_BITMAPDATA)
266 m_refData = new wxBitmapRefData;
31528cd3 267
4bb6408c
JS
268 M_BITMAPDATA->m_height = h;
269}
270
271void wxBitmap::SetDepth(int d)
272{
273 if (!M_BITMAPDATA)
274 m_refData = new wxBitmapRefData;
31528cd3 275
4bb6408c
JS
276 M_BITMAPDATA->m_depth = d;
277}
278
279void wxBitmap::SetQuality(int q)
280{
281 if (!M_BITMAPDATA)
282 m_refData = new wxBitmapRefData;
31528cd3 283
4bb6408c
JS
284 M_BITMAPDATA->m_quality = q;
285}
286
287void wxBitmap::SetOk(bool isOk)
288{
289 if (!M_BITMAPDATA)
290 m_refData = new wxBitmapRefData;
31528cd3 291
4bb6408c
JS
292 M_BITMAPDATA->m_ok = isOk;
293}
294
295void wxBitmap::SetPalette(const wxPalette& palette)
296{
297 if (!M_BITMAPDATA)
298 m_refData = new wxBitmapRefData;
31528cd3 299
4bb6408c
JS
300 M_BITMAPDATA->m_bitmapPalette = palette ;
301}
302
303void wxBitmap::SetMask(wxMask *mask)
304{
305 if (!M_BITMAPDATA)
306 m_refData = new wxBitmapRefData;
31528cd3 307
4bb6408c
JS
308 M_BITMAPDATA->m_bitmapMask = mask ;
309}
310
311void wxBitmap::AddHandler(wxBitmapHandler *handler)
312{
313 sm_handlers.Append(handler);
314}
315
316void wxBitmap::InsertHandler(wxBitmapHandler *handler)
317{
318 sm_handlers.Insert(handler);
319}
320
321bool wxBitmap::RemoveHandler(const wxString& name)
322{
323 wxBitmapHandler *handler = FindHandler(name);
324 if ( handler )
325 {
326 sm_handlers.DeleteObject(handler);
327 return TRUE;
328 }
329 else
330 return FALSE;
331}
332
333wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
334{
335 wxNode *node = sm_handlers.First();
336 while ( node )
337 {
338 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
339 if ( handler->GetName() == name )
340 return handler;
341 node = node->Next();
342 }
343 return NULL;
344}
345
346wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
347{
348 wxNode *node = sm_handlers.First();
349 while ( node )
350 {
351 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
352 if ( handler->GetExtension() == extension &&
2d120f83 353 (bitmapType == -1 || handler->GetType() == bitmapType) )
4bb6408c
JS
354 return handler;
355 node = node->Next();
356 }
357 return NULL;
358}
359
360wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
361{
362 wxNode *node = sm_handlers.First();
363 while ( node )
364 {
365 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
366 if (handler->GetType() == bitmapType)
367 return handler;
368 node = node->Next();
369 }
370 return NULL;
371}
372
373/*
2d120f83
JS
374* wxMask
375*/
4bb6408c
JS
376
377wxMask::wxMask()
378{
16c1f7f3 379 m_pixmap = (WXPixmap) 0;
4bb6408c
JS
380}
381
382// Construct a mask from a bitmap and a colour indicating
383// the transparent area
384wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
385{
16c1f7f3 386 m_pixmap = (WXPixmap) 0;
31528cd3 387
4bb6408c
JS
388 Create(bitmap, colour);
389}
390
391// Construct a mask from a bitmap and a palette index indicating
392// the transparent area
393wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
394{
16c1f7f3 395 m_pixmap = (WXPixmap) 0;
31528cd3 396
4bb6408c
JS
397 Create(bitmap, paletteIndex);
398}
399
400// Construct a mask from a mono bitmap (copies the bitmap).
401wxMask::wxMask(const wxBitmap& bitmap)
402{
16c1f7f3 403 m_pixmap = (WXPixmap) 0;
31528cd3 404
4bb6408c
JS
405 Create(bitmap);
406}
407
408wxMask::~wxMask()
409{
f97c9854
JS
410 // TODO: this may be the wrong display
411 if ( m_pixmap )
412 XFreePixmap ((Display*) wxGetDisplay(), (Pixmap) m_pixmap);
4bb6408c
JS
413}
414
415// Create a mask from a mono bitmap (copies the bitmap).
f9e02ac7 416bool wxMask::Create(const wxBitmap& WXUNUSED(bitmap))
4bb6408c 417{
2d120f83 418 // TODO
4bb6408c
JS
419 return FALSE;
420}
421
422// Create a mask from a bitmap and a palette index indicating
423// the transparent area
f9e02ac7 424bool wxMask::Create(const wxBitmap& WXUNUSED(bitmap), int WXUNUSED(paletteIndex))
4bb6408c 425{
2d120f83 426 // TODO
4bb6408c
JS
427 return FALSE;
428}
429
430// Create a mask from a bitmap and a colour indicating
431// the transparent area
f9e02ac7 432bool wxMask::Create(const wxBitmap& WXUNUSED(bitmap), const wxColour& WXUNUSED(colour))
4bb6408c 433{
2d120f83 434 // TODO
4bb6408c
JS
435 return FALSE;
436}
437
438/*
2d120f83
JS
439* wxBitmapHandler
440*/
4bb6408c
JS
441
442IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
443
31528cd3 444bool wxBitmapHandler::Create(wxBitmap *WXUNUSED(bitmap), void *WXUNUSED(data), long WXUNUSED(type),
2d120f83 445 int WXUNUSED(width), int WXUNUSED(height), int WXUNUSED(depth))
4bb6408c
JS
446{
447 return FALSE;
448}
449
f9e02ac7 450bool wxBitmapHandler::LoadFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), long WXUNUSED(type),
2d120f83 451 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
4bb6408c
JS
452{
453 return FALSE;
454}
455
31528cd3 456bool wxBitmapHandler::SaveFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), int WXUNUSED(type),
2d120f83 457 const wxPalette *WXUNUSED(palette))
4bb6408c
JS
458{
459 return FALSE;
460}
461
462/*
2d120f83
JS
463* Standard handlers
464*/
4bb6408c 465
f97c9854 466class WXDLLEXPORT wxXBMFileHandler: public wxBitmapHandler
4bb6408c 467{
f97c9854 468 DECLARE_DYNAMIC_CLASS(wxXBMFileHandler)
4bb6408c 469public:
f97c9854 470 inline wxXBMFileHandler()
4bb6408c 471 {
f97c9854
JS
472 m_name = "XBM file";
473 m_extension = "xbm";
474 m_type = wxBITMAP_TYPE_XBM;
4bb6408c 475 };
31528cd3 476
4bb6408c 477 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2d120f83 478 int desiredWidth, int desiredHeight);
4bb6408c 479};
f97c9854
JS
480IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler, wxBitmapHandler)
481
f9e02ac7 482bool wxXBMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
2d120f83 483 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
f97c9854
JS
484{
485 M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
31528cd3 486
f97c9854
JS
487 int hotX, hotY;
488 unsigned int w, h;
489 Pixmap pixmap;
31528cd3 490
f97c9854
JS
491 Display *dpy = (Display*) wxGetDisplay();
492 M_BITMAPDATA->m_display = (WXDisplay*) dpy;
31528cd3 493
f97c9854 494 int value = XReadBitmapFile (dpy, RootWindow (dpy, DefaultScreen (dpy)),
2d120f83 495 (char*) (const char*) name, &w, &h, &pixmap, &hotX, &hotY);
f97c9854
JS
496 M_BITMAPHANDLERDATA->m_width = w;
497 M_BITMAPHANDLERDATA->m_height = h;
498 M_BITMAPHANDLERDATA->m_depth = 1;
499 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
31528cd3 500
f97c9854
JS
501 if ((value == BitmapFileInvalid) ||
502 (value == BitmapOpenFailed) ||
503 (value == BitmapNoMemory))
504 {
505 M_BITMAPHANDLERDATA->m_ok = FALSE;
506 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) 0;
507 }
508 else
509 M_BITMAPHANDLERDATA->m_ok = TRUE;
31528cd3 510
f97c9854
JS
511 return M_BITMAPHANDLERDATA->m_ok ;
512}
513
514class WXDLLEXPORT wxXBMDataHandler: public wxBitmapHandler
515{
516 DECLARE_DYNAMIC_CLASS(wxXBMDataHandler)
517public:
518 inline wxXBMDataHandler()
519 {
520 m_name = "XBM data";
521 m_extension = "xbm";
522 m_type = wxBITMAP_TYPE_XBM_DATA;
523 };
31528cd3 524
f97c9854
JS
525 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
526};
527IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler, wxBitmapHandler)
528
31528cd3 529bool wxXBMDataHandler::Create( wxBitmap *bitmap, void *data, long WXUNUSED(flags),
2d120f83 530 int width, int height, int WXUNUSED(depth))
f97c9854
JS
531{
532 M_BITMAPHANDLERDATA->m_width = width;
533 M_BITMAPHANDLERDATA->m_height = height;
534 M_BITMAPHANDLERDATA->m_depth = 1;
535 M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
31528cd3 536
f97c9854
JS
537 Display *dpy = (Display*) wxGetDisplay();
538 M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
31528cd3 539
f97c9854
JS
540 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) XCreateBitmapFromData (dpy, RootWindow (dpy, DefaultScreen (dpy)), (char*) data, width, height);
541 M_BITMAPHANDLERDATA->m_ok = (M_BITMAPHANDLERDATA->m_pixmap != (WXPixmap) 0) ;
31528cd3 542
f97c9854
JS
543 // code for wxControl. TODO: can we avoid doing this until we need it?
544 // E.g. have CreateButtonPixmaps which is called on demand.
545 XImage* image = (XImage *) XtMalloc (sizeof (XImage));
546 image->width = width;
547 image->height = height;
548 image->data = (char*) data;
549 image->depth = 1;
550 image->xoffset = 0;
551 image->format = XYBitmap;
552 image->byte_order = LSBFirst;
553 image->bitmap_unit = 8;
554 image->bitmap_bit_order = LSBFirst;
555 image->bitmap_pad = 8;
556 image->bytes_per_line = (width + 7) >> 3;
31528cd3 557
f97c9854
JS
558 char tmp[128];
559 sprintf (tmp, "Im%x", (unsigned int) image);
560 XmInstallImage (image, tmp);
31528cd3 561
f97c9854 562 // Build our manually stipped pixmap.
31528cd3 563
f97c9854
JS
564 int bpl = (width + 7) / 8;
565 char *data1 = new char[height * bpl];
566 char* bits = (char*) data;
567 int i;
568 for (i = 0; i < height; i++)
569 {
570 int mask = i % 2 ? 0x55 : 0xaa;
571 int j;
572 for (j = 0; j < bpl; j++)
573 data1[i * bpl + j] = bits[i * bpl + j] & mask;
574 }
575 XImage* insensImage = (XImage *) XtMalloc (sizeof (XImage));
576 insensImage->width = width;
577 insensImage->height = height;
578 insensImage->data = data1;
579 insensImage->depth = 1;
580 insensImage->xoffset = 0;
581 insensImage->format = XYBitmap;
582 insensImage->byte_order = LSBFirst;
583 insensImage->bitmap_unit = 8;
584 insensImage->bitmap_bit_order = LSBFirst;
585 insensImage->bitmap_pad = 8;
586 insensImage->bytes_per_line = bpl;
31528cd3 587
f97c9854
JS
588 sprintf (tmp, "Not%x", (unsigned int)insensImage);
589 XmInstallImage (insensImage, tmp);
31528cd3 590
f97c9854
JS
591 M_BITMAPHANDLERDATA->m_image = (WXImage*) image;
592 M_BITMAPHANDLERDATA->m_insensImage = (WXImage*) insensImage;
31528cd3 593
f97c9854
JS
594 return TRUE;
595}
596
31528cd3 597#if wxHAVE_LIB_XPM
f97c9854
JS
598class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler
599{
600 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler)
601public:
602 inline wxXPMFileHandler()
603 {
604 m_name = "XPM file";
605 m_extension = "xpm";
606 m_type = wxBITMAP_TYPE_XPM;
607 };
31528cd3 608
f97c9854 609 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
2d120f83 610 int desiredWidth, int desiredHeight);
f97c9854
JS
611 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
612};
613
614IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler)
615
f9e02ac7 616bool wxXPMFileHandler::LoadFile( wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
2d120f83 617 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight) )
f97c9854 618{
a4294b78 619 Display *dpy = (Display*) wxGetDisplay();
f97c9854 620 M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
31528cd3 621
f97c9854
JS
622 XpmAttributes xpmAttr;
623 Pixmap pixmap;
624 Pixmap mask = 0;
31528cd3 625
f97c9854
JS
626 M_BITMAPHANDLERDATA->m_ok = FALSE;
627 xpmAttr.valuemask = XpmReturnInfos | XpmCloseness;
628 xpmAttr.closeness = 40000;
629 int errorStatus = XpmReadFileToPixmap(dpy,
630 RootWindow(dpy, DefaultScreen(dpy)), (char*) (const char*) name,
631 &pixmap, &mask, &xpmAttr);
31528cd3 632
f97c9854
JS
633 if (errorStatus == XpmSuccess)
634 {
635 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
636 if ( mask )
637 {
638 M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
639 M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
640 }
31528cd3 641
0d57be45
JS
642 unsigned int depthRet;
643 int xRet, yRet;
644 unsigned int widthRet, heightRet, borderWidthRet;
645 Window rootWindowRet;
646 XGetGeometry(dpy, pixmap, &rootWindowRet, &xRet, &yRet,
647 &widthRet, &heightRet, &borderWidthRet, &depthRet);
31528cd3 648
f97c9854
JS
649 M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
650 M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
31528cd3 651
2d120f83 652 /*
f97c9854
JS
653 if ( xpmAttr.npixels > 2 )
654 {
2d120f83 655 M_BITMAPHANDLERDATA->m_depth = 8; // TODO: next time not just a guess :-) ...
f97c9854
JS
656 } else
657 {
2d120f83 658 M_BITMAPHANDLERDATA->m_depth = 1; // mono
f97c9854 659 }
2d120f83 660 */
31528cd3 661
0d57be45 662 M_BITMAPHANDLERDATA->m_depth = depthRet;
31528cd3 663
2d120f83 664 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
31528cd3 665
2d120f83 666 XpmFreeAttributes(&xpmAttr);
31528cd3 667
f97c9854 668 M_BITMAPHANDLERDATA->m_ok = TRUE;
a4294b78 669 return TRUE;
f97c9854
JS
670 } else
671 {
2d120f83 672 // XpmDebugError(errorStatus, name);
f97c9854
JS
673 M_BITMAPHANDLERDATA->m_ok = FALSE;
674 return FALSE;
675 }
676}
677
31528cd3 678bool wxXPMFileHandler::SaveFile( wxBitmap *bitmap, const wxString& name, int WXUNUSED(type),
2d120f83 679 const wxPalette *WXUNUSED(palette))
f97c9854
JS
680{
681 if (M_BITMAPHANDLERDATA->m_ok && M_BITMAPHANDLERDATA->m_pixmap)
682 {
683 Display *dpy = (Display*) M_BITMAPHANDLERDATA->m_display;
684 int errorStatus = XpmWriteFileFromPixmap(dpy, (char*) (const char*) name,
2d120f83
JS
685 (Pixmap) M_BITMAPHANDLERDATA->m_pixmap,
686 (M_BITMAPHANDLERDATA->m_bitmapMask ? (Pixmap) M_BITMAPHANDLERDATA->m_bitmapMask->GetPixmap() : (Pixmap) 0),
687 (XpmAttributes *) NULL);
f97c9854 688 if (errorStatus == XpmSuccess)
2d120f83 689 return TRUE;
f97c9854 690 else
2d120f83 691 return FALSE;
f97c9854
JS
692 }
693 else
694 return FALSE;
695}
696
697class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
698{
699 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
700public:
a4294b78 701 inline wxXPMDataHandler()
f97c9854
JS
702 {
703 m_name = "XPM data";
704 m_extension = "xpm";
705 m_type = wxBITMAP_TYPE_XPM_DATA;
706 };
31528cd3 707
f97c9854
JS
708 virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1);
709};
710IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
711
31528cd3 712bool wxXPMDataHandler::Create( wxBitmap *bitmap, void *data, long WXUNUSED(flags),
2d120f83 713 int width, int height, int WXUNUSED(depth))
f97c9854
JS
714{
715 M_BITMAPHANDLERDATA->m_width = width;
716 M_BITMAPHANDLERDATA->m_height = height;
717 M_BITMAPHANDLERDATA->m_depth = 1;
718 M_BITMAPHANDLERDATA->m_freePixmap = TRUE;
31528cd3 719
a4294b78 720 Display *dpy = (Display*) wxGetDisplay();
f97c9854 721 M_BITMAPHANDLERDATA->m_display = (WXDisplay*) dpy;
31528cd3 722
f97c9854 723 XpmAttributes xpmAttr;
31528cd3 724
f97c9854 725 xpmAttr.valuemask = XpmReturnInfos; /* nothing yet, but get infos back */
31528cd3 726
f97c9854
JS
727 XpmColorSymbol symbolicColors[4];
728 if (sg_Control && sg_Control->GetMainWidget())
729 {
730 symbolicColors[0].name = "foreground";
731 symbolicColors[0].value = NULL;
732 symbolicColors[1].name = "background";
733 symbolicColors[1].value = NULL;
734 XtVaGetValues((Widget) sg_Control->GetMainWidget(),
735 XmNforeground, &symbolicColors[0].pixel,
736 XmNbackground, &symbolicColors[1].pixel,NULL);
737 xpmAttr.numsymbols = 2;
738 xpmAttr.colorsymbols = symbolicColors;
739 xpmAttr.valuemask |= XpmColorSymbols; // add flag
740 }
31528cd3 741
f97c9854
JS
742 Pixmap pixmap;
743 Pixmap mask = 0;
744 int ErrorStatus = XpmCreatePixmapFromData(dpy, RootWindow(dpy, DefaultScreen(dpy)),
2d120f83 745 (char**) data, &pixmap, &mask, &xpmAttr);
f97c9854
JS
746 if (ErrorStatus == XpmSuccess)
747 {
748 // Set attributes
749 M_BITMAPHANDLERDATA->m_width = xpmAttr.width;
750 M_BITMAPHANDLERDATA->m_height = xpmAttr.height;
31528cd3 751
0d57be45
JS
752 unsigned int depthRet;
753 int xRet, yRet;
754 unsigned int widthRet, heightRet, borderWidthRet;
755 Window rootWindowRet;
756 XGetGeometry(dpy, pixmap, &rootWindowRet, &xRet, &yRet,
757 &widthRet, &heightRet, &borderWidthRet, &depthRet);
31528cd3 758
2d120f83
JS
759 /*
760 if ( xpmAttr.npixels > 2 )
761 {
f97c9854 762 M_BITMAPHANDLERDATA->m_depth = 8; // next time not just a guess :-) ...
2d120f83
JS
763 } else
764 {
f97c9854 765 M_BITMAPHANDLERDATA->m_depth = 1; // mono
2d120f83
JS
766 }
767 */
31528cd3 768
0d57be45 769 M_BITMAPHANDLERDATA->m_depth = depthRet;
31528cd3 770
f97c9854
JS
771 M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels;
772 XpmFreeAttributes(&xpmAttr);
773 M_BITMAPHANDLERDATA->m_ok = TRUE;
774 M_BITMAPHANDLERDATA->m_pixmap = (WXPixmap) pixmap;
775 if ( mask )
776 {
777 M_BITMAPHANDLERDATA->m_bitmapMask = new wxMask;
778 M_BITMAPHANDLERDATA->m_bitmapMask->SetPixmap((WXPixmap) mask);
779 }
780 }
781 else
782 {
2d120f83 783 // XpmDebugError(ErrorStatus, NULL);
f97c9854
JS
784 M_BITMAPHANDLERDATA->m_ok = FALSE;
785 }
786 return M_BITMAPHANDLERDATA->m_ok ;
787}
788
31528cd3 789#endif // wxHAVE_LIB_XPM
4bb6408c
JS
790
791void wxBitmap::CleanUpHandlers()
792{
793 wxNode *node = sm_handlers.First();
794 while ( node )
795 {
796 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
797 wxNode *next = node->Next();
798 delete handler;
799 delete node;
800 node = next;
801 }
802}
803
804void wxBitmap::InitStandardHandlers()
805{
f97c9854
JS
806 // Initialize all standard bitmap or derived class handlers here.
807 AddHandler(new wxXBMFileHandler);
808 AddHandler(new wxXBMDataHandler);
31528cd3
VZ
809
810 // XPM is considered standard for Motif, although it can be omitted if
811 // libXpm is not installed
812#if wxHAVE_LIB_XPM
4bb6408c
JS
813 AddHandler(new wxXPMFileHandler);
814 AddHandler(new wxXPMDataHandler);
31528cd3 815#endif // wxHAVE_LIB_XPM
f97c9854
JS
816}
817
818WXPixmap wxBitmap::GetLabelPixmap (WXWidget w)
819{
2d120f83
JS
820 if (M_BITMAPDATA->m_image == (WXPixmap) 0)
821 return M_BITMAPDATA->m_pixmap;
31528cd3 822
2d120f83 823 Display *dpy = (Display*) M_BITMAPDATA->m_display;
31528cd3 824
f97c9854 825#ifdef FOO
2d120f83
JS
826 /*
827 If we do:
828 if (labelPixmap) return labelPixmap;
829 things can be wrong, because colors can have been changed.
31528cd3 830
2d120f83
JS
831 If we do:
832 if (labelPixmap)
833 XmDestroyPixmap(DefaultScreenOfDisplay(dpy),labelPixmap) ;
834 we got BadDrawable if the pixmap is referenced by multiples widgets
31528cd3 835
2d120f83 836 this is a catch22!!
31528cd3 837
e838cc14
VZ
838 So, before doing thing really clean, I just do nothing; if the pixmap is
839 referenced by many widgets, Motif performs caching functions.
840 And if pixmap is referenced with multiples colors, we just have some
841 memory leaks... I hope we can deal with them...
2d120f83
JS
842 */
843 // Must be destroyed, because colours can have been changed!
844 if (M_BITMAPDATA->m_labelPixmap)
845 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), M_BITMAPDATA->m_labelPixmap);
f97c9854 846#endif
31528cd3 847
2d120f83
JS
848 char tmp[128];
849 sprintf (tmp, "Im%x", (unsigned int) M_BITMAPDATA->m_image);
31528cd3 850
2d120f83
JS
851 Pixel fg, bg;
852 Widget widget = (Widget) w;
31528cd3 853
2d120f83
JS
854 while (XmIsGadget ( widget ))
855 widget = XtParent (widget);
856 XtVaGetValues (widget, XmNbackground, &bg, XmNforeground, &fg, NULL);
31528cd3 857
2d120f83 858 M_BITMAPDATA->m_labelPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
31528cd3 859
2d120f83 860 return M_BITMAPDATA->m_labelPixmap;
f97c9854
JS
861}
862
863WXPixmap wxBitmap::GetArmPixmap (WXWidget w)
864{
2d120f83
JS
865 if (M_BITMAPDATA->m_image == (WXPixmap) 0)
866 return M_BITMAPDATA->m_pixmap;
31528cd3 867
2d120f83 868 Display *dpy = (Display*) M_BITMAPDATA->m_display;
f97c9854 869#ifdef FOO
e838cc14
VZ
870 // See GetLabelPixmap () comment
871
872 // Must be destroyed, because colours can have been changed!
873 if (M_BITMAPDATA->m_armPixmap)
874 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), M_BITMAPDATA->m_armPixmap);
f97c9854 875#endif
31528cd3 876
e838cc14
VZ
877 char tmp[128];
878 sprintf (tmp, "Im%x", (unsigned int) M_BITMAPDATA->m_image);
31528cd3 879
e838cc14
VZ
880 Pixel fg, bg;
881 Widget widget = (Widget) w;
31528cd3 882
e838cc14
VZ
883 XtVaGetValues (widget, XmNarmColor, &bg, NULL);
884 while (XmIsGadget (widget))
885 widget = XtParent (widget);
886 XtVaGetValues (widget, XmNforeground, &fg, NULL);
31528cd3 887
e838cc14 888 M_BITMAPDATA->m_armPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
31528cd3 889
e838cc14 890 return M_BITMAPDATA->m_armPixmap;
f97c9854
JS
891}
892
893WXPixmap wxBitmap::GetInsensPixmap (WXWidget w)
894{
2d120f83 895 Display *dpy = (Display*) M_BITMAPDATA->m_display;
31528cd3 896
0d57be45 897 if (M_BITMAPDATA->m_insensPixmap)
2d120f83 898 return M_BITMAPDATA->m_insensPixmap;
31528cd3 899
2d120f83
JS
900 if (!w)
901 {
902 M_BITMAPDATA->m_insensPixmap = (WXPixmap) XCreateInsensitivePixmap(dpy, (Pixmap) M_BITMAPDATA->m_pixmap);
903 if (M_BITMAPDATA->m_insensPixmap)
904 return M_BITMAPDATA->m_insensPixmap;
905 else
906 return M_BITMAPDATA->m_pixmap;
907 }
31528cd3 908
2d120f83
JS
909 if (M_BITMAPDATA->m_insensImage == (WXPixmap) 0)
910 return M_BITMAPDATA->m_pixmap;
31528cd3 911
f97c9854 912#ifdef FOO
2d120f83
JS
913 See GetLabelPixmap () comment
914 // Must be destroyed, because colours can have been changed!
915 if (M_BITMAPDATA->m_insensPixmap)
916 XmDestroyPixmap (DefaultScreenOfDisplay (dpy), (Pixmap) M_BITMAPDATA->m_insensPixmap);
f97c9854 917#endif
31528cd3 918
e838cc14
VZ
919 char tmp[128];
920 sprintf (tmp, "Not%x", (unsigned int) M_BITMAPDATA->m_insensImage);
31528cd3 921
e838cc14
VZ
922 Pixel fg, bg;
923 Widget widget = (Widget) w;
31528cd3 924
e838cc14
VZ
925 while (XmIsGadget (widget))
926 widget = XtParent (widget);
927 XtVaGetValues (widget, XmNbackground, &bg, XmNforeground, &fg, NULL);
31528cd3 928
e838cc14 929 M_BITMAPDATA->m_insensPixmap = (WXPixmap) XmGetPixmap (DefaultScreenOfDisplay (dpy), tmp, fg, bg);
31528cd3 930
e838cc14 931 return M_BITMAPDATA->m_insensPixmap;
f97c9854
JS
932}
933
934// We may need this sometime...
935
936/****************************************************************************
937
2d120f83
JS
938 NAME
939 XCreateInsensitivePixmap - create a grayed-out copy of a pixmap
31528cd3 940
e838cc14
VZ
941 SYNOPSIS
942 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
31528cd3 943
e838cc14
VZ
944 DESCRIPTION
945 This function creates a grayed-out copy of the argument pixmap, suitable
946 for use as a XmLabel's XmNlabelInsensitivePixmap resource.
31528cd3 947
e838cc14
VZ
948 RETURN VALUES
949 The return value is the new Pixmap id or zero on error. Errors include
950 a NULL display argument or an invalid Pixmap argument.
31528cd3 951
e838cc14
VZ
952 ERRORS
953 If one of the XLib functions fail, it will produce a X error. The
954 default X error handler prints a diagnostic and calls exit().
31528cd3 955
e838cc14
VZ
956 SEE ALSO
957 XCopyArea(3), XCreateBitmapFromData(3), XCreateGC(3), XCreatePixmap(3),
958 XFillRectangle(3), exit(2)
31528cd3 959
e838cc14
VZ
960 AUTHOR
961 John R Veregge - john@puente.jpl.nasa.gov
962 Advanced Engineering and Prototyping Group (AEG)
963 Information Systems Technology Section (395)
964 Jet Propulsion Lab - Calif Institute of Technology
31528cd3 965
f97c9854
JS
966*****************************************************************************/
967
968Pixmap
969XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
970
971{
e838cc14
VZ
972 static char stipple_data[] =
973 {
974 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
f97c9854
JS
975 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
976 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
977 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA
e838cc14 978 };
f97c9854
JS
979 GC gc;
980 Pixmap ipixmap, stipple;
981 unsigned width, height, depth;
31528cd3 982
f97c9854
JS
983 Window window; /* These return values */
984 unsigned border; /* from XGetGeometry() */
985 int x, y; /* are not needed. */
31528cd3 986
f97c9854 987 ipixmap = 0;
31528cd3 988
f97c9854 989 if ( NULL == display || 0 == pixmap )
2d120f83 990 return ipixmap;
31528cd3 991
f97c9854 992 if ( 0 == XGetGeometry( display, pixmap, &window, &x, &y,
e838cc14
VZ
993 &width, &height, &border, &depth )
994 )
2d120f83 995 return ipixmap; /* BadDrawable: probably an invalid pixmap */
31528cd3 996
e838cc14
VZ
997 /* Get the stipple pixmap to be used to 'gray-out' the argument pixmap.
998 */
f97c9854
JS
999 stipple = XCreateBitmapFromData( display, pixmap, stipple_data, 16, 16 );
1000 if ( 0 != stipple )
1001 {
2d120f83
JS
1002 gc = XCreateGC( display, pixmap, (XtGCMask)0, (XGCValues*)NULL );
1003 if ( NULL != gc )
f97c9854 1004 {
e838cc14
VZ
1005 /* Create an identical copy of the argument pixmap.
1006 */
2d120f83
JS
1007 ipixmap = XCreatePixmap( display, pixmap, width, height, depth );
1008 if ( 0 != ipixmap )
1009 {
e838cc14
VZ
1010 /* Copy the argument pixmap into the new pixmap.
1011 */
2d120f83 1012 XCopyArea( display, pixmap, ipixmap,
e838cc14 1013 gc, 0, 0, width, height, 0, 0 );
31528cd3 1014
e838cc14
VZ
1015 /* Refill the new pixmap using the stipple algorithm/pixmap.
1016 */
2d120f83
JS
1017 XSetStipple( display, gc, stipple );
1018 XSetFillStyle( display, gc, FillStippled );
1019 XFillRectangle( display, ipixmap, gc, 0, 0, width, height );
1020 }
1021 XFreeGC( display, gc );
f97c9854 1022 }
2d120f83 1023 XFreePixmap( display, stipple );
f97c9854
JS
1024 }
1025 return ipixmap;
4bb6408c 1026}
f97c9854 1027
321db4b6
JS
1028// Creates a bitmap with transparent areas drawn in
1029// the given colour.
d166a4f8 1030wxBitmap wxCreateMaskedBitmap(const wxBitmap& bitmap, wxColour& colour)
321db4b6
JS
1031{
1032 wxBitmap newBitmap(bitmap.GetWidth(),
2d120f83
JS
1033 bitmap.GetHeight(),
1034 bitmap.GetDepth());
321db4b6
JS
1035 wxMemoryDC destDC;
1036 wxMemoryDC srcDC;
1037 srcDC.SelectObject(bitmap);
1038 destDC.SelectObject(newBitmap);
31528cd3 1039
321db4b6
JS
1040 wxBrush brush(colour, wxSOLID);
1041 destDC.SetOptimization(FALSE);
1042 destDC.SetBackground(brush);
1043 destDC.Clear();
1044 destDC.Blit(0, 0, bitmap.GetWidth(), bitmap.GetHeight(), & srcDC, 0, 0, wxCOPY, TRUE);
31528cd3 1045
321db4b6
JS
1046 return newBitmap;
1047}