0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / OpenGl / OpenGl_txgl.cxx
index 01b3040..7088d29 100755 (executable)
@@ -177,70 +177,90 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
 #ifndef WNT
 
     GLCONTEXT ctx;
-    static int sdesc[11];
     Colormap cmap;
     XVisualInfo* vis=NULL;
     /*    XVisualInfo tmplt;*/
     XSetWindowAttributes cwa;
     XColor color;
-    /*    Tint i, n, nret;*/
-    Tint n;
-    Tint scr;
     int value;
     char string[CALL_DEF_STRING_LENGTH];
-    int DBuffer = True;
-    XWindowAttributes wattr;
-
     WINDOW win;
 
-    unsigned long mask = 0;
-    /*    unsigned long background_pixel = 0;*/
-
-    if (call_util_osd_getenv("CALL_OPENGL_NO_DBF", string, CALL_DEF_STRING_LENGTH))
-      DBuffer    = False;
+    int DBuffer = (call_util_osd_getenv ("CALL_OPENGL_NO_DBF", string, CALL_DEF_STRING_LENGTH)) ? False : True;
 
     if (call_util_osd_getenv("JWR_PIXMAP_DB", string, CALL_DEF_STRING_LENGTH))
       TelSetPixmapDB(1);
 
-    XGetWindowAttributes( disp , par , &wattr );
+    XWindowAttributes wattr;
+    XGetWindowAttributes (disp, par, &wattr);
+    Tint scr = DefaultScreen (disp);
 
-    n = 0;
-    sdesc[n] = GLX_RGBA;n++;
+#if defined(__linux) || defined(Linux)
+    {
+      XVisualInfo aVisInfo;
+      int aNbItems;
+      int isGl, isDoubleBuffer, isRGBA, aDepthSize, aStencilSize;
+      unsigned long aVisInfoMask = VisualIDMask | VisualScreenMask;
+      aVisInfo.visualid = wattr.visual->visualid;
+      aVisInfo.screen   = DefaultScreen (disp);
+      vis = XGetVisualInfo (disp, aVisInfoMask, &aVisInfo, &aNbItems);
+      if (vis != NULL)
+      {
+        // check Visual for OpenGl context's parameters compability
+        if (glXGetConfig (disp, vis, GLX_USE_GL, &isGl) != 0)
+          isGl = 0;
 
-    sdesc[n] = GLX_DEPTH_SIZE;n++;
-    sdesc[n] = 1;n++;
+        if (glXGetConfig (disp, vis, GLX_RGBA, &isRGBA) != 0)
+          isRGBA = 0;
 
-    sdesc[n] = GLX_RED_SIZE;n++;
-    sdesc[n] = (wattr.depth <= 8) ? 0 : 1;n++;
+        if (glXGetConfig (disp, vis, GLX_DOUBLEBUFFER, &isDoubleBuffer) != 0)
+          isDoubleBuffer = 0;
 
-    sdesc[n] = GLX_GREEN_SIZE;n++;
-    sdesc[n] = (wattr.depth <= 8) ? 0 : 1;n++;
+        if (glXGetConfig (disp, vis, GLX_DEPTH_SIZE, &aDepthSize) != 0)
+          aDepthSize = 0;
 
-    sdesc[n] = GLX_BLUE_SIZE;n++;
-    sdesc[n] = (wattr.depth <= 8) ? 0 : 1;n++;
+        if (glXGetConfig (disp, vis, GLX_STENCIL_SIZE, &aStencilSize) != 0)
+          aStencilSize = 0;
 
-    if (DBuffer) {
-      sdesc[n] = GLX_DOUBLEBUFFER;n++;
+        if (!isGl || !aDepthSize || !aStencilSize ||
+            !isRGBA  || isDoubleBuffer != DBuffer)
+        {
+          XFree (vis);
+          vis = NULL;
+        }
+      }
     }
+#endif
 
-    sdesc[n] = None;n++;
+    if (vis == NULL)
+    {
+      int anIter = 0;
+      int anAttribs[13];
+      anAttribs[anIter++] = GLX_RGBA;
 
-    scr = DefaultScreen( disp );
+      anAttribs[anIter++] = GLX_DEPTH_SIZE;
+      anAttribs[anIter++] = 1;
 
-#if defined(__linux) || defined(Linux)
-    {
-      XVisualInfo vinfo;
-      int ninfo;
-      unsigned long vmask = VisualIDMask |  VisualScreenMask;
-      vinfo.visualid = wattr.visual->visualid;
-      vinfo.screen = DefaultScreen( disp );
-      vis = XGetVisualInfo( disp, vmask, &vinfo, &ninfo);
-    }
-#endif
+      anAttribs[anIter++] = GLX_STENCIL_SIZE;
+      anAttribs[anIter++] = 1;
 
-    if( !vis )
-      vis = glXChooseVisual( disp, scr, sdesc );
-    if( !vis) return TFailure;
+      anAttribs[anIter++] = GLX_RED_SIZE;
+      anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1;
+
+      anAttribs[anIter++] = GLX_GREEN_SIZE;
+      anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1;
+
+      anAttribs[anIter++] = GLX_BLUE_SIZE;
+      anAttribs[anIter++] = (wattr.depth <= 8) ? 0 : 1;
+
+      if (DBuffer)
+        anAttribs[anIter++] = GLX_DOUBLEBUFFER;
+
+      anAttribs[anIter++] = None;
+
+      vis = glXChooseVisual (disp, scr, anAttribs);
+      if (vis == NULL) return TFailure;
+    }
 
 #ifdef TRACE
     printf ("TxglCreateWindow \n");
@@ -271,22 +291,8 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
     */
 
     glXGetConfig( disp, vis, GLX_RED_SIZE, &value );
-
-    if ( value < 8 ) {
-      DitherProp = True;
-    }
-    else
-    {
-      DitherProp = False;
-    }
-
-    if ( vis->depth <= 8 ) {
-      BackDitherProp = True;
-    }
-    else
-    {
-      BackDitherProp = False;
-    }
+    DitherProp = (value < 8) ? True : False;
+    BackDitherProp = (vis->depth <= 8) ? True : False;
 
 #ifdef TRACE
     printf("Dithering %d BackDithering %d \n",DitherProp,BackDitherProp);
@@ -302,7 +308,6 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
       /* recover display lists from dead_ctx, then destroy it */
       ctx = glXCreateContext( disp, vis, dead_ctx, GL_TRUE );
       glXDestroyContext(dead_dpy, dead_ctx);
-      dead_ctx = 0;
     } else if (previous_ctx == 0) {
       ctx = glXCreateContext( disp, vis, NULL, GL_TRUE );
     } else {
@@ -311,9 +316,16 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
     }
     previous_ctx = ctx;
 
