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