summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/opengl')
-rw-r--r--tqtinterface/qt4/src/opengl/qt_opengl.pri18
-rw-r--r--tqtinterface/qt4/src/opengl/tqgl.cpp2374
-rw-r--r--tqtinterface/qt4/src/opengl/tqgl.h542
-rw-r--r--tqtinterface/qt4/src/opengl/tqgl_x11.cpp1425
-rw-r--r--tqtinterface/qt4/src/opengl/tqgl_x11_p.h197
-rw-r--r--tqtinterface/qt4/src/opengl/tqglcolormap.cpp292
-rw-r--r--tqtinterface/qt4/src/opengl/tqglcolormap.h99
7 files changed, 4947 insertions, 0 deletions
diff --git a/tqtinterface/qt4/src/opengl/qt_opengl.pri b/tqtinterface/qt4/src/opengl/qt_opengl.pri
new file mode 100644
index 0000000..9e324db
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/qt_opengl.pri
@@ -0,0 +1,18 @@
+# Qt opengl module
+
+opengl {
+ HEADERS += $$OPENGL_H/tqgl.h \
+ $$OPENGL_H/tqglcolormap.h
+ SOURCES += $$OPENGL_CPP/tqgl.cpp \
+ $$OPENGL_CPP/tqglcolormap.cpp
+ x11 {
+ HEADERS += $$OPENGL_H/tqgl_x11_p.h
+ SOURCES += $$OPENGL_CPP/tqgl_x11.cpp
+ }
+ else:mac:SOURCES += $$OPENGL_CPP/tqgl_mac.cpp
+ else:win32:SOURCES += $$OPENGL_CPP/tqgl_win.cpp
+
+ dlopen_opengl:DEFINES+=TQT_DLOPEN_OPENGL
+}
+
+
diff --git a/tqtinterface/qt4/src/opengl/tqgl.cpp b/tqtinterface/qt4/src/opengl/tqgl.cpp
new file mode 100644
index 0000000..80e3658
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqgl.cpp
@@ -0,0 +1,2374 @@
+/****************************************************************************
+**
+** Implementation of OpenGL classes for TQt
+**
+** Created : 970112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the opengl module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqgl.h"
+#include "tqpixmap.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqimage.h"
+#include "tqcleanuphandler.h"
+#include "tqptrdict.h"
+
+static TQGLFormat* qgl_default_format = 0;
+static TQGLFormat* qgl_default_overlay_format = 0;
+
+#if defined(TQ_WS_X11)
+#include "private/tqt_x11_p.h"
+#define INT32 dummy_INT32
+#define INT8 dummy_INT8
+#include <GL/glx.h>
+#undef INT32
+#undef INT8
+#include "tqgl_x11_p.h"
+#endif
+
+static TQCleanupHandler<TQGLFormat> qgl_cleanup_format;
+
+
+/*!
+ \class TQGL tqgl.h
+ \brief The TQGL class is a namespace for miscellaneous identifiers
+ in the TQt OpenGL module.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module OpenGL
+ \ingroup graphics
+ \ingroup images
+
+
+ Normally you can ignore this class. TQGLWidget and the other
+ OpenGL<sup>*</sup> module classes inherit it, so when you make your
+ own TQGLWidget subclass you can use the identifiers in the TQGL
+ namespace without qualification.
+
+ However, you may occasionally tqfind yourself in situations where you
+ need to refer to these identifiers from outside the TQGL namespace's
+ scope, e.g. in static functions. In such cases, simply write e.g. \c
+ TQGL::DoubleBuffer instead of just \c DoubleBuffer.
+
+ <sup>*</sup> OpenGL is a trademark of Silicon Graphics, Inc. in the
+ United States and other countries.
+
+*/
+
+
+/*****************************************************************************
+ TQGLFormat implementation
+ *****************************************************************************/
+
+
+/*!
+ \class TQGLFormat tqgl.h
+ \brief The TQGLFormat class specifies the display format of an OpenGL
+ rendering context.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup graphics
+ \ingroup images
+ \module OpenGL
+
+ A display format has several characteristics:
+ \list
+ \i \link setDoubleBuffer() Double or single buffering.\endlink
+ \i \link setDepth() Depth buffer.\endlink
+ \i \link setRgba() RGBA or color index mode.\endlink
+ \i \link setAlpha() Alpha channel.\endlink
+ \i \link setAccum() Accumulation buffer.\endlink
+ \i \link setStencil() Stencil buffer.\endlink
+ \i \link setStereo() Stereo buffers.\endlink
+ \i \link setDirectRendering() Direct rendering.\endlink
+ \i \link setOverlay() Presence of an overlay.\endlink
+ \i \link setPlane() The plane of an overlay format.\endlink
+ \endlist
+
+ You create and tell a TQGLFormat object what rendering options you
+ want from an OpenGL<sup>*</sup> rendering context.
+
+ OpenGL drivers or accelerated hardware may or may not support
+ advanced features such as alpha channel or stereographic viewing.
+ If you request some features that the driver/hardware does not
+ provide when you create a TQGLWidget, you will get a rendering
+ context with the nearest subset of features.
+
+ There are different ways to define the display characteristics of
+ a rendering context. One is to create a TQGLFormat and make it the
+ default for the entire application:
+ \code
+ TQGLFormat f;
+ f.setAlpha( TRUE );
+ f.setStereo( TRUE );
+ TQGLFormat::setDefaultFormat( f );
+ \endcode
+
+ Or you can specify the desired format when creating an object of
+ your TQGLWidget subclass:
+ \code
+ TQGLFormat f;
+ f.setDoubleBuffer( FALSE ); // single buffer
+ f.setDirectRendering( FALSE ); // software rendering
+ MyGLWidget* myWidget = new MyGLWidget( f, ... );
+ \endcode
+
+ After the widget has been created, you can tqfind out which of the
+ requested features the system was able to provide:
+ \code
+ TQGLFormat f;
+ f.setOverlay( TRUE );
+ f.setStereo( TRUE );
+ MyGLWidget* myWidget = new MyGLWidget( f, ... );
+ if ( !w->format().stereo() ) {
+ // ok, goggles off
+ if ( !w->format().hasOverlay() ) {
+ qFatal( "Cool hardware required" );
+ }
+ }
+ \endcode
+
+ <sup>*</sup> OpenGL is a trademark of Silicon Graphics, Inc. in the
+ United States and other countries.
+
+ \sa TQGLContext, TQGLWidget
+*/
+
+
+/*!
+ Constructs a TQGLFormat object with the factory default settings:
+ \list
+ \i \link setDoubleBuffer() Double buffer:\endlink Enabled.
+ \i \link setDepth() Depth buffer:\endlink Enabled.
+ \i \link setRgba() RGBA:\endlink Enabled (i.e., color index disabled).
+ \i \link setAlpha() Alpha channel:\endlink Disabled.
+ \i \link setAccum() Accumulator buffer:\endlink Disabled.
+ \i \link setStencil() Stencil buffer:\endlink Disabled.
+ \i \link setStereo() Stereo:\endlink Disabled.
+ \i \link setDirectRendering() Direct rendering:\endlink Enabled.
+ \i \link setOverlay() Overlay:\endlink Disabled.
+ \i \link setPlane() Plane:\endlink 0 (i.e., normal plane).
+ \endlist
+*/
+
+TQGLFormat::TQGLFormat()
+{
+ opts = DoubleBuffer | DepthBuffer | Rgba | DirectRendering;
+ pln = 0;
+}
+
+
+/*!
+ Creates a TQGLFormat object that is a copy of the current \link
+ defaultFormat() application default format\endlink.
+
+ If \a options is not 0, this copy is modified by these format
+ options. The \a options parameter should be \c FormatOption values
+ OR'ed together.
+
+ This constructor makes it easy to specify a certain desired format
+ in classes derived from TQGLWidget, for example:
+ \code
+ // The rendering in MyGLWidget depends on using
+ // stencil buffer and alpha channel
+ MyGLWidget::MyGLWidget( TQWidget* tqparent, const char* name )
+ : TQGLWidget( TQGLFormat( StencilBuffer | AlphaChannel ), tqparent, name )
+ {
+ if ( !format().stencil() )
+ qWarning( "Could not get stencil buffer; results will be suboptimal" );
+ if ( !format().alphaChannel() )
+ qWarning( "Could not get alpha channel; results will be suboptimal" );
+ ...
+ }
+ \endcode
+
+ Note that there are \c FormatOption values to turn format settings
+ both on and off, e.g. \c DepthBuffer and \c NoDepthBuffer,
+ \c DirectRendering and \c IndirectRendering, etc.
+
+ The \a plane parameter defaults to 0 and is the plane which this
+ format should be associated with. Not all OpenGL implmentations
+ supports overlay/underlay rendering planes.
+
+ \sa defaultFormat(), setOption()
+*/
+
+TQGLFormat::TQGLFormat( int options, int plane )
+{
+ uint newOpts = options;
+ opts = defaultFormat().opts;
+ opts |= ( newOpts & 0xffff );
+ opts &= ~( newOpts >> 16 );
+ pln = plane;
+}
+
+
+/*!
+ \fn bool TQGLFormat::doubleBuffer() const
+
+ Returns TRUE if double buffering is enabled; otherwise returns
+ FALSE. Double buffering is enabled by default.
+
+ \sa setDoubleBuffer()
+*/
+
+/*!
+ If \a enable is TRUE sets double buffering; otherwise sets single
+ buffering.
+
+ Double buffering is enabled by default.
+
+ Double buffering is a technique where graphics are rendered on an
+ off-screen buffer and not directly to the screen. When the drawing
+ has been completed, the program calls a swapBuffers() function to
+ exchange the screen contents with the buffer. The result is
+ flicker-free drawing and often better performance.
+
+ \sa doubleBuffer(), TQGLContext::swapBuffers(),
+ TQGLWidget::swapBuffers()
+*/
+
+void TQGLFormat::setDoubleBuffer( bool enable )
+{
+ setOption( enable ? DoubleBuffer : SingleBuffer );
+}
+
+
+/*!
+ \fn bool TQGLFormat::depth() const
+
+ Returns TRUE if the depth buffer is enabled; otherwise returns
+ FALSE. The depth buffer is enabled by default.
+
+ \sa setDepth()
+*/
+
+/*!
+ If \a enable is TRUE enables the depth buffer; otherwise disables
+ the depth buffer.
+
+ The depth buffer is enabled by default.
+
+ The purpose of a depth buffer (or Z-buffering) is to remove hidden
+ surfaces. Pixels are assigned Z values based on the distance to
+ the viewer. A pixel with a high Z value is closer to the viewer
+ than a pixel with a low Z value. This information is used to
+ decide whether to draw a pixel or not.
+
+ \sa depth()
+*/
+
+void TQGLFormat::setDepth( bool enable )
+{
+ setOption( enable ? DepthBuffer : NoDepthBuffer );
+}
+
+
+/*!
+ \fn bool TQGLFormat::rgba() const
+
+ Returns TRUE if RGBA color mode is set. Returns FALSE if color
+ index mode is set. The default color mode is RGBA.
+
+ \sa setRgba()
+*/
+
+/*!
+ If \a enable is TRUE sets RGBA mode. If \a enable is FALSE sets
+ color index mode.
+
+ The default color mode is RGBA.
+
+ RGBA is the preferred mode for most OpenGL applications. In RGBA
+ color mode you specify colors as red + green + blue + alpha
+ quadruplets.
+
+ In color index mode you specify an index into a color lookup
+ table.
+
+ \sa rgba()
+*/
+
+void TQGLFormat::setRgba( bool enable )
+{
+ setOption( enable ? Rgba : ColorIndex );
+}
+
+
+/*!
+ \fn bool TQGLFormat::alpha() const
+
+ Returns TRUE if the alpha channel of the framebuffer is enabled;
+ otherwise returns FALSE. The alpha channel is disabled by default.
+
+ \sa setAlpha()
+*/
+
+/*!
+ If \a enable is TRUE enables the alpha channel; otherwise disables
+ the alpha channel.
+
+ The alpha buffer is disabled by default.
+
+ The alpha channel is typically used for implementing transparency
+ or translucency. The A in RGBA specifies the transparency of a
+ pixel.
+
+ \sa alpha()
+*/
+
+void TQGLFormat::setAlpha( bool enable )
+{
+ setOption( enable ? AlphaChannel : NoAlphaChannel );
+}
+
+
+/*!
+ \fn bool TQGLFormat::accum() const
+
+ Returns TRUE if the accumulation buffer is enabled; otherwise
+ returns FALSE. The accumulation buffer is disabled by default.
+
+ \sa setAccum()
+*/
+
+/*!
+ If \a enable is TRUE enables the accumulation buffer; otherwise
+ disables the accumulation buffer.
+
+ The accumulation buffer is disabled by default.
+
+ The accumulation buffer is used to create blur effects and
+ multiple exposures.
+
+ \sa accum()
+*/
+
+void TQGLFormat::setAccum( bool enable )
+{
+ setOption( enable ? AccumBuffer : NoAccumBuffer );
+}
+
+
+/*!
+ \fn bool TQGLFormat::stencil() const
+
+ Returns TRUE if the stencil buffer is enabled; otherwise returns
+ FALSE. The stencil buffer is disabled by default.
+
+ \sa setStencil()
+*/
+
+/*!
+ If \a enable is TRUE enables the stencil buffer; otherwise
+ disables the stencil buffer.
+
+ The stencil buffer is disabled by default.
+
+ The stencil buffer masks certain parts of the drawing area so that
+ masked parts are not drawn on.
+
+ \sa stencil()
+*/
+
+void TQGLFormat::setStencil( bool enable )
+{
+ setOption( enable ? StencilBuffer: NoStencilBuffer );
+}
+
+
+/*!
+ \fn bool TQGLFormat::stereo() const
+
+ Returns TRUE if stereo buffering is enabled; otherwise returns
+ FALSE. Stereo buffering is disabled by default.
+
+ \sa setStereo()
+*/
+
+/*!
+ If \a enable is TRUE enables stereo buffering; otherwise disables
+ stereo buffering.
+
+ Stereo buffering is disabled by default.
+
+ Stereo buffering provides extra color buffers to generate left-eye
+ and right-eye images.
+
+ \sa stereo()
+*/
+
+void TQGLFormat::setStereo( bool enable )
+{
+ setOption( enable ? StereoBuffers : NoStereoBuffers );
+}
+
+
+/*!
+ \fn bool TQGLFormat::directRendering() const
+
+ Returns TRUE if direct rendering is enabled; otherwise returns
+ FALSE.
+
+ Direct rendering is enabled by default.
+
+ \sa setDirectRendering()
+*/
+
+/*!
+ If \a enable is TRUE enables direct rendering; otherwise disables
+ direct rendering.
+
+ Direct rendering is enabled by default.
+
+ Enabling this option will make OpenGL bypass the underlying window
+ system and render directly from hardware to the screen, if this is
+ supported by the system.
+
+ \sa directRendering()
+*/
+
+void TQGLFormat::setDirectRendering( bool enable )
+{
+ setOption( enable ? DirectRendering : IndirectRendering );
+}
+
+
+/*!
+ \fn bool TQGLFormat::hasOverlay() const
+
+ Returns TRUE if overlay plane is enabled; otherwise returns FALSE.
+
+ Overlay is disabled by default.
+
+ \sa setOverlay()
+*/
+
+/*!
+ If \a enable is TRUE enables an overlay plane; otherwise disables
+ the overlay plane.
+
+ Enabling the overlay plane will cause TQGLWidget to create an
+ additional context in an overlay plane. See the TQGLWidget
+ documentation for further information.
+
+ \sa hasOverlay()
+*/
+
+void TQGLFormat::setOverlay( bool enable )
+{
+ setOption( enable ? HasOverlay : NoOverlay );
+}
+
+/*!
+ Returns the plane of this format. The default for normal formats
+ is 0, which means the normal plane. The default for overlay
+ formats is 1, which is the first overlay plane.
+
+ \sa setPlane()
+*/
+int TQGLFormat::plane() const
+{
+ return pln;
+}
+
+/*!
+ Sets the requested plane to \a plane. 0 is the normal plane, 1 is
+ the first overlay plane, 2 is the second overlay plane, etc.; -1,
+ -2, etc. are underlay planes.
+
+ Note that in contrast to other format specifications, the plane
+ specifications will be matched exactly. This means that if you
+ specify a plane that the underlying OpenGL system cannot provide,
+ an \link TQGLWidget::isValid() invalid\endlink TQGLWidget will be
+ created.
+
+ \sa plane()
+*/
+void TQGLFormat::setPlane( int plane )
+{
+ pln = plane;
+}
+
+/*!
+ Sets the format option to \a opt.
+
+ \sa testOption()
+*/
+
+void TQGLFormat::setOption( FormatOption opt )
+{
+ if ( opt & 0xffff )
+ opts |= opt;
+ else
+ opts &= ~( opt >> 16 );
+}
+
+
+
+/*!
+ Returns TRUE if format option \a opt is set; otherwise returns FALSE.
+
+ \sa setOption()
+*/
+
+bool TQGLFormat::testOption( FormatOption opt ) const
+{
+ if ( opt & 0xffff )
+ return ( opts & opt ) != 0;
+ else
+ return ( opts & ( opt >> 16 ) ) == 0;
+}
+
+
+
+/*!
+ \fn bool TQGLFormat::hasOpenGL()
+
+ Returns TRUE if the window system has any OpenGL support;
+ otherwise returns FALSE.
+
+ \warning This function must not be called until the TQApplication
+ object has been created.
+*/
+
+
+
+/*!
+ \fn bool TQGLFormat::hasOpenGLOverlays()
+
+ Returns TRUE if the window system supports OpenGL overlays;
+ otherwise returns FALSE.
+
+ \warning This function must not be called until the TQApplication
+ object has been created.
+*/
+
+/*!
+ Returns the default TQGLFormat for the application. All TQGLWidgets
+ that are created use this format unless another format is
+ specified, e.g. when they are constructed.
+
+ If no special default format has been set using
+ setDefaultFormat(), the default format is the same as that created
+ with TQGLFormat().
+
+ \sa setDefaultFormat()
+*/
+
+TQGLFormat TQGLFormat::defaultFormat()
+{
+ if ( !qgl_default_format ) {
+ qgl_default_format = new TQGLFormat;
+ qgl_cleanup_format.add( &qgl_default_format );
+ }
+ return *qgl_default_format;
+}
+
+/*!
+ Sets a new default TQGLFormat for the application to \a f. For
+ example, to set single buffering as the default instead of double
+ buffering, your main() might contain code like this:
+ \code
+ TQApplication a(argc, argv);
+ TQGLFormat f;
+ f.setDoubleBuffer( FALSE );
+ TQGLFormat::setDefaultFormat( f );
+ \endcode
+
+ \sa defaultFormat()
+*/
+
+void TQGLFormat::setDefaultFormat( const TQGLFormat &f )
+{
+ if ( !qgl_default_format ) {
+ qgl_default_format = new TQGLFormat;
+ qgl_cleanup_format.add( &qgl_default_format );
+ }
+ *qgl_default_format = f;
+}
+
+
+/*!
+ Returns the default TQGLFormat for overlay contexts.
+
+ The factory default overlay format is:
+ \list
+ \i \link setDoubleBuffer() Double buffer:\endlink Disabled.
+ \i \link setDepth() Depth buffer:\endlink Disabled.
+ \i \link setRgba() RGBA:\endlink Disabled (i.e., color index enabled).
+ \i \link setAlpha() Alpha channel:\endlink Disabled.
+ \i \link setAccum() Accumulator buffer:\endlink Disabled.
+ \i \link setStencil() Stencil buffer:\endlink Disabled.
+ \i \link setStereo() Stereo:\endlink Disabled.
+ \i \link setDirectRendering() Direct rendering:\endlink Enabled.
+ \i \link setOverlay() Overlay:\endlink Disabled.
+ \i \link setPlane() Plane:\endlink 1 (i.e., first overlay plane).
+ \endlist
+
+ \sa setDefaultFormat()
+*/
+
+TQGLFormat TQGLFormat::defaultOverlayFormat()
+{
+ if ( !qgl_default_overlay_format ) {
+ qgl_default_overlay_format = new TQGLFormat;
+ qgl_default_overlay_format->opts = DirectRendering;
+ qgl_default_overlay_format->pln = 1;
+ qgl_cleanup_format.add( &qgl_default_overlay_format );
+ }
+ return *qgl_default_overlay_format;
+}
+
+/*!
+ Sets a new default TQGLFormat for overlay contexts to \a f. This
+ format is used whenever a TQGLWidget is created with a format that
+ hasOverlay() enabled.
+
+ For example, to get a double buffered overlay context (if
+ available), use code like this:
+
+ \code
+ TQGLFormat f = TQGLFormat::defaultOverlayFormat();
+ f.setDoubleBuffer( TRUE );
+ TQGLFormat::setDefaultOverlayFormat( f );
+ \endcode
+
+ As usual, you can tqfind out after widget creation whether the
+ underlying OpenGL system was able to provide the requested
+ specification:
+
+ \code
+ // ...continued from above
+ MyGLWidget* myWidget = new MyGLWidget( TQGLFormat( TQGL::HasOverlay ), ... );
+ if ( myWidget->format().hasOverlay() ) {
+ // Yes, we got an overlay, let's check _its_ format:
+ TQGLContext* olContext = myWidget->overlayContext();
+ if ( olContext->format().doubleBuffer() )
+ ; // yes, we got a double buffered overlay
+ else
+ ; // no, only single buffered overlays are available
+ }
+ \endcode
+
+ \sa defaultOverlayFormat()
+*/
+
+void TQGLFormat::setDefaultOverlayFormat( const TQGLFormat &f )
+{
+ if ( !qgl_default_overlay_format ) {
+ qgl_default_overlay_format = new TQGLFormat;
+ qgl_cleanup_format.add( &qgl_default_overlay_format );
+ }
+ *qgl_default_overlay_format = f;
+ // Make sure the user doesn't request that the overlays themselves
+ // have overlays, since it is unlikely that the system supports
+ // infinitely many planes...
+ qgl_default_overlay_format->setOverlay( FALSE );
+}
+
+
+/*!
+ Returns TRUE if all the options of the two TQGLFormats are equal;
+ otherwise returns FALSE.
+*/
+
+bool operator==( const TQGLFormat& a, const TQGLFormat& b )
+{
+ return (a.opts == b.opts) && (a.pln == b.pln);
+}
+
+
+/*!
+ Returns FALSE if all the options of the two TQGLFormats are equal;
+ otherwise returns TRUE.
+*/
+
+bool operator!=( const TQGLFormat& a, const TQGLFormat& b )
+{
+ return !( a == b );
+}
+
+
+
+/*****************************************************************************
+ TQGLContext implementation
+ *****************************************************************************/
+
+TQGLContext* TQGLContext::currentCtx = 0;
+
+/*!
+ \class TQGLContext tqgl.h
+ \brief The TQGLContext class encapsulates an OpenGL rendering context.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup graphics
+ \ingroup images
+ \module OpenGL
+
+ An OpenGL<sup>*</sup> rendering context is a complete set of
+ OpenGL state variables.
+
+ The context's \link TQGL::FormatOption format\endlink is set in the
+ constructor or later with setFormat(). The format options that are
+ actually set are returned by format(); the options you asked for
+ are returned by requestedFormat(). Note that after a TQGLContext
+ object has been constructed, the actual OpenGL context must be
+ created by explicitly calling the \link create() create()\endlink
+ function. The makeCurrent() function makes this context the
+ current rendering context. You can make \e no context current
+ using doneCurrent(). The reset() function will reset the context
+ and make it invalid.
+
+ You can examine properties of the context with, e.g. isValid(),
+ isSharing(), initialized(), windowCreated() and
+ overlayTransparentColor().
+
+ If you're using double buffering you can swap the screen contents
+ with the off-screen buffer using swapBuffers().
+
+ Please note that TQGLContext is not thread safe.
+
+ <sup>*</sup> OpenGL is a trademark of Silicon Graphics, Inc. in the
+ United States and other countries.
+
+*/
+
+
+/*!
+ Constructs an OpenGL context for the paint tqdevice \a tqdevice, which
+ can be a widget or a pixmap. The \a format specifies several
+ display options for the context.
+
+ If the underlying OpenGL/Window system cannot satisfy all the
+ features requested in \a format, the nearest subset of features
+ will be used. After creation, the format() method will return the
+ actual format obtained.
+
+ Note that after a TQGLContext object has been constructed, \link
+ create() create()\endlink must be called explicitly to create
+ the actual OpenGL context. The context will be \link isValid()
+ invalid\endlink if it was not possible to obtain a GL context at
+ all.
+
+ \sa format(), isValid()
+*/
+
+TQGLContext::TQGLContext( const TQGLFormat &format, TQPaintDevice *tqdevice )
+ : glFormat(format), reqFormat(format)
+{
+ init( tqdevice );
+}
+
+/*!
+ \overload
+ \internal
+*/
+TQGLContext::TQGLContext( const TQGLFormat &format )
+ : glFormat( format ), reqFormat(format)
+{
+ init();
+}
+
+/*!
+ Destroys the OpenGL context and frees its resources.
+*/
+
+TQGLContext::~TQGLContext()
+{
+ reset();
+ if ( d )
+ delete d;
+}
+
+
+/*!
+ \fn TQGLFormat TQGLContext::format() const
+
+ Returns the frame buffer format that was obtained (this may be a
+ subset of what was requested).
+
+ \sa requestedFormat()
+*/
+
+/*!
+ \fn TQGLFormat TQGLContext::requestedFormat() const
+
+ Returns the frame buffer format that was originally requested in
+ the constructor or setFormat().
+
+ \sa format()
+*/
+
+/*!
+ Sets a \a format for this context. The context is \link reset()
+ reset\endlink.
+
+ Call create() to create a new GL context that tries to match the
+ new format.
+
+ \code
+ TQGLContext *cx;
+ // ...
+ TQGLFormat f;
+ f.setStereo( TRUE );
+ cx->setFormat( f );
+ if ( !cx->create() )
+ exit(); // no OpenGL support, or cannot render on the specified painttqdevice
+ if ( !cx->format().stereo() )
+ exit(); // could not create stereo context
+ \endcode
+
+ \sa format(), reset(), create()
+*/
+
+void TQGLContext::setFormat( const TQGLFormat &format )
+{
+ reset();
+ glFormat = reqFormat = format;
+}
+
+/*!
+ \internal
+*/
+void TQGLContext::setDevice( TQPaintDevice *pDev )
+{
+ if ( isValid() )
+ reset();
+ d->paintDevice = pDev;
+ if ( d->paintDevice && (d->paintDevice->devType() != TQInternal::Widget
+ && d->paintDevice->devType() != TQInternal::Pixmap) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQGLContext: Unsupported paint tqdevice type" );
+#endif
+ }
+}
+
+void TQGLContext::init( TQPaintDevice *dev )
+{
+ d = new Private;
+ d->valid = FALSE;
+#if defined(TQ_WS_X11)
+ qt_resolve_gl_symbols();
+ gpm = 0;
+#endif
+ setDevice( dev );
+#if defined(TQ_WS_WIN)
+ dc = 0;
+ win = 0;
+ pixelFormatId = 0;
+ cmap = 0;
+#endif
+#if defined(TQ_WS_MAC)
+ d->oldR = TQRect(1, 1, 1, 1);
+#endif
+ d->crWin = FALSE;
+ d->initDone = FALSE;
+ d->sharing = FALSE;
+}
+
+/*!
+ \fn bool TQGLContext::isValid() const
+
+ Returns TRUE if a GL rendering context has been successfully
+ created; otherwise returns FALSE.
+*/
+
+/*!
+ \fn void TQGLContext::setValid( bool valid )
+ \internal
+
+ Forces the GL rendering context to be valid.
+*/
+
+/*!
+ \fn bool TQGLContext::isSharing() const
+
+ Returns TRUE if display list sharing with another context was
+ requested in the create() call and the GL system was able to
+ fulfill this request; otherwise returns FALSE. Note that display
+ list sharing might not be supported between contexts with
+ different formats.
+*/
+
+/*!
+ \fn bool TQGLContext::tqdeviceIsPixmap() const
+
+ Returns TRUE if the paint tqdevice of this context is a pixmap;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQGLContext::windowCreated() const
+
+ Returns TRUE if a window has been created for this context;
+ otherwise returns FALSE.
+
+ \sa setWindowCreated()
+*/
+
+/*!
+ \fn void TQGLContext::setWindowCreated( bool on )
+
+ If \a on is TRUE the context has had a window created for it. If
+ \a on is FALSE no window has been created for the context.
+
+ \sa windowCreated()
+*/
+
+/*!
+ \fn uint TQGLContext::colorIndex( const TQColor& c ) const
+
+ \internal
+
+ Returns a colormap index for the color c, in ColorIndex mode. Used
+ by qglColor() and qglClearColor().
+*/
+
+
+/*!
+ \fn bool TQGLContext::initialized() const
+
+ Returns TRUE if this context has been initialized, i.e. if
+ TQGLWidget::initializeGL() has been performed on it; otherwise
+ returns FALSE.
+
+ \sa setInitialized()
+*/
+
+/*!
+ \fn void TQGLContext::setInitialized( bool on )
+
+ If \a on is TRUE the context has been initialized, i.e.
+ TQGLContext::setInitialized() has been called on it. If \a on is
+ FALSE the context has not been initialized.
+
+ \sa initialized()
+*/
+
+/*!
+ \fn const TQGLContext* TQGLContext::currentContext()
+
+ Returns the current context, i.e. the context to which any OpenGL
+ commands will currently be directed. Returns 0 if no context is
+ current.
+
+ \sa makeCurrent()
+*/
+
+/*!
+ \fn TQColor TQGLContext::overlayTransparentColor() const
+
+ If this context is a valid context in an overlay plane, returns
+ the plane's transtqparent color. Otherwise returns an \link
+ TQColor::isValid() invalid \endlink color.
+
+ The returned color's \link TQColor::pixel() pixel \endlink value is
+ the index of the transtqparent color in the colormap of the overlay
+ plane. (Naturally, the color's RGB values are meaningless.)
+
+ The returned TQColor object will generally work as expected only
+ when passed as the argument to TQGLWidget::qglColor() or
+ TQGLWidget::qglClearColor(). Under certain circumstances it can
+ also be used to draw transtqparent graphics with a TQPainter. See the
+ examples/opengl/overlay_x11 example for details.
+*/
+
+
+/*!
+ Creates the GL context. Returns TRUE if it was successful in
+ creating a valid GL rendering context on the paint tqdevice
+ specified in the constructor; otherwise returns FALSE (i.e. the
+ context is invalid).
+
+ After successful creation, format() returns the set of features of
+ the created GL rendering context.
+
+ If \a shareContext points to a valid TQGLContext, this method will
+ try to establish OpenGL display list sharing between this context
+ and the \a shareContext. Note that this may fail if the two
+ contexts have different formats. Use isSharing() to see if sharing
+ succeeded.
+
+ \warning Implementation note: initialization of C++ class
+ members usually takes place in the class constructor. TQGLContext
+ is an exception because it must be simple to customize. The
+ virtual functions chooseContext() (and chooseVisual() for X11) can
+ be reimplemented in a subclass to select a particular context. The
+ problem is that virtual functions are not properly called during
+ construction (even though this is correct C++) because C++
+ constructs class hierarchies from the bottom up. For this reason
+ we need a create() function.
+
+ \sa chooseContext(), format(), isValid()
+*/
+
+bool TQGLContext::create( const TQGLContext* shareContext )
+{
+ reset();
+ d->valid = chooseContext( shareContext );
+ return d->valid;
+}
+
+
+
+/*!
+ \fn bool TQGLContext::chooseContext( const TQGLContext* shareContext = 0 )
+
+ This semi-internal function is called by create(). It creates a
+ system-dependent OpenGL handle that matches the format() of \a
+ shareContext as closely as possible.
+
+ On Windows, it calls the virtual function choosePixelFormat(),
+ which tqfinds a matching pixel format identifier. On X11, it calls
+ the virtual function chooseVisual() which tqfinds an appropriate X
+ visual. On other platforms it may work differently.
+*/
+
+
+/*!
+ \fn void TQGLContext::reset()
+
+ Resets the context and makes it invalid.
+
+ \sa create(), isValid()
+*/
+
+
+/*!
+ \fn void TQGLContext::makeCurrent()
+
+ Makes this context the current OpenGL rendering context. All GL
+ functions you call operate on this context until another context
+ is made current.
+
+ In some very rare cases the underlying call may fail. If this
+ occurs an error message is output to stderr.
+*/
+
+
+/*!
+ \fn void TQGLContext::swapBuffers() const
+
+ Swaps the screen contents with an off-screen buffer. Only works if
+ the context is in double buffer mode.
+
+ \sa TQGLFormat::setDoubleBuffer()
+*/
+
+
+/*!
+ \fn void TQGLContext::doneCurrent()
+
+ Makes no GL context the current context. Normally, you do not need
+ to call this function; TQGLContext calls it as necessary.
+*/
+
+
+/*!
+ \fn TQPaintDevice* TQGLContext::tqdevice() const
+
+ Returns the paint tqdevice set for this context.
+
+ \sa TQGLContext::TQGLContext()
+*/
+
+/*!
+ \fn void TQGLContext::generateFontDisplayLists( const TQFont& font, int listBase )
+
+ Generates a set of 256 display lists for the 256 first characters
+ in the font \a font. The first list will start at index \a listBase.
+
+ \sa TQGLWidget::renderText()
+*/
+
+
+/*****************************************************************************
+ TQGLWidget implementation
+ *****************************************************************************/
+
+
+/*!
+ \class TQGLWidget tqgl.h
+ \brief The TQGLWidget class is a widget for rendering OpenGL graphics.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup graphics
+ \ingroup images
+ \mainclass
+ \module OpenGL
+
+ TQGLWidget provides functionality for displaying OpenGL<sup>*</sup>
+ graphics integrated into a TQt application. It is very simple to
+ use. You inherit from it and use the subclass like any other
+ TQWidget, except that instead of drawing the widget's contents
+ using TQPainter etc. you use the standard OpenGL rendering
+ commands.
+
+ TQGLWidget provides three convenient virtual functions that you can
+ reimplement in your subclass to perform the typical OpenGL tasks:
+
+ \list
+ \i paintGL() - Renders the OpenGL scene. Gets called whenever the widget
+ needs to be updated.
+ \i resizeGL() - Sets up the OpenGL viewport, projection, etc. Gets
+ called whenever the the widget has been resized (and also when it
+ is shown for the first time because all newly created widgets get a
+ resize event automatically).
+ \i initializeGL() - Sets up the OpenGL rendering context, defines display
+ lists, etc. Gets called once before the first time resizeGL() or
+ paintGL() is called.
+ \endlist
+
+ Here is a rough outline of how a TQGLWidget subclass might look:
+
+ \code
+ class MyGLDrawer : public TQGLWidget
+ {
+ TQ_OBJECT // must include this if you use TQt Q_SIGNALS/Q_SLOTS
+
+ public:
+ MyGLDrawer( TQWidget *tqparent, const char *name )
+ : TQGLWidget(tqparent, name) {}
+
+ protected:
+
+ void initializeGL()
+ {
+ // Set up the rendering context, define display lists etc.:
+ ...
+ glClearColor( 0.0, 0.0, 0.0, 0.0 );
+ glEnable(GL_DEPTH_TEST);
+ ...
+ }
+
+ void resizeGL( int w, int h )
+ {
+ // setup viewport, projection etc.:
+ glViewport( 0, 0, (GLint)w, (GLint)h );
+ ...
+ glFrustum( ... );
+ ...
+ }
+
+ void paintGL()
+ {
+ // draw the scene:
+ ...
+ glRotatef( ... );
+ glMaterialfv( ... );
+ glBegin( GL_TQUADS );
+ glVertex3f( ... );
+ glVertex3f( ... );
+ ...
+ glEnd();
+ ...
+ }
+
+ };
+ \endcode
+
+ If you need to trigger a tqrepaint from places other than paintGL()
+ (a typical example is when using \link TQTimer timers\endlink to
+ animate scenes), you should call the widget's updateGL() function.
+
+ Your widget's OpenGL rendering context is made current when
+ paintGL(), resizeGL(), or initializeGL() is called. If you need to
+ call the standard OpenGL API functions from other places (e.g. in
+ your widget's constructor or in your own paint functions), you
+ must call makeCurrent() first.
+
+ TQGLWidget provides functions for requesting a new display \link
+ TQGLFormat format\endlink and you can also create widgets with
+ customized rendering \link TQGLContext contexts\endlink.
+
+ You can also share OpenGL display lists between TQGLWidgets (see
+ the documentation of the TQGLWidget constructors for details).
+
+ \section1 Overlays
+
+ The TQGLWidget creates a GL overlay context in addition to the
+ normal context if overlays are supported by the underlying system.
+
+ If you want to use overlays, you specify it in the \link TQGLFormat
+ format\endlink. (Note: Overlay must be requested in the format
+ passed to the TQGLWidget constructor.) Your GL widget should also
+ implement some or all of these virtual methods:
+
+ \list
+ \i paintOverlayGL()
+ \i resizeOverlayGL()
+ \i initializeOverlayGL()
+ \endlist
+
+ These methods work in the same way as the normal paintGL() etc.
+ functions, except that they will be called when the overlay
+ context is made current. You can explicitly make the overlay
+ context current by using makeOverlayCurrent(), and you can access
+ the overlay context directly (e.g. to ask for its transtqparent
+ color) by calling overlayContext().
+
+ On X servers in which the default visual is in an overlay plane,
+ non-GL TQt windows can also be used for overlays. See the
+ examples/opengl/overlay_x11 example program for details.
+
+ <sup>*</sup> OpenGL is a trademark of Silicon Graphics, Inc. in the
+ United States and other countries.
+*/
+
+// ### BCI - fix in 4.0
+
+// the display list cache can't be global because display lists are
+// tied to the GL contexts for each individual widget
+
+class TQGLWidgetPrivate
+{
+public:
+ TQMap<TQString, int> displayListCache;
+};
+
+static TQPtrDict<TQGLWidgetPrivate> * qgl_d_ptr = 0;
+static TQSingleCleanupHandler< TQPtrDict<TQGLWidgetPrivate> > qgl_cleanup_d_ptr;
+
+static TQGLWidgetPrivate * qgl_d( const TQGLWidget * w )
+{
+ if ( !qgl_d_ptr ) {
+ qgl_d_ptr = new TQPtrDict<TQGLWidgetPrivate>;
+ qgl_cleanup_d_ptr.set( &qgl_d_ptr );
+ qgl_d_ptr->setAutoDelete( TRUE );
+ }
+ TQGLWidgetPrivate * ret = qgl_d_ptr->tqfind( (void *) w );
+ if ( !ret ) {
+ ret = new TQGLWidgetPrivate;
+ qgl_d_ptr->tqreplace( (void *) w, ret );
+ }
+ return ret;
+}
+
+void qgl_delete_d( const TQGLWidget * w )
+{
+ if ( qgl_d_ptr )
+ qgl_d_ptr->remove( (void *) w );
+}
+
+/*!
+ Constructs an OpenGL widget with a \a tqparent widget and a \a name.
+
+ The \link TQGLFormat::defaultFormat() default format\endlink is
+ used. The widget will be \link isValid() invalid\endlink if the
+ system has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink.
+
+ The \a tqparent, \a name and widget flag, \a f, arguments are passed
+ to the TQWidget constructor.
+
+ If the \a shareWidget parameter points to a valid TQGLWidget, this
+ widget will share OpenGL display lists with \a shareWidget. If
+ this widget and \a shareWidget have different \link format()
+ formats\endlink, display list sharing may fail. You can check
+ whether display list sharing succeeded by calling isSharing().
+
+ The initialization of OpenGL rendering state, etc. should be done
+ by overriding the initializeGL() function, rather than in the
+ constructor of your TQGLWidget subclass.
+
+ \sa TQGLFormat::defaultFormat()
+*/
+
+TQGLWidget::TQGLWidget( TQWidget *tqparent, const char *name,
+ const TQGLWidget* shareWidget, WFlags f )
+ : TQWidget( tqparent, name, (WFlags)(f | TQt::WWinOwnDC | WNoAutoErase) )
+{
+ init( new TQGLContext(TQGLFormat::defaultFormat(), TQT_TQPAINTDEVICE(this)), shareWidget );
+}
+
+
+/*!
+ Constructs an OpenGL widget with tqparent \a tqparent, called \a name.
+
+ The \a format argument specifies the desired \link TQGLFormat
+ rendering options \endlink. If the underlying OpenGL/Window system
+ cannot satisfy all the features requested in \a format, the
+ nearest subset of features will be used. After creation, the
+ format() method will return the actual format obtained.
+
+ The widget will be \link isValid() invalid\endlink if the system
+ has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink.
+
+ The \a tqparent, \a name and widget flag, \a f, arguments are passed
+ to the TQWidget constructor.
+
+ If the \a shareWidget parameter points to a valid TQGLWidget, this
+ widget will share OpenGL display lists with \a shareWidget. If
+ this widget and \a shareWidget have different \link format()
+ formats\endlink, display list sharing may fail. You can check
+ whether display list sharing succeeded by calling isSharing().
+
+ The initialization of OpenGL rendering state, etc. should be done
+ by overriding the initializeGL() function, rather than in the
+ constructor of your TQGLWidget subclass.
+
+ \sa TQGLFormat::defaultFormat(), isValid()
+*/
+
+TQGLWidget::TQGLWidget( const TQGLFormat &format, TQWidget *tqparent,
+ const char *name, const TQGLWidget* shareWidget,
+ WFlags f )
+ : TQWidget( tqparent, name, f | (WFlags)(TQt::WWinOwnDC | WNoAutoErase) )
+{
+ init( new TQGLContext(format, TQT_TQPAINTDEVICE(this)), shareWidget );
+}
+
+/*!
+ Constructs an OpenGL widget with tqparent \a tqparent, called \a name.
+
+ The \a context argument is a pointer to the TQGLContext that
+ you wish to be bound to this widget. This allows you to pass in
+ your own TQGLContext sub-classes.
+
+ The widget will be \link isValid() invalid\endlink if the system
+ has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink.
+
+ The \a tqparent, \a name and widget flag, \a f, arguments are passed
+ to the TQWidget constructor.
+
+ If the \a shareWidget parameter points to a valid TQGLWidget, this
+ widget will share OpenGL display lists with \a shareWidget. If
+ this widget and \a shareWidget have different \link format()
+ formats\endlink, display list sharing may fail. You can check
+ whether display list sharing succeeded by calling isSharing().
+
+ The initialization of OpenGL rendering state, etc. should be done
+ by overriding the initializeGL() function, rather than in the
+ constructor of your TQGLWidget subclass.
+
+ \sa TQGLFormat::defaultFormat(), isValid()
+*/
+TQGLWidget::TQGLWidget( TQGLContext *context, TQWidget *tqparent,
+ const char *name, const TQGLWidget *shareWidget, WFlags f )
+ : TQWidget( tqparent, name, (WFlags)(f | TQt::WWinOwnDC | WNoAutoErase) )
+{
+ init( context, shareWidget );
+}
+
+/*!
+ Destroys the widget.
+*/
+
+TQGLWidget::~TQGLWidget()
+{
+#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT)
+ bool doRelease = ( glcx && glcx->windowCreated() );
+#endif
+ qgl_delete_d( this );
+ delete glcx;
+#if defined(TQ_WGL)
+ delete olcx;
+#endif
+#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT)
+ if ( doRelease )
+ glXReleaseBuffersMESA( x11Display(), winId() );
+#endif
+#if defined(TQ_WS_MAC)
+ if(gl_pix) {
+ delete gl_pix;
+ gl_pix = NULL;
+ }
+#endif
+ cleanupColormaps();
+}
+
+
+
+
+
+/*!
+ \fn TQGLFormat TQGLWidget::format() const
+
+ Returns the format of the contained GL rendering context.
+*/
+
+/*!
+ \fn bool TQGLWidget::doubleBuffer() const
+
+ Returns TRUE if the contained GL rendering context has double
+ buffering; otherwise returns FALSE.
+
+ \sa TQGLFormat::doubleBuffer()
+*/
+
+/*!
+ \fn void TQGLWidget::setAutoBufferSwap( bool on )
+
+ If \a on is TRUE automatic GL buffer swapping is switched on;
+ otherwise it is switched off.
+
+ If \a on is TRUE and the widget is using a double-buffered format,
+ the background and foreground GL buffers will automatically be
+ swapped after each paintGL() call.
+
+ The buffer auto-swapping is on by default.
+
+ \sa autoBufferSwap(), doubleBuffer(), swapBuffers()
+*/
+
+/*!
+ \fn bool TQGLWidget::autoBufferSwap() const
+
+ Returns TRUE if the widget is doing automatic GL buffer swapping;
+ otherwise returns FALSE.
+
+ \sa setAutoBufferSwap()
+*/
+
+/*!
+ \fn bool TQGLWidget::isValid() const
+
+ Returns TRUE if the widget has a valid GL rendering context;
+ otherwise returns FALSE. A widget will be invalid if the system
+ has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink.
+*/
+
+bool TQGLWidget::isValid() const
+{
+ return glcx->isValid();
+}
+
+/*!
+ \fn bool TQGLWidget::isSharing() const
+
+ Returns TRUE if display list sharing with another TQGLWidget was
+ requested in the constructor, and the GL system was able to
+ provide it; otherwise returns FALSE. The GL system may fail to
+ provide display list sharing if the two TQGLWidgets use different
+ formats.
+
+ \sa format()
+*/
+
+bool TQGLWidget::isSharing() const
+{
+ return glcx->isSharing();
+}
+
+/*!
+ \fn void TQGLWidget::makeCurrent()
+
+ Makes this widget the current widget for OpenGL operations, i.e.
+ makes the widget's rendering context the current OpenGL rendering
+ context.
+*/
+
+void TQGLWidget::makeCurrent()
+{
+#if defined( TQ_WS_MAC )
+ macInternalDoubleBuffer(); //make sure the correct context is used
+#endif
+ glcx->makeCurrent();
+}
+
+/*!
+ \fn void TQGLWidget::doneCurrent()
+
+ Makes no GL context the current context. Normally, you do not need
+ to call this function; TQGLContext calls it as necessary. However,
+ it may be useful in multithreaded environments.
+*/
+
+void TQGLWidget::doneCurrent()
+{
+ glcx->doneCurrent();
+}
+
+/*!
+ \fn void TQGLWidget::swapBuffers()
+
+ Swaps the screen contents with an off-screen buffer. This only
+ works if the widget's format specifies double buffer mode.
+
+ Normally, there is no need to explicitly call this function
+ because it is done automatically after each widget tqrepaint, i.e.
+ each time after paintGL() has been executed.
+
+ \sa doubleBuffer(), setAutoBufferSwap(), TQGLFormat::setDoubleBuffer()
+*/
+
+void TQGLWidget::swapBuffers()
+{
+ glcx->swapBuffers();
+#if defined(TQ_WS_MAC)
+ if(macInternalDoubleBuffer() && gl_pix)
+ bitBlt(this, 0, 0, gl_pix);
+#endif
+}
+
+
+/*!
+ \fn const TQGLContext* TQGLWidget::overlayContext() const
+
+ Returns the overlay context of this widget, or 0 if this widget
+ has no overlay.
+
+ \sa context()
+*/
+
+
+
+/*!
+ \fn void TQGLWidget::makeOverlayCurrent()
+
+ Makes the overlay context of this widget current. Use this if you
+ need to issue OpenGL commands to the overlay context outside of
+ initializeOverlayGL(), resizeOverlayGL(), and paintOverlayGL().
+
+ Does nothing if this widget has no overlay.
+
+ \sa makeCurrent()
+*/
+
+
+/*
+ \obsolete
+
+ Sets a new format for this widget.
+
+ If the underlying OpenGL/Window system cannot satisfy all the
+ features requested in \a format, the nearest subset of features will
+ be used. After creation, the format() method will return the actual
+ rendering context format obtained.
+
+ The widget will be assigned a new TQGLContext, and the initializeGL()
+ function will be executed for this new context before the first
+ resizeGL() or paintGL().
+
+ This method will try to keep any existing display list sharing with
+ other TQGLWidgets, but it may fail. Use isSharing() to test.
+
+ \sa format(), isSharing(), isValid()
+*/
+
+void TQGLWidget::setFormat( const TQGLFormat &format )
+{
+ setContext( new TQGLContext(format,TQT_TQPAINTDEVICE(this)) );
+}
+
+
+
+
+/*!
+ \fn const TQGLContext *TQGLWidget::context() const
+
+ Returns the context of this widget.
+
+ It is possible that the context is not valid (see isValid()), for
+ example, if the underlying hardware does not support the format
+ attributes that were requested.
+*/
+
+/*
+ \obsolete
+
+ \fn void TQGLWidget::setContext( TQGLContext *context,
+ const TQGLContext* shareContext,
+ bool deleteOldContext )
+
+ Sets a new context for this widget. The TQGLContext \a context must
+ be created using \e new. TQGLWidget will delete \a context when
+ another context is set or when the widget is destroyed.
+
+ If \a context is invalid, TQGLContext::create() is performed on
+ it. The initializeGL() function will then be executed for the new
+ context before the first resizeGL() or paintGL().
+
+ If \a context is invalid, this method will try to keep any existing
+ display list sharing with other TQGLWidgets this widget currently
+ has, or (if \a shareContext points to a valid context) start display
+ list sharing with that context, but it may fail. Use isSharing() to
+ test.
+
+ If \a deleteOldContext is TRUE (the default), the existing context
+ will be deleted. You may use FALSE here if you have kept a pointer
+ to the old context (as returned by context()), and want to restore
+ that context later.
+
+ \sa context(), isSharing()
+*/
+
+
+
+/*!
+ \fn void TQGLWidget::updateGL()
+
+ Updates the widget by calling glDraw().
+*/
+
+void TQGLWidget::updateGL()
+{
+ glDraw();
+}
+
+
+/*!
+ \fn void TQGLWidget::updateOverlayGL()
+
+ Updates the widget's overlay (if any). Will cause the virtual
+ function paintOverlayGL() to be executed.
+
+ The widget's rendering context will become the current context and
+ initializeGL() will be called if it hasn't already been called.
+*/
+
+
+/*!
+ This virtual function is called once before the first call to
+ paintGL() or resizeGL(), and then once whenever the widget has
+ been assigned a new TQGLContext. Reimplement it in a subclass.
+
+ This function should set up any required OpenGL context rendering
+ flags, defining display lists, etc.
+
+ There is no need to call makeCurrent() because this has already
+ been done when this function is called.
+*/
+
+void TQGLWidget::initializeGL()
+{
+}
+
+
+/*!
+ This virtual function is called whenever the widget needs to be
+ painted. Reimplement it in a subclass.
+
+ There is no need to call makeCurrent() because this has already
+ been done when this function is called.
+*/
+
+void TQGLWidget::paintGL()
+{
+}
+
+
+/*!
+ \fn void TQGLWidget::resizeGL( int width , int height )
+
+ This virtual function is called whenever the widget has been
+ resized. The new size is passed in \a width and \a height.
+ Reimplement it in a subclass.
+
+ There is no need to call makeCurrent() because this has already
+ been done when this function is called.
+*/
+
+void TQGLWidget::resizeGL( int, int )
+{
+}
+
+
+
+/*!
+ This virtual function is used in the same manner as initializeGL()
+ except that it operates on the widget's overlay context instead of
+ the widget's main context. This means that initializeOverlayGL()
+ is called once before the first call to paintOverlayGL() or
+ resizeOverlayGL(). Reimplement it in a subclass.
+
+ This function should set up any required OpenGL context rendering
+ flags, defining display lists, etc. for the overlay context.
+
+ There is no need to call makeOverlayCurrent() because this has
+ already been done when this function is called.
+*/
+
+void TQGLWidget::initializeOverlayGL()
+{
+}
+
+
+/*!
+ This virtual function is used in the same manner as paintGL()
+ except that it operates on the widget's overlay context instead of
+ the widget's main context. This means that paintOverlayGL() is
+ called whenever the widget's overlay needs to be painted.
+ Reimplement it in a subclass.
+
+ There is no need to call makeOverlayCurrent() because this has
+ already been done when this function is called.
+*/
+
+void TQGLWidget::paintOverlayGL()
+{
+}
+
+
+/*!
+ \fn void TQGLWidget::resizeOverlayGL( int width , int height )
+
+ This virtual function is used in the same manner as paintGL()
+ except that it operates on the widget's overlay context instead of
+ the widget's main context. This means that resizeOverlayGL() is
+ called whenever the widget has been resized. The new size is
+ passed in \a width and \a height. Reimplement it in a subclass.
+
+ There is no need to call makeOverlayCurrent() because this has
+ already been done when this function is called.
+*/
+
+void TQGLWidget::resizeOverlayGL( int, int )
+{
+}
+
+
+
+
+/*!
+ Handles paint events. Will cause the virtual paintGL() function to
+ be called.
+
+ The widget's rendering context will become the current context and
+ initializeGL() will be called if it hasn't already been called.
+*/
+
+void TQGLWidget::paintEvent( TQPaintEvent * )
+{
+ glDraw();
+ updateOverlayGL();
+}
+
+
+/*!
+ \fn void TQGLWidget::resizeEvent( TQResizeEvent * )
+
+ Handles resize events. Calls the virtual function resizeGL().
+*/
+
+
+/*!
+ \fn void TQGLWidget::setMouseTracking( bool enable )
+
+ \reimp
+*/
+
+
+/*!
+ Renders the current scene on a pixmap and returns the pixmap.
+
+ You can use this method on both visible and invisible TQGLWidgets.
+
+ This method will create a pixmap and a temporary TQGLContext to
+ render on the pixmap. It will then call initializeGL(),
+ resizeGL(), and paintGL() on this context. Finally, the widget's
+ original GL context is restored.
+
+ The size of the pixmap will be \a w pixels wide and \a h pixels
+ high unless one of these parameters is 0 (the default), in which
+ case the pixmap will have the same size as the widget.
+
+ If \a useContext is TRUE, this method will try to be more
+ efficient by using the existing GL context to render the pixmap.
+ The default is FALSE. Only use TRUE if you understand the risks.
+
+ Overlays are not rendered onto the pixmap.
+
+ If the GL rendering context and the desktop have different bit
+ depths, the result will most likely look surprising.
+
+ Note that the creation of display lists, modifications of the view
+ frustum etc. should be done from within initializeGL(). If this is
+ not done, the temporary TQGLContext will not be initialized
+ properly, and the rendered pixmap may be incomplete/corrupted.
+*/
+
+TQPixmap TQGLWidget::renderPixmap( int w, int h, bool useContext )
+{
+ TQSize sz = size();
+ if ( (w > 0) && (h > 0) )
+ sz = TQSize( w, h );
+
+#ifdef USE_QT4
+ // [FIXME]
+ bool needConversion = false;
+ TQPixmap pm;
+ pm.resize( sz );
+#else // USE_QT4
+#if defined(TQ_WS_X11)
+ TQPixmap pm( sz.width(), sz.height(), x11Depth() );
+ bool needConversion = x11Visual() != TQPaintDevice::x11AppVisual();
+
+ // make sure the pixmap uses the same visual as the widget itself
+ if ( needConversion ) {
+ TQPaintDeviceX11Data* xd = pm.getX11Data( TRUE );
+ xd->x_depth = x11Depth();
+ xd->x_visual = (Visual *) x11Visual();
+ pm.setX11Data( xd );
+ }
+#else
+ TQPixmap pm;
+ pm.resize( sz );
+#endif
+#endif // USE_QT4
+
+ glcx->doneCurrent();
+
+ bool success = TRUE;
+
+ if ( useContext && isValid() && renderCxPm( &pm ) )
+ return pm;
+
+ TQGLFormat fmt = glcx->requestedFormat();
+ fmt.setDirectRendering( FALSE ); // Direct is unlikely to work
+ fmt.setDoubleBuffer( FALSE ); // We don't need dbl buf
+
+ TQGLContext* ocx = glcx;
+ bool wasCurrent = (TQGLContext::currentContext() == ocx );
+ ocx->doneCurrent();
+ glcx = new TQGLContext( fmt, TQT_TQPAINTDEVICE(&pm) );
+ glcx->create();
+
+ if ( glcx->isValid() )
+ updateGL();
+ else
+ success = FALSE;
+
+ delete glcx;
+ glcx = ocx;
+
+ if ( wasCurrent )
+ ocx->makeCurrent();
+
+ if ( success ) {
+#if defined(TQ_WS_X11)
+ if ( needConversion ) {
+ TQImage image = pm.convertToImage();
+ TQPixmap p;
+ p = image;
+ return p;
+ }
+#endif
+ return pm;
+ } else
+ return TQPixmap();
+}
+
+
+
+/*!
+ Returns an image of the frame buffer. If \a withAlpha is TRUE the
+ alpha channel is included.
+
+ Depending on your hardware, you can explicitly select which color
+ buffer to grab with a glReadBuffer() call before calling this
+ function.
+*/
+TQImage TQGLWidget::grabFrameBuffer( bool withAlpha )
+{
+#if defined( TQ_WS_MAC )
+ if(dblbuf == macInternalDoubleBuffer(FALSE) && gl_pix) //why not optimize?
+ return ((TQPixmap*)gl_pix)->convertToImage();
+#endif
+ makeCurrent();
+ TQImage res;
+ int w = width();
+ int h = height();
+ if ( format().rgba() ) {
+ res = TQImage( w, h, 32 );
+ glReadPixels( 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, res.bits() );
+ if ( TQImage::systemByteOrder() == TQImage::BigEndian ) {
+ // OpenGL gives RGBA; TQt wants ARGB
+ uint *p = (uint*)res.bits();
+ uint *end = p + w*h;
+ if ( withAlpha && format().alpha() ) {
+ while ( p < end ) {
+ uint a = *p << 24;
+ *p = (*p >> 8) | a;
+ p++;
+ }
+ }
+ else {
+ while ( p < end )
+ *p++ >>= 8;
+ }
+ }
+ else {
+ // OpenGL gives ABGR (i.e. RGBA backwards); TQt wants ARGB
+ res = res.swapRGB();
+ }
+ res.setAlphaBuffer( withAlpha && format().alpha() );
+ }
+ else {
+#if defined (TQ_WS_WIN)
+ res = TQImage( w, h, 8 );
+ glReadPixels( 0, 0, w, h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
+ res.bits() );
+ int palSize = 0;
+ const TQRgb* pal = TQColor::palette( &palSize );
+ if ( pal && palSize ) {
+ res.setNumColors( palSize );
+ for ( int i = 0; i < palSize; i++ )
+ res.setColor( i, pal[i] );
+ }
+#endif
+ }
+
+ return res.mirror();
+}
+
+
+
+/*!
+ Initializes OpenGL for this widget's context. Calls the virtual
+ function initializeGL().
+*/
+
+void TQGLWidget::glInit()
+{
+ if ( !isValid() )
+ return;
+ makeCurrent();
+ initializeGL();
+ glcx->setInitialized( TRUE );
+}
+
+
+/*!
+ Executes the virtual function paintGL().
+
+ The widget's rendering context will become the current context and
+ initializeGL() will be called if it hasn't already been called.
+*/
+
+void TQGLWidget::glDraw()
+{
+ if ( !isValid() )
+ return;
+ makeCurrent();
+ if ( glcx->tqdeviceIsPixmap() )
+ glDrawBuffer( GL_FRONT );
+ if ( !glcx->initialized() ) {
+ glInit();
+ TQPaintDeviceMetrics dm( glcx->tqdevice() );
+ resizeGL( dm.width(), dm.height() ); // New context needs this "resize"
+ }
+ paintGL();
+ if ( doubleBuffer() ) {
+ if ( autoSwap )
+ swapBuffers();
+ } else {
+ glFlush();
+#if defined( TQ_WS_MAC )
+ if(dblbuf && gl_pix)
+ bitBlt(this, 0, 0, gl_pix);
+#endif
+ }
+}
+
+
+/*!
+ Convenience function for specifying a drawing color to OpenGL.
+ Calls glColor3 (in RGBA mode) or glIndex (in color-index mode)
+ with the color \a c. Applies to the current GL context.
+
+ \sa qglClearColor(), TQGLContext::currentContext(), TQColor
+*/
+
+void TQGLWidget::qglColor( const TQColor& c ) const
+{
+ const TQGLContext* ctx = TQGLContext::currentContext();
+ if ( ctx ) {
+ if ( ctx->format().rgba() )
+ glColor3ub( c.red(), c.green(), c.blue() );
+
+ else if ( ctx->tqdevice() == context()->tqdevice()
+ && !cmap.isEmpty() ) { // TQGLColormap in use?
+ int i = cmap.tqfind( c.rgb() );
+ if ( i < 0 )
+ i = cmap.tqfindNearest( c.rgb() );
+ glIndexi( i );
+ } else
+ glIndexi( ctx->colorIndex( c ) );
+ }
+}
+
+/*!
+ Convenience function for specifying the clearing color to OpenGL.
+ Calls glClearColor (in RGBA mode) or glClearIndex (in color-index
+ mode) with the color \a c. Applies to the current GL context.
+
+ \sa qglColor(), TQGLContext::currentContext(), TQColor
+*/
+
+void TQGLWidget::qglClearColor( const TQColor& c ) const
+{
+ const TQGLContext* ctx = TQGLContext::currentContext();
+ if ( ctx ) {
+ if ( ctx->format().rgba() )
+ glClearColor( (GLfloat)c.red() / 255.0, (GLfloat)c.green() / 255.0,
+ (GLfloat)c.blue() / 255.0, (GLfloat) 0.0 );
+ else if ( ctx->tqdevice() == context()->tqdevice()
+ && !cmap.isEmpty() ) { // TQGLColormap in use?
+ int i = cmap.tqfind( c.rgb() );
+ if ( i < 0 )
+ i = cmap.tqfindNearest( c.rgb() );
+ glClearIndex( i );
+ } else
+ glClearIndex( ctx->colorIndex( c ) );
+ }
+}
+
+
+/*!
+ Converts the image \a img into the unnamed format expected by
+ OpenGL functions such as glTexImage2D(). The returned image is not
+ usable as a TQImage, but TQImage::width(), TQImage::height() and
+ TQImage::bits() may be used with OpenGL. The following few lines
+ are from the texture example. Most of the code is irrelevant, so
+ we just quote the relevant bits:
+
+ \quotefile opengl/texture/gltexobj.cpp
+ \skipto tex1
+ \printline tex1
+ \printline gllogo.bmp
+
+ We create \e tex1 (and another variable) for OpenGL, and load a real
+ image into \e buf.
+
+ \skipto convertToGLFormat
+ \printline convertToGLFormat
+
+ A few lines later, we convert \e buf into OpenGL format and store it
+ in \e tex1.
+
+ \skipto glTexImage2D
+ \printline glTexImage2D
+ \printline tex1.bits
+
+ Note the dimension restrictions for texture images as described in
+ the glTexImage2D() documentation. The width must be 2^m + 2*border
+ and the height 2^n + 2*border where m and n are integers and
+ border is either 0 or 1.
+
+ Another function in the same example uses \e tex1 with OpenGL.
+*/
+
+
+TQImage TQGLWidget::convertToGLFormat( const TQImage& img )
+{
+ TQImage res = img.convertDepth( 32 );
+ res = res.mirror();
+
+ if ( TQImage::systemByteOrder() == TQImage::BigEndian ) {
+ // TQt has ARGB; OpenGL wants RGBA
+ for ( int i=0; i < res.height(); i++ ) {
+ uint *p = (uint*)res.scanLine( i );
+ uint *end = p + res.width();
+ while ( p < end ) {
+ *p = (*p << 8) | ((*p >> 24) & 0xFF);
+ p++;
+ }
+ }
+ }
+ else {
+ // TQt has ARGB; OpenGL wants ABGR (i.e. RGBA backwards)
+ res = res.swapRGB();
+ }
+ return res;
+}
+
+
+/*!
+ \fn TQGLColormap & TQGLWidget::colormap() const
+
+ Returns the colormap for this widget.
+
+ Usually it is only top-level widgets that can have different
+ colormaps installed. Asking for the colormap of a child widget
+ will return the colormap for the child's top-level widget.
+
+ If no colormap has been set for this widget, the TQColormap
+ returned will be empty.
+
+ \sa setColormap()
+*/
+
+/*!
+ \fn void TQGLWidget::setColormap( const TQGLColormap & cmap )
+
+ Set the colormap for this widget to \a cmap. Usually it is only
+ top-level widgets that can have colormaps installed.
+
+ \sa colormap()
+*/
+
+int TQGLWidget::displayListBase( const TQFont & fnt, int listBase )
+{
+ int base;
+
+ TQGLWidgetPrivate * d = qgl_d( this );
+ if ( !d || !glcx ) { // this can't happen unless we run out of mem
+ return 0;
+ }
+
+ // always regenerate font disp. lists for pixmaps - hw accelerated
+ // contexts can't handle this otherwise
+ bool regenerate = glcx->tqdeviceIsPixmap();
+
+#if 0 // TQT_NO_XFTFREETYPE
+ // font color needs to be part of the font cache key when using
+ // antialiased fonts since one set of glyphs needs to be generated
+ // for each font color
+ TQString color_key;
+ if (fnt.styleStrategy() != TQFont::NoAntialias) {
+ GLfloat color[4];
+ glGetFloatv(GL_CURRENT_COLOR, color);
+ color_key.sprintf("%f_%f_%f",color[0], color[1], color[2]);
+ }
+ TQString key = fnt.key() + color_key + TQString::number((int) regenerate);
+#else
+ TQString key = fnt.key() + TQString::number((int) regenerate);
+#endif
+
+ if ( !regenerate && (d->displayListCache.tqfind( key ) != d->displayListCache.end()) ) {
+ base = d->displayListCache[ key ];
+ } else {
+ int maxBase = listBase - 256;
+ TQMapConstIterator<TQString,int> it;
+ for ( it = d->displayListCache.begin(); it != d->displayListCache.end(); ++it ) {
+ if ( maxBase < it.data() ) {
+ maxBase = it.data();
+ }
+ }
+ maxBase += 256;
+ glcx->generateFontDisplayLists( fnt, maxBase );
+ d->displayListCache[ key ] = maxBase;
+ base = maxBase;
+ }
+ return base;
+}
+
+/*!
+ Renders the string \a str into the GL context of this widget.
+
+ \a x and \a y are specified in window coordinates, with the origin
+ in the upper left-hand corner of the window. If \a fnt is not
+ specified, the currently set application font will be used to
+ render the string. To change the color of the rendered text you can
+ use the glColor() call (or the qglColor() convenience function),
+ just before the renderText() call. Note that if you have
+ GL_LIGHTING enabled, the string will not appear in the color you
+ want. You should therefore switch lighting off before using
+ renderText().
+
+ \a listBase specifies the index of the first display list that is
+ generated by this function. The default value is 2000. 256 display
+ lists will be generated, one for each of the first 256 characters
+ in the font that is used to render the string. If several fonts are
+ used in the same widget, the display lists for these fonts will
+ follow the last generated list. You would normally not have to
+ change this value unless you are using lists in the same range. The
+ lists are deleted when the widget is destroyed.
+
+ Note: This function only works reliably with ASCII strings.
+*/
+
+void TQGLWidget::renderText( int x, int y, const TQString & str, const TQFont & fnt, int listBase )
+{
+ if (str.isEmpty())
+ return;
+ makeCurrent();
+ glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT | GL_LIST_BIT | GL_CURRENT_BIT );
+ glMatrixMode( GL_PROJECTION );
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho( 0, width(), height(), 0, -1, 1 );
+ glMatrixMode( GL_MODELVIEW );
+ glPushMatrix();
+ glLoadIdentity();
+
+ glRasterPos2i( 0, 0 );
+ glBitmap(0, 0, 0, 0, x, -y, NULL);
+ glListBase( displayListBase( fnt, listBase ) );
+ const char *cstr = str.latin1();
+ glCallLists( tqstrlen(cstr), GL_UNSIGNED_BYTE, cstr );
+
+ // restore the matrix stacks and GL state
+ glPopMatrix();
+ glMatrixMode( GL_PROJECTION );
+ glPopMatrix();
+ glPopAttrib();
+}
+
+/*! \overload
+
+ \a x, \a y and \a z are specified in scene or object coordinates
+ relative to the currently set projection and model matrices. This
+ can be useful if you want to annotate models with text labels and
+ have the labels move with the model as it is rotated etc.
+*/
+void TQGLWidget::renderText( double x, double y, double z, const TQString & str, const TQFont & fnt,
+ int listBase )
+{
+ if (str.isEmpty())
+ return;
+ makeCurrent();
+ glRasterPos3d( x, y, z );
+ glPushAttrib( GL_LIST_BIT );
+ glListBase( displayListBase( fnt, listBase ) );
+ const char *cstr = str.latin1();
+ glCallLists( tqstrlen(cstr), GL_UNSIGNED_BYTE, cstr );
+ glPopAttrib();
+}
+
+/*****************************************************************************
+ TQGL classes overview documentation.
+ *****************************************************************************/
+
+/*!
+
+\page opengl.html
+
+\title TQt OpenGL 3D Graphics
+
+\if defined(commercial)
+This module is part of the \link commercialeditions.html TQt Enterprise
+Edition\endlink.
+\endif
+
+\section1 Introduction
+
+OpenGL is a standard API for rendering 3D graphics.
+
+OpenGL only deals with 3D rendering and provides little or no support
+for GUI programming issues. The user interface for an
+OpenGL<sup>*</sup> application must be created with another toolkit,
+such as Motif on the X platform, Microsoft Foundation Classes (MFC)
+under Windows, or TQt on \e both platforms.
+
+The TQt OpenGL module makes it easy to use OpenGL in TQt applications.
+It provides an OpenGL widget class that can be used just like any
+other TQt widget, except that it opens an OpenGL display buffer where
+you can use the OpenGL API to render the contents.
+
+The TQt OpenGL module is implemented as a platform-independent TQt/C++
+wrapper around the platform-dependent GLX, WGL, or AGL C APIs. The
+functionality provided is very similar to Mark Kilgard's GLUT library,
+but with much more non-OpenGL-specific GUI functionality, i.e. the
+whole TQt API.
+
+\section1 Installation
+
+When you install TQt for X11, the configure script will autodetect if
+OpenGL headers and libraries are installed on your system, and if so,
+it will include the TQt OpenGL module in the TQt library. (If your
+OpenGL headers or libraries are placed in a non-standard directory,
+you may need to change the TQMAKE_INCDIR_OPENGL and/or
+TQMAKE_LIBDIR_OPENGL in the config file for your system). Some
+configurations require threading to be enabled for OpenGL, so if
+OpenGL is not detected, try \c{configure -thread}.
+
+When you install TQt for Windows, the TQt OpenGL module is always
+included.
+
+The TQt OpenGL module is not licensed for use with the TQt Professional
+Edition. Consider upgrading to the TQt Enterprise Edition if you
+require OpenGL support.
+
+Note about using Mesa on X11: Mesa versions earlier than 3.1 would use
+the name "MesaGL" and "MesaGLU" for the libraries, instead of "GL" and
+"GLU". If you want to use a pre-3.1 version of Mesa, you must change
+the Makefiles to use these library names instead. The easiest way to
+do this is to edit the TQMAKE_LIBS_OPENGL line in the config file you
+are using, changing "-lGL -lGLU" to "-lMesaGL -lMesaGLU"; then run
+"configure" again.
+
+\section1 The TQGL Classes
+
+The OpenGL support classes in TQt are:
+\list
+\i \link TQGLWidget TQGLWidget\endlink: An easy-to-use TQt
+ widget for rendering OpenGL scenes.
+\i \link TQGLContext TQGLContext\endlink: Encapsulates an OpenGL rendering context.
+\i \link TQGLFormat TQGLFormat\endlink: Specifies the
+display format of a rendering context.
+\i \link TQGLColormap TQGLColormap\endlink: Handles indexed
+colormaps in GL-index mode.
+\endlist
+
+Many applications only need the high-level TQGLWidget class. The other
+TQGL classes provide advanced features. X11 users might like to read
+the notes on \link opengl-x11-overlays.html overlays\endlink.
+
+See also the \link opengl-examples.html OpenGL examples\endlink.
+
+The TQGL documentation assumes that you are familiar with OpenGL
+programming. If you're new to the subject a good starting point is
+\l{http://www.opengl.org/}.
+
+
+<sup>*</sup> OpenGL is a trademark of Silicon Graphics, Inc. in the
+United States and other countries.
+
+*/
+
+/*!
+ \enum TQGL::FormatOption
+
+ This enum specifies the format options.
+
+ \value DoubleBuffer
+ \value DepthBuffer
+ \value Rgba
+ \value AlphaChannel
+ \value AccumBuffer
+ \value StencilBuffer
+ \value StereoBuffers
+ \value DirectRendering
+ \value HasOverlay
+ \value SingleBuffer
+ \value NoDepthBuffer
+ \value ColorIndex
+ \value NoAlphaChannel
+ \value NoAccumBuffer
+ \value NoStencilBuffer
+ \value NoStereoBuffers
+ \value IndirectRendering
+ \value NoOverlay
+*/
diff --git a/tqtinterface/qt4/src/opengl/tqgl.h b/tqtinterface/qt4/src/opengl/tqgl.h
new file mode 100644
index 0000000..4b6fce4
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqgl.h
@@ -0,0 +1,542 @@
+/****************************************************************************
+**
+** Definition of OpenGL classes for TQt
+**
+** Created : 970112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the opengl module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGL_H
+#define TQGL_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqglcolormap.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_OPENGL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_OPENGL
+#else
+#define TQM_EXPORT_OPENGL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_COMPAT
+#define TQGL_VERSION 450
+#define TQGL_VERSION_STR "4.5"
+TQM_EXPORT_OPENGL inline const char *qGLVersion() {
+ qObsolete( 0, "qGLVersion", "qVersion" );
+ return TQGL_VERSION_STR;
+}
+#endif
+
+#if defined(TQ_WS_WIN)
+# include "tqt_windows.h"
+#endif
+
+#if defined(TQ_WS_MAC)
+#if !defined( TQMAC_OPENGL_DOUBLEBUFFER )
+/* This macro is different now. If the macro is not defined TQGLWidget will
+ * try to determine when you need double buffering. If set to 0 it will
+ * never double buffer and *can* be acclerated. If set to 1 (the default)
+ * it will always double buffer. Unlike before the value of this macro does
+ * not upset binary compatability either. */
+#if TQT_MACOSX_VERSION >= 0x1020
+# define TQMAC_OPENGL_DOUBLEBUFFER 0
+#endif
+#endif
+# include <OpenGL/gl.h>
+# include <OpenGL/glu.h>
+#else
+# include <GL/gl.h>
+# include <GL/glu.h>
+#endif
+
+#if defined(TQ_WS_WIN) || defined(TQ_WS_MAC)
+class TQGLCmap;
+#endif
+
+class TQPixmap;
+#if defined(TQ_WS_X11)
+class TQGLOverlayWidget;
+#endif
+
+// Namespace class:
+class TQM_EXPORT_OPENGL TQGL
+{
+public:
+ enum FormatOption {
+ DoubleBuffer = 0x0001,
+ DepthBuffer = 0x0002,
+ Rgba = 0x0004,
+ AlphaChannel = 0x0008,
+ AccumBuffer = 0x0010,
+ StencilBuffer = 0x0020,
+ StereoBuffers = 0x0040,
+ DirectRendering = 0x0080,
+ HasOverlay = 0x0100,
+ SingleBuffer = DoubleBuffer << 16,
+ NoDepthBuffer = DepthBuffer << 16,
+ ColorIndex = Rgba << 16,
+ NoAlphaChannel = AlphaChannel << 16,
+ NoAccumBuffer = AccumBuffer << 16,
+ NoStencilBuffer = StencilBuffer << 16,
+ NoStereoBuffers = StereoBuffers << 16,
+ IndirectRendering = DirectRendering << 16,
+ NoOverlay = HasOverlay << 16
+ };
+};
+
+
+
+class TQM_EXPORT_OPENGL TQGLFormat : public TQGL
+{
+public:
+ TQGLFormat();
+ TQGLFormat( int options, int plane = 0 );
+
+ bool doubleBuffer() const;
+ void setDoubleBuffer( bool enable );
+ bool depth() const;
+ void setDepth( bool enable );
+ bool rgba() const;
+ void setRgba( bool enable );
+ bool alpha() const;
+ void setAlpha( bool enable );
+ bool accum() const;
+ void setAccum( bool enable );
+ bool stencil() const;
+ void setStencil( bool enable );
+ bool stereo() const;
+ void setStereo( bool enable );
+ bool directRendering() const;
+ void setDirectRendering( bool enable );
+ bool hasOverlay() const;
+ void setOverlay( bool enable );
+
+ int plane() const;
+ void setPlane( int plane );
+
+ void setOption( FormatOption opt );
+ bool testOption( FormatOption opt ) const;
+
+ static TQGLFormat defaultFormat();
+ static void setDefaultFormat( const TQGLFormat& f );
+
+ static TQGLFormat defaultOverlayFormat();
+ static void setDefaultOverlayFormat( const TQGLFormat& f );
+
+ static bool hasOpenGL();
+ static bool hasOpenGLOverlays();
+
+ friend TQM_EXPORT_OPENGL bool operator==( const TQGLFormat&,
+ const TQGLFormat& );
+ friend TQM_EXPORT_OPENGL bool operator!=( const TQGLFormat&,
+ const TQGLFormat& );
+private:
+ uint opts;
+ int pln;
+};
+
+
+TQM_EXPORT_OPENGL bool operator==( const TQGLFormat&, const TQGLFormat& );
+TQM_EXPORT_OPENGL bool operator!=( const TQGLFormat&, const TQGLFormat& );
+
+class TQM_EXPORT_OPENGL TQGLContext : public TQGL
+{
+public:
+ TQGLContext( const TQGLFormat& format, TQPaintDevice* tqdevice );
+ TQGLContext( const TQGLFormat& format );
+ virtual ~TQGLContext();
+
+ virtual bool create( const TQGLContext* shareContext = 0 );
+ bool isValid() const;
+ bool isSharing() const;
+ virtual void reset();
+
+ TQGLFormat format() const;
+ TQGLFormat requestedFormat() const;
+ virtual void setFormat( const TQGLFormat& format );
+
+ virtual void makeCurrent();
+ virtual void swapBuffers() const;
+
+ TQPaintDevice* tqdevice() const;
+
+ TQColor overlayTransparentColor() const;
+
+ static const TQGLContext* currentContext();
+
+protected:
+ virtual bool chooseContext( const TQGLContext* shareContext = 0 );
+ virtual void doneCurrent(); // ### 4.0: make this public - needed for multithreading stuff
+
+#if defined(TQ_WS_WIN)
+ virtual int choosePixelFormat( void* pfd, HDC pdc );
+#endif
+#if defined(TQ_WS_X11)
+ virtual void* tryVisual( const TQGLFormat& f, int bufDepth = 1 );
+ virtual void* chooseVisual();
+#endif
+#if defined(TQ_WS_MAC)
+ virtual void* chooseMacVisual(GDHandle);
+#endif
+
+ bool tqdeviceIsPixmap() const;
+ bool windowCreated() const;
+ void setWindowCreated( bool on );
+ bool initialized() const;
+ void setInitialized( bool on );
+ void generateFontDisplayLists( const TQFont & fnt, int listBase );
+
+ uint colorIndex( const TQColor& c ) const;
+ void setValid( bool valid );
+ void setDevice( TQPaintDevice *pDev );
+
+protected:
+#if defined(TQ_WS_WIN)
+ HGLRC rc;
+ HDC dc;
+ WId win;
+ int pixelFormatId;
+ TQGLCmap* cmap;
+#elif defined(TQ_WS_X11) || defined(TQ_WS_MAC)
+ void* vi;
+ void* cx;
+#if defined(TQ_WS_X11)
+ TQ_UINT32 gpm;
+#endif
+#endif
+ TQGLFormat glFormat;
+ TQGLFormat reqFormat;
+ static TQGLContext* currentCtx;
+
+private:
+ void init( TQPaintDevice *dev = 0 );
+ class Private {
+ public:
+ bool valid;
+ bool sharing;
+ bool initDone;
+ bool crWin;
+ TQPaintDevice* paintDevice;
+ TQColor transpColor;
+#ifdef TQ_WS_MAC
+ TQRect oldR;
+#endif
+ };
+ Private* d;
+
+ friend class TQGLWidget;
+#ifdef TQ_WS_MAC
+ void fixBufferRect();
+#endif
+
+private: // Disabled copy constructor and operator=
+ TQGLContext() {}
+ TQGLContext( const TQGLContext& ) {}
+ TQGLContext& operator=( const TQGLContext& ) { return *this; }
+};
+
+
+
+
+class TQM_EXPORT_OPENGL TQGLWidget : public TQWidget, public TQGL
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQGLWidget( TQWidget* tqparent=0, const char* name=0,
+ const TQGLWidget* shareWidget = 0, WFlags f=0 );
+ TQGLWidget( TQGLContext *context, TQWidget* tqparent, const char* name=0,
+ const TQGLWidget* shareWidget = 0, WFlags f=0 );
+ TQGLWidget( const TQGLFormat& format, TQWidget* tqparent=0, const char* name=0,
+ const TQGLWidget* shareWidget = 0, WFlags f=0 );
+ ~TQGLWidget();
+
+ void qglColor( const TQColor& c ) const;
+ void qglClearColor( const TQColor& c ) const;
+
+ bool isValid() const;
+ bool isSharing() const;
+ virtual void makeCurrent();
+ void doneCurrent();
+
+ bool doubleBuffer() const;
+ virtual void swapBuffers();
+
+ TQGLFormat format() const;
+#ifndef TQ_TQDOC
+ virtual void setFormat( const TQGLFormat& format );
+#endif
+
+ const TQGLContext* context() const;
+#ifndef TQ_TQDOC
+ virtual void setContext( TQGLContext* context,
+ const TQGLContext* shareContext = 0,
+ bool deleteOldContext = TRUE );
+#endif
+
+ virtual TQPixmap renderPixmap( int w = 0, int h = 0,
+ bool useContext = FALSE );
+ virtual TQImage grabFrameBuffer( bool withAlpha = FALSE );
+
+ virtual void makeOverlayCurrent();
+ const TQGLContext* overlayContext() const;
+
+ static TQImage convertToGLFormat( const TQImage& img );
+
+ void setMouseTracking( bool enable );
+ virtual void reparent( TQWidget* tqparent, WFlags f, const TQPoint& p,
+ bool showIt = FALSE );
+
+ const TQGLColormap & colormap() const;
+ void setColormap( const TQGLColormap & map );
+
+ void renderText( int x, int y, const TQString & str,
+ const TQFont & fnt = TQFont(), int listBase = 2000 );
+ void renderText( double x, double y, double z, const TQString & str,
+ const TQFont & fnt = TQFont(), int listBase = 2000 );
+public Q_SLOTS:
+ virtual void updateGL();
+ virtual void updateOverlayGL();
+
+protected:
+ virtual void initializeGL();
+ virtual void resizeGL( int w, int h );
+ virtual void paintGL();
+
+ virtual void initializeOverlayGL();
+ virtual void resizeOverlayGL( int w, int h );
+ virtual void paintOverlayGL();
+
+ void setAutoBufferSwap( bool on );
+ bool autoBufferSwap() const;
+
+ void paintEvent( TQPaintEvent* );
+ void resizeEvent( TQResizeEvent* );
+
+ virtual void glInit();
+ virtual void glDraw();
+
+private:
+ int displayListBase( const TQFont & fnt, int listBase );
+ void cleanupColormaps();
+ void init( TQGLContext *context, const TQGLWidget* shareWidget );
+ bool renderCxPm( TQPixmap* pm );
+ TQGLContext* glcx;
+ bool autoSwap;
+
+ TQGLColormap cmap;
+
+#if defined(TQ_WS_WIN) || defined(TQ_WS_MAC)
+ TQGLContext* olcx;
+#elif defined(TQ_WS_X11)
+ TQGLOverlayWidget* olw;
+ friend class TQGLOverlayWidget;
+#endif
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQGLWidget( const TQGLWidget& );
+ TQGLWidget& operator=( const TQGLWidget& );
+#endif
+
+#if defined(TQ_WS_MAC)
+private:
+ const TQGLContext *slcx;
+ uint pending_fix : 1,
+ glcx_dblbuf : 2,
+ dblbuf : 1,
+ clp_serial : 15;
+ TQPixmap *gl_pix;
+ TQGLFormat req_format;
+
+ void macInternalRecreateContext( TQGLContext *ctx,
+ const TQGLContext* = NULL,
+ bool update = TRUE );
+ bool macInternalDoubleBuffer( bool fix = TRUE );
+ virtual void setRegionDirty( bool );
+ virtual void macWidgetChangedWindow();
+#endif
+private Q_SLOTS:
+ void macInternalFixBufferRect();
+};
+
+
+//
+// TQGLFormat inline functions
+//
+
+inline bool TQGLFormat::doubleBuffer() const
+{
+ return testOption( DoubleBuffer );
+}
+
+inline bool TQGLFormat::depth() const
+{
+ return testOption( DepthBuffer );
+}
+
+inline bool TQGLFormat::rgba() const
+{
+ return testOption( Rgba );
+}
+
+inline bool TQGLFormat::alpha() const
+{
+ return testOption( AlphaChannel );
+}
+
+inline bool TQGLFormat::accum() const
+{
+ return testOption( AccumBuffer );
+}
+
+inline bool TQGLFormat::stencil() const
+{
+ return testOption( StencilBuffer );
+}
+
+inline bool TQGLFormat::stereo() const
+{
+ return testOption( StereoBuffers );
+}
+
+inline bool TQGLFormat::directRendering() const
+{
+ return testOption( DirectRendering );
+}
+
+inline bool TQGLFormat::hasOverlay() const
+{
+ return testOption( HasOverlay );
+}
+
+//
+// TQGLContext inline functions
+//
+
+inline bool TQGLContext::isValid() const
+{
+ return d->valid;
+}
+
+inline void TQGLContext::setValid( bool valid )
+{
+ d->valid = valid;
+}
+
+inline bool TQGLContext::isSharing() const
+{
+ return d->sharing;
+}
+
+inline TQGLFormat TQGLContext::format() const
+{
+ return glFormat;
+}
+
+inline TQGLFormat TQGLContext::requestedFormat() const
+{
+ return reqFormat;
+}
+
+inline TQPaintDevice* TQGLContext::tqdevice() const
+{
+ return d->paintDevice;
+}
+
+inline bool TQGLContext::tqdeviceIsPixmap() const
+{
+ return d->paintDevice->devType() == TQInternal::Pixmap;
+}
+
+
+inline bool TQGLContext::windowCreated() const
+{
+ return d->crWin;
+}
+
+
+inline void TQGLContext::setWindowCreated( bool on )
+{
+ d->crWin = on;
+}
+
+inline bool TQGLContext::initialized() const
+{
+ return d->initDone;
+}
+
+inline void TQGLContext::setInitialized( bool on )
+{
+ d->initDone = on;
+}
+
+inline const TQGLContext* TQGLContext::currentContext()
+{
+ return currentCtx;
+}
+
+//
+// TQGLWidget inline functions
+//
+
+inline TQGLFormat TQGLWidget::format() const
+{
+ return glcx->format();
+}
+
+inline const TQGLContext *TQGLWidget::context() const
+{
+ return glcx;
+}
+
+inline bool TQGLWidget::doubleBuffer() const
+{
+ return glcx->format().doubleBuffer();
+}
+
+inline void TQGLWidget::setAutoBufferSwap( bool on )
+{
+ autoSwap = on;
+}
+
+inline bool TQGLWidget::autoBufferSwap() const
+{
+ return autoSwap;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/opengl/tqgl_x11.cpp b/tqtinterface/qt4/src/opengl/tqgl_x11.cpp
new file mode 100644
index 0000000..56fc053
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqgl_x11.cpp
@@ -0,0 +1,1425 @@
+/****************************************************************************
+**
+** Implementation of OpenGL classes for TQt
+**
+** Created : 970112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the opengl module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqgl.h"
+
+#if defined(TQ_WS_X11)
+
+#include "tqmap.h"
+#include "tqpixmap.h"
+#include "tqapplication.h"
+
+#include "tqintdict.h"
+#include "private/tqfontengine_p.h"
+
+#define INT8 dummy_INT8
+#define INT32 dummy_INT32
+#include <GL/glx.h>
+#undef INT8
+#undef INT32
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+#ifndef TQT_DLOPEN_OPENGL
+extern "C" {
+ Status XmuLookupStandardColormap( Display *dpy, int screen, VisualID visualid,
+ unsigned int depth, Atom property,
+ Bool tqreplace, Bool retain );
+}
+#endif
+
+#include "tqgl_x11_p.h"
+#ifdef TQT_DLOPEN_OPENGL
+#include "tqlibrary.h"
+
+extern "C" {
+_glCallLists qt_glCallLists;
+_glClearColor qt_glClearColor;
+_glClearIndex qt_glClearIndex;
+_glColor3ub qt_glColor3ub;
+_glDeleteLists qt_glDeleteLists;
+_glDrawBuffer qt_glDrawBuffer;
+_glFlush qt_glFlush;
+_glIndexi qt_glIndexi;
+_glListBase qt_glListBase;
+_glLoadIdentity qt_glLoadIdentity;
+_glMatrixMode qt_glMatrixMode;
+_glOrtho qt_glOrtho;
+_glPopAttrib qt_glPopAttrib;
+_glPopMatrix qt_glPopMatrix;
+_glPushAttrib qt_glPushAttrib;
+_glPushMatrix qt_glPushMatrix;
+_glRasterPos2i qt_glRasterPos2i;
+_glRasterPos3d qt_glRasterPos3d;
+_glReadPixels qt_glReadPixels;
+_glViewport qt_glViewport;
+_glPixelStorei qt_glPixelStorei;
+_glBitmap qt_glBitmap;
+_glDrawPixels qt_glDrawPixels;
+_glNewList qt_glNewList;
+_glGetFloatv qt_glGetFloatv;
+_glGetIntegerv qt_glGetIntegerv;
+_glEndList qt_glEndList;
+
+_glXChooseVisual qt_glXChooseVisual;
+_glXCreateContext qt_glXCreateContext;
+_glXCreateGLXPixmap qt_glXCreateGLXPixmap;
+_glXDestroyContext qt_glXDestroyContext;
+_glXDestroyGLXPixmap qt_glXDestroyGLXPixmap;
+_glXGetClientString qt_glXGetClientString;
+_glXGetConfig qt_glXGetConfig;
+_glXIsDirect qt_glXIsDirect;
+_glXMakeCurrent qt_glXMakeCurrent;
+_glXQueryExtension qt_glXQueryExtension;
+_glXQueryExtensionsString qt_glXQueryExtensionsString;
+_glXQueryServerString qt_glXQueryServerString;
+_glXSwapBuffers qt_glXSwapBuffers;
+_glXUseXFont qt_glXUseXFont;
+_glXWaitX qt_glXWaitX;
+};
+
+bool qt_resolve_gl_symbols(bool fatal)
+{
+ static bool gl_syms_resolved = FALSE;
+ if (gl_syms_resolved)
+ return TRUE;
+
+ TQLibrary gl("GL");
+ gl.setAutoUnload(FALSE);
+
+ qt_glCallLists = (_glCallLists) gl.resolve("glCallLists");
+
+ if (!qt_glCallLists) { // if this fails the rest will surely fail
+ if (fatal)
+ qFatal("Unable to resolve GL/GLX symbols - please check your GL library installation.");
+ return FALSE;
+ }
+
+ qt_glClearColor = (_glClearColor) gl.resolve("glClearColor");
+ qt_glClearIndex = (_glClearIndex) gl.resolve("glClearIndex");
+ qt_glColor3ub = (_glColor3ub) gl.resolve("glColor3ub");
+ qt_glDeleteLists = (_glDeleteLists) gl.resolve("glDeleteLists");
+ qt_glDrawBuffer = (_glDrawBuffer) gl.resolve("glDrawBuffer");
+ qt_glFlush = (_glFlush) gl.resolve("glFlush");
+ qt_glIndexi = (_glIndexi) gl.resolve("glIndexi");
+ qt_glListBase = (_glListBase) gl.resolve("glListBase");
+ qt_glLoadIdentity = (_glLoadIdentity) gl.resolve("glLoadIdentity");
+ qt_glMatrixMode = (_glMatrixMode) gl.resolve("glMatrixMode");
+ qt_glOrtho = (_glOrtho) gl.resolve("glOrtho");
+ qt_glPopAttrib = (_glPopAttrib) gl.resolve("glPopAttrib");
+ qt_glPopMatrix = (_glPopMatrix) gl.resolve("glPopMatrix");
+ qt_glPushAttrib = (_glPushAttrib) gl.resolve("glPushAttrib");
+ qt_glPushMatrix = (_glPushMatrix) gl.resolve("glPushMatrix");
+ qt_glRasterPos2i = (_glRasterPos2i) gl.resolve("glRasterPos2i");
+ qt_glRasterPos3d = (_glRasterPos3d) gl.resolve("glRasterPos3d");
+ qt_glReadPixels = (_glReadPixels) gl.resolve("glReadPixels");
+ qt_glViewport = (_glViewport) gl.resolve("glViewport");
+ qt_glPixelStorei = (_glPixelStorei) gl.resolve("glPixelStorei");
+ qt_glBitmap = (_glBitmap) gl.resolve("glBitmap");
+ qt_glDrawPixels = (_glDrawPixels) gl.resolve("glDrawPixels");
+ qt_glNewList = (_glNewList) gl.resolve("glNewList");
+ qt_glGetFloatv = (_glGetFloatv) gl.resolve("glGetFloatv");
+ qt_glGetIntegerv = (_glGetIntegerv) gl.resolve("glGetIntegerv");
+ qt_glEndList = (_glEndList) gl.resolve("glEndList");
+
+ qt_glXChooseVisual = (_glXChooseVisual) gl.resolve("glXChooseVisual");
+ qt_glXCreateContext = (_glXCreateContext) gl.resolve("glXCreateContext");
+ qt_glXCreateGLXPixmap = (_glXCreateGLXPixmap) gl.resolve("glXCreateGLXPixmap");
+ qt_glXDestroyContext = (_glXDestroyContext) gl.resolve("glXDestroyContext");
+ qt_glXDestroyGLXPixmap = (_glXDestroyGLXPixmap) gl.resolve("glXDestroyGLXPixmap");
+ qt_glXGetClientString = (_glXGetClientString) gl.resolve("glXGetClientString");
+ qt_glXGetConfig = (_glXGetConfig) gl.resolve("glXGetConfig");
+ qt_glXIsDirect = (_glXIsDirect) gl.resolve("glXIsDirect");
+ qt_glXMakeCurrent = (_glXMakeCurrent) gl.resolve("glXMakeCurrent");
+ qt_glXQueryExtension = (_glXQueryExtension) gl.resolve("glXQueryExtension");
+ qt_glXQueryExtensionsString = (_glXQueryExtensionsString) gl.resolve("glXQueryExtensionsString");
+ qt_glXQueryServerString = (_glXQueryServerString) gl.resolve("glXQueryServerString");
+ qt_glXSwapBuffers = (_glXSwapBuffers) gl.resolve("glXSwapBuffers");
+ qt_glXUseXFont = (_glXUseXFont) gl.resolve("glXUseXFont");
+ qt_glXWaitX = (_glXWaitX) gl.resolve("glXWaitX");
+ gl_syms_resolved = TRUE;
+ return TRUE;
+}
+#endif // TQT_DLOPEN_OPENGL
+
+
+/*
+ The choose_cmap function is internal and used by TQGLWidget::setContext()
+ and GLX (not Windows). If the application can't tqfind any sharable
+ colormaps, it must at least create as few colormaps as possible. The
+ dictionary solution below ensures only one colormap is created per visual.
+ Colormaps are also deleted when the application terminates.
+*/
+
+struct CMapEntry {
+ CMapEntry();
+ ~CMapEntry();
+ Colormap cmap;
+ bool alloc;
+ XStandardColormap scmap;
+};
+
+CMapEntry::CMapEntry()
+{
+ cmap = 0;
+ alloc = FALSE;
+ scmap.colormap = 0;
+}
+
+CMapEntry::~CMapEntry()
+{
+ if ( alloc )
+ XFreeColormap( TQPaintDevice::x11AppDisplay(), cmap );
+}
+
+static TQIntDict<CMapEntry> *cmap_dict = 0;
+static bool mesa_gl = FALSE;
+static TQIntDict< TQMap<int, TQRgb> > *qglcmap_dict = 0;
+
+static void cleanup_cmaps()
+{
+ if (cmap_dict) {
+ cmap_dict->setAutoDelete(TRUE);
+ delete cmap_dict;
+ cmap_dict = 0;
+ }
+ if (qglcmap_dict) {
+ qglcmap_dict->setAutoDelete(TRUE);
+ delete qglcmap_dict;
+ qglcmap_dict = 0;
+ }
+}
+
+static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
+{
+ if ( !cmap_dict ) {
+ cmap_dict = new TQIntDict<CMapEntry>;
+ const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
+ if ( v )
+ mesa_gl = strstr(v,"Mesa") != 0;
+ qAddPostRoutine( cleanup_cmaps );
+ }
+
+ CMapEntry *x = cmap_dict->tqfind( (long) vi->visualid + ( vi->screen * 256 ) );
+ if ( x ) // found colormap for visual
+ return x->cmap;
+
+ x = new CMapEntry();
+
+ XStandardColormap *c;
+ int n, i;
+
+ // qDebug( "Choosing cmap for vID %0x", vi->visualid );
+
+ if ( vi->visualid ==
+ XVisualIDFromVisual( (Visual*)TQPaintDevice::x11AppVisual( vi->screen ) ) ) {
+ // qDebug( "Using x11AppColormap" );
+ return TQPaintDevice::x11AppColormap( vi->screen );
+ }
+
+ if ( mesa_gl ) { // we're using MesaGL
+ Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", TRUE );
+ if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 ) {
+ if ( XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
+ hp_cmaps) ) {
+ i = 0;
+ while ( i < n && x->cmap == 0 ) {
+ if ( c[i].visualid == vi->visual->visualid ) {
+ x->cmap = c[i].colormap;
+ x->scmap = c[i];
+ //qDebug( "Using HP_RGB scmap" );
+
+ }
+ i++;
+ }
+ XFree( (char *)c );
+ }
+ }
+ }
+#if !defined(TQ_OS_SOLARIS)
+ if ( !x->cmap ) {
+#ifdef TQT_DLOPEN_OPENGL
+ typedef Status (*_XmuLookupStandardColormap)( Display *dpy, int screen, VisualID visualid, unsigned int depth,
+ Atom property, Bool tqreplace, Bool retain );
+ _XmuLookupStandardColormap qt_XmuLookupStandardColormap;
+ qt_XmuLookupStandardColormap = (_XmuLookupStandardColormap) TQLibrary::resolve("Xmu", "XmuLookupStandardColormap");
+ if (!qt_XmuLookupStandardColormap)
+ qFatal("Unable to resolve Xmu symbols - please check your Xmu library installation.");
+#define XmuLookupStandardColormap qt_XmuLookupStandardColormap
+
+#endif
+
+ if ( XmuLookupStandardColormap(dpy,vi->screen,vi->visualid,vi->depth,
+ XA_RGB_DEFAULT_MAP,FALSE,TRUE) ) {
+ if ( XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
+ XA_RGB_DEFAULT_MAP) ) {
+ i = 0;
+ while ( i < n && x->cmap == 0 ) {
+ if ( c[i].visualid == vi->visualid ) {
+ x->cmap = c[i].colormap;
+ x->scmap = c[i];
+ //qDebug( "Using RGB_DEFAULT scmap" );
+ }
+ i++;
+ }
+ XFree( (char *)c );
+ }
+ }
+ }
+#endif
+ if ( !x->cmap ) { // no shared cmap found
+ x->cmap = XCreateColormap( dpy, RootWindow(dpy,vi->screen), vi->visual,
+ AllocNone );
+ x->alloc = TRUE;
+ // qDebug( "Allocating cmap" );
+ }
+
+ // associate cmap with visualid
+ cmap_dict->insert( (long) vi->visualid + ( vi->screen * 256 ), x );
+ return x->cmap;
+}
+
+struct TransColor
+{
+ VisualID vis;
+ int screen;
+ long color;
+};
+
+static TQMemArray<TransColor> trans_colors;
+static int trans_colors_init = FALSE;
+
+
+static void tqfind_trans_colors()
+{
+ struct OverlayProp {
+ long visual;
+ long type;
+ long value;
+ long layer;
+ };
+
+ trans_colors_init = TRUE;
+
+ Display* appDisplay = TQPaintDevice::x11AppDisplay();
+
+ int scr;
+ int lastsize = 0;
+ for ( scr = 0; scr < ScreenCount( appDisplay ); scr++ ) {
+ TQWidget* rootWin = TQT_TQWIDGET(TQApplication::desktop()->screen( scr ));
+ if ( !rootWin )
+ return; // Should not happen
+ Atom overlayVisualsAtom = XInternAtom( appDisplay,
+ "SERVER_OVERLAY_VISUALS", True );
+ if ( overlayVisualsAtom == None )
+ return; // Server has no overlays
+
+ Atom actualType;
+ int actualFormat;
+ ulong nItems;
+ ulong bytesAfter;
+ OverlayProp* overlayProps = 0;
+ int res = XGetWindowProperty( appDisplay, rootWin->winId(),
+ overlayVisualsAtom, 0, 10000, False,
+ overlayVisualsAtom, &actualType,
+ &actualFormat, &nItems, &bytesAfter,
+ (uchar**)&overlayProps );
+
+ if ( res != Success || actualType != overlayVisualsAtom
+ || actualFormat != 32 || nItems < 4 || !overlayProps )
+ return; // Error reading property
+
+ int numProps = nItems / 4;
+ trans_colors.resize( lastsize + numProps );
+ int j = lastsize;
+ for ( int i = 0; i < numProps; i++ ) {
+ if ( overlayProps[i].type == 1 ) {
+ trans_colors[j].vis = (VisualID)overlayProps[i].visual;
+ trans_colors[j].screen = scr;
+ trans_colors[j].color = (int)overlayProps[i].value;
+ j++;
+ }
+ }
+ XFree( overlayProps );
+ lastsize = j;
+ trans_colors.truncate( lastsize );
+ }
+}
+
+
+/*****************************************************************************
+ TQGLFormat UNIX/GLX-specific code
+ *****************************************************************************/
+
+bool TQGLFormat::hasOpenGL()
+{
+ if (!qt_resolve_gl_symbols(FALSE))
+ return FALSE;
+ return glXQueryExtension(qt_xdisplay(),0,0) != 0;
+}
+
+
+bool TQGLFormat::hasOpenGLOverlays()
+{
+ qt_resolve_gl_symbols();
+ if ( !trans_colors_init )
+ tqfind_trans_colors();
+ return trans_colors.size() > 0;
+}
+
+
+
+/*****************************************************************************
+ TQGLContext UNIX/GLX-specific code
+ *****************************************************************************/
+
+bool TQGLContext::chooseContext( const TQGLContext* shareContext )
+{
+ Display* disp = d->paintDevice->x11Display();
+ vi = chooseVisual();
+ if ( !vi )
+ return FALSE;
+
+ if ( tqdeviceIsPixmap() &&
+ (((XVisualInfo*)vi)->depth != d->paintDevice->x11Depth() ||
+ ((XVisualInfo*)vi)->screen != d->paintDevice->x11Screen()) )
+ {
+ XFree( vi );
+ XVisualInfo appVisInfo;
+ memset( &appVisInfo, 0, sizeof(XVisualInfo) );
+ appVisInfo.visualid = XVisualIDFromVisual( (Visual*)d->paintDevice->x11Visual() );
+ appVisInfo.screen = d->paintDevice->x11Screen();
+ int nvis;
+ vi = XGetVisualInfo( disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis );
+ if ( !vi )
+ return FALSE;
+
+ int useGL;
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_USE_GL, &useGL );
+ if ( !useGL )
+ return FALSE; //# Chickening out already...
+ }
+ int res;
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_LEVEL, &res );
+ glFormat.setPlane( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_DOUBLEBUFFER, &res );
+ glFormat.setDoubleBuffer( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_DEPTH_SIZE, &res );
+ glFormat.setDepth( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_RGBA, &res );
+ glFormat.setRgba( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_ALPHA_SIZE, &res );
+ glFormat.setAlpha( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_ACCUM_RED_SIZE, &res );
+ glFormat.setAccum( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_STENCIL_SIZE, &res );
+ glFormat.setStencil( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_STEREO, &res );
+ glFormat.setStereo( res );
+
+ Bool direct = format().directRendering() ? True : False;
+
+ if ( shareContext &&
+ ( !shareContext->isValid() || !shareContext->cx ) ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning("TQGLContext::chooseContext(): Cannot share with invalid context");
+#endif
+ shareContext = 0;
+ }
+
+ // 1. Sharing between rgba and color-index will give wrong colors.
+ // 2. Contexts cannot be shared btw. direct/non-direct renderers.
+ // 3. Pixmaps cannot share contexts that are set up for direct rendering.
+ if ( shareContext && (format().rgba() != shareContext->format().rgba() ||
+ (tqdeviceIsPixmap() &&
+ glXIsDirect( disp, (GLXContext)shareContext->cx ))))
+ shareContext = 0;
+
+ cx = 0;
+ if ( shareContext ) {
+ cx = glXCreateContext( disp, (XVisualInfo *)vi,
+ (GLXContext)shareContext->cx, direct );
+ if ( cx )
+ d->sharing = TRUE;
+ }
+ if ( !cx )
+ cx = glXCreateContext( disp, (XVisualInfo *)vi, None, direct );
+ if ( !cx )
+ return FALSE;
+ glFormat.setDirectRendering( glXIsDirect( disp, (GLXContext)cx ) );
+ if ( tqdeviceIsPixmap() ) {
+#if defined(GLX_MESA_pixmap_colormap) && defined(TQGL_USE_MESA_EXT)
+ gpm = glXCreateGLXPixmapMESA( disp, (XVisualInfo *)vi,
+ d->paintDevice->handle(),
+ choose_cmap( disp, (XVisualInfo *)vi ) );
+#else
+ gpm = (TQ_UINT32)glXCreateGLXPixmap( disp, (XVisualInfo *)vi,
+ d->paintDevice->handle() );
+#endif
+ if ( !gpm )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*!
+ <strong>X11 only</strong>: This virtual function tries to tqfind a
+ visual that matches the format, reducing the demands if the original
+ request cannot be met.
+
+ The algorithm for reducing the demands of the format is quite
+ simple-minded, so override this method in your subclass if your
+ application has spcific requirements on visual selection.
+
+ \sa chooseContext()
+*/
+
+void *TQGLContext::chooseVisual()
+{
+ static int bufDepths[] = { 8, 4, 2, 1 }; // Try 16, 12 also?
+ //todo: if pixmap, also make sure that vi->depth == pixmap->depth
+ void* vis = 0;
+ int i = 0;
+ bool fail = FALSE;
+ TQGLFormat fmt = format();
+ bool tryDouble = !fmt.doubleBuffer(); // Some GL impl's only have double
+ bool triedDouble = FALSE;
+ while( !fail && !( vis = tryVisual( fmt, bufDepths[i] ) ) ) {
+ if ( !fmt.rgba() && bufDepths[i] > 1 ) {
+ i++;
+ continue;
+ }
+ if ( tryDouble ) {
+ fmt.setDoubleBuffer( TRUE );
+ tryDouble = FALSE;
+ triedDouble = TRUE;
+ continue;
+ }
+ else if ( triedDouble ) {
+ fmt.setDoubleBuffer( FALSE );
+ triedDouble = FALSE;
+ }
+ if ( fmt.stereo() ) {
+ fmt.setStereo( FALSE );
+ continue;
+ }
+ if ( fmt.accum() ) {
+ fmt.setAccum( FALSE );
+ continue;
+ }
+ if ( fmt.stencil() ) {
+ fmt.setStencil( FALSE );
+ continue;
+ }
+ if ( fmt.alpha() ) {
+ fmt.setAlpha( FALSE );
+ continue;
+ }
+ if ( fmt.depth() ) {
+ fmt.setDepth( FALSE );
+ continue;
+ }
+ if ( fmt.doubleBuffer() ) {
+ fmt.setDoubleBuffer( FALSE );
+ continue;
+ }
+ fail = TRUE;
+ }
+ glFormat = fmt;
+ return vis;
+}
+
+
+/*!
+
+ \internal
+
+ <strong>X11 only</strong>: This virtual function chooses a visual
+ that matches the OpenGL \link format() format\endlink. Reimplement this
+ function in a subclass if you need a custom visual.
+
+ \sa chooseContext()
+*/
+
+void *TQGLContext::tryVisual( const TQGLFormat& f, int bufDepth )
+{
+ int spec[40];
+ int i = 0;
+ spec[i++] = GLX_LEVEL;
+ spec[i++] = f.plane();
+
+#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
+ static bool useTranspExt = FALSE;
+ static bool useTranspExtChecked = FALSE;
+ if ( f.plane() && !useTranspExtChecked && d->paintDevice ) {
+ TQCString estr( glXQueryExtensionsString( d->paintDevice->x11Display(),
+ d->paintDevice->x11Screen() ) );
+ useTranspExt = estr.tqcontains( "GLX_EXT_visual_info" );
+ //# (A bit simplistic; that could theoretically be a substring)
+ if ( useTranspExt ) {
+ TQCString cstr( glXGetClientString( d->paintDevice->x11Display(),
+ GLX_VENDOR ) );
+ useTranspExt = !cstr.tqcontains( "Xi Graphics" ); // bug workaround
+ if ( useTranspExt ) {
+ // bug workaround - some systems (eg. FireGL) refuses to return an overlay
+ // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specfied, even if
+ // the implementation supports transtqparent overlays
+ int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT,
+ f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT,
+ None };
+ XVisualInfo * vinf = glXChooseVisual( d->paintDevice->x11Display(),
+ d->paintDevice->x11Screen(), tmpSpec );
+ if ( !vinf ) {
+ useTranspExt = FALSE;
+ }
+ }
+ }
+
+ useTranspExtChecked = TRUE;
+ }
+ if ( f.plane() && useTranspExt ) {
+ // Required to avoid non-transtqparent overlay visual(!) on some systems
+ spec[i++] = GLX_TRANSPARENT_TYPE_EXT;
+ spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
+ }
+#endif
+
+ if ( f.doubleBuffer() )
+ spec[i++] = GLX_DOUBLEBUFFER;
+ if ( f.depth() ) {
+ spec[i++] = GLX_DEPTH_SIZE;
+ spec[i++] = 1;
+ }
+ if ( f.stereo() ) {
+ spec[i++] = GLX_STEREO;
+ }
+ if ( f.stencil() ) {
+ spec[i++] = GLX_STENCIL_SIZE;
+ spec[i++] = 1;
+ }
+ if ( f.rgba() ) {
+ spec[i++] = GLX_RGBA;
+ spec[i++] = GLX_RED_SIZE;
+ spec[i++] = 1;
+ spec[i++] = GLX_GREEN_SIZE;
+ spec[i++] = 1;
+ spec[i++] = GLX_BLUE_SIZE;
+ spec[i++] = 1;
+ if ( f.alpha() ) {
+ spec[i++] = GLX_ALPHA_SIZE;
+ spec[i++] = 1;
+ }
+ if ( f.accum() ) {
+ spec[i++] = GLX_ACCUM_RED_SIZE;
+ spec[i++] = 1;
+ spec[i++] = GLX_ACCUM_GREEN_SIZE;
+ spec[i++] = 1;
+ spec[i++] = GLX_ACCUM_BLUE_SIZE;
+ spec[i++] = 1;
+ if ( f.alpha() ) {
+ spec[i++] = GLX_ACCUM_ALPHA_SIZE;
+ spec[i++] = 1;
+ }
+ }
+ }
+ else {
+ spec[i++] = GLX_BUFFER_SIZE;
+ spec[i++] = bufDepth;
+ }
+
+ spec[i] = None;
+ return glXChooseVisual( d->paintDevice->x11Display(),
+ d->paintDevice->x11Screen(), spec );
+}
+
+
+void TQGLContext::reset()
+{
+ if ( !d->valid )
+ return;
+ doneCurrent();
+ if ( gpm )
+ glXDestroyGLXPixmap( d->paintDevice->x11Display(), (GLXPixmap)gpm );
+ gpm = 0;
+ glXDestroyContext( d->paintDevice->x11Display(), (GLXContext)cx );
+ if ( vi )
+ XFree( vi );
+ vi = 0;
+ cx = 0;
+ d->crWin = FALSE;
+ d->sharing = FALSE;
+ d->valid = FALSE;
+ d->transpColor = TQColor();
+ d->initDone = FALSE;
+}
+
+
+void TQGLContext::makeCurrent()
+{
+ if ( !d->valid ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQGLContext::makeCurrent(): Cannot make invalid context current.");
+#endif
+ return;
+ }
+ bool ok = TRUE;
+ if ( tqdeviceIsPixmap() )
+ ok = glXMakeCurrent( d->paintDevice->x11Display(),
+ (GLXPixmap)gpm,
+ (GLXContext)cx );
+
+ else
+ ok = glXMakeCurrent( d->paintDevice->x11Display(),
+ ((TQWidget *)d->paintDevice)->winId(),
+ (GLXContext)cx );
+#if defined(TQT_CHECK_NULL)
+ // qDebug("makeCurrent: %i, vi=%i, vi->vi=%i, vi->id=%i", (int)this, (int)vi, (int)((XVisualInfo*)vi)->visual, (int)((XVisualInfo*)vi)->visualid );
+ if ( !ok )
+ qWarning("TQGLContext::makeCurrent(): Failed.");
+#endif
+ if ( ok )
+ currentCtx = this;
+}
+
+void TQGLContext::doneCurrent()
+{
+ glXMakeCurrent( d->paintDevice->x11Display(), 0, 0 );
+ currentCtx = 0;
+}
+
+
+void TQGLContext::swapBuffers() const
+{
+ if ( !d->valid )
+ return;
+ if ( !tqdeviceIsPixmap() )
+ glXSwapBuffers( d->paintDevice->x11Display(),
+ ((TQWidget *)d->paintDevice)->winId() );
+}
+
+TQColor TQGLContext::overlayTransparentColor() const
+{
+ //### make more efficient using the transpColor member
+ if ( isValid() ) {
+ if ( !trans_colors_init )
+ tqfind_trans_colors();
+
+ VisualID myVisualId = ((XVisualInfo*)vi)->visualid;
+ int myScreen = ((XVisualInfo*)vi)->screen;
+ for ( int i = 0; i < (int)trans_colors.size(); i++ ) {
+ if ( trans_colors[i].vis == myVisualId &&
+ trans_colors[i].screen == myScreen ) {
+ XColor col;
+ col.pixel = trans_colors[i].color;
+ col.red = col.green = col.blue = 0;
+ col.flags = 0;
+ Display *dpy = d->paintDevice->x11Display();
+ if (col.pixel > (uint) ((XVisualInfo *)vi)->colormap_size - 1)
+ col.pixel = ((XVisualInfo *)vi)->colormap_size - 1;
+ XQueryColor(dpy, choose_cmap(dpy, (XVisualInfo *) vi), &col);
+ uchar r = (uchar)((col.red / 65535.0) * 255.0 + 0.5);
+ uchar g = (uchar)((col.green / 65535.0) * 255.0 + 0.5);
+ uchar b = (uchar)((col.blue / 65535.0) * 255.0 + 0.5);
+ return TQColor(tqRgb(r,g,b), trans_colors[i].color);
+ }
+ }
+ }
+ return TQColor(); // Invalid color
+}
+
+
+uint TQGLContext::colorIndex( const TQColor& c ) const
+{
+ int screen = ((XVisualInfo *)vi)->screen;
+ if ( isValid() ) {
+ if ( format().plane()
+ && c.pixel( screen ) == overlayTransparentColor().pixel( screen ) )
+ return c.pixel( screen ); // Special; don't look-up
+ if ( ((XVisualInfo*)vi)->visualid ==
+ XVisualIDFromVisual( (Visual*)TQPaintDevice::x11AppVisual( screen ) ) )
+ return c.pixel( screen ); // We're using TQColor's cmap
+
+ XVisualInfo *info = (XVisualInfo *) vi;
+ CMapEntry *x = cmap_dict->tqfind( (long) info->visualid + ( info->screen * 256 ) );
+ if ( x && !x->alloc) { // It's a standard colormap
+ int rf = (int)(((float)c.red() * (x->scmap.red_max+1))/256.0);
+ int gf = (int)(((float)c.green() * (x->scmap.green_max+1))/256.0);
+ int bf = (int)(((float)c.blue() * (x->scmap.blue_max+1))/256.0);
+ uint p = x->scmap.base_pixel
+ + ( rf * x->scmap.red_mult )
+ + ( gf * x->scmap.green_mult )
+ + ( bf * x->scmap.blue_mult );
+ return p;
+ } else {
+ if (!qglcmap_dict) {
+ qglcmap_dict = new TQIntDict< TQMap<int, TQRgb> >;
+ }
+ TQMap<int, TQRgb> *cmap;
+ if ((cmap = qglcmap_dict->tqfind((long) info->visualid)) == 0) {
+ cmap = new TQMap<int, TQRgb>;
+ qglcmap_dict->insert((long) info->visualid, cmap);
+ }
+
+ // already in the map?
+ TQRgb target = c.rgb();
+ TQMap<int, TQRgb>::Iterator it = cmap->begin();
+ for (; it != cmap->end(); ++it) {
+ if ((*it) == target)
+ return it.key();
+ }
+
+ // need to alloc color
+ unsigned long plane_mask[2];
+ unsigned long color_map_entry;
+ if (!XAllocColorCells (TQPaintDevice::x11AppDisplay(), x->cmap, TRUE, plane_mask, 0,
+ &color_map_entry, 1))
+ return c.pixel(screen);
+
+ XColor col;
+ col.flags = DoRed | DoGreen | DoBlue;
+ col.pixel = color_map_entry;
+ col.red = (ushort)((tqRed(c.rgb()) / 255.0) * 65535.0 + 0.5);
+ col.green = (ushort)((tqGreen(c.rgb()) / 255.0) * 65535.0 + 0.5);
+ col.blue = (ushort)((tqBlue(c.rgb()) / 255.0) * 65535.0 + 0.5);
+ XStoreColor(TQPaintDevice::x11AppDisplay(), x->cmap, &col);
+
+ cmap->insert(color_map_entry, target);
+ return color_map_entry;
+ }
+ }
+ return 0;
+}
+
+#ifdef USE_QT4
+// [FIXME] Implement this or switch to Qt4's OpenGL classes (preferred)
+void TQGLContext::generateFontDisplayLists( const TQFont & fnt, int listBase )
+{
+ printf("[FIXME] void TQGLContext::generateFontDisplayLists( const TQFont & fnt, int listBase ) unimplemented\n\r");
+}
+#else // USE_QT4
+#ifndef TQT_NO_XFTFREETYPE
+/*! \internal
+ This is basically a substitute for glxUseXFont() which can only
+ handle XLFD fonts. This version relies on XFT v2 to render the
+ glyphs, but it works with all fonts that XFT2 provides - both
+ antialiased and aliased bitmap and outline fonts.
+*/
+void qgl_use_font(TQFontEngineXft *engine, int first, int count, int listBase)
+{
+ GLfloat color[4];
+ glGetFloatv(GL_CURRENT_COLOR, color);
+
+ // save the pixel unpack state
+ GLint gl_swapbytes, gl_lsbfirst, gl_rowlength, gl_skiprows, gl_skippixels, gl_tqalignment;
+ glGetIntegerv (GL_UNPACK_SWAP_BYTES, &gl_swapbytes);
+ glGetIntegerv (GL_UNPACK_LSB_FIRST, &gl_lsbfirst);
+ glGetIntegerv (GL_UNPACK_ROW_LENGTH, &gl_rowlength);
+ glGetIntegerv (GL_UNPACK_SKIP_ROWS, &gl_skiprows);
+ glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &gl_skippixels);
+ glGetIntegerv (GL_UNPACK_ALIGNMENT, &gl_tqalignment);
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ Bool antialiased = False;
+#if 0 // disable antialias support for now
+ XftPatternGetBool(engine->pattern(), XFT_ANTIALIAS, 0, &antialiased);
+#endif
+#ifdef TQT_XFT2
+ FT_Face face = XftLockFace(engine->font());
+#else
+ FT_Face face = engine->face();
+#endif
+ // start generating font glyphs
+ for (int i = first; i < count; ++i) {
+ int list = listBase + i;
+ GLfloat x0, y0, dx, dy;
+
+ FT_Error err;
+
+ err = FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT);
+ if (err) {
+ qDebug("failed loading glyph %d from font", i);
+ TQ_ASSERT(!err);
+ }
+ err = FT_Render_Glyph(face->glyph, (antialiased ? ft_render_mode_normal
+ : ft_render_mode_mono));
+ if (err) {
+ qDebug("failed rendering glyph %d from font", i);
+ TQ_ASSERT(!err);
+ }
+
+ FT_Bitmap bm = face->glyph->bitmap;
+ x0 = face->glyph->metrics.horiBearingX >> 6;
+ y0 = (face->glyph->metrics.height - face->glyph->metrics.horiBearingY) >> 6;
+ dx = face->glyph->metrics.horiAdvance >> 6;
+ dy = 0;
+ int sz = bm.pitch * bm.rows;
+ uint *aa_glyph = 0;
+ uchar *ua_glyph = 0;
+
+ if (antialiased)
+ aa_glyph = new uint[sz];
+ else
+ ua_glyph = new uchar[sz];
+
+ // convert to GL format
+ for (int y = 0; y < bm.rows; ++y) {
+ for (int x = 0; x < bm.pitch; ++x) {
+ int c1 = y*bm.pitch + x;
+ int c2 = (bm.rows - y - 1) > 0 ? (bm.rows-y-1)*bm.pitch + x : x;
+ if (antialiased) {
+ aa_glyph[c1] = (int(color[0]*255) << 24)
+ | (int(color[1]*255) << 16)
+ | (int(color[2]*255) << 8) | bm.buffer[c2];
+ } else {
+ ua_glyph[c1] = bm.buffer[c2];
+ }
+ }
+ }
+
+ glNewList(list, GL_COMPILE);
+ if (antialiased) {
+ // calling glBitmap() is just a trick to move the current
+ // raster pos, since glGet*() won't work in display lists
+ glBitmap(0, 0, 0, 0, x0, -y0, 0);
+ glDrawPixels(bm.pitch, bm.rows, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, aa_glyph);
+ glBitmap(0, 0, 0, 0, dx-x0, y0, 0);
+ } else {
+ glBitmap(bm.pitch*8, bm.rows, -x0, y0, dx, dy, ua_glyph);
+ }
+ glEndList();
+ antialiased ? delete[] aa_glyph : delete[] ua_glyph;
+ }
+
+#ifdef TQT_XFT2
+ XftUnlockFace(engine->font());
+#endif
+
+ // restore pixel unpack settings
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, gl_swapbytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, gl_lsbfirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, gl_rowlength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, gl_skiprows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, gl_skippixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, gl_tqalignment);
+}
+#endif
+
+void TQGLContext::generateFontDisplayLists( const TQFont & fnt, int listBase )
+{
+ TQFont f(fnt);
+ TQFontEngine *engine = f.d->engineForScript(TQFont::Latin);
+
+#ifndef TQT_NO_XFTFREETYPE
+ if(engine->type() == TQFontEngine::Xft) {
+ qgl_use_font((TQFontEngineXft *) engine, 0, 256, listBase);
+ return;
+ }
+#endif
+ // glXUseXFont() only works with XLFD font structures and a few GL
+ // drivers crash if 0 is passed as the font handle
+ f.setStyleStrategy(TQFont::OpenGLCompatible);
+ if (f.handle() && (engine->type() == TQFontEngine::XLFD
+ || engine->type() == TQFontEngine::LatinXLFD)) {
+ glXUseXFont((Font) f.handle(), 0, 256, listBase);
+ }
+}
+
+#endif // USE_QT4
+
+/*****************************************************************************
+ TQGLOverlayWidget (Internal overlay class for X11)
+ *****************************************************************************/
+
+class TQGLOverlayWidget : public TQGLWidget
+{
+ TQ_OBJECT
+public:
+ TQGLOverlayWidget( const TQGLFormat& format, TQGLWidget* tqparent,
+ const char* name=0, const TQGLWidget* shareWidget=0 );
+
+protected:
+ void initializeGL();
+ void paintGL();
+ void resizeGL( int w, int h );
+
+private:
+ TQGLWidget* realWidget;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQGLOverlayWidget( const TQGLOverlayWidget& );
+ TQGLOverlayWidget& operator=( const TQGLOverlayWidget& );
+#endif
+};
+
+
+TQGLOverlayWidget::TQGLOverlayWidget( const TQGLFormat& format, TQGLWidget* tqparent,
+ const char* name,
+ const TQGLWidget* shareWidget )
+ : TQGLWidget( format, tqparent, name, shareWidget ? shareWidget->olw : 0 )
+{
+ realWidget = tqparent;
+}
+
+
+
+void TQGLOverlayWidget::initializeGL()
+{
+ TQColor transparentColor = context()->overlayTransparentColor();
+ if ( transparentColor.isValid() )
+ qglClearColor( transparentColor );
+ else
+ qWarning( "TQGLOverlayWidget::initializeGL(): Could not get transtqparent color" );
+ realWidget->initializeOverlayGL();
+}
+
+
+void TQGLOverlayWidget::resizeGL( int w, int h )
+{
+ glViewport( 0, 0, w, h );
+ realWidget->resizeOverlayGL( w, h );
+}
+
+
+void TQGLOverlayWidget::paintGL()
+{
+ realWidget->paintOverlayGL();
+}
+
+#undef Bool
+#include "tqgl_x11.tqmoc"
+
+/*****************************************************************************
+ TQGLWidget UNIX/GLX-specific code
+ *****************************************************************************/
+void TQGLWidget::init( TQGLContext *context, const TQGLWidget *shareWidget )
+{
+ qt_resolve_gl_symbols();
+
+ glcx = 0;
+ olw = 0;
+ autoSwap = TRUE;
+ if ( !context->tqdevice() )
+ context->setDevice( TQT_TQPAINTDEVICE(this) );
+
+ if ( shareWidget )
+ setContext( context, shareWidget->context() );
+ else
+ setContext( context );
+ setBackgroundMode( TQt::NoBackground );
+
+ if ( isValid() && context->format().hasOverlay() ) {
+ TQCString olwName( name() );
+ olwName += "-TQGL_internal_overlay_widget";
+ olw = new TQGLOverlayWidget( TQGLFormat::defaultOverlayFormat(),
+ this, olwName, shareWidget );
+ if ( olw->isValid() ) {
+ olw->setAutoBufferSwap( FALSE );
+ olw->setFocusProxy( this );
+ }
+ else {
+ delete olw;
+ olw = 0;
+ glcx->glFormat.setOverlay( FALSE );
+ }
+ }
+}
+
+/*! \reimp */
+void TQGLWidget::reparent( TQWidget* tqparent, WFlags f, const TQPoint& p,
+ bool showIt )
+{
+ if (glcx)
+ glcx->doneCurrent();
+ TQWidget::reparent( tqparent, f, p, FALSE );
+ if ( showIt )
+ show();
+}
+
+
+void TQGLWidget::setMouseTracking( bool enable )
+{
+ if ( olw )
+ olw->setMouseTracking( enable );
+ TQWidget::setMouseTracking( enable );
+}
+
+
+void TQGLWidget::resizeEvent( TQResizeEvent * )
+{
+ if ( !isValid() )
+ return;
+ makeCurrent();
+ if ( !glcx->initialized() )
+ glInit();
+ glXWaitX();
+ resizeGL( width(), height() );
+ if ( olw )
+ olw->setGeometry( rect() );
+}
+
+const TQGLContext* TQGLWidget::overlayContext() const
+{
+ if ( olw )
+ return olw->context();
+ else
+ return 0;
+}
+
+
+void TQGLWidget::makeOverlayCurrent()
+{
+ if ( olw )
+ olw->makeCurrent();
+}
+
+
+void TQGLWidget::updateOverlayGL()
+{
+ if ( olw )
+ olw->updateGL();
+}
+
+void TQGLWidget::setContext( TQGLContext *context,
+ const TQGLContext* shareContext,
+ bool deleteOldContext )
+{
+ if ( context == 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQGLWidget::setContext: Cannot set null context" );
+#endif
+ return;
+ }
+ if ( !context->tqdeviceIsPixmap() && context->tqdevice() != TQT_TQPAINTDEVICE(this) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQGLWidget::setContext: Context must refer to this widget" );
+#endif
+ return;
+ }
+
+ if ( glcx )
+ glcx->doneCurrent();
+ TQGLContext* oldcx = glcx;
+ glcx = context;
+
+ bool createFailed = FALSE;
+ if ( !glcx->isValid() ) {
+ if ( !glcx->create( shareContext ? shareContext : oldcx ) )
+ createFailed = TRUE;
+ }
+ if ( createFailed ) {
+ if ( deleteOldContext )
+ delete oldcx;
+ return;
+ }
+
+ if ( glcx->windowCreated() || glcx->tqdeviceIsPixmap() ) {
+ if ( deleteOldContext )
+ delete oldcx;
+ return;
+ }
+
+ bool visible = isVisible();
+ if ( visible )
+ hide();
+
+ XVisualInfo *vi = (XVisualInfo*)glcx->vi;
+ XSetWindowAttributes a;
+
+ a.colormap = choose_cmap( x11Display(), vi ); // tqfind best colormap
+ a.background_pixel = backgroundColor().pixel( vi->screen );
+ a.border_pixel = TQt::black.pixel( vi->screen );
+ Window p = RootWindow( x11Display(), vi->screen );
+ if ( parentWidget() )
+ p = parentWidget()->winId();
+
+ Window w = XCreateWindow( x11Display(), p, x(), y(), width(), height(),
+ 0, vi->depth, InputOutput, vi->visual,
+ CWBackPixel|CWBorderPixel|CWColormap, &a );
+
+ Window *cmw;
+ Window *cmwret;
+ int count;
+ if ( XGetWMColormapWindows( x11Display(), tqtopLevelWidget()->winId(),
+ &cmwret, &count ) ) {
+ cmw = new Window[count+1];
+ memcpy( (char *)cmw, (char *)cmwret, sizeof(Window)*count );
+ XFree( (char *)cmwret );
+ int i;
+ for ( i=0; i<count; i++ ) {
+ if ( cmw[i] == winId() ) { // tqreplace old window
+ cmw[i] = w;
+ break;
+ }
+ }
+ if ( i >= count ) // append new window
+ cmw[count++] = w;
+ } else {
+ count = 1;
+ cmw = new Window[count];
+ cmw[0] = w;
+ }
+
+#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT)
+ if ( oldcx && oldcx->windowCreated() )
+ glXReleaseBuffersMESA( x11Display(), winId() );
+#endif
+ if ( deleteOldContext )
+ delete oldcx;
+ oldcx = 0;
+
+ create( w );
+
+ XSetWMColormapWindows( x11Display(), tqtopLevelWidget()->winId(), cmw,
+ count );
+ delete [] cmw;
+
+ if ( visible )
+ show();
+ XFlush( x11Display() );
+ glcx->setWindowCreated( TRUE );
+}
+
+
+bool TQGLWidget::renderCxPm( TQPixmap* pm )
+{
+ if ( ((XVisualInfo*)glcx->vi)->depth != pm->depth() )
+ return FALSE;
+
+ GLXPixmap glPm;
+#if defined(GLX_MESA_pixmap_colormap) && defined(TQGL_USE_MESA_EXT)
+ glPm = glXCreateGLXPixmapMESA( x11Display(),
+ (XVisualInfo*)glcx->vi,
+ (Pixmap)pm->handle(),
+ choose_cmap( pm->x11Display(),
+ (XVisualInfo*)glcx->vi ) );
+#else
+ glPm = (TQ_UINT32)glXCreateGLXPixmap( x11Display(),
+ (XVisualInfo*)glcx->vi,
+ (Pixmap)pm->handle() );
+#endif
+
+ if ( !glXMakeCurrent( x11Display(), glPm, (GLXContext)glcx->cx ) ) {
+ glXDestroyGLXPixmap( x11Display(), glPm );
+ return FALSE;
+ }
+
+ glDrawBuffer( GL_FRONT );
+ if ( !glcx->initialized() )
+ glInit();
+ resizeGL( pm->width(), pm->height() );
+ paintGL();
+ glFlush();
+ makeCurrent();
+ glXDestroyGLXPixmap( x11Display(), glPm );
+ resizeGL( width(), height() );
+ return TRUE;
+}
+
+const TQGLColormap & TQGLWidget::colormap() const
+{
+ return cmap;
+}
+
+/*\internal
+ Store color values in the given colormap.
+*/
+static void qStoreColors( TQWidget * tlw, Colormap cmap,
+ const TQGLColormap & cols )
+{
+ XColor c;
+ TQRgb color;
+
+ for ( int i = 0; i < cols.size(); i++ ) {
+ color = cols.entryRgb( i );
+ c.pixel = i;
+ c.red = (ushort)( (tqRed( color ) / 255.0) * 65535.0 + 0.5 );
+ c.green = (ushort)( (tqGreen( color ) / 255.0) * 65535.0 + 0.5 );
+ c.blue = (ushort)( (tqBlue( color ) / 255.0) * 65535.0 + 0.5 );
+ c.flags = DoRed | DoGreen | DoBlue;
+ XStoreColor( tlw->x11Display(), cmap, &c );
+ }
+}
+
+#ifdef USE_QT4
+/*\internal
+ Check whether the given visual supports dynamic colormaps or not.
+*/
+static bool qCanAllocColors( TQWidget * w )
+{
+ return false;
+}
+#else // USE_QT4
+/*\internal
+ Check whether the given visual supports dynamic colormaps or not.
+*/
+static bool qCanAllocColors( TQWidget * w )
+{
+ bool validVisual = FALSE;
+ int numVisuals;
+ long tqmask;
+ XVisualInfo templ;
+ XVisualInfo * visuals;
+ VisualID id = XVisualIDFromVisual( (Visual *)
+ w->tqtopLevelWidget()->x11Visual() );
+
+ tqmask = VisualScreenMask;
+ templ.screen = w->x11Screen();
+ visuals = XGetVisualInfo( w->x11Display(), tqmask, &templ, &numVisuals );
+
+ for ( int i = 0; i < numVisuals; i++ ) {
+ if ( visuals[i].visualid == id ) {
+ switch ( visuals[i].c_class ) {
+ case TrueColor:
+ case StaticColor:
+ case StaticGray:
+ case GrayScale:
+ validVisual = FALSE;
+ break;
+ case DirectColor:
+ case PseudoColor:
+ validVisual = TRUE;
+ break;
+ }
+ break;
+ }
+ }
+ XFree( visuals );
+
+ if ( !validVisual )
+ return FALSE;
+ return TRUE;
+}
+
+void TQGLWidget::setColormap( const TQGLColormap & c )
+{
+ TQWidget * tlw = tqtopLevelWidget(); // must return a valid widget
+
+ cmap = c;
+ if ( !cmap.d )
+ return;
+
+ if ( !cmap.d->cmapHandle && !qCanAllocColors( this ) ) {
+ qWarning( "TQGLWidget::setColormap: Cannot create a read/write "
+ "colormap for this visual" );
+ return;
+ }
+
+ // If the child GL widget is not of the same visual class as the
+ // toplevel widget we will get in trouble..
+ Window wid = tlw->winId();
+ Visual * vis = (Visual *) tlw->x11Visual();;
+ VisualID cvId = XVisualIDFromVisual( (Visual *) x11Visual() );
+ VisualID tvId = XVisualIDFromVisual( (Visual *) tlw->x11Visual() );
+ if ( cvId != tvId ) {
+ wid = winId();
+ vis = (Visual *) x11Visual();
+ }
+
+ if ( !cmap.d->cmapHandle ) // allocate a cmap if necessary
+ cmap.d->cmapHandle = XCreateColormap( x11Display(), wid, vis,
+ AllocAll );
+
+ qStoreColors( this, (Colormap) cmap.d->cmapHandle, c );
+ XSetWindowColormap( x11Display(), wid, (Colormap) cmap.d->cmapHandle );
+
+ // tell the wm that this window has a special colormap
+ Window * cmw;
+ Window * cmwret;
+ int count;
+ if ( XGetWMColormapWindows( x11Display(), tlw->winId(), &cmwret,
+ &count ) )
+ {
+ cmw = new Window[count+1];
+ memcpy( (char *) cmw, (char *) cmwret, sizeof(Window) * count );
+ XFree( (char *) cmwret );
+ int i;
+ for ( i = 0; i < count; i++ ) {
+ if ( cmw[i] == winId() ) {
+ break;
+ }
+ }
+ if ( i >= count ) // append new window only if not in the list
+ cmw[count++] = winId();
+ } else {
+ count = 1;
+ cmw = new Window[count];
+ cmw[0] = winId();
+ }
+ XSetWMColormapWindows( x11Display(), tlw->winId(), cmw, count );
+ delete [] cmw;
+}
+#endif // USE_QT4
+
+/*! \internal
+ Free up any allocated colormaps. This fn is only called for
+ top-level widgets.
+*/
+void TQGLWidget::cleanupColormaps()
+{
+ if ( !cmap.d )
+ return;
+
+ if ( cmap.d->cmapHandle ) {
+ XFreeColormap( tqtopLevelWidget()->x11Display(),
+ (Colormap) cmap.d->cmapHandle );
+ cmap.d->cmapHandle = 0;
+ }
+}
+
+void TQGLWidget::macInternalFixBufferRect()
+{
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/opengl/tqgl_x11_p.h b/tqtinterface/qt4/src/opengl/tqgl_x11_p.h
new file mode 100644
index 0000000..cb88352
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqgl_x11_p.h
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Definitions needed for resolving GL/GLX symbols using dlopen()
+** under X11.
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the OpenGL module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGL_P_H
+#define TQGL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifdef TQT_DLOPEN_OPENGL
+// resolve the GL symbols we use ourselves
+bool qt_resolve_gl_symbols(bool = TRUE);
+extern "C" {
+// GL symbols
+typedef void (*_glCallLists)( GLsizei n, GLenum type, const GLvoid *lists );
+typedef void (*_glClearColor)( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha );
+typedef void (*_glClearIndex)( GLfloat c );
+typedef void (*_glColor3ub)( GLubyte red, GLubyte green, GLubyte blue );
+typedef void (*_glDeleteLists)( GLuint list, GLsizei range );
+typedef void (*_glDrawBuffer)( GLenum mode );
+typedef void (*_glFlush)( void );
+typedef void (*_glIndexi)( GLint c );
+typedef void (*_glListBase)( GLuint base );
+typedef void (*_glLoadIdentity)( void );
+typedef void (*_glMatrixMode)( GLenum mode );
+typedef void (*_glOrtho)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val );
+typedef void (*_glPopAttrib)( void );
+typedef void (*_glPopMatrix)( void );
+typedef void (*_glPushAttrib)( GLbitfield tqmask );
+typedef void (*_glPushMatrix)( void );
+typedef void (*_glRasterPos2i)( GLint x, GLint y );
+typedef void (*_glRasterPos3d)( GLdouble x, GLdouble y, GLdouble z );
+typedef void (*_glReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels );
+typedef void (*_glViewport)( GLint x, GLint y, GLsizei width, GLsizei height );
+typedef void (*_glPixelStorei)( GLenum pname, GLint param );
+typedef void (*_glBitmap)( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
+ const GLubyte *bitmap );
+typedef void (*_glDrawPixels)( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels );
+typedef void (*_glNewList)( GLuint list, GLenum mode );
+typedef void (*_glGetFloatv)( GLenum pname, GLfloat *params );
+typedef void (*_glGetIntegerv)( GLenum pname, GLint *params );
+typedef void (*_glEndList)( void );
+
+
+// GLX symbols - should be in the GL lib as well
+typedef XVisualInfo* (*_glXChooseVisual)(Display *dpy, int screen, int *attribList);
+typedef GLXContext (*_glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
+typedef GLXPixmap (*_glXCreateGLXPixmap)(Display *dpy, XVisualInfo *vis, Pixmap pixmap);
+typedef void (*_glXDestroyContext)(Display *dpy, GLXContext ctx);
+typedef void (*_glXDestroyGLXPixmap)(Display *dpy, GLXPixmap pix);
+typedef const char* (*_glXGetClientString)(Display *dpy, int name );
+typedef int (*_glXGetConfig)(Display *dpy, XVisualInfo *vis, int attrib, int *value);
+typedef Bool (*_glXIsDirect)(Display *dpy, GLXContext ctx);
+typedef Bool (*_glXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
+typedef Bool (*_glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase);
+typedef const char* (*_glXQueryExtensionsString)(Display *dpy, int screen);
+typedef const char* (*_glXQueryServerString)(Display *dpy, int screen, int name);
+typedef void (*_glXSwapBuffers)(Display *dpy, GLXDrawable drawable);
+typedef void (*_glXUseXFont)(Font font, int first, int count, int listBase);
+typedef void (*_glXWaitX)(void);
+
+extern _glCallLists qt_glCallLists;
+extern _glClearColor qt_glClearColor;
+extern _glClearIndex qt_glClearIndex;
+extern _glColor3ub qt_glColor3ub;
+extern _glDeleteLists qt_glDeleteLists;
+extern _glDrawBuffer qt_glDrawBuffer;
+extern _glFlush qt_glFlush;
+extern _glIndexi qt_glIndexi;
+extern _glListBase qt_glListBase;
+extern _glLoadIdentity qt_glLoadIdentity;
+extern _glMatrixMode qt_glMatrixMode;
+extern _glOrtho qt_glOrtho;
+extern _glPopAttrib qt_glPopAttrib;
+extern _glPopMatrix qt_glPopMatrix;
+extern _glPushAttrib qt_glPushAttrib;
+extern _glPushMatrix qt_glPushMatrix;
+extern _glRasterPos2i qt_glRasterPos2i;
+extern _glRasterPos3d qt_glRasterPos3d;
+extern _glReadPixels qt_glReadPixels;
+extern _glViewport qt_glViewport;
+extern _glPixelStorei qt_glPixelStorei;
+extern _glBitmap qt_glBitmap;
+extern _glDrawPixels qt_glDrawPixels;
+extern _glNewList qt_glNewList;
+extern _glGetFloatv qt_glGetFloatv;
+extern _glGetIntegerv qt_glGetIntegerv;
+extern _glEndList qt_glEndList;
+
+extern _glXChooseVisual qt_glXChooseVisual;
+extern _glXCreateContext qt_glXCreateContext;
+extern _glXCreateGLXPixmap qt_glXCreateGLXPixmap;
+extern _glXDestroyContext qt_glXDestroyContext;
+extern _glXDestroyGLXPixmap qt_glXDestroyGLXPixmap;
+extern _glXGetClientString qt_glXGetClientString;
+extern _glXGetConfig qt_glXGetConfig;
+extern _glXIsDirect qt_glXIsDirect;
+extern _glXMakeCurrent qt_glXMakeCurrent;
+extern _glXQueryExtension qt_glXQueryExtension;
+extern _glXQueryExtensionsString qt_glXQueryExtensionsString;
+extern _glXQueryServerString qt_glXQueryServerString;
+extern _glXSwapBuffers qt_glXSwapBuffers;
+extern _glXUseXFont qt_glXUseXFont;
+extern _glXWaitX qt_glXWaitX;
+}; // extern "C"
+
+#define glCallLists qt_glCallLists
+#define glClearColor qt_glClearColor
+#define glClearIndex qt_glClearIndex
+#define glColor3ub qt_glColor3ub
+#define glDeleteLists qt_glDeleteLists
+#define glDrawBuffer qt_glDrawBuffer
+#define glFlush qt_glFlush
+#define glIndexi qt_glIndexi
+#define glListBase qt_glListBase
+#define glLoadIdentity qt_glLoadIdentity
+#define glMatrixMode qt_glMatrixMode
+#define glOrtho qt_glOrtho
+#define glPopAttrib qt_glPopAttrib
+#define glPopMatrix qt_glPopMatrix
+#define glPushAttrib qt_glPushAttrib
+#define glPushMatrix qt_glPushMatrix
+#define glRasterPos2i qt_glRasterPos2i
+#define glRasterPos3d qt_glRasterPos3d
+#define glReadPixels qt_glReadPixels
+#define glViewport qt_glViewport
+#define glPixelStorei qt_glPixelStorei
+#define glBitmap qt_glBitmap
+#define glDrawPixels qt_glDrawPixels
+#define glNewList qt_glNewList
+#define glGetFloatv qt_glGetFloatv
+#define glGetIntegerv qt_glGetIntegerv
+#define glEndList qt_glEndList
+
+#define glXChooseVisual qt_glXChooseVisual
+#define glXCreateContext qt_glXCreateContext
+#define glXCreateGLXPixmap qt_glXCreateGLXPixmap
+#define glXDestroyContext qt_glXDestroyContext
+#define glXDestroyGLXPixmap qt_glXDestroyGLXPixmap
+#define glXGetClientString qt_glXGetClientString
+#define glXGetConfig qt_glXGetConfig
+#define glXIsDirect qt_glXIsDirect
+#define glXMakeCurrent qt_glXMakeCurrent
+#define glXQueryExtension qt_glXQueryExtension
+#define glXQueryExtensionsString qt_glXQueryExtensionsString
+#define glXQueryServerString qt_glXQueryServerString
+#define glXSwapBuffers qt_glXSwapBuffers
+#define glXUseXFont qt_glXUseXFont
+#define glXWaitX qt_glXWaitX
+
+#else
+inline bool qt_resolve_gl_symbols(bool = TRUE) { return TRUE; }
+#endif // TQT_DLOPEN_OPENGL
+#endif // TQGL_P_H
diff --git a/tqtinterface/qt4/src/opengl/tqglcolormap.cpp b/tqtinterface/qt4/src/opengl/tqglcolormap.cpp
new file mode 100644
index 0000000..6366e8b
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqglcolormap.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Implementation of TQGLColormap class
+**
+** Created : 20010326
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the opengl module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/*!
+ \class TQGLColormap tqglcolormap.h
+ \brief The TQGLColormap class is used for installing custom colormaps into
+ TQGLWidgets.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module OpenGL
+ \ingroup graphics
+ \ingroup images
+
+ TQGLColormap provides a platform independent way of specifying and
+ installing indexed colormaps into TQGLWidgets. TQGLColormap is
+ especially useful when using the \link opengl.html OpenGL\endlink
+ color-index mode.
+
+ Under X11 you must use an X server that supports either a \c
+ PseudoColor or \c DirectColor visual class. If your X server
+ currently only provides a \c GrayScale, \c TrueColor, \c
+ StaticColor or \c StaticGray visual, you will not be able to
+ allocate colorcells for writing. If this is the case, try setting
+ your X server to 8 bit mode. It should then provide you with at
+ least a \c PseudoColor visual. Note that you may experience
+ colormap flashing if your X server is running in 8 bit mode.
+
+ Under Windows the size of the colormap is always set to 256
+ colors. Note that under Windows you can also install colormaps
+ in child widgets.
+
+ This class uses explicit sharing (see \link shclass.html Shared
+ Classes\endlink).
+
+ Example of use:
+ \code
+ #include <tqapplication.h>
+ #include <tqglcolormap.h>
+
+ int main()
+ {
+ TQApplication a( argc, argv );
+
+ MySuperGLWidget widget( 0 ); // A TQGLWidget in color-index mode
+ TQGLColormap colormap;
+
+ // This will fill the colormap with colors ranging from
+ // black to white.
+ for ( int i = 0; i < colormap.size(); i++ )
+ colormap.setEntry( i, tqRgb( i, i, i ) );
+
+ widget.setColormap( colormap );
+ widget.show();
+ return a.exec();
+ }
+ \endcode
+
+ \sa TQGLWidget::setColormap(), TQGLWidget::colormap()
+*/
+
+#include "tqglcolormap.h"
+#include "tqmemarray.h"
+
+
+/*!
+ Construct a TQGLColormap.
+*/
+TQGLColormap::TQGLColormap()
+{
+ d = 0;
+}
+
+
+/*!
+ Construct a shallow copy of \a map.
+*/
+TQGLColormap::TQGLColormap( const TQGLColormap & map )
+{
+ d = map.d;
+ if ( d )
+ d->ref();
+}
+
+/*!
+ Dereferences the TQGLColormap and deletes it if this was the last
+ reference to it.
+*/
+TQGLColormap::~TQGLColormap()
+{
+ if ( d && d->deref() ) {
+ delete d;
+ d = 0;
+ }
+}
+
+/*!
+ Assign a shallow copy of \a map to this TQGLColormap.
+*/
+TQGLColormap & TQGLColormap::operator=( const TQGLColormap & map )
+{
+ if ( map.d != 0 )
+ map.d->ref();
+
+ if ( d && d->deref() )
+ delete d;
+ d = map.d;
+
+ return *this;
+}
+
+/*!
+ Detaches this TQGLColormap from the shared block.
+*/
+void TQGLColormap::detach()
+{
+ if ( d && d->count != 1 ) {
+ // ### What about the actual colormap handle?
+ Private * newd = new Private();
+ newd->cells = d->cells;
+ newd->cells.detach();
+ if ( d->deref() )
+ delete d;
+ d = newd;
+ }
+}
+
+/*!
+ Set cell at index \a idx in the colormap to color \a color.
+*/
+void TQGLColormap::setEntry( int idx, TQRgb color )
+{
+ if ( !d )
+ d = new Private();
+
+#if defined(TQT_CHECK_RANGE)
+ if ( idx < 0 || idx > (int) d->cells.size() ) {
+ qWarning( "TQGLColormap::setRgb: Index out of range." );
+ return;
+ }
+#endif
+ d->cells[ idx ] = color;
+}
+
+/*!
+ Set an array of cells in this colormap. \a count is the number of
+ colors that should be set, \a colors is the array of colors, and
+ \a base is the starting index.
+*/
+void TQGLColormap::setEntries( int count, const TQRgb * colors, int base )
+{
+ if ( !d )
+ d = new Private();
+
+ if ( !colors || base < 0 || base >= (int) d->cells.size() )
+ return;
+
+ for( int i = base; i < base + count; i++ ) {
+ if ( i < (int) d->cells.size() )
+ setEntry( i, colors[i] );
+ else
+ break;
+ }
+}
+
+/*!
+ Returns the TQRgb value in the colorcell with index \a idx.
+*/
+TQRgb TQGLColormap::entryRgb( int idx ) const
+{
+ if ( !d || idx < 0 || idx > (int) d->cells.size() )
+ return 0;
+ else
+ return d->cells[ idx ];
+}
+
+/*!
+ \overload
+
+ Set the cell with index \a idx in the colormap to color \a color.
+*/
+void TQGLColormap::setEntry( int idx, const TQColor & color )
+{
+ setEntry( idx, color.rgb() );
+}
+
+/*!
+ Returns the TQRgb value in the colorcell with index \a idx.
+*/
+TQColor TQGLColormap::entryColor( int idx ) const
+{
+ if ( !d || idx < 0 || idx > (int) d->cells.size() )
+ return TQColor();
+ else
+ return TQColor( d->cells[ idx ] );
+}
+
+/*!
+ Returns TRUE if the colormap is empty; otherwise returns FALSE. A
+ colormap with no color values set is considered to be empty.
+*/
+bool TQGLColormap::isEmpty() const
+{
+ return (d == 0) || (d->cells.size() == 0) || (d->cmapHandle == 0);
+}
+
+
+/*!
+ Returns the number of colorcells in the colormap.
+*/
+int TQGLColormap::size() const
+{
+ return d != 0 ? d->cells.size() : 0;
+}
+
+/*!
+ Returns the index of the color \a color. If \a color is not in the
+ map, -1 is returned.
+*/
+int TQGLColormap::tqfind( TQRgb color ) const
+{
+ if ( d )
+ return d->cells.tqfind( color );
+ return -1;
+}
+
+/*!
+ Returns the index of the color that is the closest match to color
+ \a color.
+*/
+int TQGLColormap::tqfindNearest( TQRgb color ) const
+{
+ int idx = tqfind( color );
+ if ( idx >= 0 )
+ return idx;
+ int mapSize = size();
+ int mindist = 200000;
+ int r = tqRed( color );
+ int g = tqGreen( color );
+ int b = tqBlue( color );
+ int rx, gx, bx, dist;
+ for ( int i=0; i < mapSize; i++ ) {
+ TQRgb ci = d->cells[i];
+ rx = r - tqRed( ci );
+ gx = g - tqGreen( ci );
+ bx = b - tqBlue( ci );
+ dist = rx*rx + gx*gx + bx*bx; // calculate distance
+ if ( dist < mindist ) { // minimal?
+ mindist = dist;
+ idx = i;
+ }
+ }
+ return idx;
+}
diff --git a/tqtinterface/qt4/src/opengl/tqglcolormap.h b/tqtinterface/qt4/src/opengl/tqglcolormap.h
new file mode 100644
index 0000000..d6fec59
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqglcolormap.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Definition of TQGLColormap class
+**
+** Created : 20010326
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the opengl module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGLCOLORMAP_H
+#define TQGLCOLORMAP_H
+
+#ifndef TQT_H
+#include "tqcolor.h"
+#include "tqmemarray.h"
+#include "tqshared.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_OPENGL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_OPENGL
+#else
+#define TQM_EXPORT_OPENGL TQ_EXPORT
+#endif
+
+class TQWidget;
+class TQM_EXPORT_OPENGL TQGLColormap
+{
+public:
+ TQGLColormap();
+ TQGLColormap( const TQGLColormap & );
+ ~TQGLColormap();
+
+ TQGLColormap &operator=( const TQGLColormap & );
+
+ bool isEmpty() const;
+ int size() const;
+ void detach();
+
+ void setEntries( int count, const TQRgb * colors, int base = 0 );
+ void setEntry( int idx, TQRgb color );
+ void setEntry( int idx, const TQColor & color );
+ TQRgb entryRgb( int idx ) const;
+ TQColor entryColor( int idx ) const;
+ int tqfind( TQRgb color ) const;
+ int tqfindNearest( TQRgb color ) const;
+
+private:
+ class Private : public TQShared
+ {
+ public:
+ Private() {
+ cells.resize( 256 ); // ### hardcoded to 256 entries for now
+ cmapHandle = 0;
+ }
+
+ ~Private() {
+ }
+
+ TQMemArray<TQRgb> cells;
+ TQt::HANDLE cmapHandle;
+ };
+
+ Private * d;
+
+ friend class TQGLWidget;
+};
+
+#endif