|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id: fl_color_win32.cxx 8129 2010-12-28 15:33:36Z manolo $" 00003 // 00004 // WIN32 color functions for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Copyright 1998-2010 by Bill Spitzak and others. 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Library General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Library General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 // USA. 00022 // 00023 // Please report all bugs and problems on the following page: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00028 // The fltk "colormap". This allows ui colors to be stored in 8-bit 00029 // locations, and provides a level of indirection so that global color 00030 // changes can be made. Not to be confused with the X colormap, which 00031 // I try to hide completely. 00032 00033 // SGI compiler seems to have problems with unsigned char arguments 00034 // being used to index arrays. So I always copy them to an integer 00035 // before use. 00036 00037 #include <config.h> 00038 #include <FL/Fl.H> 00039 #include <FL/x.H> 00040 #include <FL/fl_draw.H> 00041 00042 static unsigned fl_cmap[256] = { 00043 #include "fl_cmap.h" // this is a file produced by "cmap.cxx": 00044 }; 00045 00046 // Translations to win32 data structures: 00047 Fl_XMap fl_xmap[256]; 00048 00049 Fl_XMap* fl_current_xmap; 00050 00051 HPALETTE fl_palette; 00052 static HGDIOBJ tmppen=0; 00053 static HPEN savepen=0; 00054 00055 void fl_cleanup_pens(void) { 00056 for (int i=0; i<256; i++) { 00057 if (fl_xmap[i].pen) DeleteObject(fl_xmap[i].pen); 00058 } 00059 } 00060 00061 void fl_save_pen(void) { 00062 if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0); 00063 savepen = (HPEN)SelectObject(fl_gc, tmppen); 00064 } 00065 00066 void fl_restore_pen(void) { 00067 if (savepen) SelectObject(fl_gc, savepen); 00068 DeleteObject(tmppen); 00069 tmppen = 0; 00070 savepen = 0; 00071 } 00072 00073 static void clear_xmap(Fl_XMap& xmap) { 00074 if (xmap.pen) { 00075 HGDIOBJ tmppen = GetStockObject(BLACK_PEN); 00076 HGDIOBJ oldpen = SelectObject(fl_gc, tmppen); // Push out the current pen of the gc 00077 if(oldpen != xmap.pen) SelectObject(fl_gc, oldpen); // Put it back if it is not the one we are about to delete 00078 DeleteObject((HGDIOBJ)(xmap.pen)); 00079 xmap.pen = 0; 00080 xmap.brush = -1; 00081 } 00082 } 00083 00084 static void set_xmap(Fl_XMap& xmap, COLORREF c) { 00085 xmap.rgb = c; 00086 if (xmap.pen) { 00087 HGDIOBJ oldpen = SelectObject(fl_gc,GetStockObject(BLACK_PEN)); // replace current pen with safe one 00088 if (oldpen != xmap.pen)SelectObject(fl_gc,oldpen); // if old one not xmap.pen, need to put it back 00089 DeleteObject(xmap.pen); // delete pen 00090 } 00091 xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen 00092 xmap.brush = -1; 00093 } 00094 00095 Fl_Color fl_color_; 00096 00097 void Fl_GDI_Graphics_Driver::color(Fl_Color i) { 00098 if (i & 0xffffff00) { 00099 unsigned rgb = (unsigned)i; 00100 fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8)); 00101 } else { 00102 fl_color_ = i; 00103 Fl_XMap &xmap = fl_xmap[i]; 00104 if (!xmap.pen) { 00105 #if USE_COLORMAP 00106 if (fl_palette) { 00107 set_xmap(xmap, PALETTEINDEX(i)); 00108 } else { 00109 #endif 00110 unsigned c = fl_cmap[i]; 00111 set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8))); 00112 #if USE_COLORMAP 00113 } 00114 #endif 00115 } 00116 fl_current_xmap = ⟼ 00117 SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); 00118 } 00119 } 00120 00121 void Fl_GDI_Graphics_Driver::color(uchar r, uchar g, uchar b) { 00122 static Fl_XMap xmap; 00123 COLORREF c = RGB(r,g,b); 00124 fl_color_ = fl_rgb_color(r, g, b); 00125 if (!xmap.pen || c != xmap.rgb) { 00126 clear_xmap(xmap); 00127 set_xmap(xmap, c); 00128 } 00129 fl_current_xmap = ⟼ 00130 SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); 00131 } 00132 00133 HBRUSH fl_brush() { 00134 return fl_brush_action(0); 00135 } 00136 00137 HBRUSH fl_brush_action(int action) { 00138 Fl_XMap *xmap = fl_current_xmap; 00139 // Wonko: we use some statistics to cache only a limited number 00140 // of brushes: 00141 #define FL_N_BRUSH 16 00142 static struct Fl_Brush { 00143 HBRUSH brush; 00144 unsigned short usage; 00145 Fl_XMap* backref; 00146 } brushes[FL_N_BRUSH]; 00147 00148 if (action) { 00149 SelectObject(fl_gc, GetStockObject(BLACK_BRUSH)); // Load stock object 00150 for (int i=0; i<FL_N_BRUSH; i++) { 00151 if (brushes[i].brush) 00152 DeleteObject(brushes[i].brush); // delete all brushes in array 00153 } 00154 return NULL; 00155 } 00156 00157 int i = xmap->brush; // find the associated brush 00158 if (i != -1) { // if the brush was allready allocated 00159 if (brushes[i].brush == NULL) goto CREATE_BRUSH; 00160 if ( (++brushes[i].usage) > 32000 ) { // keep a usage statistic 00161 for (int j=0; j<FL_N_BRUSH; j++) { 00162 if (brushes[j].usage>16000) 00163 brushes[j].usage -= 16000; 00164 else 00165 brushes[j].usage = 0; 00166 } 00167 } 00168 return brushes[i].brush; 00169 } else { 00170 int umin = 32000, imin = 0; 00171 for (i=0; i<FL_N_BRUSH; i++) { 00172 if (brushes[i].brush == NULL) goto CREATE_BRUSH; 00173 if (brushes[i].usage<umin) { 00174 umin = brushes[i].usage; 00175 imin = i; 00176 } 00177 } 00178 i = imin; 00179 HGDIOBJ tmpbrush = GetStockObject(BLACK_BRUSH); // get a stock brush 00180 HGDIOBJ oldbrush = SelectObject(fl_gc,tmpbrush); // load in into current context 00181 if (oldbrush != brushes[i].brush) SelectObject(fl_gc,oldbrush); // reload old one 00182 DeleteObject(brushes[i].brush); // delete the one in list 00183 brushes[i].brush = NULL; 00184 brushes[i].backref->brush = -1; 00185 } 00186 CREATE_BRUSH: 00187 brushes[i].brush = CreateSolidBrush(xmap->rgb); 00188 brushes[i].usage = 0; 00189 brushes[i].backref = xmap; 00190 xmap->brush = i; 00191 return brushes[i].brush; 00192 } 00193 00194 void Fl::free_color(Fl_Color i, int overlay) { 00195 if (overlay) return; // do something about GL overlay? 00196 clear_xmap(fl_xmap[i]); 00197 } 00198 00199 void Fl::set_color(Fl_Color i, unsigned c) { 00200 if (fl_cmap[i] != c) { 00201 clear_xmap(fl_xmap[i]); 00202 fl_cmap[i] = c; 00203 } 00204 } 00205 00206 #if USE_COLORMAP 00207 00208 // 'fl_select_palette()' - Make a color palette for 8-bit displays if necessary 00209 // Thanks to Michael Sweet @ Easy Software Products for this 00210 00211 HPALETTE 00212 fl_select_palette(void) 00213 { 00214 static char beenhere; 00215 if (!beenhere) { 00216 beenhere = 1; 00217 00218 //if (GetDeviceCaps(fl_gc, BITSPIXEL) > 8) return NULL; 00219 int nColors = GetDeviceCaps(fl_gc, SIZEPALETTE); 00220 if (nColors <= 0 || nColors > 256) return NULL; 00221 // this will try to work on < 256 color screens, but will probably 00222 // come out quite badly. 00223 00224 // I lamely try to get this variable-sized object allocated on stack: 00225 ulong foo[(sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY))/sizeof(ulong)+1]; 00226 LOGPALETTE *pPal = (LOGPALETTE*)foo; 00227 00228 pPal->palVersion = 0x300; 00229 pPal->palNumEntries = nColors; 00230 00231 // Build 256 colors from the standard FLTK colormap... 00232 00233 for (int i = 0; i < nColors; i ++) { 00234 pPal->palPalEntry[i].peRed = (fl_cmap[i] >> 24) & 255; 00235 pPal->palPalEntry[i].peGreen = (fl_cmap[i] >> 16) & 255; 00236 pPal->palPalEntry[i].peBlue = (fl_cmap[i] >> 8) & 255; 00237 pPal->palPalEntry[i].peFlags = 0; 00238 }; 00239 00240 // Create the palette: 00241 fl_palette = CreatePalette(pPal); 00242 } 00243 if (fl_palette) { 00244 SelectPalette(fl_gc, fl_palette, FALSE); 00245 RealizePalette(fl_gc); 00246 } 00247 return fl_palette; 00248 } 00249 00250 #endif 00251 00252 // 00253 // End of "$Id: fl_color_win32.cxx 8129 2010-12-28 15:33:36Z manolo $". 00254 //