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 #pragma message disable nosimpint
31 #pragma message enable nosimpint
34 #include "wx/motif/private.h"
40 #if !USE_SHARED_LIBRARIES
41 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
42 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
45 wxBitmapRefData::wxBitmapRefData()
55 m_pixmap
= (WXPixmap
) 0;
56 m_display
= (WXDisplay
*) 0;
58 m_freePixmap
= TRUE
; //TODO: necessary?
59 m_freeColors
= (unsigned long*) 0;
60 m_freeColorsCount
= 0;
62 // These 5 variables are for wxControl
63 m_insensPixmap
= (WXPixmap
) 0;
64 m_labelPixmap
= (WXPixmap
) 0;
65 m_armPixmap
= (WXPixmap
) 0;
66 m_image
= (WXImage
*) 0;
67 m_insensImage
= (WXImage
*) 0;
70 wxBitmapRefData::~wxBitmapRefData()
73 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_labelPixmap
);
76 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_armPixmap
);
79 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_insensPixmap
);
83 XmUninstallImage ((XImage
*) m_image
);
84 XtFree ((char *) (XImage
*) m_image
);
89 XmUninstallImage ((XImage
*) m_insensImage
);
90 delete[] ((XImage
*) m_insensImage
)->data
;
91 XtFree ((char *) (XImage
*) m_insensImage
);
93 if (m_pixmap
&& m_freePixmap
)
94 XFreePixmap ((Display
*) m_display
, (Pixmap
) m_pixmap
);
98 int screen
= DefaultScreen((Display
*) m_display
);
99 Colormap cmp
= DefaultColormap((Display
*) m_display
,screen
);
101 for(llp
= 0;llp
< m_freeColorsCount
;llp
++)
102 XFreeColors((Display
*) m_display
, cmp
, &m_freeColors
[llp
], 1, 0L);
111 wxList
wxBitmap::sm_handlers
;
117 if ( wxTheBitmapList
)
118 wxTheBitmapList
->AddBitmap(this);
121 wxBitmap::~wxBitmap()
124 wxTheBitmapList
->DeleteObject(this);
127 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
)
129 m_refData
= new wxBitmapRefData
;
131 (void) Create((void*) bits
, wxBITMAP_TYPE_XBM_DATA
, width
, height
, depth
);
133 if ( wxTheBitmapList
)
134 wxTheBitmapList
->AddBitmap(this);
137 wxBitmap::wxBitmap(int w
, int h
, int d
)
139 (void)Create(w
, h
, d
);
141 if ( wxTheBitmapList
)
142 wxTheBitmapList
->AddBitmap(this);
145 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
)
147 (void) Create(data
, type
, width
, height
, depth
);
149 if ( wxTheBitmapList
)
150 wxTheBitmapList
->AddBitmap(this);
153 wxBitmap::wxBitmap(const wxString
& filename
, long type
)
155 LoadFile(filename
, (int)type
);
157 if ( wxTheBitmapList
)
158 wxTheBitmapList
->AddBitmap(this);
161 // Create from XPM data
162 static wxControl
* sg_Control
= NULL
;
163 wxBitmap::wxBitmap(char **data
, wxControl
* control
)
165 // Pass the control to the Create function using a global
166 sg_Control
= control
;
168 (void) Create((void *)data
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
170 sg_Control
= (wxControl
*) NULL
;
173 bool wxBitmap::Create(int w
, int h
, int d
)
177 m_refData
= new wxBitmapRefData
;
180 d
= wxDisplayDepth();
182 M_BITMAPDATA
->m_width
= w
;
183 M_BITMAPDATA
->m_height
= h
;
184 M_BITMAPDATA
->m_depth
= d
;
185 M_BITMAPDATA
->m_freePixmap
= TRUE
;
187 Display
*dpy
= (Display
*) wxGetDisplay();
189 M_BITMAPDATA
->m_display
= dpy
; /* MATTHEW: [4] Remember the display */
191 M_BITMAPDATA
->m_pixmap
= (WXPixmap
) XCreatePixmap (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)),
194 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_pixmap
!= (WXPixmap
) 0) ;
195 return M_BITMAPDATA
->m_ok
;
198 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
202 m_refData
= new wxBitmapRefData
;
204 wxBitmapHandler
*handler
= FindHandler(type
);
206 if ( handler
== NULL
) {
208 if (!image
.LoadFile( filename
, type
)) return FALSE
;
211 *this = image
.ConvertToBitmap();
217 return handler
->LoadFile(this, filename
, type
, -1, -1);
220 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
)
224 m_refData
= new wxBitmapRefData
;
226 wxBitmapHandler
*handler
= FindHandler(type
);
228 if ( handler
== NULL
) {
229 wxLogWarning("no data bitmap handler for type %d defined.", type
);
234 return handler
->Create(this, data
, type
, width
, height
, depth
);
237 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette
*palette
)
239 wxBitmapHandler
*handler
= FindHandler(type
);
241 if ( handler
== NULL
) { // try wxImage
242 wxImage
image( *this );
243 if (image
.Ok()) return image
.SaveFile( filename
, type
);
247 return handler
->SaveFile(this, filename
, type
, palette
);
250 void wxBitmap::SetWidth(int w
)
253 m_refData
= new wxBitmapRefData
;
255 M_BITMAPDATA
->m_width
= w
;
258 void wxBitmap::SetHeight(int h
)
261 m_refData
= new wxBitmapRefData
;
263 M_BITMAPDATA
->m_height
= h
;
266 void wxBitmap::SetDepth(int d
)
269 m_refData
= new wxBitmapRefData
;
271 M_BITMAPDATA
->m_depth
= d
;
274 void wxBitmap::SetQuality(int q
)
277 m_refData
= new wxBitmapRefData
;
279 M_BITMAPDATA
->m_quality
= q
;
282 void wxBitmap::SetOk(bool isOk
)
285 m_refData
= new wxBitmapRefData
;
287 M_BITMAPDATA
->m_ok
= isOk
;
290 void wxBitmap::SetPalette(const wxPalette
& palette
)
293 m_refData
= new wxBitmapRefData
;
295 M_BITMAPDATA
->m_bitmapPalette
= palette
;
298 void wxBitmap::SetMask(wxMask
*mask
)
301 m_refData
= new wxBitmapRefData
;
303 M_BITMAPDATA
->m_bitmapMask
= mask
;
306 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
308 sm_handlers
.Append(handler
);
311 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
313 sm_handlers
.Insert(handler
);
316 bool wxBitmap::RemoveHandler(const wxString
& name
)
318 wxBitmapHandler
*handler
= FindHandler(name
);
321 sm_handlers
.DeleteObject(handler
);
328 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
330 wxNode
*node
= sm_handlers
.First();
333 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
334 if ( handler
->GetName() == name
)
341 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
)
343 wxNode
*node
= sm_handlers
.First();
346 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
347 if ( handler
->GetExtension() == extension
&&
348 (bitmapType
== -1 || handler
->GetType() == bitmapType
) )
355 wxBitmapHandler
*wxBitmap::FindHandler(long bitmapType
)
357 wxNode
*node
= sm_handlers
.First();
360 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
361 if (handler
->GetType() == bitmapType
)
374 m_pixmap
= (WXPixmap
) 0;
377 // Construct a mask from a bitmap and a colour indicating
378 // the transparent area
379 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
381 m_pixmap
= (WXPixmap
) 0;
383 Create(bitmap
, colour
);
386 // Construct a mask from a bitmap and a palette index indicating
387 // the transparent area
388 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
390 m_pixmap
= (WXPixmap
) 0;
392 Create(bitmap
, paletteIndex
);
395 // Construct a mask from a mono bitmap (copies the bitmap).
396 wxMask::wxMask(const wxBitmap
& bitmap
)
398 m_pixmap
= (WXPixmap
) 0;
405 // TODO: this may be the wrong display
407 XFreePixmap ((Display
*) wxGetDisplay(), (Pixmap
) m_pixmap
);
410 // Create a mask from a mono bitmap (copies the bitmap).
411 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
))
417 // Create a mask from a bitmap and a palette index indicating
418 // the transparent area
419 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
), int WXUNUSED(paletteIndex
))
425 // Create a mask from a bitmap and a colour indicating
426 // the transparent area
427 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
), const wxColour
& WXUNUSED(colour
))
437 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
439 bool wxBitmapHandler::Create(wxBitmap
*WXUNUSED(bitmap
), void *WXUNUSED(data
), long WXUNUSED(type
),
440 int WXUNUSED(width
), int WXUNUSED(height
), int WXUNUSED(depth
))
445 bool wxBitmapHandler::LoadFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), long WXUNUSED(type
),
446 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
451 bool wxBitmapHandler::SaveFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), int WXUNUSED(type
),
452 const wxPalette
*WXUNUSED(palette
))
461 class WXDLLEXPORT wxXBMFileHandler
: public wxBitmapHandler
463 DECLARE_DYNAMIC_CLASS(wxXBMFileHandler
)
465 inline wxXBMFileHandler()
469 m_type
= wxBITMAP_TYPE_XBM
;
472 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
473 int desiredWidth
, int desiredHeight
);
475 IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler
, wxBitmapHandler
)
477 bool wxXBMFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
478 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
480 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
486 Display
*dpy
= (Display
*) wxGetDisplay();
487 M_BITMAPDATA
->m_display
= (WXDisplay
*) dpy
;
489 int value
= XReadBitmapFile (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)),
490 (char*) (const char*) name
, &w
, &h
, &pixmap
, &hotX
, &hotY
);
491 M_BITMAPHANDLERDATA
->m_width
= w
;
492 M_BITMAPHANDLERDATA
->m_height
= h
;
493 M_BITMAPHANDLERDATA
->m_depth
= 1;
494 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
496 if ((value
== BitmapFileInvalid
) ||
497 (value
== BitmapOpenFailed
) ||
498 (value
== BitmapNoMemory
))
500 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
501 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) 0;
504 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
506 return M_BITMAPHANDLERDATA
->m_ok
;
509 class WXDLLEXPORT wxXBMDataHandler
: public wxBitmapHandler
511 DECLARE_DYNAMIC_CLASS(wxXBMDataHandler
)
513 inline wxXBMDataHandler()
517 m_type
= wxBITMAP_TYPE_XBM_DATA
;
520 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
522 IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler
, wxBitmapHandler
)
524 bool wxXBMDataHandler::Create( wxBitmap
*bitmap
, void *data
, long WXUNUSED(flags
),
525 int width
, int height
, int WXUNUSED(depth
))
527 M_BITMAPHANDLERDATA
->m_width
= width
;
528 M_BITMAPHANDLERDATA
->m_height
= height
;
529 M_BITMAPHANDLERDATA
->m_depth
= 1;
530 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
532 Display
*dpy
= (Display
*) wxGetDisplay();
533 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
535 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) XCreateBitmapFromData (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)), (char*) data
, width
, height
);
536 M_BITMAPHANDLERDATA
->m_ok
= (M_BITMAPHANDLERDATA
->m_pixmap
!= (WXPixmap
) 0) ;
538 // code for wxControl. TODO: can we avoid doing this until we need it?
539 // E.g. have CreateButtonPixmaps which is called on demand.
540 XImage
* image
= (XImage
*) XtMalloc (sizeof (XImage
));
541 image
->width
= width
;
542 image
->height
= height
;
543 image
->data
= (char*) data
;
546 image
->format
= XYBitmap
;
547 image
->byte_order
= LSBFirst
;
548 image
->bitmap_unit
= 8;
549 image
->bitmap_bit_order
= LSBFirst
;
550 image
->bitmap_pad
= 8;
551 image
->bytes_per_line
= (width
+ 7) >> 3;
554 sprintf (tmp
, "Im%x", (unsigned int) image
);
555 XmInstallImage (image
, tmp
);
557 // Build our manually stipped pixmap.
559 int bpl
= (width
+ 7) / 8;
560 char *data1
= new char[height
* bpl
];
561 char* bits
= (char*) data
;
563 for (i
= 0; i
< height
; i
++)
565 int mask
= i
% 2 ? 0x55 : 0xaa;
567 for (j
= 0; j
< bpl
; j
++)
568 data1
[i
* bpl
+ j
] = bits
[i
* bpl
+ j
] & mask
;
570 XImage
* insensImage
= (XImage
*) XtMalloc (sizeof (XImage
));
571 insensImage
->width
= width
;
572 insensImage
->height
= height
;
573 insensImage
->data
= data1
;
574 insensImage
->depth
= 1;
575 insensImage
->xoffset
= 0;
576 insensImage
->format
= XYBitmap
;
577 insensImage
->byte_order
= LSBFirst
;
578 insensImage
->bitmap_unit
= 8;
579 insensImage
->bitmap_bit_order
= LSBFirst
;
580 insensImage
->bitmap_pad
= 8;
581 insensImage
->bytes_per_line
= bpl
;
583 sprintf (tmp
, "Not%x", (unsigned int)insensImage
);
584 XmInstallImage (insensImage
, tmp
);
586 M_BITMAPHANDLERDATA
->m_image
= (WXImage
*) image
;
587 M_BITMAPHANDLERDATA
->m_insensImage
= (WXImage
*) insensImage
;
593 class WXDLLEXPORT wxXPMFileHandler
: public wxBitmapHandler
595 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler
)
597 inline wxXPMFileHandler()
601 m_type
= wxBITMAP_TYPE_XPM
;
604 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
605 int desiredWidth
, int desiredHeight
);
606 virtual bool SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
= NULL
);
609 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler
, wxBitmapHandler
)
611 bool wxXPMFileHandler::LoadFile( wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
612 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
) )
614 Display
*dpy
= (Display
*) wxGetDisplay();
615 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
617 XpmAttributes xpmAttr
;
621 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
622 xpmAttr
.valuemask
= XpmReturnInfos
| XpmCloseness
;
623 xpmAttr
.closeness
= 40000;
624 int errorStatus
= XpmReadFileToPixmap(dpy
,
625 RootWindow(dpy
, DefaultScreen(dpy
)), (char*) (const char*) name
,
626 &pixmap
, &mask
, &xpmAttr
);
628 if (errorStatus
== XpmSuccess
)
630 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
633 M_BITMAPHANDLERDATA
->m_bitmapMask
= new wxMask
;
634 M_BITMAPHANDLERDATA
->m_bitmapMask
->SetPixmap((WXPixmap
) mask
);
637 unsigned int depthRet
;
639 unsigned int widthRet
, heightRet
, borderWidthRet
;
640 Window rootWindowRet
;
641 XGetGeometry(dpy
, pixmap
, &rootWindowRet
, &xRet
, &yRet
,
642 &widthRet
, &heightRet
, &borderWidthRet
, &depthRet
);
644 M_BITMAPHANDLERDATA
->m_width
= xpmAttr
.width
;
645 M_BITMAPHANDLERDATA
->m_height
= xpmAttr
.height
;
648 if ( xpmAttr.npixels > 2 )
650 M_BITMAPHANDLERDATA->m_depth = 8; // TODO: next time not just a guess :-) ...
653 M_BITMAPHANDLERDATA->m_depth = 1; // mono
657 M_BITMAPHANDLERDATA
->m_depth
= depthRet
;
659 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
661 XpmFreeAttributes(&xpmAttr
);
663 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
667 // XpmDebugError(errorStatus, name);
668 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
673 bool wxXPMFileHandler::SaveFile( wxBitmap
*bitmap
, const wxString
& name
, int WXUNUSED(type
),
674 const wxPalette
*WXUNUSED(palette
))
676 if (M_BITMAPHANDLERDATA
->m_ok
&& M_BITMAPHANDLERDATA
->m_pixmap
)
678 Display
*dpy
= (Display
*) M_BITMAPHANDLERDATA
->m_display
;
679 int errorStatus
= XpmWriteFileFromPixmap(dpy
, (char*) (const char*) name
,
680 (Pixmap
) M_BITMAPHANDLERDATA
->m_pixmap
,
681 (M_BITMAPHANDLERDATA
->m_bitmapMask
? (Pixmap
) M_BITMAPHANDLERDATA
->m_bitmapMask
->GetPixmap() : (Pixmap
) 0),
682 (XpmAttributes
*) NULL
);
683 if (errorStatus
== XpmSuccess
)
692 class WXDLLEXPORT wxXPMDataHandler
: public wxBitmapHandler
694 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler
)
696 inline wxXPMDataHandler()
700 m_type
= wxBITMAP_TYPE_XPM_DATA
;
703 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
705 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler
, wxBitmapHandler
)
707 bool wxXPMDataHandler::Create( wxBitmap
*bitmap
, void *data
, long WXUNUSED(flags
),
708 int width
, int height
, int WXUNUSED(depth
))
710 M_BITMAPHANDLERDATA
->m_width
= width
;
711 M_BITMAPHANDLERDATA
->m_height
= height
;
712 M_BITMAPHANDLERDATA
->m_depth
= 1;
713 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
715 Display
*dpy
= (Display
*) wxGetDisplay();
716 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
718 XpmAttributes xpmAttr
;
720 xpmAttr
.valuemask
= XpmReturnInfos
; /* nothing yet, but get infos back */
722 XpmColorSymbol symbolicColors
[4];
723 if (sg_Control
&& sg_Control
->GetMainWidget())
725 symbolicColors
[0].name
= "foreground";
726 symbolicColors
[0].value
= NULL
;
727 symbolicColors
[1].name
= "background";
728 symbolicColors
[1].value
= NULL
;
729 XtVaGetValues((Widget
) sg_Control
->GetMainWidget(),
730 XmNforeground
, &symbolicColors
[0].pixel
,
731 XmNbackground
, &symbolicColors
[1].pixel
,NULL
);
732 xpmAttr
.numsymbols
= 2;
733 xpmAttr
.colorsymbols
= symbolicColors
;
734 xpmAttr
.valuemask
|= XpmColorSymbols
; // add flag
739 int ErrorStatus
= XpmCreatePixmapFromData(dpy
, RootWindow(dpy
, DefaultScreen(dpy
)),
740 (char**) data
, &pixmap
, &mask
, &xpmAttr
);
741 if (ErrorStatus
== XpmSuccess
)
744 M_BITMAPHANDLERDATA
->m_width
= xpmAttr
.width
;
745 M_BITMAPHANDLERDATA
->m_height
= xpmAttr
.height
;
747 unsigned int depthRet
;
749 unsigned int widthRet
, heightRet
, borderWidthRet
;
750 Window rootWindowRet
;
751 XGetGeometry(dpy
, pixmap
, &rootWindowRet
, &xRet
, &yRet
,
752 &widthRet
, &heightRet
, &borderWidthRet
, &depthRet
);
755 if ( xpmAttr.npixels > 2 )
757 M_BITMAPHANDLERDATA->m_depth = 8; // next time not just a guess :-) ...
760 M_BITMAPHANDLERDATA->m_depth = 1; // mono
764 M_BITMAPHANDLERDATA
->m_depth
= depthRet
;
766 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
767 XpmFreeAttributes(&xpmAttr
);
768 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
769 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
772 M_BITMAPHANDLERDATA
->m_bitmapMask
= new wxMask
;
773 M_BITMAPHANDLERDATA
->m_bitmapMask
->SetPixmap((WXPixmap
) mask
);
778 // XpmDebugError(ErrorStatus, NULL);
779 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
781 return M_BITMAPHANDLERDATA
->m_ok
;
784 #endif // wxHAVE_LIB_XPM
786 void wxBitmap::CleanUpHandlers()
788 wxNode
*node
= sm_handlers
.First();
791 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
792 wxNode
*next
= node
->Next();
799 void wxBitmap::InitStandardHandlers()
801 // Initialize all standard bitmap or derived class handlers here.
802 AddHandler(new wxXBMFileHandler
);
803 AddHandler(new wxXBMDataHandler
);
805 // XPM is considered standard for Motif, although it can be omitted if
806 // libXpm is not installed
808 AddHandler(new wxXPMFileHandler
);
809 AddHandler(new wxXPMDataHandler
);
810 #endif // wxHAVE_LIB_XPM
813 WXPixmap
wxBitmap::GetLabelPixmap (WXWidget w
)
815 if (M_BITMAPDATA
->m_image
== (WXPixmap
) 0)
816 return M_BITMAPDATA
->m_pixmap
;
818 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
823 if (labelPixmap) return labelPixmap;
824 things can be wrong, because colors can have been changed.
828 XmDestroyPixmap(DefaultScreenOfDisplay(dpy),labelPixmap) ;
829 we got BadDrawable if the pixmap is referenced by multiples widgets
833 So, before doing thing really clean, I just do nothing; if the pixmap is
834 referenced by many widgets, Motif performs caching functions.
835 And if pixmap is referenced with multiples colors, we just have some
836 memory leaks... I hope we can deal with them...
838 // Must be destroyed, because colours can have been changed!
839 if (M_BITMAPDATA
->m_labelPixmap
)
840 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), M_BITMAPDATA
->m_labelPixmap
);
844 sprintf (tmp
, "Im%x", (unsigned int) M_BITMAPDATA
->m_image
);
847 Widget widget
= (Widget
) w
;
849 while (XmIsGadget ( widget
))
850 widget
= XtParent (widget
);
851 XtVaGetValues (widget
, XmNbackground
, &bg
, XmNforeground
, &fg
, NULL
);
853 M_BITMAPDATA
->m_labelPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
855 return M_BITMAPDATA
->m_labelPixmap
;
858 WXPixmap
wxBitmap::GetArmPixmap (WXWidget w
)
860 if (M_BITMAPDATA
->m_image
== (WXPixmap
) 0)
861 return M_BITMAPDATA
->m_pixmap
;
863 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
865 See
GetLabelPixmap () comment
866 // Must be destroyed, because colours can have been changed!
867 if (M_BITMAPDATA
->m_armPixmap
)
868 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), M_BITMAPDATA
->m_armPixmap
);
872 sprintf (tmp
, "Im%x", (unsigned int) M_BITMAPDATA
->m_image
);
875 Widget widget
= (Widget
) w
;
877 XtVaGetValues (widget
, XmNarmColor
, &bg
, NULL
);
878 while (XmIsGadget (widget
))
879 widget
= XtParent (widget
);
880 XtVaGetValues (widget
, XmNforeground
, &fg
, NULL
);
882 M_BITMAPDATA
->m_armPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
884 return M_BITMAPDATA
->m_armPixmap
;
887 WXPixmap
wxBitmap::GetInsensPixmap (WXWidget w
)
889 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
891 if (M_BITMAPDATA
->m_insensPixmap
)
892 return M_BITMAPDATA
->m_insensPixmap
;
896 M_BITMAPDATA
->m_insensPixmap
= (WXPixmap
) XCreateInsensitivePixmap(dpy
, (Pixmap
) M_BITMAPDATA
->m_pixmap
);
897 if (M_BITMAPDATA
->m_insensPixmap
)
898 return M_BITMAPDATA
->m_insensPixmap
;
900 return M_BITMAPDATA
->m_pixmap
;
903 if (M_BITMAPDATA
->m_insensImage
== (WXPixmap
) 0)
904 return M_BITMAPDATA
->m_pixmap
;
907 See
GetLabelPixmap () comment
908 // Must be destroyed, because colours can have been changed!
909 if (M_BITMAPDATA
->m_insensPixmap
)
910 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), (Pixmap
) M_BITMAPDATA
->m_insensPixmap
);
914 sprintf (tmp
, "Not%x", (unsigned int) M_BITMAPDATA
->m_insensImage
);
917 Widget widget
= (Widget
) w
;
919 while (XmIsGadget (widget
))
920 widget
= XtParent (widget
);
921 XtVaGetValues (widget
, XmNbackground
, &bg
, XmNforeground
, &fg
, NULL
);
923 M_BITMAPDATA
->m_insensPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
925 return M_BITMAPDATA
->m_insensPixmap
;
928 // We may need this sometime...
930 /****************************************************************************
933 XCreateInsensitivePixmap - create a grayed-out copy of a pixmap
936 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
939 This function creates a grayed-out copy of the argument pixmap, suitable
940 for use as a XmLabel's XmNlabelInsensitivePixmap resource.
943 The return value is the new Pixmap id or zero on error. Errors include
944 a NULL display argument or an invalid Pixmap argument.
947 If one of the XLib functions fail, it will produce a X error. The
948 default X error handler prints a diagnostic and calls exit().
951 XCopyArea(3), XCreateBitmapFromData(3), XCreateGC(3), XCreatePixmap(3),
952 XFillRectangle(3), exit(2)
955 John R Veregge - john@puente.jpl.nasa.gov
956 Advanced Engineering and Prototyping Group (AEG)
957 Information Systems Technology Section (395)
958 Jet Propulsion Lab - Calif Institute of Technology
960 *****************************************************************************/
963 XCreateInsensitivePixmap( Display
*display
, Pixmap pixmap
)
967 char stipple_data
[] =
969 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
970 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
971 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
972 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA
975 Pixmap ipixmap
, stipple
;
976 unsigned width
, height
, depth
;
978 Window window
; /* These return values */
979 unsigned border
; /* from XGetGeometry() */
980 int x
, y
; /* are not needed. */
984 if ( NULL
== display
|| 0 == pixmap
)
987 if ( 0 == XGetGeometry( display
, pixmap
, &window
, &x
, &y
,
988 &width
, &height
, &border
, &depth
)
990 return ipixmap
; /* BadDrawable: probably an invalid pixmap */
992 /* Get the stipple pixmap to be used to 'gray-out' the argument pixmap.
994 stipple
= XCreateBitmapFromData( display
, pixmap
, stipple_data
, 16, 16 );
997 gc
= XCreateGC( display
, pixmap
, (XtGCMask
)0, (XGCValues
*)NULL
);
1000 /* Create an identical copy of the argument pixmap.
1002 ipixmap
= XCreatePixmap( display
, pixmap
, width
, height
, depth
);
1005 /* Copy the argument pixmap into the new pixmap.
1007 XCopyArea( display
, pixmap
, ipixmap
,
1008 gc
, 0, 0, width
, height
, 0, 0 );
1010 /* Refill the new pixmap using the stipple algorithm/pixmap.
1012 XSetStipple( display
, gc
, stipple
);
1013 XSetFillStyle( display
, gc
, FillStippled
);
1014 XFillRectangle( display
, ipixmap
, gc
, 0, 0, width
, height
);
1016 XFreeGC( display
, gc
);
1018 XFreePixmap( display
, stipple
);
1023 // Creates a bitmap with transparent areas drawn in
1024 // the given colour.
1025 wxBitmap
wxCreateMaskedBitmap(wxBitmap
& bitmap
, wxColour
& colour
)
1027 wxBitmap
newBitmap(bitmap
.GetWidth(),
1032 srcDC
.SelectObject(bitmap
);
1033 destDC
.SelectObject(newBitmap
);
1035 wxBrush
brush(colour
, wxSOLID
);
1036 destDC
.SetOptimization(FALSE
);
1037 destDC
.SetBackground(brush
);
1039 destDC
.Blit(0, 0, bitmap
.GetWidth(), bitmap
.GetHeight(), & srcDC
, 0, 0, wxCOPY
, TRUE
);