1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bitmap.h"
18 #include "wx/palette.h"
19 #include "wx/bitmap.h"
22 #include "wx/control.h"
23 #include "wx/dcmemory.h"
27 #include "wx/motif/private.h"
33 #if !USE_SHARED_LIBRARIES
34 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
35 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
38 wxBitmapRefData::wxBitmapRefData()
48 m_pixmap
= (WXPixmap
) 0;
49 m_display
= (WXDisplay
*) 0;
51 m_freePixmap
= TRUE
; //TODO: necessary?
52 m_freeColors
= (unsigned long*) 0;
53 m_freeColorsCount
= 0;
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;
63 wxBitmapRefData::~wxBitmapRefData()
66 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_labelPixmap
);
69 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_armPixmap
);
72 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_insensPixmap
);
76 XmUninstallImage ((XImage
*) m_image
);
77 XtFree ((char *) (XImage
*) m_image
);
82 XmUninstallImage ((XImage
*) m_insensImage
);
83 delete[] ((XImage
*) m_insensImage
)->data
;
84 XtFree ((char *) (XImage
*) m_insensImage
);
86 if (m_pixmap
&& m_freePixmap
)
87 XFreePixmap ((Display
*) m_display
, (Pixmap
) m_pixmap
);
91 int screen
= DefaultScreen((Display
*) m_display
);
92 Colormap cmp
= DefaultColormap((Display
*) m_display
,screen
);
94 for(llp
= 0;llp
< m_freeColorsCount
;llp
++)
95 XFreeColors((Display
*) m_display
, cmp
, &m_freeColors
[llp
], 1, 0L);
104 wxList
wxBitmap::sm_handlers
;
110 if ( wxTheBitmapList
)
111 wxTheBitmapList
->AddBitmap(this);
114 wxBitmap::~wxBitmap()
117 wxTheBitmapList
->DeleteObject(this);
120 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
)
122 m_refData
= new wxBitmapRefData
;
124 (void) Create((void*) bits
, wxBITMAP_TYPE_XBM_DATA
, width
, height
, depth
);
126 if ( wxTheBitmapList
)
127 wxTheBitmapList
->AddBitmap(this);
130 wxBitmap::wxBitmap(int w
, int h
, int d
)
132 (void)Create(w
, h
, d
);
134 if ( wxTheBitmapList
)
135 wxTheBitmapList
->AddBitmap(this);
138 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
)
140 (void) Create(data
, type
, width
, height
, depth
);
142 if ( wxTheBitmapList
)
143 wxTheBitmapList
->AddBitmap(this);
146 wxBitmap::wxBitmap(const wxString
& filename
, long type
)
148 LoadFile(filename
, (int)type
);
150 if ( wxTheBitmapList
)
151 wxTheBitmapList
->AddBitmap(this);
154 // Create from XPM data
155 static wxControl
* sg_Control
= NULL
;
156 wxBitmap::wxBitmap(char **data
, wxControl
* control
)
158 // Pass the control to the Create function using a global
159 sg_Control
= control
;
161 (void) Create((void *)data
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
163 sg_Control
= (wxControl
*) NULL
;
166 bool wxBitmap::Create(int w
, int h
, int d
)
170 m_refData
= new wxBitmapRefData
;
173 d
= wxDisplayDepth();
175 M_BITMAPDATA
->m_width
= w
;
176 M_BITMAPDATA
->m_height
= h
;
177 M_BITMAPDATA
->m_depth
= d
;
178 M_BITMAPDATA
->m_freePixmap
= TRUE
;
180 Display
*dpy
= (Display
*) wxGetDisplay();
182 M_BITMAPDATA
->m_display
= dpy
; /* MATTHEW: [4] Remember the display */
184 M_BITMAPDATA
->m_pixmap
= (WXPixmap
) XCreatePixmap (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)),
187 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_pixmap
!= (WXPixmap
) 0) ;
188 return M_BITMAPDATA
->m_ok
;
191 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
195 m_refData
= new wxBitmapRefData
;
197 wxBitmapHandler
*handler
= FindHandler(type
);
199 if ( handler
== NULL
) {
200 wxLogWarning("%s: no bitmap handler for type %d defined.", (const char*) filename
, type
);
205 return handler
->LoadFile(this, filename
, type
, -1, -1);
208 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
)
212 m_refData
= new wxBitmapRefData
;
214 wxBitmapHandler
*handler
= FindHandler(type
);
216 if ( handler
== NULL
) {
217 wxLogWarning("no data bitmap handler for type %d defined.", type
);
222 return handler
->Create(this, data
, type
, width
, height
, depth
);
225 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette
*palette
)
227 wxBitmapHandler
*handler
= FindHandler(type
);
229 if ( handler
== NULL
) {
230 wxLogWarning("no bitmap handler for type %d defined.", type
);
235 return handler
->SaveFile(this, filename
, type
, palette
);
238 void wxBitmap::SetWidth(int w
)
241 m_refData
= new wxBitmapRefData
;
243 M_BITMAPDATA
->m_width
= w
;
246 void wxBitmap::SetHeight(int h
)
249 m_refData
= new wxBitmapRefData
;
251 M_BITMAPDATA
->m_height
= h
;
254 void wxBitmap::SetDepth(int d
)
257 m_refData
= new wxBitmapRefData
;
259 M_BITMAPDATA
->m_depth
= d
;
262 void wxBitmap::SetQuality(int q
)
265 m_refData
= new wxBitmapRefData
;
267 M_BITMAPDATA
->m_quality
= q
;
270 void wxBitmap::SetOk(bool isOk
)
273 m_refData
= new wxBitmapRefData
;
275 M_BITMAPDATA
->m_ok
= isOk
;
278 void wxBitmap::SetPalette(const wxPalette
& palette
)
281 m_refData
= new wxBitmapRefData
;
283 M_BITMAPDATA
->m_bitmapPalette
= palette
;
286 void wxBitmap::SetMask(wxMask
*mask
)
289 m_refData
= new wxBitmapRefData
;
291 M_BITMAPDATA
->m_bitmapMask
= mask
;
294 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
296 sm_handlers
.Append(handler
);
299 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
301 sm_handlers
.Insert(handler
);
304 bool wxBitmap::RemoveHandler(const wxString
& name
)
306 wxBitmapHandler
*handler
= FindHandler(name
);
309 sm_handlers
.DeleteObject(handler
);
316 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
318 wxNode
*node
= sm_handlers
.First();
321 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
322 if ( handler
->GetName() == name
)
329 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
)
331 wxNode
*node
= sm_handlers
.First();
334 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
335 if ( handler
->GetExtension() == extension
&&
336 (bitmapType
== -1 || handler
->GetType() == bitmapType
) )
343 wxBitmapHandler
*wxBitmap::FindHandler(long bitmapType
)
345 wxNode
*node
= sm_handlers
.First();
348 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
349 if (handler
->GetType() == bitmapType
)
362 m_pixmap
= (WXPixmap
) 0;
365 // Construct a mask from a bitmap and a colour indicating
366 // the transparent area
367 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
369 m_pixmap
= (WXPixmap
) 0;
371 Create(bitmap
, colour
);
374 // Construct a mask from a bitmap and a palette index indicating
375 // the transparent area
376 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
378 m_pixmap
= (WXPixmap
) 0;
380 Create(bitmap
, paletteIndex
);
383 // Construct a mask from a mono bitmap (copies the bitmap).
384 wxMask::wxMask(const wxBitmap
& bitmap
)
386 m_pixmap
= (WXPixmap
) 0;
393 // TODO: this may be the wrong display
395 XFreePixmap ((Display
*) wxGetDisplay(), (Pixmap
) m_pixmap
);
398 // Create a mask from a mono bitmap (copies the bitmap).
399 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
))
405 // Create a mask from a bitmap and a palette index indicating
406 // the transparent area
407 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
), int WXUNUSED(paletteIndex
))
413 // Create a mask from a bitmap and a colour indicating
414 // the transparent area
415 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
), const wxColour
& WXUNUSED(colour
))
425 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
427 bool wxBitmapHandler::Create(wxBitmap
*WXUNUSED(bitmap
), void *WXUNUSED(data
), long WXUNUSED(type
),
428 int WXUNUSED(width
), int WXUNUSED(height
), int WXUNUSED(depth
))
433 bool wxBitmapHandler::LoadFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), long WXUNUSED(type
),
434 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
439 bool wxBitmapHandler::SaveFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), int WXUNUSED(type
),
440 const wxPalette
*WXUNUSED(palette
))
449 class WXDLLEXPORT wxXBMFileHandler
: public wxBitmapHandler
451 DECLARE_DYNAMIC_CLASS(wxXBMFileHandler
)
453 inline wxXBMFileHandler()
457 m_type
= wxBITMAP_TYPE_XBM
;
460 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
461 int desiredWidth
, int desiredHeight
);
463 IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler
, wxBitmapHandler
)
465 bool wxXBMFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
466 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
468 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
474 Display
*dpy
= (Display
*) wxGetDisplay();
475 M_BITMAPDATA
->m_display
= (WXDisplay
*) dpy
;
477 int value
= XReadBitmapFile (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)),
478 (char*) (const char*) name
, &w
, &h
, &pixmap
, &hotX
, &hotY
);
479 M_BITMAPHANDLERDATA
->m_width
= w
;
480 M_BITMAPHANDLERDATA
->m_height
= h
;
481 M_BITMAPHANDLERDATA
->m_depth
= 1;
482 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
484 if ((value
== BitmapFileInvalid
) ||
485 (value
== BitmapOpenFailed
) ||
486 (value
== BitmapNoMemory
))
488 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
489 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) 0;
492 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
494 return M_BITMAPHANDLERDATA
->m_ok
;
497 class WXDLLEXPORT wxXBMDataHandler
: public wxBitmapHandler
499 DECLARE_DYNAMIC_CLASS(wxXBMDataHandler
)
501 inline wxXBMDataHandler()
505 m_type
= wxBITMAP_TYPE_XBM_DATA
;
508 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
510 IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler
, wxBitmapHandler
)
512 bool wxXBMDataHandler::Create( wxBitmap
*bitmap
, void *data
, long WXUNUSED(flags
),
513 int width
, int height
, int WXUNUSED(depth
))
515 M_BITMAPHANDLERDATA
->m_width
= width
;
516 M_BITMAPHANDLERDATA
->m_height
= height
;
517 M_BITMAPHANDLERDATA
->m_depth
= 1;
518 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
520 Display
*dpy
= (Display
*) wxGetDisplay();
521 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
523 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) XCreateBitmapFromData (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)), (char*) data
, width
, height
);
524 M_BITMAPHANDLERDATA
->m_ok
= (M_BITMAPHANDLERDATA
->m_pixmap
!= (WXPixmap
) 0) ;
526 // code for wxControl. TODO: can we avoid doing this until we need it?
527 // E.g. have CreateButtonPixmaps which is called on demand.
528 XImage
* image
= (XImage
*) XtMalloc (sizeof (XImage
));
529 image
->width
= width
;
530 image
->height
= height
;
531 image
->data
= (char*) data
;
534 image
->format
= XYBitmap
;
535 image
->byte_order
= LSBFirst
;
536 image
->bitmap_unit
= 8;
537 image
->bitmap_bit_order
= LSBFirst
;
538 image
->bitmap_pad
= 8;
539 image
->bytes_per_line
= (width
+ 7) >> 3;
542 sprintf (tmp
, "Im%x", (unsigned int) image
);
543 XmInstallImage (image
, tmp
);
545 // Build our manually stipped pixmap.
547 int bpl
= (width
+ 7) / 8;
548 char *data1
= new char[height
* bpl
];
549 char* bits
= (char*) data
;
551 for (i
= 0; i
< height
; i
++)
553 int mask
= i
% 2 ? 0x55 : 0xaa;
555 for (j
= 0; j
< bpl
; j
++)
556 data1
[i
* bpl
+ j
] = bits
[i
* bpl
+ j
] & mask
;
558 XImage
* insensImage
= (XImage
*) XtMalloc (sizeof (XImage
));
559 insensImage
->width
= width
;
560 insensImage
->height
= height
;
561 insensImage
->data
= data1
;
562 insensImage
->depth
= 1;
563 insensImage
->xoffset
= 0;
564 insensImage
->format
= XYBitmap
;
565 insensImage
->byte_order
= LSBFirst
;
566 insensImage
->bitmap_unit
= 8;
567 insensImage
->bitmap_bit_order
= LSBFirst
;
568 insensImage
->bitmap_pad
= 8;
569 insensImage
->bytes_per_line
= bpl
;
571 sprintf (tmp
, "Not%x", (unsigned int)insensImage
);
572 XmInstallImage (insensImage
, tmp
);
574 M_BITMAPHANDLERDATA
->m_image
= (WXImage
*) image
;
575 M_BITMAPHANDLERDATA
->m_insensImage
= (WXImage
*) insensImage
;
581 class WXDLLEXPORT wxXPMFileHandler
: public wxBitmapHandler
583 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler
)
585 inline wxXPMFileHandler()
589 m_type
= wxBITMAP_TYPE_XPM
;
592 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
593 int desiredWidth
, int desiredHeight
);
594 virtual bool SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
= NULL
);
597 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler
, wxBitmapHandler
)
599 bool wxXPMFileHandler::LoadFile( wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
600 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
) )
602 Display
*dpy
= (Display
*) wxGetDisplay();
603 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
605 XpmAttributes xpmAttr
;
609 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
610 xpmAttr
.valuemask
= XpmReturnInfos
| XpmCloseness
;
611 xpmAttr
.closeness
= 40000;
612 int errorStatus
= XpmReadFileToPixmap(dpy
,
613 RootWindow(dpy
, DefaultScreen(dpy
)), (char*) (const char*) name
,
614 &pixmap
, &mask
, &xpmAttr
);
616 if (errorStatus
== XpmSuccess
)
618 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
621 M_BITMAPHANDLERDATA
->m_bitmapMask
= new wxMask
;
622 M_BITMAPHANDLERDATA
->m_bitmapMask
->SetPixmap((WXPixmap
) mask
);
625 unsigned int depthRet
;
627 unsigned int widthRet
, heightRet
, borderWidthRet
;
628 Window rootWindowRet
;
629 XGetGeometry(dpy
, pixmap
, &rootWindowRet
, &xRet
, &yRet
,
630 &widthRet
, &heightRet
, &borderWidthRet
, &depthRet
);
632 M_BITMAPHANDLERDATA
->m_width
= xpmAttr
.width
;
633 M_BITMAPHANDLERDATA
->m_height
= xpmAttr
.height
;
636 if ( xpmAttr.npixels > 2 )
638 M_BITMAPHANDLERDATA->m_depth = 8; // TODO: next time not just a guess :-) ...
641 M_BITMAPHANDLERDATA->m_depth = 1; // mono
645 M_BITMAPHANDLERDATA
->m_depth
= depthRet
;
647 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
649 XpmFreeAttributes(&xpmAttr
);
651 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
655 // XpmDebugError(errorStatus, name);
656 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
661 bool wxXPMFileHandler::SaveFile( wxBitmap
*bitmap
, const wxString
& name
, int WXUNUSED(type
),
662 const wxPalette
*WXUNUSED(palette
))
664 if (M_BITMAPHANDLERDATA
->m_ok
&& M_BITMAPHANDLERDATA
->m_pixmap
)
666 Display
*dpy
= (Display
*) M_BITMAPHANDLERDATA
->m_display
;
667 int errorStatus
= XpmWriteFileFromPixmap(dpy
, (char*) (const char*) name
,
668 (Pixmap
) M_BITMAPHANDLERDATA
->m_pixmap
,
669 (M_BITMAPHANDLERDATA
->m_bitmapMask
? (Pixmap
) M_BITMAPHANDLERDATA
->m_bitmapMask
->GetPixmap() : (Pixmap
) 0),
670 (XpmAttributes
*) NULL
);
671 if (errorStatus
== XpmSuccess
)
680 class WXDLLEXPORT wxXPMDataHandler
: public wxBitmapHandler
682 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler
)
684 inline wxXPMDataHandler()
688 m_type
= wxBITMAP_TYPE_XPM_DATA
;
691 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
693 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler
, wxBitmapHandler
)
695 bool wxXPMDataHandler::Create( wxBitmap
*bitmap
, void *data
, long WXUNUSED(flags
),
696 int width
, int height
, int WXUNUSED(depth
))
698 M_BITMAPHANDLERDATA
->m_width
= width
;
699 M_BITMAPHANDLERDATA
->m_height
= height
;
700 M_BITMAPHANDLERDATA
->m_depth
= 1;
701 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
703 Display
*dpy
= (Display
*) wxGetDisplay();
704 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
706 XpmAttributes xpmAttr
;
708 xpmAttr
.valuemask
= XpmReturnInfos
; /* nothing yet, but get infos back */
710 XpmColorSymbol symbolicColors
[4];
711 if (sg_Control
&& sg_Control
->GetMainWidget())
713 symbolicColors
[0].name
= "foreground";
714 symbolicColors
[0].value
= NULL
;
715 symbolicColors
[1].name
= "background";
716 symbolicColors
[1].value
= NULL
;
717 XtVaGetValues((Widget
) sg_Control
->GetMainWidget(),
718 XmNforeground
, &symbolicColors
[0].pixel
,
719 XmNbackground
, &symbolicColors
[1].pixel
,NULL
);
720 xpmAttr
.numsymbols
= 2;
721 xpmAttr
.colorsymbols
= symbolicColors
;
722 xpmAttr
.valuemask
|= XpmColorSymbols
; // add flag
727 int ErrorStatus
= XpmCreatePixmapFromData(dpy
, RootWindow(dpy
, DefaultScreen(dpy
)),
728 (char**) data
, &pixmap
, &mask
, &xpmAttr
);
729 if (ErrorStatus
== XpmSuccess
)
732 M_BITMAPHANDLERDATA
->m_width
= xpmAttr
.width
;
733 M_BITMAPHANDLERDATA
->m_height
= xpmAttr
.height
;
735 unsigned int depthRet
;
737 unsigned int widthRet
, heightRet
, borderWidthRet
;
738 Window rootWindowRet
;
739 XGetGeometry(dpy
, pixmap
, &rootWindowRet
, &xRet
, &yRet
,
740 &widthRet
, &heightRet
, &borderWidthRet
, &depthRet
);
743 if ( xpmAttr.npixels > 2 )
745 M_BITMAPHANDLERDATA->m_depth = 8; // next time not just a guess :-) ...
748 M_BITMAPHANDLERDATA->m_depth = 1; // mono
752 M_BITMAPHANDLERDATA
->m_depth
= depthRet
;
754 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
755 XpmFreeAttributes(&xpmAttr
);
756 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
757 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
760 M_BITMAPHANDLERDATA
->m_bitmapMask
= new wxMask
;
761 M_BITMAPHANDLERDATA
->m_bitmapMask
->SetPixmap((WXPixmap
) mask
);
766 // XpmDebugError(ErrorStatus, NULL);
767 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
769 return M_BITMAPHANDLERDATA
->m_ok
;
774 void wxBitmap::CleanUpHandlers()
776 wxNode
*node
= sm_handlers
.First();
779 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
780 wxNode
*next
= node
->Next();
787 void wxBitmap::InitStandardHandlers()
789 // Initialize all standard bitmap or derived class handlers here.
790 AddHandler(new wxXBMFileHandler
);
791 AddHandler(new wxXBMDataHandler
);
793 // XPM is considered standard for Motif, although it can be omitted if absolutely
796 AddHandler(new wxXPMFileHandler
);
797 AddHandler(new wxXPMDataHandler
);
801 WXPixmap
wxBitmap::GetLabelPixmap (WXWidget w
)
803 if (M_BITMAPDATA
->m_image
== (WXPixmap
) 0)
804 return M_BITMAPDATA
->m_pixmap
;
806 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
811 if (labelPixmap) return labelPixmap;
812 things can be wrong, because colors can have been changed.
816 XmDestroyPixmap(DefaultScreenOfDisplay(dpy),labelPixmap) ;
817 we got BadDrawable if the pixmap is referenced by multiples widgets
821 So, before doing thing really clean, I just do nothing; if the pixmap is
822 referenced by many widgets, Motif performs caching functions.
823 And if pixmap is referenced with multiples colors, we just have some
824 memory leaks... I hope we can deal with them...
826 // Must be destroyed, because colours can have been changed!
827 if (M_BITMAPDATA
->m_labelPixmap
)
828 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), M_BITMAPDATA
->m_labelPixmap
);
832 sprintf (tmp
, "Im%x", (unsigned int) M_BITMAPDATA
->m_image
);
835 Widget widget
= (Widget
) w
;
837 while (XmIsGadget ( widget
))
838 widget
= XtParent (widget
);
839 XtVaGetValues (widget
, XmNbackground
, &bg
, XmNforeground
, &fg
, NULL
);
841 M_BITMAPDATA
->m_labelPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
843 return M_BITMAPDATA
->m_labelPixmap
;
846 WXPixmap
wxBitmap::GetArmPixmap (WXWidget w
)
848 if (M_BITMAPDATA
->m_image
== (WXPixmap
) 0)
849 return M_BITMAPDATA
->m_pixmap
;
851 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
853 See
GetLabelPixmap () comment
854 // Must be destroyed, because colours can have been changed!
855 if (M_BITMAPDATA
->m_armPixmap
)
856 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), M_BITMAPDATA
->m_armPixmap
);
860 sprintf (tmp
, "Im%x", (unsigned int) M_BITMAPDATA
->m_image
);
863 Widget widget
= (Widget
) w
;
865 XtVaGetValues (widget
, XmNarmColor
, &bg
, NULL
);
866 while (XmIsGadget (widget
))
867 widget
= XtParent (widget
);
868 XtVaGetValues (widget
, XmNforeground
, &fg
, NULL
);
870 M_BITMAPDATA
->m_armPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
872 return M_BITMAPDATA
->m_armPixmap
;
875 WXPixmap
wxBitmap::GetInsensPixmap (WXWidget w
)
877 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
879 if (M_BITMAPDATA
->m_insensPixmap
)
880 return M_BITMAPDATA
->m_insensPixmap
;
884 M_BITMAPDATA
->m_insensPixmap
= (WXPixmap
) XCreateInsensitivePixmap(dpy
, (Pixmap
) M_BITMAPDATA
->m_pixmap
);
885 if (M_BITMAPDATA
->m_insensPixmap
)
886 return M_BITMAPDATA
->m_insensPixmap
;
888 return M_BITMAPDATA
->m_pixmap
;
891 if (M_BITMAPDATA
->m_insensImage
== (WXPixmap
) 0)
892 return M_BITMAPDATA
->m_pixmap
;
895 See
GetLabelPixmap () comment
896 // Must be destroyed, because colours can have been changed!
897 if (M_BITMAPDATA
->m_insensPixmap
)
898 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), (Pixmap
) M_BITMAPDATA
->m_insensPixmap
);
902 sprintf (tmp
, "Not%x", (unsigned int) M_BITMAPDATA
->m_insensImage
);
905 Widget widget
= (Widget
) w
;
907 while (XmIsGadget (widget
))
908 widget
= XtParent (widget
);
909 XtVaGetValues (widget
, XmNbackground
, &bg
, XmNforeground
, &fg
, NULL
);
911 M_BITMAPDATA
->m_insensPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
913 return M_BITMAPDATA
->m_insensPixmap
;
916 // We may need this sometime...
918 /****************************************************************************
921 XCreateInsensitivePixmap - create a grayed-out copy of a pixmap
924 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
927 This function creates a grayed-out copy of the argument pixmap, suitable
928 for use as a XmLabel's XmNlabelInsensitivePixmap resource.
931 The return value is the new Pixmap id or zero on error. Errors include
932 a NULL display argument or an invalid Pixmap argument.
935 If one of the XLib functions fail, it will produce a X error. The
936 default X error handler prints a diagnostic and calls exit().
939 XCopyArea(3), XCreateBitmapFromData(3), XCreateGC(3), XCreatePixmap(3),
940 XFillRectangle(3), exit(2)
943 John R Veregge - john@puente.jpl.nasa.gov
944 Advanced Engineering and Prototyping Group (AEG)
945 Information Systems Technology Section (395)
946 Jet Propulsion Lab - Calif Institute of Technology
948 *****************************************************************************/
951 XCreateInsensitivePixmap( Display
*display
, Pixmap pixmap
)
955 char stipple_data
[] =
957 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
958 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
959 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
960 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA
963 Pixmap ipixmap
, stipple
;
964 unsigned width
, height
, depth
;
966 Window window
; /* These return values */
967 unsigned border
; /* from XGetGeometry() */
968 int x
, y
; /* are not needed. */
972 if ( NULL
== display
|| 0 == pixmap
)
975 if ( 0 == XGetGeometry( display
, pixmap
, &window
, &x
, &y
,
976 &width
, &height
, &border
, &depth
)
978 return ipixmap
; /* BadDrawable: probably an invalid pixmap */
980 /* Get the stipple pixmap to be used to 'gray-out' the argument pixmap.
982 stipple
= XCreateBitmapFromData( display
, pixmap
, stipple_data
, 16, 16 );
985 gc
= XCreateGC( display
, pixmap
, (XtGCMask
)0, (XGCValues
*)NULL
);
988 /* Create an identical copy of the argument pixmap.
990 ipixmap
= XCreatePixmap( display
, pixmap
, width
, height
, depth
);
993 /* Copy the argument pixmap into the new pixmap.
995 XCopyArea( display
, pixmap
, ipixmap
,
996 gc
, 0, 0, width
, height
, 0, 0 );
998 /* Refill the new pixmap using the stipple algorithm/pixmap.
1000 XSetStipple( display
, gc
, stipple
);
1001 XSetFillStyle( display
, gc
, FillStippled
);
1002 XFillRectangle( display
, ipixmap
, gc
, 0, 0, width
, height
);
1004 XFreeGC( display
, gc
);
1006 XFreePixmap( display
, stipple
);
1011 // Creates a bitmap with transparent areas drawn in
1012 // the given colour.
1013 wxBitmap
wxCreateMaskedBitmap(wxBitmap
& bitmap
, wxColour
& colour
)
1015 wxBitmap
newBitmap(bitmap
.GetWidth(),
1020 srcDC
.SelectObject(bitmap
);
1021 destDC
.SelectObject(newBitmap
);
1023 wxBrush
brush(colour
, wxSOLID
);
1024 destDC
.SetOptimization(FALSE
);
1025 destDC
.SetBackground(brush
);
1027 destDC
.Blit(0, 0, bitmap
.GetWidth(), bitmap
.GetHeight(), & srcDC
, 0, 0, wxCOPY
, TRUE
);