When DRAW on Windows is launched with option -c, the command is now properly transferred to Tcl thread (separate thread that runs Tcl interpretor on Windows except when DRAW is run in batch mode) for execution, instead of being evaluated in the main thread.
Execution of DRAW in batch mode (option -b) is fixed by enabling proper initialization of the Tcl interpretor and replacement of backslashes in path to startup script by straight slashes on Windows in that mode.
Declaration of global variables used for communication of console command between threads is moved to Draw_Window.hxx to ensure consistency.
Function wscpy_s is used instead of memcpy to avoid possible buffer overrun.
return aNbChar;
}
-extern console_semaphore_value volatile console_semaphore;
-extern wchar_t console_command[1000];
-
/*--------------------------------------------------------*\
| EDIT WINDOW PROCEDURE
\*--------------------------------------------------------*/
//TCollection_AsciiString aCmdUtf8 (aCmdBuffer + sizeof(THE_PROMPT) / sizeof(wchar_t) - 1);
//Draw_Interprete (aCmdUtf8.ToCString());
//if (toExit) { DestroyProc (hWnd); }
- wcscpy (console_command, aCmdBuffer + sizeof(THE_PROMPT) / sizeof(wchar_t) - 1);
+ wcscpy_s (console_command, aCmdBuffer + sizeof(THE_PROMPT) / sizeof(wchar_t) - 1);
console_semaphore = HAS_CONSOLE_COMMAND;
// Purge the buffer
nbline = SendMessageW (hWnd, EM_GETLINECOUNT, 0l, 0l);
static ostream spystream(&Draw_Spyfile);
-static Standard_Boolean XLoop;
-
static Handle(Draw_ProgressIndicator) PInd = NULL;
Standard_EXPORT Standard_Boolean Draw_Interprete(const char* command);
// *******************************************************************
// read an init file
// *******************************************************************
-#ifdef _WIN32
-extern console_semaphore_value volatile console_semaphore;
-extern wchar_t console_command[1000];
-#endif
static void ReadInitFile (const TCollection_AsciiString& theFileName)
{
TCollection_AsciiString aPath = theFileName;
#ifdef _WIN32
+ aPath.ChangeAll('\\', '/');
if (!Draw_Batch)
{
try
{
- aPath.ChangeAll ('\\', '/');
{
- const TCollection_ExtendedString aCmdWide = TCollection_ExtendedString ("source -encoding utf-8 \"") + TCollection_ExtendedString (aPath) + "\"";
- memcpy (console_command, aCmdWide.ToWideString(), Min (aCmdWide.Length() + 1, 980) * sizeof(wchar_t));
+ TCollection_ExtendedString aCmdWide ("source -encoding utf-8 \"");
+ aCmdWide += TCollection_ExtendedString (aPath) + "\"";
+ wcscpy_s (console_command, aCmdWide.ToWideString());
}
console_semaphore = HAS_CONSOLE_COMMAND;
while (console_semaphore == HAS_CONSOLE_COMMAND)
Draw_Batch=!Init_Appli();
#endif
else
+ {
cout << "DRAW is running in batch mode" << endl;
+ theCommands.Init();
+ Tcl_Init(theCommands.Interp());
+ }
- XLoop = !Draw_Batch;
- if (XLoop)
+ if (! Draw_Batch)
{
// Default colors
for (int i = 0; i < MAXCOLOR; ++i)
}
// execute command from command line
- if (!aCommand.IsEmpty()) {
- Draw_Interprete (aCommand.ToCString());
+ if (!aCommand.IsEmpty())
+ {
+#ifdef _WIN32
+ if (!Draw_Batch)
+ {
+ // on Windows except batch mode, commands are executed in separate thread
+ while (console_semaphore == HAS_CONSOLE_COMMAND) Sleep(10);
+ TCollection_ExtendedString aCmdWide(aCommand);
+ wcscpy_s(console_command, aCmdWide.ToWideString());
+ console_semaphore = HAS_CONSOLE_COMMAND;
+ while (console_semaphore == HAS_CONSOLE_COMMAND) Sleep(10);
+ }
+ else
+#endif
+ Draw_Interprete (aCommand.ToCString()); // Linux and Windows batch mode
// provide a clean exit, this is useful for some analysis tools
if ( ! isInteractiveForced )
#ifndef _WIN32
// *****************************************************************
// X loop
// *****************************************************************
- if (XLoop) {
+ if (! Draw_Batch) {
#ifdef _WIN32
Run_Appli(hWnd);
#else
}
else
{
- char cmd[255];
- for (;;)
+ const int MAXCMD = 2048;
+ char cmd[MAXCMD];
+ for (int ncmd = 1;; ++ncmd)
{
- cout << "Viewer>";
- int i = -1;
- do {
- cin.get(cmd[++i]);
- } while ((cmd[i] != '\n') && (!cin.fail()));
- cmd[i] = '\0';
+ cout << "Draw[" << ncmd << "]> ";
+ if (cin.getline (cmd, MAXCMD).fail())
+ {
+ break;
+ }
Draw_Interprete(cmd);
}
}
#include <Image_AlienPixMap.hxx>
#include <NCollection_List.hxx>
+extern Standard_Boolean Draw_Batch;
extern Standard_Boolean Draw_VirtualWindows;
static Tcl_Interp *interp; /* Interpreter for this application. */
static NCollection_List<Draw_Window::FCallbackBeforeTerminate> MyCallbacks;
//* threads sinchronization *//
DWORD dwMainThreadId;
console_semaphore_value volatile console_semaphore = WAIT_CONSOLE_COMMAND;
-#define THE_COMMAND_SIZE 1000 /* Console Command size */
-wchar_t console_command[THE_COMMAND_SIZE];
+wchar_t console_command[DRAW_COMMAND_SIZE + 1];
bool volatile isTkLoopStarted = false;
/*--------------------------------------------------------*\
&IDThread);
if (!hThread) {
cout << "Tcl/Tk main loop thread not created. Switching to batch mode..." << endl;
+ Draw_Batch = Standard_True;
#ifdef _TK
try {
OCC_CATCH_SIGNALS
&& isConsoleInput)
{
DWORD aNbRead = 0;
- if (ReadConsoleW (anStdIn, console_command, THE_COMMAND_SIZE, &aNbRead, NULL))
+ if (ReadConsoleW (anStdIn, console_command, DRAW_COMMAND_SIZE, &aNbRead, NULL))
{
console_command[aNbRead] = L'\0';
console_semaphore = HAS_CONSOLE_COMMAND;
}
// fgetws() works only for characters within active locale (see setlocale())
- if (fgetws (console_command, THE_COMMAND_SIZE, stdin))
+ if (fgetws (console_command, DRAW_COMMAND_SIZE, stdin))
{
console_semaphore = HAS_CONSOLE_COMMAND;
}
}
#ifdef _TK
// We should not exit until the Main Tk window is closed
- toLoop = (Tk_GetNumMainWindows() > 0) || Draw_VirtualWindows;
+ toLoop = (Draw_VirtualWindows || Tk_GetNumMainWindows() > 0);
#endif
}
Tcl_Exit(0);
WAIT_CONSOLE_COMMAND,
HAS_CONSOLE_COMMAND} console_semaphore_value;
+// global variable describing console state
+extern console_semaphore_value volatile console_semaphore;
+
+// Console command buffer
+#define DRAW_COMMAND_SIZE 1000
+extern wchar_t console_command[DRAW_COMMAND_SIZE + 1];
+
// PROCEDURE DE DRAW WINDOW
Standard_EXPORT Standard_Boolean Init_Appli(HINSTANCE,HINSTANCE,int,HWND&);