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