themes: Workaround for bug where a background color of RGB 0,0,0 in Black color schem...
[ntk.git] / src / Fl_Gl_Overlay.cxx
blobb9ef2b64ab7d64120c0b73535a47b962fefd29c1
1 //
2 // "$Id: Fl_Gl_Overlay.cxx 7903 2010-11-28 21:06:39Z matt $"
3 //
4 // OpenGL overlay code for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2010 by Bill Spitzak and others.
7 //
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
21 // USA.
23 // Please report all bugs and problems on the following page:
25 // http://www.fltk.org/str.php
28 #include <config.h>
29 #if HAVE_GL
31 #include <FL/Fl.H>
32 #include <FL/x.H>
33 #include "Fl_Gl_Choice.H"
34 #include <FL/Fl_Gl_Window.H>
35 #include <stdlib.h>
37 #if !HAVE_GL_OVERLAY
39 int Fl_Gl_Window::can_do_overlay() {return 0;}
41 void Fl_Gl_Window::make_overlay() {overlay = this;}
43 #else
45 // Methods on Fl_Gl_Window that create an overlay window. Because
46 // many programs don't need the overlay, this is separated into this
47 // source file so it is not linked in if not used.
49 // Under X this is done by creating another window, of class _Fl_Gl_Overlay
50 // which is a subclass of Fl_Gl_Window except it uses the overlay planes.
51 // A pointer to this is stored in the "overlay" pointer of the Fl_Gl_Window.
53 // Under win32 another GLX context is created to draw into the overlay
54 // and it is stored in the "overlay" pointer.
56 // In both cases if overlay hardware is unavailable, the overlay is
57 // "faked" by drawing into the main layers. This is indicated by
58 // setting overlay == this.
60 #ifndef WIN32
61 ////////////////////////////////////////////////////////////////
62 // X version
64 extern XVisualInfo *fl_find_overlay_visual();
65 extern XVisualInfo *fl_overlay_visual;
66 extern Colormap fl_overlay_colormap;
67 extern unsigned long fl_transparent_pixel;
68 extern uchar fl_overlay;
70 class _Fl_Gl_Overlay : public Fl_Gl_Window {
71 void flush();
72 void draw();
73 public:
74 void show();
75 _Fl_Gl_Overlay(int x, int y, int w, int h) :
76 Fl_Gl_Window(x,y,w,h) {
77 set_flag(INACTIVE);
81 void _Fl_Gl_Overlay::flush() {
82 make_current();
83 #ifdef BOXX_BUGS
84 // The BoXX overlay is broken and you must not call swap-buffers. This
85 // code will make it work, but we lose because machines that do support
86 // double-buffered overlays will blink when they don't have to
87 glDrawBuffer(GL_FRONT);
88 draw();
89 #else
90 draw();
91 swap_buffers();
92 #endif
93 glFlush();
94 valid(1);
97 void _Fl_Gl_Overlay::draw() {
98 if (!valid()) glClearIndex((GLfloat)fl_transparent_pixel);
99 if (damage() != FL_DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT);
100 Fl_Gl_Window *w = (Fl_Gl_Window *)parent();
101 uchar save_valid = w->valid();
102 w->valid(valid());
103 fl_overlay = 1;
104 w->draw_overlay();
105 fl_overlay = 0;
106 valid(w->valid());
107 w->valid(save_valid);
110 void _Fl_Gl_Overlay::show() {
111 if (!shown()) {
112 fl_background_pixel = int(fl_transparent_pixel);
113 Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
114 fl_background_pixel = -1;
115 // find the outermost window to tell wm about the colormap:
116 Fl_Window *w = window();
117 for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
118 XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
119 context(fl_create_gl_context(fl_overlay_visual), 1);
120 valid(0);
122 Fl_Gl_Window::show();
125 int Fl_Gl_Window::can_do_overlay() {
126 return fl_find_overlay_visual() != 0;
129 void Fl_Gl_Window::make_overlay() {
130 if (overlay) return;
131 if (can_do_overlay()) {
132 _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h());
133 overlay = o;
134 add(*o);
135 o->show();
136 } else {
137 overlay = this; // fake the overlay
141 #else
142 ////////////////////////////////////////////////////////////////
143 // WIN32 version:
145 //static COLORREF *palette;
146 extern int fl_overlay_depth;
148 void Fl_Gl_Window::make_overlay() {
149 if (overlay) return;
151 GLContext context = fl_create_gl_context(this, g, 1);
152 if (!context) {overlay = this; return;} // fake the overlay
154 HDC hdc = Fl_X::i(this)->private_dc;
155 overlay = context;
156 LAYERPLANEDESCRIPTOR pfd;
157 wglDescribeLayerPlane(hdc, g->pixelformat, 1, sizeof(pfd), &pfd);
158 if (!pfd.iPixelType) {
159 ; // full-color overlay
160 } else {
161 fl_overlay_depth = pfd.cColorBits; // used by gl_color()
162 if (fl_overlay_depth > 8) fl_overlay_depth = 8;
163 COLORREF palette[256];
164 int n = (1<<fl_overlay_depth)-1;
165 // copy all colors except #0 into the overlay palette:
166 for (int i = 0; i <= n; i++) {
167 uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b);
168 palette[i] = RGB(r,g,b);
170 // always provide black & white in the last 2 pixels:
171 if (fl_overlay_depth < 8) {
172 palette[n-1] = RGB(0,0,0);
173 palette[n] = RGB(255,255,255);
175 // and use it:
176 wglSetLayerPaletteEntries(hdc, 1, 1, n, palette+1);
177 wglRealizeLayerPalette(hdc, 1, TRUE);
179 valid(0);
180 return;
183 int Fl_Gl_Window::can_do_overlay() {
184 if (!g) {
185 g = Fl_Gl_Choice::find(mode_,alist);
186 if (!g) return 0;
188 return (g->pfd.bReserved & 15) != 0;
191 ////////////////////////////////////////////////////////////////
192 #endif
194 #endif
196 void Fl_Gl_Window::redraw_overlay() {
197 if (!shown()) return;
198 make_overlay();
199 #ifdef __APPLE__
200 redraw();
201 #else
202 #ifndef WIN32
203 if (overlay != this)
204 ((Fl_Gl_Window*)overlay)->redraw();
205 else
206 #endif
207 damage(FL_DAMAGE_OVERLAY);
208 #endif
211 void Fl_Gl_Window::make_overlay_current() {
212 make_overlay();
213 #ifdef __APPLE__
214 // this is not very useful, but unfortunately, Apple decided
215 // that front buffer drawing can no longer (OS X 10.4) be
216 // supported on their platforms.
217 make_current();
218 #else
219 #if HAVE_GL_OVERLAY
220 if (overlay != this) {
221 #ifdef WIN32
222 fl_set_gl_context(this, (GLContext)overlay);
223 // if (fl_overlay_depth)
224 // wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
225 #else
226 ((Fl_Gl_Window*)overlay)->make_current();
227 #endif
228 } else
229 #endif
230 glDrawBuffer(GL_FRONT);
231 #endif
233 /** Hides the window if it is not this window, does nothing in WIN32. */
234 void Fl_Gl_Window::hide_overlay() {
235 #if HAVE_GL_OVERLAY
236 #ifdef WIN32
237 // nothing needs to be done? Or should it be erased?
238 #else
239 if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide();
240 #endif
241 #endif
244 #endif
247 // End of "$Id: Fl_Gl_Overlay.cxx 7903 2010-11-28 21:06:39Z matt $".