]> git.saurik.com Git - wxWidgets.git/blame - src/msw/glcanvas.cpp
don't refresh the current cell in SetCellHighlightROPenWidth() if it's invalid (...
[wxWidgets.git] / src / msw / glcanvas.cpp
CommitLineData
8b089c5e 1/////////////////////////////////////////////////////////////////////////////
2b8646e0 2// Name: src/msw/glcanvas.cpp
77ffb593 3// Purpose: wxGLCanvas, for using OpenGL with wxWidgets under MS Windows
8b089c5e
JS
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
8b089c5e
JS
10/////////////////////////////////////////////////////////////////////////////
11
dc3065a5
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
8b089c5e
JS
20#include "wx/wxprec.h"
21
22#if defined(__BORLANDC__)
02761f6c 23 #pragma hdrstop
8b089c5e
JS
24#endif
25
8b089c5e
JS
26#if wxUSE_GLCANVAS
27
28#ifndef WX_PRECOMP
af0b1533
VZ
29 #include "wx/intl.h"
30 #include "wx/log.h"
234d8e90 31 #include "wx/app.h"
02761f6c 32 #include "wx/module.h"
8b089c5e
JS
33#endif
34
af0b1533 35#include "wx/msw/private.h"
8b089c5e 36
af0b1533 37#include "wx/glcanvas.h"
8b089c5e 38
dc3065a5
VZ
39// from src/msw/window.cpp
40LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
41 WPARAM wParam, LPARAM lParam);
42
43#ifdef GL_EXT_vertex_array
b8ee9a86
WS
44 #define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) name
45#else
46 #define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) WXUNUSED(name)
47#endif
48
dc3065a5
VZ
49// ----------------------------------------------------------------------------
50// libraries
51// ----------------------------------------------------------------------------
52
0e82bd96
VZ
53/*
54 The following two compiler directives are specific to the Microsoft Visual
55 C++ family of compilers
56
57 Fundementally what they do is instruct the linker to use these two libraries
58 for the resolution of symbols. In essence, this is the equivalent of adding
59 these two libraries to either the Makefile or project file.
60
61 This is NOT a recommended technique, and certainly is unlikely to be used
77ffb593 62 anywhere else in wxWidgets given it is so specific to not only wxMSW, but
0e82bd96
VZ
63 also the VC compiler. However, in the case of opengl support, it's an
64 applicable technique as opengl is optional in setup.h This code (wrapped by
65 wxUSE_GLCANVAS), now allows opengl support to be added purely by modifying
66 setup.h rather than by having to modify either the project or DSP fle.
67
68 See MSDN for further information on the exact usage of these commands.
69*/
70#ifdef _MSC_VER
71# pragma comment( lib, "opengl32" )
72# pragma comment( lib, "glu32" )
73#endif
74
dc3065a5
VZ
75// ----------------------------------------------------------------------------
76// constants
77// ----------------------------------------------------------------------------
34fdf762 78
b225f659
VZ
79static const wxChar *wxGLCanvasClassName = wxT("wxGLCanvasClass");
80static const wxChar *wxGLCanvasClassNameNoRedraw = wxT("wxGLCanvasClassNR");
8b089c5e 81
dc3065a5
VZ
82// ============================================================================
83// implementation
84// ============================================================================
8b089c5e 85
53fcd32e
VZ
86// ----------------------------------------------------------------------------
87// wxGLModule is responsible for unregistering wxGLCanvasClass Windows class
88// ----------------------------------------------------------------------------
89
90class wxGLModule : public wxModule
91{
92public:
93 bool OnInit() { return true; }
94 void OnExit() { UnregisterClasses(); }
95
96 // register the GL classes if not done yet, return true if ok, false if
97 // registration failed
98 static bool RegisterClasses();
99
100 // unregister the classes, done automatically on program termination
101 static void UnregisterClasses();
102
103private:
104 // wxGLCanvas is only used from the main thread so this is MT-ok
105 static bool ms_registeredGLClasses;
106
107 DECLARE_DYNAMIC_CLASS(wxGLModule)
108};
109
110IMPLEMENT_DYNAMIC_CLASS(wxGLModule, wxModule)
111
112bool wxGLModule::ms_registeredGLClasses = false;
113
114/* static */
115bool wxGLModule::RegisterClasses()
116{
dc3065a5 117 if ( ms_registeredGLClasses )
53fcd32e
VZ
118 return true;
119
120 // We have to register a special window class because we need the CS_OWNDC
dc3065a5
VZ
121 // style for GLCanvas: some OpenGL drivers are buggy and don't work with
122 // windows without this style
53fcd32e
VZ
123 WNDCLASS wndclass;
124
125 // the fields which are common to all classes
126 wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
127 wndclass.cbClsExtra = 0;
128 wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for?
129 wndclass.hInstance = wxhInstance;
130 wndclass.hIcon = (HICON) NULL;
131 wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
132 wndclass.lpszMenuName = NULL;
133
134 // Register the GLCanvas class name
135 wndclass.hbrBackground = (HBRUSH)NULL;
136 wndclass.lpszClassName = wxGLCanvasClassName;
137 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
138
139 if ( !::RegisterClass(&wndclass) )
140 {
141 wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)"));
142 return false;
143 }
144
145 // Register the GLCanvas class name for windows which don't do full repaint
146 // on resize
147 wndclass.lpszClassName = wxGLCanvasClassNameNoRedraw;
148 wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW);
149
150 if ( !::RegisterClass(&wndclass) )
151 {
152 wxLogLastError(wxT("RegisterClass(wxGLCanvasClassNameNoRedraw)"));
153
154 ::UnregisterClass(wxGLCanvasClassName, wxhInstance);
155
156 return false;
157 }
158
159 ms_registeredGLClasses = true;
160
161 return true;
162}
163
164/* static */
165void wxGLModule::UnregisterClasses()
166{
167 // we need to unregister the classes in case we're in a DLL which is
168 // unloaded and then loaded again because if we don't, the registration is
169 // going to fail in wxGLCanvas::Create() the next time we're loaded
170 if ( ms_registeredGLClasses )
171 {
172 ::UnregisterClass(wxGLCanvasClassName, wxhInstance);
173 ::UnregisterClass(wxGLCanvasClassNameNoRedraw, wxhInstance);
174
175 ms_registeredGLClasses = false;
176 }
177}
178
dc3065a5
VZ
179// ----------------------------------------------------------------------------
180// wxGLContext
181// ----------------------------------------------------------------------------
8b089c5e 182
b7ea712c 183IMPLEMENT_CLASS(wxGLContext, wxObject)
8b089c5e 184
dc3065a5 185wxGLContext::wxGLContext(wxGLCanvas *win, const wxGLContext* other)
8b089c5e 186{
dc3065a5
VZ
187 m_glContext = wglCreateContext(win->GetHDC());
188 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGL context") );
8b089c5e 189
dc3065a5
VZ
190 if ( other )
191 {
192 if ( !wglShareLists(other->m_glContext, m_glContext) )
193 wxLogLastError(_T("wglShareLists"));
194 }
8b089c5e
JS
195}
196
197wxGLContext::~wxGLContext()
198{
dc3065a5 199 // note that it's ok to delete the context even if it's the current one
f48d169c 200 wglDeleteContext(m_glContext);
8b089c5e
JS
201}
202
5ec69e96 203bool wxGLContext::SetCurrent(const wxGLCanvas& win) const
8b089c5e 204{
dc3065a5
VZ
205 if ( !wglMakeCurrent(win.GetHDC(), m_glContext) )
206 {
207 wxLogLastError(_T("wglMakeCurrent"));
5ec69e96 208 return false;
dc3065a5 209 }
5ec69e96 210 return true;
8b089c5e
JS
211}
212
dc3065a5
VZ
213// ============================================================================
214// wxGLCanvas
215// ============================================================================
8b089c5e 216
4660d7e5 217IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
8b089c5e 218
4660d7e5 219BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow)
8b089c5e
JS
220 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged)
221 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette)
222END_EVENT_TABLE()
223
dc3065a5
VZ
224// ----------------------------------------------------------------------------
225// wxGLCanvas construction
226// ----------------------------------------------------------------------------
8b089c5e 227
dc3065a5 228void wxGLCanvas::Init()
8b089c5e 229{
dc3065a5
VZ
230#if WXWIN_COMPATIBILITY_2_8
231 m_glContext = NULL;
232#endif
233 m_hDC = NULL;
8b089c5e
JS
234}
235
dc3065a5
VZ
236wxGLCanvas::wxGLCanvas(wxWindow *parent,
237 wxWindowID id,
238 const int *attribList,
239 const wxPoint& pos,
240 const wxSize& size,
241 long style,
242 const wxString& name,
243 const wxPalette& palette)
8b089c5e 244{
dc3065a5 245 Init();
8b089c5e 246
dc3065a5 247 (void)Create(parent, id, pos, size, style, name, attribList, palette);
8b089c5e
JS
248}
249
250wxGLCanvas::~wxGLCanvas()
251{
dc3065a5 252 ::ReleaseDC(GetHwnd(), m_hDC);
8b089c5e
JS
253}
254
b225f659
VZ
255// Replaces wxWindow::Create functionality, since we need to use a different
256// window class
257bool wxGLCanvas::Create(wxWindow *parent,
258 wxWindowID id,
259 const wxPoint& pos,
260 const wxSize& size,
261 long style,
dc3065a5
VZ
262 const wxString& name,
263 const int *attribList,
264 const wxPalette& palette)
8b089c5e 265{
53fcd32e 266 wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") );
8b089c5e 267
53fcd32e 268 if ( !wxGLModule::RegisterClasses() )
b225f659 269 {
53fcd32e 270 wxLogError(_("Failed to register OpenGL window class."));
b225f659 271
213ceb3f 272 return false;
b225f659
VZ
273 }
274
53fcd32e
VZ
275 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
276 return false;
f48d169c 277
53fcd32e 278 parent->AddChild(this);
f48d169c 279
53fcd32e
VZ
280 /*
281 A general rule with OpenGL and Win32 is that any window that will have a
282 HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS.
283 You can find references about this within the knowledge base and most OpenGL
284 books that contain the wgl function descriptions.
285 */
53fcd32e 286 WXDWORD exStyle = 0;
dc3065a5
VZ
287 DWORD msflags = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
288 msflags |= MSWGetStyle(style, &exStyle);
289
290 if ( !MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle) )
291 return false;
f48d169c 292
dc3065a5
VZ
293 m_hDC = ::GetDC(GetHwnd());
294 if ( !m_hDC )
295 return false;
296
297 if ( !DoSetup(attribList) )
298 return false;
299
300#if wxUSE_PALETTE
301 if ( !SetupPalette(palette) )
302 return false;
303#else // !wxUSE_PALETTE
304 wxUnusedVar(palette);
305#endif // wxUSE_PALETTE/!wxUSE_PALETTE
306
307 return true;
308}
309
310// ----------------------------------------------------------------------------
311// operations
312// ----------------------------------------------------------------------------
313
5ec69e96 314bool wxGLCanvas::SwapBuffers()
dc3065a5
VZ
315{
316 if ( !::SwapBuffers(m_hDC) )
5ec69e96 317 {
dc3065a5 318 wxLogLastError(_T("SwapBuffers"));
77a96c67 319 return false;
5ec69e96 320 }
77a96c67 321
5ec69e96 322 return true;
8b089c5e
JS
323}
324
dc3065a5
VZ
325// ----------------------------------------------------------------------------
326// pixel format stuff
327// ----------------------------------------------------------------------------
328
329static void
330AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, const int *attribList)
8b089c5e 331{
dc3065a5
VZ
332 if ( !attribList )
333 return;
334
4aa59c3d 335 // remove default attributes
f48d169c
UN
336 pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
337 pfd.iPixelType = PFD_TYPE_COLORINDEX;
b225f659 338
4aa59c3d 339 for ( int arg = 0; attribList[arg]; )
f48d169c 340 {
dc3065a5
VZ
341 switch ( attribList[arg++] )
342 {
343 case WX_GL_RGBA:
344 pfd.iPixelType = PFD_TYPE_RGBA;
345 break;
4aa59c3d 346
dc3065a5
VZ
347 case WX_GL_BUFFER_SIZE:
348 pfd.cColorBits = attribList[arg++];
349 break;
4aa59c3d 350
dc3065a5
VZ
351 case WX_GL_LEVEL:
352 // this member looks like it may be obsolete
353 if ( attribList[arg] > 0 )
354 pfd.iLayerType = PFD_OVERLAY_PLANE;
355 else if ( attribList[arg] < 0 )
356 pfd.iLayerType = (BYTE)PFD_UNDERLAY_PLANE;
357 else
358 pfd.iLayerType = PFD_MAIN_PLANE;
359 arg++;
360 break;
4aa59c3d 361
dc3065a5
VZ
362 case WX_GL_DOUBLEBUFFER:
363 pfd.dwFlags |= PFD_DOUBLEBUFFER;
364 break;
4aa59c3d 365
dc3065a5
VZ
366 case WX_GL_STEREO:
367 pfd.dwFlags |= PFD_STEREO;
368 break;
4aa59c3d 369
dc3065a5
VZ
370 case WX_GL_AUX_BUFFERS:
371 pfd.cAuxBuffers = attribList[arg++];
372 break;
4aa59c3d 373
dc3065a5 374 case WX_GL_MIN_RED:
4aa59c3d 375 pfd.cColorBits += (pfd.cRedBits = attribList[arg++]);
dc3065a5 376 break;
4aa59c3d 377
dc3065a5 378 case WX_GL_MIN_GREEN:
4aa59c3d 379 pfd.cColorBits += (pfd.cGreenBits = attribList[arg++]);
dc3065a5 380 break;
4aa59c3d 381
dc3065a5 382 case WX_GL_MIN_BLUE:
4aa59c3d 383 pfd.cColorBits += (pfd.cBlueBits = attribList[arg++]);
dc3065a5 384 break;
4aa59c3d 385
dc3065a5
VZ
386 case WX_GL_MIN_ALPHA:
387 // doesn't count in cColorBits
388 pfd.cAlphaBits = attribList[arg++];
389 break;
4aa59c3d 390
dc3065a5
VZ
391 case WX_GL_DEPTH_SIZE:
392 pfd.cDepthBits = attribList[arg++];
393 break;
4aa59c3d 394
dc3065a5
VZ
395 case WX_GL_STENCIL_SIZE:
396 pfd.cStencilBits = attribList[arg++];
397 break;
4aa59c3d 398
dc3065a5 399 case WX_GL_MIN_ACCUM_RED:
4aa59c3d 400 pfd.cAccumBits += (pfd.cAccumRedBits = attribList[arg++]);
dc3065a5 401 break;
4aa59c3d 402
dc3065a5 403 case WX_GL_MIN_ACCUM_GREEN:
4aa59c3d 404 pfd.cAccumBits += (pfd.cAccumGreenBits = attribList[arg++]);
dc3065a5 405 break;
4aa59c3d 406
dc3065a5 407 case WX_GL_MIN_ACCUM_BLUE:
4aa59c3d 408 pfd.cAccumBits += (pfd.cAccumBlueBits = attribList[arg++]);
dc3065a5 409 break;
4aa59c3d 410
dc3065a5 411 case WX_GL_MIN_ACCUM_ALPHA:
4aa59c3d 412 pfd.cAccumBits += (pfd.cAccumAlphaBits = attribList[arg++]);
dc3065a5
VZ
413 break;
414 }
8b089c5e 415 }
a3081354
VZ
416}
417
dc3065a5
VZ
418/* static */
419int
420wxGLCanvas::ChooseMatchingPixelFormat(HDC hdc,
421 const int *attribList,
422 PIXELFORMATDESCRIPTOR *ppfd)
a3081354 423{
dc3065a5
VZ
424 // default neutral pixel format
425 PIXELFORMATDESCRIPTOR pfd =
426 {
427 sizeof(PIXELFORMATDESCRIPTOR), // size
428 1, // version
b225f659
VZ
429 PFD_SUPPORT_OPENGL |
430 PFD_DRAW_TO_WINDOW |
4aa59c3d
VZ
431 PFD_DOUBLEBUFFER, // use double-buffering by default
432 PFD_TYPE_RGBA, // default pixel type
433 0, // preferred color depth (don't care)
434 0, 0, 0, 0, 0, 0, // color bits and shift bits (ignored)
435 0, 0, // alpha bits and shift (ignored)
436 0, // accumulation total bits
437 0, 0, 0, 0, // accumulator RGBA bits (not used)
dc3065a5
VZ
438 16, // depth buffer
439 0, // no stencil buffer
440 0, // no auxiliary buffers
441 PFD_MAIN_PLANE, // main layer
442 0, // reserved
443 0, 0, 0, // no layer, visible, damage masks
b225f659 444 };
a3081354 445
dc3065a5
VZ
446 if ( !ppfd )
447 ppfd = &pfd;
448 else
449 *ppfd = pfd;
a3081354 450
dc3065a5
VZ
451 AdjustPFDForAttributes(*ppfd, attribList);
452
453 return ::ChoosePixelFormat(hdc, ppfd);
8b089c5e
JS
454}
455
3f20f7d8
VZ
456/* static */
457bool wxGLCanvasBase::IsDisplaySupported(const int *attribList)
458{
459 // We need a device context to test the pixel format, so get one
460 // for the root window.
461 return wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList) > 0;
462}
463
dc3065a5 464bool wxGLCanvas::DoSetup(const int *attribList)
8b089c5e 465{
8b089c5e 466 PIXELFORMATDESCRIPTOR pfd;
dc3065a5
VZ
467 const int pixelFormat = ChooseMatchingPixelFormat(m_hDC, attribList, &pfd);
468 if ( !pixelFormat )
469 {
470 wxLogLastError(_T("ChoosePixelFormat"));
471 return false;
472 }
473
474 if ( !::SetPixelFormat(m_hDC, pixelFormat, &pfd) )
475 {
476 wxLogLastError(_T("SetPixelFormat"));
477 return false;
478 }
479
480 return true;
481}
482
483// ----------------------------------------------------------------------------
484// palette stuff
485// ----------------------------------------------------------------------------
8b089c5e 486
dc3065a5 487#if wxUSE_PALETTE
8b089c5e 488
dc3065a5
VZ
489bool wxGLCanvas::SetupPalette(const wxPalette& palette)
490{
491 const int pixelFormat = ::GetPixelFormat(m_hDC);
492 if ( !pixelFormat )
8b089c5e 493 {
dc3065a5
VZ
494 wxLogLastError(_T("GetPixelFormat"));
495 return false;
8b089c5e 496 }
dc3065a5
VZ
497
498 PIXELFORMATDESCRIPTOR pfd;
499 if ( !::DescribePixelFormat(m_hDC, pixelFormat, sizeof(pfd), &pfd) )
8b089c5e 500 {
dc3065a5
VZ
501 wxLogLastError(_T("DescribePixelFormat"));
502 return false;
8b089c5e
JS
503 }
504
dc3065a5
VZ
505 if ( !(pfd.dwFlags & PFD_NEED_PALETTE) )
506 return true;
507
8b089c5e
JS
508 m_palette = palette;
509
510 if ( !m_palette.Ok() )
511 {
512 m_palette = CreateDefaultPalette();
dc3065a5
VZ
513 if ( !m_palette.Ok() )
514 return false;
515 }
516
517 if ( !::SelectPalette(m_hDC, GetHpaletteOf(m_palette), FALSE) )
518 {
519 wxLogLastError(_T("SelectPalette"));
520 return false;
8b089c5e
JS
521 }
522
dc3065a5 523 if ( ::RealizePalette(m_hDC) == GDI_ERROR )
8b089c5e 524 {
dc3065a5
VZ
525 wxLogLastError(_T("RealizePalette"));
526 return false;
8b089c5e 527 }
dc3065a5
VZ
528
529 return true;
8b089c5e
JS
530}
531
532wxPalette wxGLCanvas::CreateDefaultPalette()
533{
534 PIXELFORMATDESCRIPTOR pfd;
535 int paletteSize;
dc3065a5 536 int pixelFormat = GetPixelFormat(m_hDC);
8b089c5e 537
dc3065a5 538 DescribePixelFormat(m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
8b089c5e 539
f48d169c 540 paletteSize = 1 << pfd.cColorBits;
8b089c5e
JS
541
542 LOGPALETTE* pPal =
543 (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
544 pPal->palVersion = 0x300;
b8ee9a86 545 pPal->palNumEntries = (WORD)paletteSize;
8b089c5e
JS
546
547 /* build a simple RGB color palette */
548 {
b225f659
VZ
549 int redMask = (1 << pfd.cRedBits) - 1;
550 int greenMask = (1 << pfd.cGreenBits) - 1;
551 int blueMask = (1 << pfd.cBlueBits) - 1;
552 int i;
553
554 for (i=0; i<paletteSize; ++i) {
555 pPal->palPalEntry[i].peRed =
b8ee9a86 556 (BYTE)((((i >> pfd.cRedShift) & redMask) * 255) / redMask);
b225f659 557 pPal->palPalEntry[i].peGreen =
b8ee9a86 558 (BYTE)((((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask);
b225f659 559 pPal->palPalEntry[i].peBlue =
b8ee9a86 560 (BYTE)((((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask);
b225f659
VZ
561 pPal->palPalEntry[i].peFlags = 0;
562 }
8b089c5e
JS
563 }
564
565 HPALETTE hPalette = CreatePalette(pPal);
566 free(pPal);
567
568 wxPalette palette;
569 palette.SetHPALETTE((WXHPALETTE) hPalette);
570
571 return palette;
572}
573
8b089c5e
JS
574void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event)
575{
f48d169c
UN
576 /* realize palette if this is the current window */
577 if ( GetPalette()->Ok() ) {
578 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
dc3065a5
VZ
579 ::SelectPalette(GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
580 ::RealizePalette(GetHDC());
f48d169c 581 Refresh();
213ceb3f 582 event.SetPaletteRealized(true);
f48d169c
UN
583 }
584 else
213ceb3f 585 event.SetPaletteRealized(false);
8b089c5e
JS
586}
587
8b089c5e
JS
588void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
589{
f48d169c
UN
590 /* realize palette if this is *not* the current window */
591 if ( GetPalette() &&
8b089c5e 592 GetPalette()->Ok() && (this != event.GetChangedWindow()) )
f48d169c
UN
593 {
594 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
dc3065a5
VZ
595 ::SelectPalette(GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
596 ::RealizePalette(GetHDC());
f48d169c
UN
597 Refresh();
598 }
8b089c5e
JS
599}
600
dc3065a5 601#endif // wxUSE_PALETTE
a3081354 602
dc3065a5
VZ
603// ----------------------------------------------------------------------------
604// deprecated wxGLCanvas methods using implicit wxGLContext
605// ----------------------------------------------------------------------------
a3081354 606
dc3065a5
VZ
607// deprecated constructors creating an implicit m_glContext
608#if WXWIN_COMPATIBILITY_2_8
609
610wxGLCanvas::wxGLCanvas(wxWindow *parent,
611 wxWindowID id,
612 const wxPoint& pos,
613 const wxSize& size,
614 long style,
615 const wxString& name,
616 const int *attribList,
617 const wxPalette& palette)
a3081354 618{
dc3065a5 619 Init();
a3081354 620
dc3065a5
VZ
621 if ( Create(parent, id, pos, size, style, name, attribList, palette) )
622 m_glContext = new wxGLContext(this);
623}
a3081354 624
dc3065a5
VZ
625wxGLCanvas::wxGLCanvas(wxWindow *parent,
626 const wxGLContext *shared,
627 wxWindowID id,
628 const wxPoint& pos,
629 const wxSize& size,
630 long style,
631 const wxString& name,
632 const int *attribList,
633 const wxPalette& palette)
634{
635 Init();
a3081354 636
dc3065a5
VZ
637 if ( Create(parent, id, pos, size, style, name, attribList, palette) )
638 m_glContext = new wxGLContext(this, shared);
639}
640
641wxGLCanvas::wxGLCanvas(wxWindow *parent,
642 const wxGLCanvas *shared,
643 wxWindowID id,
644 const wxPoint& pos,
645 const wxSize& size,
646 long style,
647 const wxString& name,
648 const int *attribList,
649 const wxPalette& palette)
650{
651 Init();
a3081354 652
dc3065a5
VZ
653 if ( Create(parent, id, pos, size, style, name, attribList, palette) )
654 m_glContext = new wxGLContext(this, shared ? shared->m_glContext : NULL);
a3081354
VZ
655}
656
dc3065a5
VZ
657#endif // WXWIN_COMPATIBILITY_2_8
658
659
660// ----------------------------------------------------------------------------
661// wxGLApp
662// ----------------------------------------------------------------------------
663
664bool wxGLApp::InitGLVisual(const int *attribList)
a3081354 665{
dc3065a5
VZ
666 if ( !wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList) )
667 {
668 wxLogError(_("Failed to initialize OpenGL"));
669 return false;
670 }
671
672 return true;
a3081354
VZ
673}
674
dc3065a5 675#endif // wxUSE_GLCANVAS