0027772: Foundation Classes - define Standard_Boolean using C++ type "bool" instead...
[occt.git] / src / Draw / Draw.cxx
CommitLineData
b311480e 1// Created on: 1993-08-13
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1993-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17
42cf5bc1 18#include <Draw.hxx>
7fd59977 19#include <Draw_Appli.hxx>
7fd59977 20#include <Draw_Drawable3D.hxx>
42cf5bc1 21#include <Draw_Failure.hxx>
7fd59977 22#include <Draw_Interpretor.hxx>
23#include <Draw_ProgressIndicator.hxx>
42cf5bc1 24#include <Draw_Window.hxx>
25#include <gp_Pnt2d.hxx>
26#include <OSD.hxx>
27#include <OSD_Environment.hxx>
7fd59977 28#include <OSD_SharedLibrary.hxx>
42cf5bc1 29#include <OSD_Timer.hxx>
30#include <Plugin_MapOfFunctions.hxx>
7fd59977 31#include <Resource_Manager.hxx>
7fd59977 32#include <Standard_ErrorHandler.hxx>
42cf5bc1 33#include <Standard_Stream.hxx>
34#include <Standard_Version.hxx>
35#include <TCollection_AsciiString.hxx>
6a0964c2 36
37#include <tcl.h>
6a0964c2 38// on MSVC, use #pragma to define name of the Tcl library to link with,
39// depending on Tcl version number
40#ifdef _MSC_VER
41// two helper macros are needed to convert version number macro to string literal
42#define STRINGIZE1(a) #a
43#define STRINGIZE2(a) STRINGIZE1(a)
44#pragma comment (lib, "tcl" STRINGIZE2(TCL_MAJOR_VERSION) STRINGIZE2(TCL_MINOR_VERSION) ".lib")
45#pragma comment (lib, "tk" STRINGIZE2(TCL_MAJOR_VERSION) STRINGIZE2(TCL_MINOR_VERSION) ".lib")
46#undef STRINGIZE2
47#undef STRINGIZE1
48#endif
49
7fd59977 50extern Standard_Boolean Draw_ParseFailed;
7fd59977 51
52Standard_EXPORT Draw_Viewer dout;
53Standard_EXPORT Draw_Interpretor theCommands;
54Standard_EXPORT Standard_Boolean Draw_Batch;
55Standard_EXPORT Standard_Boolean Draw_Spying = Standard_False;
56Standard_EXPORT Standard_Boolean Draw_Chrono = Standard_False;
57Standard_EXPORT Standard_Boolean Draw_VirtualWindows = Standard_False;
58Standard_EXPORT Standard_Boolean ErrorMessages = Standard_True;
59
60static const char* ColorNames[MAXCOLOR] = {
61 "White","Red","Green","Blue","Cyan","Gold","Magenta",
62 "Maroon","Orange","Pink","Salmon","Violet","Yellow","Khaki","Coral"
63 };
64
65filebuf Draw_Spyfile;
66
67static ostream spystream(&Draw_Spyfile);
68
69static Standard_Boolean XLoop;
70
71static Handle(Draw_ProgressIndicator) PInd = NULL;
72
bf03eb83 73Standard_EXPORT Standard_Boolean Draw_Interprete(const char* command);
7fd59977 74// true if complete command
75
7fd59977 76// *******************************************************************
77// read an init file
78// *******************************************************************
57c28b61 79#ifdef _WIN32
7fd59977 80extern console_semaphore_value volatile console_semaphore;
81extern char console_command[1000];
82#endif
83
86be4295 84static void ReadInitFile (const TCollection_AsciiString& theFileName)
7fd59977 85{
86be4295 86 TCollection_AsciiString aPath = theFileName;
57c28b61 87#ifdef _WIN32
7fd59977 88 if (!Draw_Batch) {
89 try {
86be4295
A
90 aPath.ChangeAll ('\\', '/');
91
91322f44 92 Sprintf(console_command, "source \"%.980s\"", aPath.ToCString());
7fd59977 93 console_semaphore = HAS_CONSOLE_COMMAND;
94 while (console_semaphore == HAS_CONSOLE_COMMAND)
95 Sleep(10);
96 }
97 catch(...) {
98 cout << "Error while reading a script file." << endl;
99 ExitProcess(0);
100 }
101 } else {
102#endif
86be4295 103 char* com = new char [aPath.Length() + strlen ("source ") + 2];
91322f44 104 Sprintf (com, "source %s", aPath.ToCString());
86be4295 105 Draw_Interprete (com);
7fd59977 106 delete [] com;
57c28b61 107#ifdef _WIN32
7fd59977 108 }
109#endif
110}
7fd59977 111
112//=======================================================================
113//function :
114//purpose : Set/Get Progress Indicator
115//=======================================================================
116void Draw::SetProgressBar(const Handle(Draw_ProgressIndicator)& thePI)
117{
118 PInd = thePI;
119}
120
121Handle(Draw_ProgressIndicator) Draw::GetProgressBar()
122{
123 return PInd;
124}
125
57c28b61 126#ifndef _WIN32
7fd59977 127/*--------------------------------------------------------*\
128| exitProc: finalization handler for Tcl/Tk thread. Forces parent process to die
129\*--------------------------------------------------------*/
130void exitProc(ClientData /*dc*/)
131{
132 if (!Draw_Batch) {
133 for (Standard_Integer id = 0; id < MAXVIEW; id++)
134 dout.DeleteView(id);
135 }
136}
137#endif
138
139// *******************************************************************
140// main
141// *******************************************************************
dac04bfa 142#ifdef _WIN32
7fd59977 143//Standard_EXPORT void Draw_Appli(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lps
144Standard_EXPORT void Draw_Appli(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszLine, int nShow,const FDraw_InitAppli Draw_InitAppli)
145#else
146void Draw_Appli(Standard_Integer argc, char** argv,const FDraw_InitAppli Draw_InitAppli)
147#endif
148{
dac04bfa 149
150// prepend extra DLL search path to override system libraries like opengl32.dll
151#ifdef _WIN32
152 OSD_Environment aUserDllEnv ("CSF_UserDllPath");
153 TCollection_AsciiString aUserDllPath = aUserDllEnv.Value();
154 if (!aUserDllPath.IsEmpty())
155 {
156 // This function available since Win XP SP1 #if (_WIN32_WINNT >= 0x0502).
157 // We retrieve dynamically here (kernel32 should be always preloaded).
158 typedef BOOL (WINAPI *SetDllDirectoryA_t)(const char* thePathName);
159 HMODULE aKern32Module = GetModuleHandleA ("kernel32");
160 SetDllDirectoryA_t aFunc = (aKern32Module != NULL)
161 ? (SetDllDirectoryA_t )GetProcAddress (aKern32Module, "SetDllDirectoryA") : NULL;
162 if (aFunc != NULL)
163 {
164 aFunc (aUserDllPath.ToCString());
165 }
166 else
167 {
168 //std::cerr << "SetDllDirectoryA() is not available on this system!\n";
169 }
170 if (aKern32Module != NULL)
171 {
172 FreeLibrary (aKern32Module);
173 }
174 }
175#endif
176
7fd59977 177 // *****************************************************************
178 // analyze arguments
179 // *****************************************************************
180 Draw_Batch = Standard_False;
bf03eb83 181 TCollection_AsciiString aRunFile, aCommand;
7fd59977 182 Standard_Integer i;
183 Standard_Boolean isInteractiveForced = Standard_False;
bf03eb83 184
dac04bfa 185#ifdef _WIN32
bf03eb83 186 // On NT command line arguments are in the lpzline and not in argv
187 int argc = 0;
188 const int MAXARGS = 1024;
189 const char* argv[MAXARGS];
190 for (const char* p = strtok(lpszLine, " \t"); p != NULL; p = strtok(NULL, " \t")) {
191 argv[argc++] = p;
192 }
193#endif
194
195 // parse command line
196 for (i = 1; i < argc; i++) {
197 if (strcasecmp (argv[i], "-h") == 0 || strcasecmp (argv[i], "--help") == 0)
198 {
199 cout << "Open CASCADE " << OCC_VERSION_STRING_EXT << " DRAW Test Harness" << endl << endl;
200 cout << "Options: " << endl;
201 cout << " -b: batch mode (no GUI, no viewers)" << endl;
202 cout << " -v: no GUI, use virtual (off-screen) windows for viewers" << endl;
203 cout << " -i: interactive mode" << endl;
204 cout << " -f file: execute script from file" << endl;
205 cout << " -c command args...: execute command (with optional arguments)" << endl << endl;
206 cout << "Options -b, -v, and -i are mutually exclusive." << endl;
207 cout << "If -c or -f are given, -v is default; otherwise default is -i." << endl;
208 cout << "Options -c and -f are alternatives and should be at the end " << endl;
209 cout << "of the command line. " << endl;
210 cout << "Option -c can accept set of commands separated by ';'." << endl;
211 return;
7fd59977 212 }
bf03eb83 213 else if (strcasecmp (argv[i], "-b") == 0)
214 Draw_Batch = Standard_True;
215 else if (strcasecmp (argv[i], "-v") == 0) {
7fd59977 216 // force virtual windows
217 Draw_VirtualWindows = Standard_True;
bf03eb83 218 } else if (strcasecmp (argv[i], "-i") == 0) {
7fd59977 219 // force interactive
220 Draw_VirtualWindows = Standard_False;
221 isInteractiveForced = Standard_True;
bf03eb83 222 } else if (strcasecmp (argv[i], "-f") == 0) { // -f option should be LAST!
7fd59977 223 Draw_VirtualWindows = !isInteractiveForced;
224 if (++i < argc) {
86be4295 225 aRunFile = TCollection_AsciiString (argv[i]);
7fd59977 226 }
227 break;
bf03eb83 228 } else if (strcasecmp (argv[i], "-c") == 0) { // -c option should be LAST!
7fd59977 229 Draw_VirtualWindows = !isInteractiveForced;
bf03eb83 230 if (++i < argc) {
231 aCommand = TCollection_AsciiString (argv[i]);
232 }
233 while (++i < argc) {
234 aCommand.AssignCat (" ");
235 aCommand.AssignCat (argv[i]);
7fd59977 236 }
237 break;
bf03eb83 238 } else {
239 cout << "Error: unsupported option " << argv[i] << endl;
7fd59977 240 }
241 }
bf03eb83 242
7fd59977 243 // *****************************************************************
244 // set signals
245 // *****************************************************************
d538d7a2 246 OSD::SetSignal(Standard_False);
7fd59977 247
bf03eb83 248#ifdef _WIN32
249 // in interactive mode, force Windows to report dll loading problems interactively
250 if ( ! Draw_VirtualWindows && ! Draw_Batch )
251 ::SetErrorMode (0);
252#endif
253
7fd59977 254 // *****************************************************************
255 // init X window and create display
256 // *****************************************************************
57c28b61 257#ifdef _WIN32
1d47d8d0 258 HWND hWnd = NULL;
7fd59977 259#endif
260
261 if (!Draw_Batch)
57c28b61 262#ifdef _WIN32
bf03eb83 263 Draw_Batch=!Init_Appli(hInst, hPrevInst, nShow, hWnd);
7fd59977 264#else
265 Draw_Batch=!Init_Appli();
266#endif
267 else
bf03eb83 268 cout << "DRAW is running in batch mode" << endl;
7fd59977 269
270 XLoop = !Draw_Batch;
271 if (XLoop) {
272 // Default colors
273 for (i=0;i<MAXCOLOR;i++) {
274 if (!dout.DefineColor(i,ColorNames[i]))
275 cout <<"Could not allocate default color "<<ColorNames[i]<<endl;
276 }
277 }
278
279 // *****************************************************************
280 // set maximum precision for cout
281 // *****************************************************************
282 cout.precision(15);
283
284 // *****************************************************************
285 // standard commands
286 // *****************************************************************
287 Draw::BasicCommands(theCommands);
288 Draw::VariableCommands(theCommands);
289 Draw::UnitCommands(theCommands);
290 if (!Draw_Batch) Draw::GraphicCommands(theCommands);
291
292 // *****************************************************************
293 // user commands
294 // *****************************************************************
295 Draw_InitAppli(theCommands);
296
57c28b61 297#ifndef _WIN32
7fd59977 298 Tcl_CreateExitHandler(exitProc, 0);
299#endif
300
301 // *****************************************************************
302 // read init files
303 // *****************************************************************
304 // default
86be4295
A
305
306 if (getenv ("DRAWDEFAULT") == NULL)
7fd59977 307 {
86be4295 308 if (getenv ("CASROOT") == NULL)
7fd59977 309 {
57c28b61 310#ifdef _WIN32
86be4295 311 ReadInitFile ("ddefault");
7fd59977 312#else
86be4295
A
313 cout << " the CASROOT variable is mandatory to Run OpenCascade "<< endl;
314 cout << "No default file" << endl;
7fd59977 315#endif
316 }
317 else
318 {
86be4295
A
319 TCollection_AsciiString aDefStr (getenv ("CASROOT"));
320 aDefStr += "/src/DrawResources/DrawDefault";
321 ReadInitFile (aDefStr);
7fd59977 322 }
323 }
324 else
325 {
86be4295 326 ReadInitFile (getenv ("DRAWDEFAULT"));
7fd59977 327 }
328
bf03eb83 329 // read commands from file
86be4295 330 if (!aRunFile.IsEmpty()) {
bf03eb83 331 ReadInitFile (aRunFile);
332 // provide a clean exit, this is useful for some analysis tools
333 if ( ! isInteractiveForced )
57c28b61 334#ifndef _WIN32
bf03eb83 335 return;
336#else
337 ExitProcess(0);
7fd59977 338#endif
bf03eb83 339 }
7fd59977 340
bf03eb83 341 // execute command from command line
342 if (!aCommand.IsEmpty()) {
343 Draw_Interprete (aCommand.ToCString());
344 // provide a clean exit, this is useful for some analysis tools
345 if ( ! isInteractiveForced )
57c28b61 346#ifndef _WIN32
bf03eb83 347 return;
7fd59977 348#else
bf03eb83 349 ExitProcess(0);
7fd59977 350#endif
351 }
352
353 // *****************************************************************
354 // X loop
355 // *****************************************************************
356 if (XLoop) {
57c28b61 357#ifdef _WIN32
bf03eb83 358 Run_Appli(hWnd);
7fd59977 359#else
360 Run_Appli(Draw_Interprete);
361#endif
362 }
363 else
364 {
365 char cmd[255];
dde68833 366 for (;;)
367 {
7fd59977 368 cout << "Viewer>";
369 i = -1;
370 do {
371 cin.get(cmd[++i]);
372 } while ((cmd[i] != '\n') && (!cin.fail()));
373 cmd[i] = '\0';
dde68833 374 Draw_Interprete(cmd);
375 }
7fd59977 376 }
57c28b61 377#ifdef _WIN32
7fd59977 378 // Destruction de l'application
379 Destroy_Appli(hInst);
380#endif
381}
382//#endif
383
384// User functions called before and after each command
385void (*Draw_BeforeCommand)() = NULL;
386void (*Draw_AfterCommand)(Standard_Integer) = NULL;
387
bf03eb83 388Standard_Boolean Draw_Interprete(const char* com)
7fd59977 389{
390
391 static Standard_Boolean first = Standard_True;
392 static Tcl_DString command;
393
394 if (first) {
395 first = Standard_False;
396 Tcl_DStringInit(&command);
397 }
398
399#if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 1)))
400 // OCC63: Since Tcl 8.1 it uses UTF-8 encoding for internal representation of strings
401 Tcl_ExternalToUtfDString ( NULL, com, -1, &command );
402#else
403 Tcl_DStringAppend(&command,com,-1);
404#endif
405
406 if (!theCommands.Complete(Tcl_DStringValue(&command)))
407 return Standard_False;
408
409 // *******************************************************************
410 // Command interpreter
411 // *******************************************************************
412
413// Standard_Integer i = 0;
414// Standard_Integer j = 0;
415
416 Standard_Boolean wasspying = Draw_Spying;
417
418 OSD_Timer tictac;
419 Standard_Boolean hadchrono = Draw_Chrono;
420 if (hadchrono) tictac.Start();
421
422 if (Draw_BeforeCommand) (*Draw_BeforeCommand) ();
423
424 Standard_Integer c;
425
426 c = theCommands.RecordAndEval(Tcl_DStringValue(&command));
427
428 if (Draw_AfterCommand) (*Draw_AfterCommand)(c);
429
430 if (wasspying && Draw_Spying) {
431 if (c > 0) spystream << "# ";
432 spystream << Tcl_DStringValue(&command) << "\n";
433 }
434
435 dout.Flush();
436
437 if (*theCommands.Result())
438 cout << theCommands.Result() << endl;
439
440 if (Draw_Chrono && hadchrono) {
441 tictac.Stop();
442 tictac.Show();
443 }
444
445 Tcl_DStringFree(&command);
446
447 return Standard_True;
448}
449
450//
451// for TCl
452//
453
454Standard_Integer Tcl_AppInit (Tcl_Interp *)
455{
456 return 0;
457}
458
459//
460// for debug call
461//
462
463
464
465Standard_Integer Draw_Call (char *c)
466{
467 Standard_Integer r = theCommands.Eval(c);
468 cout << theCommands.Result() << endl;
469 return r;
470}
471
7fd59977 472//=================================================================================
473//
474//=================================================================================
475void Draw::Load(Draw_Interpretor& theDI, const TCollection_AsciiString& theKey,
476 const TCollection_AsciiString& theResourceFileName,
477 TCollection_AsciiString& theDefaultsDirectory,
478 TCollection_AsciiString& theUserDefaultsDirectory,
479 const Standard_Boolean Verbose ) {
480
97385d61 481 static Plugin_MapOfFunctions theMapOfFunctions;
7fd59977 482 OSD_Function f;
483
484 if(!theMapOfFunctions.IsBound(theKey)) {
485
486 Handle(Resource_Manager) aPluginResource = new Resource_Manager(theResourceFileName.ToCString(), theDefaultsDirectory, theUserDefaultsDirectory, Verbose);
487
488 if(!aPluginResource->Find(theKey.ToCString())) {
489 Standard_SStream aMsg; aMsg << "Could not find the resource:";
490 aMsg << theKey.ToCString()<< endl;
491 cout << "could not find the resource:"<<theKey.ToCString()<< endl;
492 Draw_Failure::Raise(aMsg);
493 }
494
495 TCollection_AsciiString aPluginLibrary("");
7c65581d 496#if !defined(_WIN32) || defined(__MINGW32__)
7fd59977 497 aPluginLibrary += "lib";
498#endif
499 aPluginLibrary += aPluginResource->Value(theKey.ToCString());
57c28b61 500#ifdef _WIN32
7fd59977 501 aPluginLibrary += ".dll";
502#elif __APPLE__
503 aPluginLibrary += ".dylib";
504#elif defined (HPUX) || defined(_hpux)
505 aPluginLibrary += ".sl";
506#else
507 aPluginLibrary += ".so";
508#endif
509 OSD_SharedLibrary aSharedLibrary(aPluginLibrary.ToCString());
510 if(!aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) {
511 TCollection_AsciiString error(aSharedLibrary.DlError());
512 Standard_SStream aMsg; aMsg << "Could not open: ";
513 aMsg << aPluginResource->Value(theKey.ToCString());
514 aMsg << "; reason: ";
515 aMsg << error.ToCString();
0797d9d3 516#ifdef OCCT_DEBUG
7fd59977 517 cout << "could not open: " << aPluginResource->Value(theKey.ToCString())<< " ; reason: "<< error.ToCString() << endl;
518#endif
519 Draw_Failure::Raise(aMsg);
520 }
521 f = aSharedLibrary.DlSymb("PLUGINFACTORY");
522 if( f == NULL ) {
523 TCollection_AsciiString error(aSharedLibrary.DlError());
524 Standard_SStream aMsg; aMsg << "Could not find the factory in: ";
525 aMsg << aPluginResource->Value(theKey.ToCString());
526 aMsg << error.ToCString();
527 Draw_Failure::Raise(aMsg);
528 }
529 theMapOfFunctions.Bind(theKey, f);
530 }
531 else
532 f = theMapOfFunctions(theKey);
533
534// void (*fp) (Draw_Interpretor&, const TCollection_AsciiString&) = NULL;
535// fp = (void (*)(Draw_Interpretor&, const TCollection_AsciiString&)) f;
536// (*fp) (theDI, theKey);
537
538 void (*fp) (Draw_Interpretor&) = NULL;
539 fp = (void (*)(Draw_Interpretor&)) f;
540 (*fp) (theDI);
541
542}