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