2 // "$Id: fl_color_win32.cxx 8384 2011-02-06 12:32:23Z manolo $"
4 // WIN32 color functions for the Fast Light Tool Kit (FLTK).
6 // Copyright 1998-2010 by Bill Spitzak and others.
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 // Please report all bugs and problems on the following page:
25 // http://www.fltk.org/str.php
28 // The fltk "colormap". This allows ui colors to be stored in 8-bit
29 // locations, and provides a level of indirection so that global color
30 // changes can be made. Not to be confused with the X colormap, which
31 // I try to hide completely.
33 // SGI compiler seems to have problems with unsigned char arguments
34 // being used to index arrays. So I always copy them to an integer
40 #include <FL/fl_draw.H>
42 static unsigned fl_cmap
[256] = {
43 #include "fl_cmap.h" // this is a file produced by "cmap.cxx":
46 // Translations to win32 data structures:
49 Fl_XMap
* fl_current_xmap
;
52 static HGDIOBJ tmppen
=0;
53 static HPEN savepen
=0;
55 void fl_cleanup_pens(void) {
56 for (int i
=0; i
<256; i
++) {
57 if (fl_xmap
[i
].pen
) DeleteObject(fl_xmap
[i
].pen
);
61 void fl_save_pen(void) {
62 if(!tmppen
) tmppen
= CreatePen(PS_SOLID
, 1, 0);
63 savepen
= (HPEN
)SelectObject(fl_gc
, tmppen
);
66 void fl_restore_pen(void) {
67 if (savepen
) SelectObject(fl_gc
, savepen
);
73 static void clear_xmap(Fl_XMap
& xmap
) {
75 HGDIOBJ tmppen
= GetStockObject(BLACK_PEN
);
76 HGDIOBJ oldpen
= SelectObject(fl_gc
, tmppen
); // Push out the current pen of the gc
77 if(oldpen
!= xmap
.pen
) SelectObject(fl_gc
, oldpen
); // Put it back if it is not the one we are about to delete
78 DeleteObject((HGDIOBJ
)(xmap
.pen
));
84 static void set_xmap(Fl_XMap
& xmap
, COLORREF c
) {
87 HGDIOBJ oldpen
= SelectObject(fl_gc
,GetStockObject(BLACK_PEN
)); // replace current pen with safe one
88 if (oldpen
!= xmap
.pen
)SelectObject(fl_gc
,oldpen
); // if old one not xmap.pen, need to put it back
89 DeleteObject(xmap
.pen
); // delete pen
91 xmap
.pen
= CreatePen(PS_SOLID
, 1, xmap
.rgb
); // get a pen into xmap.pen
95 void Fl_GDI_Graphics_Driver::color(Fl_Color i
) {
97 unsigned rgb
= (unsigned)i
;
98 fl_color((uchar
)(rgb
>> 24), (uchar
)(rgb
>> 16), (uchar
)(rgb
>> 8));
100 Fl_Graphics_Driver::color(i
);
101 Fl_XMap
&xmap
= fl_xmap
[i
];
105 set_xmap(xmap
, PALETTEINDEX(i
));
108 unsigned c
= fl_cmap
[i
];
109 set_xmap(xmap
, RGB(uchar(c
>>24), uchar(c
>>16), uchar(c
>>8)));
114 fl_current_xmap
= &xmap
;
115 SelectObject(fl_gc
, (HGDIOBJ
)(xmap
.pen
));
119 void Fl_GDI_Graphics_Driver::color(uchar r
, uchar g
, uchar b
) {
121 COLORREF c
= RGB(r
,g
,b
);
122 Fl_Graphics_Driver::color( fl_rgb_color(r
, g
, b
) );
123 if (!xmap
.pen
|| c
!= xmap
.rgb
) {
127 fl_current_xmap
= &xmap
;
128 SelectObject(fl_gc
, (HGDIOBJ
)(xmap
.pen
));
132 return fl_brush_action(0);
135 HBRUSH
fl_brush_action(int action
) {
136 Fl_XMap
*xmap
= fl_current_xmap
;
137 // Wonko: we use some statistics to cache only a limited number
139 #define FL_N_BRUSH 16
140 static struct Fl_Brush
{
142 unsigned short usage
;
144 } brushes
[FL_N_BRUSH
];
147 SelectObject(fl_gc
, GetStockObject(BLACK_BRUSH
)); // Load stock object
148 for (int i
=0; i
<FL_N_BRUSH
; i
++) {
149 if (brushes
[i
].brush
)
150 DeleteObject(brushes
[i
].brush
); // delete all brushes in array
155 int i
= xmap
->brush
; // find the associated brush
156 if (i
!= -1) { // if the brush was allready allocated
157 if (brushes
[i
].brush
== NULL
) goto CREATE_BRUSH
;
158 if ( (++brushes
[i
].usage
) > 32000 ) { // keep a usage statistic
159 for (int j
=0; j
<FL_N_BRUSH
; j
++) {
160 if (brushes
[j
].usage
>16000)
161 brushes
[j
].usage
-= 16000;
163 brushes
[j
].usage
= 0;
166 return brushes
[i
].brush
;
168 int umin
= 32000, imin
= 0;
169 for (i
=0; i
<FL_N_BRUSH
; i
++) {
170 if (brushes
[i
].brush
== NULL
) goto CREATE_BRUSH
;
171 if (brushes
[i
].usage
<umin
) {
172 umin
= brushes
[i
].usage
;
177 HGDIOBJ tmpbrush
= GetStockObject(BLACK_BRUSH
); // get a stock brush
178 HGDIOBJ oldbrush
= SelectObject(fl_gc
,tmpbrush
); // load in into current context
179 if (oldbrush
!= brushes
[i
].brush
) SelectObject(fl_gc
,oldbrush
); // reload old one
180 DeleteObject(brushes
[i
].brush
); // delete the one in list
181 brushes
[i
].brush
= NULL
;
182 brushes
[i
].backref
->brush
= -1;
185 brushes
[i
].brush
= CreateSolidBrush(xmap
->rgb
);
186 brushes
[i
].usage
= 0;
187 brushes
[i
].backref
= xmap
;
189 return brushes
[i
].brush
;
192 void Fl::free_color(Fl_Color i
, int overlay
) {
193 if (overlay
) return; // do something about GL overlay?
194 clear_xmap(fl_xmap
[i
]);
197 void Fl::set_color(Fl_Color i
, unsigned c
) {
198 if (fl_cmap
[i
] != c
) {
199 clear_xmap(fl_xmap
[i
]);
206 // 'fl_select_palette()' - Make a color palette for 8-bit displays if necessary
207 // Thanks to Michael Sweet @ Easy Software Products for this
210 fl_select_palette(void)
212 static char beenhere
;
216 //if (GetDeviceCaps(fl_gc, BITSPIXEL) > 8) return NULL;
217 int nColors
= GetDeviceCaps(fl_gc
, SIZEPALETTE
);
218 if (nColors
<= 0 || nColors
> 256) return NULL
;
219 // this will try to work on < 256 color screens, but will probably
220 // come out quite badly.
222 // I lamely try to get this variable-sized object allocated on stack:
223 ulong foo
[(sizeof(LOGPALETTE
)+256*sizeof(PALETTEENTRY
))/sizeof(ulong
)+1];
224 LOGPALETTE
*pPal
= (LOGPALETTE
*)foo
;
226 pPal
->palVersion
= 0x300;
227 pPal
->palNumEntries
= nColors
;
229 // Build 256 colors from the standard FLTK colormap...
231 for (int i
= 0; i
< nColors
; i
++) {
232 pPal
->palPalEntry
[i
].peRed
= (fl_cmap
[i
] >> 24) & 255;
233 pPal
->palPalEntry
[i
].peGreen
= (fl_cmap
[i
] >> 16) & 255;
234 pPal
->palPalEntry
[i
].peBlue
= (fl_cmap
[i
] >> 8) & 255;
235 pPal
->palPalEntry
[i
].peFlags
= 0;
238 // Create the palette:
239 fl_palette
= CreatePalette(pPal
);
242 SelectPalette(fl_gc
, fl_palette
, FALSE
);
243 RealizePalette(fl_gc
);
251 // End of "$Id: fl_color_win32.cxx 8384 2011-02-06 12:32:23Z manolo $".