+#include <X11/xpm.h>
+#else
+#include "wx/xpmdecod.h"
+#include "wx/wfstream.h"
+#endif
+#endif
+
+//-----------------------------------------------------------------------------
+// wxMask
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMask,wxObject)
+
+wxMask::wxMask()
+{
+ m_bitmap = NULL;
+ m_display = NULL;
+}
+
+wxMask::wxMask(const wxMask& mask)
+{
+ m_display = mask.m_display;
+ if ( !mask.m_bitmap )
+ {
+ m_bitmap = NULL;
+ return;
+ }
+
+ m_size = mask.m_size;
+
+ // Duplicate the mask bitmap using the existing wxGetSubPixmap() function.
+ // There are probably/surely better ways to do it.
+ m_bitmap = wxGetSubPixmap(m_display, mask.m_bitmap,
+ 0, 0, m_size.x, m_size.y,
+ 1);
+}
+
+wxMask::wxMask( const wxBitmap& bitmap, const wxColour& colour )
+{
+ m_bitmap = NULL;
+ Create( bitmap, colour );
+}
+
+wxMask::wxMask( const wxBitmap& bitmap, int paletteIndex )
+{
+ m_bitmap = NULL;
+ Create( bitmap, paletteIndex );
+}
+
+wxMask::wxMask( const wxBitmap& bitmap )
+{
+ m_bitmap = NULL;
+ Create( bitmap );
+}
+
+wxMask::~wxMask()
+{
+ if (m_bitmap)
+ XFreePixmap( (Display*) m_display, (Pixmap) m_bitmap );
+}
+
+bool wxMask::Create( const wxBitmap& bitmap,
+ const wxColour& colour )
+{
+ m_size = bitmap.GetSize();
+
+#if !wxUSE_NANOX
+ if (m_bitmap)
+ {
+ XFreePixmap( (Display*) m_display, (Pixmap) m_bitmap );
+ m_bitmap = NULL;
+ }
+
+ m_display = bitmap.GetDisplay();
+
+ wxImage image = bitmap.ConvertToImage();
+ if (!image.IsOk()) return false;
+
+ m_display = bitmap.GetDisplay();
+
+ Display *xdisplay = (Display*) m_display;
+ int xscreen = DefaultScreen( xdisplay );
+ Window xroot = RootWindow( xdisplay, xscreen );
+
+ m_bitmap = (WXPixmap) XCreatePixmap( xdisplay, xroot, image.GetWidth(), image.GetHeight(), 1 );
+ GC gc = XCreateGC( xdisplay, (Pixmap) m_bitmap, 0, NULL );
+
+ XSetForeground( xdisplay, gc, WhitePixel(xdisplay,xscreen) );
+ XSetFillStyle( xdisplay, gc, FillSolid );
+ XFillRectangle( xdisplay, (Pixmap) m_bitmap, gc, 0, 0, image.GetWidth(), image.GetHeight() );
+
+ unsigned char *data = image.GetData();
+ int index = 0;
+
+ unsigned char red = colour.Red();
+ unsigned char green = colour.Green();
+ unsigned char blue = colour.Blue();
+
+ int bpp = wxTheApp->GetVisualInfo(m_display)->m_visualDepth;
+
+ if (bpp == 15)
+ {
+ red &= 0xf8;
+ green &= 0xf8;
+ blue &= 0xf8;
+ } else
+ if (bpp == 16)
+ {
+ red &= 0xf8;
+ green &= 0xfc;
+ blue &= 0xf8;
+ } else
+ if (bpp == 12)
+ {
+ red &= 0xf0;
+ green &= 0xf0;
+ blue &= 0xf0;
+ }
+
+ XSetForeground( xdisplay, gc, BlackPixel(xdisplay,xscreen) );
+
+ int width = image.GetWidth();
+ int height = image.GetHeight();
+ for (int j = 0; j < height; j++)
+ {
+ int start_x = -1;
+ int i;
+ for (i = 0; i < width; i++)
+ {
+ if ((data[index] == red) &&
+ (data[index+1] == green) &&
+ (data[index+2] == blue))
+ {
+ if (start_x == -1)
+ start_x = i;
+ }
+ else
+ {
+ if (start_x != -1)
+ {
+ XDrawLine( xdisplay, (Pixmap) m_bitmap, gc, start_x, j, i-1, j );
+ start_x = -1;
+ }
+ }
+ index += 3;
+ }
+ if (start_x != -1)
+ XDrawLine( xdisplay, (Pixmap) m_bitmap, gc, start_x, j, i, j );
+ }
+
+ XFreeGC( xdisplay, gc );
+
+ return true;
+#else
+ return false;