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