OCC22199 OpenGL memory leaks in TKOpenGl
[occt.git] / src / OpenGl / OpenGl_txgl.cxx
1 /***********************************************************************
2
3 FONCTION :
4 ----------
5 File OpenGl_txgl :
6
7
8 REMARQUES:
9 ---------- 
10
11
12 HISTORIQUE DES MODIFICATIONS   :
13 --------------------------------
14 xx-xx-xx : xxx ; Creation.
15 07-02-96 : FMN ; Suppression code inutile:
16 - TxglLink() et TxglUnlink()
17 08-03-96 : FMN ; Suppression variables globales
18 Ajout cmn_delete_from_htbl() dans TxglDestroyWindow()
19 21-03-96 : CAL ; test sur previous_ctx dans TxglDestroyWindow()
20 et dans TxglSetDbuff()
21 01-04-96 : CAL ; Integration MINSK portage WNT
22 15-04-96 : CAL ; Integration travail PIXMAP de Jim ROTH
23 26-04-96 : FMN ; Correction warning de compilation
24 20-06-96 : CAL ; Retrait du XDestroyWindow dans TxglDestroyWindow
25 18-07-96 : FMN ; Suppression code inutile: TxglSetWindow().
26 27-09-96 : CAL ; Portage WNT
27 16-10-96 : GG  ; Coder le parametre de GLX_DEPTH_SIZE a 1 plutot
28 que 0 si l'on souhaite accroitre les performances
29 de 50% en utilisant le ZBuffer hardware !!!
30 Si la fenetre fournie a deja le bon visual pas
31 la peine de creer une sous-fenetre.
32 16-10-96 : GG  ; Le dithering doit etre active aussi avec 12 plans
33 de maniere a ameliorer la qualite
34 17-10-96 : FMN ; Ajout fonction printVisualInfo()
35 06-11-96 : CAL ; Remise a True du BackDitherProp pour < 12 plans
36 12-11-96 : CAL ; BackDitherProp = True pour <= 8 plans
37 BackDitherProp = False pour > 8 plans
38 29-01-97 : FMN ; Amelioration du tests pour le dithering
39 DitherProp = True pour <= 8 plans red
40 DitherProp = False pour > 8 plans red
41 Suppression de TxglSetDbuff()
42 06-06-97 : FMN ; Meilleure gestion glXMakeCurrent (pb avec LightWoks)
43 Suppression de previous_win
44 02-07-97 : FMN ; Suppression variable ESSAI
45 07-10-97 : FMN ; Simplification WNT 
46 13-10-97 : FMN ; Ajout wglShareLists
47 06-02-98 : FMN ; PRO11674: Suppression XSetErrorHandler(0) inutile
48 23-11-98 : CAL ; PRO16603: previous_ctx jamais remis a 0 pour eviter
49 la perte des lists.
50 07-12-98 : CAL ; PRO 16311 et PRO 11821
51 02.14.100 : JR : Warnings on WNT
52 14.07.06 : SAN : OCC12977: update previous_ctx properly in TxglDestroyWindow.
53 Old code resulted in crashes on some ATI Radeon cards under Linux.
54
55 ************************************************************************/
56
57 #define BUC60691  /*GG 06/06/00 Due to a severe bug in secondary 
58 //      table hash-code computation not yet solve,
59 //      It's necessary to compute the primary hash-key key
60 //      correctly under WNT/W98. The actual method is wrong
61 //      because a size 4 is used for this table instead
62 //      a conventional prime number as under UNIX system (23).
63 //       Under W98 sometimes the function wglMakeContext() does
64 //      not work for an UNKNOWN reason, the number of DC
65 //      seems limited to 5 but nothing tell that the limit is
66 //      reached !
67 //      We try right now to recover this error by creating a new DC.
68 */
69
70 #define RIC120303 /*GG Add new function TxglSetWindow using
71 //      the GLXContext defined by the user
72 //      Add new function TxglGetContext.
73 */
74
75 #define OCC954  /*SAV: 13/11/02 - check GLRC before deleting it*/
76
77 /*----------------------------------------------------------------------*/
78 /*
79 * Includes
80 */
81 #include <OpenGl_tgl_all.hxx>
82 #include <OpenGl_telem_util.hxx>
83 #include <stdio.h>
84
85 #include <OpenGl_Memory.hxx>
86 #include <OpenGl_ResourceCleaner.hxx>
87
88
89 #ifdef WNT
90 struct HTBL_ENTRY {
91   HDC   hDC;
92   HGLRC hGLRC;
93   int   nUsed;
94   IMPLEMENT_MEMORY_OPERATORS
95 };
96
97
98 int call_util_osd_getenv ( char*, char*, int );
99 #endif  /* WNT */
100
101 #include <OpenGl_txgl.hxx>
102 int call_util_osd_getenv( char * , char * , int ) ;
103
104 /*----------------------------------------------------------------------*/
105 /*
106 * Variables statiques
107 */
108
109 #ifndef WNT
110 typedef NCollection_DataMap<Tint, GLCONTEXT> GLContextMap;
111 #else
112 typedef NCollection_DataMap<Tint, HTBL_ENTRY*> GLContextMap;
113 #endif
114
115 static GLContextMap _Txgl_Map;
116
117
118 #ifndef WNT
119 static  int BackDitherProp = False; /* Dithering pour le background */
120 static  int DitherProp = True;    /* Dithering pour le trace  */
121 static  GLXContext previous_ctx = 0;  /* Use for share display list */
122 static  GLXContext dead_ctx;            /* Context to be destroyed */
123 static  Display *dead_dpy;              /* Display associated with dead_ctx */
124 #else
125 static  int BackDitherProp = FALSE; /* Dithering pour le background */
126 static  int DitherProp = TRUE;    /* Dithering pour le trace  */
127 static  BOOL s_sysPalInUse;             /* Flag to check system colors usage */ 
128 static  HGLRC previous_ctx = 0;   /* Use for share display list */
129 #endif /* WNT */
130
131 /*----------------------------------------------------------------------*/
132 /*
133 * Constantes
134 */
135
136 #define NO_TRACE
137
138 #define CALL_DEF_STRING_LENGTH 132
139
140 #define WIN_HTBL_SIZE 23
141
142 /*----------------------------------------------------------------------*/
143 /*
144 * Fonctions statiques
145 */
146
147 #ifndef WNT
148 #ifdef TRACE
149 static GLvoid printVisualInfo( Display *, XVisualInfo *glxVisual );
150 #endif
151 #else
152 #ifdef BUC60691
153 static BOOL win95 = FALSE;
154 #endif
155
156 static int find_pixel_format(HTBL_ENTRY * hte, PIXELFORMATDESCRIPTOR * pfd);
157
158 __declspec( dllexport ) int __fastcall __OpenGl_INIT__ ( 
159   unsigned hInstance, unsigned long reason_for_call
160   ) {
161     if ( reason_for_call == DLL_PROCESS_ATTACH ) {
162
163     }
164     return 1;
165
166   }  /* end __OpenGl_INIT__ */
167 #endif  /* WNT */
168
169   /*----------------------------------------------------------------------*/
170
171   WINDOW
172     TxglCreateWindow( DISPLAY  *disp, WINDOW par,
173     Tint x, Tint y, Tint w, Tint h, Tint bw,
174     Tfloat bgcolr, Tfloat bgcolg, Tfloat bgcolb )
175   {
176
177 #ifndef WNT
178
179     GLCONTEXT ctx;
180     static int sdesc[11];
181     Colormap cmap;
182     XVisualInfo* vis=NULL;
183     /*    XVisualInfo tmplt;*/
184     XSetWindowAttributes cwa;
185     XColor color;
186     /*    Tint i, n, nret;*/
187     Tint n;
188     Tint scr;
189     int value;
190     char string[CALL_DEF_STRING_LENGTH];
191     int DBuffer = True;
192     XWindowAttributes wattr;
193
194     WINDOW win;
195
196     unsigned long mask = 0;
197     /*    unsigned long background_pixel = 0;*/
198
199     if (call_util_osd_getenv("CALL_OPENGL_NO_DBF", string, CALL_DEF_STRING_LENGTH))
200       DBuffer    = False;
201
202     if (call_util_osd_getenv("JWR_PIXMAP_DB", string, CALL_DEF_STRING_LENGTH))
203       TelSetPixmapDB(1);
204
205     XGetWindowAttributes( disp , par , &wattr );
206
207     n = 0;
208     sdesc[n] = GLX_RGBA;n++;
209
210     sdesc[n] = GLX_DEPTH_SIZE;n++;
211     sdesc[n] = 1;n++;
212
213     sdesc[n] = GLX_RED_SIZE;n++;
214     sdesc[n] = (wattr.depth <= 8) ? 0 : 1;n++;
215
216     sdesc[n] = GLX_GREEN_SIZE;n++;
217     sdesc[n] = (wattr.depth <= 8) ? 0 : 1;n++;
218
219     sdesc[n] = GLX_BLUE_SIZE;n++;
220     sdesc[n] = (wattr.depth <= 8) ? 0 : 1;n++;
221
222     if (DBuffer) {
223       sdesc[n] = GLX_DOUBLEBUFFER;n++;
224     }
225
226     sdesc[n] = None;n++;
227
228     scr = DefaultScreen( disp );
229
230 #if defined(__linux) || defined(Linux)
231     {
232       XVisualInfo vinfo;
233       int ninfo;
234       unsigned long vmask = VisualIDMask |  VisualScreenMask;
235       vinfo.visualid = wattr.visual->visualid;
236       vinfo.screen = DefaultScreen( disp );
237       vis = XGetVisualInfo( disp, vmask, &vinfo, &ninfo);
238     }
239 #endif
240
241     if( !vis )
242       vis = glXChooseVisual( disp, scr, sdesc );
243     if( !vis) return TFailure;
244
245 #ifdef TRACE
246     printf ("TxglCreateWindow \n");
247     printf ("Informations sur le visual\n");
248     printf ("par visualid %x%x %d\n", wattr.visual->visualid, wattr.visual->visualid);
249     printf ("vis visualid 0x%x %d\n", vis->visualid, vis->visualid);
250     printf ("vis depth %d\n", vis->depth);
251     printf ("vis class %d\n", vis->class);
252     printf ("vis red_mask %ld\n", vis->red_mask);
253     printf ("vis green_mask %ld\n", vis->green_mask);
254     printf ("vis blue_mask %ld\n", vis->blue_mask);
255     printf ("vis colormap_size %d\n", vis->colormap_size);
256     printf ("vis bits_per_rgb %d\n", vis->bits_per_rgb);
257     printVisualInfo( disp, vis );
258 #endif
259
260     /*
261     * Le BackDitherProp est utilise pour le clear du background
262     * Pour eviter une difference de couleurs avec la couleur choisie
263     * par l'application (XWindow) il faut desactiver le dithering
264     * au dessus de 8 plans.
265     * 
266     * Pour le DitherProp:
267     * On cherchera a activer le Dithering que si le Visual a au moins
268     * 8 plans pour le GLX_RED_SIZE. Le test est plus sur car on peut
269     * avoir une profondeur superieure a 12 mais avoir besoin du dithering.
270     * (Carte Impact avec GLX_RED_SIZE a 5 par exemple)
271     */
272
273     glXGetConfig( disp, vis, GLX_RED_SIZE, &value );
274
275     if ( value < 8 ) {
276       DitherProp = True;
277     }
278     else
279     {
280       DitherProp = False;
281     }
282
283     if ( vis->depth <= 8 ) {
284       BackDitherProp = True;
285     }
286     else
287     {
288       BackDitherProp = False;
289     }
290
291 #ifdef TRACE
292     printf("Dithering %d BackDithering %d \n",DitherProp,BackDitherProp);
293 #endif
294
295     if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH))
296       DitherProp = False;
297
298     if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH))
299       BackDitherProp = False;
300
301     if (dead_ctx) {
302       /* recover display lists from dead_ctx, then destroy it */
303       ctx = glXCreateContext( disp, vis, dead_ctx, GL_TRUE );
304       glXDestroyContext(dead_dpy, dead_ctx);
305       dead_ctx = 0;
306     } else if (previous_ctx == 0) {
307       ctx = glXCreateContext( disp, vis, NULL, GL_TRUE );
308     } else {
309       /* ctx est une copie du previous */
310       ctx = glXCreateContext( disp, vis, previous_ctx, GL_TRUE );
311     }
312     previous_ctx = ctx;
313
314     if( !ctx) return TFailure;
315
316     OpenGl_ResourceCleaner::GetInstance()->AppendContext( ctx, true );
317
318     cmap = XCreateColormap( disp,  par, vis->visual, AllocNone );
319
320     color.red = (unsigned short) (bgcolr * 0xFFFF);
321     color.green = (unsigned short) (bgcolg * 0xFFFF);
322     color.blue  = (unsigned short) (bgcolb * 0xFFFF);
323     color.flags = DoRed | DoGreen | DoBlue;
324     XAllocColor( disp, cmap, &color );
325
326     cwa.colormap  = cmap;
327     cwa.event_mask  = StructureNotifyMask;
328     cwa.border_pixel  = color.pixel;
329     cwa.background_pixel = color.pixel;
330
331     mask = CWBackPixel | CWColormap | CWBorderPixel | CWEventMask;
332
333     if( vis->visualid == wattr.visual->visualid ) {
334       win = par;
335     } 
336     else 
337     {
338       win = XCreateWindow( disp, par, x, y, w, h, bw,
339         vis->depth, InputOutput, vis->visual,
340         mask, &cwa );
341     }
342
343 #ifdef TRACE
344     printf ("TxglCreateWindow win %x par %x \n", win, par);
345 #endif
346
347     XSetWindowBackground( disp, win, cwa.background_pixel );
348     XClearWindow( disp, win );
349
350     /* if in Pixmap double buffering mode, set up pixmap */
351
352     if (TelTestPixmapDB())
353     {
354       GC gc;
355       Pixmap pixmap;
356       GLXPixmap glxpixmap;
357
358       printf("setting up pixmap double buffering\n");
359
360       gc = XCreateGC(disp, win, 0, NULL);
361
362       pixmap = XCreatePixmap(disp, win, w, h, vis->depth);
363
364       glxpixmap = glXCreateGLXPixmap(disp, vis, pixmap);
365
366       glXMakeCurrent(disp, glxpixmap, ctx);
367
368       glDrawBuffer(GL_FRONT);
369
370       TelSetPixmapDBParams(disp, win, w, h, vis->depth, gc, pixmap, glxpixmap, ctx);
371     }
372
373     XFree((char*)vis);  
374
375     _Txgl_Map.Bind( (Tint)win, ctx );
376
377     return win;
378
379 #else /* WNT */
380
381     HTBL_ENTRY*           hte;
382     PIXELFORMATDESCRIPTOR pfd;
383     BOOL                  DBuffer = TRUE;
384     int                   iPixelFormat;
385     char                  string[ CALL_DEF_STRING_LENGTH ];
386
387 #ifdef BUC60691
388     OSVERSIONINFO os;
389     os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
390     GetVersionEx(&os);
391     if( os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) win95 = TRUE; 
392 #endif
393
394     if ( _Txgl_Map.IsBound( (Tint)par ) ) {
395       hte = _Txgl_Map.ChangeFind( (Tint)par );
396       if ( hte ) 
397       {
398         ++hte -> nUsed;
399         printf("*TxglCreateWindow.window %d is alreday created\n",par);
400         return par;
401       }
402     }
403
404     hte = new HTBL_ENTRY();
405
406     if ( !hte ) return 0;
407     hte -> hDC   = GetDC ( par );
408
409     iPixelFormat = find_pixel_format(hte, &pfd);
410
411     if ( !iPixelFormat ) 
412     {
413       printf ("*OpenGL interface: ChoosePixelFormat failed. Error code: %d\n",GetLastError ());
414
415       ReleaseDC ( par, hte -> hDC );
416       delete hte;
417
418       return 0;
419     }  
420
421     if ( pfd.dwFlags & PFD_NEED_PALETTE ) 
422     {
423 #ifndef _WIN64
424       WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLong ( par, GWL_USERDATA );
425 #else
426       WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLong ( par, GWLP_USERDATA );
427 #endif
428
429       InterfaceGraphic_RealizePalette (hte -> hDC, wd -> hPal, FALSE,
430         s_sysPalInUse = pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE); 
431     }  
432
433     if ( pfd.cColorBits <= 8 ) 
434     { 
435       DitherProp     = TRUE;
436       BackDitherProp = TRUE;    
437     }  
438
439     if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH))
440       DitherProp = FALSE;
441
442     if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH))
443       BackDitherProp = FALSE;
444
445     if (  !SetPixelFormat ( hte -> hDC, iPixelFormat, &pfd )  ) 
446     {
447       printf ("*OpenGL interface: SetPixelFormat failed. Error code %d\n",GetLastError ()); 
448       ReleaseDC ( par, hte -> hDC );
449       delete hte;
450       return 0; 
451     }  
452
453     hte -> hGLRC = wglCreateContext ( hte -> hDC );
454
455     if ( !hte -> hGLRC ) 
456     { 
457       printf ("*OpenGL interface: wglCreateContext failed. Error code: %d\n",GetLastError ());    
458       return 0;     
459     }  
460
461     Standard_Boolean isShared = Standard_True;
462
463     if (previous_ctx == 0 )
464       previous_ctx = hte -> hGLRC;
465     // if we already have some shared context
466     else
467     {
468       // try to share context with one from resource cleaner list
469       GLCONTEXT shareCtx = OpenGl_ResourceCleaner::GetInstance()->GetSharedContext();
470       
471       if (shareCtx != 0)
472         isShared = (Standard_Boolean)wglShareLists(shareCtx, hte -> hGLRC);
473       else
474       {
475         isShared = (Standard_Boolean)wglShareLists(previous_ctx, hte -> hGLRC);
476               // add shared previous_ctx to a control list if it's not there
477         if (isShared)
478           OpenGl_ResourceCleaner::GetInstance()->AppendContext(previous_ctx, isShared);
479       }
480     }
481
482     // add the context to OpenGl_ResourceCleaner control list
483     OpenGl_ResourceCleaner::GetInstance()->AppendContext( hte -> hGLRC, isShared);
484     _Txgl_Map.Bind( (Tint)par, hte );
485
486     return par;
487
488 #endif  /* WNT */
489
490   }
491
492 #ifdef RIC120302
493   WINDOW
494     TxglSetWindow( DISPLAY  *disp, WINDOW par, GLCONTEXT ctx)
495   {
496 #ifndef WNT
497     XVisualInfo* vis;
498     char string[CALL_DEF_STRING_LENGTH];
499     XWindowAttributes wattr;
500
501     XGetWindowAttributes( disp , par , &wattr );
502     {
503       unsigned long vmask = VisualIDMask |  VisualScreenMask;
504       XVisualInfo vinfo;
505       int ninfo;
506       vinfo.visualid = wattr.visual->visualid;
507       vinfo.screen = DefaultScreen( disp );
508       vis = XGetVisualInfo( disp, vmask, &vinfo, &ninfo);
509     }
510
511     if( !vis) return TFailure;
512
513 #ifdef TRACE
514     printf ("TxglSetWindow \n");
515     printf ("Informations sur le visual\n");
516     printf ("par visualid %x%x %d\n", wattr.visual->visualid, wattr.visual->visualid);
517     printf ("vis visualid 0x%x %d\n", vis->visualid, vis->visualid);
518     printf ("vis depth %d\n", vis->depth);
519     printf ("vis class %d\n", vis->class);
520     printf ("vis red_mask %ld\n", vis->red_mask);
521     printf ("vis green_mask %ld\n", vis->green_mask);
522     printf ("vis blue_mask %ld\n", vis->blue_mask);
523     printf ("vis colormap_size %d\n", vis->colormap_size);
524     printf ("vis bits_per_rgb %d\n", vis->bits_per_rgb);
525     printVisualInfo( disp, vis );
526 #endif
527
528     /*
529     * Le BackDitherProp est utilise pour le clear du background
530     * Pour eviter une difference de couleurs avec la couleur choisie
531     * par l'application (XWindow) il faut desactiver le dithering
532     * au dessus de 8 plans.
533     * 
534     * Pour le DitherProp:
535     * On cherchera a activer le Dithering que si le Visual a au moins
536     * 8 plans pour le GLX_RED_SIZE. Le test est plus sur car on peut
537     * avoir une profondeur superieure a 12 mais avoir besoin du dithering.
538     * (Carte Impact avec GLX_RED_SIZE a 5 par exemple)
539     */
540
541     {
542       int value;
543       glXGetConfig( disp, vis, GLX_RED_SIZE, &value );
544
545       if ( value < 8 ) {
546         DitherProp = True;
547       } else {
548         DitherProp = False;
549       }
550
551       if ( vis->depth <= 8 ) {
552         BackDitherProp = True;
553       } else {
554         BackDitherProp = False;
555       }
556     }
557
558 #ifdef TRACE
559     printf("Dithering %d BackDithering %d \n",DitherProp,BackDitherProp);
560 #endif
561
562     if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH))
563       DitherProp = False;
564
565     if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH))
566       BackDitherProp = False;
567
568     previous_ctx = ctx;
569
570     XFree((char*)vis);  
571
572     _Txgl_Map.Bind( ( Tint )par, ctx );
573 #else /* WNT */
574
575     /* abd
576     cmn_htbl_elem         rec;*/
577     HTBL_ENTRY*           hte;
578     PIXELFORMATDESCRIPTOR pfd;
579     BOOL                  DBuffer = TRUE;
580     int                   iPixelFormat;
581     char                  string[ CALL_DEF_STRING_LENGTH ];
582
583 #ifdef BUC60691
584     OSVERSIONINFO os;
585     os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
586     GetVersionEx(&os);
587     if( os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) win95 = TRUE; 
588 #endif
589
590     if ( _Txgl_Map.IsBound( ( Tint )par ) )
591     {
592       hte = _Txgl_Map.ChangeFind( ( Tint )par );
593       ++hte -> nUsed;
594       printf("*TxglSetWindow.window %d is alreday created\n",par);
595       return par;
596     }
597
598     hte = new HTBL_ENTRY();
599
600     if ( !hte ) return 0;
601
602     hte -> hDC   = GetDC ( par );
603     iPixelFormat = find_pixel_format(hte, &pfd);
604
605     if ( !iPixelFormat ) 
606     {
607       printf ("*OpenGL interface: ChoosePixelFormat failed. Error code: %d\n",GetLastError ());
608
609       ReleaseDC ( par, hte -> hDC );
610       delete hte;
611
612       return 0;
613     }  
614
615     if ( pfd.dwFlags & PFD_NEED_PALETTE ) 
616     {
617 #ifndef _WIN64
618       WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLong ( par, GWL_USERDATA );
619 #else
620       WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLong ( par, GWLP_USERDATA );
621 #endif
622
623       InterfaceGraphic_RealizePalette (hte -> hDC, wd -> hPal, FALSE,
624         s_sysPalInUse = pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE); 
625     }  
626
627     if ( pfd.cColorBits <= 8 ) 
628     { 
629       DitherProp     = TRUE;
630       BackDitherProp = TRUE;    
631     }  
632
633     if (call_util_osd_getenv ("CALL_OPENGL_NO_DITHER", string, CALL_DEF_STRING_LENGTH))
634       DitherProp = FALSE;
635
636     if (call_util_osd_getenv ("CALL_OPENGL_NO_BACKDITHER", string, CALL_DEF_STRING_LENGTH))
637       BackDitherProp = FALSE;
638
639     if (  !SetPixelFormat ( hte -> hDC, iPixelFormat, &pfd )  ) 
640     {
641       printf ("*OpenGL interface: SetPixelFormat failed. Error code %d\n",GetLastError ()); 
642       ReleaseDC ( par, hte -> hDC );
643       delete hte;
644       return 0; 
645     }  
646
647     hte -> hGLRC = previous_ctx = ctx;
648
649     _Txgl_Map.Bind( ( Tint )par, hte );
650 #endif  /* WNT */
651
652     return par;
653
654   }
655 #endif /*RIC120302*/
656
657   /*----------------------------------------------------------------------*/
658
659   TStatus
660     TxglWinset( DISPLAY *disp, WINDOW win )
661   {
662
663 #ifndef WNT
664
665     Bool  i;
666     GLXContext ctx;
667     GLenum errorcode;
668     const GLubyte *errorstring;
669
670     if ( !_Txgl_Map.IsBound( win ) )
671       return TFailure;
672
673     ctx = _Txgl_Map.ChangeFind( win );
674
675
676 #ifdef TRACE
677     printf ("TxglWinset::glXMakeCurrent %x \n", win);
678 #endif
679     if (TelTestPixmapDB())
680     {
681       i = glXMakeCurrent(disp, TelGetGLXPixmap(), ctx);
682     }
683     else
684     {
685       i = glXMakeCurrent(disp, win, ctx);  /* TRUE/FALSE */
686     }
687     if (!i)
688     {
689       errorcode = glGetError();
690       errorstring = gluErrorString(errorcode);
691       printf("glXMakeCurrent failed: %d %s\n", errorcode, errorstring);
692     }
693
694     return  i == True ? TSuccess : TFailure;
695
696 #else /* WNT */
697
698     HTBL_ENTRY*   hte;
699     HDC    hdc    = NULL;
700     HGLRC  hglrc  = NULL;
701     TStatus       retVal = TFailure;
702
703     __try {
704
705       if ( !_Txgl_Map.IsBound( ( Tint )win ) ) {
706         printf("OpenGL interface:  TxglWinset failed.UNKNOWN win %x\n",win);
707         __leave;
708       }
709       hte = _Txgl_Map.ChangeFind( ( Tint )win );
710
711 #ifdef BUC60691
712       if( win95 ) {
713         retVal = (TStatus)ReleaseDC ( win, hte -> hDC );
714         hte -> hDC   = GetDC ( win );
715       }   
716 #endif
717       if (  !wglMakeCurrent ( hte -> hDC, hte -> hGLRC )  ) 
718       {
719 #ifdef BUC60691
720         GLenum errorcode;
721         const GLubyte *errorstring;
722
723         errorcode = glGetError();
724         errorstring = gluErrorString(errorcode);
725         printf("wglMakeCurrent failed: %d %s\n", errorcode, errorstring);
726 #else
727         printf ("OpenGL interface: wglMakeCurrent failed. Error code: %d\n",GetLastError ());
728 #endif
729         retVal = TFailure;  
730       } else retVal = TSuccess;
731
732     }  /* end __try */
733
734
735     __finally 
736     {    
737     }  
738
739     return retVal;
740
741 #endif  /* WNT */
742
743   }
744
745   /*----------------------------------------------------------------------*/
746
747   WINDOW
748     TxglGetSubWindow( DISPLAY *disp, WINDOW win )
749     /* This function assumes that there is only
750     one child for the parent */
751   {
752
753 #ifndef WNT
754
755     Window root, parent, *child, w;
756     unsigned int num;
757
758     if( XQueryTree( disp, win, &root, &parent, &child, &num ) )
759     {
760       if (! num) return win;
761       w = child[0];
762       XFree( (char *)child );
763       return w;
764     }
765     else
766       return 0;
767
768 #else /* WNT */
769
770     return win;
771
772 #endif  /* WNT */
773
774   }
775
776   /*----------------------------------------------------------------------*/
777
778   void
779     TxglDestroyWindow( DISPLAY *disp, WINDOW win )
780   {
781
782 #ifndef WNT
783
784     GLXContext ctx;
785     Tint dummy;
786
787     if ( !_Txgl_Map.IsBound(win) )
788       return;
789     ctx = _Txgl_Map.ChangeFind(win);
790
791     /* FSXXX sync necessary if non-direct rendering */
792     glXWaitGL();
793
794     OpenGl_ResourceCleaner::GetInstance()->RemoveContext( ctx );
795     _Txgl_Map.UnBind( win );
796
797     if (previous_ctx == ctx) {
798       /* san -- OCC12977: it's important to put some valid GLXContext or null into
799       previous_ctx here, otherwise next glxCreateContext() will crash on some ATI Radeon cards
800       */
801       previous_ctx = NULL;
802       if ( _Txgl_Map.Size() > 0 ) {
803         GLContextMap::Iterator it(_Txgl_Map);
804         previous_ctx = it.Value();
805       }
806       /*
807       * if this is the last remaining context, do not destroy it yet, to avoid
808       * losing any shared display lists (fonts...)
809       */
810       if (previous_ctx) {
811         glXDestroyContext(disp, ctx);
812       } else {
813         dead_ctx = ctx;
814         dead_dpy = disp;
815       }
816     } else {
817       glXDestroyContext(disp, ctx);
818     }
819
820 #else /* WNT */
821
822     HTBL_ENTRY*   hte;
823 #ifdef _DEBUG 
824     WINDOW_DATA*  wd;
825 #endif  /* _DEBUG */
826     if ( !_Txgl_Map.IsBound(( Tint )win) )
827       return;
828     hte = _Txgl_Map.ChangeFind(( Tint )win);
829
830 #ifdef _DEBUG 
831     /* In release version of application we need to process    */
832     /*  palette messages in the main application message loop. */
833     /*  In debug version we don't have message loop for most   */
834     /*  cases. So, let's restore system colors here now.       */
835 #ifndef _WIN64
836     wd = ( WINDOW_DATA* )GetWindowLong ( win, GWL_USERDATA );
837 #else
838     wd = ( WINDOW_DATA* )GetWindowLong ( win, GWLP_USERDATA );
839 #endif
840
841     if ( wd != NULL ) InterfaceGraphic_RealizePalette (
842       hte -> hDC, wd -> hPal, TRUE, s_sysPalInUse);
843 #endif  /* _DEBUG */
844
845     if ( --hte -> nUsed == 0 ) 
846     { 
847       OpenGl_ResourceCleaner::GetInstance()->RemoveContext( hte -> hGLRC );
848 #ifdef OCC954    
849       if ( wglGetCurrentContext() != NULL )
850 #endif
851         wglDeleteContext ( hte -> hGLRC );
852       ReleaseDC ( win, hte -> hDC );
853       _Txgl_Map.UnBind( (Tint ) win );
854       if( _Txgl_Map.Size() == 0 ) {
855         previous_ctx = 0;
856       }
857       delete hte;
858     }  
859
860 #endif  /* WNT */
861
862   }
863
864   /*----------------------------------------------------------------------*/
865
866   int
867     TxglGetDither(void)
868   {
869     return DitherProp;
870   }
871
872   /*----------------------------------------------------------------------*/
873
874   int
875     TxglGetBackDither(void)
876   {
877     return BackDitherProp;
878   }
879
880
881   /*----------------------------------------------------------------------*/
882   /*RIC120302*/
883   GLCONTEXT 
884     TxglGetContext( WINDOW win )
885   {
886     GLCONTEXT ctx = NULL;
887     if ( _Txgl_Map.IsBound( (Tint) win ) )
888       ctx = 
889 #ifdef WNT    
890       _Txgl_Map.Find( (Tint) win )->hGLRC;
891 #else
892       _Txgl_Map.Find( win );
893 #endif
894
895     return ctx;  
896   }
897   /*RIC120302*/
898
899   /*----------------------------------------------------------------------*/
900   enum { ZERO = 0, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN };
901
902   /* Unused :*/
903 #ifdef TRACE
904   static const char*
905     className( int class )
906   {
907     static char      *classes[] = {
908       "StaticGray",
909         "GrayScale",
910         "StaticColor",
911         "PseudoColor",
912         "TrueColor",
913         "DirectColor",
914     };
915
916     if ( class < ZERO || class > FIVE )
917       return "unknown";
918     else
919       return classes[class];
920   }
921 #endif
922   /*----------------------------------------------------------------------*/
923 #ifndef WNT
924
925 #ifdef TRACE
926   static GLvoid printVisualInfo( DISPLAY  *display, XVisualInfo *glxVisual )
927   {
928
929 #define TrueFalse(x)  ( x ? "True" : "False" )
930
931     int        tmp;
932
933     printf("\n" );
934     printf("   X Visual Information ...\n\n" );
935     printf("\tvisualid : 0x%x\n", glxVisual->visualid );
936     printf("\tclass    : %s\n\n", className( glxVisual->class ) );
937
938     glXGetConfig(display, glxVisual, GLX_USE_GL, &tmp);
939     printf( "\tSupport GL ( GLX_USE_GL ) : %s\n", TrueFalse(tmp) );
940
941     glXGetConfig(display, glxVisual, GLX_LEVEL, &tmp);
942     printf( "\tFramebuffer ( GLX_LEVEL ) : %s\n\n",
943       (tmp < ZERO) ? "Underlay" : (tmp == ZERO ? "Normal"  : tmp > ONE ? "Overlay"  : "Popup") );
944
945     glXGetConfig(display, glxVisual, GLX_BUFFER_SIZE, &tmp);
946     printf( "\tFramebuffer depth ( GLX_BUFFER_SIZE )     : %d\n", tmp );
947
948     glXGetConfig(display, glxVisual, GLX_DOUBLEBUFFER, &tmp);
949     printf( "\tDoublebuffer ( GLX_DOUBLEBUFFER )         : %s\n",
950       TrueFalse(tmp) );
951
952     glXGetConfig(display, glxVisual, GLX_DEPTH_SIZE, &tmp);
953     printf( "\tDepth buffer depth ( GLX_DEPTH_SIZE )     : %d\n", tmp );
954
955     glXGetConfig(display, glxVisual, GLX_STENCIL_SIZE, &tmp);
956     printf( "\tStencil buffer depth ( GLX_STENCIL_SIZE ) : %d\n", tmp );
957
958     glXGetConfig(display, glxVisual, GLX_STEREO, &tmp);
959     printf( "\tStereo Buffer ( GLX_STEREO )              : %s\n",
960       TrueFalse(tmp) );
961
962     glXGetConfig(display, glxVisual, GLX_AUX_BUFFERS, &tmp);
963     printf( "\tAuxillary Buffers ( GLX_AUX_BUFFERS)      : %d\n\n", tmp );
964
965     glXGetConfig(display, glxVisual, GLX_RGBA, &tmp);
966     printf( "\tColor mode ( GLX_RGBA )       : %s\n", tmp ? "RGBA" :
967     "Color Index" );
968
969     glXGetConfig(display, glxVisual, GLX_RED_SIZE, &tmp);
970     printf( "\tRed Bits ( GLX_RED_SIZE )     : %d\n", tmp );
971
972     glXGetConfig(display, glxVisual, GLX_GREEN_SIZE, &tmp);
973     printf( "\tGreen Bits ( GLX_GREEN_SIZE ) : %d\n", tmp );
974
975     glXGetConfig(display, glxVisual, GLX_BLUE_SIZE, &tmp);
976     printf( "\tBlue Bits ( GLX_BLUE_SIZE )   : %d\n", tmp );
977
978     glXGetConfig(display, glxVisual, GLX_ALPHA_SIZE, &tmp);
979     printf( "\tAlpha Bits ( GLX_ALPHA_SIZE ) : %d\n\n", tmp );
980
981     glXGetConfig(display, glxVisual, GLX_ACCUM_RED_SIZE, &tmp);
982     printf( "\tRed Accumulation Bits ( GLX_ACCUM_RED_SIZE )     : %d\n", tmp );
983
984     glXGetConfig(display, glxVisual, GLX_ACCUM_GREEN_SIZE, &tmp);
985     printf( "\tGreen Accumulation Bits ( GLX_ACCUM_GREEN_SIZE ) : %d\n", tmp );
986
987     glXGetConfig(display, glxVisual, GLX_ACCUM_BLUE_SIZE, &tmp);
988     printf( "\tBlue Accumulation Bits ( GLX_ACCUM_BLUE_SIZE )   : %d\n", tmp );
989
990     glXGetConfig(display, glxVisual, GLX_ACCUM_ALPHA_SIZE, &tmp);
991     printf( "\tAlpha Accumulation Bits ( GLX_ACCUM_ALPHA_SIZE ) : %d\n\n", tmp );
992   }
993 #endif //TRACE
994 #else //WNT
995   int find_pixel_format(HTBL_ENTRY * hte, PIXELFORMATDESCRIPTOR * pfd)
996   {
997     int                   iPixelFormat = 0;
998     int                   iGood = 0;
999     int                   i, j;
1000     PIXELFORMATDESCRIPTOR pfd0;
1001     char                  string[ CALL_DEF_STRING_LENGTH ];
1002     BOOL                  DBuffer = TRUE;
1003     const int             cBits[] = { 32, 24 };
1004     const int             dBits[] = { 32, 24, 16 };
1005
1006     if (call_util_osd_getenv ("CALL_OPENGL_NO_DBF",
1007       string, CALL_DEF_STRING_LENGTH)) 
1008       DBuffer = FALSE;
1009
1010     pfd0.nSize           = sizeof ( PIXELFORMATDESCRIPTOR );
1011     pfd0.nVersion        = 1;
1012     pfd0.dwFlags         = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
1013     pfd0.dwFlags        |= ( DBuffer ) ? PFD_DOUBLEBUFFER : PFD_SUPPORT_GDI;
1014     pfd0.iPixelType      = PFD_TYPE_RGBA;
1015     pfd0.cRedBits        = 0;
1016     pfd0.cRedShift       = 0;
1017     pfd0.cGreenBits      = 0;
1018     pfd0.cGreenShift     = 0;
1019     pfd0.cBlueBits       = 0;
1020     pfd0.cBlueShift      = 0;
1021     pfd0.cAlphaBits      = 0;
1022     pfd0.cAlphaShift     = 0;
1023     pfd0.cAccumBits      = 0;
1024     pfd0.cAccumRedBits   = 0;
1025     pfd0.cAccumGreenBits = 0;
1026     pfd0.cAccumBlueBits  = 0;
1027     pfd0.cAccumAlphaBits = 0;
1028     pfd0.cStencilBits    = 0;
1029     pfd0.cAuxBuffers     = 0;
1030     pfd0.iLayerType      = PFD_MAIN_PLANE;
1031     pfd0.bReserved       = 0;
1032     pfd0.dwLayerMask     = 0;
1033     pfd0.dwVisibleMask   = 0;
1034     pfd0.dwDamageMask    = 0;
1035
1036     hte -> nUsed = 1;    
1037
1038     for (i = 0; i < sizeof(dBits) / sizeof(int); i++) {
1039
1040       pfd0.cDepthBits = dBits[i];
1041       iGood = 0;
1042       for (j = 0; j < sizeof(cBits) / sizeof(int); j++) {
1043
1044         pfd0.cColorBits = cBits[j];
1045         iPixelFormat = ChoosePixelFormat ( hte -> hDC, &pfd0 );
1046
1047         if (iPixelFormat) {
1048           pfd->cDepthBits = 0;
1049           pfd->cColorBits = 0;
1050           DescribePixelFormat (hte -> hDC, iPixelFormat,
1051             sizeof ( PIXELFORMATDESCRIPTOR ), pfd);
1052           if (pfd->cColorBits >= cBits[j] && pfd->cDepthBits >= dBits[i])
1053             break;
1054           if (iGood == 0)
1055             iGood = iPixelFormat;
1056         }
1057       }
1058       if (j < sizeof(cBits) / sizeof(int))
1059         break;
1060     }
1061
1062     if ( !iPixelFormat )
1063       iPixelFormat = iGood;
1064
1065     return iPixelFormat;
1066   }
1067
1068 #endif  /* WNT */
1069   /*----------------------------------------------------------------------*/