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