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