0020716: Eliminate usage of "config.h" header file
[occt.git] / src / Draw / Draw_Window.cxx
1 // Created on: 1994-07-27
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // include windows.h first to have all definitions available
18 #ifdef WNT
19 #include <windows.h>
20 #endif
21
22 #include <Standard_ErrorHandler.hxx>
23
24 #include <tcl.h>
25 #include <Draw_Interpretor.hxx>
26 #include <Draw_Appli.hxx>
27 #include <TCollection_AsciiString.hxx>
28 #include <Image_AlienPixMap.hxx>
29
30 extern Draw_Interpretor theCommands;
31 extern Standard_Boolean Draw_VirtualWindows;
32 static Tcl_Interp *interp;        /* Interpreter for this application. */
33
34 /*
35  *----------------------------------------------------------------------
36  *
37  * Prompt --
38  *
39  *        Issue a prompt on standard output, or invoke a script
40  *        to issue the prompt.
41  *
42  * Results:
43  *        None.
44  *
45  * Side effects:
46  *        A prompt gets output, and a Tcl script may be evaluated
47  *        in interp.
48  *
49  *----------------------------------------------------------------------
50  */
51
52 static void Prompt(Tcl_Interp *Interp, int partial)
53 {
54
55   // MKV 29.03.05
56 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))) && !defined(USE_NON_CONST)
57     const char *promptCmd;
58 #else
59     char *promptCmd;
60 #endif
61     int code;
62     Tcl_Channel  outChannel, errChannel;
63     outChannel = Tcl_GetStdChannel(TCL_STDOUT);
64     promptCmd = Tcl_GetVar(Interp,(char*)
65         (partial ? "tcl_prompt2" : "tcl_prompt1"), TCL_GLOBAL_ONLY);
66
67     if (promptCmd == NULL) {
68 defaultPrompt:
69       if (!partial && outChannel) {
70         Tcl_Write(outChannel, "% ", 2);
71       }
72     } else {
73       code = Tcl_Eval(Interp, promptCmd);
74       outChannel = Tcl_GetStdChannel(TCL_STDOUT);
75       errChannel = Tcl_GetStdChannel(TCL_STDERR);
76       if (code != TCL_OK) {
77         if (errChannel) {
78 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
79           Tcl_Write(errChannel, Tcl_GetStringResult(Interp), -1);
80 #else
81           Tcl_Write(errChannel, Interp->result, -1);
82 #endif
83           Tcl_Write(errChannel, "\n", 1);
84         }
85         Tcl_AddErrorInfo(Interp,
86                          "\n    (script that generates prompt)");
87         goto defaultPrompt;
88       }
89     }
90     if (outChannel) {
91       Tcl_Flush(outChannel);
92     }
93 }
94
95 #if !defined(_WIN32) && !defined(__WIN32__)
96
97 #include <OSD_Timer.hxx>
98 #include <Draw_Window.hxx>
99 #include <unistd.h>
100
101 #if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
102   // use forward declaration for small subset of used Tk functions
103   // to workaround broken standard Tk framework installation within OS X SDKs
104   // which *HAS* X11 headers in Tk.framework but doesn't install them appropriately
105   #define _TK
106   typedef struct Tk_Window_* Tk_Window;
107   typedef const char* Tk_Uid;
108
109   extern "C" int Tk_Init (Tcl_Interp* interp);
110   extern "C" void Tk_MainLoop();
111   extern "C" Tk_Window Tk_MainWindow (Tcl_Interp* interp) ;
112   extern "C" Tk_Uid Tk_GetUid (const char* str);
113   extern "C" const char* Tk_SetAppName (Tk_Window tkwin, const char* name) ;
114   extern "C" void Tk_GeometryRequest (Tk_Window tkwin, int reqWidth, int reqHeight);
115
116 #else
117   #include <tk.h>
118 #endif
119
120 /*
121  * Global variables used by the main program:
122  */
123
124 char *tcl_RcFileName = NULL;    /* Name of a user-specific startup script
125                                  * to source if the application is being run
126                                  * interactively (e.g. "~/.wishrc").  Set
127                                  * by Tcl_AppInit.  NULL means don't source
128                                  * anything ever. */
129
130 static Tcl_DString command;     /* Used to assemble lines of terminal input
131                                  * into Tcl commands. */
132 static Tcl_DString line;        /* Used to read the next line from the
133                                  * terminal input. */
134 //static char errorExitCmd[] = "exit 1";
135
136 /*
137  * Forward declarations for procedures defined later in this file:
138  */
139
140 static void StdinProc (ClientData clientData, int mask);
141
142 static void Prompt (Tcl_Interp *Interp, int partial);
143
144 static Standard_Boolean tty;        /* Non-zero means standard input is a
145                                  * terminal-like device.  Zero means it's
146                                  * a file. */
147
148 Standard_Integer Draw_WindowScreen = 0;
149 Standard_Boolean Draw_BlackBackGround = Standard_True;
150
151
152 // Initialization of static variables of Draw_Window
153 //======================================================
154 Draw_Window* Draw_Window::firstWindow = NULL;
155
156 // X11 specific part
157 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
158 #include <X11/Xutil.h>
159 #include <Aspect_DisplayConnection.hxx>
160
161 static unsigned long thePixels[MAXCOLOR];
162
163 Display* Draw_WindowDisplay = NULL;
164 Colormap Draw_WindowColorMap;
165 static Handle(Aspect_DisplayConnection) Draw_DisplayConnection;
166
167 // Base_Window struct definition
168 //===================================
169 struct Base_Window
170 {
171   GC gc;
172   XSetWindowAttributes xswa;
173 };
174
175 //=======================================================================
176 //function : Draw_Window
177 //purpose  :
178 //=======================================================================
179 Draw_Window::Draw_Window() :
180        base(*new Base_Window()),
181        win(0),
182        myBuffer(0),
183        next(firstWindow),
184        previous(NULL),
185        myUseBuffer(Standard_False),
186        withWindowManager(Standard_True)
187 {
188   myMother = RootWindow(Draw_WindowDisplay,
189                         Draw_WindowScreen);
190
191   if (firstWindow) firstWindow->previous = this;
192   firstWindow = this;
193 }
194
195 //=======================================================================
196 //function : Draw_Window
197 //purpose  :
198 //=======================================================================
199 Draw_Window::Draw_Window(Window mother) :
200        base(*new Base_Window()),
201        win(0),
202        myBuffer(0),
203        next(firstWindow),
204        previous(NULL),
205        myUseBuffer(Standard_False),
206        withWindowManager(Standard_True)
207 {
208   myMother = mother;
209
210   if (firstWindow) firstWindow->previous = this;
211   firstWindow = this;
212 }
213
214 //=======================================================================
215 //function : Draw_Window
216 //purpose  :
217 //=======================================================================
218 Draw_Window::Draw_Window (const char* title,
219                           Standard_Integer X, Standard_Integer Y,
220                           Standard_Integer DX, Standard_Integer DY) :
221        base(*new Base_Window()),
222        win(0),
223        myBuffer(0),
224        next(firstWindow),
225        previous(NULL),
226        myUseBuffer(Standard_False),
227        withWindowManager(Standard_True)
228 {
229   myMother = RootWindow(Draw_WindowDisplay,
230                         Draw_WindowScreen);
231
232   if (firstWindow) firstWindow->previous = this;
233   firstWindow = this;
234   Init(X,Y,DX,DY);
235   SetTitle(title);
236 }
237
238 //=======================================================================
239 //function : Draw_Window
240 //purpose  :
241 //=======================================================================
242 Draw_Window::Draw_Window (const char* window ) :
243        base(*new Base_Window()),
244        win(0),
245        myBuffer(0),
246        next(firstWindow),
247        previous(NULL),
248        myUseBuffer(Standard_False),
249        withWindowManager(Standard_True)
250 {
251   sscanf(window,"%lx",&win);
252   Standard_Integer X,Y,DX,DY;
253
254   if (firstWindow) firstWindow->previous = this;
255   firstWindow = this;
256   GetPosition(X,Y);
257   DX=HeightWin();
258   DY=WidthWin();
259
260   Init(X,Y,DX,DY);
261 }
262
263 //=======================================================================
264 //function : Draw_Window
265 //purpose  :
266 //=======================================================================
267 Draw_Window::Draw_Window (Window mother,
268                           char* title,
269                           Standard_Integer X, Standard_Integer Y,
270                           Standard_Integer DX, Standard_Integer DY) :
271        base(*new Base_Window()),
272        win(0),
273        myBuffer(0),
274        next(firstWindow),
275        previous(NULL),
276        myUseBuffer(Standard_False),
277        withWindowManager(Standard_True)
278 {
279   myMother = mother;
280
281   if (firstWindow) firstWindow->previous = this;
282   firstWindow = this;
283   Init(X,Y,DX,DY);
284   SetTitle(title);
285 }
286
287 //=======================================================================
288 //function : ~Draw_Window
289 //purpose  :
290 //=======================================================================
291 Draw_Window::~Draw_Window()
292 {
293   if (previous)
294     previous->next = next;
295   else
296     firstWindow = next;
297   if (next)
298     next->previous = previous;
299
300   if (myBuffer != 0)
301   {
302     XFreePixmap(Draw_WindowDisplay, myBuffer);
303     myBuffer = 0;
304   }
305   // Liberation pointer on Base_Window
306   delete &base;
307 }
308
309 //=======================================================================
310 //function : Init
311 //purpose  :
312 //=======================================================================
313 void Draw_Window::Init(Standard_Integer X, Standard_Integer Y,
314                        Standard_Integer DX, Standard_Integer DY)
315 {
316   unsigned long setmask;
317
318   if (Draw_BlackBackGround)
319   {
320     base.xswa.background_pixel = BlackPixel(Draw_WindowDisplay,Draw_WindowScreen);
321     base.xswa.border_pixel     = WhitePixel(Draw_WindowDisplay,Draw_WindowScreen);
322   }
323   else
324   {
325     base.xswa.background_pixel = WhitePixel(Draw_WindowDisplay,Draw_WindowScreen);
326     base.xswa.border_pixel     = BlackPixel(Draw_WindowDisplay,Draw_WindowScreen);
327   }
328   base.xswa.colormap         = Draw_WindowColorMap;
329   setmask               = CWBackPixel | CWBorderPixel ;
330
331   XSizeHints myHints;
332   myHints.flags = USPosition;
333   myHints.x = (int) X;
334   myHints.y = (int) Y;
335
336   if (win == 0)
337   {
338     win = XCreateWindow(Draw_WindowDisplay,
339                         myMother,
340                         (int) X,(int) Y,
341                         (unsigned int) DX,(unsigned int) DY,
342                         5,
343                         DefaultDepth(Draw_WindowDisplay,Draw_WindowScreen),
344                         InputOutput,
345                         DefaultVisual(Draw_WindowDisplay,Draw_WindowScreen),
346                         setmask,&base.xswa);
347     XSelectInput(Draw_WindowDisplay, win, ButtonPressMask|ExposureMask|
348                                           StructureNotifyMask);
349
350     // advise to the window manager to place it where I need
351     XSetWMNormalHints(Draw_WindowDisplay,win,&myHints);
352
353     if (Draw_VirtualWindows)
354     {
355       myUseBuffer = Standard_True;
356       InitBuffer();
357     }
358   }
359
360   base.gc = XCreateGC(Draw_WindowDisplay, win, 0, NULL);
361
362   XSetPlaneMask(Draw_WindowDisplay,base.gc,AllPlanes);
363   XSetForeground(Draw_WindowDisplay,
364                  base.gc, WhitePixel(Draw_WindowDisplay,Draw_WindowScreen));
365   XSetBackground(Draw_WindowDisplay,
366                  base.gc, BlackPixel(Draw_WindowDisplay,Draw_WindowScreen));
367   // save in case of window recovery
368
369   base.xswa.backing_store = Always;
370   XChangeWindowAttributes(Draw_WindowDisplay, win,
371                           CWBackingStore, &base.xswa);
372
373   XSetLineAttributes (Draw_WindowDisplay, base.gc,
374                       0, LineSolid, CapButt, JoinMiter);
375 }
376
377 //=======================================================================
378 //function : InitBuffer
379 //purpose  :
380 //=======================================================================
381 void Draw_Window::InitBuffer()
382 {
383   if (myUseBuffer) {
384     if (myBuffer != 0) {
385       XFreePixmap (Draw_WindowDisplay, myBuffer);
386     }
387     XWindowAttributes winAttr;
388     XGetWindowAttributes (Draw_WindowDisplay, win, &winAttr);
389     myBuffer = XCreatePixmap (Draw_WindowDisplay, win, winAttr.width, winAttr.height, winAttr.depth);
390   }
391   else if (myBuffer != 0)
392   {
393     XFreePixmap (Draw_WindowDisplay, myBuffer);
394     myBuffer = 0;
395   }
396 }
397
398 //=======================================================================
399 //function : StopWinManager
400 //purpose  :
401 //=======================================================================
402 void Draw_Window::StopWinManager()
403 {
404 //  XGCValues winGc;
405   XWindowAttributes winAttr;
406   XGetWindowAttributes (Draw_WindowDisplay, win, &winAttr);
407   Destroy();
408
409   XSizeHints myHints;
410   myHints.flags = USPosition;
411   myHints.x = (int) 30;
412   myHints.y = (int) 100;
413
414   base.xswa.override_redirect = 1;
415   base.xswa.border_pixel = BlackPixel(Draw_WindowDisplay,
416                                  Draw_WindowScreen);
417   base.xswa.background_pixel = WhitePixel(Draw_WindowDisplay,
418                                Draw_WindowScreen);
419
420   withWindowManager = Standard_False;
421
422   win = XCreateWindow(Draw_WindowDisplay, myMother,
423                       winAttr.x, winAttr.y,
424                       winAttr.width, winAttr.height,
425                       2,
426                       CopyFromParent, InputOutput, CopyFromParent,
427                       CWBorderPixel|CWOverrideRedirect|CWBackPixel, &base.xswa);
428
429
430   // adwise to the window manager to place it where I wish
431   XSetWMNormalHints(Draw_WindowDisplay,win,&myHints);
432
433   // all masks of the old window are reassigned to the new one.
434   XSelectInput(Draw_WindowDisplay,win,winAttr.your_event_mask);
435 }
436
437 //=======================================================================
438 //function : SetPosition
439 //purpose  :
440 //=======================================================================
441 void Draw_Window::SetPosition(Standard_Integer NewXpos,
442                               Standard_Integer NewYpos)
443 {
444   Standard_Integer x,y;
445   GetPosition(x, y);
446
447   if ( (x != NewXpos) || (y != NewYpos) )
448     XMoveWindow(Draw_WindowDisplay, win, NewXpos, NewYpos);
449 }
450
451 //=======================================================================
452 //function : SetDimension
453 //purpose  :
454 //=======================================================================
455 void Draw_Window::SetDimension(Standard_Integer NewDx,
456                                Standard_Integer NewDy)
457 {
458   if ( (NewDx != WidthWin() ) || (NewDy != HeightWin() ) )
459     XResizeWindow(Draw_WindowDisplay, win, NewDx, NewDy);
460 }
461
462 //=======================================================================
463 //function : GetPosition
464 //purpose  :
465 //=======================================================================
466 void Draw_Window::GetPosition(Standard_Integer &PosX,
467                               Standard_Integer &PosY)
468 {
469   XWindowAttributes winAttr;
470   XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);
471
472   PosX = winAttr.x;
473   PosY = winAttr.y;
474 }
475
476 //=======================================================================
477 //function : HeightWin
478 //purpose  :
479 //=======================================================================
480 Standard_Integer Draw_Window::HeightWin() const
481 {
482   Standard_Integer DY;
483   XWindowAttributes winAttr;
484   XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);
485
486   DY = winAttr.height;
487   return DY;
488 }
489
490 //=======================================================================
491 //function : WidthWin
492 //purpose  :
493 //=======================================================================
494 Standard_Integer Draw_Window::WidthWin() const
495 {
496   Standard_Integer DX;
497   XWindowAttributes winAttr;
498   XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);
499
500   DX = winAttr.width;
501   return DX;
502 }
503
504 //=======================================================================
505 //function : SetTitle
506 //purpose  :
507 //=======================================================================
508 void Draw_Window::SetTitle(const char* title)
509 {
510   XStoreName(Draw_WindowDisplay, win, title);
511 }
512
513 //=======================================================================
514 //function : GetTitle
515 //purpose  :
516 //=======================================================================
517 char* Draw_Window::GetTitle()
518 {
519   char* title;
520   XFetchName(Draw_WindowDisplay, win, &title);
521   return title;
522 }
523
524 //=======================================================================
525 //function : GetDrawable
526 //purpose  :
527 //=======================================================================
528 Drawable Draw_Window::GetDrawable() const
529 {
530   return myUseBuffer ? myBuffer : win;
531 }
532
533 //=======================================================================
534 //function :DefineColor
535 //purpose  :
536 //=======================================================================
537 Standard_Boolean Draw_Window::DefineColor(const Standard_Integer i, const char* colorName)
538 {
539   XColor color;
540
541   if (!XParseColor(Draw_WindowDisplay,Draw_WindowColorMap,colorName,&color))
542     return Standard_False;
543   if (!XAllocColor(Draw_WindowDisplay,Draw_WindowColorMap,&color))
544     return Standard_False;
545   thePixels[i % MAXCOLOR] = color.pixel;
546   return Standard_True;
547 }
548
549 //=======================================================================
550 //function : DisplayWindow
551 //purpose  :
552 //=======================================================================
553 void Draw_Window::DisplayWindow()
554 {
555   if (Draw_VirtualWindows)
556   {
557     return;
558   }
559   else
560   {
561     XMapRaised(Draw_WindowDisplay, win);
562   }
563   XFlush(Draw_WindowDisplay);
564 }
565
566 //=======================================================================
567 //function : Hide
568 //purpose  :
569 //=======================================================================
570 void Draw_Window::Hide()
571 {
572    XUnmapWindow(Draw_WindowDisplay, win);
573 }
574
575 //=======================================================================
576 //function : Destroy
577 //purpose  :
578 //=======================================================================
579 void Draw_Window::Destroy()
580 {
581   XFreeGC (Draw_WindowDisplay, base.gc);
582   XDestroyWindow(Draw_WindowDisplay, win);
583   win = 0;
584   if (myBuffer != 0)
585   {
586     XFreePixmap(Draw_WindowDisplay, myBuffer);
587     myBuffer = 0;
588   }
589 }
590
591 //=======================================================================
592 //function : Clear
593 //purpose  :
594 //=======================================================================
595 void Draw_Window::Clear()
596 {
597   if (myUseBuffer)
598   {
599     // XClearArea only applicable for windows
600     XGCValues currValues;
601     XGetGCValues(Draw_WindowDisplay, base.gc, GCBackground | GCForeground, &currValues);
602     XSetForeground(Draw_WindowDisplay, base.gc, currValues.background);
603     XFillRectangle(Draw_WindowDisplay, myBuffer, base.gc, 0, 0, WidthWin(), HeightWin());
604     XSetForeground(Draw_WindowDisplay, base.gc, currValues.foreground);
605   }
606   else
607   {
608     XClearArea(Draw_WindowDisplay, win, 0, 0, 0, 0, False);
609   }
610 }
611
612 //=======================================================================
613 //function : Flush
614 //purpose  :
615 //=======================================================================
616 void Draw_Window::Flush()
617 {
618   XFlush(Draw_WindowDisplay);
619 }
620
621 //=======================================================================
622 //function : DrawString
623 //purpose  :
624 //=======================================================================
625 void Draw_Window::DrawString(int X, int Y, char *text)
626 {
627   XDrawString(Draw_WindowDisplay, GetDrawable(), base.gc, X, Y, text, strlen(text));
628 }
629
630 //=======================================================================
631 //function : DrawSegments
632 //purpose  :
633 //=======================================================================
634 void Draw_Window::DrawSegments(Segment *tab, int nbElem)
635 {
636   XDrawSegments(Draw_WindowDisplay, GetDrawable(), base.gc, (XSegment*) tab, nbElem);
637 }
638
639 //=======================================================================
640 //function : Redraw
641 //purpose  :
642 //=======================================================================
643 void Draw_Window::Redraw()
644 {
645   if (myUseBuffer) {
646     XCopyArea (Draw_WindowDisplay,
647                myBuffer, win, // source, destination Drawables
648                base.gc,
649                0, 0,  // source x, y
650                WidthWin(), HeightWin(),
651                0, 0); // destination x, y
652   }
653 }
654
655 //=======================================================================
656 //function : SetColor
657 //purpose  :
658 //=======================================================================
659 void Draw_Window::SetColor(Standard_Integer color)
660 {
661   XSetForeground(Draw_WindowDisplay, base.gc, thePixels[color]);
662 }
663
664 //=======================================================================
665 //function : SetMode
666 //purpose  :
667 //=======================================================================
668 void Draw_Window::SetMode( int mode)
669 {
670   XSetFunction(Draw_WindowDisplay, base.gc, mode);
671 }
672
673 //=======================================================================
674 //function : Save
675 //purpose  :
676 //=======================================================================
677 Standard_Boolean Draw_Window::Save (const char* theFileName) const
678 {
679   // make sure all draw operations done
680   XSync (Draw_WindowDisplay, True);
681
682   // the attributes
683   XWindowAttributes winAttr;
684   XGetWindowAttributes (Draw_WindowDisplay, win, &winAttr);
685
686   if (!myUseBuffer)
687   {
688     // make sure that the whole window fit on display to prevent BadMatch error
689     XWindowAttributes winAttrRoot;
690     XGetWindowAttributes (Draw_WindowDisplay, XRootWindowOfScreen (winAttr.screen), &winAttrRoot);
691
692     Window winChildDummy;
693     int winLeft = 0;
694     int winTop = 0;
695     XTranslateCoordinates (Draw_WindowDisplay, win, XRootWindowOfScreen (winAttr.screen),
696                            0, 0, &winLeft, &winTop, &winChildDummy);
697
698     if (((winLeft + winAttr.width) > winAttrRoot.width)  || winLeft < winAttrRoot.x ||
699         ((winTop + winAttr.height) > winAttrRoot.height) || winTop  < winAttrRoot.y)
700     {
701       std::cerr << "The window not fully visible! Can't create the snapshot.\n";
702       return Standard_False;
703     }
704   }
705
706   XVisualInfo aVInfo;
707   if (XMatchVisualInfo (Draw_WindowDisplay, Draw_WindowScreen, 32, TrueColor, &aVInfo) == 0
708    && XMatchVisualInfo (Draw_WindowDisplay, Draw_WindowScreen, 24, TrueColor, &aVInfo) == 0)
709   {
710     std::cerr << "24-bit TrueColor visual is not supported by server!\n";
711     return Standard_False;
712   }
713
714   Image_AlienPixMap anImage;
715   bool isBigEndian = Image_PixMap::IsBigEndianHost();
716   const Standard_Size aSizeRowBytes = Standard_Size(winAttr.width) * 4;
717   if (!anImage.InitTrash (isBigEndian ? Image_PixMap::ImgRGB32 : Image_PixMap::ImgBGR32,
718                           Standard_Size(winAttr.width), Standard_Size(winAttr.height), aSizeRowBytes))
719   {
720     return Standard_False;
721   }
722   anImage.SetTopDown (true);
723
724   XImage* anXImage = XCreateImage (Draw_WindowDisplay, aVInfo.visual,
725                                    32, ZPixmap, 0, (char* )anImage.ChangeData(), winAttr.width, winAttr.height, 32, int(aSizeRowBytes));
726   anXImage->bitmap_bit_order = anXImage->byte_order = (isBigEndian ? MSBFirst : LSBFirst);
727   if (XGetSubImage (Draw_WindowDisplay, GetDrawable(),
728                     0, 0, winAttr.width, winAttr.height,
729                     AllPlanes, ZPixmap, anXImage, 0, 0) == NULL)
730   {
731     anXImage->data = NULL;
732     XDestroyImage (anXImage);
733     return Standard_False;
734   }
735
736   // destroy the image
737   anXImage->data = NULL;
738   XDestroyImage (anXImage);
739
740   // save the image
741   return anImage.Save (theFileName);
742 }
743
744 //=======================================================================
745 //function : Wait
746 //purpose  :
747 //=======================================================================
748
749 void Draw_Window::Wait (Standard_Boolean wait)
750 {
751   Flush();
752   if (!wait) {
753     XSelectInput(Draw_WindowDisplay,win,
754                  ButtonPressMask|ExposureMask | StructureNotifyMask |
755                  PointerMotionMask);
756   }
757   else {
758     XSelectInput(Draw_WindowDisplay,win,
759                  ButtonPressMask|ExposureMask | StructureNotifyMask);
760   }
761 }
762
763 //=======================================================================
764 //function : ProcessEvent
765 //purpose  :
766 //=======================================================================
767
768 void ProcessEvent(Draw_Window& win, XEvent& xev)
769 {
770   Standard_Integer X,Y,button;
771   KeySym keysym;
772   XComposeStatus stat;
773   char chainekey[10];
774
775
776   switch (xev.type) {
777
778   case Expose :
779     win.WExpose();
780     break;
781
782   case ButtonPress :
783     X = xev.xbutton.x;
784     Y = xev.xbutton.y;
785     button = xev.xbutton.button;
786     win.WButtonPress(X,Y,button);
787     break;
788
789   case ButtonRelease :
790     X = xev.xbutton.x;
791     Y = xev.xbutton.y;
792     button = xev.xbutton.button;
793     win.WButtonRelease(X,Y,button);
794     break;
795
796   case KeyPress :
797     XLookupString(&(xev.xkey),
798                          chainekey,
799                          10,
800                          &keysym,
801                          &stat);
802     break;
803
804   case MotionNotify :
805     X = xev.xmotion.x;
806     Y = xev.xmotion.y;
807     win.WMotionNotify(X,Y);
808     break;
809
810   case ConfigureNotify :
811     if (win.withWindowManager)
812       win.WConfigureNotify(xev.xconfigure.x, xev.xconfigure.y,
813                            xev.xconfigure.width,
814                            xev.xconfigure.height);
815     break;
816
817   case UnmapNotify :
818
819     win.WUnmapNotify();
820     break;
821   }
822 }
823
824 //=======================================================================
825 //function : WExpose
826 //purpose  :
827 //=======================================================================
828 void Draw_Window::WExpose()
829 {
830 }
831
832 //=======================================================================
833 //function : WButtonPress
834 //purpose  :
835 //=======================================================================
836 void Draw_Window::WButtonPress(const Standard_Integer,
837                                const Standard_Integer,
838                                const Standard_Integer&)
839 {
840 }
841
842 //=======================================================================
843 //function : WButtonRelease
844 //purpose  :
845 //=======================================================================
846 void Draw_Window::WButtonRelease(const Standard_Integer,
847                                  const Standard_Integer,
848                                  const Standard_Integer&)
849 {
850 }
851
852 /**************************
853 //=======================================================================
854 //function : WKeyPress
855 //purpose  :
856 //=======================================================================
857
858 void Draw_Window::WKeyPress(char, KeySym&)
859 {
860 }
861 ***************************/
862
863 //=======================================================================
864 //function : WMotionNotify
865 //purpose  :
866 //=======================================================================
867 void Draw_Window::WMotionNotify(const Standard_Integer ,
868                                 const Standard_Integer )
869 {
870 }
871
872 //=======================================================================
873 //function : WConfigureNotify
874 //purpose  :
875 //=======================================================================
876
877 void Draw_Window::WConfigureNotify(const Standard_Integer,
878                                    const Standard_Integer,
879                                    const Standard_Integer,
880                                    const Standard_Integer)
881 {
882 }
883
884 //=======================================================================
885 //function : WUnmapNotify
886 //purpose  :
887 //=======================================================================
888
889 void Draw_Window::WUnmapNotify()
890 {
891 }
892
893
894 //======================================================
895 // funtion : ProcessEvents
896 // purpose : process pending X events
897 //======================================================
898
899 static void ProcessEvents(ClientData,int)
900 {
901   // test for X Event
902
903   while (XPending(Draw_WindowDisplay)) {
904
905     XEvent xev;
906     xev.type = 0;
907
908     XNextEvent(Draw_WindowDisplay,&xev);
909
910     /* search the window in the window list */
911     Draw_Window* w = Draw_Window::firstWindow;
912     Standard_Integer found=0;
913     while (w) {
914       if (xev.xany.window == w->win) {
915         ProcessEvent(*w, xev);
916         found=1;
917         break;
918       }
919       w = w->next;
920     }
921     if (found==0) {
922       Tk_HandleEvent(&xev);
923     }
924   }
925 }
926
927 //======================================================
928 // funtion : GetNextEvent()
929 // purpose :
930 //======================================================
931 void GetNextEvent(Event& ev)
932 {
933   XEvent xev;
934   XNextEvent(Draw_WindowDisplay, &xev);
935   switch(xev.type)
936   {
937     case ButtonPress :
938       ev.type = 4;
939       ev.window = xev.xbutton.window;
940       ev.button = xev.xbutton.button;
941       ev.x = xev.xbutton.x;
942       ev.y = xev.xbutton.y;
943       break;
944
945     case MotionNotify :
946       ev.type = 6;
947       ev.window = xev.xmotion.window;
948       ev.button = 0;
949       ev.x = xev.xmotion.x;
950       ev.y = xev.xmotion.y;
951       break;
952   }
953 }
954 #endif //__APPLE__
955
956 //======================================================
957 // funtion :Run_Appli
958 // purpose :
959 //======================================================
960
961
962 static Standard_Boolean(*Interprete) (const char*);
963
964 void Run_Appli(Standard_Boolean (*interprete) (const char*))
965 {
966   Tcl_Channel outChannel, inChannel ;
967   Interprete = interprete;
968
969 #ifdef _TK
970
971     /*
972      * Commands will come from standard input, so set up an event
973      * handler for standard input.  If the input device is aEvaluate the
974      * .rc file, if one has been specified, set up an event handler
975      * for standard input, and print a prompt if the input
976      * device is a terminal.
977      */
978   inChannel = Tcl_GetStdChannel(TCL_STDIN);
979   if (inChannel) {
980             Tcl_CreateChannelHandler(inChannel, TCL_READABLE, StdinProc,
981                     (ClientData) inChannel);
982         }
983
984   // Create a handler for the draw display
985
986   // Adding of the casting into void* to be able to compile on AO1
987   // ConnectionNumber(Draw_WindowDisplay) is an int 32 bits
988   //                    (void*) is a pointer      64 bits ???????
989
990 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
991 #if TCL_MAJOR_VERSION  < 8
992     Tk_CreateFileHandler((void*) ConnectionNumber(Draw_WindowDisplay),
993                          TK_READABLE, ProcessEvents,(ClientData) 0 );
994 #else
995     Tk_CreateFileHandler(ConnectionNumber(Draw_WindowDisplay),
996                          TK_READABLE, ProcessEvents,(ClientData) 0 );
997 #endif
998 #endif // __APPLE__
999
1000 #endif
1001
1002   if (tty) Prompt(theCommands.Interp(), 0);
1003   Prompt(theCommands.Interp(), 0);
1004
1005   outChannel = Tcl_GetStdChannel(TCL_STDOUT);
1006   if (outChannel) {
1007         Tcl_Flush(outChannel);
1008     }
1009   Tcl_DStringInit(&command);
1010
1011   /*
1012    * Loop infinitely, waiting for commands to execute.  When there
1013    * are no windows left, Tk_MainLoop returns and we exit.
1014    */
1015
1016 #ifdef _TK
1017
1018   if (Draw_VirtualWindows) {
1019     // main window will never shown
1020     // but main loop will parse all Xlib messages
1021     Tcl_Eval(theCommands.Interp(), "wm withdraw .");
1022   }
1023   Tk_MainLoop();
1024
1025 #else
1026
1027   fd_set readset;
1028   Standard_Integer count = ConnectionNumber(Draw_WindowDisplay);
1029   Standard_Integer numfd;
1030   while (1) {
1031       FD_ZERO(&readset);
1032       FD_SET(0,&readset);
1033       FD_SET(count,&readset);
1034 #ifdef HPUX
1035       numfd = select(count+1,(Integer*)&readset,NULL,NULL,NULL);
1036 #else
1037       numfd = select(count+1,&readset,NULL,NULL,NULL);
1038 #endif
1039       if (FD_ISSET(0,&readset))     StdinProc((ClientData)0,0);
1040       if (FD_ISSET(count,&readset)) ProcessEvents((ClientData)0,0);
1041     }
1042
1043 #endif
1044 }
1045
1046 //======================================================
1047 // funtion : Init_Appli()
1048 // purpose :
1049 //======================================================
1050 Standard_Boolean Init_Appli()
1051 {
1052   theCommands.Init();
1053   interp = theCommands.Interp();
1054
1055   Tcl_Init(interp) ;
1056   try {
1057     OCC_CATCH_SIGNALS
1058     Tk_Init(interp) ;
1059   } catch  (Standard_Failure) {
1060     cout <<" Pb au lancement de TK_Init "<<endl;
1061   }
1062
1063   Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
1064
1065   Tk_Window aMainWindow = Tk_MainWindow(interp) ;
1066   if (aMainWindow == NULL) {
1067 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
1068     fprintf(stderr, "%s\n", Tcl_GetStringResult(interp));
1069 #else
1070     fprintf(stderr, "%s\n", interp->result);
1071 #endif
1072     exit(1);
1073   }
1074 #if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1075   Tk_SetAppName(aMainWindow, "Draw");
1076 #else
1077   Tk_Name(aMainWindow) = Tk_GetUid(Tk_SetAppName(aMainWindow, "Draw"));
1078 #endif
1079
1080   Tk_GeometryRequest (aMainWindow, 200, 200);
1081
1082 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
1083   if (Draw_DisplayConnection.IsNull())
1084   {
1085     try
1086     {
1087       Draw_DisplayConnection = new Aspect_DisplayConnection();
1088     }
1089     catch (Standard_Failure)
1090     {
1091       std::cout << "Cannot open display. Interpret commands in batch mode." << std::endl;
1092       return Standard_False;
1093     }
1094   }
1095   if (Draw_WindowDisplay == NULL)
1096   {
1097     Draw_WindowDisplay = Draw_DisplayConnection->GetDisplay();
1098   }
1099   //
1100   // synchronize the display server : could be done within Tk_Init
1101   //
1102   XSynchronize(Draw_WindowDisplay, True);
1103   XSetInputFocus(Draw_WindowDisplay,
1104                  PointerRoot,
1105                  RevertToPointerRoot,
1106                  CurrentTime);
1107
1108   Draw_WindowScreen   = DefaultScreen(Draw_WindowDisplay);
1109   Draw_WindowColorMap = DefaultColormap(Draw_WindowDisplay,
1110                                         Draw_WindowScreen);
1111 #endif // __APPLE__
1112
1113   tty = isatty(0);
1114   Tcl_SetVar(interp,"tcl_interactive",(char*)(tty ? "1" : "0"), TCL_GLOBAL_ONLY);
1115 //  Tcl_SetVar(interp,"tcl_interactive",tty ? "1" : "0", TCL_GLOBAL_ONLY);
1116   return Standard_True;
1117 }
1118
1119 //======================================================
1120 // funtion : Destroy_Appli()
1121 // purpose :
1122 //======================================================
1123 void Destroy_Appli()
1124 {
1125   //XCloseDisplay(Draw_WindowDisplay);
1126 }
1127
1128 /*
1129  *----------------------------------------------------------------------
1130  *
1131  * StdinProc --
1132  *
1133  *        This procedure is invoked by the event dispatcher whenever
1134  *        standard input becomes readable.  It grabs the next line of
1135  *        input characters, adds them to a command being assembled, and
1136  *        executes the command if it's complete.
1137  *
1138  * Results:
1139  *        None.
1140  *
1141  * Side effects:
1142  *        Could be almost arbitrary, depending on the command that's
1143  *        typed.
1144  *
1145  *----------------------------------------------------------------------
1146  */
1147
1148     /* ARGSUSED */
1149 //static void StdinProc(ClientData clientData, int mask)
1150 static void StdinProc(ClientData clientData, int )
1151 {
1152   static int gotPartial = 0;
1153   char *cmd;
1154 //  int code, count;
1155   int count;
1156   Tcl_Channel chan = (Tcl_Channel) clientData;
1157
1158   // MSV Nov 2, 2001: patch for TCL 8.3: initialize line to avoid exception
1159   //                  when first user input is an empty string
1160   Tcl_DStringFree(&line);
1161   count = Tcl_Gets(chan, &line);
1162
1163   // MKV 26.05.05
1164 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)))
1165   Tcl_DString linetmp;
1166   Tcl_DStringInit(&linetmp);
1167   Tcl_UniChar * UniCharString;
1168   UniCharString = Tcl_UtfToUniCharDString(Tcl_DStringValue(&line),-1,&linetmp);
1169   Standard_Integer l = Tcl_UniCharLen(UniCharString);
1170   TCollection_AsciiString AsciiString("");
1171   Standard_Character Character;
1172   Standard_Integer i;
1173   for (i=0; i<l; i++) {
1174     Character = UniCharString[i];
1175     AsciiString.AssignCat(Character);
1176   }
1177   Tcl_DStringInit(&line);
1178   Tcl_DStringAppend(&line, AsciiString.ToCString(), -1);
1179 #endif
1180   if (count < 0) {
1181     if (!gotPartial) {
1182       if (tty) {
1183         Tcl_Exit(0);
1184       } else {
1185         Tcl_DeleteChannelHandler(chan, StdinProc, (ClientData) chan);
1186       }
1187       return;
1188     } else {
1189       count = 0;
1190     }
1191   }
1192
1193   (void) Tcl_DStringAppend(&command, Tcl_DStringValue(&line), -1);
1194   cmd = Tcl_DStringAppend(&command, "\n", -1);
1195   Tcl_DStringFree(&line);
1196   try {
1197     OCC_CATCH_SIGNALS
1198   if (!Tcl_CommandComplete(cmd)) {
1199     gotPartial = 1;
1200     goto prompt;
1201   }
1202   gotPartial = 0;
1203
1204   /*
1205    * Disable the stdin channel handler while evaluating the command;
1206    * otherwise if the command re-enters the event loop we might
1207    * process commands from stdin before the current command is
1208    * finished.  Among other things, this will trash the text of the
1209    * command being evaluated.
1210    */
1211
1212   Tcl_CreateChannelHandler(chan, 0, StdinProc, (ClientData) chan);
1213
1214
1215   /*
1216    * Disable the stdin file handler while evaluating the command;
1217    * otherwise if the command re-enters the event loop we might
1218    * process commands from stdin before the current command is
1219    * finished.  Among other things, this will trash the text of the
1220    * command being evaluated.
1221    */
1222
1223 #ifdef _TK
1224    //  Tk_CreateFileHandler(0, 0, StdinProc, (ClientData) 0);
1225 #endif
1226     //
1227     // xab average to avoid an output SIGBUS of DRAW
1228     // to ultimately prescise or remove once
1229     // the problem of free on the global variable at the average
1230     //
1231     //
1232
1233   Interprete(cmd);
1234
1235
1236   Tcl_CreateChannelHandler(chan, TCL_READABLE, StdinProc,
1237                            (ClientData) chan);
1238   Tcl_DStringFree(&command);
1239
1240   /*
1241    * Output a prompt.
1242    */
1243
1244 prompt:
1245   if (tty) Prompt(interp, gotPartial);
1246
1247  } catch (Standard_Failure) {}
1248
1249 }
1250
1251 #else
1252
1253 // Source Specifique WNT
1254
1255 /****************************************************\
1256 *  Draw_Window.cxx :
1257 *
1258 \****************************************************/
1259
1260 #include "Draw_Window.hxx"
1261 #include "DrawRessource.h"
1262 #include "init.h"
1263
1264 #include <Draw_Appli.hxx>
1265 #include <OSD.hxx>
1266
1267 #include <tk.h>
1268
1269 #define PENWIDTH 1
1270 #define CLIENTWND 0
1271 // Position of information in the extra memory
1272
1273 // indicates SUBSYSTEM:CONSOLE linker option, to be set to True in main()
1274 Standard_EXPORT
1275 Standard_Boolean Draw_IsConsoleSubsystem = Standard_False;
1276
1277
1278 Standard_Boolean Draw_BlackBackGround = Standard_True;
1279
1280 // Creation of color stylos
1281 HPEN colorPenTab[MAXCOLOR] = {CreatePen(PS_SOLID, PENWIDTH, RGB(255,255,255)),
1282                               CreatePen(PS_SOLID, PENWIDTH, RGB(255,0,0)),
1283                               CreatePen(PS_SOLID, PENWIDTH, RGB(0,255,0)),
1284                               CreatePen(PS_SOLID, PENWIDTH, RGB(0,0,255)),
1285                               CreatePen(PS_SOLID, PENWIDTH, RGB(0,255,255)),
1286                               CreatePen(PS_SOLID, PENWIDTH, RGB(255,215,0)),
1287                               CreatePen(PS_SOLID, PENWIDTH, RGB(255,0,255)),
1288                               CreatePen(PS_SOLID, PENWIDTH, RGB(255,52,179)),
1289                               CreatePen(PS_SOLID, PENWIDTH, RGB(255,165,0)),
1290                               CreatePen(PS_SOLID, PENWIDTH, RGB(255,228,225)),
1291                               CreatePen(PS_SOLID, PENWIDTH, RGB(255,160,122)),
1292                               CreatePen(PS_SOLID, PENWIDTH, RGB(199,21,133)),
1293                               CreatePen(PS_SOLID, PENWIDTH, RGB(255,255,0)),
1294                               CreatePen(PS_SOLID, PENWIDTH, RGB(240,230,140)),
1295                               CreatePen(PS_SOLID, PENWIDTH, RGB(255,127,80))};
1296
1297 // Correspondance mode X11 and WINDOWS NT
1298 int modeTab[16] = {R2_BLACK, R2_MASKPEN, R2_MASKPENNOT, R2_COPYPEN,
1299                    R2_MASKNOTPEN, R2_NOP, R2_XORPEN, R2_MERGEPEN,
1300                    R2_NOTMASKPEN, R2_NOTXORPEN, R2_NOT, R2_MERGEPENNOT,
1301                    R2_NOTCOPYPEN, R2_MERGENOTPEN, R2_NOTMERGEPEN, R2_WHITE};
1302
1303 /*--------------------------------------------------------*\
1304 |  CREATE DRAW WINDOW PROCEDURE
1305 \*--------------------------------------------------------*/
1306 HWND DrawWindow::CreateDrawWindow(HWND hWndClient, int nitem)
1307 {
1308   if (Draw_IsConsoleSubsystem) {
1309     HWND aWin = CreateWindow (DRAWCLASS, DRAWTITLE,
1310                               WS_OVERLAPPEDWINDOW,
1311                               1,1,1,1,
1312                               NULL, NULL,::GetModuleHandle(NULL), NULL);
1313     if (!Draw_VirtualWindows)
1314     {
1315       SetWindowPos(aWin, HWND_TOPMOST, 1,1,1,1, SWP_NOMOVE);
1316       SetWindowPos(aWin, HWND_NOTOPMOST, 1,1,1,1, SWP_NOMOVE);
1317     }
1318     return aWin;
1319   }
1320   else {
1321     HANDLE hInstance;
1322     hInstance = (HANDLE)GetWindowLongPtr(hWndClient,GWLP_HINSTANCE);
1323
1324     return CreateMDIWindow(DRAWCLASS, DRAWTITLE,
1325                            WS_CAPTION | WS_CHILD | WS_THICKFRAME,
1326                            1,1,0,0,
1327                            hWndClient, (HINSTANCE)hInstance, nitem);
1328   }
1329 }
1330
1331
1332 /*--------------------------------------------------------*\
1333 |  DRAW WINDOW PROCEDURE
1334 \*--------------------------------------------------------*/
1335 LRESULT APIENTRY DrawWindow::DrawProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam )
1336 {
1337   DrawWindow* localObjet = (DrawWindow*)GetWindowLongPtr(hWnd, CLIENTWND);
1338   if (!localObjet)
1339     {
1340       if (Draw_IsConsoleSubsystem)
1341         return (DefWindowProc(hWnd, wMsg, wParam, lParam));
1342       else
1343         return(DefMDIChildProc(hWnd, wMsg, wParam, lParam));
1344     }
1345
1346   PAINTSTRUCT ps;
1347
1348   switch(wMsg)
1349   {
1350   case WM_PAINT :
1351     BeginPaint(hWnd, &ps);
1352     if (localObjet->GetUseBuffer())
1353       localObjet->Redraw();
1354     else
1355       localObjet->WExpose();
1356     EndPaint(hWnd, &ps);
1357     return 0l;
1358     break;
1359
1360   case WM_SIZE:
1361     if (localObjet->GetUseBuffer()) {
1362       localObjet->InitBuffer();
1363       localObjet->WExpose();
1364       localObjet->Redraw();
1365       return 0l;
1366     }
1367
1368   default:
1369     if (Draw_IsConsoleSubsystem)
1370       return (DefWindowProc(hWnd, wMsg, wParam, lParam));
1371     else
1372       return(DefMDIChildProc(hWnd, wMsg, wParam, lParam));
1373   }
1374 }
1375
1376
1377
1378 /*
1379 **  IMPLEMENTATION of the CLASS DRAWWINDOW
1380  */
1381
1382 /*--------------------------------------------------------*\
1383 | Initialization of static variables of DrawWindow
1384 \*--------------------------------------------------------*/
1385
1386 DrawWindow* DrawWindow::firstWindow = NULL;
1387 HWND DrawWindow::hWndClientMDI = 0;
1388
1389 /*--------------------------------------------------------*\
1390 | Constructors of Draw_Window
1391 \*--------------------------------------------------------*/
1392
1393 // Default Constructor
1394 //________________________
1395 DrawWindow::DrawWindow() :
1396         win(0),
1397         next(firstWindow),
1398         previous(NULL),
1399         myMemHbm(NULL),
1400         myUseBuffer(Standard_False)
1401 {
1402   if (firstWindow) firstWindow->previous = this;
1403   firstWindow = this;
1404 }
1405
1406 //________________________
1407 DrawWindow::DrawWindow(char* title,
1408                        Standard_Integer X, Standard_Integer Y,
1409                        Standard_Integer dX,Standard_Integer dY) :
1410        win(0),        next(firstWindow), previous(NULL), myMemHbm(NULL), myUseBuffer(Standard_False)
1411 {
1412   if (firstWindow) firstWindow->previous = this;
1413   firstWindow = this;
1414   Init(X, Y, dX, dY);
1415   SetTitle(title);
1416 }
1417 DrawWindow::DrawWindow(char* title,
1418                        Standard_Integer X, Standard_Integer Y,
1419                        Standard_Integer dX,Standard_Integer dY,
1420                        HWND theWin) :
1421        win(theWin),next(firstWindow), previous(NULL), myMemHbm(NULL), myUseBuffer(Standard_False)
1422 {
1423   if (firstWindow) firstWindow->previous = this;
1424   firstWindow = this;
1425   Init(X, Y, dX, dY);
1426   SetTitle(title);
1427 }
1428
1429
1430
1431 /*--------------------------------------------------------*\
1432 | Destructor of DrawWindow
1433 \*--------------------------------------------------------*/
1434 DrawWindow::~DrawWindow()
1435 {
1436   if (previous)
1437     previous->next = next;
1438   else
1439     firstWindow = next;
1440   if (next)
1441     next->previous = previous;
1442
1443   // Delete 'off-screen drawing'-related objects
1444   if (myMemHbm) {
1445     DeleteObject(myMemHbm);
1446     myMemHbm = NULL;
1447   }
1448 }
1449
1450
1451
1452 /*--------------------------------------------------------*\
1453 |  Init
1454 \*--------------------------------------------------------*/
1455 void DrawWindow::Init(Standard_Integer theXLeft, Standard_Integer theYTop,
1456                       Standard_Integer theWidth, Standard_Integer theHeight)
1457 {
1458   if (win == NULL)
1459   {
1460     win = CreateDrawWindow(hWndClientMDI, 0);
1461   }
1462
1463   // include decorations in the window dimensions
1464   // to reproduce same behaviour of Xlib window.
1465   DWORD aWinStyle   = GetWindowLong (win, GWL_STYLE);
1466   DWORD aWinStyleEx = GetWindowLong (win, GWL_EXSTYLE);
1467   HMENU aMenu       = GetMenu (win);
1468
1469   RECT aRect;
1470   aRect.top    = theYTop;
1471   aRect.bottom = theYTop + theHeight;
1472   aRect.left   = theXLeft;
1473   aRect.right  = theXLeft + theWidth;
1474   AdjustWindowRectEx (&aRect, aWinStyle, aMenu != NULL ? TRUE : FALSE, aWinStyleEx);
1475
1476   SetPosition  (aRect.left, aRect.top);
1477   SetDimension (aRect.right - aRect.left, aRect.bottom - aRect.top);
1478   // Save the pointer at the instance associated to the window
1479   SetWindowLongPtr(win, CLIENTWND, (LONG_PTR)this);
1480   HDC hDC = GetDC(win);
1481   SetBkColor(hDC, RGB(0, 0, 0));
1482   myCurrPen  = 3;
1483   myCurrMode = 3;
1484   SelectObject(hDC, colorPenTab[myCurrPen]); // Default pencil
1485   SelectObject(hDC, GetStockObject(BLACK_BRUSH));
1486   SetTextColor(hDC, RGB(0,0,255));
1487   ReleaseDC(win, hDC);
1488
1489   if (Draw_VirtualWindows)
1490   {
1491     // create a virtual window
1492     SetUseBuffer (Standard_True);
1493   }
1494 }
1495
1496 /*--------------------------------------------------------*\
1497 |  SetUseBuffer
1498 \*--------------------------------------------------------*/
1499 void DrawWindow::SetUseBuffer(Standard_Boolean use)
1500 {
1501   myUseBuffer = use;
1502   InitBuffer();
1503 }
1504
1505 /*--------------------------------------------------------*\
1506 |  InitBuffer
1507 \*--------------------------------------------------------*/
1508 void DrawWindow::InitBuffer()
1509 {
1510   if (myUseBuffer) {
1511     RECT rc;
1512     HDC hDC = GetDC(win);
1513     GetClientRect(win, &rc);
1514     if (myMemHbm) {
1515       BITMAP aBmp;
1516       GetObject(myMemHbm, sizeof(BITMAP), &aBmp);
1517       if (rc.right-rc.left == aBmp.bmWidth && rc.bottom-rc.top == aBmp.bmHeight) return;
1518       DeleteObject(myMemHbm);
1519     }
1520     myMemHbm = (HBITMAP)CreateCompatibleBitmap(hDC,
1521                                       rc.right-rc.left,
1522                                       rc.bottom-rc.top);
1523     HDC aMemDC      = GetMemDC(hDC);
1524     FillRect(aMemDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
1525     ReleaseMemDC(aMemDC);
1526     ReleaseDC(win, hDC);
1527   }
1528   else {
1529     if (myMemHbm) {
1530       DeleteObject(myMemHbm);
1531       myMemHbm = NULL;
1532     }
1533   }
1534 }
1535
1536 /*--------------------------------------------------------*\
1537 |  GetMemDC
1538 \*--------------------------------------------------------*/
1539 HDC DrawWindow::GetMemDC(HDC theWinDC)
1540 {
1541   if (!myUseBuffer) return NULL;
1542
1543   HDC aWorkDC = CreateCompatibleDC(theWinDC);
1544   myOldHbm = (HBITMAP)SelectObject(aWorkDC, myMemHbm);
1545   SetROP2(aWorkDC, modeTab[myCurrMode]);
1546   SelectObject(aWorkDC, colorPenTab[myCurrPen]);
1547   SetBkColor(aWorkDC, RGB(0, 0, 0));
1548   SelectObject(aWorkDC, GetStockObject(BLACK_BRUSH));
1549   SetTextColor(aWorkDC, RGB(0,0,255));
1550   return aWorkDC;
1551 }
1552
1553
1554 /*--------------------------------------------------------*\
1555 |  ReleaseMemDC
1556 \*--------------------------------------------------------*/
1557 void DrawWindow::ReleaseMemDC(HDC theMemDC)
1558 {
1559   if (!myUseBuffer || !theMemDC) return;
1560
1561   if (myOldHbm) SelectObject(theMemDC, myOldHbm);
1562   DeleteDC(theMemDC);
1563 }
1564
1565
1566 /*--------------------------------------------------------*\
1567 |  SetPosition
1568 \*--------------------------------------------------------*/
1569 void DrawWindow::SetPosition(Standard_Integer posX, Standard_Integer posY)
1570 {
1571   SetWindowPos(win, 0,
1572                posX, posY,
1573                0, 0,
1574                SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
1575 }
1576
1577
1578 /*--------------------------------------------------------*\
1579 |  SetDimension
1580 \*--------------------------------------------------------*/
1581 void DrawWindow::SetDimension(Standard_Integer dimX, Standard_Integer dimY)
1582 {
1583   SetWindowPos(win, 0,
1584                0, 0,
1585                dimX, dimY,
1586                SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
1587 }
1588
1589
1590 /*--------------------------------------------------------*\
1591 |  GetPosition
1592 \*--------------------------------------------------------*/
1593 void DrawWindow::GetPosition(Standard_Integer &dimX,
1594                              Standard_Integer &dimY)
1595 {
1596   RECT rect;
1597   GetWindowRect(win, &rect);
1598
1599   POINT point;
1600   point.x = rect.left;
1601   point.y = rect.top;
1602
1603   ScreenToClient(hWndClientMDI, &point);
1604   dimX = point.x;
1605   dimY = point.y;
1606 }
1607
1608
1609 /*--------------------------------------------------------*\
1610 |  HeightWin
1611 \*--------------------------------------------------------*/
1612 Standard_Integer DrawWindow::HeightWin() const
1613 {
1614   RECT rect;
1615   GetClientRect(win, &rect);
1616   return(rect.bottom-rect.top);
1617 }
1618
1619
1620 /*--------------------------------------------------------*\
1621 |  WidthWin
1622 \*--------------------------------------------------------*/
1623 Standard_Integer DrawWindow::WidthWin() const
1624 {
1625   RECT rect;
1626   GetClientRect(win, &rect);
1627   return(rect.right-rect.left);
1628 }
1629
1630
1631 /*--------------------------------------------------------*\
1632 |  SetTitle
1633 \*--------------------------------------------------------*/
1634 void DrawWindow::SetTitle(char* title)
1635 {
1636   SetWindowText(win, title);
1637 }
1638
1639
1640 /*--------------------------------------------------------*\
1641 |  GetTitle
1642 |    Attention do not forget to unallocate the memory
1643 \*--------------------------------------------------------*/
1644 char* DrawWindow::GetTitle()
1645 {
1646   char* title=new char[31];
1647   GetWindowText(win, title, 30);
1648   return title;
1649 }
1650
1651
1652 /*--------------------------------------------------------*\
1653 |  DisplayWindow
1654 \*--------------------------------------------------------*/
1655 void DrawWindow::DisplayWindow()
1656 {
1657   if (Draw_VirtualWindows)
1658   {
1659     return;
1660   }
1661   ShowWindow (win, SW_SHOW);
1662   UpdateWindow (win);
1663 }
1664
1665
1666 /*--------------------------------------------------------*\
1667 |  Hide
1668 \*--------------------------------------------------------*/
1669 void DrawWindow::Hide()
1670 {
1671   ShowWindow(win, SW_HIDE);
1672 }
1673
1674
1675 /*--------------------------------------------------------*\
1676 |  Destroy
1677 \*--------------------------------------------------------*/
1678 void DrawWindow::Destroy()
1679 {
1680   DestroyWindow(win);
1681 }
1682
1683
1684
1685 /*--------------------------------------------------------*\
1686 |  Clear
1687 \*--------------------------------------------------------*/
1688 void DrawWindow::Clear()
1689 {
1690   HDC hDC = GetDC(win);
1691   HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
1692
1693   SaveDC(aWorkDC);
1694   SelectObject(aWorkDC,GetStockObject(BLACK_PEN));
1695   Rectangle(aWorkDC, 0, 0, WidthWin(), HeightWin());
1696   RestoreDC(aWorkDC,-1);
1697
1698   if (myUseBuffer) ReleaseMemDC(aWorkDC);
1699   ReleaseDC(win,hDC);
1700 }
1701
1702 /*--------------------------------------------------------*\
1703 |  SaveBitmap
1704 \*--------------------------------------------------------*/
1705 static Standard_Boolean SaveBitmap (HBITMAP     theHBitmap,
1706                                     const char* theFileName)
1707 {
1708   // Get informations about the bitmap
1709   BITMAP aBitmap;
1710   if (GetObject (theHBitmap, sizeof(BITMAP), (LPSTR )&aBitmap) == 0)
1711   {
1712     return Standard_False;
1713   }
1714
1715   Image_AlienPixMap anImage;
1716   const Standard_Size aSizeRowBytes = Standard_Size(aBitmap.bmWidth) * 4;
1717   if (!anImage.InitTrash (Image_PixMap::ImgBGR32, Standard_Size(aBitmap.bmWidth), Standard_Size(aBitmap.bmHeight), aSizeRowBytes))
1718   {
1719     return Standard_False;
1720   }
1721   anImage.SetTopDown (false);
1722
1723   // Setup image data
1724   BITMAPINFOHEADER aBitmapInfo;
1725   memset (&aBitmapInfo, 0, sizeof(BITMAPINFOHEADER));
1726   aBitmapInfo.biSize        = sizeof(BITMAPINFOHEADER);
1727   aBitmapInfo.biWidth       = aBitmap.bmWidth;
1728   aBitmapInfo.biHeight      = aBitmap.bmHeight; // positive means bottom-up!
1729   aBitmapInfo.biPlanes      = 1;
1730   aBitmapInfo.biBitCount    = 32; // use 32bit for automatic word-alignment per row
1731   aBitmapInfo.biCompression = BI_RGB;
1732
1733   // Copy the pixels
1734   HDC aDC = GetDC (NULL);
1735   Standard_Boolean isSuccess = GetDIBits (aDC, theHBitmap,
1736                                           0,                           // first scan line to set
1737                                           aBitmap.bmHeight,            // number of scan lines to copy
1738                                           anImage.ChangeData(),        // array for bitmap bits
1739                                           (LPBITMAPINFO )&aBitmapInfo, // bitmap data info
1740                                           DIB_RGB_COLORS) != 0;
1741   ReleaseDC (NULL, aDC);
1742   return isSuccess && anImage.Save (theFileName);
1743 }
1744
1745 /*--------------------------------------------------------*\
1746 |  Save
1747 \*--------------------------------------------------------*/
1748 Standard_Boolean DrawWindow::Save (const char* theFileName) const
1749 {
1750   if (myUseBuffer)
1751   {
1752     return SaveBitmap (myMemHbm, theFileName);
1753   }
1754
1755   RECT aRect;
1756   GetClientRect (win, &aRect);
1757   int aWidth  = aRect.right  - aRect.left;
1758   int aHeight = aRect.bottom - aRect.top;
1759
1760   // Prepare the DCs
1761   HDC aDstDC = GetDC (NULL);
1762   HDC aSrcDC = GetDC (win); // we copy only client area
1763   HDC aMemDC = CreateCompatibleDC (aDstDC);
1764
1765   // Copy the screen to the bitmap
1766   HBITMAP anHBitmapDump = CreateCompatibleBitmap (aDstDC, aWidth, aHeight);
1767   HBITMAP anHBitmapOld = (HBITMAP )SelectObject (aMemDC, anHBitmapDump);
1768   BitBlt (aMemDC, 0, 0, aWidth, aHeight, aSrcDC, 0, 0, SRCCOPY);
1769
1770   Standard_Boolean isSuccess = SaveBitmap (anHBitmapDump, theFileName);
1771
1772   // Free objects
1773   DeleteObject (SelectObject (aMemDC, anHBitmapOld));
1774   DeleteDC (aMemDC);
1775
1776   return isSuccess;
1777 }
1778
1779 /*--------------------------------------------------------*\
1780 |  DrawString
1781 \*--------------------------------------------------------*/
1782 void DrawWindow::DrawString(int x,int y, char* text)
1783 {
1784   HDC hDC = GetDC(win);
1785   HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
1786
1787   TextOut(aWorkDC, x, y, text, (int )strlen(text));
1788
1789   if (myUseBuffer) ReleaseMemDC(aWorkDC);
1790   ReleaseDC(win,hDC);
1791 }
1792
1793 /*--------------------------------------------------------*\
1794 |  DrawSegments
1795 \*--------------------------------------------------------*/
1796 void DrawWindow::DrawSegments(Segment *tab, int nbElem)
1797 {
1798   HDC hDC = GetDC(win);
1799   HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
1800
1801   for(int i = 0 ; i < nbElem ; i++)
1802   {
1803     MoveToEx(aWorkDC, tab[i].x1, tab[i].y1, NULL);
1804     LineTo(aWorkDC, tab[i].x2, tab[i].y2);
1805   }
1806
1807   if (myUseBuffer) ReleaseMemDC(aWorkDC);
1808   ReleaseDC(win,hDC);
1809 }
1810
1811 /*--------------------------------------------------------*\
1812 |  Redraw
1813 \*--------------------------------------------------------*/
1814 void DrawWindow::Redraw()
1815 {
1816   if (myUseBuffer) {
1817     HDC hDC = GetDC(win);
1818     RECT rc;
1819     GetClientRect(win, &rc);
1820     HDC aMemDC = GetMemDC(hDC);
1821     BitBlt(hDC,
1822            rc.left, rc.top,
1823            rc.right-rc.left, rc.bottom-rc.top,
1824            aMemDC,
1825            0, 0, SRCCOPY);
1826     ReleaseMemDC(aMemDC);
1827     ReleaseDC(win,hDC);
1828   }
1829 }
1830
1831 /*--------------------------------------------------------*\
1832 |  SetMode
1833 \*--------------------------------------------------------*/
1834 void DrawWindow::SetMode(int mode)
1835 {
1836   HDC hDC = GetDC(win);
1837   myCurrMode = mode;
1838   SetROP2(hDC, modeTab[mode]);
1839   ReleaseDC(win,hDC);
1840 }
1841
1842
1843 /*--------------------------------------------------------*\
1844 |  SetColor
1845 \*--------------------------------------------------------*/
1846 void DrawWindow::SetColor(Standard_Integer color)
1847 {
1848   HDC hDC = GetDC(win);
1849   myCurrPen = color;
1850   SelectObject(hDC,colorPenTab[color]);
1851   ReleaseDC(win,hDC);
1852 }
1853
1854
1855 /*--------------------------------------------------------*\
1856 |  WExpose
1857 \*--------------------------------------------------------*/
1858 void DrawWindow::WExpose()
1859 {
1860 }
1861
1862
1863 /*--------------------------------------------------------*\
1864 |  WButtonPress
1865 \*--------------------------------------------------------*/
1866 void DrawWindow::WButtonPress(const Standard_Integer,
1867                                const Standard_Integer,
1868                                const Standard_Integer&)
1869 {
1870 }
1871
1872
1873 /*--------------------------------------------------------*\
1874 |  WButtonRelease
1875 \*--------------------------------------------------------*/
1876 void DrawWindow::WButtonRelease(const Standard_Integer,
1877                                  const Standard_Integer,
1878                                  const Standard_Integer&)
1879 {
1880 }
1881
1882
1883 /*--------------------------------------------------------*\
1884 |  WMotionNotify
1885 \*--------------------------------------------------------*/
1886 void Draw_Window::WMotionNotify(const Standard_Integer ,
1887                                 const Standard_Integer )
1888 {
1889 }
1890
1891
1892 /*--------------------------------------------------------*\
1893 |  WConfigureNotify
1894 \*--------------------------------------------------------*/
1895 void DrawWindow::WConfigureNotify(const Standard_Integer,
1896                                    const Standard_Integer,
1897                                    const Standard_Integer,
1898                                    const Standard_Integer)
1899 {
1900 }
1901
1902
1903 /*--------------------------------------------------------*\
1904 |  WUnmapNotify
1905 \*--------------------------------------------------------*/
1906 void DrawWindow::WUnmapNotify()
1907 {
1908 }
1909
1910
1911
1912 /*
1913 **  IMPLEMENTATION of the CLASS SEGMENT
1914  */
1915
1916 /*--------------------------------------------------------*\
1917 |  Init
1918 \*--------------------------------------------------------*/
1919
1920 void Segment::Init(Standard_Integer a1, Standard_Integer a2,
1921                    Standard_Integer a3, Standard_Integer a4)
1922 {
1923   x1=a1;
1924   y1=a2;
1925   x2=a3;
1926   y2=a4;
1927 }
1928
1929 static DWORD WINAPI tkLoop(VOID);
1930 #ifdef _TK
1931 static Tk_Window mainWindow;
1932 #endif
1933
1934 //* threads sinchronization *//
1935 DWORD  dwMainThreadId;
1936 console_semaphore_value volatile console_semaphore = WAIT_CONSOLE_COMMAND;
1937 //char console_command[1000];
1938 #define COMMAND_SIZE 1000     /* Console Command size */
1939 char console_command[COMMAND_SIZE];
1940 bool volatile isTkLoopStarted = false;
1941
1942 /*--------------------------------------------------------*\
1943 |  Init_Appli
1944 \*--------------------------------------------------------*/
1945 Standard_Boolean Init_Appli(HINSTANCE hInst,
1946                             HINSTANCE hPrevInst, int nShow, HWND& hWndFrame )
1947 {
1948   DWORD IDThread;
1949   HANDLE hThread;
1950   console_semaphore = STOP_CONSOLE;
1951   theCommands.Init();
1952   interp = theCommands.Interp();
1953   Tcl_Init(interp) ;
1954
1955   dwMainThreadId = GetCurrentThreadId();
1956
1957   //necessary for normal Tk operation
1958   hThread = CreateThread(NULL, // no security attributes
1959                            0,                           // use default stack size
1960                            (LPTHREAD_START_ROUTINE) tkLoop, // thread function
1961                            NULL,                    // no thread function argument
1962                            0,                       // use default creation flags
1963                            &IDThread);
1964   if (!hThread) {
1965     cout << "Tcl/Tk main loop thread not created. Switching to batch mode..." << endl;
1966 #ifdef _TK
1967     try {
1968       OCC_CATCH_SIGNALS
1969       Tk_Init(interp) ;
1970     } catch  (Standard_Failure) {
1971       cout <<" Pb au lancement de TK_Init "<<endl;
1972     }
1973
1974     Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
1975 #endif
1976     //since the main Tcl/Tk loop wasn't created --> switch to batch mode
1977     return Standard_False;
1978   }
1979
1980   // san - 06/08/2002 - Time for tkLoop to start; Tk fails to initialize otherwise
1981   while (!isTkLoopStarted)
1982     Sleep(10);
1983
1984   // Saving of window classes
1985   if(!hPrevInst)
1986     if(!RegisterAppClass(hInst))
1987       return(Standard_False);
1988
1989   /*
1990    ** Enter the application message-polling loop.  This is the anchor for
1991    ** the application.
1992   */
1993   hWndFrame = !Draw_IsConsoleSubsystem ? CreateAppWindow (hInst) : NULL;
1994   if (hWndFrame != NULL)
1995   {
1996     ShowWindow(hWndFrame,nShow);
1997     UpdateWindow(hWndFrame);
1998   }
1999
2000   return Standard_True;
2001 }
2002
2003 Standard_Boolean Draw_Interprete (const char*);
2004
2005 /*--------------------------------------------------------*\
2006 |  readStdinThreadFunc
2007 \*--------------------------------------------------------*/
2008 static DWORD WINAPI readStdinThreadFunc(VOID)
2009 {
2010   if (!Draw_IsConsoleSubsystem) return 1;
2011   for(;;) {
2012     while (console_semaphore != WAIT_CONSOLE_COMMAND)
2013       Sleep(100);
2014       if (fgets(console_command,COMMAND_SIZE,stdin))
2015       {
2016         console_semaphore = HAS_CONSOLE_COMMAND;
2017       }
2018   }
2019 }
2020
2021 /*--------------------------------------------------------*\
2022 |  exitProc: finalization handler for Tcl/Tk thread. Forces parent process to die
2023 \*--------------------------------------------------------*/
2024 void exitProc(ClientData /*dc*/)
2025 {
2026   HANDLE proc = GetCurrentProcess();
2027   TerminateProcess(proc, 0);
2028 }
2029
2030 /*--------------------------------------------------------*\
2031 |  tkLoop: implements Tk_Main()-like behaviour in a separate thread
2032 \*--------------------------------------------------------*/
2033 static DWORD WINAPI tkLoop(VOID)
2034 {
2035   Tcl_CreateExitHandler(exitProc, 0);
2036 #if (TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5))
2037   Tcl_RegisterChannel(theCommands.Interp(),  Tcl_GetStdChannel(TCL_STDIN));
2038   Tcl_RegisterChannel(theCommands.Interp(),  Tcl_GetStdChannel(TCL_STDOUT));
2039   Tcl_RegisterChannel(theCommands.Interp(),  Tcl_GetStdChannel(TCL_STDERR));
2040 #endif
2041
2042 #ifdef _TK
2043   // initialize the Tk library if not in 'virtual windows' mode
2044   // (virtual windows are created by OCCT with native APIs,
2045   // thus Tk will be useless)
2046   if (!Draw_VirtualWindows)
2047   {
2048     try
2049     {
2050       OCC_CATCH_SIGNALS
2051       Standard_Integer res = Tk_Init (interp);
2052       if (res != TCL_OK)
2053       {
2054 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
2055         cout << "tkLoop: error in Tk initialization. Tcl reported: " << Tcl_GetStringResult(interp) << endl;
2056 #else
2057         cout << "tkLoop: error in Tk initialization. Tcl reported: " << interp->result << endl;
2058 #endif
2059       }
2060     }
2061     catch (Standard_Failure)
2062     {
2063       cout << "tkLoop: exception in TK_Init\n";
2064     }
2065     Tcl_StaticPackage (interp, "Tk", Tk_Init, (Tcl_PackageInitProc* ) NULL);
2066     mainWindow = Tk_MainWindow (interp);
2067     if (mainWindow == NULL)
2068     {
2069 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
2070       fprintf (stderr, "%s\n", Tcl_GetStringResult(interp));
2071 #else
2072       fprintf (stderr, "%s\n", interp->result);
2073 #endif
2074       cout << "tkLoop: Tk_MainWindow() returned NULL. Exiting...\n";
2075       Tcl_Exit (0);
2076     }
2077     Tk_Name(mainWindow) = Tk_GetUid (Tk_SetAppName (mainWindow, "Draw"));
2078   }
2079 #endif //#ifdef _TK
2080
2081   // set signal handler in the new thread
2082   OSD::SetSignal();
2083
2084   // inform the others that we have started
2085   isTkLoopStarted = true;
2086
2087   while (console_semaphore == STOP_CONSOLE)
2088     Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
2089
2090   if (Draw_IsConsoleSubsystem && console_semaphore == WAIT_CONSOLE_COMMAND)
2091     Prompt(interp, 0);
2092
2093   //process a command
2094   Standard_Boolean toLoop = Standard_True;
2095   while (toLoop)
2096   {
2097     while(Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT));
2098     if (console_semaphore == HAS_CONSOLE_COMMAND)
2099     {
2100       if (Draw_Interprete (console_command))
2101       {
2102         if (Draw_IsConsoleSubsystem) Prompt (interp, 0);
2103       }
2104       else
2105       {
2106         if (Draw_IsConsoleSubsystem) Prompt (interp, 1);
2107       }
2108       console_semaphore = WAIT_CONSOLE_COMMAND;
2109     }
2110     else
2111     {
2112       Sleep(100);
2113     }
2114   #ifdef _TK
2115     // We should not exit until the Main Tk window is closed
2116     toLoop = (Tk_GetNumMainWindows() > 0) || Draw_VirtualWindows;
2117   #endif
2118   }
2119   Tcl_Exit(0);
2120   return 0;
2121 }
2122
2123
2124 /*--------------------------------------------------------*\
2125 |  Run_Appli
2126 \*--------------------------------------------------------*/
2127 void Run_Appli(HWND hWnd)
2128 {
2129   MSG msg;
2130   HACCEL hAccel = NULL;
2131
2132   msg.wParam = 1;
2133
2134 //  if (!(hAccel = LoadAccelerators (hInstance, MAKEINTRESOURCE(ACCEL_ID))))
2135 //        MessageBox(hWnd, "MDI: Load Accel failure!", "Error", MB_OK);
2136   DWORD IDThread;
2137   HANDLE hThread;
2138   if (Draw_IsConsoleSubsystem) {
2139     hThread = CreateThread(NULL, // no security attributes
2140                            0,                           // use default stack size
2141                            (LPTHREAD_START_ROUTINE) readStdinThreadFunc, // thread function
2142                            NULL,                    // no thread function argument
2143                            0,                       // use default creation flags
2144                            &IDThread);              // returns thread identifier
2145     if (!hThread) {
2146       cout << "pb in creation of the thread reading stdin" << endl;
2147       Draw_IsConsoleSubsystem = Standard_False;
2148       Init_Appli(GetModuleHandle(NULL),
2149                  GetModuleHandle(NULL),
2150                  1, hWnd); // reinit => create MDI client wnd
2151     }
2152   }
2153
2154   //turn on the command interpretation mechanism (regardless of the mode)
2155   if (console_semaphore == STOP_CONSOLE)
2156     console_semaphore = WAIT_CONSOLE_COMMAND;
2157
2158   //simple Win32 message loop
2159   while (GetMessage(&msg, NULL, 0, 0) > 0)
2160   {
2161     if (!TranslateAccelerator(hWnd, hAccel, &msg))
2162     {
2163       TranslateMessage(&msg);
2164       DispatchMessage(&msg);
2165     }
2166   }
2167   ExitProcess(0);
2168 }
2169
2170
2171 /*--------------------------------------------------------*\
2172 |  Destroy_Appli
2173 \*--------------------------------------------------------*/
2174 void Destroy_Appli(HINSTANCE hInst)
2175 {
2176   UnregisterAppClass(hInst);
2177   for (int i = 0 ; i < MAXCOLOR ; i++)
2178     DeleteObject(colorPenTab[i]);
2179 }
2180
2181 /*--------------------------------------------------------*\
2182 |  SelectWait
2183 \*--------------------------------------------------------*/
2184 void DrawWindow::SelectWait(HANDLE& hWnd, int& x, int& y, int& button)
2185 {
2186   MSG msg;
2187
2188   msg.wParam = 1;
2189
2190   GetMessage(&msg,NULL,0,0);
2191   while((msg.message != WM_RBUTTONDOWN && msg.message != WM_LBUTTONDOWN) ||
2192         ! ( Draw_IsConsoleSubsystem || IsChild(DrawWindow::hWndClientMDI,msg.hwnd)) )
2193     GetMessage(&msg,NULL,0,0);
2194
2195   hWnd = msg.hwnd;
2196   x = LOWORD(msg.lParam);
2197   y = HIWORD(msg.lParam);
2198   if (msg.message == WM_LBUTTONDOWN)
2199     button = 1;
2200   else
2201     button = 3;
2202 }
2203
2204 /*--------------------------------------------------------*\
2205 |  SelectNoWait
2206 \*--------------------------------------------------------*/
2207 void DrawWindow::SelectNoWait(HANDLE& hWnd, int& x, int& y, int& button)
2208 {
2209   MSG msg;
2210
2211   msg.wParam = 1;
2212
2213   GetMessage(&msg,NULL,0,0);
2214   while((msg.message != WM_RBUTTONDOWN && msg.message != WM_LBUTTONDOWN &&
2215         msg.message != WM_MOUSEMOVE) ||
2216         ! ( Draw_IsConsoleSubsystem || IsChild(DrawWindow::hWndClientMDI,msg.hwnd) ) )
2217     GetMessage(&msg,NULL,0,0);
2218   hWnd = msg.hwnd;
2219   x = LOWORD(msg.lParam);
2220   y = HIWORD(msg.lParam);
2221   switch (msg.message)
2222   {
2223     case WM_LBUTTONDOWN :
2224                     button = 1;
2225                     break;
2226
2227     case WM_RBUTTONDOWN :
2228                     button = 3;
2229                     break;
2230
2231     case WM_MOUSEMOVE :
2232                     button = 0;
2233                     break;
2234   }
2235 }
2236
2237 Standard_Boolean DrawWindow::DefineColor (const Standard_Integer, const char*)
2238 {
2239   return Standard_True;
2240 };
2241
2242 #endif