-    if( !ctx) return TFailure;
+    if( ctx )
+      OpenGl_ResourceCleaner::GetInstance()->AppendContext( ctx, true );
 
-    OpenGl_ResourceCleaner::GetInstance()->AppendContext( ctx, true );
+    // remove the dead_ctx for ResourceCleaner after appending shared ctx
+    if (dead_ctx) {
+      OpenGl_ResourceCleaner::GetInstance()->RemoveContext(dead_ctx);
+      dead_ctx = 0;
+    }
+
+    if( !ctx) return TFailure;
 
     cmap = XCreateColormap( disp,  par, vis->visual, AllocNone );
 
@@ -328,7 +340,7 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
     cwa.border_pixel  = color.pixel;
     cwa.background_pixel = color.pixel;
 
-    mask = CWBackPixel | CWColormap | CWBorderPixel | CWEventMask;
+    unsigned long mask = CWBackPixel | CWColormap | CWBorderPixel | CWEventMask;
 
     if( vis->visualid == wattr.visual->visualid ) {
       win = par;
@@ -420,11 +432,7 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
 
     if ( pfd.dwFlags & PFD_NEED_PALETTE ) 
     {
-#ifndef _WIN64
-      WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLong ( par, GWL_USERDATA );
-#else
-      WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLong ( par, GWLP_USERDATA );
-#endif
+      WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLongPtr ( par, GWLP_USERDATA );
 
       InterfaceGraphic_RealizePalette (hte -> hDC, wd -> hPal, FALSE,
         s_sysPalInUse = pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE); 
@@ -614,11 +622,7 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
 
     if ( pfd.dwFlags & PFD_NEED_PALETTE ) 
     {
-#ifndef _WIN64
-      WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLong ( par, GWL_USERDATA );
-#else
-      WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLong ( par, GWLP_USERDATA );
-#endif
+      WINDOW_DATA* wd = ( WINDOW_DATA* )GetWindowLongPtr ( par, GWLP_USERDATA );
 
       InterfaceGraphic_RealizePalette (hte -> hDC, wd -> hPal, FALSE,
         s_sysPalInUse = pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE); 
@@ -686,9 +690,9 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
     }
     if (!i)
     {
-      errorcode = glGetError();
-      errorstring = gluErrorString(errorcode);
-      printf("glXMakeCurrent failed: %d %s\n", errorcode, errorstring);
+      // if there is no current context it might be impossible to use
+      // glGetError correctly
+      printf("glXMakeCurrent failed!\n");
     }
 
     return  i == True ? TSuccess : TFailure;
@@ -791,7 +795,6 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
     /* FSXXX sync necessary if non-direct rendering */
     glXWaitGL();
 
-    OpenGl_ResourceCleaner::GetInstance()->RemoveContext( ctx );
     _Txgl_Map.UnBind( win );
 
     if (previous_ctx == ctx) {
@@ -808,12 +811,14 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
       * losing any shared display lists (fonts...)
       */
       if (previous_ctx) {
+        OpenGl_ResourceCleaner::GetInstance()->RemoveContext(ctx);
         glXDestroyContext(disp, ctx);
       } else {
         dead_ctx = ctx;
         dead_dpy = disp;
       }
     } else {
+      OpenGl_ResourceCleaner::GetInstance()->RemoveContext(ctx);
       glXDestroyContext(disp, ctx);
     }
 
@@ -832,11 +837,7 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
     /*  palette messages in the main application message loop. */
     /*  In debug version we don't have message loop for most   */
     /*  cases. So, let's restore system colors here now.       */
-#ifndef _WIN64
-    wd = ( WINDOW_DATA* )GetWindowLong ( win, GWL_USERDATA );
-#else
-    wd = ( WINDOW_DATA* )GetWindowLong ( win, GWLP_USERDATA );
-#endif
+    wd = ( WINDOW_DATA* )GetWindowLongPtr ( win, GWLP_USERDATA );
 
     if ( wd != NULL ) InterfaceGraphic_RealizePalette (
       hte -> hDC, wd -> hPal, TRUE, s_sysPalInUse);
@@ -996,12 +997,14 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
   {
     int                   iPixelFormat = 0;
     int                   iGood = 0;
-    int                   i, j;
+    int                   i, j, k;
     PIXELFORMATDESCRIPTOR pfd0;
     char                  string[ CALL_DEF_STRING_LENGTH ];
     BOOL                  DBuffer = TRUE;
+    const int             sBits[] = { 8, 1 };
     const int             cBits[] = { 32, 24 };
     const int             dBits[] = { 32, 24, 16 };
+    int                   goodBits[3] = { 0, 0, 0 };
 
     if (call_util_osd_getenv ("CALL_OPENGL_NO_DBF",
       string, CALL_DEF_STRING_LENGTH)) 
@@ -1034,28 +1037,59 @@ __declspec( dllexport ) int __fastcall __OpenGl_INIT__ (
     pfd0.dwDamageMask    = 0;
 
     hte -> nUsed = 1;    
-
-    for (i = 0; i < sizeof(dBits) / sizeof(int); i++) {
-
-      pfd0.cDepthBits = dBits[i];
-      iGood = 0;
-      for (j = 0; j < sizeof(cBits) / sizeof(int); j++) {
-
-        pfd0.cColorBits = cBits[j];
-        iPixelFormat = ChoosePixelFormat ( hte -> hDC, &pfd0 );
-
-        if (iPixelFormat) {
-          pfd->cDepthBits = 0;
-          pfd->cColorBits = 0;
-          DescribePixelFormat (hte -> hDC, iPixelFormat,
-            sizeof ( PIXELFORMATDESCRIPTOR ), pfd);
-          if (pfd->cColorBits >= cBits[j] && pfd->cDepthBits >= dBits[i])
-            break;
-          if (iGood == 0)
-            iGood = iPixelFormat;
+    /*
+      This loop tries to find the pixel format with parameters not worse
+      than given in sBits, cBits, dBits, giving the priority to color bits
+      then depth bits, with stencil bits having the lowest priority.
+      If the needed combination is not found then the iGood value is used, it
+      is rememebered during the loop as the best ever found combination. 
+     */
+
+    for (k = 0; k < sizeof(sBits) / sizeof(int); k++) {
+
+      pfd0.cStencilBits = sBits[k];
+      for (i = 0; i < sizeof(dBits) / sizeof(int); i++) {
+
+        pfd0.cDepthBits = dBits[i];
+        iGood = 0;
+        for (j = 0; j < sizeof(cBits) / sizeof(int); j++) {
+
+          pfd0.cColorBits = cBits[j];
+          iPixelFormat = ChoosePixelFormat ( hte -> hDC, &pfd0 );
+
+          if (iPixelFormat) {
+            pfd->cDepthBits = 0;
+            pfd->cColorBits = 0;
+            pfd->cStencilBits = 0;
+            DescribePixelFormat (hte -> hDC, iPixelFormat,
+                                 sizeof ( PIXELFORMATDESCRIPTOR ), pfd);
+            if (pfd->cColorBits >= cBits[j] &&
+                pfd->cDepthBits >= dBits[i] &&
+                pfd->cStencilBits >= sBits[k])
+              break; /* found - stop the lookup immediately */
+            if (pfd->cColorBits > goodBits[0]) {
+              goodBits[0] = pfd->cColorBits;
+              goodBits[1] = pfd->cDepthBits;
+              goodBits[2] = pfd->cStencilBits;
+              iGood = iPixelFormat;
+            } else if (pfd->cColorBits == goodBits[0]) {
+              if (pfd->cDepthBits > goodBits[1]) {
+                goodBits[1] = pfd->cDepthBits;
+                goodBits[2] = pfd->cStencilBits;
+                iGood = iPixelFormat;
+              } else if (pfd->cDepthBits == goodBits[1]) {
+                if (pfd->cStencilBits > goodBits[2]) {
+                  goodBits[2] = pfd->cStencilBits;
+                  iGood = iPixelFormat;
+                }
+              }
+            }
+          }
         }
+        if (j < sizeof(cBits) / sizeof(int))
+          break;
       }
-      if (j < sizeof(cBits) / sizeof(int))
+      if (i < sizeof(dBits) / sizeof(int))
         break;
     }