0031171: Draw - support Unicode input / output in console on Windows
[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>
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 55extern Standard_Boolean Draw_ParseFailed;
7fd59977 56
57Standard_EXPORT Draw_Viewer dout;
58Standard_EXPORT Draw_Interpretor theCommands;
59Standard_EXPORT Standard_Boolean Draw_Batch;
60Standard_EXPORT Standard_Boolean Draw_Spying = Standard_False;
61Standard_EXPORT Standard_Boolean Draw_Chrono = Standard_False;
62Standard_EXPORT Standard_Boolean Draw_VirtualWindows = Standard_False;
63Standard_EXPORT Standard_Boolean ErrorMessages = Standard_True;
64
65static const char* ColorNames[MAXCOLOR] = {
66 "White","Red","Green","Blue","Cyan","Gold","Magenta",
67 "Maroon","Orange","Pink","Salmon","Violet","Yellow","Khaki","Coral"
68 };
69
04232180 70std::filebuf Draw_Spyfile;
7fd59977 71
04232180 72static std::ostream spystream(&Draw_Spyfile);
7fd59977 73
7fd59977 74static Handle(Draw_ProgressIndicator) PInd = NULL;
75
bf03eb83 76Standard_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 83static 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
117static 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.
128static 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")
164static 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//=======================================================================
231Draw_Interpretor& Draw::GetInterpretor()
232{
233 return theCommands;
234}
235
7fd59977 236//=======================================================================
237//function :
238//purpose : Set/Get Progress Indicator
239//=======================================================================
240void Draw::SetProgressBar(const Handle(Draw_ProgressIndicator)& thePI)
241{
242 PInd = thePI;
243}
244
245Handle(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\*--------------------------------------------------------*/
254void 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 267Standard_EXPORT void Draw_Appli(HINSTANCE hInst, HINSTANCE hPrevInst, int nShow, int argc, wchar_t** argv, const FDraw_InitAppli Draw_InitAppli)
7fd59977 268#else
ad03c234 269void 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
567void (*Draw_BeforeCommand)() = NULL;
568void (*Draw_AfterCommand)(Standard_Integer) = NULL;
569
bf03eb83 570Standard_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 {
ad03c234 624 std::cout << theCommands.Result() << std::endl;
ad03c234 625 }
7fd59977 626
627 if (Draw_Chrono && hadchrono) {
628 tictac.Stop();
629 tictac.Show();
630 }
631
632 Tcl_DStringFree(&command);
633
634 return Standard_True;
635}
636
637//
638// for TCl
639//
640
641Standard_Integer Tcl_AppInit (Tcl_Interp *)
642{
643 return 0;
644}
645
646//
647// for debug call
648//
649
650
651
652Standard_Integer Draw_Call (char *c)
653{
654 Standard_Integer r = theCommands.Eval(c);
04232180 655 std::cout << theCommands.Result() << std::endl;
7fd59977 656 return r;
657}
658
7fd59977 659//=================================================================================
660//
661//=================================================================================
662void Draw::Load(Draw_Interpretor& theDI, const TCollection_AsciiString& theKey,
663 const TCollection_AsciiString& theResourceFileName,
664 TCollection_AsciiString& theDefaultsDirectory,
665 TCollection_AsciiString& theUserDefaultsDirectory,
666 const Standard_Boolean Verbose ) {
667
97385d61 668 static Plugin_MapOfFunctions theMapOfFunctions;
7fd59977 669 OSD_Function f;
670
671 if(!theMapOfFunctions.IsBound(theKey)) {
672
673 Handle(Resource_Manager) aPluginResource = new Resource_Manager(theResourceFileName.ToCString(), theDefaultsDirectory, theUserDefaultsDirectory, Verbose);
674
675 if(!aPluginResource->Find(theKey.ToCString())) {
676 Standard_SStream aMsg; aMsg << "Could not find the resource:";
04232180 677 aMsg << theKey.ToCString()<< std::endl;
678 std::cout << "could not find the resource:"<<theKey.ToCString()<< std::endl;
9775fa61 679 throw Draw_Failure(aMsg.str().c_str());
7fd59977 680 }
681
682 TCollection_AsciiString aPluginLibrary("");
7c65581d 683#if !defined(_WIN32) || defined(__MINGW32__)
7fd59977 684 aPluginLibrary += "lib";
685#endif
686 aPluginLibrary += aPluginResource->Value(theKey.ToCString());
57c28b61 687#ifdef _WIN32
7fd59977 688 aPluginLibrary += ".dll";
689#elif __APPLE__
690 aPluginLibrary += ".dylib";
691#elif defined (HPUX) || defined(_hpux)
692 aPluginLibrary += ".sl";
693#else
694 aPluginLibrary += ".so";
695#endif
696 OSD_SharedLibrary aSharedLibrary(aPluginLibrary.ToCString());
697 if(!aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) {
698 TCollection_AsciiString error(aSharedLibrary.DlError());
699 Standard_SStream aMsg; aMsg << "Could not open: ";
700 aMsg << aPluginResource->Value(theKey.ToCString());
701 aMsg << "; reason: ";
702 aMsg << error.ToCString();
0797d9d3 703#ifdef OCCT_DEBUG
04232180 704 std::cout << "could not open: " << aPluginResource->Value(theKey.ToCString())<< " ; reason: "<< error.ToCString() << std::endl;
7fd59977 705#endif
9775fa61 706 throw Draw_Failure(aMsg.str().c_str());
7fd59977 707 }
708 f = aSharedLibrary.DlSymb("PLUGINFACTORY");
709 if( f == NULL ) {
710 TCollection_AsciiString error(aSharedLibrary.DlError());
711 Standard_SStream aMsg; aMsg << "Could not find the factory in: ";
712 aMsg << aPluginResource->Value(theKey.ToCString());
713 aMsg << error.ToCString();
9775fa61 714 throw Draw_Failure(aMsg.str().c_str());
7fd59977 715 }
716 theMapOfFunctions.Bind(theKey, f);
717 }
718 else
719 f = theMapOfFunctions(theKey);
720
721// void (*fp) (Draw_Interpretor&, const TCollection_AsciiString&) = NULL;
722// fp = (void (*)(Draw_Interpretor&, const TCollection_AsciiString&)) f;
723// (*fp) (theDI, theKey);
724
725 void (*fp) (Draw_Interpretor&) = NULL;
726 fp = (void (*)(Draw_Interpretor&)) f;
727 (*fp) (theDI);
728
729}