1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bitmap.h"
17 #define XtParent XTPARENT
22 #include "wx/palette.h"
23 #include "wx/bitmap.h"
26 #include "wx/control.h"
27 #include "wx/dcmemory.h"
32 #pragma message disable nosimpint
36 #pragma message enable nosimpint
39 #include "wx/motif/private.h"
47 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
48 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
50 wxBitmapRefData::wxBitmapRefData()
60 m_pixmap
= (WXPixmap
) 0;
61 m_display
= (WXDisplay
*) 0;
63 m_freePixmap
= TRUE
; //TODO: necessary?
64 m_freeColors
= (unsigned long*) 0;
65 m_freeColorsCount
= 0;
67 // These 5 variables are for wxControl
68 m_insensPixmap
= (WXPixmap
) 0;
69 m_labelPixmap
= (WXPixmap
) 0;
70 m_armPixmap
= (WXPixmap
) 0;
71 m_image
= (WXImage
*) 0;
72 m_insensImage
= (WXImage
*) 0;
75 wxBitmapRefData::~wxBitmapRefData()
78 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_labelPixmap
);
81 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_armPixmap
);
84 XmDestroyPixmap (DefaultScreenOfDisplay ((Display
*) m_display
), (Pixmap
) m_insensPixmap
);
88 XmUninstallImage ((XImage
*) m_image
);
89 XtFree ((char *) (XImage
*) m_image
);
94 XmUninstallImage ((XImage
*) m_insensImage
);
95 delete[] ((XImage
*) m_insensImage
)->data
;
96 XtFree ((char *) (XImage
*) m_insensImage
);
98 if (m_pixmap
&& m_freePixmap
)
99 XFreePixmap ((Display
*) m_display
, (Pixmap
) m_pixmap
);
103 int screen
= DefaultScreen((Display
*) m_display
);
104 Colormap cmp
= DefaultColormap((Display
*) m_display
,screen
);
106 for(llp
= 0;llp
< m_freeColorsCount
;llp
++)
107 XFreeColors((Display
*) m_display
, cmp
, &m_freeColors
[llp
], 1, 0L);
116 wxList
wxBitmap::sm_handlers
;
118 #define M_BMPDATA ((wxBitmapRefData *)m_refData)
124 if ( wxTheBitmapList
)
125 wxTheBitmapList
->AddBitmap(this);
128 wxBitmap::~wxBitmap()
131 wxTheBitmapList
->DeleteObject(this);
134 wxBitmap::wxBitmap(const char bits
[], int width
, int height
, int depth
)
136 m_refData
= new wxBitmapRefData
;
138 (void) Create((void*) bits
, wxBITMAP_TYPE_XBM_DATA
, width
, height
, depth
);
140 if ( wxTheBitmapList
)
141 wxTheBitmapList
->AddBitmap(this);
144 wxBitmap::wxBitmap(int w
, int h
, int d
)
146 (void)Create(w
, h
, d
);
148 if ( wxTheBitmapList
)
149 wxTheBitmapList
->AddBitmap(this);
152 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
)
154 (void) Create(data
, type
, width
, height
, depth
);
156 if ( wxTheBitmapList
)
157 wxTheBitmapList
->AddBitmap(this);
160 wxBitmap::wxBitmap(const wxString
& filename
, long type
)
162 LoadFile(filename
, (int)type
);
164 if ( wxTheBitmapList
)
165 wxTheBitmapList
->AddBitmap(this);
168 // Create from XPM data
169 static wxControl
* sg_Control
= NULL
;
170 wxBitmap::wxBitmap(char **data
, wxControl
* control
)
172 // Pass the control to the Create function using a global
173 sg_Control
= control
;
175 (void) Create((void *)data
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
177 sg_Control
= (wxControl
*) NULL
;
180 bool wxBitmap::CreateFromXpm(const char **bits
)
182 wxCHECK_MSG( bits
, FALSE
, _T("NULL pointer in wxBitmap::CreateFromXpm") );
184 return Create(bits
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
187 bool wxBitmap::Create(int w
, int h
, int d
)
191 m_refData
= new wxBitmapRefData
;
194 d
= wxDisplayDepth();
196 M_BITMAPDATA
->m_width
= w
;
197 M_BITMAPDATA
->m_height
= h
;
198 M_BITMAPDATA
->m_depth
= d
;
199 M_BITMAPDATA
->m_freePixmap
= TRUE
;
201 Display
*dpy
= (Display
*) wxGetDisplay();
203 M_BITMAPDATA
->m_display
= dpy
; /* MATTHEW: [4] Remember the display */
205 M_BITMAPDATA
->m_pixmap
= (WXPixmap
) XCreatePixmap (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)),
208 M_BITMAPDATA
->m_ok
= (M_BITMAPDATA
->m_pixmap
!= (WXPixmap
) 0) ;
209 return M_BITMAPDATA
->m_ok
;
212 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
216 m_refData
= new wxBitmapRefData
;
218 wxBitmapHandler
*handler
= FindHandler(type
);
220 if ( handler
== NULL
) {
222 if (!image
.LoadFile( filename
, type
)) return FALSE
;
225 *this = image
.ConvertToBitmap();
231 return handler
->LoadFile(this, filename
, type
, -1, -1);
234 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
)
238 m_refData
= new wxBitmapRefData
;
240 wxBitmapHandler
*handler
= FindHandler(type
);
242 if ( handler
== NULL
) {
243 wxLogWarning("no data bitmap handler for type %d defined.", type
);
248 return handler
->Create(this, data
, type
, width
, height
, depth
);
251 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette
*palette
)
253 wxBitmapHandler
*handler
= FindHandler(type
);
255 if ( handler
== NULL
) { // try wxImage
256 wxImage
image( *this );
257 if (image
.Ok()) return image
.SaveFile( filename
, type
);
261 return handler
->SaveFile(this, filename
, type
, palette
);
264 void wxBitmap::SetWidth(int w
)
267 m_refData
= new wxBitmapRefData
;
269 M_BITMAPDATA
->m_width
= w
;
272 void wxBitmap::SetHeight(int h
)
275 m_refData
= new wxBitmapRefData
;
277 M_BITMAPDATA
->m_height
= h
;
280 void wxBitmap::SetDepth(int d
)
283 m_refData
= new wxBitmapRefData
;
285 M_BITMAPDATA
->m_depth
= d
;
288 void wxBitmap::SetQuality(int q
)
291 m_refData
= new wxBitmapRefData
;
293 M_BITMAPDATA
->m_quality
= q
;
296 void wxBitmap::SetOk(bool isOk
)
299 m_refData
= new wxBitmapRefData
;
301 M_BITMAPDATA
->m_ok
= isOk
;
304 void wxBitmap::SetPalette(const wxPalette
& palette
)
307 m_refData
= new wxBitmapRefData
;
309 M_BITMAPDATA
->m_bitmapPalette
= palette
;
312 void wxBitmap::SetMask(wxMask
*mask
)
315 m_refData
= new wxBitmapRefData
;
317 M_BITMAPDATA
->m_bitmapMask
= mask
;
320 wxBitmap
wxBitmap::GetSubBitmap( const wxRect
& rect
) const
323 (rect
.x
>= 0) && (rect
.y
>= 0) &&
324 (rect
.x
+rect
.width
<= M_BMPDATA
->m_width
) && (rect
.y
+rect
.height
<= M_BMPDATA
->m_height
),
325 wxNullBitmap
, wxT("invalid bitmap or bitmap region") );
327 wxBitmap
ret( rect
.width
, rect
.height
, 0 );
328 wxASSERT_MSG( ret
.Ok(), wxT("GetSubBitmap error") );
330 // The remaining still TODO
334 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
336 sm_handlers
.Append(handler
);
339 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
341 sm_handlers
.Insert(handler
);
344 bool wxBitmap::RemoveHandler(const wxString
& name
)
346 wxBitmapHandler
*handler
= FindHandler(name
);
349 sm_handlers
.DeleteObject(handler
);
356 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
358 wxNode
*node
= sm_handlers
.First();
361 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
362 if ( handler
->GetName() == name
)
369 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
)
371 wxNode
*node
= sm_handlers
.First();
374 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
375 if ( handler
->GetExtension() == extension
&&
376 (bitmapType
== -1 || handler
->GetType() == bitmapType
) )
383 wxBitmapHandler
*wxBitmap::FindHandler(long bitmapType
)
385 wxNode
*node
= sm_handlers
.First();
388 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
389 if (handler
->GetType() == bitmapType
)
402 m_pixmap
= (WXPixmap
) 0;
405 // Construct a mask from a bitmap and a colour indicating
406 // the transparent area
407 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
409 m_pixmap
= (WXPixmap
) 0;
411 Create(bitmap
, colour
);
414 // Construct a mask from a bitmap and a palette index indicating
415 // the transparent area
416 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
418 m_pixmap
= (WXPixmap
) 0;
420 Create(bitmap
, paletteIndex
);
423 // Construct a mask from a mono bitmap (copies the bitmap).
424 wxMask::wxMask(const wxBitmap
& bitmap
)
426 m_pixmap
= (WXPixmap
) 0;
433 // TODO: this may be the wrong display
435 XFreePixmap ((Display
*) wxGetDisplay(), (Pixmap
) m_pixmap
);
438 // Create a mask from a mono bitmap (copies the bitmap).
439 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
))
445 // Create a mask from a bitmap and a palette index indicating
446 // the transparent area
447 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
), int WXUNUSED(paletteIndex
))
453 // Create a mask from a bitmap and a colour indicating
454 // the transparent area
455 bool wxMask::Create(const wxBitmap
& WXUNUSED(bitmap
), const wxColour
& WXUNUSED(colour
))
465 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
467 bool wxBitmapHandler::Create(wxBitmap
*WXUNUSED(bitmap
), void *WXUNUSED(data
), long WXUNUSED(type
),
468 int WXUNUSED(width
), int WXUNUSED(height
), int WXUNUSED(depth
))
473 bool wxBitmapHandler::LoadFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), long WXUNUSED(type
),
474 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
479 bool wxBitmapHandler::SaveFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), int WXUNUSED(type
),
480 const wxPalette
*WXUNUSED(palette
))
489 class WXDLLEXPORT wxXBMFileHandler
: public wxBitmapHandler
491 DECLARE_DYNAMIC_CLASS(wxXBMFileHandler
)
493 inline wxXBMFileHandler()
497 m_type
= wxBITMAP_TYPE_XBM
;
500 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
501 int desiredWidth
, int desiredHeight
);
503 IMPLEMENT_DYNAMIC_CLASS(wxXBMFileHandler
, wxBitmapHandler
)
505 bool wxXBMFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
506 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
508 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
514 Display
*dpy
= (Display
*) wxGetDisplay();
515 M_BITMAPDATA
->m_display
= (WXDisplay
*) dpy
;
517 int value
= XReadBitmapFile (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)),
518 (char*) (const char*) name
, &w
, &h
, &pixmap
, &hotX
, &hotY
);
519 M_BITMAPHANDLERDATA
->m_width
= w
;
520 M_BITMAPHANDLERDATA
->m_height
= h
;
521 M_BITMAPHANDLERDATA
->m_depth
= 1;
522 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
524 if ((value
== BitmapFileInvalid
) ||
525 (value
== BitmapOpenFailed
) ||
526 (value
== BitmapNoMemory
))
528 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
529 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) 0;
532 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
534 return M_BITMAPHANDLERDATA
->m_ok
;
537 class WXDLLEXPORT wxXBMDataHandler
: public wxBitmapHandler
539 DECLARE_DYNAMIC_CLASS(wxXBMDataHandler
)
541 inline wxXBMDataHandler()
545 m_type
= wxBITMAP_TYPE_XBM_DATA
;
548 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
550 IMPLEMENT_DYNAMIC_CLASS(wxXBMDataHandler
, wxBitmapHandler
)
552 bool wxXBMDataHandler::Create( wxBitmap
*bitmap
, void *data
, long WXUNUSED(flags
),
553 int width
, int height
, int WXUNUSED(depth
))
555 M_BITMAPHANDLERDATA
->m_width
= width
;
556 M_BITMAPHANDLERDATA
->m_height
= height
;
557 M_BITMAPHANDLERDATA
->m_depth
= 1;
558 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
560 Display
*dpy
= (Display
*) wxGetDisplay();
561 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
563 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) XCreateBitmapFromData (dpy
, RootWindow (dpy
, DefaultScreen (dpy
)), (char*) data
, width
, height
);
564 M_BITMAPHANDLERDATA
->m_ok
= (M_BITMAPHANDLERDATA
->m_pixmap
!= (WXPixmap
) 0) ;
566 // code for wxControl. TODO: can we avoid doing this until we need it?
567 // E.g. have CreateButtonPixmaps which is called on demand.
568 XImage
* image
= (XImage
*) XtMalloc (sizeof (XImage
));
569 image
->width
= width
;
570 image
->height
= height
;
571 image
->data
= (char*) data
;
574 image
->format
= XYBitmap
;
575 image
->byte_order
= LSBFirst
;
576 image
->bitmap_unit
= 8;
577 image
->bitmap_bit_order
= LSBFirst
;
578 image
->bitmap_pad
= 8;
579 image
->bytes_per_line
= (width
+ 7) >> 3;
582 sprintf (tmp
, "Im%x", (unsigned int) image
);
583 XmInstallImage (image
, tmp
);
585 // Build our manually stipped pixmap.
587 int bpl
= (width
+ 7) / 8;
588 char *data1
= new char[height
* bpl
];
589 char* bits
= (char*) data
;
591 for (i
= 0; i
< height
; i
++)
593 int mask
= i
% 2 ? 0x55 : 0xaa;
595 for (j
= 0; j
< bpl
; j
++)
596 data1
[i
* bpl
+ j
] = bits
[i
* bpl
+ j
] & mask
;
598 XImage
* insensImage
= (XImage
*) XtMalloc (sizeof (XImage
));
599 insensImage
->width
= width
;
600 insensImage
->height
= height
;
601 insensImage
->data
= data1
;
602 insensImage
->depth
= 1;
603 insensImage
->xoffset
= 0;
604 insensImage
->format
= XYBitmap
;
605 insensImage
->byte_order
= LSBFirst
;
606 insensImage
->bitmap_unit
= 8;
607 insensImage
->bitmap_bit_order
= LSBFirst
;
608 insensImage
->bitmap_pad
= 8;
609 insensImage
->bytes_per_line
= bpl
;
611 sprintf (tmp
, "Not%x", (unsigned int)insensImage
);
612 XmInstallImage (insensImage
, tmp
);
614 M_BITMAPHANDLERDATA
->m_image
= (WXImage
*) image
;
615 M_BITMAPHANDLERDATA
->m_insensImage
= (WXImage
*) insensImage
;
621 class WXDLLEXPORT wxXPMFileHandler
: public wxBitmapHandler
623 DECLARE_DYNAMIC_CLASS(wxXPMFileHandler
)
625 inline wxXPMFileHandler()
629 m_type
= wxBITMAP_TYPE_XPM
;
632 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
633 int desiredWidth
, int desiredHeight
);
634 virtual bool SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
= NULL
);
637 IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler
, wxBitmapHandler
)
639 bool wxXPMFileHandler::LoadFile( wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
640 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
) )
642 Display
*dpy
= (Display
*) wxGetDisplay();
643 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
645 XpmAttributes xpmAttr
;
649 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
650 xpmAttr
.valuemask
= XpmReturnInfos
| XpmCloseness
;
651 xpmAttr
.closeness
= 40000;
652 int errorStatus
= XpmReadFileToPixmap(dpy
,
653 RootWindow(dpy
, DefaultScreen(dpy
)), (char*) (const char*) name
,
654 &pixmap
, &mask
, &xpmAttr
);
656 if (errorStatus
== XpmSuccess
)
658 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
661 M_BITMAPHANDLERDATA
->m_bitmapMask
= new wxMask
;
662 M_BITMAPHANDLERDATA
->m_bitmapMask
->SetPixmap((WXPixmap
) mask
);
665 unsigned int depthRet
;
667 unsigned int widthRet
, heightRet
, borderWidthRet
;
668 Window rootWindowRet
;
669 XGetGeometry(dpy
, pixmap
, &rootWindowRet
, &xRet
, &yRet
,
670 &widthRet
, &heightRet
, &borderWidthRet
, &depthRet
);
672 M_BITMAPHANDLERDATA
->m_width
= xpmAttr
.width
;
673 M_BITMAPHANDLERDATA
->m_height
= xpmAttr
.height
;
676 if ( xpmAttr.npixels > 2 )
678 M_BITMAPHANDLERDATA->m_depth = 8; // TODO: next time not just a guess :-) ...
681 M_BITMAPHANDLERDATA->m_depth = 1; // mono
685 M_BITMAPHANDLERDATA
->m_depth
= depthRet
;
687 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
689 XpmFreeAttributes(&xpmAttr
);
691 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
695 // XpmDebugError(errorStatus, name);
696 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
701 bool wxXPMFileHandler::SaveFile( wxBitmap
*bitmap
, const wxString
& name
, int WXUNUSED(type
),
702 const wxPalette
*WXUNUSED(palette
))
704 if (M_BITMAPHANDLERDATA
->m_ok
&& M_BITMAPHANDLERDATA
->m_pixmap
)
706 Display
*dpy
= (Display
*) M_BITMAPHANDLERDATA
->m_display
;
707 int errorStatus
= XpmWriteFileFromPixmap(dpy
, (char*) (const char*) name
,
708 (Pixmap
) M_BITMAPHANDLERDATA
->m_pixmap
,
709 (M_BITMAPHANDLERDATA
->m_bitmapMask
? (Pixmap
) M_BITMAPHANDLERDATA
->m_bitmapMask
->GetPixmap() : (Pixmap
) 0),
710 (XpmAttributes
*) NULL
);
711 if (errorStatus
== XpmSuccess
)
720 class WXDLLEXPORT wxXPMDataHandler
: public wxBitmapHandler
722 DECLARE_DYNAMIC_CLASS(wxXPMDataHandler
)
724 inline wxXPMDataHandler()
728 m_type
= wxBITMAP_TYPE_XPM_DATA
;
731 virtual bool Create(wxBitmap
*bitmap
, void *data
, long flags
, int width
, int height
, int depth
= 1);
733 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler
, wxBitmapHandler
)
735 bool wxXPMDataHandler::Create( wxBitmap
*bitmap
, void *data
, long WXUNUSED(flags
),
736 int width
, int height
, int WXUNUSED(depth
))
738 M_BITMAPHANDLERDATA
->m_width
= width
;
739 M_BITMAPHANDLERDATA
->m_height
= height
;
740 M_BITMAPHANDLERDATA
->m_depth
= 1;
741 M_BITMAPHANDLERDATA
->m_freePixmap
= TRUE
;
743 Display
*dpy
= (Display
*) wxGetDisplay();
744 M_BITMAPHANDLERDATA
->m_display
= (WXDisplay
*) dpy
;
746 XpmAttributes xpmAttr
;
748 xpmAttr
.valuemask
= XpmReturnInfos
; /* nothing yet, but get infos back */
750 XpmColorSymbol symbolicColors
[4];
751 if (sg_Control
&& sg_Control
->GetMainWidget())
753 symbolicColors
[0].name
= "foreground";
754 symbolicColors
[0].value
= NULL
;
755 symbolicColors
[1].name
= "background";
756 symbolicColors
[1].value
= NULL
;
757 XtVaGetValues((Widget
) sg_Control
->GetMainWidget(),
758 XmNforeground
, &symbolicColors
[0].pixel
,
759 XmNbackground
, &symbolicColors
[1].pixel
,NULL
);
760 xpmAttr
.numsymbols
= 2;
761 xpmAttr
.colorsymbols
= symbolicColors
;
762 xpmAttr
.valuemask
|= XpmColorSymbols
; // add flag
767 int ErrorStatus
= XpmCreatePixmapFromData(dpy
, RootWindow(dpy
, DefaultScreen(dpy
)),
768 (char**) data
, &pixmap
, &mask
, &xpmAttr
);
769 if (ErrorStatus
== XpmSuccess
)
772 M_BITMAPHANDLERDATA
->m_width
= xpmAttr
.width
;
773 M_BITMAPHANDLERDATA
->m_height
= xpmAttr
.height
;
775 unsigned int depthRet
;
777 unsigned int widthRet
, heightRet
, borderWidthRet
;
778 Window rootWindowRet
;
779 XGetGeometry(dpy
, pixmap
, &rootWindowRet
, &xRet
, &yRet
,
780 &widthRet
, &heightRet
, &borderWidthRet
, &depthRet
);
783 if ( xpmAttr.npixels > 2 )
785 M_BITMAPHANDLERDATA->m_depth = 8; // next time not just a guess :-) ...
788 M_BITMAPHANDLERDATA->m_depth = 1; // mono
792 M_BITMAPHANDLERDATA
->m_depth
= depthRet
;
794 M_BITMAPHANDLERDATA
->m_numColors
= xpmAttr
.npixels
;
795 XpmFreeAttributes(&xpmAttr
);
796 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
797 M_BITMAPHANDLERDATA
->m_pixmap
= (WXPixmap
) pixmap
;
800 M_BITMAPHANDLERDATA
->m_bitmapMask
= new wxMask
;
801 M_BITMAPHANDLERDATA
->m_bitmapMask
->SetPixmap((WXPixmap
) mask
);
806 // XpmDebugError(ErrorStatus, NULL);
807 M_BITMAPHANDLERDATA
->m_ok
= FALSE
;
809 return M_BITMAPHANDLERDATA
->m_ok
;
812 #endif // wxHAVE_LIB_XPM
814 void wxBitmap::CleanUpHandlers()
816 wxNode
*node
= sm_handlers
.First();
819 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
820 wxNode
*next
= node
->Next();
827 void wxBitmap::InitStandardHandlers()
829 // Initialize all standard bitmap or derived class handlers here.
830 AddHandler(new wxXBMFileHandler
);
831 AddHandler(new wxXBMDataHandler
);
833 // XPM is considered standard for Motif, although it can be omitted if
834 // libXpm is not installed
836 AddHandler(new wxXPMFileHandler
);
837 AddHandler(new wxXPMDataHandler
);
838 #endif // wxHAVE_LIB_XPM
841 WXPixmap
wxBitmap::GetLabelPixmap (WXWidget w
)
843 if (M_BITMAPDATA
->m_image
== (WXPixmap
) 0)
844 return M_BITMAPDATA
->m_pixmap
;
846 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
851 if (labelPixmap) return labelPixmap;
852 things can be wrong, because colors can have been changed.
856 XmDestroyPixmap(DefaultScreenOfDisplay(dpy),labelPixmap) ;
857 we got BadDrawable if the pixmap is referenced by multiples widgets
861 So, before doing thing really clean, I just do nothing; if the pixmap is
862 referenced by many widgets, Motif performs caching functions.
863 And if pixmap is referenced with multiples colors, we just have some
864 memory leaks... I hope we can deal with them...
866 // Must be destroyed, because colours can have been changed!
867 if (M_BITMAPDATA
->m_labelPixmap
)
868 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), M_BITMAPDATA
->m_labelPixmap
);
872 sprintf (tmp
, "Im%x", (unsigned int) M_BITMAPDATA
->m_image
);
875 Widget widget
= (Widget
) w
;
877 while (XmIsGadget ( widget
))
878 widget
= XtParent (widget
);
879 XtVaGetValues (widget
, XmNbackground
, &bg
, XmNforeground
, &fg
, NULL
);
881 M_BITMAPDATA
->m_labelPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
883 return M_BITMAPDATA
->m_labelPixmap
;
886 WXPixmap
wxBitmap::GetArmPixmap (WXWidget w
)
888 if (M_BITMAPDATA
->m_image
== (WXPixmap
) 0)
889 return M_BITMAPDATA
->m_pixmap
;
891 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
893 // See GetLabelPixmap () comment
895 // Must be destroyed, because colours can have been changed!
896 if (M_BITMAPDATA
->m_armPixmap
)
897 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), M_BITMAPDATA
->m_armPixmap
);
901 sprintf (tmp
, "Im%x", (unsigned int) M_BITMAPDATA
->m_image
);
904 Widget widget
= (Widget
) w
;
906 XtVaGetValues (widget
, XmNarmColor
, &bg
, NULL
);
907 while (XmIsGadget (widget
))
908 widget
= XtParent (widget
);
909 XtVaGetValues (widget
, XmNforeground
, &fg
, NULL
);
911 M_BITMAPDATA
->m_armPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
913 return M_BITMAPDATA
->m_armPixmap
;
916 WXPixmap
wxBitmap::GetInsensPixmap (WXWidget w
)
918 Display
*dpy
= (Display
*) M_BITMAPDATA
->m_display
;
920 if (M_BITMAPDATA
->m_insensPixmap
)
921 return M_BITMAPDATA
->m_insensPixmap
;
925 M_BITMAPDATA
->m_insensPixmap
= (WXPixmap
) XCreateInsensitivePixmap(dpy
, (Pixmap
) M_BITMAPDATA
->m_pixmap
);
926 if (M_BITMAPDATA
->m_insensPixmap
)
927 return M_BITMAPDATA
->m_insensPixmap
;
929 return M_BITMAPDATA
->m_pixmap
;
932 if (M_BITMAPDATA
->m_insensImage
== (WXPixmap
) 0)
933 return M_BITMAPDATA
->m_pixmap
;
936 See
GetLabelPixmap () comment
937 // Must be destroyed, because colours can have been changed!
938 if (M_BITMAPDATA
->m_insensPixmap
)
939 XmDestroyPixmap (DefaultScreenOfDisplay (dpy
), (Pixmap
) M_BITMAPDATA
->m_insensPixmap
);
943 sprintf (tmp
, "Not%x", (unsigned int) M_BITMAPDATA
->m_insensImage
);
946 Widget widget
= (Widget
) w
;
948 while (XmIsGadget (widget
))
949 widget
= XtParent (widget
);
950 XtVaGetValues (widget
, XmNbackground
, &bg
, XmNforeground
, &fg
, NULL
);
952 M_BITMAPDATA
->m_insensPixmap
= (WXPixmap
) XmGetPixmap (DefaultScreenOfDisplay (dpy
), tmp
, fg
, bg
);
954 return M_BITMAPDATA
->m_insensPixmap
;
957 // We may need this sometime...
959 /****************************************************************************
962 XCreateInsensitivePixmap - create a grayed-out copy of a pixmap
965 Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap )
968 This function creates a grayed-out copy of the argument pixmap, suitable
969 for use as a XmLabel's XmNlabelInsensitivePixmap resource.
972 The return value is the new Pixmap id or zero on error. Errors include
973 a NULL display argument or an invalid Pixmap argument.
976 If one of the XLib functions fail, it will produce a X error. The
977 default X error handler prints a diagnostic and calls exit().
980 XCopyArea(3), XCreateBitmapFromData(3), XCreateGC(3), XCreatePixmap(3),
981 XFillRectangle(3), exit(2)
984 John R Veregge - john@puente.jpl.nasa.gov
985 Advanced Engineering and Prototyping Group (AEG)
986 Information Systems Technology Section (395)
987 Jet Propulsion Lab - Calif Institute of Technology
989 *****************************************************************************/
992 XCreateInsensitivePixmap( Display
*display
, Pixmap pixmap
)
995 static char stipple_data
[] =
997 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
998 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
999 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA,
1000 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA
1003 Pixmap ipixmap
, stipple
;
1004 unsigned width
, height
, depth
;
1006 Window window
; /* These return values */
1007 unsigned border
; /* from XGetGeometry() */
1008 int x
, y
; /* are not needed. */
1012 if ( NULL
== display
|| 0 == pixmap
)
1015 if ( 0 == XGetGeometry( display
, pixmap
, &window
, &x
, &y
,
1016 &width
, &height
, &border
, &depth
)
1018 return ipixmap
; /* BadDrawable: probably an invalid pixmap */
1020 /* Get the stipple pixmap to be used to 'gray-out' the argument pixmap.
1022 stipple
= XCreateBitmapFromData( display
, pixmap
, stipple_data
, 16, 16 );
1025 gc
= XCreateGC( display
, pixmap
, (XtGCMask
)0, (XGCValues
*)NULL
);
1028 /* Create an identical copy of the argument pixmap.
1030 ipixmap
= XCreatePixmap( display
, pixmap
, width
, height
, depth
);
1033 /* Copy the argument pixmap into the new pixmap.
1035 XCopyArea( display
, pixmap
, ipixmap
,
1036 gc
, 0, 0, width
, height
, 0, 0 );
1038 /* Refill the new pixmap using the stipple algorithm/pixmap.
1040 XSetStipple( display
, gc
, stipple
);
1041 XSetFillStyle( display
, gc
, FillStippled
);
1042 XFillRectangle( display
, ipixmap
, gc
, 0, 0, width
, height
);
1044 XFreeGC( display
, gc
);
1046 XFreePixmap( display
, stipple
);
1051 // Creates a bitmap with transparent areas drawn in
1052 // the given colour.
1053 wxBitmap
wxCreateMaskedBitmap(const wxBitmap
& bitmap
, wxColour
& colour
)
1055 wxBitmap
newBitmap(bitmap
.GetWidth(),
1060 srcDC
.SelectObject(bitmap
);
1061 destDC
.SelectObject(newBitmap
);
1063 wxBrush
brush(colour
, wxSOLID
);
1064 destDC
.SetOptimization(FALSE
);
1065 destDC
.SetBackground(brush
);
1067 destDC
.Blit(0, 0, bitmap
.GetWidth(), bitmap
.GetHeight(), & srcDC
, 0, 0, wxCOPY
, TRUE
);
1075 //-----------------------------------------------------------------------------
1076 // wxImage conversion routines
1077 //-----------------------------------------------------------------------------
1081 Date: Wed, 05 Jan 2000 11:45:40 +0100
1082 From: Frits Boel <boel@niob.knaw.nl>
1083 To: julian.smart@ukonline.co.uk
1084 Subject: Patch for Motif ConvertToBitmap
1088 I've been working on a wxWin application for image processing. From the
1089 beginning, I was surprised by the (lack of) speed of ConvertToBitmap,
1090 till I looked in the source code of image.cpp. I saw that converting a
1091 wxImage to a bitmap with 8-bit pixels is done with comparing every pixel
1092 to the 256 colors of the palet. A very time-consuming piece of code!
1094 Because I wanted a faster application, I've made a 'patch' for this. In
1095 short: every pixel of the image is compared to a sorted list with
1096 colors. If the color is found in the list, the palette entry is
1097 returned; if the color is not found, the color palette is searched and
1098 then the palette entry is returned and the color added to the sorted
1101 Maybe there is another method for this, namely changing the palette
1102 itself (if the colors are known, as is the case with tiffs with a
1103 colormap). I did not look at this, maybe someone else did?
1105 The code of the patch is attached, have a look on it, and maybe you will
1106 ship it with the next release of wxMotif?
1111 Software engineer at Hubrecht Laboratory, The Netherlands.
1118 wxSearchColor( void );
1119 wxSearchColor( int size
, XColor
*colors
);
1120 ~wxSearchColor( void );
1122 int SearchColor( int r
, int g
, int b
);
1124 int AddColor( unsigned int value
, int pos
);
1128 unsigned int *color
;
1135 wxSearchColor::wxSearchColor( void )
1138 colors
= (XColor
*) NULL
;
1139 color
= (unsigned int *) NULL
;
1140 entry
= (int*) NULL
;
1146 wxSearchColor::wxSearchColor( int size_
, XColor
*colors_
)
1151 color
= new unsigned int[size
];
1152 entry
= new int [size
];
1154 for (i
= 0; i
< size
; i
++ ) {
1158 bottom
= top
= ( size
>> 1 );
1161 wxSearchColor::~wxSearchColor( void )
1163 if ( color
) delete color
;
1164 if ( entry
) delete entry
;
1167 int wxSearchColor::SearchColor( int r
, int g
, int b
)
1169 unsigned int value
= ( ( ( r
* 256 ) + g
) * 256 ) + b
;
1174 while ( begin
<= end
) {
1176 middle
= ( begin
+ end
) >> 1;
1178 if ( value
== color
[middle
] ) {
1179 return( entry
[middle
] );
1180 } else if ( value
< color
[middle
] ) {
1188 return AddColor( value
, middle
);
1191 int wxSearchColor::AddColor( unsigned int value
, int pos
)
1195 int max
= 3 * (65536);
1196 for ( i
= 0; i
< 256; i
++ ) {
1197 int rdiff
= ((value
>> 8) & 0xFF00 ) - colors
[i
].red
;
1198 int gdiff
= ((value
) & 0xFF00 ) - colors
[i
].green
;
1199 int bdiff
= ((value
<< 8) & 0xFF00 ) - colors
[i
].blue
;
1200 int sum
= abs (rdiff
) + abs (gdiff
) + abs (bdiff
);
1201 if (sum
< max
) { pixel
= i
; max
= sum
; }
1204 if ( entry
[pos
] < 0 ) {
1207 } else if ( value
< color
[pos
] ) {
1210 for ( i
= bottom
; i
< pos
; i
++ ) {
1211 color
[i
-1] = color
[i
];
1212 entry
[i
-1] = entry
[i
];
1215 color
[pos
-1] = value
;
1216 entry
[pos
-1] = pixel
;
1217 } else if ( top
< size
-1 ) {
1218 for ( i
= top
; i
>= pos
; i
-- ) {
1219 color
[i
+1] = color
[i
];
1220 entry
[i
+1] = entry
[i
];
1229 if ( top
< size
-1 ) {
1230 for ( i
= top
; i
> pos
; i
-- ) {
1231 color
[i
+1] = color
[i
];
1232 entry
[i
+1] = entry
[i
];
1235 color
[pos
+1] = value
;
1236 entry
[pos
+1] = pixel
;
1237 } else if ( bottom
> 0 ) {
1238 for ( i
= bottom
; i
< pos
; i
++ ) {
1239 color
[i
-1] = color
[i
];
1240 entry
[i
-1] = entry
[i
];
1253 bool wxBitmap::CreateFromImage( const wxImage
& image
, int depth
)
1255 wxCHECK_MSG( image
.Ok(), FALSE
, wxT("invalid image") )
1256 wxCHECK_MSG( depth
== -1, FALSE
, wxT("invalid bitmap depth") )
1258 m_refData
= new wxBitmapRefData();
1260 if (wxTheBitmapList
) wxTheBitmapList
->AddBitmap(this);
1262 int width
= image
.GetWidth();
1263 int height
= image
.GetHeight();
1265 SetHeight( height
);
1268 Display
*dpy
= (Display
*) wxGetDisplay();
1269 Visual
* vis
= DefaultVisual( dpy
, DefaultScreen( dpy
) );
1270 int bpp
= DefaultDepth( dpy
, DefaultScreen( dpy
) );
1274 XImage
*data_image
= XCreateImage( dpy
, vis
, bpp
, ZPixmap
, 0, 0, width
, height
, 32, 0 );
1275 data_image
->data
= (char*) malloc( data_image
->bytes_per_line
* data_image
->height
);
1277 Create( width
, height
, bpp
);
1281 XImage
*mask_image
= (XImage
*) NULL
;
1282 if (image
.HasMask())
1284 mask_image
= XCreateImage( dpy
, vis
, 1, ZPixmap
, 0, 0, width
, height
, 32, 0 );
1285 mask_image
->data
= (char*) malloc( mask_image
->bytes_per_line
* mask_image
->height
);
1288 // Retrieve depth info
1290 XVisualInfo vinfo_template
;
1293 vinfo_template
.visual
= vis
;
1294 vinfo_template
.visualid
= XVisualIDFromVisual( vis
);
1295 vinfo_template
.depth
= bpp
;
1298 vi
= XGetVisualInfo( dpy
, VisualIDMask
|VisualDepthMask
, &vinfo_template
, &nitem
);
1300 wxCHECK_MSG( vi
, FALSE
, wxT("no visual") );
1304 if ((bpp
== 16) && (vi
->red_mask
!= 0xf800)) bpp
= 15;
1305 if (bpp
< 8) bpp
= 8;
1309 enum byte_order
{ RGB
, RBG
, BRG
, BGR
, GRB
, GBR
};
1310 byte_order b_o
= RGB
;
1314 if ((vi
->red_mask
> vi
->green_mask
) && (vi
->green_mask
> vi
->blue_mask
)) b_o
= RGB
;
1315 else if ((vi
->red_mask
> vi
->blue_mask
) && (vi
->blue_mask
> vi
->green_mask
)) b_o
= RGB
;
1316 else if ((vi
->blue_mask
> vi
->red_mask
) && (vi
->red_mask
> vi
->green_mask
)) b_o
= BRG
;
1317 else if ((vi
->blue_mask
> vi
->green_mask
) && (vi
->green_mask
> vi
->red_mask
)) b_o
= BGR
;
1318 else if ((vi
->green_mask
> vi
->red_mask
) && (vi
->red_mask
> vi
->blue_mask
)) b_o
= GRB
;
1319 else if ((vi
->green_mask
> vi
->blue_mask
) && (vi
->blue_mask
> vi
->red_mask
)) b_o
= GBR
;
1322 int r_mask
= image
.GetMaskRed();
1323 int g_mask
= image
.GetMaskGreen();
1324 int b_mask
= image
.GetMaskBlue();
1329 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap( dpy
);
1331 for (int i
= 0; i
< 256; i
++) colors
[i
].pixel
= i
;
1332 XQueryColors( dpy
, cmap
, colors
, 256 );
1335 wxSearchColor
scolor( 256, colors
);
1336 unsigned char* data
= image
.GetData();
1338 bool hasMask
= image
.HasMask();
1341 for (int y
= 0; y
< height
; y
++)
1343 for (int x
= 0; x
< width
; x
++)
1345 int r
= data
[index
];
1347 int g
= data
[index
];
1349 int b
= data
[index
];
1354 if ((r
== r_mask
) && (b
== b_mask
) && (g
== g_mask
))
1355 XPutPixel( mask_image
, x
, y
, 0 );
1357 XPutPixel( mask_image
, x
, y
, 1 );
1364 #if 0 // Old, slower code
1367 if (wxTheApp->m_colorCube)
1369 pixel = wxTheApp->m_colorCube
1370 [ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
1375 int max
= 3 * (65536);
1376 for (int i
= 0; i
< 256; i
++)
1378 int rdiff
= (r
<< 8) - colors
[i
].red
;
1379 int gdiff
= (g
<< 8) - colors
[i
].green
;
1380 int bdiff
= (b
<< 8) - colors
[i
].blue
;
1381 int sum
= abs (rdiff
) + abs (gdiff
) + abs (bdiff
);
1382 if (sum
< max
) { pixel
= i
; max
= sum
; }
1389 // And this is all to get the 'right' color...
1390 int pixel
= scolor
.SearchColor( r
, g
, b
);
1391 XPutPixel( data_image
, x
, y
, pixel
);
1396 int pixel
= ((r
& 0xf8) << 7) | ((g
& 0xf8) << 2) | ((b
& 0xf8) >> 3);
1397 XPutPixel( data_image
, x
, y
, pixel
);
1402 int pixel
= ((r
& 0xf8) << 8) | ((g
& 0xfc) << 3) | ((b
& 0xf8) >> 3);
1403 XPutPixel( data_image
, x
, y
, pixel
);
1412 case RGB
: pixel
= (r
<< 16) | (g
<< 8) | b
; break;
1413 case RBG
: pixel
= (r
<< 16) | (b
<< 8) | g
; break;
1414 case BRG
: pixel
= (b
<< 16) | (r
<< 8) | g
; break;
1415 case BGR
: pixel
= (b
<< 16) | (g
<< 8) | r
; break;
1416 case GRB
: pixel
= (g
<< 16) | (r
<< 8) | b
; break;
1417 case GBR
: pixel
= (g
<< 16) | (b
<< 8) | r
; break;
1419 XPutPixel( data_image
, x
, y
, pixel
);
1429 gcvalues
.foreground
= BlackPixel( dpy
, DefaultScreen( dpy
) );
1430 GC gc
= XCreateGC( dpy
, RootWindow ( dpy
, DefaultScreen(dpy
) ), GCForeground
, &gcvalues
);
1431 XPutImage( dpy
, (Drawable
)GetPixmap(), gc
, data_image
, 0, 0, 0, 0, width
, height
);
1433 XDestroyImage( data_image
);
1437 if (image
.HasMask())
1439 wxBitmap
maskBitmap(width
, height
, 1);
1441 GC gcMask
= XCreateGC( dpy
, (Pixmap
) maskBitmap
.GetPixmap(), (XtGCMask
) 0, (XGCValues
*)NULL
);
1442 XPutImage( dpy
, (Drawable
)maskBitmap
.GetPixmap(), gcMask
, mask_image
, 0, 0, 0, 0, width
, height
);
1444 XDestroyImage( mask_image
);
1445 XFreeGC( dpy
, gcMask
);
1447 wxMask
* mask
= new wxMask
;
1448 mask
->SetPixmap(maskBitmap
.GetPixmap());
1452 maskBitmap
.SetPixmapNull();
1459 wxImage
wxBitmap::ConvertToImage() const
1463 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
1465 Display
*dpy
= (Display
*) wxGetDisplay();
1466 Visual
* vis
= DefaultVisual( dpy
, DefaultScreen( dpy
) );
1467 int bpp
= DefaultDepth( dpy
, DefaultScreen( dpy
) );
1469 XImage
*ximage
= XGetImage( dpy
,
1470 (Drawable
)GetPixmap(),
1472 GetWidth(), GetHeight(),
1473 AllPlanes
, ZPixmap
);
1475 wxCHECK_MSG( ximage
, wxNullImage
, wxT("couldn't create image") );
1477 image
.Create( GetWidth(), GetHeight() );
1478 char unsigned *data
= image
.GetData();
1482 XDestroyImage( ximage
);
1483 wxFAIL_MSG( wxT("couldn't create image") );
1488 GdkImage *gdk_image_mask = (GdkImage*) NULL;
1491 gdk_image_mask = gdk_image_get( GetMask()->GetBitmap(),
1493 GetWidth(), GetHeight() );
1495 image.SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable
1499 // Retrieve depth info
1501 XVisualInfo vinfo_template
;
1504 vinfo_template
.visual
= vis
;
1505 vinfo_template
.visualid
= XVisualIDFromVisual( vis
);
1506 vinfo_template
.depth
= bpp
;
1509 vi
= XGetVisualInfo( dpy
, VisualIDMask
|VisualDepthMask
, &vinfo_template
, &nitem
);
1511 wxCHECK_MSG( vi
, wxNullImage
, wxT("no visual") );
1513 if ((bpp
== 16) && (vi
->red_mask
!= 0xf800)) bpp
= 15;
1520 Colormap cmap
= (Colormap
)wxTheApp
->GetMainColormap( dpy
);
1522 for (int i
= 0; i
< 256; i
++) colors
[i
].pixel
= i
;
1523 XQueryColors( dpy
, cmap
, colors
, 256 );
1527 for (int j
= 0; j
< GetHeight(); j
++)
1529 for (int i
= 0; i
< GetWidth(); i
++)
1531 int pixel
= XGetPixel( ximage
, i
, j
);
1534 data
[pos
] = colors
[pixel
].red
>> 8;
1535 data
[pos
+1] = colors
[pixel
].green
>> 8;
1536 data
[pos
+2] = colors
[pixel
].blue
>> 8;
1537 } else if (bpp
== 15)
1539 data
[pos
] = (pixel
>> 7) & 0xf8;
1540 data
[pos
+1] = (pixel
>> 2) & 0xf8;
1541 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1542 } else if (bpp
== 16)
1544 data
[pos
] = (pixel
>> 8) & 0xf8;
1545 data
[pos
+1] = (pixel
>> 3) & 0xfc;
1546 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1549 data
[pos
] = (pixel
>> 16) & 0xff;
1550 data
[pos
+1] = (pixel
>> 8) & 0xff;
1551 data
[pos
+2] = pixel
& 0xff;
1557 int mask_pixel = gdk_image_get_pixel( gdk_image_mask, i, j );
1558 if (mask_pixel == 0)
1571 XDestroyImage( ximage
);
1573 if (gdk_image_mask) gdk_image_destroy( gdk_image_mask );