]> git.saurik.com Git - wxWidgets.git/blame - utils/glcanvas/motif/glcanvas.cpp
Moved wxGLCanvas to more normal positions
[wxWidgets.git] / utils / glcanvas / motif / glcanvas.cpp
CommitLineData
06ad8636
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: glcanvas.cpp
3// Purpose: wxGLCanvas, for using OpenGL with wxWindows 2.0 for Motif.
4// Uses the GLX extension.
5// Author: Julian Smart and Wolfram Gloger
6// Modified by:
7// Created: 1995, 1999
8// RCS-ID: $Id$
9// Copyright: (c) Julian Smart, Wolfram Gloger
10// Licence: wxWindows licence
11/////////////////////////////////////////////////////////////////////////////
12
13#ifdef __GNUG__
14#pragma implementation "glcanvas.h"
15#endif
16
17#include "glcanvas.h"
18#include "wx/utils.h"
19#include "wx/app.h"
20
21#include <Xm/Xm.h>
22#include "wx/motif/private.h"
23
24#ifdef OLD_MESA
25// workaround for bug in Mesa's glx.c
26static int bitcount( unsigned long n )
27{
28 int bits;
29 for (bits=0; n>0;) {
30 if(n & 1) bits++;
31 n = n >> 1;
32 }
33 return bits;
34}
35#endif
36
37/*
38 * GLCanvas implementation
39 */
40
41IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow)
42
43wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos,
44 const wxSize& size, long style,
45 const wxString& name, int *attrib_list, const wxPalette& palette):
46 wxScrolledWindow(parent, id, pos, size, style, name)
47{
48 XVisualInfo *vi, vi_templ;
49 XWindowAttributes xwa;
50 int val, n;
51
52 Display* display = (Display*) GetXDisplay();
53
54 glx_cx = 0;
55 // Check for the presence of the GLX extension
56 if(!glXQueryExtension(display, NULL, NULL)) {
57 wxDebugMsg("wxGLCanvas: GLX extension is missing\n");
58 return;
59 }
60
61 if(attrib_list) {
62 // Get an appropriate visual
63 vi = glXChooseVisual(display, DefaultScreen(display), attrib_list);
64 if(!vi) return;
65
66 // Here we should make sure that vi is the same visual as the
67 // one used by the xwindow drawable in wxCanvas. However,
68 // there is currently no mechanism for this in wx_canvs.cc.
69 } else {
70 // By default, we use the visual of xwindow
71 XGetWindowAttributes(display, (Window) GetXWindow(), &xwa);
72 vi_templ.visualid = XVisualIDFromVisual(xwa.visual);
73 vi = XGetVisualInfo(display, VisualIDMask, &vi_templ, &n);
74 if(!vi) return;
75 glXGetConfig(display, vi, GLX_USE_GL, &val);
76 if(!val) return;
77 // Basically, this is it. It should be possible to use vi
78 // in glXCreateContext() below. But this fails with Mesa.
79 // I notified the Mesa author about it; there may be a fix.
80#ifdef OLD_MESA
81 // Construct an attribute list matching the visual
82 int a_list[32];
83 n = 0;
84 if(vi->c_class==TrueColor || vi->c_class==DirectColor) { // RGBA visual
85 a_list[n++] = GLX_RGBA;
86 a_list[n++] = GLX_RED_SIZE;
87 a_list[n++] = bitcount(vi->red_mask);
88 a_list[n++] = GLX_GREEN_SIZE;
89 a_list[n++] = bitcount(vi->green_mask);
90 a_list[n++] = GLX_BLUE_SIZE;
91 a_list[n++] = bitcount(vi->blue_mask);
92 glXGetConfig(display, vi, GLX_ALPHA_SIZE, &val);
93 a_list[n++] = GLX_ALPHA_SIZE;
94 a_list[n++] = val;
95 } else { // Color index visual
96 glXGetConfig(display, vi, GLX_BUFFER_SIZE, &val);
97 a_list[n++] = GLX_BUFFER_SIZE;
98 a_list[n++] = val;
99 }
100 a_list[n] = None;
101 XFree(vi);
102 vi = glXChooseVisual(display, DefaultScreen(display), a_list);
103 if(!vi) return;
104#endif /* OLD_MESA */
105 }
106
107 // Create the GLX context and make it current
108 glx_cx = glXCreateContext(display, vi, 0, GL_TRUE);
109#ifndef OLD_MESA
110 XFree(vi);
111#endif
112 SetCurrent();
113}
114
115wxGLCanvas::~wxGLCanvas(void)
116{
117 Display* display = (Display*) GetXDisplay();
118 if(glx_cx) glXDestroyContext(display, glx_cx);
119}
120
121void wxGLCanvas::SwapBuffers()
122{
123 Display* display = (Display*) GetXDisplay();
124 if(glx_cx) glXSwapBuffers(display, (Window) GetXWindow());
125}
126
127void wxGLCanvas::SetCurrent()
128{
129 Display* display = (Display*) GetXDisplay();
130 if(glx_cx) glXMakeCurrent(display, (Window) GetXWindow(), glx_cx);
131}
132
133void wxGLCanvas::SetColour(const char *col)
134{
135 wxColour *the_colour = wxTheColourDatabase->FindColour(col);
136 if(the_colour) {
137 GLboolean b;
138 glGetBooleanv(GL_RGBA_MODE, &b);
139 if(b) {
140 glColor3ub(the_colour->Red(),
141 the_colour->Green(),
142 the_colour->Blue());
143 } else {
144 GLint pix = (GLint)the_colour->m_pixel;
145 if(pix == -1) {
146 XColor exact_def;
147 exact_def.red = (unsigned short)the_colour->Red() << 8;
148 exact_def.green = (unsigned short)the_colour->Green() << 8;
149 exact_def.blue = (unsigned short)the_colour->Blue() << 8;
150 exact_def.flags = DoRed | DoGreen | DoBlue;
151 if(!XAllocColor((Display*) GetXDisplay(), (Colormap) wxTheApp->GetMainColormap(GetXDisplay()), &exact_def)) {
152 wxDebugMsg("wxGLCanvas: cannot allocate color\n");
153 return;
154 }
155 pix = the_colour->m_pixel = exact_def.pixel;
156 }
157 glIndexi(pix);
158 }
159 }
160}
161