0020716: Eliminate usage of "config.h" header file
[occt.git] / src / Draw / Draw.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 9a0f82e..ed04b5f
@@ -1,76 +1,59 @@
 // Created on: 1993-08-13
 // Created by: Bruno DUMORTIER
 // Copyright (c) 1993-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 #include <Draw.ixx>
 
-#if defined(HAVE_TIME_H) || defined(WNT)
-# include <time.h>
-#endif
-
 #include <Draw_Appli.hxx>
 #include <OSD.hxx>
+#include <OSD_Environment.hxx>
 #include <OSD_Timer.hxx>
 
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
-
 #include <Draw_Window.hxx>
 #include <gp_Pnt2d.hxx>
 
 #include <Standard_Stream.hxx>
+#include <Standard_Version.hxx>
 
 #include <Draw_Drawable3D.hxx>
 #include <Draw_Interpretor.hxx>
 #include <Draw_ProgressIndicator.hxx>
-#include <tcl.h>
 
-#include <Draw_MapOfFunctions.hxx>
+#include <Plugin_MapOfFunctions.hxx>
 #include <OSD_SharedLibrary.hxx>
 #include <Resource_Manager.hxx>
 #include <Draw_Failure.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <Standard_ErrorHandler.hxx>
-extern Standard_Boolean Draw_ParseFailed;
-#ifndef WNT
-extern Standard_Boolean Draw_LowWindows;
+
+#include <tcl.h>
+
+// on MSVC, use #pragma to define name of the Tcl library to link with,
+// depending on Tcl version number
+#ifdef _MSC_VER
+// two helper macros are needed to convert version number macro to string literal
+#define STRINGIZE1(a) #a
+#define STRINGIZE2(a) STRINGIZE1(a)
+#pragma comment (lib, "tcl" STRINGIZE2(TCL_MAJOR_VERSION) STRINGIZE2(TCL_MINOR_VERSION) ".lib")
+#pragma comment (lib, "tk"  STRINGIZE2(TCL_MAJOR_VERSION) STRINGIZE2(TCL_MINOR_VERSION) ".lib")
+#undef STRINGIZE2
+#undef STRINGIZE1
 #endif
 
+extern Standard_Boolean Draw_ParseFailed;
+
 Standard_EXPORT Draw_Viewer dout;
 Standard_EXPORT Draw_Interpretor theCommands;
 Standard_EXPORT Standard_Boolean Draw_Batch;
@@ -92,11 +75,9 @@ static   Standard_Boolean XLoop;
 
 static Handle(Draw_ProgressIndicator) PInd = NULL;
 
-Standard_EXPORT Standard_Boolean Draw_Interprete(char* command);
+Standard_EXPORT Standard_Boolean Draw_Interprete(const char* command);
 // true if complete command
 
-//#ifndef WNT
-
 // *******************************************************************
 // read an init file
 // *******************************************************************
@@ -111,10 +92,9 @@ static void ReadInitFile (const TCollection_AsciiString& theFileName)
 #ifdef WNT
   if (!Draw_Batch) {
     try {
-      OCC_CATCH_SIGNALS
       aPath.ChangeAll ('\\', '/');
 
-      sprintf(console_command, "source \"%s\"", aPath.ToCString());
+      Sprintf(console_command, "source \"%.980s\"", aPath.ToCString());
       console_semaphore = HAS_CONSOLE_COMMAND;
       while (console_semaphore == HAS_CONSOLE_COMMAND)
         Sleep(10);
@@ -126,14 +106,13 @@ static void ReadInitFile (const TCollection_AsciiString& theFileName)
   } else {
 #endif
     char* com = new char [aPath.Length() + strlen ("source ") + 2];
-    sprintf (com, "source %s", aPath.ToCString());
+    Sprintf (com, "source %s", aPath.ToCString());
     Draw_Interprete (com);
     delete [] com;
 #ifdef WNT
   }
 #endif
 }
-//#endif
 
 //=======================================================================
 //function :
@@ -165,83 +144,133 @@ void exitProc(ClientData /*dc*/)
 // *******************************************************************
 // main
 // *******************************************************************
