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