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