-#ifdef WNT
+#ifdef _WIN32
 //Standard_EXPORT void Draw_Appli(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lps
 Standard_EXPORT void Draw_Appli(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszLine, int nShow,const FDraw_InitAppli Draw_InitAppli)
 #else
 void Draw_Appli(Standard_Integer argc, char** argv,const FDraw_InitAppli Draw_InitAppli)
 #endif
 {
+
+// prepend extra DLL search path to override system libraries like opengl32.dll
+#ifdef _WIN32
+  OSD_Environment aUserDllEnv ("CSF_UserDllPath");
+  TCollection_AsciiString aUserDllPath = aUserDllEnv.Value();
+  if (!aUserDllPath.IsEmpty())
+  {
+    // This function available since Win XP SP1 #if (_WIN32_WINNT >= 0x0502).
+    // We retrieve dynamically here (kernel32 should be always preloaded).
+    typedef BOOL (WINAPI *SetDllDirectoryA_t)(const char* thePathName);
+    HMODULE aKern32Module = GetModuleHandleA ("kernel32");
+    SetDllDirectoryA_t aFunc = (aKern32Module != NULL)
+                             ? (SetDllDirectoryA_t )GetProcAddress (aKern32Module, "SetDllDirectoryA") : NULL;
+    if (aFunc != NULL)
+    {
+      aFunc (aUserDllPath.ToCString());
+    }
+    else
+    {
+      //std::cerr << "SetDllDirectoryA() is not available on this system!\n";
+    }
+    if (aKern32Module != NULL)
+    {
+      FreeLibrary (aKern32Module);
+    }
+  }
+#endif
+
   // *****************************************************************
   // analyze arguments
   // *****************************************************************
   Draw_Batch = Standard_False;
-  TCollection_AsciiString aRunFile;
+  TCollection_AsciiString aRunFile, aCommand;
   Standard_Integer i;
   Standard_Boolean isInteractiveForced = Standard_False;
-#ifndef WNT
-  for (i = 0; i < argc; i++) {
-    if (strcasecmp(argv[i],"-b") == 0)
-      Draw_Batch = Standard_True;
-# ifndef __sgi
-    else if (strcasecmp(argv[i],"-l") == 0) {
-      Draw_LowWindows = Standard_True;
+
+#ifdef _WIN32
+  // On NT command line arguments are in the lpzline and not in argv
+  int argc = 0;
+  const int MAXARGS = 1024;
+  const char* argv[MAXARGS];
+  for (const char* p = strtok(lpszLine, " \t"); p != NULL; p = strtok(NULL, " \t")) {
+    argv[argc++] = p;
+  }
+#endif
+
+  // parse command line
+  for (i = 1; i < argc; i++) {
+    if (strcasecmp (argv[i], "-h") == 0 || strcasecmp (argv[i], "--help") == 0)
+    {
+      cout << "Open CASCADE " << OCC_VERSION_STRING_EXT << " DRAW Test Harness" << endl << endl;
+      cout << "Options: " << endl;
+      cout << "  -b: batch mode (no GUI, no viewers)" << endl;
+      cout << "  -v: no GUI, use virtual (off-screen) windows for viewers" << endl;
+      cout << "  -i: interactive mode" << endl;
+      cout << "  -f file: execute script from file" << endl;
+      cout << "  -c command args...: execute command (with optional arguments)" << endl << endl;
+      cout << "Options -b, -v, and -i are mutually exclusive." << endl;
+      cout << "If -c or -f are given, -v is default; otherwise default is -i." << endl;
+      cout << "Options -c and -f are alternatives and should be at the end " << endl;
+      cout << "of the command line. " << endl;
+      cout << "Option -c can accept set of commands separated by ';'." << endl;
+      return;
     }
-# endif
-    else if (strcasecmp(argv[i],"-v") == 0) {
+    else if (strcasecmp (argv[i], "-b") == 0)
+      Draw_Batch = Standard_True;
+    else if (strcasecmp (argv[i], "-v") == 0) {
       // force virtual windows
       Draw_VirtualWindows = Standard_True;
-    } else if (strcasecmp(argv[i],"-i") == 0) {
+    } else if (strcasecmp (argv[i], "-i") == 0) {
       // force interactive
       Draw_VirtualWindows = Standard_False;
       isInteractiveForced = Standard_True;
-    } else if (strcasecmp(argv[i],"-f") == 0) { // -f option should be LAST!
+    } else if (strcasecmp (argv[i], "-f") == 0) { // -f option should be LAST!
       Draw_VirtualWindows = !isInteractiveForced;
       if (++i < argc) {
         aRunFile = TCollection_AsciiString (argv[i]);
       }
       break;
-    }
-  }
-#else
-  // On NT command line arguments are in the lpzline and not in argv
-  for (char* p = strtok(lpszLine, " \t"); p != NULL; p = strtok(NULL, " \t")) {
-    if (strcasecmp(p, "-v") == 0) {
-      Draw_VirtualWindows = Standard_True;
-    } else if (strcasecmp(p, "-i") == 0) {
-      // force interactive
-      Draw_VirtualWindows = Standard_False;
-      isInteractiveForced = Standard_True;
-    } else if (strcasecmp(p, "-f") == 0) { // -f option should be LAST!
+    } else if (strcasecmp (argv[i], "-c") == 0) { // -c option should be LAST!
       Draw_VirtualWindows = !isInteractiveForced;
-      p = strtok(NULL," \t");
-      if (p != NULL) {
-        aRunFile = TCollection_AsciiString (p);
+      if (++i < argc) {
+        aCommand = TCollection_AsciiString (argv[i]);
+      }
+      while (++i < argc) {
+        aCommand.AssignCat (" ");
+        aCommand.AssignCat (argv[i]);
       }
       break;
+    } else {
+      cout << "Error: unsupported option " << argv[i] << endl;
     }
   }
-#endif
+
   // *****************************************************************
   // set signals
   // *****************************************************************
   OSD::SetSignal();
 
+#ifdef _WIN32
+  // in interactive mode, force Windows to report dll loading problems interactively
+  if ( ! Draw_VirtualWindows && ! Draw_Batch )
+    ::SetErrorMode (0);
+#endif
+
   // *****************************************************************
   // init X window and create display
   // *****************************************************************
 #ifdef WNT
-  HWND hWnd;
+  HWND hWnd = NULL;
 #endif
 
   if (!Draw_Batch)
 #ifdef WNT
-       Draw_Batch=!Init_Appli(hInst, hPrevInst, nShow, hWnd);
+    Draw_Batch=!Init_Appli(hInst, hPrevInst, nShow, hWnd);
 #else
     Draw_Batch=!Init_Appli();
 #endif
   else
-    cout << "batch mode" << endl;
+    cout << "DRAW is running in batch mode" << endl;
 
   XLoop = !Draw_Batch;
   if (XLoop) {
@@ -302,24 +331,27 @@ void Draw_Appli(Standard_Integer argc, char** argv,const FDraw_InitAppli Draw_In
     ReadInitFile (getenv ("DRAWDEFAULT"));
   }
 
-  // pure batch
+  // read commands from file
   if (!aRunFile.IsEmpty()) {
-    // do not map raise the windows, so test programs are discrete
+    ReadInitFile (aRunFile);
+    // provide a clean exit, this is useful for some analysis tools
+    if ( ! isInteractiveForced )
 #ifndef WNT
-    Draw_LowWindows = Standard_True;
-#endif
-  // comme on ne peut pas photographier les fenetres trop discretes sur sgi
-  // on se met en vedette !! (pmn 20/02/97)
-#ifdef __sgi
-    Draw_LowWindows = Standard_False;
+      return;
+#else
+      ExitProcess(0);
 #endif
+  }
 
-    ReadInitFile (aRunFile);
-    // provide a clean exit, this is usefull for some analysis tools
+  // execute command from command line
+  if (!aCommand.IsEmpty()) {
+    Draw_Interprete (aCommand.ToCString());
+    // provide a clean exit, this is useful for some analysis tools
+    if ( ! isInteractiveForced )
 #ifndef WNT
-    return;
+      return;
 #else
-    ExitProcess(0);
+      ExitProcess(0);
 #endif
   }
 
@@ -328,7 +360,7 @@ void Draw_Appli(Standard_Integer argc, char** argv,const FDraw_InitAppli Draw_In
   // *****************************************************************
   if (XLoop) {
 #ifdef WNT
-       Run_Appli(hWnd);
+    Run_Appli(hWnd);
 #else
     Run_Appli(Draw_Interprete);
 #endif
@@ -356,7 +388,7 @@ void Draw_Appli(Standard_Integer argc, char** argv,const FDraw_InitAppli Draw_In
 void (*Draw_BeforeCommand)() = NULL;
 void (*Draw_AfterCommand)(Standard_Integer) = NULL;
 
-Standard_Boolean Draw_Interprete(char* com)
+Standard_Boolean Draw_Interprete(const char* com)
 {
 
   static Standard_Boolean first = Standard_True;
@@ -440,76 +472,6 @@ Standard_Integer  Draw_Call (char *c)
    return r;
 }
 
-
-//=================================================================================
-//
-//=================================================================================
-void Draw::Load(Draw_Interpretor& theDI, const TCollection_AsciiString& theKey,
-                const TCollection_AsciiString& theResourceFileName) {
-
-  static Draw_MapOfFunctions theMapOfFunctions;
-  OSD_Function f;
-
-  if(!theMapOfFunctions.IsBound(theKey)) {
-
-    Handle(Resource_Manager) aPluginResource = new Resource_Manager(theResourceFileName.ToCString());
-    if(!aPluginResource->Find(theKey.ToCString())) {
-      Standard_SStream aMsg; aMsg << "Could not find the resource:";
-      aMsg << theKey.ToCString()<< endl;
-      cout << "could not find the resource:"<<theKey.ToCString()<< endl;
-      Draw_Failure::Raise(aMsg);
-    }
-
-    TCollection_AsciiString aPluginLibrary("");
-#ifndef WNT
-    aPluginLibrary += "lib";
-#endif
-    aPluginLibrary +=  aPluginResource->Value(theKey.ToCString());
-#ifdef WNT
-    aPluginLibrary += ".dll";
-#elif __APPLE__
-    aPluginLibrary += ".dylib";
-#elif defined (HPUX) || defined(_hpux)
-    aPluginLibrary += ".sl";
-#else
-    aPluginLibrary += ".so";
-#endif
-    OSD_SharedLibrary aSharedLibrary(aPluginLibrary.ToCString());
-    if(!aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) {
-      TCollection_AsciiString error(aSharedLibrary.DlError());
-      Standard_SStream aMsg; aMsg << "Could not open: ";
-      aMsg << aPluginResource->Value(theKey.ToCString());
-      aMsg << "; reason: ";
-      aMsg << error.ToCString();
-#ifdef DEB
-      cout << "could not open: "  << aPluginResource->Value(theKey.ToCString())<< " ; reason: "<< error.ToCString() << endl;
-#endif
-      Draw_Failure::Raise(aMsg);
-    }
-    f = aSharedLibrary.DlSymb("PLUGINFACTORY");
-    if( f == NULL ) {
-      TCollection_AsciiString error(aSharedLibrary.DlError());
-      Standard_SStream aMsg; aMsg << "Could not find the factory in: ";
-      aMsg << aPluginResource->Value(theKey.ToCString());
-      aMsg << error.ToCString();
-      Draw_Failure::Raise(aMsg);
-    }
-    theMapOfFunctions.Bind(theKey, f);
-  }
-  else
-    f = theMapOfFunctions(theKey);
-
-//   void (*fp) (Draw_Interpretor&, const TCollection_AsciiString&) = NULL;
-//   fp = (void (*)(Draw_Interpretor&, const TCollection_AsciiString&)) f;
-//   (*fp) (theDI, theKey);
-
-  void (*fp) (Draw_Interpretor&) = NULL;
-  fp = (void (*)(Draw_Interpretor&)) f;
-  (*fp) (theDI);
-
-}
-
-
 //=================================================================================
 //
 //=================================================================================
@@ -519,7 +481,7 @@ void Draw::Load(Draw_Interpretor& theDI, const TCollection_AsciiString& theKey,
                TCollection_AsciiString& theUserDefaultsDirectory,
                const Standard_Boolean Verbose ) {
 
-  static Draw_MapOfFunctions theMapOfFunctions;
+  static Plugin_MapOfFunctions theMapOfFunctions;
   OSD_Function f;
 
   if(!theMapOfFunctions.IsBound(theKey)) {