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