#include "wx/log.h"
#include "wx/image.h"
#include "wx/app.h"
+#if wxUSE_NANOX
+#include "wx/dcmemory.h"
+#endif
#include "wx/x11/private.h"
+/* No point in using libXPM for NanoX */
+#if wxUSE_NANOX
+#undef wxHAVE_LIB_XPM
+#define wxHAVE_LIB_XPM 0
+
+// Copy from the drawable to the wxImage
+bool wxGetImageFromDrawable(GR_DRAW_ID drawable, int srcX, int srcY, int width, int height, wxImage& image);
+#endif
+
+#if wxUSE_XPM
#if wxHAVE_LIB_XPM
- #include <X11/xpm.h>
+#include <X11/xpm.h>
+#else
+#include "wx/xpmdecod.h"
+#include "wx/wfstream.h"
+#endif
#endif
#include <math.h>
bool wxMask::Create( const wxBitmap& bitmap,
const wxColour& colour )
{
+#if !wxUSE_NANOX
if (m_bitmap)
{
XFreePixmap( (Display*) m_display, (Pixmap) m_bitmap );
m_display = bitmap.GetDisplay();
Display *xdisplay = (Display*) m_display;
-
int xscreen = DefaultScreen( xdisplay );
Window xroot = RootWindow( xdisplay, xscreen );
- Visual* xvisual = DefaultVisual( xdisplay, xscreen );
- int bpp = DefaultDepth( xdisplay, xscreen );
m_bitmap = (WXPixmap) XCreatePixmap( xdisplay, xroot, image.GetWidth(), image.GetHeight(), 1 );
GC gc = XCreateGC( xdisplay, (Pixmap) m_bitmap, 0, NULL );
unsigned char green = colour.Green();
unsigned char blue = colour.Blue();
- XVisualInfo vinfo_template;
- XVisualInfo *vi;
-
- vinfo_template.visual = xvisual;
- vinfo_template.visualid = XVisualIDFromVisual( xvisual );
- vinfo_template.depth = bpp;
- int nitem = 0;
-
- vi = XGetVisualInfo( xdisplay, VisualIDMask|VisualDepthMask, &vinfo_template, &nitem );
- wxASSERT_MSG( vi, wxT("No visual info") );
+ int bpp = wxTheApp->m_visualDepth;
- if ((bpp == 16) && (vi->red_mask != 0xf800)) bpp = 15;
if (bpp == 15)
{
red = red & 0xf8;
XSetForeground( xdisplay, gc, BlackPixel(xdisplay,xscreen) );
- for (int j = 0; j < image.GetHeight(); j++)
+ 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 < image.GetWidth(); i++)
+ for (i = 0; i < width; i++)
{
if ((data[index] == red) &&
(data[index+1] == green) &&
XFreeGC( xdisplay, gc );
return TRUE;
+#else
+ return FALSE;
+#endif
+ // wxUSE_NANOX
}
bool wxMask::Create( const wxBitmap& bitmap, int paletteIndex )
bool wxMask::Create( const wxBitmap& bitmap )
{
+#if !wxUSE_NANOX
if (m_bitmap)
{
XFreePixmap( (Display*) m_display, (Pixmap) m_bitmap );
XFreeGC( (Display*) m_display, gc );
return TRUE;
+#else
+ return FALSE;
+#endif
+ // wxUSE_NANOX
}
//-----------------------------------------------------------------------------
M_BMPDATA->m_mask = (wxMask *) NULL;
M_BMPDATA->m_width = width;
M_BMPDATA->m_height = height;
+
+#if wxUSE_NANOX
+ M_BMPDATA->m_pixmap = (WXPixmap) GrNewPixmap(width, height, NULL);
+ M_BMPDATA->m_bpp = bpp;
+
+ wxASSERT_MSG( M_BMPDATA->m_pixmap, wxT("Bitmap creation failed") );
+#else
if (depth == 1)
{
M_BMPDATA->m_bitmap = (WXPixmap) XCreatePixmap( (Display*) M_BMPDATA->m_display, xroot, width, height, 1 );
M_BMPDATA->m_bpp = depth;
}
-
+#endif
return Ok();
}
bool wxBitmap::CreateFromXpm( const char **bits )
{
+#if wxUSE_XPM
+#if wxHAVE_LIB_XPM
UnRef();
wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid bitmap data") )
XGetGeometry( xdisplay, pixmap, &xroot, &xRet, &yRet,
&widthRet, &heightRet, &borderWidthRet, &depthRet);
- wxASSERT_MSG( bpp == (int)depthRet, wxT("colour depth mismatch") )
+ wxASSERT_MSG( bpp == (int)depthRet, wxT("colour depth mismatch") );
#endif
XpmFreeAttributes(&xpmAttr);
M_BMPDATA->m_mask->SetBitmap( (WXPixmap) mask );
M_BMPDATA->m_mask->SetDisplay( xdisplay );
}
+ return TRUE;
}
else
{
return FALSE;
}
-
- return TRUE;
+#else
+ wxXPMDecoder decoder;
+ wxImage image(decoder.ReadData(bits));
+ if (image.Ok())
+ return CreateFromImage(image);
+ else
+ return FALSE;
+#endif
+#endif
+ return FALSE;
}
bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
{
+#if wxUSE_NANOX
+ if (!image.Ok())
+ {
+ wxASSERT_MSG(image.Ok(), "Invalid wxImage passed to wxBitmap::CreateFromImage.");
+ return FALSE;
+ }
+
+ int w = image.GetWidth();
+ int h = image.GetHeight();
+
+ if (!Create(w, h, depth))
+ return FALSE;
+
+ // Unfortunately the mask has to be screen-depth since
+ // 1-bpp bitmaps don't seem to be supported
+ // TODO: implement transparent drawing, presumably
+ // by doing several blits as per the Windows
+ // implementation because Nano-X doesn't support
+ // XSetClipMask.
+ // TODO: could perhaps speed this function up
+ // by making a buffer of pixel values,
+ // and then calling GrArea to write that to the
+ // pixmap. See demos/nxroach.c.
+
+ bool hasMask = image.HasMask();
+
+ GC pixmapGC = GrNewGC();
+ Pixmap pixmap = (Pixmap) GetPixmap();
+
+ GC maskGC = 0;
+ Pixmap maskPixmap = 0;
+
+ unsigned char maskR = 0;
+ unsigned char maskG = 0;
+ unsigned char maskB = 0;
+
+ if (hasMask)
+ {
+ maskR = image.GetMaskRed();
+ maskG = image.GetMaskGreen();
+ maskB = image.GetMaskBlue();
+
+ maskGC = GrNewGC();
+ maskPixmap = GrNewPixmap(w, h, 0);
+ if (!maskPixmap)
+ hasMask = FALSE;
+ else
+ {
+ wxMask* mask = new wxMask;
+ mask->SetBitmap((WXPixmap) maskPixmap);
+ SetMask(mask);
+ }
+ }
+
+ GR_COLOR lastPixmapColour = 0;
+ GR_COLOR lastMaskColour = 0;
+
+ int i, j;
+ for (i = 0; i < w; i++)
+ {
+ for (j = 0; j < h; j++)
+ {
+ unsigned char red = image.GetRed(i, j);
+ unsigned char green = image.GetGreen(i, j);
+ unsigned char blue = image.GetBlue(i, j);
+
+ GR_COLOR colour = GR_RGB(red, green, blue);
+
+ // Efficiency measure
+ if (colour != lastPixmapColour || (i == 0 && j == 0))
+ {
+ GrSetGCForeground(pixmapGC, colour);
+ lastPixmapColour = colour;
+ }
+
+ GrPoint(pixmap, pixmapGC, i, j);
+
+ if (hasMask)
+ {
+ // scan the bitmap for the transparent colour and set the corresponding
+ // pixels in the mask to BLACK and the rest to WHITE
+ if (maskR == red && maskG == green && maskB == blue)
+ {
+ colour = GR_RGB(0, 0, 0);
+ }
+ else
+ {
+ colour = GR_RGB(255, 255, 255);
+ }
+ if (colour != lastMaskColour || (i == 0 && j == 0))
+ {
+ GrSetGCForeground(maskGC, colour);
+ lastMaskColour = colour;
+ }
+ GrPoint(maskPixmap, maskGC, i, j);
+ }
+ }
+ }
+
+ GrDestroyGC(pixmapGC);
+ if (hasMask)
+ GrDestroyGC(maskGC);
+
+ return TRUE;
+#else
+ // !wxUSE_NANOX
+
UnRef();
wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") )
Window xroot = RootWindow( xdisplay, xscreen );
Visual* xvisual = DefaultVisual( xdisplay, xscreen );
- int bpp = DefaultDepth( xdisplay, xscreen );
+ int bpp = wxTheApp->m_visualDepth;
int width = image.GetWidth();
int height = image.GetHeight();
SetMask( mask );
}
- // Retrieve info
-
- XVisualInfo vinfo_template;
- XVisualInfo *vi;
-
- vinfo_template.visual = xvisual;
- vinfo_template.visualid = XVisualIDFromVisual( xvisual );
- vinfo_template.depth = bpp;
- int nitem = 0;
-
- vi = XGetVisualInfo( xdisplay, VisualIDMask|VisualDepthMask, &vinfo_template, &nitem );
- wxASSERT_MSG( vi, wxT("No visual info") );
-
- if ((bpp == 16) && (vi->red_mask != 0xf800)) bpp = 15;
if (bpp < 8) bpp = 8;
// Render
if (bpp > 8)
{
- if ((vi->red_mask > vi->green_mask) && (vi->green_mask > vi->blue_mask)) b_o = RGB;
- else if ((vi->red_mask > vi->blue_mask) && (vi->blue_mask > vi->green_mask)) b_o = RBG;
- else if ((vi->blue_mask > vi->red_mask) && (vi->red_mask > vi->green_mask)) b_o = BRG;
- else if ((vi->blue_mask > vi->green_mask) && (vi->green_mask > vi->red_mask)) b_o = BGR;
- else if ((vi->green_mask > vi->red_mask) && (vi->red_mask > vi->blue_mask)) b_o = GRB;
- else if ((vi->green_mask > vi->blue_mask) && (vi->blue_mask > vi->red_mask)) b_o = GBR;
+ if ((wxTheApp->m_visualRedMask > wxTheApp->m_visualGreenMask) && (wxTheApp->m_visualGreenMask > wxTheApp->m_visualBlueMask)) b_o = RGB;
+ else if ((wxTheApp->m_visualRedMask > wxTheApp->m_visualBlueMask) && (wxTheApp->m_visualBlueMask > wxTheApp->m_visualGreenMask)) b_o = RBG;
+ else if ((wxTheApp->m_visualBlueMask > wxTheApp->m_visualRedMask) && (wxTheApp->m_visualRedMask > wxTheApp->m_visualGreenMask)) b_o = BRG;
+ else if ((wxTheApp->m_visualBlueMask > wxTheApp->m_visualGreenMask) && (wxTheApp->m_visualGreenMask > wxTheApp->m_visualRedMask)) b_o = BGR;
+ else if ((wxTheApp->m_visualGreenMask > wxTheApp->m_visualRedMask) && (wxTheApp->m_visualRedMask > wxTheApp->m_visualBlueMask)) b_o = GRB;
+ else if ((wxTheApp->m_visualGreenMask > wxTheApp->m_visualBlueMask) && (wxTheApp->m_visualBlueMask > wxTheApp->m_visualRedMask)) b_o = GBR;
}
- XFree( vi );
-
int r_mask = image.GetMaskRed();
int g_mask = image.GetMaskGreen();
int b_mask = image.GetMaskBlue();
unsigned char* data = image.GetData();
wxASSERT_MSG( data, "No image data" );
+
+ unsigned char *colorCube = wxTheApp->m_colorCube;
bool hasMask = image.HasMask();
case 8:
{
int pixel = 0;
-#if 0
- if (wxTheApp->m_colorCube)
- {
- pixel = wxTheApp->m_colorCube[ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
- }
- else
- {
- GdkColormap *cmap = gtk_widget_get_default_colormap();
- GdkColor *colors = cmap->colors;
- int max = 3 * (65536);
-
- for (int i = 0; i < cmap->size; i++)
- {
- int rdiff = (r << 8) - colors[i].red;
- int gdiff = (g << 8) - colors[i].green;
- int bdiff = (b << 8) - colors[i].blue;
- int sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
- if (sum < max) { pixel = i; max = sum; }
- }
- }
-#endif
+ pixel = colorCube[ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
XPutPixel( data_image, x, y, pixel );
break;
}
GC gc = XCreateGC( xdisplay, (Pixmap) M_BMPDATA->m_pixmap, 0, NULL );
XPutImage( xdisplay, (Pixmap) M_BMPDATA->m_pixmap, gc, data_image, 0, 0, 0, 0, width, height );
-
XDestroyImage( data_image );
XFreeGC( xdisplay, gc );
if (image.HasMask())
{
GC gc = XCreateGC( xdisplay, (Pixmap) GetMask()->GetBitmap(), 0, NULL );
- XPutImage( xdisplay, (Pixmap) GetMask()->GetBitmap(), gc, data_image, 0, 0, 0, 0, width, height );
+ XPutImage( xdisplay, (Pixmap) GetMask()->GetBitmap(), gc, mask_image, 0, 0, 0, 0, width, height );
XDestroyImage( mask_image );
XFreeGC( xdisplay, gc );
}
return TRUE;
-}
-
-static void wxCalcPrecAndShift( unsigned long mask, int *shift, int *prec )
-{
- *shift = 0;
- *prec = 0;
-
- while (!(mask & 0x1))
- {
- (*shift)++;
- mask >>= 1;
- }
-
- while (mask & 0x1)
- {
- (*prec)++;
- mask >>= 1;
- }
+#endif
+ // wxUSE_NANOX
}
wxImage wxBitmap::ConvertToImage() const
Display *xdisplay = (Display*) M_BMPDATA->m_display;
wxASSERT_MSG( xdisplay, wxT("No display") );
-
- int xscreen = DefaultScreen( xdisplay );
- Visual* xvisual = DefaultVisual( xdisplay, xscreen );
-
- int bpp = DefaultDepth( xdisplay, xscreen );
-
+
+#if wxUSE_NANOX
+ //int bpp = DefaultDepth(xdisplay, xscreen);
+ wxGetImageFromDrawable((Pixmap) GetPixmap(), 0, 0, GetWidth(), GetHeight(), image);
+ return image;
+#else
+ // !wxUSE_NANOX
+ int bpp = wxTheApp->m_visualDepth;
XImage *x_image = NULL;
if (GetPixmap())
{
if (GetPixmap())
{
- // Retrieve info
-
- XVisualInfo vinfo_template;
- XVisualInfo *vi;
-
- vinfo_template.visual = xvisual;
- vinfo_template.visualid = XVisualIDFromVisual( xvisual );
- vinfo_template.depth = bpp;
- int nitem = 0;
-
- vi = XGetVisualInfo( xdisplay, VisualIDMask|VisualDepthMask, &vinfo_template, &nitem );
- wxASSERT_MSG( vi, wxT("No visual info") );
-
- int red_prec,green_prec,blue_prec;
- int red_shift,green_shift,blue_shift;
- wxCalcPrecAndShift( vi->red_mask, &red_shift, &red_prec );
- wxCalcPrecAndShift( vi->green_mask, &green_shift, &green_prec );
- wxCalcPrecAndShift( vi->blue_mask, &blue_shift, &blue_prec );
- if (bpp == 16) bpp = red_prec + green_prec + blue_prec;
-
- red_shift_right = red_shift;
- red_shift_left = 8-red_prec;
- green_shift_right = green_shift;
- green_shift_left = 8-green_prec;
- blue_shift_right = blue_shift;
- blue_shift_left = 8-blue_prec;
+ red_shift_right = wxTheApp->m_visualRedShift;
+ red_shift_left = 8-wxTheApp->m_visualRedPrec;
+ green_shift_right = wxTheApp->m_visualGreenShift;
+ green_shift_left = 8-wxTheApp->m_visualGreenPrec;
+ blue_shift_right = wxTheApp->m_visualBlueShift;
+ blue_shift_left = 8-wxTheApp->m_visualBluePrec;
-#if 0
- use_shift = (vi->visual->c_class == TrueColor) || (vi->visual->c_class == DirectColor);
-#else
- use_shift = TRUE;
-#endif
-
- XFree( vi );
+ use_shift = (wxTheApp->m_visualType == GrayScale) || (wxTheApp->m_visualType != PseudoColor);
}
+
if (GetBitmap())
{
bpp = 1;
}
+ XColor *colors = (XColor*) wxTheApp->m_visualColormap;
-// GdkColormap *cmap = gtk_widget_get_default_colormap();
-
+ int width = GetWidth();
+ int height = GetHeight();
long pos = 0;
- for (int j = 0; j < GetHeight(); j++)
+ for (int j = 0; j < height; j++)
{
- for (int i = 0; i < GetWidth(); i++)
+ for (int i = 0; i < width; i++)
{
unsigned long pixel = XGetPixel( x_image, i, j );
if (bpp == 1)
data[pos+1] = (pixel >> green_shift_right) << green_shift_left;
data[pos+2] = (pixel >> blue_shift_right) << blue_shift_left;
}
-#if 0
- else if (cmap->colors)
+ else if (colors)
{
- data[pos] = cmap->colors[pixel].red >> 8;
- data[pos+1] = cmap->colors[pixel].green >> 8;
- data[pos+2] = cmap->colors[pixel].blue >> 8;
+ data[pos] = colors[pixel].red >> 8;
+ data[pos+1] = colors[pixel].green >> 8;
+ data[pos+2] = colors[pixel].blue >> 8;
}
-#endif
else
{
wxFAIL_MSG( wxT("Image conversion failed. Unknown visual type.") );
XDestroyImage( x_image );
if (x_image_mask) XDestroyImage( x_image_mask );
-
return image;
+#endif
+ // wxUSE_NANOX
}
wxBitmap::wxBitmap( const wxBitmap& bmp )
wxBitmap::wxBitmap( const char bits[], int width, int height, int WXUNUSED(depth) )
{
+#if !wxUSE_NANOX
m_refData = new wxBitmapRefData();
M_BMPDATA->m_display = wxGlobalDisplay();
M_BMPDATA->m_width = width;
M_BMPDATA->m_height = height;
M_BMPDATA->m_bpp = 1;
-
+#endif
wxCHECK_RET( M_BMPDATA->m_bitmap, wxT("couldn't create bitmap") );
}
if (type == wxBITMAP_TYPE_XPM)
{
+#if wxUSE_XPM
+#if wxHAVE_LIB_XPM
m_refData = new wxBitmapRefData();
M_BMPDATA->m_display = wxGlobalDisplay();
return FALSE;
}
+#else
+#if wxUSE_STREAMS
+ wxXPMDecoder decoder;
+ wxFileInputStream stream(name);
+ if (stream.Ok())
+ {
+ wxImage image(decoder.ReadFile(stream));
+ if (image.Ok())
+ return CreateFromImage(image);
+ else
+ return FALSE;
+ }
+ else
+ return FALSE;
+#else
+ return FALSE;
+#endif
+ // wxUSE_STREAMS
+#endif
+ // wxHAVE_LIB_XPM
+#endif
+ // wxUSE_XPM
+ return FALSE;
}
else // try if wxImage can load it
{
return M_BMPDATA->m_display;
}
+#if wxUSE_NANOX
+// Copy from the drawable to the wxImage
+bool wxGetImageFromDrawable(GR_DRAW_ID drawable, int srcX, int srcY, int width, int height, wxImage& image)
+{
+ GR_SCREEN_INFO sinfo;
+ int x, y;
+ GR_PIXELVAL *pixels;
+ GR_PALETTE* palette = NULL;
+ unsigned char rgb[3], *pp;
+
+ GrGetScreenInfo(&sinfo);
+
+ if (sinfo.pixtype == MWPF_PALETTE) {
+ if(!(palette = (GR_PALETTE*) malloc(sizeof(GR_PALETTE)))) {
+ return FALSE;
+ }
+ GrGetSystemPalette(palette);
+ }
+
+ if(!(pixels = (GR_PIXELVAL*) malloc(sizeof(GR_PIXELVAL) * width * height)))
+ {
+ return FALSE;
+ }
+
+ image.Create(width, height);
+
+ GrReadArea(drawable, srcX, srcY, width, height,
+ pixels);
+
+
+ for(x = 0; x < sinfo.cols; x++) {
+
+ pp = (unsigned char *)pixels +
+ ((x + (y * sinfo.cols)) *
+ sizeof(GR_PIXELVAL));
+
+ switch(sinfo.pixtype) {
+ /* FIXME: These may need modifying on big endian. */
+ case MWPF_TRUECOLOR0888:
+ case MWPF_TRUECOLOR888:
+ rgb[0] = pp[2];
+ rgb[1] = pp[1];
+ rgb[2] = pp[0];
+ break;
+ case MWPF_PALETTE:
+ rgb[0] = palette->palette[pp[0]].r;
+ rgb[1] = palette->palette[pp[0]].g;
+ rgb[2] = palette->palette[pp[0]].b;
+ break;
+ case MWPF_TRUECOLOR565:
+ rgb[0] = pp[1] & 0xf8;
+ rgb[1] = ((pp[1] & 0x07) << 5) |
+ ((pp[0] & 0xe0) >> 3);
+ rgb[2] = (pp[0] & 0x1f) << 3;
+ break;
+ case MWPF_TRUECOLOR555:
+ rgb[0] = (pp[1] & 0x7c) << 1;
+ rgb[1] = ((pp[1] & 0x03) << 6) |
+ ((pp[0] & 0xe0) >> 2);
+ rgb[2] = (pp[0] & 0x1f) << 3;
+ break;
+ case MWPF_TRUECOLOR332:
+ rgb[0] = pp[0] & 0xe0;
+ rgb[1] = (pp[0] & 0x1c) << 3;
+ rgb[2] = (pp[0] & 0x03) << 6;
+ break;
+ default:
+ fprintf(stderr, "Unsupported pixel "
+ "format\n");
+ return 1;
+ }
+
+ image.SetRGB(x, y, rgb[0], rgb[1], rgb[2]);
+
+ }
+
+ free(pixels);
+ if(palette) free(palette);
+
+ return TRUE;
+}
+
+#if 0
+int GrGetPixelColor(GR_SCREEN_INFO* sinfo, GR_PALETTE* palette, GR_PIXELVAL pixel,
+ unsigned char* red, unsigned char* green, unsigned char* blue)
+{
+ unsigned char rgb[3], *pp;
+
+ pp = (unsigned char*) & pixel ;
+
+ switch (sinfo.pixtype)
+ {
+ /* FIXME: These may need modifying on big endian. */
+ case MWPF_TRUECOLOR0888:
+ case MWPF_TRUECOLOR888:
+ rgb[0] = pp[2];
+ rgb[1] = pp[1];
+ rgb[2] = pp[0];
+ break;
+ case MWPF_PALETTE:
+ rgb[0] = palette->palette[pp[0]].r;
+ rgb[1] = palette->palette[pp[0]].g;
+ rgb[2] = palette->palette[pp[0]].b;
+ break;
+ case MWPF_TRUECOLOR565:
+ rgb[0] = pp[1] & 0xf8;
+ rgb[1] = ((pp[1] & 0x07) << 5) |
+ ((pp[0] & 0xe0) >> 3);
+ rgb[2] = (pp[0] & 0x1f) << 3;
+ break;
+ case MWPF_TRUECOLOR555:
+ rgb[0] = (pp[1] & 0x7c) << 1;
+ rgb[1] = ((pp[1] & 0x03) << 6) |
+ ((pp[0] & 0xe0) >> 2);
+ rgb[2] = (pp[0] & 0x1f) << 3;
+ break;
+ case MWPF_TRUECOLOR332:
+ rgb[0] = pp[0] & 0xe0;
+ rgb[1] = (pp[0] & 0x1c) << 3;
+ rgb[2] = (pp[0] & 0x03) << 6;
+ break;
+ default:
+ fprintf(stderr, "Unsupported pixel format\n");
+ return 0;
+ }
+
+
+ *(red) = rgb[0];
+ *(green) = rgb[1];
+ *(blue) = rgb[2];
+ return 1;
+}
+#endif
+
+#endif
+ // wxUSE_NANOX
+