9a0f82e35f5b642191fa72b03857d9680e552e51
[occt.git] / src / Draw / Draw.cxx
1 // Created on: 1993-08-13
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include <Draw.ixx>
27
28 #if defined(HAVE_TIME_H) || defined(WNT)
29 # include <time.h>
30 #endif
31
32 #include <Draw_Appli.hxx>
33 #include <OSD.hxx>
34 #include <OSD_Timer.hxx>
35
36 #ifdef HAVE_SYS_TIME_H
37 # include <sys/time.h>
38 #endif
39
40 #ifdef HAVE_SYS_TYPES_H
41 # include <sys/types.h>
42 #endif
43
44 #ifdef HAVE_UNISTD_H
45 # include <unistd.h>
46 #endif
47
48 #ifdef HAVE_STRINGS_H
49 # include <strings.h>
50 #endif
51
52
53 #include <Draw_Window.hxx>
54 #include <gp_Pnt2d.hxx>
55
56 #include <Standard_Stream.hxx>
57
58 #include <Draw_Drawable3D.hxx>
59 #include <Draw_Interpretor.hxx>
60 #include <Draw_ProgressIndicator.hxx>
61 #include <tcl.h>
62
63 #include <Draw_MapOfFunctions.hxx>
64 #include <OSD_SharedLibrary.hxx>
65 #include <Resource_Manager.hxx>
66 #include <Draw_Failure.hxx>
67 #include <TCollection_AsciiString.hxx>
68 #include <Standard_ErrorHandler.hxx>
69 extern Standard_Boolean Draw_ParseFailed;
70 #ifndef WNT
71 extern Standard_Boolean Draw_LowWindows;
72 #endif
73
74 Standard_EXPORT Draw_Viewer dout;
75 Standard_EXPORT Draw_Interpretor theCommands;
76 Standard_EXPORT Standard_Boolean Draw_Batch;
77 Standard_EXPORT Standard_Boolean Draw_Spying = Standard_False;
78 Standard_EXPORT Standard_Boolean Draw_Chrono = Standard_False;
79 Standard_EXPORT Standard_Boolean Draw_VirtualWindows = Standard_False;
80 Standard_EXPORT Standard_Boolean ErrorMessages = Standard_True;
81
82 static const char* ColorNames[MAXCOLOR] = {
83   "White","Red","Green","Blue","Cyan","Gold","Magenta",
84   "Maroon","Orange","Pink","Salmon","Violet","Yellow","Khaki","Coral"
85   };
86
87 filebuf Draw_Spyfile;
88
89 static ostream spystream(&Draw_Spyfile);
90
91 static   Standard_Boolean XLoop;
92
93 static Handle(Draw_ProgressIndicator) PInd = NULL;
94
95 Standard_EXPORT Standard_Boolean Draw_Interprete(char* command);
96 // true if complete command
97
98 //#ifndef WNT
99
100 // *******************************************************************
101 // read an init file
102 // *******************************************************************
103 #ifdef WNT
104 extern console_semaphore_value volatile console_semaphore;
105 extern char console_command[1000];
106 #endif
107
108 static void ReadInitFile (const TCollection_AsciiString& theFileName)
109 {
110   TCollection_AsciiString aPath = theFileName;
111 #ifdef WNT
112   if (!Draw_Batch) {
113     try {
114       OCC_CATCH_SIGNALS
115       aPath.ChangeAll ('\\', '/');
116
117       sprintf(console_command, "source \"%s\"", aPath.ToCString());
118       console_semaphore = HAS_CONSOLE_COMMAND;
119       while (console_semaphore == HAS_CONSOLE_COMMAND)
120         Sleep(10);
121     }
122     catch(...) {
123       cout << "Error while reading a script file." << endl;
124       ExitProcess(0);
125     }
126   } else {
127 #endif
128     char* com = new char [aPath.Length() + strlen ("source ") + 2];
129     sprintf (com, "source %s", aPath.ToCString());
130     Draw_Interprete (com);
131     delete [] com;
132 #ifdef WNT
133   }
134 #endif
135 }
136 //#endif
137
138 //=======================================================================
139 //function :
140 //purpose  : Set/Get Progress Indicator
141 //=======================================================================
142 void Draw::SetProgressBar(const Handle(Draw_ProgressIndicator)& thePI)
143 {
144   PInd = thePI;
145 }
146
147 Handle(Draw_ProgressIndicator) Draw::GetProgressBar()
148 {
149   return PInd;
150 }
151
152 #ifndef WNT
153 /*--------------------------------------------------------*\
154 |  exitProc: finalization handler for Tcl/Tk thread. Forces parent process to die
155 \*--------------------------------------------------------*/
156 void exitProc(ClientData /*dc*/)
157 {
158   if (!Draw_Batch) {
159     for (Standard_Integer id = 0; id < MAXVIEW; id++)
160       dout.DeleteView(id);
161   }
162 }
163 #endif
164
165 // *******************************************************************
166 // main
167 // *******************************************************************
168 #ifdef WNT
169 //Standard_EXPORT void Draw_Appli(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lps
170 Standard_EXPORT void Draw_Appli(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszLine, int nShow,const FDraw_InitAppli Draw_InitAppli)
171 #else
172 void Draw_Appli(Standard_Integer argc, char** argv,const FDraw_InitAppli Draw_InitAppli)
173 #endif
174 {
175   // *****************************************************************
176   // analyze arguments
177   // *****************************************************************
178   Draw_Batch = Standard_False;
179   TCollection_AsciiString aRunFile;
180   Standard_Integer i;
181   Standard_Boolean isInteractiveForced = Standard_False;
182 #ifndef WNT
183   for (i = 0; i < argc; i++) {
184     if (strcasecmp(argv[i],"-b") == 0)
185       Draw_Batch = Standard_True;
186 # ifndef __sgi
187     else if (strcasecmp(argv[i],"-l") == 0) {
188       Draw_LowWindows = Standard_True;
189     }
190 # endif
191     else if (strcasecmp(argv[i],"-v") == 0) {
192       // force virtual windows
193       Draw_VirtualWindows = Standard_True;
194     } else if (strcasecmp(argv[i],"-i") == 0) {
195       // force interactive
196       Draw_VirtualWindows = Standard_False;
197       isInteractiveForced = Standard_True;
198     } else if (strcasecmp(argv[i],"-f") == 0) { // -f option should be LAST!
199       Draw_VirtualWindows = !isInteractiveForced;
200       if (++i < argc) {
201         aRunFile = TCollection_AsciiString (argv[i]);
202       }
203       break;
204     }
205   }
206 #else
207   // On NT command line arguments are in the lpzline and not in argv
208   for (char* p = strtok(lpszLine, " \t"); p != NULL; p = strtok(NULL, " \t")) {
209     if (strcasecmp(p, "-v") == 0) {
210       Draw_VirtualWindows = Standard_True;
211     } else if (strcasecmp(p, "-i") == 0) {
212       // force interactive
213       Draw_VirtualWindows = Standard_False;
214       isInteractiveForced = Standard_True;
215     } else if (strcasecmp(p, "-f") == 0) { // -f option should be LAST!
216       Draw_VirtualWindows = !isInteractiveForced;
217       p = strtok(NULL," \t");
218       if (p != NULL) {
219         aRunFile = TCollection_AsciiString (p);
220       }
221       break;
222     }
223   }
224 #endif
225   // *****************************************************************
226   // set signals
227   // *****************************************************************
228   OSD::SetSignal();
229
230   // *****************************************************************
231   // init X window and create display
232   // *****************************************************************
233 #ifdef WNT
234   HWND hWnd;
235 #endif
236
237   if (!Draw_Batch)
238 #ifdef WNT
239         Draw_Batch=!Init_Appli(hInst, hPrevInst, nShow, hWnd);
240 #else
241     Draw_Batch=!Init_Appli();
242 #endif
243   else
244     cout << "batch mode" << endl;
245
246   XLoop = !Draw_Batch;
247   if (XLoop) {
248     // Default colors
249     for (i=0;i<MAXCOLOR;i++) {
250       if (!dout.DefineColor(i,ColorNames[i]))
251         cout <<"Could not allocate default color "<<ColorNames[i]<<endl;
252     }
253   }
254
255   // *****************************************************************
256   // set maximum precision for cout
257   // *****************************************************************
258   cout.precision(15);
259
260   // *****************************************************************
261   // standard commands
262   // *****************************************************************
263   Draw::BasicCommands(theCommands);
264   Draw::VariableCommands(theCommands);
265   Draw::UnitCommands(theCommands);
266   if (!Draw_Batch) Draw::GraphicCommands(theCommands);
267
268   // *****************************************************************
269   // user commands
270   // *****************************************************************
271   Draw_InitAppli(theCommands);
272
273 #ifndef WNT
274   Tcl_CreateExitHandler(exitProc, 0);
275 #endif
276
277   // *****************************************************************
278   // read init files
279   // *****************************************************************
280   // default
281
282   if (getenv ("DRAWDEFAULT") == NULL)
283   {
284     if (getenv ("CASROOT") == NULL)
285     {
286 #ifdef WNT
287       ReadInitFile ("ddefault");
288 #else
289       cout << " the CASROOT variable is mandatory to Run OpenCascade "<< endl;
290       cout << "No default file" << endl;
291 #endif
292     }
293     else
294     {
295       TCollection_AsciiString aDefStr (getenv ("CASROOT"));
296       aDefStr += "/src/DrawResources/DrawDefault";
297       ReadInitFile (aDefStr);
298     }
299   }
300   else
301   {
302     ReadInitFile (getenv ("DRAWDEFAULT"));
303   }
304
305   // pure batch
306   if (!aRunFile.IsEmpty()) {
307     // do not map raise the windows, so test programs are discrete
308 #ifndef WNT
309     Draw_LowWindows = Standard_True;
310 #endif
311   // comme on ne peut pas photographier les fenetres trop discretes sur sgi
312   // on se met en vedette !! (pmn 20/02/97)
313 #ifdef __sgi
314     Draw_LowWindows = Standard_False;
315 #endif
316
317     ReadInitFile (aRunFile);
318     // provide a clean exit, this is usefull for some analysis tools
319 #ifndef WNT
320     return;
321 #else
322     ExitProcess(0);
323 #endif
324   }
325
326   // *****************************************************************
327   // X loop
328   // *****************************************************************
329   if (XLoop) {
330 #ifdef WNT
331         Run_Appli(hWnd);
332 #else
333     Run_Appli(Draw_Interprete);
334 #endif
335   }
336   else
337   {
338     char cmd[255];
339     do {
340       cout << "Viewer>";
341       i = -1;
342       do {
343         cin.get(cmd[++i]);
344       } while ((cmd[i] != '\n') && (!cin.fail()));
345       cmd[i] = '\0';
346     } while (Draw_Interprete(cmd) != (unsigned int ) -2);
347   }
348 #ifdef WNT
349   // Destruction de l'application
350   Destroy_Appli(hInst);
351 #endif
352 }
353 //#endif
354
355 // User functions called before and after each command
356 void (*Draw_BeforeCommand)() = NULL;
357 void (*Draw_AfterCommand)(Standard_Integer) = NULL;
358
359 Standard_Boolean Draw_Interprete(char* com)
360 {
361
362   static Standard_Boolean first = Standard_True;
363   static Tcl_DString command;
364
365   if (first) {
366     first = Standard_False;
367     Tcl_DStringInit(&command);
368   }
369
370 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 1)))
371   // OCC63: Since Tcl 8.1 it uses UTF-8 encoding for internal representation of strings
372   Tcl_ExternalToUtfDString ( NULL, com, -1, &command );
373 #else
374   Tcl_DStringAppend(&command,com,-1);
375 #endif
376
377   if (!theCommands.Complete(Tcl_DStringValue(&command)))
378     return Standard_False;
379
380   // *******************************************************************
381   // Command interpreter
382   // *******************************************************************
383
384 //  Standard_Integer i = 0;
385 //  Standard_Integer j = 0;
386
387   Standard_Boolean wasspying = Draw_Spying;
388
389   OSD_Timer tictac;
390   Standard_Boolean hadchrono = Draw_Chrono;
391   if (hadchrono) tictac.Start();
392
393   if (Draw_BeforeCommand) (*Draw_BeforeCommand) ();
394
395   Standard_Integer c;
396
397   c = theCommands.RecordAndEval(Tcl_DStringValue(&command));
398
399   if (Draw_AfterCommand) (*Draw_AfterCommand)(c);
400
401   if (wasspying && Draw_Spying) {
402     if (c > 0) spystream << "# ";
403     spystream << Tcl_DStringValue(&command) << "\n";
404   }
405
406   dout.Flush();
407
408   if (*theCommands.Result())
409     cout << theCommands.Result() << endl;
410
411   if (Draw_Chrono && hadchrono) {
412     tictac.Stop();
413     tictac.Show();
414   }
415
416   Tcl_DStringFree(&command);
417
418   return Standard_True;
419 }
420
421 //
422 // for TCl
423 //
424
425 Standard_Integer Tcl_AppInit (Tcl_Interp *)
426 {
427   return 0;
428 }
429
430 //
431 // for debug call
432 //
433
434
435
436 Standard_Integer  Draw_Call (char *c)
437 {
438    Standard_Integer r = theCommands.Eval(c);
439    cout << theCommands.Result() << endl;
440    return r;
441 }
442
443
444 //=================================================================================
445 //
446 //=================================================================================
447 void Draw::Load(Draw_Interpretor& theDI, const TCollection_AsciiString& theKey,
448                  const TCollection_AsciiString& theResourceFileName) {
449
450   static Draw_MapOfFunctions theMapOfFunctions;
451   OSD_Function f;
452
453   if(!theMapOfFunctions.IsBound(theKey)) {
454
455     Handle(Resource_Manager) aPluginResource = new Resource_Manager(theResourceFileName.ToCString());
456     if(!aPluginResource->Find(theKey.ToCString())) {
457       Standard_SStream aMsg; aMsg << "Could not find the resource:";
458       aMsg << theKey.ToCString()<< endl;
459       cout << "could not find the resource:"<<theKey.ToCString()<< endl;
460       Draw_Failure::Raise(aMsg);
461     }
462
463     TCollection_AsciiString aPluginLibrary("");
464 #ifndef WNT
465     aPluginLibrary += "lib";
466 #endif
467     aPluginLibrary +=  aPluginResource->Value(theKey.ToCString());
468 #ifdef WNT
469     aPluginLibrary += ".dll";
470 #elif __APPLE__
471     aPluginLibrary += ".dylib";
472 #elif defined (HPUX) || defined(_hpux)
473     aPluginLibrary += ".sl";
474 #else
475     aPluginLibrary += ".so";
476 #endif
477     OSD_SharedLibrary aSharedLibrary(aPluginLibrary.ToCString());
478     if(!aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) {
479       TCollection_AsciiString error(aSharedLibrary.DlError());
480       Standard_SStream aMsg; aMsg << "Could not open: ";
481       aMsg << aPluginResource->Value(theKey.ToCString());
482       aMsg << "; reason: ";
483       aMsg << error.ToCString();
484 #ifdef DEB
485       cout << "could not open: "  << aPluginResource->Value(theKey.ToCString())<< " ; reason: "<< error.ToCString() << endl;
486 #endif
487       Draw_Failure::Raise(aMsg);
488     }
489     f = aSharedLibrary.DlSymb("PLUGINFACTORY");
490     if( f == NULL ) {
491       TCollection_AsciiString error(aSharedLibrary.DlError());
492       Standard_SStream aMsg; aMsg << "Could not find the factory in: ";
493       aMsg << aPluginResource->Value(theKey.ToCString());
494       aMsg << error.ToCString();
495       Draw_Failure::Raise(aMsg);
496     }
497     theMapOfFunctions.Bind(theKey, f);
498   }
499   else
500     f = theMapOfFunctions(theKey);
501
502 //   void (*fp) (Draw_Interpretor&, const TCollection_AsciiString&) = NULL;
503 //   fp = (void (*)(Draw_Interpretor&, const TCollection_AsciiString&)) f;
504 //   (*fp) (theDI, theKey);
505
506   void (*fp) (Draw_Interpretor&) = NULL;
507   fp = (void (*)(Draw_Interpretor&)) f;
508   (*fp) (theDI);
509
510 }
511
512
513 //=================================================================================
514 //
515 //=================================================================================
516 void Draw::Load(Draw_Interpretor& theDI, const TCollection_AsciiString& theKey,
517                 const TCollection_AsciiString& theResourceFileName,
518                 TCollection_AsciiString& theDefaultsDirectory,
519                 TCollection_AsciiString& theUserDefaultsDirectory,
520                 const Standard_Boolean Verbose ) {
521
522   static Draw_MapOfFunctions theMapOfFunctions;
523   OSD_Function f;
524
525   if(!theMapOfFunctions.IsBound(theKey)) {
526
527     Handle(Resource_Manager) aPluginResource = new Resource_Manager(theResourceFileName.ToCString(), theDefaultsDirectory, theUserDefaultsDirectory, Verbose);
528
529     if(!aPluginResource->Find(theKey.ToCString())) {
530       Standard_SStream aMsg; aMsg << "Could not find the resource:";
531       aMsg << theKey.ToCString()<< endl;
532       cout << "could not find the resource:"<<theKey.ToCString()<< endl;
533       Draw_Failure::Raise(aMsg);
534     }
535
536     TCollection_AsciiString aPluginLibrary("");
537 #ifndef WNT
538     aPluginLibrary += "lib";
539 #endif
540     aPluginLibrary +=  aPluginResource->Value(theKey.ToCString());
541 #ifdef WNT
542     aPluginLibrary += ".dll";
543 #elif __APPLE__
544     aPluginLibrary += ".dylib";
545 #elif defined (HPUX) || defined(_hpux)
546     aPluginLibrary += ".sl";
547 #else
548     aPluginLibrary += ".so";
549 #endif
550     OSD_SharedLibrary aSharedLibrary(aPluginLibrary.ToCString());
551     if(!aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) {
552       TCollection_AsciiString error(aSharedLibrary.DlError());
553       Standard_SStream aMsg; aMsg << "Could not open: ";
554       aMsg << aPluginResource->Value(theKey.ToCString());
555       aMsg << "; reason: ";
556       aMsg << error.ToCString();
557 #ifdef DEB
558       cout << "could not open: "  << aPluginResource->Value(theKey.ToCString())<< " ; reason: "<< error.ToCString() << endl;
559 #endif
560       Draw_Failure::Raise(aMsg);
561     }
562     f = aSharedLibrary.DlSymb("PLUGINFACTORY");
563     if( f == NULL ) {
564       TCollection_AsciiString error(aSharedLibrary.DlError());
565       Standard_SStream aMsg; aMsg << "Could not find the factory in: ";
566       aMsg << aPluginResource->Value(theKey.ToCString());
567       aMsg << error.ToCString();
568       Draw_Failure::Raise(aMsg);
569     }
570     theMapOfFunctions.Bind(theKey, f);
571   }
572   else
573     f = theMapOfFunctions(theKey);
574
575 //   void (*fp) (Draw_Interpretor&, const TCollection_AsciiString&) = NULL;
576 //   fp = (void (*)(Draw_Interpretor&, const TCollection_AsciiString&)) f;
577 //   (*fp) (theDI, theKey);
578
579   void (*fp) (Draw_Interpretor&) = NULL;
580   fp = (void (*)(Draw_Interpretor&)) f;
581   (*fp) (theDI);
582
583 }