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