1998-10-20 00:46:58 +04:00
|
|
|
//
|
2000-09-15 11:52:51 +04:00
|
|
|
// "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.12 2000/09/15 07:52:51 spitzak Exp $"
|
1998-10-20 00:46:58 +04:00
|
|
|
//
|
|
|
|
// OpenGL overlay code for the Fast Light Tool Kit (FLTK).
|
|
|
|
//
|
2000-04-26 02:17:00 +04:00
|
|
|
// Copyright 1998-2000 by Bill Spitzak and others.
|
1998-10-20 00:46:58 +04:00
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Library General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Library General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Library General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
// USA.
|
|
|
|
//
|
2000-06-06 01:21:24 +04:00
|
|
|
// Please report all bugs and problems to "fltk-bugs@fltk.org".
|
1998-10-20 00:46:58 +04:00
|
|
|
//
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
#if HAVE_GL
|
|
|
|
|
|
|
|
#include <FL/Fl.H>
|
|
|
|
#include <FL/Fl_Gl_Window.H>
|
|
|
|
#include <FL/x.H>
|
|
|
|
#include "Fl_Gl_Choice.H"
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#if HAVE_GL_OVERLAY
|
|
|
|
|
2000-04-07 20:55:46 +04:00
|
|
|
#ifndef _WIN32
|
1998-10-06 22:21:25 +04:00
|
|
|
|
|
|
|
// Methods on Fl_Gl_Window that create an overlay window. Because
|
|
|
|
// many programs don't need the overlay, this is seperated into this
|
|
|
|
// source file so it is not linked in if not used.
|
|
|
|
|
|
|
|
// Under X this is done by creating another window, of class _Fl_Gl_Overlay
|
|
|
|
// which is a subclass of Fl_Gl_Window except it uses the overlay planes.
|
|
|
|
// A pointer to this is stored in the "overlay" pointer of the Fl_Gl_Window.
|
|
|
|
|
|
|
|
// Under win32 another GLX context is created to draw into the overlay
|
|
|
|
// and it is stored in into the "overlay" pointer.
|
|
|
|
|
|
|
|
// In both cases if overlay hardware is unavailable, the overlay is
|
|
|
|
// "faked" by drawing into the main layers. This is indicated by
|
|
|
|
// setting overlay == this.
|
|
|
|
|
|
|
|
extern XVisualInfo *fl_find_overlay_visual();
|
|
|
|
extern XVisualInfo *fl_overlay_visual;
|
|
|
|
extern Colormap fl_overlay_colormap;
|
|
|
|
extern unsigned long fl_transparent_pixel;
|
|
|
|
static Fl_Gl_Choice overlay_choice;
|
|
|
|
extern uchar fl_overlay;
|
|
|
|
|
|
|
|
class _Fl_Gl_Overlay : public Fl_Gl_Window {
|
|
|
|
void draw();
|
|
|
|
public:
|
|
|
|
void show();
|
|
|
|
_Fl_Gl_Overlay(int x, int y, int w, int h) :
|
|
|
|
Fl_Gl_Window(x,y,w,h) {
|
2000-03-18 13:04:18 +03:00
|
|
|
set_flag(INACTIVE);
|
1998-10-06 22:21:25 +04:00
|
|
|
overlay_choice.vis = fl_overlay_visual;
|
|
|
|
overlay_choice.colormap = fl_overlay_colormap;
|
|
|
|
overlay_choice.r = 0;
|
|
|
|
overlay_choice.d = 0;
|
|
|
|
overlay_choice.o = 1;
|
|
|
|
g = &overlay_choice;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void _Fl_Gl_Overlay::draw() {
|
2000-06-29 11:23:56 +04:00
|
|
|
if (!valid_) glClearIndex((GLfloat)fl_transparent_pixel);
|
1998-10-19 21:53:09 +04:00
|
|
|
if (damage() != FL_DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT);
|
1998-10-06 22:21:25 +04:00
|
|
|
Fl_Gl_Window *w = (Fl_Gl_Window *)parent();
|
|
|
|
uchar save_valid = w->valid_;
|
|
|
|
w->valid_ = valid_;
|
|
|
|
fl_overlay = 1;
|
|
|
|
w->draw_overlay();
|
|
|
|
fl_overlay = 0;
|
|
|
|
valid_ = w->valid_;
|
|
|
|
w->valid_ = save_valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
void _Fl_Gl_Overlay::show() {
|
|
|
|
if (shown()) {Fl_Gl_Window::show(); return;}
|
|
|
|
fl_background_pixel = int(fl_transparent_pixel);
|
|
|
|
Fl_Gl_Window::show();
|
|
|
|
fl_background_pixel = -1;
|
|
|
|
// find the outermost window to tell wm about the colormap:
|
|
|
|
Fl_Window *w = window();
|
|
|
|
for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
|
|
|
|
XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Fl_Gl_Window::can_do_overlay() {
|
|
|
|
return fl_find_overlay_visual() != 0;
|
|
|
|
}
|
|
|
|
|
2000-04-07 20:55:46 +04:00
|
|
|
#else // _WIN32:
|
1998-10-06 22:21:25 +04:00
|
|
|
|
|
|
|
int Fl_Gl_Window::can_do_overlay() {
|
2000-03-18 13:04:18 +03:00
|
|
|
Fl_Gl_Choice* choice = Fl_Gl_Choice::find(0,0);
|
|
|
|
return (choice && (choice->pfd.bReserved & 15));
|
1998-10-06 22:21:25 +04:00
|
|
|
}
|
|
|
|
|
2000-04-07 20:55:46 +04:00
|
|
|
extern int fl_overlay_depth;
|
2000-03-24 11:42:03 +03:00
|
|
|
|
1998-10-06 22:21:25 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
int Fl_Gl_Window::can_do_overlay() {return 0;}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void Fl_Gl_Window::make_overlay() {
|
|
|
|
if (!overlay) {
|
|
|
|
#if HAVE_GL_OVERLAY
|
2000-04-07 20:55:46 +04:00
|
|
|
#ifdef _WIN32
|
2000-03-24 11:55:34 +03:00
|
|
|
HDC hdc = fl_private_dc(this, mode_,&g);
|
|
|
|
GLXContext context = wglCreateLayerContext(hdc, 1);
|
2000-04-07 20:55:46 +04:00
|
|
|
if (context) { // we found a usable overlay context
|
2000-03-24 11:55:34 +03:00
|
|
|
if (fl_first_context) wglShareLists(fl_first_context, context);
|
|
|
|
else fl_first_context = context;
|
|
|
|
overlay = context;
|
|
|
|
LAYERPLANEDESCRIPTOR pfd;
|
|
|
|
wglDescribeLayerPlane(hdc, g->pixelformat, 1, sizeof(pfd), &pfd);
|
|
|
|
if (!pfd.iPixelType) {
|
|
|
|
; // full-color overlay
|
2000-03-24 11:42:03 +03:00
|
|
|
} else {
|
2000-03-24 11:55:34 +03:00
|
|
|
fl_overlay_depth = pfd.cColorBits; // used by gl_color()
|
|
|
|
if (fl_overlay_depth > 8) fl_overlay_depth = 8;
|
|
|
|
COLORREF palette[256];
|
2000-06-10 22:24:31 +04:00
|
|
|
int n = (1<<fl_overlay_depth)-1;
|
2000-03-24 11:55:34 +03:00
|
|
|
// copy all colors except #0 into the overlay palette:
|
2000-06-10 22:24:31 +04:00
|
|
|
for (int i = 0; i <= n; i++) {
|
2000-03-24 11:55:34 +03:00
|
|
|
uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b);
|
|
|
|
palette[i] = RGB(r,g,b);
|
2000-03-24 11:42:03 +03:00
|
|
|
}
|
2000-03-24 11:55:34 +03:00
|
|
|
// always provide black & white in the last 2 pixels:
|
|
|
|
if (fl_overlay_depth < 8) {
|
2000-06-10 22:24:31 +04:00
|
|
|
palette[n-1] = RGB(0,0,0);
|
|
|
|
palette[n] = RGB(255,255,255);
|
2000-03-24 11:55:34 +03:00
|
|
|
}
|
|
|
|
// and use it:
|
2000-06-10 22:24:31 +04:00
|
|
|
wglSetLayerPaletteEntries(hdc, 1, 1, n, palette+1);
|
2000-03-24 11:55:34 +03:00
|
|
|
wglRealizeLayerPalette(hdc, 1, TRUE);
|
1998-10-06 22:21:25 +04:00
|
|
|
}
|
2000-03-24 11:55:34 +03:00
|
|
|
valid(0);
|
|
|
|
return;
|
1998-10-06 22:21:25 +04:00
|
|
|
}
|
2000-03-24 11:42:03 +03:00
|
|
|
#else
|
1998-10-06 22:21:25 +04:00
|
|
|
if (can_do_overlay()) {
|
|
|
|
_Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h());
|
|
|
|
overlay = o;
|
2000-09-15 11:52:51 +04:00
|
|
|
add(*o);
|
1998-10-06 22:21:25 +04:00
|
|
|
o->show();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
overlay = this; // fake the overlay
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Fl_Gl_Window::redraw_overlay() {
|
|
|
|
if (!shown()) return;
|
|
|
|
make_overlay();
|
2000-04-07 20:55:46 +04:00
|
|
|
#ifndef _WIN32
|
1998-10-06 22:21:25 +04:00
|
|
|
if (overlay != this)
|
|
|
|
((Fl_Gl_Window*)overlay)->redraw();
|
|
|
|
else
|
|
|
|
#endif
|
1998-10-19 21:53:09 +04:00
|
|
|
damage(FL_DAMAGE_OVERLAY);
|
1998-10-06 22:21:25 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void Fl_Gl_Window::make_overlay_current() {
|
|
|
|
make_overlay();
|
|
|
|
#if HAVE_GL_OVERLAY
|
|
|
|
if (overlay != this) {
|
2000-04-07 20:55:46 +04:00
|
|
|
#ifdef _WIN32
|
1999-09-16 09:34:27 +04:00
|
|
|
fl_set_gl_context(this, (GLXContext)overlay);
|
2000-06-10 22:24:31 +04:00
|
|
|
// if (fl_overlay_depth)
|
|
|
|
// wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
|
1998-10-06 22:21:25 +04:00
|
|
|
#else
|
1999-09-16 09:34:27 +04:00
|
|
|
((Fl_Gl_Window*)overlay)->make_current();
|
1998-10-06 22:21:25 +04:00
|
|
|
#endif
|
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
glDrawBuffer(GL_FRONT);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Fl_Gl_Window::hide_overlay() {
|
|
|
|
#if HAVE_GL_OVERLAY
|
2000-04-07 20:55:46 +04:00
|
|
|
#ifdef _WIN32
|
1998-10-06 22:21:25 +04:00
|
|
|
// nothing needs to be done? Or should it be erased?
|
|
|
|
#else
|
|
|
|
if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide();
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
1998-10-20 00:46:58 +04:00
|
|
|
|
|
|
|
//
|
2000-09-15 11:52:51 +04:00
|
|
|
// End of "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.12 2000/09/15 07:52:51 spitzak Exp $".
|
1998-10-20 00:46:58 +04:00
|
|
|
//
|