7fd59977 |
1 | // File: Draw.cxx |
2 | // Created: Fri Aug 13 09:22:06 1993 |
3 | // Author: Bruno DUMORTIER |
4 | // <dub@phylox> |
5 | |
6 | #ifdef HAVE_CONFIG_H |
7 | # include <config.h> |
8 | #endif |
9 | |
10 | #include <Draw.ixx> |
11 | |
12 | #if defined(HAVE_TIME_H) || defined(WNT) |
13 | # include <time.h> |
14 | #endif |
15 | |
16 | #include <Draw_Appli.hxx> |
17 | #include <OSD.hxx> |
18 | #include <OSD_Timer.hxx> |
19 | |
20 | #ifdef HAVE_SYS_TIME_H |
21 | # include <sys/time.h> |
22 | #endif |
23 | |
24 | #ifdef HAVE_SYS_TYPES_H |
25 | # include <sys/types.h> |
26 | #endif |
27 | |
28 | #ifdef HAVE_UNISTD_H |
29 | # include <unistd.h> |
30 | #endif |
31 | |
32 | #ifdef HAVE_STRINGS_H |
33 | # include <strings.h> |
34 | #endif |
35 | |
36 | |
37 | #include <Draw_Window.hxx> |
38 | #include <gp_Pnt2d.hxx> |
39 | |
40 | #include <Standard_Stream.hxx> |
41 | |
42 | #include <Draw_Drawable3D.hxx> |
43 | #include <Draw_Interpretor.hxx> |
44 | #include <Draw_ProgressIndicator.hxx> |
45 | #include <tcl.h> |
46 | |
47 | #include <Draw_MapOfFunctions.hxx> |
48 | #include <OSD_SharedLibrary.hxx> |
49 | #include <Resource_Manager.hxx> |
50 | #include <Draw_Failure.hxx> |
51 | #include <TCollection_AsciiString.hxx> |
52 | #include <Standard_ErrorHandler.hxx> |
53 | extern Standard_Boolean Draw_ParseFailed; |
54 | #ifndef WNT |
55 | extern Standard_Boolean Draw_LowWindows; |
56 | #endif |
57 | |
58 | Standard_EXPORT Draw_Viewer dout; |
59 | Standard_EXPORT Draw_Interpretor theCommands; |
60 | Standard_EXPORT Standard_Boolean Draw_Batch; |
61 | Standard_EXPORT Standard_Boolean Draw_Spying = Standard_False; |
62 | Standard_EXPORT Standard_Boolean Draw_Chrono = Standard_False; |
63 | Standard_EXPORT Standard_Boolean Draw_VirtualWindows = Standard_False; |
64 | Standard_EXPORT Standard_Boolean ErrorMessages = Standard_True; |
65 | |
66 | static const char* ColorNames[MAXCOLOR] = { |
67 | "White","Red","Green","Blue","Cyan","Gold","Magenta", |
68 | "Maroon","Orange","Pink","Salmon","Violet","Yellow","Khaki","Coral" |
69 | }; |
70 | |
71 | filebuf Draw_Spyfile; |
72 | |
73 | static ostream spystream(&Draw_Spyfile); |
74 | |
75 | static Standard_Boolean XLoop; |
76 | |
77 | static Handle(Draw_ProgressIndicator) PInd = NULL; |
78 | |
79 | Standard_EXPORT Standard_Boolean Draw_Interprete(char* command); |
80 | // true if complete command |
81 | |
82 | //#ifndef WNT |
83 | |
84 | // ******************************************************************* |
85 | // read an init file |
86 | // ******************************************************************* |
87 | #ifdef WNT |
88 | extern console_semaphore_value volatile console_semaphore; |
89 | extern char console_command[1000]; |
90 | #endif |
91 | |
92 | static void ReadInitFile(char* filename) |
93 | { |
94 | #ifdef WNT |
95 | if (!Draw_Batch) { |
96 | try { |
97 | OCC_CATCH_SIGNALS |
98 | for(Standard_Integer i = 0; filename[i] != 0; i++) |
99 | if(filename[i] == '\\') filename[i] = '/'; |
100 | sprintf(console_command,"source \"%s\"",filename); |
101 | console_semaphore = HAS_CONSOLE_COMMAND; |
102 | while (console_semaphore == HAS_CONSOLE_COMMAND) |
103 | Sleep(10); |
104 | } |
105 | catch(...) { |
106 | cout << "Error while reading a script file." << endl; |
107 | ExitProcess(0); |
108 | } |
109 | } else { |
110 | #endif |
111 | char* com = new char [strlen(filename)+strlen("source ")+2]; |
112 | sprintf(com,"source %s",filename); |
113 | Draw_Interprete(com); |
114 | delete [] com; |
115 | #ifdef WNT |
116 | } |
117 | #endif |
118 | } |
119 | //#endif |
120 | |
121 | //======================================================================= |
122 | //function : |
123 | //purpose : Set/Get Progress Indicator |
124 | //======================================================================= |
125 | void Draw::SetProgressBar(const Handle(Draw_ProgressIndicator)& thePI) |
126 | { |
127 | PInd = thePI; |
128 | } |
129 | |
130 | Handle(Draw_ProgressIndicator) Draw::GetProgressBar() |
131 | { |
132 | return PInd; |
133 | } |
134 | |
135 | #ifndef WNT |
136 | /*--------------------------------------------------------*\ |
137 | | exitProc: finalization handler for Tcl/Tk thread. Forces parent process to die |
138 | \*--------------------------------------------------------*/ |
139 | void exitProc(ClientData /*dc*/) |
140 | { |
141 | if (!Draw_Batch) { |
142 | for (Standard_Integer id = 0; id < MAXVIEW; id++) |
143 | dout.DeleteView(id); |
144 | } |
145 | } |
146 | #endif |
147 | |
148 | // ******************************************************************* |
149 | // main |
150 | // ******************************************************************* |
151 | #ifdef WNT |
152 | //Standard_EXPORT void Draw_Appli(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lps |
153 | Standard_EXPORT void Draw_Appli(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszLine, int nShow,const FDraw_InitAppli Draw_InitAppli) |
154 | #else |
155 | void Draw_Appli(Standard_Integer argc, char** argv,const FDraw_InitAppli Draw_InitAppli) |
156 | #endif |
157 | { |
158 | // ***************************************************************** |
159 | // analyze arguments |
160 | // ***************************************************************** |
161 | Draw_Batch = Standard_False; |
162 | char* runfile = NULL; |
163 | Standard_Integer i; |
164 | Standard_Boolean isInteractiveForced = Standard_False; |
165 | #ifndef WNT |
166 | for (i = 0; i < argc; i++) { |
167 | if (strcasecmp(argv[i],"-b") == 0) |
168 | Draw_Batch = Standard_True; |
169 | # ifndef __sgi |
170 | else if (strcasecmp(argv[i],"-l") == 0) { |
171 | Draw_LowWindows = Standard_True; |
172 | } |
173 | # endif |
174 | else if (strcasecmp(argv[i],"-v") == 0) { |
175 | // force virtual windows |
176 | Draw_VirtualWindows = Standard_True; |
177 | } else if (strcasecmp(argv[i],"-i") == 0) { |
178 | // force interactive |
179 | Draw_VirtualWindows = Standard_False; |
180 | isInteractiveForced = Standard_True; |
181 | } else if (strcasecmp(argv[i],"-f") == 0) { // -f option should be LAST! |
182 | Draw_VirtualWindows = !isInteractiveForced; |
183 | if (++i < argc) { |
184 | runfile = argv[i]; |
185 | } |
186 | break; |
187 | } |
188 | } |
189 | #else |
190 | // On NT command line arguments are in the lpzline and not in argv |
191 | for (char* p = strtok(lpszLine, " \t"); p != NULL; p = strtok(NULL, " \t")) { |
192 | if (strcasecmp(p, "-v") == 0) { |
193 | Draw_VirtualWindows = Standard_True; |
194 | } else if (strcasecmp(p, "-i") == 0) { |
195 | // force interactive |
196 | Draw_VirtualWindows = Standard_False; |
197 | isInteractiveForced = Standard_True; |
198 | } else if (strcasecmp(p, "-f") == 0) { // -f option should be LAST! |
199 | Draw_VirtualWindows = !isInteractiveForced; |
200 | p = strtok(NULL," \t"); |
201 | if (p != NULL) { |
202 | runfile = p; |
203 | } |
204 | break; |
205 | } |
206 | } |
207 | #endif |
208 | // ***************************************************************** |
209 | // set signals |
210 | // ***************************************************************** |
211 | OSD::SetSignal(); |
212 | |
213 | // ***************************************************************** |
214 | // init X window and create display |
215 | // ***************************************************************** |
216 | #ifdef WNT |
217 | HWND hWnd; |
218 | #endif |
219 | |
220 | if (!Draw_Batch) |
221 | #ifdef WNT |
222 | Draw_Batch=!Init_Appli(hInst, hPrevInst, nShow, hWnd); |
223 | #else |
224 | Draw_Batch=!Init_Appli(); |
225 | #endif |
226 | else |
227 | cout << "batch mode" << endl; |
228 | |
229 | XLoop = !Draw_Batch; |
230 | if (XLoop) { |
231 | // Default colors |
232 | for (i=0;i<MAXCOLOR;i++) { |
233 | if (!dout.DefineColor(i,ColorNames[i])) |
234 | cout <<"Could not allocate default color "<<ColorNames[i]<<endl; |
235 | } |
236 | } |
237 | |
238 | // ***************************************************************** |
239 | // set maximum precision for cout |
240 | // ***************************************************************** |
241 | cout.precision(15); |
242 | |
243 | // ***************************************************************** |
244 | // standard commands |
245 | // ***************************************************************** |
246 | Draw::BasicCommands(theCommands); |
247 | Draw::VariableCommands(theCommands); |
248 | Draw::UnitCommands(theCommands); |
249 | if (!Draw_Batch) Draw::GraphicCommands(theCommands); |
250 | |
251 | // ***************************************************************** |
252 | // user commands |
253 | // ***************************************************************** |
254 | Draw_InitAppli(theCommands); |
255 | |
256 | #ifndef WNT |
257 | Tcl_CreateExitHandler(exitProc, 0); |
258 | #endif |
259 | |
260 | // ***************************************************************** |
261 | // read init files |
262 | // ***************************************************************** |
263 | // default |
264 | char* dflt = getenv("DRAWDEFAULT"); |
265 | if (dflt == NULL) |
266 | { |
267 | char* casroot = getenv("CASROOT"); |
268 | if (casroot == NULL) |
269 | { |
270 | #ifdef WNT |
271 | ReadInitFile("ddefault"); |
272 | #else |
273 | cout << " the CASROOT variable is mandatory to Run OpenCascade "<< endl; |
274 | cout << "No default file" << endl; |
275 | #endif |
276 | } |
277 | else |
278 | { |
279 | char* thedefault = (char *) malloc (128); |
280 | thedefault[0] = '\0'; |
281 | strcat(thedefault,casroot); |
282 | strcat (thedefault,"/src/DrawResources/DrawDefault"); |
283 | ReadInitFile(thedefault); |
284 | } |
285 | } |
286 | else |
287 | { |
288 | ReadInitFile(dflt); |
289 | } |
290 | |
291 | // pure batch |
292 | if (runfile) { |
293 | // do not map raise the windows, so test programs are discrete |
294 | #ifndef WNT |
295 | Draw_LowWindows = Standard_True; |
296 | #endif |
297 | // comme on ne peut pas photographier les fenetres trop discretes sur sgi |
298 | // on se met en vedette !! (pmn 20/02/97) |
299 | #ifdef __sgi |
300 | Draw_LowWindows = Standard_False; |
301 | #endif |
302 | |
303 | ReadInitFile(runfile); |
304 | // provide a clean exit, this is usefull for some analysis tools |
305 | #ifndef WNT |
306 | return; |
307 | #else |
308 | ExitProcess(0); |
309 | #endif |
310 | } |
311 | |
312 | // ***************************************************************** |
313 | // X loop |
314 | // ***************************************************************** |
315 | if (XLoop) { |
316 | #ifdef WNT |
317 | Run_Appli(hWnd); |
318 | #else |
319 | Run_Appli(Draw_Interprete); |
320 | #endif |
321 | } |
322 | else |
323 | { |
324 | char cmd[255]; |
325 | do { |
326 | cout << "Viewer>"; |
327 | i = -1; |
328 | do { |
329 | cin.get(cmd[++i]); |
330 | } while ((cmd[i] != '\n') && (!cin.fail())); |
331 | cmd[i] = '\0'; |
332 | } while (Draw_Interprete(cmd) != (unsigned int ) -2); |
333 | } |
334 | #ifdef WNT |
335 | // Destruction de l'application |
336 | Destroy_Appli(hInst); |
337 | #endif |
338 | } |
339 | //#endif |
340 | |
341 | // User functions called before and after each command |
342 | void (*Draw_BeforeCommand)() = NULL; |
343 | void (*Draw_AfterCommand)(Standard_Integer) = NULL; |
344 | |
345 | Standard_Boolean Draw_Interprete(char* com) |
346 | { |
347 | |
348 | static Standard_Boolean first = Standard_True; |
349 | static Tcl_DString command; |
350 | |
351 | if (first) { |
352 | first = Standard_False; |
353 | Tcl_DStringInit(&command); |
354 | } |
355 | |
356 | #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 1))) |
357 | // OCC63: Since Tcl 8.1 it uses UTF-8 encoding for internal representation of strings |
358 | Tcl_ExternalToUtfDString ( NULL, com, -1, &command ); |
359 | #else |
360 | Tcl_DStringAppend(&command,com,-1); |
361 | #endif |
362 | |
363 | if (!theCommands.Complete(Tcl_DStringValue(&command))) |
364 | return Standard_False; |
365 | |
366 | // ******************************************************************* |
367 | // Command interpreter |
368 | // ******************************************************************* |
369 | |
370 | // Standard_Integer i = 0; |
371 | // Standard_Integer j = 0; |
372 | |
373 | Standard_Boolean wasspying = Draw_Spying; |
374 | |
375 | OSD_Timer tictac; |
376 | Standard_Boolean hadchrono = Draw_Chrono; |
377 | if (hadchrono) tictac.Start(); |
378 | |
379 | if (Draw_BeforeCommand) (*Draw_BeforeCommand) (); |
380 | |
381 | Standard_Integer c; |
382 | |
383 | c = theCommands.RecordAndEval(Tcl_DStringValue(&command)); |
384 | |
385 | if (Draw_AfterCommand) (*Draw_AfterCommand)(c); |
386 | |
387 | if (wasspying && Draw_Spying) { |
388 | if (c > 0) spystream << "# "; |
389 | spystream << Tcl_DStringValue(&command) << "\n"; |
390 | } |
391 | |
392 | dout.Flush(); |
393 | |
394 | if (*theCommands.Result()) |
395 | cout << theCommands.Result() << endl; |
396 | |
397 | if (Draw_Chrono && hadchrono) { |
398 | tictac.Stop(); |
399 | tictac.Show(); |
400 | } |
401 | |
402 | Tcl_DStringFree(&command); |
403 | |
404 | return Standard_True; |
405 | } |
406 | |
407 | // |
408 | // for TCl |
409 | // |
410 | |
411 | Standard_Integer Tcl_AppInit (Tcl_Interp *) |
412 | { |
413 | return 0; |
414 | } |
415 | |
416 | // |
417 | // for debug call |
418 | // |
419 | |
420 | |
421 | |
422 | Standard_Integer Draw_Call (char *c) |
423 | { |
424 | Standard_Integer r = theCommands.Eval(c); |
425 | cout << theCommands.Result() << endl; |
426 | return r; |
427 | } |
428 | |
429 | |
430 | //================================================================================= |
431 | // |
432 | //================================================================================= |
433 | void Draw::Load(Draw_Interpretor& theDI, const TCollection_AsciiString& theKey, |
434 | const TCollection_AsciiString& theResourceFileName) { |
435 | |
436 | static Draw_MapOfFunctions theMapOfFunctions; |
437 | OSD_Function f; |
438 | |
439 | if(!theMapOfFunctions.IsBound(theKey)) { |
440 | |
441 | Handle(Resource_Manager) aPluginResource = new Resource_Manager(theResourceFileName.ToCString()); |
442 | if(!aPluginResource->Find(theKey.ToCString())) { |
443 | Standard_SStream aMsg; aMsg << "Could not find the resource:"; |
444 | aMsg << theKey.ToCString()<< endl; |
445 | cout << "could not find the resource:"<<theKey.ToCString()<< endl; |
446 | Draw_Failure::Raise(aMsg); |
447 | } |
448 | |
449 | TCollection_AsciiString aPluginLibrary(""); |
450 | #ifndef WNT |
451 | aPluginLibrary += "lib"; |
452 | #endif |
453 | aPluginLibrary += aPluginResource->Value(theKey.ToCString()); |
454 | #ifdef WNT |
455 | aPluginLibrary += ".dll"; |
456 | #elif __APPLE__ |
457 | aPluginLibrary += ".dylib"; |
458 | #elif defined (HPUX) || defined(_hpux) |
459 | aPluginLibrary += ".sl"; |
460 | #else |
461 | aPluginLibrary += ".so"; |
462 | #endif |
463 | OSD_SharedLibrary aSharedLibrary(aPluginLibrary.ToCString()); |
464 | if(!aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) { |
465 | TCollection_AsciiString error(aSharedLibrary.DlError()); |
466 | Standard_SStream aMsg; aMsg << "Could not open: "; |
467 | aMsg << aPluginResource->Value(theKey.ToCString()); |
468 | aMsg << "; reason: "; |
469 | aMsg << error.ToCString(); |
470 | #ifdef DEB |
471 | cout << "could not open: " << aPluginResource->Value(theKey.ToCString())<< " ; reason: "<< error.ToCString() << endl; |
472 | #endif |
473 | Draw_Failure::Raise(aMsg); |
474 | } |
475 | f = aSharedLibrary.DlSymb("PLUGINFACTORY"); |
476 | if( f == NULL ) { |
477 | TCollection_AsciiString error(aSharedLibrary.DlError()); |
478 | Standard_SStream aMsg; aMsg << "Could not find the factory in: "; |
479 | aMsg << aPluginResource->Value(theKey.ToCString()); |
480 | aMsg << error.ToCString(); |
481 | Draw_Failure::Raise(aMsg); |
482 | } |
483 | theMapOfFunctions.Bind(theKey, f); |
484 | } |
485 | else |
486 | f = theMapOfFunctions(theKey); |
487 | |
488 | // void (*fp) (Draw_Interpretor&, const TCollection_AsciiString&) = NULL; |
489 | // fp = (void (*)(Draw_Interpretor&, const TCollection_AsciiString&)) f; |
490 | // (*fp) (theDI, theKey); |
491 | |
492 | void (*fp) (Draw_Interpretor&) = NULL; |
493 | fp = (void (*)(Draw_Interpretor&)) f; |
494 | (*fp) (theDI); |
495 | |
496 | } |
497 | |
498 | |
499 | //================================================================================= |
500 | // |
501 | //================================================================================= |
502 | void Draw::Load(Draw_Interpretor& theDI, const TCollection_AsciiString& theKey, |
503 | const TCollection_AsciiString& theResourceFileName, |
504 | TCollection_AsciiString& theDefaultsDirectory, |
505 | TCollection_AsciiString& theUserDefaultsDirectory, |
506 | const Standard_Boolean Verbose ) { |
507 | |
508 | static Draw_MapOfFunctions theMapOfFunctions; |
509 | OSD_Function f; |
510 | |
511 | if(!theMapOfFunctions.IsBound(theKey)) { |
512 | |
513 | Handle(Resource_Manager) aPluginResource = new Resource_Manager(theResourceFileName.ToCString(), theDefaultsDirectory, theUserDefaultsDirectory, Verbose); |
514 | |
515 | if(!aPluginResource->Find(theKey.ToCString())) { |
516 | Standard_SStream aMsg; aMsg << "Could not find the resource:"; |
517 | aMsg << theKey.ToCString()<< endl; |
518 | cout << "could not find the resource:"<<theKey.ToCString()<< endl; |
519 | Draw_Failure::Raise(aMsg); |
520 | } |
521 | |
522 | TCollection_AsciiString aPluginLibrary(""); |
523 | #ifndef WNT |
524 | aPluginLibrary += "lib"; |
525 | #endif |
526 | aPluginLibrary += aPluginResource->Value(theKey.ToCString()); |
527 | #ifdef WNT |
528 | aPluginLibrary += ".dll"; |
529 | #elif __APPLE__ |
530 | aPluginLibrary += ".dylib"; |
531 | #elif defined (HPUX) || defined(_hpux) |
532 | aPluginLibrary += ".sl"; |
533 | #else |
534 | aPluginLibrary += ".so"; |
535 | #endif |
536 | OSD_SharedLibrary aSharedLibrary(aPluginLibrary.ToCString()); |
537 | if(!aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) { |
538 | TCollection_AsciiString error(aSharedLibrary.DlError()); |
539 | Standard_SStream aMsg; aMsg << "Could not open: "; |
540 | aMsg << aPluginResource->Value(theKey.ToCString()); |
541 | aMsg << "; reason: "; |
542 | aMsg << error.ToCString(); |
543 | #ifdef DEB |
544 | cout << "could not open: " << aPluginResource->Value(theKey.ToCString())<< " ; reason: "<< error.ToCString() << endl; |
545 | #endif |
546 | Draw_Failure::Raise(aMsg); |
547 | } |
548 | f = aSharedLibrary.DlSymb("PLUGINFACTORY"); |
549 | if( f == NULL ) { |
550 | TCollection_AsciiString error(aSharedLibrary.DlError()); |
551 | Standard_SStream aMsg; aMsg << "Could not find the factory in: "; |
552 | aMsg << aPluginResource->Value(theKey.ToCString()); |
553 | aMsg << error.ToCString(); |
554 | Draw_Failure::Raise(aMsg); |
555 | } |
556 | theMapOfFunctions.Bind(theKey, f); |
557 | } |
558 | else |
559 | f = theMapOfFunctions(theKey); |
560 | |
561 | // void (*fp) (Draw_Interpretor&, const TCollection_AsciiString&) = NULL; |
562 | // fp = (void (*)(Draw_Interpretor&, const TCollection_AsciiString&)) f; |
563 | // (*fp) (theDI, theKey); |
564 | |
565 | void (*fp) (Draw_Interpretor&) = NULL; |
566 | fp = (void (*)(Draw_Interpretor&)) f; |
567 | (*fp) (theDI); |
568 | |
569 | } |