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"
28 #include "wx/motif/private.h"
34 #if !USE_SHARED_LIBRARIES
35 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
36 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
39 wxBitmapRefData::wxBitmapRefData()
49 m_pixmap
= (WXPixmap
) 0;
50 m_display
= (WXDisplay
*) 0;
52 m_freePixmap
= TRUE
; //TODO: necessary?
53 m_freeColors
= (unsigned long*) 0;
54 m_freeColorsCount
= 0;
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;
64 wxBitmapRefData::~wxBitmapRefData()
67 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_labelPixmap
);
70 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_armPixmap
);
73 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_insensPixmap
);
77 XmUninstallImage ((XImage
*) m_image
);
78 XtFree ((char *) (XImage
*) m_image
);
83 XmUninstallImage ((XImage
*) m_insensImage
);
84 delete[] ((XImage
*) m_insensImage
)->data
;
85 XtFree ((char *) (XImage
*) m_insensImage
);
87 if (m_pixmap
&& m_freePixmap
)
88 XFreePixmap ((Display
*) m_display
, (Pixmap
) m_pixmap
);
92 int screen
= DefaultScreen((Display
*) m_display
);
93 Colormap cmp
= DefaultColormap((Display
*) m_display
,screen
);
95 for(llp
= 0;llp
< m_freeColorsCount
;llp
++)
96 XFreeColors((Display
*) m_display
, cmp
, &m_freeColors
[llp
], 1, 0L);
105 wxList
wxBitmap::sm_handlers
;
111 if ( wxTheBitmapList
)
112 wxTheBitmapList
->AddBitmap(this);
115 wxBitmap::~wxBitmap()
118 wxTheBitmapList
->DeleteObject(this);
121 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
)
123 m_refData
= new wxBitmapRefData
;
125 (void) Create((void*) bits
, wxBITMAP_TYPE_XBM_DATA
, width
, height
, depth
);
127 if ( wxTheBitmapList
)
128 wxTheBitmapList
->AddBitmap(this);
131 wxBitmap::wxBitmap(int w
, int h
, int d
)
133 (void)Create(w
, h
, d
);
135 if ( wxTheBitmapList
)
136 wxTheBitmapList
->AddBitmap(this);
139 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
)
141 (void) Create(data
, type
, width
, height
, depth
);
143 if ( wxTheBitmapList
)
144 wxTheBitmapList
->AddBitmap(this);
147 wxBitmap::wxBitmap(const wxString
& filename
, long type
)
149 LoadFile(filename
, (int)type
);
151 if ( wxTheBitmapList
)
152 wxTheBitmapList
->AddBitmap(this);
155 // Create from XPM data
156 static wxControl
* sg_Control
= NULL
;
157 wxBitmap::wxBitmap(char **data
, wxControl
* control
)
159 // Pass the control to the Create function using a global
160 sg_Control
= control
;
162 (void) Create((void *)data
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
164 sg_Control
= (wxControl
*) NULL
;
167 bool wxBitmap::Create(int w
, int h
, int d
)
171 m_refData
= new wxBitmapRefData
;
174 d
= wxDisplayDepth();
176 M_BITMAPDATA
->m_width
= w
;
177 M_BITMAPDATA
->m_height
= h
;
178 M_BITMAPDATA
->m_depth
= d
;
179 M_BITMAPDATA
->m_freePixmap
= TRUE
;
181 Display
*dpy
= (Display
*) wxGetDisplay();
183 M_BITMAPDATA
->m_display
= dpy
; /* MATTHEW: [4] Remember the display */
185 M_BITMAPDATA
->m_pixmap
= (WXPixmap
) XCreatePixmap (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)),
188 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_pixmap
!= (WXPixmap
) 0) ;
189 return M_BITMAPDATA
->m_ok
;
192 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
196 m_refData
= new wxBitmapRefData
;
198 wxBitmapHandler
*handler
= FindHandler(type
);
200 if ( handler
== NULL
) {
202 if (!image
.LoadFile( filename
, type
)) return FALSE
;
205 *this = image
.ConvertToBitmap();
211 return handler
->LoadFile(this, filename
, type
, -1, -1);
214 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
)
218 m_refData
= new wxBitmapRefData
;
220 wxBitmapHandler
*handler
= FindHandler(type
);
222 if ( handler
== NULL
) {
223 wxLogWarning("no data bitmap handler for type %d defined.", type
);
228 return handler
->Create(this, data
, type
, width
, height
, depth
);
231 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette
*palette
)
233 wxBitmapHandler
*handler
= FindHandler(type
);
235 if ( handler
== NULL
) { // try wxImage
236 wxImage
image( *this );
237 if (image
.Ok()) return image
.SaveFile( filename
, type
);
241 return handler
->SaveFile(this, filename
, type
, palette
);
244 void wxBitmap::SetWidth(int w
)
247 m_refData
= new wxBitmapRefData
;
249 M_BITMAPDATA
->m_width
= w
;
252 void wxBitmap::SetHeight(int h
)
255 m_refData
= new wxBitmapRefData
;
257 M_BITMAPDATA
->m_height
= h
;
260 void wxBitmap::SetDepth(int d
)
263 m_refData
= new wxBitmapRefData
;
265 M_BITMAPDATA
->m_depth
= d
;
268 void wxBitmap::SetQuality(int q
)
271 m_refData
= new wxBitmapRefData
;
273 M_BITMAPDATA
->m_quality
= q
;
276 void wxBitmap::SetOk(bool isOk
)
279 m_refData
= new wxBitmapRefData
;
281 M_BITMAPDATA
->m_ok
= isOk
;
284 void wxBitmap::SetPalette(const wxPalette
& palette
)
287 m_refData
= new wxBitmapRefData
;
289 M_BITMAPDATA
->m_bitmapPalette
= palette
;
292 void wxBitmap::SetMask(wxMask
*mask
)
295 m_refData
= new wxBitmapRefData
;
297 M_BITMAPDATA
->m_bitmapMask
= mask
;
300 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
302 sm_handlers
.Append(handler
);
305 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
307 sm_handlers
.Insert(handler
);
310 bool wxBitmap::RemoveHandler(const wxString
& name
)
312 wxBitmapHandler
*handler
= FindHandler(name
);
315 sm_handlers
.DeleteObject(handler
);
322 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
324 wxNode
*node
= sm_handlers
.First();
327 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
328 if ( handler
->GetName() == name
)
335 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
)
337 wxNode
*node
= sm_handlers
.First();
340 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
341 if ( handler
->GetExtension() == extension
&&
342 (bitmapType
== -1 || handler
->GetType() == bitmapType
) )
349 wxBitmapHandler
*wxBitmap::FindHandler(long bitmapType
)
351 wxNode
*node
= sm_handlers
.First();
354 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
355 if (handler
->GetType() == bitmapType
)
368 m_pixmap
= (WXPixmap
) 0;
371 // Construct a mask from a bitmap and a colour indicating
372 // the transparent area
373 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
375 m_pixmap
= (WXPixmap
) 0;
377 Create(bitmap
, colour
);
380 // Construct a mask from a bitmap and a palette index indicating
381 // the transparent area
382 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
384 m_pixmap
= (WXPixmap
) 0;
386 Create(bitmap
, paletteIndex
);
389 // Construct a mask from a mono bitmap (copies the bitmap).
390 wxMask::wxMask(const wxBitmap
& bitmap
)
392 m_pixmap
= (WXPixmap
) 0;
399 // TODO: this may be the wrong display
401 XFreePixmap ((Display
*) wxGetDisplay(), (Pixmap
) m_pixmap
);
404 // Create a mask from a mono bitmap (copies the bitmap).
405 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
))
411 // Create a mask from a bitmap and a palette index indicating
412 // the transparent area
413 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
), int WXUNUSED(paletteIndex
))
419 // Create a mask from a bitmap and a colour indicating
420 // the transparent area
421 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
), const wxColour
& WXUNUSED(colour
))
431 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
433 bool wxBitmapHandler::Create(wxBitmap
*WXUNUSED(bitmap
), void *WXUNUSED(data
), long WXUNUSED(type
),
434 int WXUNUSED(width
), int WXUNUSED(height
), int WXUNUSED(depth
))
439 bool wxBitmapHandler::LoadFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), long WXUNUSED(type
),
440 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
445 bool wxBitmapHandler::SaveFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), int WXUNUSED(type
),
446 const wxPalette
*WXUNUSED(palette
))
455 class WXDLLEXPORT wxXBMFileHandler
: public wxBitmapHandler
457 DECLARE_DYNAMIC_CLASS(wxXBMFileHandler
)
459 inline wxXBMFileHandler()
463 m_type
= wxBITMAP_TYPE_XBM
;
466 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
467 int desiredWidth
, int desiredHeight
);
469 IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler
, wxBitmapHandler
)
471 bool wxXBMFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
472 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
474 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
480 Display
*dpy
= (Display
*) wxGetDisplay();
481 M_BITMAPDATA
->m_display
= (WXDisplay
*) dpy
;
483 int value
= XReadBitmapFile (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)),
484 (char*) (const char*) name
, &w
, &h
, &pixmap
, &hotX
, &hotY
);
485 M_BITMAPHANDLERDATA
->m_width
= w
;
486 M_BITMAPHANDLERDATA
->m_height
= h
;
487 M_BITMAPHANDLERDATA
->m_depth
= 1;
488 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
490 if ((value
== BitmapFileInvalid
) ||
491 (value
== BitmapOpenFailed
) ||
492 (value
== BitmapNoMemory
))
494 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
495 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) 0;
498 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
500 return M_BITMAPHANDLERDATA
->m_ok
;
503 class WXDLLEXPORT wxXBMDataHandler
: public wxBitmapHandler
505 DECLARE_DYNAMIC_CLASS(wxXBMDataHandler
)
507 inline wxXBMDataHandler()
511 m_type
= wxBITMAP_TYPE_XBM_DATA
;
514 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
516 IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler
, wxBitmapHandler
)
518 bool wxXBMDataHandler::Create( wxBitmap
*bitmap
, void *data
, long WXUNUSED(flags
),
519 int width
, int height
, int WXUNUSED(depth
))
521 M_BITMAPHANDLERDATA
->m_width
= width
;
522 M_BITMAPHANDLERDATA
->m_height
= height
;
523 M_BITMAPHANDLERDATA
->m_depth
= 1;
524 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
526 Display
*dpy
= (Display
*) wxGetDisplay();
527 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
529 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) XCreateBitmapFromData (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)), (char*) data
, width
, height
);
530 M_BITMAPHANDLERDATA
->m_ok
= (M_BITMAPHANDLERDATA
->m_pixmap
!= (WXPixmap
) 0) ;
532 // code for wxControl. TODO: can we avoid doing this until we need it?
533 // E.g. have CreateButtonPixmaps which is called on demand.
534 XImage
* image
= (XImage
*) XtMalloc (sizeof (XImage
));
535 image
->width
= width
;
536 image
->height
= height
;
537 image
->data
= (char*) data
;
540 image
->format
= XYBitmap
;
541 image
->byte_order
= LSBFirst
;
542 image
->bitmap_unit
= 8;
543 image
->bitmap_bit_order
= LSBFirst
;
544 image
->bitmap_pad
= 8;
545 image
->bytes_per_line
= (width
+ 7) >> 3;
548 sprintf (tmp
, "Im%x", (unsigned int) image
);
549 XmInstallImage (image
, tmp
);
551 // Build our manually stipped pixmap.
553 int bpl
= (width
+ 7) / 8;
554 char *data1
= new char[height
* bpl
];
555 char* bits
= (char*) data
;
557 for (i
= 0; i
< height
; i
++)
559 int mask
= i
% 2 ? 0x55 : 0xaa;
561 for (j
= 0; j
< bpl
; j
++)
562 data1
[i
* bpl
+ j
] = bits
[i
* bpl
+ j
] & mask
;
564 XImage
* insensImage
= (XImage
*) XtMalloc (sizeof (XImage
));
565 insensImage
->width
= width
;
566 insensImage
->height
= height
;
567 insensImage
->data
= data1
;
568 insensImage
->depth
= 1;
569 insensImage
->xoffset
= 0;
570 insensImage
->format
= XYBitmap
;
571 insensImage
->byte_order
= LSBFirst
;
572 insensImage
->bitmap_unit
= 8;
573 insensImage
->bitmap_bit_order
= LSBFirst
;
574 insensImage
->bitmap_pad
= 8;
575 insensImage
->bytes_per_line
= bpl
;
577 sprintf (tmp
, "Not%x", (unsigned int)insensImage
);
578 XmInstallImage (insensImage
, tmp
);
580 M_BITMAPHANDLERDATA
->m_image
= (WXImage
*) image
;
581 M_BITMAPHANDLERDATA
->m_insensImage
= (WXImage
*) insensImage
;
587 class WXDLLEXPORT wxXPMFileHandler
: public wxBitmapHandler
589 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler
)
591 inline wxXPMFileHandler()
595 m_type
= wxBITMAP_TYPE_XPM
;
598 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
599 int desiredWidth
, int desiredHeight
);
600 virtual bool SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
= NULL
);
603 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler
, wxBitmapHandler
)
605 bool wxXPMFileHandler::LoadFile( wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
606 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
) )
608 Display
*dpy
= (Display
*) wxGetDisplay();
609 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
611 XpmAttributes xpmAttr
;
615 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
616 xpmAttr
.valuemask
= XpmReturnInfos
| XpmCloseness
;
617 xpmAttr
.closeness
= 40000;
618 int errorStatus
= XpmReadFileToPixmap(dpy
,
619 RootWindow(dpy
, DefaultScreen(dpy
)), (char*) (const char*) name
,
620 &pixmap
, &mask
, &xpmAttr
);
622 if (errorStatus
== XpmSuccess
)
624 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
627 M_BITMAPHANDLERDATA
->m_bitmapMask
= new wxMask
;
628 M_BITMAPHANDLERDATA
->m_bitmapMask
->SetPixmap((WXPixmap
) mask
);
631 unsigned int depthRet
;
633 unsigned int widthRet
, heightRet
, borderWidthRet
;
634 Window rootWindowRet
;
635 XGetGeometry(dpy
, pixmap
, &rootWindowRet
, &xRet
, &yRet
,
636 &widthRet
, &heightRet
, &borderWidthRet
, &depthRet
);
638 M_BITMAPHANDLERDATA
->m_width
= xpmAttr
.width
;
639 M_BITMAPHANDLERDATA
->m_height
= xpmAttr
.height
;
642 if ( xpmAttr.npixels > 2 )
644 M_BITMAPHANDLERDATA->m_depth = 8; // TODO: next time not just a guess :-) ...
647 M_BITMAPHANDLERDATA->m_depth = 1; // mono
651 M_BITMAPHANDLERDATA
->m_depth
= depthRet
;
653 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
655 XpmFreeAttributes(&xpmAttr
);
657 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
661 // XpmDebugError(errorStatus, name);
662 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
667 bool wxXPMFileHandler::SaveFile( wxBitmap
*bitmap
, const wxString
& name
, int WXUNUSED(type
),
668 const wxPalette
*WXUNUSED(palette
))
670 if (M_BITMAPHANDLERDATA
->m_ok
&& M_BITMAPHANDLERDATA
->m_pixmap
)
672 Display
*dpy
= (Display
*) M_BITMAPHANDLERDATA
->m_display
;
673 int errorStatus
= XpmWriteFileFromPixmap(dpy
, (char*) (const char*) name
,
674 (Pixmap
) M_BITMAPHANDLERDATA
->m_pixmap
,
675 (M_BITMAPHANDLERDATA
->m_bitmapMask
? (Pixmap
) M_BITMAPHANDLERDATA
->m_bitmapMask
->GetPixmap() : (Pixmap
) 0),
676 (XpmAttributes
*) NULL
);
677 if (errorStatus
== XpmSuccess
)
686 class WXDLLEXPORT wxXPMDataHandler
: public wxBitmapHandler
688 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler
)
690 inline wxXPMDataHandler()
694 m_type
= wxBITMAP_TYPE_XPM_DATA
;
697 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
699 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler
, wxBitmapHandler
)
701 bool wxXPMDataHandler::Create( wxBitmap
*bitmap
, void *data
, long WXUNUSED(flags
),
702 int width
, int height
, int WXUNUSED(depth
))
704 M_BITMAPHANDLERDATA
->m_width
= width
;
705 M_BITMAPHANDLERDATA
->m_height
= height
;
706 M_BITMAPHANDLERDATA
->m_depth
= 1;
707 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
709 Display
*dpy
= (Display
*) wxGetDisplay();
710 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
712 XpmAttributes xpmAttr
;
714 xpmAttr
.valuemask
= XpmReturnInfos
; /* nothing yet, but get infos back */
716 XpmColorSymbol symbolicColors
[4];
717 if (sg_Control
&& sg_Control
->GetMainWidget())
719 symbolicColors
[0].name
= "foreground";
720 symbolicColors
[0].value
= NULL
;
721 symbolicColors
[1].name
= "background";
722 symbolicColors
[1].value
= NULL
;
723 XtVaGetValues((Widget
) sg_Control
->GetMainWidget(),
724 XmNforeground
, &symbolicColors
[0].pixel
,
725 XmNbackground
, &symbolicColors
[1].pixel
,NULL
);
726 xpmAttr
.numsymbols
= 2;
727 xpmAttr
.colorsymbols
= symbolicColors
;
728 xpmAttr
.valuemask
|= XpmColorSymbols
; // add flag
733 int ErrorStatus
= XpmCreatePixmapFromData(dpy
, RootWindow(dpy
, DefaultScreen(dpy
)),
734 (char**) data
, &pixmap
, &mask
, &xpmAttr
);
735 if (ErrorStatus
== XpmSuccess
)
738 M_BITMAPHANDLERDATA
->m_width
= xpmAttr
.width
;
739 M_BITMAPHANDLERDATA
->m_height
= xpmAttr
.height
;
741 unsigned int depthRet
;
743 unsigned int widthRet
, heightRet
, borderWidthRet
;
744 Window rootWindowRet
;
745 XGetGeometry(dpy
, pixmap
, &rootWindowRet
, &xRet
, &yRet
,
746 &widthRet
, &heightRet
, &borderWidthRet
, &depthRet
);
749 if ( xpmAttr.npixels > 2 )
751 M_BITMAPHANDLERDATA->m_depth = 8; // next time not just a guess :-) ...
754 M_BITMAPHANDLERDATA->m_depth = 1; // mono
758 M_BITMAPHANDLERDATA
->m_depth
= depthRet
;
760 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
761 XpmFreeAttributes(&xpmAttr
);
762 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
763 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
766 M_BITMAPHANDLERDATA
->m_bitmapMask
= new wxMask
;
767 M_BITMAPHANDLERDATA
->m_bitmapMask
->SetPixmap((WXPixmap
) mask
);
772 // XpmDebugError(ErrorStatus, NULL);
773 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
775 return M_BITMAPHANDLERDATA
->m_ok
;
778 #endif // wxHAVE_LIB_XPM
780 void wxBitmap::CleanUpHandlers()
782 wxNode
*node
= sm_handlers
.First();
785 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
786 wxNode
*next
= node
->Next();
793 void wxBitmap::InitStandardHandlers()
795 // Initialize all standard bitmap or derived class handlers here.
796 AddHandler(new wxXBMFileHandler
);
797 AddHandler(new wxXBMDataHandler
);
799 // XPM is considered standard for Motif, although it can be omitted if
800 // libXpm is not installed
802 AddHandler(new wxXPMFileHandler
);
803 AddHandler(new wxXPMDataHandler
);
804 #endif // wxHAVE_LIB_XPM
807 WXPixmap
wxBitmap::GetLabelPixmap (WXWidget w
)
809 if (M_BITMAPDATA
->m_image
== (WXPixmap
) 0)
810 return M_BITMAPDATA
->m_pixmap
;
812 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
817 if (labelPixmap) return labelPixmap;
818 things can be wrong, because colors can have been changed.
822 XmDestroyPixmap(DefaultScreenOfDisplay(dpy),labelPixmap) ;
823 we got BadDrawable if the pixmap is referenced by multiples widgets
827 So, before doing thing really clean, I just do nothing; if the pixmap is
828 referenced by many widgets, Motif performs caching functions.
829 And if pixmap is referenced with multiples colors, we just have some
830 memory leaks... I hope we can deal with them...
832 // Must be destroyed, because colours can have been changed!
833 if (M_BITMAPDATA
->m_labelPixmap
)
834 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), M_BITMAPDATA
->m_labelPixmap
);
838 sprintf (tmp
, "Im%x", (unsigned int) M_BITMAPDATA
->m_image
);
841 Widget widget
= (Widget
) w
;
843 while (XmIsGadget ( widget
))
844 widget
= XtParent (widget
);
845 XtVaGetValues (widget
, XmNbackground
, &bg
, XmNforeground
, &fg
, NULL
);
847 M_BITMAPDATA
->m_labelPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
849 return M_BITMAPDATA
->m_labelPixmap
;
852 WXPixmap
wxBitmap::GetArmPixmap (WXWidget w
)
854 if (M_BITMAPDATA
->m_image
== (WXPixmap
) 0)
855 return M_BITMAPDATA
->m_pixmap
;
857 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
859 See
GetLabelPixmap () comment
860 // Must be destroyed, because colours can have been changed!
861 if (M_BITMAPDATA
->m_armPixmap
)
862 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), M_BITMAPDATA
->m_armPixmap
);
866 sprintf (tmp
, "Im%x", (unsigned int) M_BITMAPDATA
->m_image
);
869 Widget widget
= (Widget
) w
;
871 XtVaGetValues (widget
, XmNarmColor
, &bg
, NULL
);
872 while (XmIsGadget (widget
))
873 widget
= XtParent (widget
);
874 XtVaGetValues (widget
, XmNforeground
, &fg
, NULL
);
876 M_BITMAPDATA
->m_armPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
878 return M_BITMAPDATA
->m_armPixmap
;
881 WXPixmap
wxBitmap::GetInsensPixmap (WXWidget w
)
883 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
885 if (M_BITMAPDATA
->m_insensPixmap
)
886 return M_BITMAPDATA
->m_insensPixmap
;
890 M_BITMAPDATA
->m_insensPixmap
= (WXPixmap
) XCreateInsensitivePixmap(dpy
, (Pixmap
) M_BITMAPDATA
->m_pixmap
);
891 if (M_BITMAPDATA
->m_insensPixmap
)
892 return M_BITMAPDATA
->m_insensPixmap
;
894 return M_BITMAPDATA
->m_pixmap
;
897 if (M_BITMAPDATA
->m_insensImage
== (WXPixmap
) 0)
898 return M_BITMAPDATA
->m_pixmap
;
901 See
GetLabelPixmap () comment
902 // Must be destroyed, because colours can have been changed!
903 if (M_BITMAPDATA
->m_insensPixmap
)
904 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), (Pixmap
) M_BITMAPDATA
->m_insensPixmap
);
908 sprintf (tmp
, "Not%x", (unsigned int) M_BITMAPDATA
->m_insensImage
);
911 Widget widget
= (Widget
) w
;
913 while (XmIsGadget (widget
))
914 widget
= XtParent (widget
);
915 XtVaGetValues (widget
, XmNbackground
, &bg
, XmNforeground
, &fg
, NULL
);
917 M_BITMAPDATA
->m_insensPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
919 return M_BITMAPDATA
->m_insensPixmap
;
922 // We may need this sometime...
924 /****************************************************************************
927 XCreateInsensitivePixmap - create a grayed-out copy of a pixmap
930 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
933 This function creates a grayed-out copy of the argument pixmap, suitable
934 for use as a XmLabel's XmNlabelInsensitivePixmap resource.
937 The return value is the new Pixmap id or zero on error. Errors include
938 a NULL display argument or an invalid Pixmap argument.
941 If one of the XLib functions fail, it will produce a X error. The
942 default X error handler prints a diagnostic and calls exit().
945 XCopyArea(3), XCreateBitmapFromData(3), XCreateGC(3), XCreatePixmap(3),
946 XFillRectangle(3), exit(2)
949 John R Veregge - john@puente.jpl.nasa.gov
950 Advanced Engineering and Prototyping Group (AEG)
951 Information Systems Technology Section (395)
952 Jet Propulsion Lab - Calif Institute of Technology
954 *****************************************************************************/
957 XCreateInsensitivePixmap( Display
*display
, Pixmap pixmap
)
961 char stipple_data
[] =
963 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
964 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
965 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
966 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA
969 Pixmap ipixmap
, stipple
;
970 unsigned width
, height
, depth
;
972 Window window
; /* These return values */
973 unsigned border
; /* from XGetGeometry() */
974 int x
, y
; /* are not needed. */
978 if ( NULL
== display
|| 0 == pixmap
)
981 if ( 0 == XGetGeometry( display
, pixmap
, &window
, &x
, &y
,
982 &width
, &height
, &border
, &depth
)
984 return ipixmap
; /* BadDrawable: probably an invalid pixmap */
986 /* Get the stipple pixmap to be used to 'gray-out' the argument pixmap.
988 stipple
= XCreateBitmapFromData( display
, pixmap
, stipple_data
, 16, 16 );
991 gc
= XCreateGC( display
, pixmap
, (XtGCMask
)0, (XGCValues
*)NULL
);
994 /* Create an identical copy of the argument pixmap.
996 ipixmap
= XCreatePixmap( display
, pixmap
, width
, height
, depth
);
999 /* Copy the argument pixmap into the new pixmap.
1001 XCopyArea( display
, pixmap
, ipixmap
,
1002 gc
, 0, 0, width
, height
, 0, 0 );
1004 /* Refill the new pixmap using the stipple algorithm/pixmap.
1006 XSetStipple( display
, gc
, stipple
);
1007 XSetFillStyle( display
, gc
, FillStippled
);
1008 XFillRectangle( display
, ipixmap
, gc
, 0, 0, width
, height
);
1010 XFreeGC( display
, gc
);
1012 XFreePixmap( display
, stipple
);
1017 // Creates a bitmap with transparent areas drawn in
1018 // the given colour.
1019 wxBitmap
wxCreateMaskedBitmap(wxBitmap
& bitmap
, wxColour
& colour
)
1021 wxBitmap
newBitmap(bitmap
.GetWidth(),
1026 srcDC
.SelectObject(bitmap
);
1027 destDC
.SelectObject(newBitmap
);
1029 wxBrush
brush(colour
, wxSOLID
);
1030 destDC
.SetOptimization(FALSE
);
1031 destDC
.SetBackground(brush
);
1033 destDC
.Blit(0, 0, bitmap
.GetWidth(), bitmap
.GetHeight(), & srcDC
, 0, 0, wxCOPY
, TRUE
);