Commit | Line | Data |
---|---|---|
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> | |
aafe169f | 28 | #include <OSD_File.hxx> |
29 | #include <OSD_Process.hxx> | |
7fd59977 | 30 | #include <OSD_SharedLibrary.hxx> |
42cf5bc1 | 31 | #include <OSD_Timer.hxx> |
32 | #include <Plugin_MapOfFunctions.hxx> | |
7fd59977 | 33 | #include <Resource_Manager.hxx> |
7fd59977 | 34 | #include <Standard_ErrorHandler.hxx> |
42cf5bc1 | 35 | #include <Standard_Stream.hxx> |
36 | #include <Standard_Version.hxx> | |
37 | #include <TCollection_AsciiString.hxx> | |
6a0964c2 | 38 | |
39 | #include <tcl.h> | |
6a0964c2 | 40 | // on MSVC, use #pragma to define name of the Tcl library to link with, |
41 | // depending on Tcl version number | |
42 | #ifdef _MSC_VER | |
43 | // two helper macros are needed to convert version number macro to string literal | |
44 | #define STRINGIZE1(a) #a | |
45 | #define STRINGIZE2(a) STRINGIZE1(a) | |
46 | #pragma comment (lib, "tcl" STRINGIZE2(TCL_MAJOR_VERSION) STRINGIZE2(TCL_MINOR_VERSION) ".lib") | |
47 | #pragma comment (lib, "tk" STRINGIZE2(TCL_MAJOR_VERSION) STRINGIZE2(TCL_MINOR_VERSION) ".lib") | |
48 | #undef STRINGIZE2 | |
49 | #undef STRINGIZE1 | |
50 | #endif | |
51 | ||
7fd59977 | 52 | extern Standard_Boolean Draw_ParseFailed; |
7fd59977 | 53 | |
54 | Standard_EXPORT Draw_Viewer dout; | |
55 | Standard_EXPORT Draw_Interpretor theCommands; | |
56 | Standard_EXPORT Standard_Boolean Draw_Batch; | |
57 | Standard_EXPORT Standard_Boolean Draw_Spying = Standard_False; | |
58 | Standard_EXPORT Standard_Boolean Draw_Chrono = Standard_False; | |
59 | Standard_EXPORT Standard_Boolean Draw_VirtualWindows = Standard_False; | |
60 | Standard_EXPORT Standard_Boolean ErrorMessages = Standard_True; | |
61 | ||
62 | static const char* ColorNames[MAXCOLOR] = { | |
63 | "White","Red","Green","Blue","Cyan","Gold","Magenta", | |
64 | "Maroon","Orange","Pink","Salmon","Violet","Yellow","Khaki","Coral" | |
65 | }; | |
66 | ||
67 | filebuf Draw_Spyfile; | |
68 | ||
69 | static ostream spystream(&Draw_Spyfile); | |
70 | ||
7fd59977 | 71 | static Handle(Draw_ProgressIndicator) PInd = NULL; |
72 | ||
bf03eb83 | 73 | Standard_EXPORT Standard_Boolean Draw_Interprete(const char* command); |
7fd59977 | 74 | // true if complete command |
75 | ||
7fd59977 | 76 | // ******************************************************************* |
77 | // read an init file | |
78 | // ******************************************************************* | |
7fd59977 | 79 | |
aafe169f | 80 | static void interpreteTclCommand (const TCollection_AsciiString& theCmd) |
7fd59977 | 81 | { |
57c28b61 | 82 | #ifdef _WIN32 |
ad03c234 | 83 | if (!Draw_Batch) |
84 | { | |
85 | try | |
86 | { | |
aafe169f | 87 | while (console_semaphore == HAS_CONSOLE_COMMAND) |
88 | { | |
89 | Sleep(10); | |
90 | } | |
ad03c234 | 91 | { |
aafe169f | 92 | TCollection_ExtendedString aCmdWide (theCmd); |
9b4243f9 | 93 | wcscpy_s (console_command, aCmdWide.ToWideString()); |
ad03c234 | 94 | } |
7fd59977 | 95 | console_semaphore = HAS_CONSOLE_COMMAND; |
96 | while (console_semaphore == HAS_CONSOLE_COMMAND) | |
ad03c234 | 97 | { |
7fd59977 | 98 | Sleep(10); |
ad03c234 | 99 | } |
7fd59977 | 100 | } |
aafe169f | 101 | catch (...) |
102 | { | |
103 | std::cout << "Error while reading a script file.\n"; | |
7fd59977 | 104 | ExitProcess(0); |
105 | } | |
aafe169f | 106 | } |
107 | else | |
7fd59977 | 108 | #endif |
aafe169f | 109 | { |
110 | Draw_Interprete (theCmd.ToCString()); | |
7fd59977 | 111 | } |
aafe169f | 112 | } |
113 | ||
114 | static void ReadInitFile (const TCollection_AsciiString& theFileName) | |
115 | { | |
116 | TCollection_AsciiString aCmd = theFileName; | |
117 | #ifdef _WIN32 | |
118 | aCmd.ChangeAll ('\\', '/'); | |
7fd59977 | 119 | #endif |
aafe169f | 120 | aCmd = TCollection_AsciiString ("source -encoding utf-8 \"") + aCmd + "\""; |
121 | interpreteTclCommand (aCmd); | |
122 | } | |
123 | ||
124 | //! Define environment variable available from Tcl and OCCT. | |
125 | static void setOcctTclEnv (const TCollection_AsciiString& theName, | |
126 | TCollection_AsciiString& thePath) | |
127 | { | |
128 | if (thePath.IsEmpty()) | |
129 | { | |
130 | return; | |
131 | } | |
132 | ||
133 | thePath.ChangeAll ('\\', '/'); | |
134 | OSD_Environment aRedPathEnv (theName); | |
135 | aRedPathEnv.SetValue (thePath); | |
136 | aRedPathEnv.Build(); | |
137 | ||
138 | const TCollection_AsciiString aPutEnv = theName + "=" + thePath; | |
139 | Tcl_PutEnv (aPutEnv.ToCString()); | |
140 | } | |
141 | ||
142 | //! Look for resource within standard installation layouts relative to executable location. | |
143 | //! | |
144 | //! Bin (INSTALL_DIR_BIN): | |
145 | //! - Windows: <prefix>/win64/vc10/bin(d) | |
146 | //! - Unix: <prefix>/bin | |
147 | //! Resources (INSTALL_DIR_RESOURCE): | |
148 | //! - Windows: <prefix>/src | |
149 | //! - Unix: <prefix>/share/opencascade-7.0.0/resources | |
150 | //! Samples (INSTALL_DIR_SAMPLES): | |
151 | //! - Windows: <prefix>/samples | |
152 | //! - Unix: <prefix>/share/opencascade-7.0.0/samples | |
153 | //! Tests (INSTALL_DIR_TESTS): | |
154 | //! - Windows: <prefix>/tests | |
155 | //! - Unix: <prefix>/share/opencascade-7.0.0/tests | |
156 | //! | |
157 | //! @param theCasRoot [out] found CASROOT location (e.g. installation folder) | |
158 | //! @param theResRoot [out] found resources root location | |
159 | //! @param theResName [in] resource to find ("resources", "samples", etc.) | |
160 | //! @param theProbeFile [in] file to probe within resources location (e.g. "DrawResources/DrawDefault" within "resources") | |
161 | static bool searchResources (TCollection_AsciiString& theCasRoot, | |
162 | TCollection_AsciiString& theResRoot, | |
163 | const TCollection_AsciiString& theResName, | |
164 | const TCollection_AsciiString& theProbeFile) | |
165 | { | |
166 | const TCollection_AsciiString aResLayouts[] = | |
167 | { | |
168 | TCollection_AsciiString("/share/opencascade-" OCC_VERSION_STRING_EXT "/") + theResName, | |
169 | TCollection_AsciiString("/share/opencascade-" OCC_VERSION_COMPLETE "/") + theResName, | |
170 | TCollection_AsciiString("/share/opencascade-" OCC_VERSION_STRING "/") + theResName, | |
171 | TCollection_AsciiString("/share/opencascade/") + theResName, | |
172 | TCollection_AsciiString("/share/occt-" OCC_VERSION_STRING_EXT "/") + theResName, | |
173 | TCollection_AsciiString("/share/occt-" OCC_VERSION_COMPLETE "/") + theResName, | |
174 | TCollection_AsciiString("/share/occt-" OCC_VERSION_STRING "/") + theResName, | |
175 | TCollection_AsciiString("/share/occt/") + theResName, | |
176 | TCollection_AsciiString("/") + theResName, | |
177 | TCollection_AsciiString("/share/opencascade"), | |
178 | TCollection_AsciiString("/share/occt"), | |
179 | TCollection_AsciiString("/share"), | |
180 | TCollection_AsciiString("/src"), | |
181 | TCollection_AsciiString("") | |
182 | }; | |
183 | ||
184 | const TCollection_AsciiString anExeDir (OSD_Process::ExecutableFolder()); | |
185 | for (Standard_Integer aLayIter = 0;; ++aLayIter) | |
186 | { | |
187 | const TCollection_AsciiString& aResLayout = aResLayouts[aLayIter]; | |
188 | const TCollection_AsciiString aProbeFile = aResLayout + "/" + theProbeFile; | |
189 | if (OSD_File (anExeDir + aProbeFile).Exists()) | |
190 | { | |
191 | theCasRoot = anExeDir; | |
192 | theResRoot = theCasRoot + aResLayout; | |
193 | return true; | |
194 | } | |
195 | // <prefix>/bin(d) | |
196 | else if (OSD_File (anExeDir + "../" + aProbeFile).Exists()) | |
197 | { | |
198 | theCasRoot = anExeDir + ".."; | |
199 | theResRoot = theCasRoot + aResLayout; | |
200 | return true; | |
201 | } | |
202 | // <prefix>/gcc/bin(d) | |
203 | else if (OSD_File (anExeDir + "../../" + aProbeFile).Exists()) | |
204 | { | |
205 | theCasRoot = anExeDir + "../.."; | |
206 | theResRoot = theCasRoot + aResLayout; | |
207 | return true; | |
208 | } | |
209 | // <prefix>/win64/vc10/bin(d) | |
210 | else if (OSD_File (anExeDir + "../../../" + aProbeFile).Exists()) | |
211 | { | |
212 | theCasRoot = anExeDir + "../../.."; | |
213 | theResRoot = theCasRoot + aResLayout; | |
214 | return true; | |
215 | } | |
216 | ||
217 | if (aResLayout.IsEmpty()) | |
218 | { | |
219 | return false; | |
220 | } | |
221 | } | |
7fd59977 | 222 | } |
7fd59977 | 223 | |
e59839c8 | 224 | //======================================================================= |
225 | //function : GetInterpretor | |
226 | //purpose : | |
227 | //======================================================================= | |
228 | Draw_Interpretor& Draw::GetInterpretor() | |
229 | { | |
230 | return theCommands; | |
231 | } | |
232 | ||
7fd59977 | 233 | //======================================================================= |
234 | //function : | |
235 | //purpose : Set/Get Progress Indicator | |
236 | //======================================================================= | |
237 | void Draw::SetProgressBar(const Handle(Draw_ProgressIndicator)& thePI) | |
238 | { | |
239 | PInd = thePI; | |
240 | } | |
241 | ||
242 | Handle(Draw_ProgressIndicator) Draw::GetProgressBar() | |
243 | { | |
244 | return PInd; | |
245 | } | |
246 | ||
57c28b61 | 247 | #ifndef _WIN32 |
7fd59977 | 248 | /*--------------------------------------------------------*\ |
249 | | exitProc: finalization handler for Tcl/Tk thread. Forces parent process to die | |
250 | \*--------------------------------------------------------*/ | |
251 | void exitProc(ClientData /*dc*/) | |
252 | { | |
253 | if (!Draw_Batch) { | |
254 | for (Standard_Integer id = 0; id < MAXVIEW; id++) | |
255 | dout.DeleteView(id); | |
256 | } | |
257 | } | |
258 | #endif | |
259 | ||
260 | // ******************************************************************* | |
261 | // main | |
262 | // ******************************************************************* | |
dac04bfa | 263 | #ifdef _WIN32 |
ad03c234 | 264 | Standard_EXPORT void Draw_Appli(HINSTANCE hInst, HINSTANCE hPrevInst, int nShow, int argc, wchar_t** argv, const FDraw_InitAppli Draw_InitAppli) |
7fd59977 | 265 | #else |
ad03c234 | 266 | void Draw_Appli(int argc, char** argv, const FDraw_InitAppli Draw_InitAppli) |
7fd59977 | 267 | #endif |
268 | { | |
dac04bfa | 269 | |
270 | // prepend extra DLL search path to override system libraries like opengl32.dll | |
271 | #ifdef _WIN32 | |
272 | OSD_Environment aUserDllEnv ("CSF_UserDllPath"); | |
ad03c234 | 273 | const TCollection_ExtendedString aUserDllPath (aUserDllEnv.Value()); |
dac04bfa | 274 | if (!aUserDllPath.IsEmpty()) |
275 | { | |
276 | // This function available since Win XP SP1 #if (_WIN32_WINNT >= 0x0502). | |
277 | // We retrieve dynamically here (kernel32 should be always preloaded). | |
ad03c234 | 278 | typedef BOOL (WINAPI *SetDllDirectoryW_t)(const wchar_t* thePathName); |
279 | HMODULE aKern32Module = GetModuleHandleW (L"kernel32"); | |
280 | SetDllDirectoryW_t aFunc = (aKern32Module != NULL) | |
281 | ? (SetDllDirectoryW_t )GetProcAddress (aKern32Module, "SetDllDirectoryW") : NULL; | |
dac04bfa | 282 | if (aFunc != NULL) |
283 | { | |
ad03c234 | 284 | aFunc (aUserDllPath.ToWideString()); |
dac04bfa | 285 | } |
286 | else | |
287 | { | |
ad03c234 | 288 | //std::cerr << "SetDllDirectoryW() is not available on this system!\n"; |
dac04bfa | 289 | } |
290 | if (aKern32Module != NULL) | |
291 | { | |
292 | FreeLibrary (aKern32Module); | |
293 | } | |
294 | } | |
295 | #endif | |
296 | ||
7fd59977 | 297 | // ***************************************************************** |
298 | // analyze arguments | |
299 | // ***************************************************************** | |
300 | Draw_Batch = Standard_False; | |
bf03eb83 | 301 | TCollection_AsciiString aRunFile, aCommand; |
7fd59977 | 302 | Standard_Boolean isInteractiveForced = Standard_False; |
bf03eb83 | 303 | |
bf03eb83 | 304 | // parse command line |
ad03c234 | 305 | for (int anArgIter = 1; anArgIter < argc; ++anArgIter) |
306 | { | |
307 | TCollection_AsciiString anArg (argv[anArgIter]); | |
308 | anArg.LowerCase(); | |
309 | if (anArg == "-h" | |
310 | || anArg == "--help") | |
bf03eb83 | 311 | { |
ad03c234 | 312 | std::cout << "Open CASCADE " << OCC_VERSION_STRING_EXT << " DRAW Test Harness\n\n"; |
313 | std::cout << "Options:\n"; | |
314 | std::cout << " -b: batch mode (no GUI, no viewers)\n"; | |
315 | std::cout << " -v: no GUI, use virtual (off-screen) windows for viewers\n"; | |
316 | std::cout << " -i: interactive mode\n"; | |
317 | std::cout << " -f file: execute script from file\n"; | |
318 | std::cout << " -c command args...: execute command (with optional arguments)\n\n"; | |
319 | std::cout << "Options -b, -v, and -i are mutually exclusive.\n"; | |
320 | std::cout << "If -c or -f are given, -v is default; otherwise default is -i.\n"; | |
321 | std::cout << "Options -c and -f are alternatives and should be at the end \n"; | |
322 | std::cout << "of the command line.\n"; | |
323 | std::cout << "Option -c can accept set of commands separated by ';'.\n"; | |
bf03eb83 | 324 | return; |
7fd59977 | 325 | } |
ad03c234 | 326 | else if (anArg == "-b") |
327 | { | |
bf03eb83 | 328 | Draw_Batch = Standard_True; |
ad03c234 | 329 | } |
330 | else if (anArg == "-v") | |
331 | { | |
7fd59977 | 332 | // force virtual windows |
333 | Draw_VirtualWindows = Standard_True; | |
ad03c234 | 334 | } |
335 | else if (anArg == "-i") | |
336 | { | |
7fd59977 | 337 | // force interactive |
338 | Draw_VirtualWindows = Standard_False; | |
339 | isInteractiveForced = Standard_True; | |
ad03c234 | 340 | } |
341 | else if (anArg == "-f") // -f option should be LAST! | |
342 | { | |
7fd59977 | 343 | Draw_VirtualWindows = !isInteractiveForced; |
ad03c234 | 344 | if (++anArgIter < argc) |
345 | { | |
346 | aRunFile = TCollection_AsciiString (argv[anArgIter]); | |
7fd59977 | 347 | } |
348 | break; | |
ad03c234 | 349 | } |
350 | else if (anArg == "-c") // -c option should be LAST! | |
351 | { | |
7fd59977 | 352 | Draw_VirtualWindows = !isInteractiveForced; |
ad03c234 | 353 | if (++anArgIter < argc) |
354 | { | |
355 | aCommand = TCollection_AsciiString (argv[anArgIter]); | |
bf03eb83 | 356 | } |
ad03c234 | 357 | while (++anArgIter < argc) |
358 | { | |
bf03eb83 | 359 | aCommand.AssignCat (" "); |
ad03c234 | 360 | aCommand.AssignCat (argv[anArgIter]); |
7fd59977 | 361 | } |
362 | break; | |
ad03c234 | 363 | } |
364 | else | |
365 | { | |
366 | std::cout << "Error: unsupported option " << TCollection_AsciiString (argv[anArgIter]) << "\n"; | |
7fd59977 | 367 | } |
368 | } | |
bf03eb83 | 369 | |
7fd59977 | 370 | // ***************************************************************** |
371 | // set signals | |
372 | // ***************************************************************** | |
d538d7a2 | 373 | OSD::SetSignal(Standard_False); |
7fd59977 | 374 | |
bf03eb83 | 375 | #ifdef _WIN32 |
376 | // in interactive mode, force Windows to report dll loading problems interactively | |
377 | if ( ! Draw_VirtualWindows && ! Draw_Batch ) | |
378 | ::SetErrorMode (0); | |
379 | #endif | |
380 | ||
7fd59977 | 381 | // ***************************************************************** |
382 | // init X window and create display | |
383 | // ***************************************************************** | |
57c28b61 | 384 | #ifdef _WIN32 |
1d47d8d0 | 385 | HWND hWnd = NULL; |
7fd59977 | 386 | #endif |
387 | ||
388 | if (!Draw_Batch) | |
57c28b61 | 389 | #ifdef _WIN32 |
bf03eb83 | 390 | Draw_Batch=!Init_Appli(hInst, hPrevInst, nShow, hWnd); |
7fd59977 | 391 | #else |
392 | Draw_Batch=!Init_Appli(); | |
393 | #endif | |
394 | else | |
9b4243f9 | 395 | { |
bf03eb83 | 396 | cout << "DRAW is running in batch mode" << endl; |
9b4243f9 | 397 | theCommands.Init(); |
398 | Tcl_Init(theCommands.Interp()); | |
399 | } | |
7fd59977 | 400 | |
9b4243f9 | 401 | if (! Draw_Batch) |
ad03c234 | 402 | { |
7fd59977 | 403 | // Default colors |
ad03c234 | 404 | for (int i = 0; i < MAXCOLOR; ++i) |
405 | { | |
406 | if (!dout.DefineColor (i, ColorNames[i])) | |
407 | { | |
408 | std::cout <<"Could not allocate default color " << ColorNames[i] << std::endl; | |
409 | } | |
7fd59977 | 410 | } |
411 | } | |
412 | ||
413 | // ***************************************************************** | |
414 | // set maximum precision for cout | |
415 | // ***************************************************************** | |
416 | cout.precision(15); | |
417 | ||
418 | // ***************************************************************** | |
419 | // standard commands | |
420 | // ***************************************************************** | |
421 | Draw::BasicCommands(theCommands); | |
422 | Draw::VariableCommands(theCommands); | |
423 | Draw::UnitCommands(theCommands); | |
424 | if (!Draw_Batch) Draw::GraphicCommands(theCommands); | |
425 | ||
426 | // ***************************************************************** | |
427 | // user commands | |
428 | // ***************************************************************** | |
429 | Draw_InitAppli(theCommands); | |
430 | ||
57c28b61 | 431 | #ifndef _WIN32 |
7fd59977 | 432 | Tcl_CreateExitHandler(exitProc, 0); |
433 | #endif | |
434 | ||
435 | // ***************************************************************** | |
436 | // read init files | |
437 | // ***************************************************************** | |
438 | // default | |
aafe169f | 439 | const TCollection_AsciiString aDrawDef (OSD_Environment ("DRAWDEFAULT").Value()); |
440 | if (!aDrawDef.IsEmpty()) | |
441 | { | |
442 | ReadInitFile (aDrawDef); | |
443 | } | |
444 | else | |
7fd59977 | 445 | { |
aafe169f | 446 | TCollection_AsciiString aDrawHome; |
447 | TCollection_AsciiString aCasRoot (OSD_Environment ("CASROOT").Value()); | |
448 | if (!aCasRoot.IsEmpty()) | |
449 | { | |
450 | aDrawHome = aCasRoot + "/src/DrawResources"; | |
451 | } | |
452 | else | |
453 | { | |
454 | // search for relative locations within standard development environment | |
455 | TCollection_AsciiString aResPath; | |
456 | if (searchResources (aCasRoot, aResPath, "resources", "DrawResources/DrawDefault")) | |
457 | { | |
458 | aDrawHome = aResPath + "/DrawResources"; | |
459 | setOcctTclEnv ("CASROOT", aCasRoot); | |
460 | setOcctTclEnv ("DRAWHOME", aDrawHome); | |
461 | setOcctTclEnv ("CSF_OCCTResourcePath", aResPath); | |
462 | } | |
463 | ||
464 | TCollection_AsciiString aSamplesPath; | |
465 | if (OSD_Environment ("CSF_OCCTSamplesPath").Value().IsEmpty() | |
466 | && searchResources (aCasRoot, aSamplesPath, "samples", "tcl/Readme.txt")) | |
467 | { | |
468 | setOcctTclEnv ("CSF_OCCTSamplesPath", aSamplesPath); | |
469 | } | |
470 | ||
471 | TCollection_AsciiString aTestsPath; | |
472 | if (OSD_Environment ("CSF_TestScriptsPath").Value().IsEmpty() | |
473 | && searchResources (aCasRoot, aTestsPath, "tests", "parse.rules")) | |
474 | { | |
475 | setOcctTclEnv ("CSF_TestScriptsPath", aTestsPath); | |
476 | } | |
477 | } | |
478 | ||
479 | if (!aDrawHome.IsEmpty()) | |
480 | { | |
481 | const TCollection_AsciiString aDefStr = aDrawHome + "/DrawDefault"; | |
482 | ReadInitFile (aDefStr); | |
483 | } | |
484 | else | |
7fd59977 | 485 | { |
57c28b61 | 486 | #ifdef _WIN32 |
86be4295 | 487 | ReadInitFile ("ddefault"); |
7fd59977 | 488 | #else |
86be4295 A |
489 | cout << " the CASROOT variable is mandatory to Run OpenCascade "<< endl; |
490 | cout << "No default file" << endl; | |
7fd59977 | 491 | #endif |
492 | } | |
7fd59977 | 493 | } |
494 | ||
bf03eb83 | 495 | // read commands from file |
86be4295 | 496 | if (!aRunFile.IsEmpty()) { |
bf03eb83 | 497 | ReadInitFile (aRunFile); |
498 | // provide a clean exit, this is useful for some analysis tools | |
499 | if ( ! isInteractiveForced ) | |
57c28b61 | 500 | #ifndef _WIN32 |
bf03eb83 | 501 | return; |
502 | #else | |
503 | ExitProcess(0); | |
7fd59977 | 504 | #endif |
bf03eb83 | 505 | } |
7fd59977 | 506 | |
bf03eb83 | 507 | // execute command from command line |
9b4243f9 | 508 | if (!aCommand.IsEmpty()) |
509 | { | |
510 | #ifdef _WIN32 | |
511 | if (!Draw_Batch) | |
512 | { | |
513 | // on Windows except batch mode, commands are executed in separate thread | |
514 | while (console_semaphore == HAS_CONSOLE_COMMAND) Sleep(10); | |
515 | TCollection_ExtendedString aCmdWide(aCommand); | |
516 | wcscpy_s(console_command, aCmdWide.ToWideString()); | |
517 | console_semaphore = HAS_CONSOLE_COMMAND; | |
518 | while (console_semaphore == HAS_CONSOLE_COMMAND) Sleep(10); | |
519 | } | |
520 | else | |
521 | #endif | |
522 | Draw_Interprete (aCommand.ToCString()); // Linux and Windows batch mode | |
bf03eb83 | 523 | // provide a clean exit, this is useful for some analysis tools |
524 | if ( ! isInteractiveForced ) | |
57c28b61 | 525 | #ifndef _WIN32 |
bf03eb83 | 526 | return; |
7fd59977 | 527 | #else |
bf03eb83 | 528 | ExitProcess(0); |
7fd59977 | 529 | #endif |
530 | } | |
531 | ||
532 | // ***************************************************************** | |
533 | // X loop | |
534 | // ***************************************************************** | |
9b4243f9 | 535 | if (! Draw_Batch) { |
57c28b61 | 536 | #ifdef _WIN32 |
bf03eb83 | 537 | Run_Appli(hWnd); |
7fd59977 | 538 | #else |
539 | Run_Appli(Draw_Interprete); | |
540 | #endif | |
541 | } | |
542 | else | |
543 | { | |
9b4243f9 | 544 | const int MAXCMD = 2048; |
545 | char cmd[MAXCMD]; | |
546 | for (int ncmd = 1;; ++ncmd) | |
dde68833 | 547 | { |
9b4243f9 | 548 | cout << "Draw[" << ncmd << "]> "; |
549 | if (cin.getline (cmd, MAXCMD).fail()) | |
550 | { | |
551 | break; | |
552 | } | |
dde68833 | 553 | Draw_Interprete(cmd); |
554 | } | |
7fd59977 | 555 | } |
57c28b61 | 556 | #ifdef _WIN32 |
7fd59977 | 557 | // Destruction de l'application |
558 | Destroy_Appli(hInst); | |
559 | #endif | |
560 | } | |
561 | //#endif | |
562 | ||
563 | // User functions called before and after each command | |
564 | void (*Draw_BeforeCommand)() = NULL; | |
565 | void (*Draw_AfterCommand)(Standard_Integer) = NULL; | |
566 | ||
bf03eb83 | 567 | Standard_Boolean Draw_Interprete(const char* com) |
7fd59977 | 568 | { |
569 | ||
570 | static Standard_Boolean first = Standard_True; | |
571 | static Tcl_DString command; | |
572 | ||
573 | if (first) { | |
574 | first = Standard_False; | |
575 | Tcl_DStringInit(&command); | |
576 | } | |
577 | ||
ad03c234 | 578 | #ifdef _WIN32 |
579 | // string is already converted into UTF-8 | |
580 | Tcl_DStringAppend(&command, com, -1); | |
581 | #elif ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 1))) | |
7fd59977 | 582 | // OCC63: Since Tcl 8.1 it uses UTF-8 encoding for internal representation of strings |
583 | Tcl_ExternalToUtfDString ( NULL, com, -1, &command ); | |
584 | #else | |
585 | Tcl_DStringAppend(&command,com,-1); | |
586 | #endif | |
587 | ||
588 | if (!theCommands.Complete(Tcl_DStringValue(&command))) | |
589 | return Standard_False; | |
590 | ||
591 | // ******************************************************************* | |
592 | // Command interpreter | |
593 | // ******************************************************************* | |
594 | ||
595 | // Standard_Integer i = 0; | |
596 | // Standard_Integer j = 0; | |
597 | ||
598 | Standard_Boolean wasspying = Draw_Spying; | |
599 | ||
600 | OSD_Timer tictac; | |
601 | Standard_Boolean hadchrono = Draw_Chrono; | |
602 | if (hadchrono) tictac.Start(); | |
603 | ||
604 | if (Draw_BeforeCommand) (*Draw_BeforeCommand) (); | |
605 | ||
606 | Standard_Integer c; | |
607 | ||
608 | c = theCommands.RecordAndEval(Tcl_DStringValue(&command)); | |
609 | ||
610 | if (Draw_AfterCommand) (*Draw_AfterCommand)(c); | |
611 | ||
612 | if (wasspying && Draw_Spying) { | |
613 | if (c > 0) spystream << "# "; | |
614 | spystream << Tcl_DStringValue(&command) << "\n"; | |
615 | } | |
616 | ||
617 | dout.Flush(); | |
618 | ||
619 | if (*theCommands.Result()) | |
ad03c234 | 620 | { |
621 | #ifdef _WIN32 | |
622 | const TCollection_ExtendedString aResWide (theCommands.Result()); | |
623 | std::wcout << aResWide.ToWideString() << std::endl; | |
624 | #else | |
625 | std::cout << theCommands.Result() << std::endl; | |
626 | #endif | |
627 | } | |
7fd59977 | 628 | |
629 | if (Draw_Chrono && hadchrono) { | |
630 | tictac.Stop(); | |
631 | tictac.Show(); | |
632 | } | |
633 | ||
634 | Tcl_DStringFree(&command); | |
635 | ||
636 | return Standard_True; | |
637 | } | |
638 | ||
639 | // | |
640 | // for TCl | |
641 | // | |
642 | ||
643 | Standard_Integer Tcl_AppInit (Tcl_Interp *) | |
644 | { | |
645 | return 0; | |
646 | } | |
647 | ||
648 | // | |
649 | // for debug call | |
650 | // | |
651 | ||
652 | ||
653 | ||
654 | Standard_Integer Draw_Call (char *c) | |
655 | { | |
656 | Standard_Integer r = theCommands.Eval(c); | |
657 | cout << theCommands.Result() << endl; | |
658 | return r; | |
659 | } | |
660 | ||
7fd59977 | 661 | //================================================================================= |
662 | // | |
663 | //================================================================================= | |
664 | void Draw::Load(Draw_Interpretor& theDI, const TCollection_AsciiString& theKey, | |
665 | const TCollection_AsciiString& theResourceFileName, | |
666 | TCollection_AsciiString& theDefaultsDirectory, | |
667 | TCollection_AsciiString& theUserDefaultsDirectory, | |
668 | const Standard_Boolean Verbose ) { | |
669 | ||
97385d61 | 670 | static Plugin_MapOfFunctions theMapOfFunctions; |
7fd59977 | 671 | OSD_Function f; |
672 | ||
673 | if(!theMapOfFunctions.IsBound(theKey)) { | |
674 | ||
675 | Handle(Resource_Manager) aPluginResource = new Resource_Manager(theResourceFileName.ToCString(), theDefaultsDirectory, theUserDefaultsDirectory, Verbose); | |
676 | ||
677 | if(!aPluginResource->Find(theKey.ToCString())) { | |
678 | Standard_SStream aMsg; aMsg << "Could not find the resource:"; | |
679 | aMsg << theKey.ToCString()<< endl; | |
680 | cout << "could not find the resource:"<<theKey.ToCString()<< endl; | |
9775fa61 | 681 | throw Draw_Failure(aMsg.str().c_str()); |
7fd59977 | 682 | } |
683 | ||
684 | TCollection_AsciiString aPluginLibrary(""); | |
7c65581d | 685 | #if !defined(_WIN32) || defined(__MINGW32__) |
7fd59977 | 686 | aPluginLibrary += "lib"; |
687 | #endif | |
688 | aPluginLibrary += aPluginResource->Value(theKey.ToCString()); | |
57c28b61 | 689 | #ifdef _WIN32 |
7fd59977 | 690 | aPluginLibrary += ".dll"; |
691 | #elif __APPLE__ | |
692 | aPluginLibrary += ".dylib"; | |
693 | #elif defined (HPUX) || defined(_hpux) | |
694 | aPluginLibrary += ".sl"; | |
695 | #else | |
696 | aPluginLibrary += ".so"; | |
697 | #endif | |
698 | OSD_SharedLibrary aSharedLibrary(aPluginLibrary.ToCString()); | |
699 | if(!aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) { | |
700 | TCollection_AsciiString error(aSharedLibrary.DlError()); | |
701 | Standard_SStream aMsg; aMsg << "Could not open: "; | |
702 | aMsg << aPluginResource->Value(theKey.ToCString()); | |
703 | aMsg << "; reason: "; | |
704 | aMsg << error.ToCString(); | |
0797d9d3 | 705 | #ifdef OCCT_DEBUG |
7fd59977 | 706 | cout << "could not open: " << aPluginResource->Value(theKey.ToCString())<< " ; reason: "<< error.ToCString() << endl; |
707 | #endif | |
9775fa61 | 708 | throw Draw_Failure(aMsg.str().c_str()); |
7fd59977 | 709 | } |
710 | f = aSharedLibrary.DlSymb("PLUGINFACTORY"); | |
711 | if( f == NULL ) { | |
712 | TCollection_AsciiString error(aSharedLibrary.DlError()); | |
713 | Standard_SStream aMsg; aMsg << "Could not find the factory in: "; | |
714 | aMsg << aPluginResource->Value(theKey.ToCString()); | |
715 | aMsg << error.ToCString(); | |
9775fa61 | 716 | throw Draw_Failure(aMsg.str().c_str()); |
7fd59977 | 717 | } |
718 | theMapOfFunctions.Bind(theKey, f); | |
719 | } | |
720 | else | |
721 | f = theMapOfFunctions(theKey); | |
722 | ||
723 | // void (*fp) (Draw_Interpretor&, const TCollection_AsciiString&) = NULL; | |
724 | // fp = (void (*)(Draw_Interpretor&, const TCollection_AsciiString&)) f; | |
725 | // (*fp) (theDI, theKey); | |
726 | ||
727 | void (*fp) (Draw_Interpretor&) = NULL; | |
728 | fp = (void (*)(Draw_Interpretor&)) f; | |
729 | (*fp) (theDI); | |
730 | ||
731 | } |