Back to index

plt-scheme  4.2.1
Bitmap.cc
Go to the documentation of this file.
00001 /*                                                      -*- C++ -*-
00002  *
00003  * Purpose: bitmap classes to implement pixmaps, icons, and cursors
00004  *
00005  * Authors: Markus Holzem and Julian Smart
00006  *
00007  * Copyright: (C) 2004-2009 PLT Scheme Inc.
00008  * Copyright: (C) 1995, AIAI, University of Edinburgh (Julian)
00009  * Copyright: (C) 1995, GNU (Markus)
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00024  * 02110-1301 USA.
00025  */
00026 
00027 #ifdef __GNUG__
00028 #pragma implementation "Bitmap.h"
00029 #endif
00030 
00031 #define  Uses_XLib
00032 #define  Uses_wxBitmap
00033 #define  Uses_wxColour
00034 #define  Uses_wxMemoryDC
00035 #include "wx.h"
00036 
00037 #if USE_XPM
00038 #      include "../../contrib/xpm/lib/xpm.h"
00039 #endif
00040 #if USE_IMAGE_LOADING_IN_X
00041 #define WXI_SKIP_WX_INCLUDES
00042 #       include WXIMAGE_INCLUDE
00043 #endif
00044 #include <X11/cursorfont.h>
00045 
00046 extern "C" { 
00047 #include "XWidgets/wxAllocColor.h"
00048 };
00049 extern Colormap wx_default_colormap;
00050 
00051 extern int read_JPEG_file(char * filename, wxBitmap *bm);
00052 extern int write_JPEG_file(char * filename, wxBitmap *bm, int quality_val);
00053 
00054 extern int wx_read_png(char *file_name, wxBitmap *bm, int w_mask, wxColour *bg);
00055 extern int wx_write_png(char *file_name, wxBitmap *bm);
00056 
00057 extern void wxAlphaBlit(wxBitmap *label_bm, wxBitmap *bm, wxBitmap *loaded_mask, 
00058                      int br, int bg, int bb);
00059 
00060 #include "../../../wxcommon/wxGLConfig.h"
00061 
00062 // hints for what to free in wxBitmap::Destroy()
00063 enum {
00064     __BITMAP_NORMAL, // <-- no special data
00065 #if USE_XPM
00066     __BITMAP_XPM     // <-- XpmAttributes
00067 #endif
00068 };
00069 
00070 class wxBitmap_Xintern : public gc {
00071 public:
00072     int          type;                    // what is the type of the bitmap
00073     unsigned int width, height, depth;    // dimensions of bitmap
00074     int          x_hot, y_hot;            // hotspot of bitmap
00075     Pixmap       x_pixmap;         // the displayable pixmap
00076 #ifdef WX_USE_XRENDER
00077     long      picture;
00078 #endif
00079     // Optional stuff for different bitmaps
00080     XpmAttributes* xpm;            // for XPM pixmaps
00081     void         *account;
00082 };
00083 
00084 class wxCursor_Xintern : public gc {
00085 public:
00086     Cursor x_cursor;
00087 };
00088 
00089 //-----------------------------------------------------------------------------
00090 // wxBitmap
00091 //-----------------------------------------------------------------------------
00092 
00093 // create nothing
00094 wxBitmap::wxBitmap(void)
00095 {
00096     __type = wxTYPE_BITMAP;
00097 
00098     Xbitmap = NULL;
00099     cmap    = wxAPP_COLOURMAP;
00100 }
00101 
00102 // create bitmap from bitmap-data
00103 wxBitmap::wxBitmap(char bits[], int w, int h)
00104 {
00105     __type = wxTYPE_BITMAP;
00106 
00107     Xbitmap = new wxBitmap_Xintern;
00108     cmap    = wxAPP_COLOURMAP;
00109 
00110     // set bitmap specific data
00111     Xbitmap->type   = __BITMAP_NORMAL;
00112     Xbitmap->width  = w;
00113     Xbitmap->height = h;
00114     Xbitmap->depth  = 1; // don't know what to do if depth > 1 !!!
00115     Xbitmap->x_hot  = 0;
00116     Xbitmap->y_hot  = 0;
00117 
00118     // create pixmap with depth 1
00119     Xbitmap->x_pixmap = XCreateBitmapFromData(wxAPP_DISPLAY, wxAPP_ROOT, bits, w, h);
00120     if (Xbitmap->x_pixmap == None) {
00121       // create failed
00122       DELETE_OBJ Xbitmap;
00123       Xbitmap = NULL;
00124     }
00125     Xbitmap->account = GC_malloc_accounting_shadow((w * h) >> 3);
00126 
00127     WXGC_IGNORE(this, selectedTo);
00128 }
00129 
00130 // create bitmap from file
00131 wxBitmap::wxBitmap(char *bitmap_file, long flags, wxColour *bg)
00132 {
00133     __type = wxTYPE_BITMAP;
00134 
00135     Xbitmap = NULL;
00136     cmap    = wxAPP_COLOURMAP;
00137 
00138     // use load method
00139     (void)LoadFile(bitmap_file, flags, bg);
00140 
00141     WXGC_IGNORE(this, selectedTo);
00142 }
00143 
00144 #if USE_XPM
00145 
00146 // create bitmap from xpm-data
00147 wxBitmap::wxBitmap(char **data, wxItem *WXUNUSED(anItem)) // anItem used for MOTIF
00148 {
00149     int ErrorStatus;
00150 
00151     __type = wxTYPE_BITMAP;
00152 
00153     cmap    = wxAPP_COLOURMAP;
00154     Xbitmap = new wxBitmap_Xintern;
00155     // what I want to get from XPM
00156 #ifdef MZ_PRECISE_GC
00157     {
00158       XpmAttributes *attr;
00159       attr = (XpmAttributes *)GC_malloc_atomic(sizeof(XpmAttributes));
00160       Xbitmap->xpm = attr;
00161     }
00162 #else
00163     Xbitmap->xpm = new WXGC_ATOMIC XpmAttributes;
00164 #endif
00165     Xbitmap->xpm->valuemask = (XpmReturnInfos | XpmReturnPixels | XpmCloseness
00166                             | XpmVisual | XpmDepth | XpmColormap);
00167     Xbitmap->xpm->closeness = 40000;
00168     Xbitmap->xpm->visual = wxAPP_VISUAL;
00169     Xbitmap->xpm->depth = wx_visual_depth;
00170     Xbitmap->xpm->colormap = wx_default_colormap;
00171     // create pixmap
00172     ErrorStatus = XpmCreatePixmapFromData(wxAPP_DISPLAY, wxAPP_ROOT,
00173                                      data, &(Xbitmap->x_pixmap),
00174                                      (Pixmap*)NULL, Xbitmap->xpm);
00175     if (ErrorStatus == XpmSuccess) {
00176        int sdummy; unsigned int udummy; Window wdummy;
00177        // create pixmap successful
00178        Xbitmap->type   = __BITMAP_XPM;
00179        Xbitmap->width  = Xbitmap->xpm->width;
00180        Xbitmap->height = Xbitmap->xpm->height;
00181        Xbitmap->x_hot  = Xbitmap->xpm->x_hotspot;
00182        Xbitmap->y_hot  = Xbitmap->xpm->y_hotspot;
00183        // get depth of pixmap
00184        XGetGeometry(wxAPP_DISPLAY, Xbitmap->x_pixmap, &wdummy, &sdummy, &sdummy,
00185                    &udummy, &udummy, &udummy, &(Xbitmap->depth));
00186        Xbitmap->account = GC_malloc_accounting_shadow(Xbitmap->width * Xbitmap->height * 4);
00187     } else {
00188        // create failed: free all memory
00189        XpmFreeAttributes(Xbitmap->xpm);
00190        DELETE_OBJ Xbitmap;
00191        Xbitmap = NULL;
00192     }
00193 
00194     WXGC_IGNORE(this, selectedTo);
00195 }
00196 
00197 #endif
00198 
00199 // create bitmap of given size
00200 wxBitmap::wxBitmap(int w, int h, Bool b_and_w)
00201 {
00202     __type = wxTYPE_BITMAP;
00203 
00204     Xbitmap = NULL;
00205     cmap    = wxAPP_COLOURMAP;
00206 
00207     // use create method
00208     (void)Create(w, h, b_and_w ? 1 : -1);
00209 
00210     WXGC_IGNORE(this, selectedTo);
00211 }
00212 
00213 // destroy bitmap
00214 wxBitmap::~wxBitmap(void)
00215 {
00216     // free pixmap and infos
00217     Destroy();
00218 
00219     selectedTo = NULL;
00220 }
00221 
00222 static int errorFlagged;
00223 static int FlagError(Display*, XErrorEvent*)
00224 {
00225   errorFlagged = 1;
00226   return 0;
00227 }
00228 
00229 typedef int (*X_Err_Handler)(Display*, XErrorEvent*);
00230 
00231 // create empty bitmap with dimensions w,h,d
00232 Bool wxBitmap::Create(int w, int h, int d)
00233 {
00234     X_Err_Handler old_handler;
00235 
00236     Destroy(); // destroy old bitmap if any
00237 
00238     Xbitmap = new wxBitmap_Xintern;
00239     // set pixmap specific data
00240     Xbitmap->type   = __BITMAP_NORMAL;
00241     Xbitmap->width  = w;
00242     Xbitmap->height = h;
00243     if (d < 1) {
00244       Xbitmap->depth = wxDisplayDepth();
00245     } else {
00246       Xbitmap->depth = d;
00247     }
00248     Xbitmap->x_hot  = 0;
00249     Xbitmap->y_hot  = 0;
00250     // create pixmap
00251 
00252     old_handler = XSetErrorHandler(FlagError);
00253     errorFlagged = 0;
00254 
00255     Xbitmap->x_pixmap = XCreatePixmap(wxAPP_DISPLAY, wxAPP_ROOT, w, h, Xbitmap->depth);
00256     
00257     XSync(wxAPP_DISPLAY, FALSE);
00258 
00259     if (errorFlagged)
00260       Xbitmap->x_pixmap = None;
00261 
00262     XSetErrorHandler(old_handler);
00263 
00264     if (Xbitmap->x_pixmap == None) {
00265       // create failed!
00266       DELETE_OBJ Xbitmap;
00267       Xbitmap = NULL;
00268     } else {
00269       Xbitmap->account = GC_malloc_accounting_shadow((w * h * ((Xbitmap->depth == 1) ? 1 : 32)) >> 3);
00270     }
00271 
00272     return Ok();
00273 }
00274 
00275 // destroy bitmap
00276 void wxBitmap::Destroy(void)
00277 {
00278   FreeMaskBit();
00279 
00280   if (Xbitmap) {
00281     XFreePixmap(wxAPP_DISPLAY, Xbitmap->x_pixmap); // free pixmap
00282     GC_free_accounting_shadow(Xbitmap->account);
00283     Xbitmap->account = NULL;
00284 # ifdef WX_USE_XRENDER
00285     if (Xbitmap->picture) {
00286       wxFreePicture(Xbitmap->picture);
00287     }
00288 # endif
00289     
00290     switch (Xbitmap->type) { // free type specific data
00291     case __BITMAP_XPM:
00292       {
00293        // free XPM data
00294        Colormap cm;
00295        cm = *((Colormap*)(cmap->GetHandle()));
00296        XFreeColors(wxAPP_DISPLAY, cm, Xbitmap->xpm->pixels, Xbitmap->xpm->npixels, 0);
00297        XpmFreeAttributes(Xbitmap->xpm);
00298       }
00299       break;
00300     default:
00301       break; // no other formats so far
00302     }
00303     DELETE_OBJ Xbitmap;
00304   }
00305   // contains no pixmap
00306   Xbitmap = NULL;
00307 }
00308 
00309 extern int wxsGetImageType(char *);
00310 
00311 // load bitmaps
00312 Bool wxBitmap::LoadFile(char *fname, long flags, wxColour *bg)
00313 {
00314   int getMask;
00315 
00316   if (selectedIntoDC)
00317     return FALSE;
00318 
00319   Destroy(); // destroy old pixmap if any
00320 
00321   if (flags & wxBITMAP_TYPE_MASK)
00322     getMask = 1;
00323   else
00324     getMask = 0;
00325 
00326   if (!flags || (flags == wxBITMAP_TYPE_MASK))
00327     flags = wxsGetImageType(fname);
00328 
00329   /* MATTHEW: move "Xbitmap = new wxBitmap_Xintern" into
00330      two appropriate cases. */
00331 
00332   if (flags & wxBITMAP_TYPE_XBM) { // XBM file format
00333     Xbitmap = new wxBitmap_Xintern;
00334 
00335     if (XReadBitmapFile(wxAPP_DISPLAY, wxAPP_ROOT, fname,
00336                      &(Xbitmap->width), &(Xbitmap->height),
00337                      &(Xbitmap->x_pixmap), 
00338                      &(Xbitmap->x_hot), &(Xbitmap->y_hot))
00339        == BitmapSuccess)
00340       {
00341        Xbitmap->type  = __BITMAP_NORMAL;
00342        Xbitmap->depth = 1;
00343        Xbitmap->account = GC_malloc_accounting_shadow((Xbitmap->width * Xbitmap->height) >> 3);
00344       } else {
00345        DELETE_OBJ Xbitmap;
00346        Xbitmap = NULL;
00347       }
00348   }
00349   else if (flags & wxBITMAP_TYPE_JPEG) {
00350     if (!read_JPEG_file(fname, this)) {
00351       Destroy();
00352     }
00353   }
00354   else if (flags & wxBITMAP_TYPE_PNG) {
00355     if (!wx_read_png(fname, this, getMask, bg)) {
00356       Destroy();
00357     }
00358   }
00359 #if USE_XPM
00360 else if (flags & wxBITMAP_TYPE_XPM) { // XPM file format
00361   Xbitmap = new wxBitmap_Xintern;
00362 
00363   // what I want to get
00364 #ifdef MZ_PRECISE_GC
00365   {
00366     XpmAttributes *attr;
00367     attr = (XpmAttributes *)GC_malloc_atomic(sizeof(XpmAttributes));
00368     Xbitmap->xpm = attr;
00369   }
00370 #else
00371   Xbitmap->xpm = new WXGC_ATOMIC XpmAttributes;
00372 #endif
00373   Xbitmap->xpm->valuemask = XpmReturnInfos | XpmReturnPixels | XpmCloseness | XpmDepth;
00374   Xbitmap->xpm->closeness = 40000;
00375   Xbitmap->xpm->depth = DefaultDepth(wxAPP_DISPLAY, DefaultScreen(wxAPP_DISPLAY));
00376   
00377   if (XpmReadFileToPixmap(wxAPP_DISPLAY, wxAPP_ROOT, fname,
00378                        &(Xbitmap->x_pixmap), (Pixmap*)NULL, Xbitmap->xpm)
00379       == XpmSuccess)
00380     {
00381       // read pixmap ok!
00382       int sdummy; unsigned int udummy; Window wdummy;
00383       Xbitmap->type   = __BITMAP_XPM;
00384       Xbitmap->width  = Xbitmap->xpm->width;
00385       Xbitmap->height = Xbitmap->xpm->height;
00386       Xbitmap->x_hot  = Xbitmap->xpm->x_hotspot;
00387       Xbitmap->y_hot  = Xbitmap->xpm->y_hotspot;
00388       XGetGeometry(wxAPP_DISPLAY, Xbitmap->x_pixmap, &wdummy, &sdummy, &sdummy,
00389                  &udummy, &udummy, &udummy, &(Xbitmap->depth));
00390       Xbitmap->account = GC_malloc_accounting_shadow(Xbitmap->width * Xbitmap->height * 4);
00391     } else {
00392       // read failed: free all memory
00393       XpmFreeAttributes(Xbitmap->xpm);
00394       DELETE_OBJ Xbitmap;
00395       Xbitmap = NULL;
00396     }
00397 }
00398 #endif
00399 #if USE_IMAGE_LOADING_IN_X
00400 else if ((flags & wxBITMAP_TYPE_ANY) || (flags & wxBITMAP_TYPE_BMP) ||
00401         (flags & wxBITMAP_TYPE_GIF))
00402   {
00403     wxColourMap *map = NULL;
00404     Bool success = FALSE;
00405 
00406     if (flags & wxBITMAP_DISCARD_COLOURMAP)
00407       success = wxLoadIntoBitmap(fname, this, NULL, getMask);
00408     else {
00409       wxColourMap *cm;
00410       success = wxLoadIntoBitmap(fname, this, &cm, getMask);
00411       cmap = cm;
00412     }
00413 
00414     if (!success && map) {
00415       DELETE_OBJ map;
00416       map = NULL;
00417     }
00418 
00419     if (map)
00420       cmap = map;
00421   }
00422 #endif
00423 
00424   return Ok();
00425 }
00426 
00427 static int write_pixmap_as_bitmap(Display *display, Pixmap pm, char *fname, 
00428                                int width, int height)
00429 {
00430   char *data;
00431   int rw, ok, i, j, pos;
00432   XImage *img;
00433   Pixmap bm;
00434 
00435   img = XGetImage(display, pm, 0, 0, width, height, AllPlanes, ZPixmap);
00436 
00437   rw = ((width + 1) >> 3);
00438 
00439   data = new WXGC_ATOMIC char[rw * height];
00440 
00441   pos = 0;
00442   for (j = 0; j < height; j++, pos += rw) {
00443     int bit = 0x01, v = 0, count = 0;
00444     int row = pos;
00445 
00446     for (i = 0; i < width; i++) {
00447       XColor xcol;
00448       unsigned long pixel;
00449 
00450       pixel = XGetPixel(img, i, j);
00451       if (xcol.pixel != pixel) {
00452        xcol.pixel = pixel;
00453        
00454        wxQueryColor(display, 
00455                    wx_default_colormap,
00456                    &xcol);
00457       }
00458 
00459       if ((xcol.red >> 8) != 255
00460          || (xcol.green >> 8) != 255
00461          || (xcol.blue >> 8) != 255)
00462        v += bit;
00463 
00464       bit = bit << 1;
00465       count++;
00466       if (count == 8) {
00467        data[row++] = v;
00468        v = 0;
00469        bit = 0x01;
00470        count = 0;
00471       }
00472     }
00473     if (bit != 0x01)
00474       data[row] = v;
00475   }
00476 
00477   bm = XCreateBitmapFromData(display, pm, data, width, height);
00478 
00479   ok = (XWriteBitmapFile(display, fname, bm, width, height, 0, 0)
00480        == BitmapSuccess);
00481 
00482   XFreePixmap(display, bm);
00483 
00484   XDestroyImage(img);
00485 
00486   return ok;
00487 } 
00488 
00489 // save bitmaps
00490 Bool wxBitmap::SaveFile(char *fname, int type, int quality, wxColourMap *WXUNUSED(cmap))
00491 {
00492   if (Xbitmap) {
00493     if (selectedTo)
00494       selectedTo->EndSetPixel();
00495     
00496     switch (type) {
00497     case wxBITMAP_TYPE_XBM:
00498       if (Xbitmap->depth == 1)
00499        return (XWriteBitmapFile(wxAPP_DISPLAY, fname, Xbitmap->x_pixmap,
00500                              Xbitmap->width, Xbitmap->height,
00501                              Xbitmap->x_hot, Xbitmap->y_hot)
00502               == BitmapSuccess);
00503       else {
00504        return write_pixmap_as_bitmap(wxAPP_DISPLAY, Xbitmap->x_pixmap,  fname, 
00505                                   Xbitmap->width, Xbitmap->height);
00506       }
00507       break; // write failed or depth != 1
00508     case wxBITMAP_TYPE_XPM:
00509       return (XpmWriteFileFromPixmap(wxAPP_DISPLAY, fname, Xbitmap->x_pixmap,
00510                                  (Pixmap)NULL, (XpmAttributes*)NULL)
00511              == XpmSuccess);
00512       break; // write failed
00513     case wxBITMAP_TYPE_JPEG:
00514       return write_JPEG_file(fname, this, quality);
00515       break; // write failed
00516     case wxBITMAP_TYPE_PNG:
00517       return wx_write_png(fname, this);
00518       break; // write failed
00519     default:
00520       break; // no other save methods so far
00521     }
00522   }
00523   return FALSE;
00524 }
00525 
00526 // retrieve infos
00527 int   wxBitmap::GetDepth(void)  { return (Xbitmap ? Xbitmap->depth : 0); }
00528 int   wxBitmap::GetHeight(void) { return (Xbitmap ? Xbitmap->height : 0); }
00529 int   wxBitmap::GetWidth(void)  { return (Xbitmap ? Xbitmap->width : 0); }
00530 void  wxBitmap::GetHotSpot(int *x, int *y)
00531 {
00532     if (Xbitmap) { *x = Xbitmap->x_hot; *y = Xbitmap->y_hot; }
00533     else         { *x = *y = 0; }
00534 }
00535 
00536 void* wxBitmap::GetHandle(void) {
00537   return (Xbitmap ? &(Xbitmap->x_pixmap) : NULL);
00538 }
00539 
00540 #ifdef WX_USE_XRENDER
00541 long wxBitmap::GetPicture(void) { 
00542   if (Xbitmap) {
00543     if (!Xbitmap->picture) {
00544       long p;
00545       p = wxMakePicture(Xbitmap->x_pixmap, Xbitmap->depth != 1);
00546       Xbitmap->picture = p;
00547     }
00548     return Xbitmap->picture;
00549   } else
00550     return 0;
00551 }
00552 #endif
00553 
00554 wxBitmap *wxBitmap::GetMaskBit()
00555 {
00556   wxBitmap *bm;
00557   wxMemoryDC *tmp;
00558   wxColour *c;
00559   int mw, mh, v, mono;
00560 
00561   /* Need to create an 8-bit alpha (grayscale) pixmap or 1-bit mask by
00562      reading pixels of the mask pixmap. Even in the 8-bit case, we
00563      don't worry about a colormap for this pixmap; it will be
00564      interpreted as graysacle by Xrender. */
00565 
00566   if (maskBit)
00567     return maskBit;
00568 
00569 #ifdef WX_USE_XRENDER
00570   mono = !wxXRenderHere();
00571 #else
00572   mono = 1;
00573 #endif
00574 
00575   mw = GetWidth();
00576   mh = GetHeight();
00577          
00578   bm = new wxBitmap();
00579   bm->Create(mw, mh, mono ? 1 : 8);
00580          
00581   if (bm->Ok()) {
00582     Pixmap bpm;
00583     XImage *img;
00584     int i, j;
00585          
00586     bpm = GETPIXMAP(bm);
00587 
00588     tmp = new wxMemoryDC(1);
00589     tmp->SelectObject(this);
00590            
00591     c = new wxColour(0, 0, 0);
00592     img = XGetImage(wxAPP_DISPLAY, bpm, 0, 0, mw, mh, AllPlanes, ZPixmap);
00593            
00594     tmp->BeginGetPixelFast(0, 0, mw, mh);
00595     for (i = 0; i < mw; i++) {
00596       for (j = 0; j < mh; j++) {
00597        int r_c, g_c, b_c;
00598        tmp->GetPixelFast(i, j, &r_c, &g_c, &b_c);
00599        v = (r_c + g_c + b_c) / 3;
00600        XPutPixel(img, i, j, 255 - v);
00601       }
00602     }
00603     tmp->EndGetPixelFast();
00604 
00605     tmp->SelectObject(NULL);
00606 
00607     {
00608       GC agc;
00609       agc = XCreateGC(wxAPP_DISPLAY, bpm, 0, NULL);
00610       XPutImage(wxAPP_DISPLAY, bpm, agc, img, 0, 0, 0, 0, mw, mh);
00611       XFreeGC(wxAPP_DISPLAY, agc);
00612     }
00613 
00614     XDestroyImage(img);
00615 
00616     maskBit = bm;
00617   } else {
00618     DELETE_OBJ bm;
00619   }
00620 
00621   return maskBit;
00622 }
00623 
00624 void wxBitmap::FreeMaskBit()
00625 {
00626   if (maskBit) {
00627     DELETE_OBJ maskBit;
00628     maskBit = NULL;
00629   }
00630 }
00631 
00632 void *wxBitmap::GetLabelPixmap(Bool for_button)
00633 {
00634   int can_x_render;
00635 
00636 #ifdef WX_USE_XRENDER
00637   can_x_render = wxXRenderHere();
00638 #else
00639   can_x_render = 0;
00640 #endif
00641 
00642   if (!can_x_render
00643       && ((for_button && !button_label_bm)
00644          || (!for_button && !label_bm))
00645       && loaded_mask
00646       && (loaded_mask->GetDepth() != 1)
00647       && (loaded_mask->GetWidth() == GetWidth())
00648       && (loaded_mask->GetHeight() == GetHeight())) {
00649     /* Manually construct the alpha-masked image */
00650     int w, h;
00651     wxBitmap *bm;
00652 
00653     w = GetWidth();
00654     h = GetHeight();
00655     bm = new wxBitmap(w, h, 0);
00656     if (bm->Ok()) {
00657       int r, g, b;
00658 
00659       if (selectedTo)
00660        selectedTo->EndSetPixel();
00661       if (loaded_mask->selectedTo)
00662        loaded_mask->selectedTo->EndSetPixel();
00663 
00664       {
00665        wxColor *co;
00666        if (for_button)
00667          co = wxBUTTON_COLOR;
00668        else
00669          co = wxGREY;
00670        r = co->Red();
00671        g = co->Green();
00672        b = co->Blue();
00673       }
00674 
00675       wxAlphaBlit(bm, this, loaded_mask, r, g, b);
00676 
00677       if (for_button)
00678        button_label_bm = bm;
00679       else
00680        label_bm = bm;
00681     }
00682   }
00683 
00684   if (for_button) {
00685     if (button_label_bm)
00686       return (void *)GETPIXMAP(button_label_bm);
00687   } else {
00688     if (label_bm)
00689       return (void *)GETPIXMAP(label_bm);
00690   }
00691 
00692   return (void *)GETPIXMAP(this);
00693 }
00694 
00695 void wxBitmap::ReleaseLabel()
00696 {
00697   if (!selectedIntoDC) {
00698     if (label_bm) {
00699       DELETE_OBJ label_bm;
00700       label_bm = NULL;
00701     }
00702     if (button_label_bm) {
00703       DELETE_OBJ button_label_bm;
00704       button_label_bm = NULL;
00705     }
00706   }
00707 }
00708 
00709 
00710 void wxBitmap::SetGLConfig(wxGLConfig *_gl_cfg)
00711 {
00712   if (_gl_cfg)
00713     _gl_cfg = _gl_cfg->Clone();
00714   gl_cfg = _gl_cfg;
00715 }
00716 
00717 wxGLConfig *wxBitmap::GetGLConfig(void)
00718 {
00719   if (gl_cfg)
00720     return gl_cfg->Clone();
00721   else
00722     return NULL;
00723 }
00724 
00725 //-----------------------------------------------------------------------------
00726 // wxCursor
00727 //-----------------------------------------------------------------------------
00728 
00729 /* wxCursor is a subclass of wxBitmap for historical reasons. It
00730    doesn't make any sense. */
00731 
00732 static XColor black = { 0, 0, 0, 0, 0, 0 };
00733 static XColor white = { 0, 65535, 65535, 65535, DoRed | DoGreen | DoBlue, 0 };
00734 
00735 wxCursor::wxCursor(void) : wxBitmap()
00736 {
00737     __type = wxTYPE_CURSOR;
00738 
00739     Xcursor = NULL;
00740 }
00741 
00742 wxCursor::wxCursor(wxBitmap *bm, wxBitmap *mask, int x, int y) : wxBitmap()
00743 {
00744     __type = wxTYPE_CURSOR;
00745 
00746     Xcursor = NULL;
00747 
00748     if (bm->Ok() && mask->Ok()
00749        && (bm->GetDepth() == 1)
00750        && (mask->GetDepth() == 1)
00751        && (bm->GetWidth() == mask->GetWidth())
00752        && (bm->GetHeight() == mask->GetHeight())) {
00753       Xcursor = new wxCursor_Xintern;
00754       Xcursor->x_cursor
00755        = XCreatePixmapCursor(wxAPP_DISPLAY,
00756                            bm->Xbitmap->x_pixmap, mask->Xbitmap->x_pixmap,
00757                            &black, &white,
00758                            x, y);
00759     }
00760 }
00761 
00762 static unsigned int x_cursor_id[] = { // same order as wxCURSOR_...
00763        XC_left_ptr,          XC_based_arrow_down,       XC_based_arrow_up,
00764        XC_target,           XC_crosshair,        XC_cross_reverse,
00765        XC_double_arrow,     XC_hand2,            XC_xterm,
00766        XC_leftbutton,              XC_sizing,           XC_middlebutton,
00767        XC_pirate,           XC_spraycan,         XC_pencil,
00768        XC_sb_left_arrow,    XC_sb_right_arrow,   XC_question_arrow,
00769        XC_rightbutton,             XC_circle,           XC_sb_v_double_arrow,
00770        XC_circle,           XC_sb_h_double_arrow,       XC_sizing,
00771        XC_spraycan,         XC_watch,            XC_watch,
00772       };
00773 
00774 static char char_data[32] = { // bits for char pointer
00775        0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
00776        0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
00777        0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
00778        0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
00779     };
00780 
00781 static char blank_data[32] = { // bits for blank pointer
00782        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00783        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00784        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00785        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00786     };
00787 
00788 static char nwse_bits[32] = {
00789  0x00,0x00,0x00,0x00,0xf8,0x00,0x38,0x00,0x58,0x00,0xa8,0x00,0x48,0x01,0x80,
00790  0x02,0x00,0x25,0x00,0x2a,0x00,0x34,0x00,0x38,0x00,0x3e,0x00,0x00,0x00,0x00,
00791  0x00,0x00};
00792 
00793 static char swne_bits[32] = {
00794  0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x38,0x00,0x34,0x00,0x2a,0x00,0x25,0x80,
00795  0x02,0x48,0x01,0xa8,0x00,0x58,0x00,0x38,0x00,0xf8,0x00,0x00,0x00,0x00,0x00,
00796  0x00,0x00};
00797 
00798 /* The xlib_spinning_[mask_]bits definition is taken from the Mozilla
00799    source code, "nsWidget.cpp". We're using it under the LGPL.
00800 
00801    My X server seems to recognize exactly this pattern of bits, and
00802    the actual cursor that is uses is prettier than the bits below. So
00803    don't change any of the bits. */
00804 
00805 static const char xlib_spinning_bits[] = {
00806   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
00807   0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
00808   0x7c, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00,
00809   0xfc, 0x3b, 0x00, 0x00, 0x7c, 0x38, 0x00, 0x00, 0x6c, 0x54, 0x00, 0x00,
00810   0xc4, 0xdc, 0x00, 0x00, 0xc0, 0x44, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00,
00811   0x80, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00812   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00813   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00814   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00815   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00816   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00817  
00818 static const char xlib_spinning_mask_bits[] = {
00819   0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
00820   0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
00821   0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe, 0x3b, 0x00, 0x00,
00822   0xfe, 0x7f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00,
00823   0xee, 0xff, 0x01, 0x00, 0xe4, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00,
00824   0xc0, 0x7f, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00825   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00826   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00827   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00828   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00829   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00830 
00831 wxCursor::wxCursor(int cursor_type) : wxBitmap()
00832 {
00833     Pixmap pixmap;
00834     
00835     __type = wxTYPE_CURSOR;
00836 
00837     Xcursor = new wxCursor_Xintern;
00838 
00839     switch (cursor_type) {
00840     case wxCURSOR_BLANK:
00841       pixmap = XCreateBitmapFromData(wxAPP_DISPLAY, wxAPP_ROOT, blank_data, 16, 16);
00842       Xcursor->x_cursor = XCreatePixmapCursor(wxAPP_DISPLAY, pixmap, pixmap, &black, &black, 8, 8);
00843       XFreePixmap(wxAPP_DISPLAY, pixmap);
00844       break;
00845     case wxCURSOR_CHAR:
00846       pixmap = XCreateBitmapFromData(wxAPP_DISPLAY, wxAPP_ROOT, char_data, 16, 16);
00847       Xcursor->x_cursor = XCreatePixmapCursor(wxAPP_DISPLAY, pixmap, pixmap, &black, &black, 0, 13);
00848       XFreePixmap(wxAPP_DISPLAY, pixmap);
00849       break;
00850     case wxCURSOR_SIZENESW:
00851       pixmap = XCreateBitmapFromData(wxAPP_DISPLAY, wxAPP_ROOT, swne_bits, 16, 16);
00852       Xcursor->x_cursor = XCreatePixmapCursor(wxAPP_DISPLAY, pixmap, pixmap, &black, &black, 0, 13);
00853       XFreePixmap(wxAPP_DISPLAY, pixmap);
00854       break;
00855     case wxCURSOR_SIZENWSE:
00856       pixmap = XCreateBitmapFromData(wxAPP_DISPLAY, wxAPP_ROOT, nwse_bits, 16, 16);
00857       Xcursor->x_cursor = XCreatePixmapCursor(wxAPP_DISPLAY, pixmap, pixmap, &black, &black, 0, 13);
00858       XFreePixmap(wxAPP_DISPLAY, pixmap);
00859       break;
00860     case wxCURSOR_WAIT:
00861       {
00862        Pixmap mask;
00863        pixmap = XCreateBitmapFromData(wxAPP_DISPLAY, wxAPP_ROOT, xlib_spinning_bits, 32, 32);
00864        mask = XCreateBitmapFromData(wxAPP_DISPLAY, wxAPP_ROOT, xlib_spinning_mask_bits, 32, 32);
00865        Xcursor->x_cursor = XCreatePixmapCursor(wxAPP_DISPLAY, pixmap, mask, &black, &white, 2, 2);
00866        XFreePixmap(wxAPP_DISPLAY, pixmap);
00867        XFreePixmap(wxAPP_DISPLAY, mask);
00868       }
00869       break;
00870     default:
00871       if (wxFIRST_X11_CURSOR <= cursor_type && cursor_type <= wxLAST_X11_CURSOR) {
00872        Xcursor->x_cursor = XCreateFontCursor(wxAPP_DISPLAY, x_cursor_id[cursor_type]);
00873       }
00874       break;
00875     }
00876     if (!Xcursor->x_cursor) {
00877       DELETE_OBJ Xcursor;
00878       Xcursor = NULL;
00879     }
00880 }
00881 
00882 wxCursor::~wxCursor(void)
00883 {
00884     if (Xcursor) {
00885       DELETE_OBJ Xcursor;
00886       Xcursor = NULL;
00887     }
00888 }
00889 
00890 void* wxCursor::GetHandle(void) { return (Xcursor ? &(Xcursor->x_cursor) : NULL); }