0024233: OpenGl_Window - compilation for Windows NT 4.0 target
[occt.git] / src / OpenGl / OpenGl_Window.cxx
1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 #include <OpenGl_GlCore11.hxx>
21
22 #include <InterfaceGraphic.hxx>
23
24 #include <OpenGl_Window.hxx>
25
26 #include <OpenGl_Context.hxx>
27 #include <OpenGl_Display.hxx>
28
29 #include <Aspect_GraphicDeviceDefinitionError.hxx>
30 #include <TCollection_AsciiString.hxx>
31
32 IMPLEMENT_STANDARD_HANDLE(OpenGl_Window,MMgt_TShared)
33 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Window,MMgt_TShared)
34
35 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
36
37 namespace
38 {
39   static const TEL_COLOUR THE_DEFAULT_BG_COLOR = { { 0.F, 0.F, 0.F, 1.F } };
40
41 #if defined(_WIN32)
42
43   // WGL_ARB_pixel_format
44 #ifndef WGL_NUMBER_PIXEL_FORMATS_ARB
45   #define WGL_NUMBER_PIXEL_FORMATS_ARB            0x2000
46   #define WGL_DRAW_TO_WINDOW_ARB                  0x2001
47   #define WGL_DRAW_TO_BITMAP_ARB                  0x2002
48   #define WGL_ACCELERATION_ARB                    0x2003
49   #define WGL_NEED_PALETTE_ARB                    0x2004
50   #define WGL_NEED_SYSTEM_PALETTE_ARB             0x2005
51   #define WGL_SWAP_LAYER_BUFFERS_ARB              0x2006
52   #define WGL_SWAP_METHOD_ARB                     0x2007
53   #define WGL_NUMBER_OVERLAYS_ARB                 0x2008
54   #define WGL_NUMBER_UNDERLAYS_ARB                0x2009
55   #define WGL_TRANSPARENT_ARB                     0x200A
56   #define WGL_TRANSPARENT_RED_VALUE_ARB           0x2037
57   #define WGL_TRANSPARENT_GREEN_VALUE_ARB         0x2038
58   #define WGL_TRANSPARENT_BLUE_VALUE_ARB          0x2039
59   #define WGL_TRANSPARENT_ALPHA_VALUE_ARB         0x203A
60   #define WGL_TRANSPARENT_INDEX_VALUE_ARB         0x203B
61   #define WGL_SHARE_DEPTH_ARB                     0x200C
62   #define WGL_SHARE_STENCIL_ARB                   0x200D
63   #define WGL_SHARE_ACCUM_ARB                     0x200E
64   #define WGL_SUPPORT_GDI_ARB                     0x200F
65   #define WGL_SUPPORT_OPENGL_ARB                  0x2010
66   #define WGL_DOUBLE_BUFFER_ARB                   0x2011
67   #define WGL_STEREO_ARB                          0x2012
68   #define WGL_PIXEL_TYPE_ARB                      0x2013
69   #define WGL_COLOR_BITS_ARB                      0x2014
70   #define WGL_RED_BITS_ARB                        0x2015
71   #define WGL_RED_SHIFT_ARB                       0x2016
72   #define WGL_GREEN_BITS_ARB                      0x2017
73   #define WGL_GREEN_SHIFT_ARB                     0x2018
74   #define WGL_BLUE_BITS_ARB                       0x2019
75   #define WGL_BLUE_SHIFT_ARB                      0x201A
76   #define WGL_ALPHA_BITS_ARB                      0x201B
77   #define WGL_ALPHA_SHIFT_ARB                     0x201C
78   #define WGL_ACCUM_BITS_ARB                      0x201D
79   #define WGL_ACCUM_RED_BITS_ARB                  0x201E
80   #define WGL_ACCUM_GREEN_BITS_ARB                0x201F
81   #define WGL_ACCUM_BLUE_BITS_ARB                 0x2020
82   #define WGL_ACCUM_ALPHA_BITS_ARB                0x2021
83   #define WGL_DEPTH_BITS_ARB                      0x2022
84   #define WGL_STENCIL_BITS_ARB                    0x2023
85   #define WGL_AUX_BUFFERS_ARB                     0x2024
86
87   #define WGL_NO_ACCELERATION_ARB                 0x2025
88   #define WGL_GENERIC_ACCELERATION_ARB            0x2026
89   #define WGL_FULL_ACCELERATION_ARB               0x2027
90
91   #define WGL_SWAP_EXCHANGE_ARB                   0x2028
92   #define WGL_SWAP_COPY_ARB                       0x2029
93   #define WGL_SWAP_UNDEFINED_ARB                  0x202A
94
95   #define WGL_TYPE_RGBA_ARB                       0x202B
96   #define WGL_TYPE_COLORINDEX_ARB                 0x202C
97 #endif // WGL_NUMBER_PIXEL_FORMATS_ARB
98
99   // WGL_ARB_create_context_profile
100 #ifndef WGL_CONTEXT_MAJOR_VERSION_ARB
101   #define WGL_CONTEXT_MAJOR_VERSION_ARB           0x2091
102   #define WGL_CONTEXT_MINOR_VERSION_ARB           0x2092
103   #define WGL_CONTEXT_LAYER_PLANE_ARB             0x2093
104   #define WGL_CONTEXT_FLAGS_ARB                   0x2094
105   #define WGL_CONTEXT_PROFILE_MASK_ARB            0x9126
106
107   // WGL_CONTEXT_FLAGS bits
108   #define WGL_CONTEXT_DEBUG_BIT_ARB               0x0001
109   #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB  0x0002
110
111   // WGL_CONTEXT_PROFILE_MASK_ARB bits
112   #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB          0x00000001
113   #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
114 #endif // WGL_CONTEXT_MAJOR_VERSION_ARB
115
116   static LRESULT CALLBACK wndProcDummy (HWND theWin, UINT theMsg, WPARAM theParamW, LPARAM theParamL)
117   {
118     return DefWindowProcW (theWin, theMsg, theParamW, theParamL);
119   }
120 #else
121   static Bool WaitForNotify (Display* theDisp, XEvent* theEv, char* theArg)
122   {
123     return (theEv->type == MapNotify) && (theEv->xmap.window == (Window )theArg);
124   }
125 #endif
126
127 };
128
129 // =======================================================================
130 // function : OpenGl_Window
131 // purpose  :
132 // =======================================================================
133 OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
134                               const CALL_DEF_WINDOW&        theCWindow,
135                               Aspect_RenderingContext       theGContext,
136                               const Handle(OpenGl_Caps)&    theCaps,
137                               const Handle(OpenGl_Context)& theShareCtx)
138 : myDisplay (theDisplay),
139   myGlContext (new OpenGl_Context (theCaps)),
140   myOwnGContext (theGContext == 0),
141 #if defined(_WIN32)
142   mySysPalInUse (FALSE),
143 #endif
144   myWidth ((Standard_Integer )theCWindow.dx),
145   myHeight ((Standard_Integer )theCWindow.dy),
146   myBgColor (THE_DEFAULT_BG_COLOR),
147   myDither (theDisplay->Dither()),
148   myBackDither (theDisplay->BackDither())
149 {
150   myBgColor.rgb[0] = theCWindow.Background.r;
151   myBgColor.rgb[1] = theCWindow.Background.g;
152   myBgColor.rgb[2] = theCWindow.Background.b;
153
154 #if defined(_WIN32)
155   HWND  aWindow   = (HWND )theCWindow.XWindow;
156   HDC   aWindowDC = GetDC (aWindow);
157   HGLRC aGContext = (HGLRC )theGContext;
158
159   PIXELFORMATDESCRIPTOR aPixelFrmt;
160   memset (&aPixelFrmt, 0, sizeof(aPixelFrmt));
161   aPixelFrmt.nSize        = sizeof(PIXELFORMATDESCRIPTOR);
162   aPixelFrmt.nVersion     = 1;
163   aPixelFrmt.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
164   aPixelFrmt.iPixelType   = PFD_TYPE_RGBA;
165   aPixelFrmt.cColorBits   = 24;
166   aPixelFrmt.cDepthBits   = 24;
167   aPixelFrmt.cStencilBits = 8;
168   aPixelFrmt.iLayerType   = PFD_MAIN_PLANE;
169   if (theCaps->contextStereo)
170   {
171     aPixelFrmt.dwFlags |= PFD_STEREO;
172   }
173
174   int aPixelFrmtId = ChoosePixelFormat (aWindowDC, &aPixelFrmt);
175   if (aPixelFrmtId == 0)
176   {
177     ReleaseDC (aWindow, aWindowDC);
178
179     TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: ChoosePixelFormat failed. Error code: ");
180     aMsg += (int )GetLastError();
181     Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
182     return;
183   }
184
185   DescribePixelFormat (aWindowDC, aPixelFrmtId, sizeof(aPixelFrmt), &aPixelFrmt);
186   if (aPixelFrmt.dwFlags & PFD_NEED_PALETTE)
187   {
188     WINDOW_DATA* aWndData = (WINDOW_DATA* )GetWindowLongPtr (aWindow, GWLP_USERDATA);
189
190     mySysPalInUse = (aPixelFrmt.dwFlags & PFD_NEED_SYSTEM_PALETTE) ? TRUE : FALSE;
191     InterfaceGraphic_RealizePalette (aWindowDC, aWndData->hPal, FALSE, mySysPalInUse);
192   }
193
194   if (myDither)
195   {
196     myDither = (aPixelFrmt.cColorBits <= 8);
197   }
198
199   if (myBackDither)
200   {
201     myBackDither = (aPixelFrmt.cColorBits <= 8);
202   }
203
204   HGLRC aSlaveCtx = !theShareCtx.IsNull() ? (HGLRC )theShareCtx->myGContext : NULL;
205   if (aGContext == NULL)
206   {
207     // create temporary context to retrieve advanced context creation procedures
208     HMODULE aModule = GetModuleHandleW(NULL);
209     WNDCLASSW aClass; memset (&aClass, 0, sizeof(aClass));
210     aClass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
211     aClass.lpfnWndProc   = wndProcDummy;
212     aClass.hInstance     = aModule;
213     aClass.lpszClassName = L"OpenGl_WindowTmp";
214     HWND  aWinTmp     = NULL;
215     HDC   aDevCtxTmp  = NULL;
216     HGLRC aRendCtxTmp = NULL;
217     if ((!theCaps->contextDebug && !theCaps->contextNoAccel)
218      || RegisterClassW (&aClass) == 0)
219     {
220       aClass.lpszClassName = NULL;
221     }
222     if (aClass.lpszClassName != NULL)
223     {
224       DWORD anExStyle = WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE;
225     #if (_WIN32_WINNT >= 0x0500)
226       anExStyle |= WS_EX_NOACTIVATE;
227     #endif
228       aWinTmp = CreateWindowExW(anExStyle,
229                                 aClass.lpszClassName, L"OpenGl_WindowTmp",
230                                 WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED,
231                                 2, 2, 4, 4,
232                                 NULL, NULL, aModule, NULL);
233     }
234     if (aWinTmp != NULL)
235     {
236       aDevCtxTmp = GetDC (aWinTmp);
237       SetPixelFormat (aDevCtxTmp, aPixelFrmtId, &aPixelFrmt);
238       aRendCtxTmp = wglCreateContext (aDevCtxTmp);
239     }
240
241     typedef BOOL (WINAPI *wglChoosePixelFormatARB_t)(HDC           theDevCtx,
242                                                      const int*    theIntAttribs,
243                                                      const float*  theFloatAttribs,
244                                                      unsigned int  theMaxFormats,
245                                                      int*          theFormatsOut,
246                                                      unsigned int* theNumFormatsOut);
247     typedef HGLRC (WINAPI *wglCreateContextAttribsARB_t)(HDC        theDevCtx,
248                                                          HGLRC      theShareContext,
249                                                          const int* theAttribs);
250     wglChoosePixelFormatARB_t    aChoosePixProc = NULL;
251     wglCreateContextAttribsARB_t aCreateCtxProc = NULL;
252     if (aRendCtxTmp != NULL)
253     {
254       wglMakeCurrent (aDevCtxTmp, aRendCtxTmp);
255
256       typedef const char* (WINAPI *wglGetExtensionsStringARB_t)(HDC theDeviceContext);
257       wglGetExtensionsStringARB_t aGetExtensions = (wglGetExtensionsStringARB_t  )wglGetProcAddress ("wglGetExtensionsStringARB");
258       const char* aWglExts = (aGetExtensions != NULL) ? aGetExtensions (wglGetCurrentDC()) : NULL;
259       if (OpenGl_Context::CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
260       {
261         aChoosePixProc = (wglChoosePixelFormatARB_t    )wglGetProcAddress ("wglChoosePixelFormatARB");
262       }
263       if (OpenGl_Context::CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
264       {
265         aCreateCtxProc = (wglCreateContextAttribsARB_t )wglGetProcAddress ("wglCreateContextAttribsARB");
266       }
267     }
268
269     // choose extended pixel format
270     if (aChoosePixProc != NULL)
271     {
272       const int aPixAttribs[] =
273       {
274         WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
275         WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
276         WGL_DOUBLE_BUFFER_ARB,  GL_TRUE,
277         WGL_STEREO_ARB,         theCaps->contextStereo ? GL_TRUE : GL_FALSE,
278         WGL_PIXEL_TYPE_ARB,     WGL_TYPE_RGBA_ARB,
279         //WGL_SAMPLE_BUFFERS_ARB, 1,
280         //WGL_SAMPLES_ARB,        8,
281         WGL_COLOR_BITS_ARB,     24,
282         WGL_DEPTH_BITS_ARB,     24,
283         WGL_STENCIL_BITS_ARB,   8,
284         WGL_ACCELERATION_ARB,   theCaps->contextNoAccel ? WGL_NO_ACCELERATION_ARB : WGL_FULL_ACCELERATION_ARB,
285         0, 0,
286       };
287       unsigned int aFrmtsNb = 0;
288       aChoosePixProc (aWindowDC, aPixAttribs, NULL, 1, &aPixelFrmtId, &aFrmtsNb);
289     }
290
291     // setup pixel format - may be set only once per window
292     if (!SetPixelFormat (aWindowDC, aPixelFrmtId, &aPixelFrmt))
293     {
294       ReleaseDC (aWindow, aWindowDC);
295
296       TCollection_AsciiString aMsg("OpenGl_Window::CreateWindow: SetPixelFormat failed. Error code: ");
297       aMsg += (int )GetLastError();
298       Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
299       return;
300     }
301
302     // create GL context with extra options
303     if (aCreateCtxProc != NULL)
304     {
305       // Beware! NVIDIA drivers reject context creation when WGL_CONTEXT_PROFILE_MASK_ARB are specified
306       // but not WGL_CONTEXT_MAJOR_VERSION_ARB/WGL_CONTEXT_MINOR_VERSION_ARB.
307       int aCtxAttribs[] =
308       {
309         //WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
310         //WGL_CONTEXT_MINOR_VERSION_ARB, 2,
311         //WGL_CONTEXT_PROFILE_MASK_ARB,  WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
312         WGL_CONTEXT_FLAGS_ARB,         theCaps->contextDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
313         0, 0
314       };
315
316       aGContext = aCreateCtxProc (aWindowDC, aSlaveCtx, aCtxAttribs);
317       if (aGContext != NULL)
318       {
319         aSlaveCtx = NULL;
320       }
321     }
322
323     if (aRendCtxTmp != NULL)
324     {
325       wglDeleteContext (aRendCtxTmp);
326     }
327     if (aDevCtxTmp != NULL)
328     {
329       ReleaseDC (aWinTmp, aDevCtxTmp);
330     }
331     if (aWinTmp != NULL)
332     {
333       DestroyWindow (aWinTmp);
334     }
335     if (aClass.lpszClassName != NULL)
336     {
337       UnregisterClassW (aClass.lpszClassName, aModule);
338     }
339
340     if (aGContext == NULL)
341     {
342       // create context using obsolete functionality
343       aGContext = wglCreateContext (aWindowDC);
344     }
345     if (aGContext == NULL)
346     {
347       ReleaseDC (aWindow, aWindowDC);
348
349       TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglCreateContext failed. Error code: ");
350       aMsg += (int )GetLastError();
351       Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
352       return;
353     }
354   }
355
356   // all GL context within one OpenGl_GraphicDriver should be shared!
357   if (aSlaveCtx != NULL && wglShareLists (aSlaveCtx, aGContext) != TRUE)
358   {
359     TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglShareLists failed. Error code: ");
360     aMsg += (int )GetLastError();
361     Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
362     return;
363   }
364
365   myGlContext->Init ((Aspect_Handle )aWindow, (Aspect_Handle )aWindowDC, (Aspect_RenderingContext )aGContext);
366 #else
367   WINDOW aParent = (WINDOW )theCWindow.XWindow;
368   WINDOW aWindow = 0;
369   DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay();
370   GLXContext aGContext = (GLXContext )theGContext;
371
372   XWindowAttributes wattr;
373   XGetWindowAttributes (aDisp, aParent, &wattr);
374   const int scr = DefaultScreen (aDisp);
375
376   XVisualInfo* aVis = NULL;
377   {
378     unsigned long aVisInfoMask = VisualIDMask | VisualScreenMask;
379     XVisualInfo aVisInfo;
380     aVisInfo.visualid = wattr.visual->visualid;
381     aVisInfo.screen   = scr;
382     int aNbItems;
383     aVis = XGetVisualInfo (aDisp, aVisInfoMask, &aVisInfo, &aNbItems);
384   }
385
386   if (!myOwnGContext)
387   {
388     if (aVis != NULL)
389     {
390       Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: XGetVisualInfo failed.");
391       return;
392     }
393
394     aWindow = aParent;
395   }
396   else
397   {
398   #if defined(__linux) || defined(Linux) || defined(__APPLE__)
399     if (aVis != NULL)
400     {
401       // check Visual for OpenGl context's parameters compability
402       int isGl = 0, isDoubleBuffer = 0, isRGBA = 0, aDepthSize = 0, aStencilSize = 0;
403
404       if (glXGetConfig (aDisp, aVis, GLX_USE_GL, &isGl) != 0)
405         isGl = 0;
406
407       if (glXGetConfig (aDisp, aVis, GLX_RGBA, &isRGBA) != 0)
408         isRGBA = 0;
409
410       if (glXGetConfig (aDisp, aVis, GLX_DOUBLEBUFFER, &isDoubleBuffer) != 0)
411         isDoubleBuffer = 0;
412
413       if (glXGetConfig (aDisp, aVis, GLX_DEPTH_SIZE, &aDepthSize) != 0)
414         aDepthSize = 0;
415
416       if (glXGetConfig (aDisp, aVis, GLX_STENCIL_SIZE, &aStencilSize) != 0)
417         aStencilSize = 0;
418
419       if (!isGl || !aDepthSize || !isRGBA  || (isDoubleBuffer ? 1 : 0) != (myDisplay->DBuffer()? 1 : 0))
420       {
421         XFree (aVis);
422         aVis = NULL;
423       }
424     }
425   #endif
426
427     if (aVis == NULL)
428     {
429       int anIter = 0;
430       int anAttribs[13];
431       anAttribs[anIter++] = GLX_RGBA;
432
433       anAttribs[anIter++] = GLX_DEPTH_SIZE;
434       anAttribs[anIter++] = 1;
435
436       anAttribs[anIter++] = GLX_STENCIL_SIZE;
437       anAttribs[anIter++] = 1;
438
439       anAttribs[anIter++] = GLX_RED_SIZE;
440       anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1;
441
442       anAttribs[anIter++] = GLX_GREEN_SIZE;
443       anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1;
444
445       anAttribs[anIter++] = GLX_BLUE_SIZE;
446       anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1;
447
448       if (myDisplay->DBuffer())
449         anAttribs[anIter++] = GLX_DOUBLEBUFFER;
450
451       anAttribs[anIter++] = None;
452
453       aVis = glXChooseVisual (aDisp, scr, anAttribs);
454       if (aVis == NULL)
455       {
456         Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: glXChooseVisual failed.");
457         return;
458       }
459     }
460
461     if (!theShareCtx.IsNull())
462     {
463       // ctx est une copie du previous
464       aGContext = glXCreateContext (aDisp, aVis, (GLXContext )theShareCtx->myGContext, GL_TRUE);
465     }
466     else
467     {
468       aGContext = glXCreateContext (aDisp, aVis, NULL, GL_TRUE);
469     }
470
471     if (!aGContext)
472     {
473       Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: glXCreateContext failed.");
474       return;
475     }
476
477     Colormap cmap = XCreateColormap (aDisp, aParent, aVis->visual, AllocNone);
478
479     XColor color;
480     color.red   = (unsigned short) (myBgColor.rgb[0] * 0xFFFF);
481     color.green = (unsigned short) (myBgColor.rgb[1] * 0xFFFF);
482     color.blue  = (unsigned short) (myBgColor.rgb[2] * 0xFFFF);
483     color.flags = DoRed | DoGreen | DoBlue;
484     XAllocColor (aDisp, cmap, &color);
485
486     XSetWindowAttributes cwa;
487     cwa.colormap         = cmap;
488     cwa.event_mask       = StructureNotifyMask;
489     cwa.border_pixel     = color.pixel;
490     cwa.background_pixel = color.pixel;
491
492     if (aVis->visualid == wattr.visual->visualid)
493     {
494       aWindow = aParent;
495     }
496     else
497     {
498       unsigned long mask = CWBackPixel | CWColormap | CWBorderPixel | CWEventMask;
499       aWindow = XCreateWindow (aDisp, aParent, 0, 0, myWidth, myHeight, 0/*bw*/, aVis->depth, InputOutput, aVis->visual, mask, &cwa);
500     }
501
502     XSetWindowBackground (aDisp, aWindow, cwa.background_pixel);
503     XClearWindow (aDisp, aWindow);
504
505     if (aWindow != aParent)
506     {
507       XEvent anEvent;
508       XMapWindow (aDisp, aWindow);
509       XIfEvent (aDisp, &anEvent, WaitForNotify, (char* )aWindow);
510     }
511   }
512
513   /*
514   * Le BackDitherProp est utilise pour le clear du background
515   * Pour eviter une difference de couleurs avec la couleur choisie
516   * par l'application (XWindow) il faut desactiver le dithering
517   * au dessus de 8 plans.
518   *
519   * Pour le DitherProp:
520   * On cherchera a activer le Dithering que si le Visual a au moins
521   * 8 plans pour le GLX_RED_SIZE. Le test est plus sur car on peut
522   * avoir une profondeur superieure a 12 mais avoir besoin du dithering.
523   * (Carte Impact avec GLX_RED_SIZE a 5 par exemple)
524   */
525
526   int aValue;
527   glXGetConfig (aDisp, aVis, GLX_RED_SIZE, &aValue);
528
529   if (myDither)
530     myDither = (aValue < 8);
531
532   if (myBackDither)
533     myBackDither = (aVis->depth <= 8);
534
535   XFree ((char* )aVis);
536
537   myGlContext->Init ((Aspect_Drawable )aWindow, (Aspect_Display )myDisplay->GetDisplay(), (Aspect_RenderingContext )aGContext);
538 #endif
539   myGlContext->Share (theShareCtx);
540
541   Init();
542 }
543
544 // =======================================================================
545 // function : ~OpenGl_Window
546 // purpose  :
547 // =======================================================================
548 OpenGl_Window::~OpenGl_Window()
549 {
550 #if defined(_WIN32)
551   HWND  aWindow   = (HWND  )myGlContext->myWindow;
552   HDC   aWindowDC = (HDC   )myGlContext->myWindowDC;
553   HGLRC aGContext = (HGLRC )myGlContext->myGContext;
554   myGlContext.Nullify();
555
556   if (myOwnGContext)
557   {
558     if (wglGetCurrentContext() != NULL)
559     {
560       wglDeleteContext (aGContext);
561     }
562     ReleaseDC (aWindow, aWindowDC);
563   }
564 #else
565   Display*    aDisplay  = (Display*    )myGlContext->myDisplay;
566   GLXContext  aGContext = (GLXContext  )myGlContext->myGContext;
567   myGlContext.Nullify();
568
569   if (aDisplay != NULL && myOwnGContext)
570   {
571     // FSXXX sync necessary if non-direct rendering
572     glXWaitGL();
573     glXDestroyContext (aDisplay, aGContext);
574   }
575 #endif
576 }
577
578 #endif // !__APPLE__
579
580 // =======================================================================
581 // function : Activate
582 // purpose  :
583 // =======================================================================
584 Standard_Boolean OpenGl_Window::Activate()
585 {
586   return myGlContext->MakeCurrent();
587 }
588
589 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
590
591 // =======================================================================
592 // function : Resize
593 // purpose  : call_subr_resize
594 // =======================================================================
595 void OpenGl_Window::Resize (const CALL_DEF_WINDOW& theCWindow)
596 {
597   DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay();
598   if (aDisp == NULL)
599     return;
600
601   // If the size is not changed - do nothing
602   if ((myWidth == theCWindow.dx) && (myHeight == theCWindow.dy))
603     return;
604
605   myWidth  = (Standard_Integer )theCWindow.dx;
606   myHeight = (Standard_Integer )theCWindow.dy;
607
608 #if !defined(_WIN32)
609   XResizeWindow (aDisp, myGlContext->myWindow, (unsigned int )myWidth, (unsigned int )myHeight);
610   XSync (aDisp, False);
611 #endif
612
613   Init();
614 }
615
616 #endif // !__APPLE__
617
618 // =======================================================================
619 // function : ReadDepths
620 // purpose  : TelReadDepths
621 // =======================================================================
622 void OpenGl_Window::ReadDepths (const Standard_Integer theX,     const Standard_Integer theY,
623                                 const Standard_Integer theWidth, const Standard_Integer theHeight,
624                                 float* theDepths)
625 {
626   if (theDepths == NULL || !Activate())
627     return;
628
629   glMatrixMode (GL_PROJECTION);
630   glLoadIdentity();
631   gluOrtho2D (0.0, (GLdouble )myWidth, 0.0, (GLdouble )myHeight);
632   glMatrixMode (GL_MODELVIEW);
633   glLoadIdentity();
634
635   glRasterPos2i (theX, theY);
636   DisableFeatures();
637   glReadPixels (theX, theY, theWidth, theHeight, GL_DEPTH_COMPONENT, GL_FLOAT, theDepths);
638   EnableFeatures();
639 }
640
641 // =======================================================================
642 // function : SetBackgroundColor
643 // purpose  : call_subr_set_background
644 // =======================================================================
645 void OpenGl_Window::SetBackgroundColor (const Standard_ShortReal theR,
646                                         const Standard_ShortReal theG,
647                                         const Standard_ShortReal theB)
648 {
649   myBgColor.rgb[0] = theR;
650   myBgColor.rgb[1] = theG;
651   myBgColor.rgb[2] = theB;
652 }
653
654 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
655
656 // =======================================================================
657 // function : Init
658 // purpose  :
659 // =======================================================================
660 void OpenGl_Window::Init()
661 {
662   if (!Activate())
663     return;
664
665 #if defined(_WIN32)
666   RECT cr;
667   GetClientRect ((HWND )myGlContext->myWindow, &cr);
668   myWidth  = cr.right - cr.left;
669   myHeight = cr.bottom - cr.top;
670 #else
671   Window aRootWin;
672   int aDummy;
673   unsigned int aDummyU;
674   unsigned int aNewWidth  = 0;
675   unsigned int aNewHeight = 0;
676   DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay();
677   XGetGeometry (aDisp, myGlContext->myWindow, &aRootWin, &aDummy, &aDummy, &aNewWidth, &aNewHeight, &aDummyU, &aDummyU);
678   myWidth  = aNewWidth;
679   myHeight = aNewHeight;
680 #endif
681
682   glMatrixMode (GL_MODELVIEW);
683   glViewport (0, 0, myWidth, myHeight);
684
685   glDisable (GL_SCISSOR_TEST);
686   glDrawBuffer (GL_BACK);
687 }
688
689 #endif // !__APPLE__
690
691 // =======================================================================
692 // function : EnablePolygonOffset
693 // purpose  : call_subr_enable_polygon_offset
694 // =======================================================================
695 void OpenGl_Window::EnablePolygonOffset() const
696 {
697   Standard_ShortReal aFactor, aUnits;
698   myDisplay->PolygonOffset (aFactor, aUnits);
699   glPolygonOffset (aFactor, aUnits);
700   glEnable (GL_POLYGON_OFFSET_FILL);
701 }
702
703 // =======================================================================
704 // function : DisablePolygonOffset
705 // purpose  : call_subr_disable_polygon_offset
706 // =======================================================================
707 void OpenGl_Window::DisablePolygonOffset() const
708 {
709   glDisable (GL_POLYGON_OFFSET_FILL);
710 }
711
712 // =======================================================================
713 // function : EnableFeatures
714 // purpose  :
715 // =======================================================================
716 void OpenGl_Window::EnableFeatures() const
717 {
718   /*glPixelTransferi (GL_MAP_COLOR, GL_TRUE);*/
719
720   if (myDither)
721     glEnable (GL_DITHER);
722   else
723     glDisable (GL_DITHER);
724 }
725
726 // =======================================================================
727 // function : DisableFeatures
728 // purpose  :
729 // =======================================================================
730 void OpenGl_Window::DisableFeatures() const
731 {
732   glDisable (GL_DITHER);
733   glPixelTransferi (GL_MAP_COLOR, GL_FALSE);
734
735   /*
736   * Disable stuff that's likely to slow down glDrawPixels.
737   * (Omit as much of this as possible, when you know in advance
738   * that the OpenGL state will already be set correctly.)
739   */
740   glDisable(GL_ALPHA_TEST);
741   glDisable(GL_BLEND);
742   glDisable(GL_DEPTH_TEST);
743   glDisable(GL_FOG);
744   glDisable(GL_LIGHTING);
745
746   glDisable(GL_LOGIC_OP);
747   glDisable(GL_STENCIL_TEST);
748   glDisable(GL_TEXTURE_1D);
749   glDisable(GL_TEXTURE_2D);
750   glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
751   glPixelTransferi(GL_RED_SCALE, 1);
752   glPixelTransferi(GL_RED_BIAS, 0);
753   glPixelTransferi(GL_GREEN_SCALE, 1);
754   glPixelTransferi(GL_GREEN_BIAS, 0);
755   glPixelTransferi(GL_BLUE_SCALE, 1);
756   glPixelTransferi(GL_BLUE_BIAS, 0);
757   glPixelTransferi(GL_ALPHA_SCALE, 1);
758   glPixelTransferi(GL_ALPHA_BIAS, 0);
759
760   /*
761   * Disable extensions that could slow down glDrawPixels.
762   * (Actually, you should check for the presence of the proper
763   * extension before making these calls.  I've omitted that
764   * code for simplicity.)
765   */
766
767 #ifdef GL_EXT_convolution
768   glDisable(GL_CONVOLUTION_1D_EXT);
769   glDisable(GL_CONVOLUTION_2D_EXT);
770   glDisable(GL_SEPARABLE_2D_EXT);
771 #endif
772
773 #ifdef GL_EXT_histogram
774   glDisable(GL_HISTOGRAM_EXT);
775   glDisable(GL_MINMAX_EXT);
776 #endif
777
778 #ifdef GL_EXT_texture3D
779   glDisable(GL_TEXTURE_3D_EXT);
780 #endif
781 }
782
783 // =======================================================================
784 // function : MakeFrontBufCurrent
785 // purpose  : TelMakeFrontBufCurrent
786 // =======================================================================
787 void OpenGl_Window::MakeFrontBufCurrent() const
788 {
789   glDrawBuffer (GL_FRONT);
790 }
791
792 // =======================================================================
793 // function : MakeBackBufCurrent
794 // purpose  : TelMakeBackBufCurrent
795 // =======================================================================
796 void OpenGl_Window::MakeBackBufCurrent() const
797 {
798   glDrawBuffer (GL_BACK);
799 }
800
801 // =======================================================================
802 // function : MakeFrontAndBackBufCurrent
803 // purpose  : TelMakeFrontAndBackBufCurrent
804 // =======================================================================
805 void OpenGl_Window::MakeFrontAndBackBufCurrent() const
806 {
807   glDrawBuffer (GL_FRONT_AND_BACK);
808 }
809
810 // =======================================================================
811 // function : GetGContext
812 // purpose  :
813 // =======================================================================
814 GLCONTEXT OpenGl_Window::GetGContext() const
815 {
816   return (GLCONTEXT )myGlContext->myGContext;
817 }