1 // Created on: 1994-07-27
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // include windows.h first to have all definitions available
22 #include <Standard_ErrorHandler.hxx>
25 #include <Draw_Interpretor.hxx>
26 #include <Draw_Appli.hxx>
27 #include <TCollection_AsciiString.hxx>
28 #include <Image_AlienPixMap.hxx>
30 extern Draw_Interpretor theCommands;
31 extern Standard_Boolean Draw_VirtualWindows;
32 static Tcl_Interp *interp; /* Interpreter for this application. */
35 *----------------------------------------------------------------------
39 * Issue a prompt on standard output, or invoke a script
40 * to issue the prompt.
46 * A prompt gets output, and a Tcl script may be evaluated
49 *----------------------------------------------------------------------
52 static void Prompt(Tcl_Interp *Interp, int partial)
56 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))) && !defined(USE_NON_CONST)
57 const char *promptCmd;
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);
67 if (promptCmd == NULL) {
69 if (!partial && outChannel) {
70 Tcl_Write(outChannel, "% ", 2);
73 code = Tcl_Eval(Interp, promptCmd);
74 outChannel = Tcl_GetStdChannel(TCL_STDOUT);
75 errChannel = Tcl_GetStdChannel(TCL_STDERR);
78 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
79 Tcl_Write(errChannel, Tcl_GetStringResult(Interp), -1);
81 Tcl_Write(errChannel, Interp->result, -1);
83 Tcl_Write(errChannel, "\n", 1);
85 Tcl_AddErrorInfo(Interp,
86 "\n (script that generates prompt)");
91 Tcl_Flush(outChannel);
95 #if !defined(_WIN32) && !defined(__WIN32__)
101 #include <OSD_Timer.hxx>
103 #ifdef HAVE_SYS_TIME_H
104 # include <sys/time.h>
107 #ifdef HAVE_SYS_TYPES_H
108 # include <sys/types.h>
111 #ifdef HAVE_SYS_SELECT_H
112 #include <sys/select.h>
115 #ifdef HAVE_SYS_FILIO_H
116 #include <sys/filio.h>
118 #include <sys/ioctl.h>
127 #include <Draw_Window.hxx>
129 #ifdef HAVE_STRINGS_H
130 # include <strings.h>
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
140 typedef struct Tk_Window_* Tk_Window;
141 typedef const char* Tk_Uid;
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);
155 * Global variables used by the main program:
158 char *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
164 static Tcl_DString command; /* Used to assemble lines of terminal input
165 * into Tcl commands. */
166 static Tcl_DString line; /* Used to read the next line from the
168 //static char errorExitCmd[] = "exit 1";
171 * Forward declarations for procedures defined later in this file:
174 static void StdinProc (ClientData clientData, int mask);
176 static void Prompt (Tcl_Interp *Interp, int partial);
178 static Standard_Boolean tty; /* Non-zero means standard input is a
179 * terminal-like device. Zero means it's
182 static unsigned long thePixels[MAXCOLOR];
184 Standard_Integer Draw_WindowScreen = 0;
185 Standard_Boolean Draw_BlackBackGround = Standard_True;
188 // Initialization of static variables of Draw_Window
189 //======================================================
190 Draw_Window* Draw_Window::firstWindow = NULL;
193 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
194 #include <X11/Xutil.h>
195 #include <Aspect_DisplayConnection.hxx>
197 Display* Draw_WindowDisplay = NULL;
198 Colormap Draw_WindowColorMap;
199 static Handle(Aspect_DisplayConnection) Draw_DisplayConnection;
201 // Base_Window struct definition
202 //===================================
206 XSetWindowAttributes xswa;
209 //=======================================================================
210 //function : Draw_Window
212 //=======================================================================
213 Draw_Window::Draw_Window() :
214 base(*new Base_Window()),
219 myUseBuffer(Standard_False),
220 withWindowManager(Standard_True)
222 myMother = RootWindow(Draw_WindowDisplay,
225 if (firstWindow) firstWindow->previous = this;
229 //=======================================================================
230 //function : Draw_Window
232 //=======================================================================
233 Draw_Window::Draw_Window(Window mother) :
234 base(*new Base_Window()),
239 myUseBuffer(Standard_False),
240 withWindowManager(Standard_True)
244 if (firstWindow) firstWindow->previous = this;
248 //=======================================================================
249 //function : Draw_Window
251 //=======================================================================
252 Draw_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()),
260 myUseBuffer(Standard_False),
261 withWindowManager(Standard_True)
263 myMother = RootWindow(Draw_WindowDisplay,
266 if (firstWindow) firstWindow->previous = this;
272 //=======================================================================
273 //function : Draw_Window
275 //=======================================================================
276 Draw_Window::Draw_Window (const char* window ) :
277 base(*new Base_Window()),
282 myUseBuffer(Standard_False),
283 withWindowManager(Standard_True)
285 sscanf(window,"%lx",&win);
286 Standard_Integer X,Y,DX,DY;
288 if (firstWindow) firstWindow->previous = this;
297 //=======================================================================
298 //function : Draw_Window
300 //=======================================================================
301 Draw_Window::Draw_Window (Window mother,
303 Standard_Integer X, Standard_Integer Y,
304 Standard_Integer DX, Standard_Integer DY) :
305 base(*new Base_Window()),
310 myUseBuffer(Standard_False),
311 withWindowManager(Standard_True)
315 if (firstWindow) firstWindow->previous = this;
321 //=======================================================================
322 //function : ~Draw_Window
324 //=======================================================================
325 Draw_Window::~Draw_Window()
328 previous->next = next;
332 next->previous = previous;
336 XFreePixmap(Draw_WindowDisplay, myBuffer);
339 // Liberation pointer on Base_Window
343 //=======================================================================
346 //=======================================================================
347 void Draw_Window::Init(Standard_Integer X, Standard_Integer Y,
348 Standard_Integer DX, Standard_Integer DY)
350 unsigned long setmask;
352 if (Draw_BlackBackGround)
354 base.xswa.background_pixel = BlackPixel(Draw_WindowDisplay,Draw_WindowScreen);
355 base.xswa.border_pixel = WhitePixel(Draw_WindowDisplay,Draw_WindowScreen);
359 base.xswa.background_pixel = WhitePixel(Draw_WindowDisplay,Draw_WindowScreen);
360 base.xswa.border_pixel = BlackPixel(Draw_WindowDisplay,Draw_WindowScreen);
362 base.xswa.colormap = Draw_WindowColorMap;
363 setmask = CWBackPixel | CWBorderPixel ;
366 myHints.flags = USPosition;
372 win = XCreateWindow(Draw_WindowDisplay,
375 (unsigned int) DX,(unsigned int) DY,
377 DefaultDepth(Draw_WindowDisplay,Draw_WindowScreen),
379 DefaultVisual(Draw_WindowDisplay,Draw_WindowScreen),
381 XSelectInput(Draw_WindowDisplay, win, ButtonPressMask|ExposureMask|
382 StructureNotifyMask);
384 // advise to the window manager to place it where I need
385 XSetWMNormalHints(Draw_WindowDisplay,win,&myHints);
387 if (Draw_VirtualWindows)
389 myUseBuffer = Standard_True;
394 base.gc = XCreateGC(Draw_WindowDisplay, win, 0, NULL);
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
403 base.xswa.backing_store = Always;
404 XChangeWindowAttributes(Draw_WindowDisplay, win,
405 CWBackingStore, &base.xswa);
407 XSetLineAttributes (Draw_WindowDisplay, base.gc,
408 0, LineSolid, CapButt, JoinMiter);
411 //=======================================================================
412 //function : InitBuffer
414 //=======================================================================
415 void Draw_Window::InitBuffer()
419 XFreePixmap (Draw_WindowDisplay, myBuffer);
421 XWindowAttributes winAttr;
422 XGetWindowAttributes (Draw_WindowDisplay, win, &winAttr);
423 myBuffer = XCreatePixmap (Draw_WindowDisplay, win, winAttr.width, winAttr.height, winAttr.depth);
425 else if (myBuffer != 0)
427 XFreePixmap (Draw_WindowDisplay, myBuffer);
432 //=======================================================================
433 //function : StopWinManager
435 //=======================================================================
436 void Draw_Window::StopWinManager()
439 XWindowAttributes winAttr;
440 XGetWindowAttributes (Draw_WindowDisplay, win, &winAttr);
444 myHints.flags = USPosition;
445 myHints.x = (int) 30;
446 myHints.y = (int) 100;
448 base.xswa.override_redirect = 1;
449 base.xswa.border_pixel = BlackPixel(Draw_WindowDisplay,
451 base.xswa.background_pixel = WhitePixel(Draw_WindowDisplay,
454 withWindowManager = Standard_False;
456 win = XCreateWindow(Draw_WindowDisplay, myMother,
457 winAttr.x, winAttr.y,
458 winAttr.width, winAttr.height,
460 CopyFromParent, InputOutput, CopyFromParent,
461 CWBorderPixel|CWOverrideRedirect|CWBackPixel, &base.xswa);
464 // adwise to the window manager to place it where I wish
465 XSetWMNormalHints(Draw_WindowDisplay,win,&myHints);
467 // all masks of the old window are reassigned to the new one.
468 XSelectInput(Draw_WindowDisplay,win,winAttr.your_event_mask);
471 //=======================================================================
472 //function : SetPosition
474 //=======================================================================
475 void Draw_Window::SetPosition(Standard_Integer NewXpos,
476 Standard_Integer NewYpos)
478 Standard_Integer x,y;
481 if ( (x != NewXpos) || (y != NewYpos) )
482 XMoveWindow(Draw_WindowDisplay, win, NewXpos, NewYpos);
485 //=======================================================================
486 //function : SetDimension
488 //=======================================================================
489 void Draw_Window::SetDimension(Standard_Integer NewDx,
490 Standard_Integer NewDy)
492 if ( (NewDx != WidthWin() ) || (NewDy != HeightWin() ) )
493 XResizeWindow(Draw_WindowDisplay, win, NewDx, NewDy);
496 //=======================================================================
497 //function : GetPosition
499 //=======================================================================
500 void Draw_Window::GetPosition(Standard_Integer &PosX,
501 Standard_Integer &PosY)
503 XWindowAttributes winAttr;
504 XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);
510 //=======================================================================
511 //function : HeightWin
513 //=======================================================================
514 Standard_Integer Draw_Window::HeightWin() const
517 XWindowAttributes winAttr;
518 XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);
524 //=======================================================================
525 //function : WidthWin
527 //=======================================================================
528 Standard_Integer Draw_Window::WidthWin() const
531 XWindowAttributes winAttr;
532 XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);
538 //=======================================================================
539 //function : SetTitle
541 //=======================================================================
542 void Draw_Window::SetTitle(const char* title)
544 XStoreName(Draw_WindowDisplay, win, title);
547 //=======================================================================
548 //function : GetTitle
550 //=======================================================================
551 char* Draw_Window::GetTitle()
554 XFetchName(Draw_WindowDisplay, win, &title);
558 //=======================================================================
559 //function : GetDrawable
561 //=======================================================================
562 Drawable Draw_Window::GetDrawable() const
564 return myUseBuffer ? myBuffer : win;
567 //=======================================================================
568 //function :DefineColor
570 //=======================================================================
571 Standard_Boolean Draw_Window::DefineColor(const Standard_Integer i, const char* colorName)
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;
583 //=======================================================================
584 //function : DisplayWindow
586 //=======================================================================
587 void Draw_Window::DisplayWindow()
589 if (Draw_VirtualWindows)
595 XMapRaised(Draw_WindowDisplay, win);
597 XFlush(Draw_WindowDisplay);
600 //=======================================================================
603 //=======================================================================
604 void Draw_Window::Hide()
606 XUnmapWindow(Draw_WindowDisplay, win);
609 //=======================================================================
612 //=======================================================================
613 void Draw_Window::Destroy()
615 XFreeGC (Draw_WindowDisplay, base.gc);
616 XDestroyWindow(Draw_WindowDisplay, win);
620 XFreePixmap(Draw_WindowDisplay, myBuffer);
625 //=======================================================================
628 //=======================================================================
629 void Draw_Window::Clear()
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);
642 XClearArea(Draw_WindowDisplay, win, 0, 0, 0, 0, False);
646 //=======================================================================
649 //=======================================================================
650 void Draw_Window::Flush()
652 XFlush(Draw_WindowDisplay);
655 //=======================================================================
656 //function : DrawString
658 //=======================================================================
659 void Draw_Window::DrawString(int X, int Y, char *text)
661 XDrawString(Draw_WindowDisplay, GetDrawable(), base.gc, X, Y, text, strlen(text));
664 //=======================================================================
665 //function : DrawSegments
667 //=======================================================================
668 void Draw_Window::DrawSegments(Segment *tab, int nbElem)
670 XDrawSegments(Draw_WindowDisplay, GetDrawable(), base.gc, (XSegment*) tab, nbElem);
673 //=======================================================================
676 //=======================================================================
677 void Draw_Window::Redraw()
680 XCopyArea (Draw_WindowDisplay,
681 myBuffer, win, // source, destination Drawables
684 WidthWin(), HeightWin(),
685 0, 0); // destination x, y
689 //=======================================================================
690 //function : SetColor
692 //=======================================================================
693 void Draw_Window::SetColor(Standard_Integer color)
695 XSetForeground(Draw_WindowDisplay, base.gc, thePixels[color]);
698 //=======================================================================
701 //=======================================================================
702 void Draw_Window::SetMode( int mode)
704 XSetFunction(Draw_WindowDisplay, base.gc, mode);
707 //=======================================================================
710 //=======================================================================
711 Standard_Boolean Draw_Window::Save (const char* theFileName) const
713 // make sure all draw operations done
714 XSync (Draw_WindowDisplay, True);
717 XWindowAttributes winAttr;
718 XGetWindowAttributes (Draw_WindowDisplay, win, &winAttr);
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);
726 Window winChildDummy;
729 XTranslateCoordinates (Draw_WindowDisplay, win, XRootWindowOfScreen (winAttr.screen),
730 0, 0, &winLeft, &winTop, &winChildDummy);
732 if (((winLeft + winAttr.width) > winAttrRoot.width) || winLeft < winAttrRoot.x ||
733 ((winTop + winAttr.height) > winAttrRoot.height) || winTop < winAttrRoot.y)
735 std::cerr << "The window not fully visible! Can't create the snapshot.\n";
736 return Standard_False;
741 if (XMatchVisualInfo (Draw_WindowDisplay, Draw_WindowScreen, 32, TrueColor, &aVInfo) == 0
742 && XMatchVisualInfo (Draw_WindowDisplay, Draw_WindowScreen, 24, TrueColor, &aVInfo) == 0)
744 std::cerr << "24-bit TrueColor visual is not supported by server!\n";
745 return Standard_False;
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))
754 return Standard_False;
756 anImage.SetTopDown (true);
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)
765 anXImage->data = NULL;
766 XDestroyImage (anXImage);
767 return Standard_False;
771 anXImage->data = NULL;
772 XDestroyImage (anXImage);
775 return anImage.Save (theFileName);
778 //=======================================================================
781 //=======================================================================
783 void Draw_Window::Wait (Standard_Boolean wait)
787 XSelectInput(Draw_WindowDisplay,win,
788 ButtonPressMask|ExposureMask | StructureNotifyMask |
792 XSelectInput(Draw_WindowDisplay,win,
793 ButtonPressMask|ExposureMask | StructureNotifyMask);
797 //=======================================================================
798 //function : ProcessEvent
800 //=======================================================================
802 void ProcessEvent(Draw_Window& win, XEvent& xev)
804 Standard_Integer X,Y,button,lenk;
820 button = xev.xbutton.button;
821 win.WButtonPress(X,Y,button);
827 button = xev.xbutton.button;
828 win.WButtonRelease(X,Y,button);
832 lenk = XLookupString(&(xev.xkey),
842 //WKeyPress(c,keysym);
848 win.WMotionNotify(X,Y);
851 case ConfigureNotify :
852 if (win.withWindowManager)
853 win.WConfigureNotify(xev.xconfigure.x, xev.xconfigure.y,
854 xev.xconfigure.width,
855 xev.xconfigure.height);
865 //=======================================================================
868 //=======================================================================
869 void Draw_Window::WExpose()
873 //=======================================================================
874 //function : WButtonPress
876 //=======================================================================
877 void Draw_Window::WButtonPress(const Standard_Integer,
878 const Standard_Integer,
879 const Standard_Integer&)
883 //=======================================================================
884 //function : WButtonRelease
886 //=======================================================================
887 void Draw_Window::WButtonRelease(const Standard_Integer,
888 const Standard_Integer,
889 const Standard_Integer&)
893 /**************************
894 //=======================================================================
895 //function : WKeyPress
897 //=======================================================================
899 void Draw_Window::WKeyPress(char, KeySym&)
902 ***************************/
904 //=======================================================================
905 //function : WMotionNotify
907 //=======================================================================
908 void Draw_Window::WMotionNotify(const Standard_Integer ,
909 const Standard_Integer )
913 //=======================================================================
914 //function : WConfigureNotify
916 //=======================================================================
918 void Draw_Window::WConfigureNotify(const Standard_Integer,
919 const Standard_Integer,
920 const Standard_Integer,
921 const Standard_Integer)
925 //=======================================================================
926 //function : WUnmapNotify
928 //=======================================================================
930 void Draw_Window::WUnmapNotify()
935 //======================================================
936 // funtion : ProcessEvents
937 // purpose : process pending X events
938 //======================================================
940 static void ProcessEvents(ClientData,int)
944 while (XPending(Draw_WindowDisplay)) {
949 XNextEvent(Draw_WindowDisplay,&xev);
951 /* search the window in the window list */
952 Draw_Window* w = Draw_Window::firstWindow;
953 Standard_Integer found=0;
955 if (xev.xany.window == w->win) {
956 ProcessEvent(*w, xev);
963 Tk_HandleEvent(&xev);
968 //======================================================
969 // funtion : GetNextEvent()
971 //======================================================
972 void GetNextEvent(Event& ev)
975 XNextEvent(Draw_WindowDisplay, &xev);
980 ev.window = xev.xbutton.window;
981 ev.button = xev.xbutton.button;
982 ev.x = xev.xbutton.x;
983 ev.y = xev.xbutton.y;
988 ev.window = xev.xmotion.window;
990 ev.x = xev.xmotion.x;
991 ev.y = xev.xmotion.y;
997 //======================================================
998 // funtion :Run_Appli
1000 //======================================================
1003 static Standard_Boolean(*Interprete) (const char*);
1005 void Run_Appli(Standard_Boolean (*interprete) (const char*))
1007 Tcl_Channel outChannel, inChannel ;
1008 Interprete = interprete;
1013 * Commands will come from standard input, so set up an event
1014 * handler for standard input. If the input device is aEvaluate the
1015 * .rc file, if one has been specified, set up an event handler
1016 * for standard input, and print a prompt if the input
1017 * device is a terminal.
1019 inChannel = Tcl_GetStdChannel(TCL_STDIN);
1021 Tcl_CreateChannelHandler(inChannel, TCL_READABLE, StdinProc,
1022 (ClientData) inChannel);
1025 // Create a handler for the draw display
1027 // Adding of the casting into void* to be able to compile on AO1
1028 // ConnectionNumber(Draw_WindowDisplay) is an int 32 bits
1029 // (void*) is a pointer 64 bits ???????
1031 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
1032 #if TCL_MAJOR_VERSION < 8
1033 Tk_CreateFileHandler((void*) ConnectionNumber(Draw_WindowDisplay),
1034 TK_READABLE, ProcessEvents,(ClientData) 0 );
1036 Tk_CreateFileHandler(ConnectionNumber(Draw_WindowDisplay),
1037 TK_READABLE, ProcessEvents,(ClientData) 0 );
1043 if (tty) Prompt(theCommands.Interp(), 0);
1044 Prompt(theCommands.Interp(), 0);
1046 outChannel = Tcl_GetStdChannel(TCL_STDOUT);
1048 Tcl_Flush(outChannel);
1050 Tcl_DStringInit(&command);
1053 * Loop infinitely, waiting for commands to execute. When there
1054 * are no windows left, Tk_MainLoop returns and we exit.
1059 if (Draw_VirtualWindows) {
1060 // main window will never shown
1061 // but main loop will parse all Xlib messages
1062 Tcl_Eval(theCommands.Interp(), "wm withdraw .");
1069 Standard_Integer count = ConnectionNumber(Draw_WindowDisplay);
1070 Standard_Integer numfd;
1074 FD_SET(count,&readset);
1076 numfd = select(count+1,(Integer*)&readset,NULL,NULL,NULL);
1078 numfd = select(count+1,&readset,NULL,NULL,NULL);
1080 if (FD_ISSET(0,&readset)) StdinProc((ClientData)0,0);
1081 if (FD_ISSET(count,&readset)) ProcessEvents((ClientData)0,0);
1087 //======================================================
1088 // funtion : Init_Appli()
1090 //======================================================
1091 Standard_Boolean Init_Appli()
1094 interp = theCommands.Interp();
1100 } catch (Standard_Failure) {
1101 cout <<" Pb au lancement de TK_Init "<<endl;
1104 Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
1106 Tk_Window aMainWindow = Tk_MainWindow(interp) ;
1107 if (aMainWindow == NULL) {
1108 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
1109 fprintf(stderr, "%s\n", Tcl_GetStringResult(interp));
1111 fprintf(stderr, "%s\n", interp->result);
1115 #if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
1116 Tk_SetAppName(aMainWindow, "Draw");
1118 Tk_Name(aMainWindow) = Tk_GetUid(Tk_SetAppName(aMainWindow, "Draw"));
1121 Tk_GeometryRequest (aMainWindow, 200, 200);
1123 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
1124 if (Draw_DisplayConnection.IsNull())
1128 Draw_DisplayConnection = new Aspect_DisplayConnection();
1130 catch (Standard_Failure)
1132 std::cout << "Cannot open display. Interpret commands in batch mode." << std::endl;
1133 return Standard_False;
1136 if (Draw_WindowDisplay == NULL)
1138 Draw_WindowDisplay = Draw_DisplayConnection->GetDisplay();
1141 // synchronize the display server : could be done within Tk_Init
1143 XSynchronize(Draw_WindowDisplay, True);
1144 XSetInputFocus(Draw_WindowDisplay,
1146 RevertToPointerRoot,
1149 Draw_WindowScreen = DefaultScreen(Draw_WindowDisplay);
1150 Draw_WindowColorMap = DefaultColormap(Draw_WindowDisplay,
1155 Tcl_SetVar(interp,"tcl_interactive",(char*)(tty ? "1" : "0"), TCL_GLOBAL_ONLY);
1156 // Tcl_SetVar(interp,"tcl_interactive",tty ? "1" : "0", TCL_GLOBAL_ONLY);
1157 return Standard_True;
1160 //======================================================
1161 // funtion : Destroy_Appli()
1163 //======================================================
1164 void Destroy_Appli()
1166 //XCloseDisplay(Draw_WindowDisplay);
1170 *----------------------------------------------------------------------
1174 * This procedure is invoked by the event dispatcher whenever
1175 * standard input becomes readable. It grabs the next line of
1176 * input characters, adds them to a command being assembled, and
1177 * executes the command if it's complete.
1183 * Could be almost arbitrary, depending on the command that's
1186 *----------------------------------------------------------------------
1190 //static void StdinProc(ClientData clientData, int mask)
1191 static void StdinProc(ClientData clientData, int )
1193 static int gotPartial = 0;
1197 Tcl_Channel chan = (Tcl_Channel) clientData;
1199 // MSV Nov 2, 2001: patch for TCL 8.3: initialize line to avoid exception
1200 // when first user input is an empty string
1201 Tcl_DStringFree(&line);
1202 count = Tcl_Gets(chan, &line);
1205 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)))
1206 Tcl_DString linetmp;
1207 Tcl_DStringInit(&linetmp);
1208 Tcl_UniChar * UniCharString;
1209 UniCharString = Tcl_UtfToUniCharDString(Tcl_DStringValue(&line),-1,&linetmp);
1210 Standard_Integer l = Tcl_UniCharLen(UniCharString);
1211 TCollection_AsciiString AsciiString("");
1212 Standard_Character Character;
1214 for (i=0; i<l; i++) {
1215 Character = UniCharString[i];
1216 AsciiString.AssignCat(Character);
1218 Tcl_DStringInit(&line);
1219 Tcl_DStringAppend(&line, AsciiString.ToCString(), -1);
1226 Tcl_DeleteChannelHandler(chan, StdinProc, (ClientData) chan);
1234 (void) Tcl_DStringAppend(&command, Tcl_DStringValue(&line), -1);
1235 cmd = Tcl_DStringAppend(&command, "\n", -1);
1236 Tcl_DStringFree(&line);
1239 if (!Tcl_CommandComplete(cmd)) {
1246 * Disable the stdin channel handler while evaluating the command;
1247 * otherwise if the command re-enters the event loop we might
1248 * process commands from stdin before the current command is
1249 * finished. Among other things, this will trash the text of the
1250 * command being evaluated.
1253 Tcl_CreateChannelHandler(chan, 0, StdinProc, (ClientData) chan);
1257 * Disable the stdin file handler while evaluating the command;
1258 * otherwise if the command re-enters the event loop we might
1259 * process commands from stdin before the current command is
1260 * finished. Among other things, this will trash the text of the
1261 * command being evaluated.
1265 // Tk_CreateFileHandler(0, 0, StdinProc, (ClientData) 0);
1268 // xab average to avoid an output SIGBUS of DRAW
1269 // to ultimately prescise or remove once
1270 // the problem of free on the global variable at the average
1277 Tcl_CreateChannelHandler(chan, TCL_READABLE, StdinProc,
1279 Tcl_DStringFree(&command);
1286 if (tty) Prompt(interp, gotPartial);
1288 } catch (Standard_Failure) {}
1294 // Source Specifique WNT
1296 /****************************************************\
1299 \****************************************************/
1301 #include "Draw_Window.hxx"
1302 #include "DrawRessource.h"
1305 #include <Draw_Appli.hxx>
1312 // Position of information in the extra memory
1314 // indicates SUBSYSTEM:CONSOLE linker option, to be set to True in main()
1316 Standard_Boolean Draw_IsConsoleSubsystem = Standard_False;
1319 Standard_Boolean Draw_BlackBackGround = Standard_True;
1321 // Creation of color stylos
1322 HPEN colorPenTab[MAXCOLOR] = {CreatePen(PS_SOLID, PENWIDTH, RGB(255,255,255)),
1323 CreatePen(PS_SOLID, PENWIDTH, RGB(255,0,0)),
1324 CreatePen(PS_SOLID, PENWIDTH, RGB(0,255,0)),
1325 CreatePen(PS_SOLID, PENWIDTH, RGB(0,0,255)),
1326 CreatePen(PS_SOLID, PENWIDTH, RGB(0,255,255)),
1327 CreatePen(PS_SOLID, PENWIDTH, RGB(255,215,0)),
1328 CreatePen(PS_SOLID, PENWIDTH, RGB(255,0,255)),
1329 CreatePen(PS_SOLID, PENWIDTH, RGB(255,52,179)),
1330 CreatePen(PS_SOLID, PENWIDTH, RGB(255,165,0)),
1331 CreatePen(PS_SOLID, PENWIDTH, RGB(255,228,225)),
1332 CreatePen(PS_SOLID, PENWIDTH, RGB(255,160,122)),
1333 CreatePen(PS_SOLID, PENWIDTH, RGB(199,21,133)),
1334 CreatePen(PS_SOLID, PENWIDTH, RGB(255,255,0)),
1335 CreatePen(PS_SOLID, PENWIDTH, RGB(240,230,140)),
1336 CreatePen(PS_SOLID, PENWIDTH, RGB(255,127,80))};
1338 // Correspondance mode X11 and WINDOWS NT
1339 int modeTab[16] = {R2_BLACK, R2_MASKPEN, R2_MASKPENNOT, R2_COPYPEN,
1340 R2_MASKNOTPEN, R2_NOP, R2_XORPEN, R2_MERGEPEN,
1341 R2_NOTMASKPEN, R2_NOTXORPEN, R2_NOT, R2_MERGEPENNOT,
1342 R2_NOTCOPYPEN, R2_MERGENOTPEN, R2_NOTMERGEPEN, R2_WHITE};
1344 /*--------------------------------------------------------*\
1345 | CREATE DRAW WINDOW PROCEDURE
1346 \*--------------------------------------------------------*/
1347 HWND DrawWindow::CreateDrawWindow(HWND hWndClient, int nitem)
1349 if (Draw_IsConsoleSubsystem) {
1350 HWND aWin = CreateWindow (DRAWCLASS, DRAWTITLE,
1351 WS_OVERLAPPEDWINDOW,
1353 NULL, NULL,::GetModuleHandle(NULL), NULL);
1354 if (!Draw_VirtualWindows)
1356 SetWindowPos(aWin, HWND_TOPMOST, 1,1,1,1, SWP_NOMOVE);
1357 SetWindowPos(aWin, HWND_NOTOPMOST, 1,1,1,1, SWP_NOMOVE);
1364 hInstance = (HANDLE)GetWindowLong(hWndClient,GWL_HINSTANCE);
1366 hInstance = (HANDLE)GetWindowLong(hWndClient,GWLP_HINSTANCE);
1369 return CreateMDIWindow(DRAWCLASS, DRAWTITLE,
1370 WS_CAPTION | WS_CHILD | WS_THICKFRAME,
1372 hWndClient, (HINSTANCE)hInstance, nitem);
1377 /*--------------------------------------------------------*\
1378 | DRAW WINDOW PROCEDURE
1379 \*--------------------------------------------------------*/
1380 LRESULT APIENTRY DrawWindow::DrawProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam )
1382 DrawWindow* localObjet = (DrawWindow*)GetWindowLong(hWnd, CLIENTWND);
1385 if (Draw_IsConsoleSubsystem)
1386 return (DefWindowProc(hWnd, wMsg, wParam, lParam));
1388 return(DefMDIChildProc(hWnd, wMsg, wParam, lParam));
1396 BeginPaint(hWnd, &ps);
1397 if (localObjet->GetUseBuffer())
1398 localObjet->Redraw();
1400 localObjet->WExpose();
1401 EndPaint(hWnd, &ps);
1406 if (localObjet->GetUseBuffer()) {
1407 localObjet->InitBuffer();
1408 localObjet->WExpose();
1409 localObjet->Redraw();
1414 if (Draw_IsConsoleSubsystem)
1415 return (DefWindowProc(hWnd, wMsg, wParam, lParam));
1417 return(DefMDIChildProc(hWnd, wMsg, wParam, lParam));
1424 ** IMPLEMENTATION of the CLASS DRAWWINDOW
1427 /*--------------------------------------------------------*\
1428 | Initialization of static variables of DrawWindow
1429 \*--------------------------------------------------------*/
1431 DrawWindow* DrawWindow::firstWindow = NULL;
1432 HWND DrawWindow::hWndClientMDI = 0;
1434 /*--------------------------------------------------------*\
1435 | Constructors of Draw_Window
1436 \*--------------------------------------------------------*/
1438 // Default Constructor
1439 //________________________
1440 DrawWindow::DrawWindow() :
1445 myUseBuffer(Standard_False)
1447 if (firstWindow) firstWindow->previous = this;
1451 //________________________
1452 DrawWindow::DrawWindow(char* title,
1453 Standard_Integer X, Standard_Integer Y,
1454 Standard_Integer dX,Standard_Integer dY) :
1455 win(0), next(firstWindow), previous(NULL), myMemHbm(NULL), myUseBuffer(Standard_False)
1457 if (firstWindow) firstWindow->previous = this;
1462 DrawWindow::DrawWindow(char* title,
1463 Standard_Integer X, Standard_Integer Y,
1464 Standard_Integer dX,Standard_Integer dY,
1466 win(theWin),next(firstWindow), previous(NULL), myMemHbm(NULL), myUseBuffer(Standard_False)
1468 if (firstWindow) firstWindow->previous = this;
1476 /*--------------------------------------------------------*\
1477 | Destructor of DrawWindow
1478 \*--------------------------------------------------------*/
1479 DrawWindow::~DrawWindow()
1482 previous->next = next;
1486 next->previous = previous;
1488 // Delete 'off-screen drawing'-related objects
1490 DeleteObject(myMemHbm);
1497 /*--------------------------------------------------------*\
1499 \*--------------------------------------------------------*/
1500 void DrawWindow::Init(Standard_Integer theXLeft, Standard_Integer theYTop,
1501 Standard_Integer theWidth, Standard_Integer theHeight)
1505 win = CreateDrawWindow(hWndClientMDI, 0);
1508 // include decorations in the window dimensions
1509 // to reproduce same behaviour of Xlib window.
1510 DWORD aWinStyle = GetWindowLong (win, GWL_STYLE);
1511 DWORD aWinStyleEx = GetWindowLong (win, GWL_EXSTYLE);
1512 HMENU aMenu = GetMenu (win);
1515 aRect.top = theYTop;
1516 aRect.bottom = theYTop + theHeight;
1517 aRect.left = theXLeft;
1518 aRect.right = theXLeft + theWidth;
1519 AdjustWindowRectEx (&aRect, aWinStyle, aMenu != NULL ? TRUE : FALSE, aWinStyleEx);
1521 SetPosition (aRect.left, aRect.top);
1522 SetDimension (aRect.right - aRect.left, aRect.bottom - aRect.top);
1523 // Save the pointer at the instance associated to the window
1524 SetWindowLong(win, CLIENTWND, (LONG)this);
1525 HDC hDC = GetDC(win);
1526 SetBkColor(hDC, RGB(0, 0, 0));
1529 SelectObject(hDC, colorPenTab[myCurrPen]); // Default pencil
1530 SelectObject(hDC, GetStockObject(BLACK_BRUSH));
1531 SetTextColor(hDC, RGB(0,0,255));
1532 ReleaseDC(win, hDC);
1534 if (Draw_VirtualWindows)
1536 // create a virtual window
1537 SetUseBuffer (Standard_True);
1541 /*--------------------------------------------------------*\
1543 \*--------------------------------------------------------*/
1544 void DrawWindow::SetUseBuffer(Standard_Boolean use)
1550 /*--------------------------------------------------------*\
1552 \*--------------------------------------------------------*/
1553 void DrawWindow::InitBuffer()
1557 HDC hDC = GetDC(win);
1558 GetClientRect(win, &rc);
1561 GetObject(myMemHbm, sizeof(BITMAP), &aBmp);
1562 if (rc.right-rc.left == aBmp.bmWidth && rc.bottom-rc.top == aBmp.bmHeight) return;
1563 DeleteObject(myMemHbm);
1565 myMemHbm = (HBITMAP)CreateCompatibleBitmap(hDC,
1568 HDC aMemDC = GetMemDC(hDC);
1569 FillRect(aMemDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
1570 ReleaseMemDC(aMemDC);
1571 ReleaseDC(win, hDC);
1575 DeleteObject(myMemHbm);
1581 /*--------------------------------------------------------*\
1583 \*--------------------------------------------------------*/
1584 HDC DrawWindow::GetMemDC(HDC theWinDC)
1586 if (!myUseBuffer) return NULL;
1588 HDC aWorkDC = CreateCompatibleDC(theWinDC);
1589 myOldHbm = (HBITMAP)SelectObject(aWorkDC, myMemHbm);
1590 SetROP2(aWorkDC, modeTab[myCurrMode]);
1591 SelectObject(aWorkDC, colorPenTab[myCurrPen]);
1592 SetBkColor(aWorkDC, RGB(0, 0, 0));
1593 SelectObject(aWorkDC, GetStockObject(BLACK_BRUSH));
1594 SetTextColor(aWorkDC, RGB(0,0,255));
1599 /*--------------------------------------------------------*\
1601 \*--------------------------------------------------------*/
1602 void DrawWindow::ReleaseMemDC(HDC theMemDC)
1604 if (!myUseBuffer || !theMemDC) return;
1606 if (myOldHbm) SelectObject(theMemDC, myOldHbm);
1611 /*--------------------------------------------------------*\
1613 \*--------------------------------------------------------*/
1614 void DrawWindow::SetPosition(Standard_Integer posX, Standard_Integer posY)
1616 SetWindowPos(win, 0,
1619 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
1623 /*--------------------------------------------------------*\
1625 \*--------------------------------------------------------*/
1626 void DrawWindow::SetDimension(Standard_Integer dimX, Standard_Integer dimY)
1628 SetWindowPos(win, 0,
1631 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
1635 /*--------------------------------------------------------*\
1637 \*--------------------------------------------------------*/
1638 void DrawWindow::GetPosition(Standard_Integer &dimX,
1639 Standard_Integer &dimY)
1642 GetWindowRect(win, &rect);
1645 point.x = rect.left;
1648 ScreenToClient(hWndClientMDI, &point);
1654 /*--------------------------------------------------------*\
1656 \*--------------------------------------------------------*/
1657 Standard_Integer DrawWindow::HeightWin() const
1660 GetClientRect(win, &rect);
1661 return(rect.bottom-rect.top);
1665 /*--------------------------------------------------------*\
1667 \*--------------------------------------------------------*/
1668 Standard_Integer DrawWindow::WidthWin() const
1671 GetClientRect(win, &rect);
1672 return(rect.right-rect.left);
1676 /*--------------------------------------------------------*\
1678 \*--------------------------------------------------------*/
1679 void DrawWindow::SetTitle(char* title)
1681 SetWindowText(win, title);
1685 /*--------------------------------------------------------*\
1687 | Attention do not forget to unallocate the memory
1688 \*--------------------------------------------------------*/
1689 char* DrawWindow::GetTitle()
1691 char* title=new char[31];
1692 GetWindowText(win, title, 30);
1697 /*--------------------------------------------------------*\
1699 \*--------------------------------------------------------*/
1700 void DrawWindow::DisplayWindow()
1702 if (Draw_VirtualWindows)
1706 ShowWindow (win, SW_SHOW);
1711 /*--------------------------------------------------------*\
1713 \*--------------------------------------------------------*/
1714 void DrawWindow::Hide()
1716 ShowWindow(win, SW_HIDE);
1720 /*--------------------------------------------------------*\
1722 \*--------------------------------------------------------*/
1723 void DrawWindow::Destroy()
1730 /*--------------------------------------------------------*\
1732 \*--------------------------------------------------------*/
1733 void DrawWindow::Clear()
1735 HDC hDC = GetDC(win);
1736 HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
1739 SelectObject(aWorkDC,GetStockObject(BLACK_PEN));
1740 Rectangle(aWorkDC, 0, 0, WidthWin(), HeightWin());
1741 RestoreDC(aWorkDC,-1);
1743 if (myUseBuffer) ReleaseMemDC(aWorkDC);
1747 /*--------------------------------------------------------*\
1749 \*--------------------------------------------------------*/
1750 static Standard_Boolean SaveBitmap (HBITMAP theHBitmap,
1751 const char* theFileName)
1753 // Get informations about the bitmap
1755 if (GetObject (theHBitmap, sizeof(BITMAP), (LPSTR )&aBitmap) == 0)
1757 return Standard_False;
1760 Image_AlienPixMap anImage;
1761 const Standard_Size aSizeRowBytes = Standard_Size(aBitmap.bmWidth) * 4;
1762 if (!anImage.InitTrash (Image_PixMap::ImgBGR32, Standard_Size(aBitmap.bmWidth), Standard_Size(aBitmap.bmHeight), aSizeRowBytes))
1764 return Standard_False;
1766 anImage.SetTopDown (false);
1769 BITMAPINFOHEADER aBitmapInfo;
1770 memset (&aBitmapInfo, 0, sizeof(BITMAPINFOHEADER));
1771 aBitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
1772 aBitmapInfo.biWidth = aBitmap.bmWidth;
1773 aBitmapInfo.biHeight = aBitmap.bmHeight; // positive means bottom-up!
1774 aBitmapInfo.biPlanes = 1;
1775 aBitmapInfo.biBitCount = 32; // use 32bit for automatic word-alignment per row
1776 aBitmapInfo.biCompression = BI_RGB;
1779 HDC aDC = GetDC (NULL);
1780 Standard_Boolean isSuccess = GetDIBits (aDC, theHBitmap,
1781 0, // first scan line to set
1782 aBitmap.bmHeight, // number of scan lines to copy
1783 anImage.ChangeData(), // array for bitmap bits
1784 (LPBITMAPINFO )&aBitmapInfo, // bitmap data info
1785 DIB_RGB_COLORS) != 0;
1786 ReleaseDC (NULL, aDC);
1787 return isSuccess && anImage.Save (theFileName);
1790 /*--------------------------------------------------------*\
1792 \*--------------------------------------------------------*/
1793 Standard_Boolean DrawWindow::Save (const char* theFileName) const
1797 return SaveBitmap (myMemHbm, theFileName);
1801 GetClientRect (win, &aRect);
1802 int aWidth = aRect.right - aRect.left;
1803 int aHeight = aRect.bottom - aRect.top;
1806 HDC aDstDC = GetDC (NULL);
1807 HDC aSrcDC = GetDC (win); // we copy only client area
1808 HDC aMemDC = CreateCompatibleDC (aDstDC);
1810 // Copy the screen to the bitmap
1811 HBITMAP anHBitmapDump = CreateCompatibleBitmap (aDstDC, aWidth, aHeight);
1812 HBITMAP anHBitmapOld = (HBITMAP )SelectObject (aMemDC, anHBitmapDump);
1813 BitBlt (aMemDC, 0, 0, aWidth, aHeight, aSrcDC, 0, 0, SRCCOPY);
1815 Standard_Boolean isSuccess = SaveBitmap (anHBitmapDump, theFileName);
1818 DeleteObject (SelectObject (aMemDC, anHBitmapOld));
1824 /*--------------------------------------------------------*\
1826 \*--------------------------------------------------------*/
1827 void DrawWindow::DrawString(int x,int y, char* text)
1829 HDC hDC = GetDC(win);
1830 HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
1832 TextOut(aWorkDC, x, y, text, (int )strlen(text));
1834 if (myUseBuffer) ReleaseMemDC(aWorkDC);
1838 /*--------------------------------------------------------*\
1840 \*--------------------------------------------------------*/
1841 void DrawWindow::DrawSegments(Segment *tab, int nbElem)
1843 HDC hDC = GetDC(win);
1844 HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
1846 for(int i = 0 ; i < nbElem ; i++)
1848 MoveToEx(aWorkDC, tab[i].x1, tab[i].y1, NULL);
1849 LineTo(aWorkDC, tab[i].x2, tab[i].y2);
1852 if (myUseBuffer) ReleaseMemDC(aWorkDC);
1856 /*--------------------------------------------------------*\
1858 \*--------------------------------------------------------*/
1859 void DrawWindow::Redraw()
1862 HDC hDC = GetDC(win);
1864 GetClientRect(win, &rc);
1865 HDC aMemDC = GetMemDC(hDC);
1868 rc.right-rc.left, rc.bottom-rc.top,
1871 ReleaseMemDC(aMemDC);
1876 /*--------------------------------------------------------*\
1878 \*--------------------------------------------------------*/
1879 void DrawWindow::SetMode(int mode)
1881 HDC hDC = GetDC(win);
1883 SetROP2(hDC, modeTab[mode]);
1888 /*--------------------------------------------------------*\
1890 \*--------------------------------------------------------*/
1891 void DrawWindow::SetColor(Standard_Integer color)
1893 HDC hDC = GetDC(win);
1895 SelectObject(hDC,colorPenTab[color]);
1900 /*--------------------------------------------------------*\
1902 \*--------------------------------------------------------*/
1903 void DrawWindow::WExpose()
1908 /*--------------------------------------------------------*\
1910 \*--------------------------------------------------------*/
1911 void DrawWindow::WButtonPress(const Standard_Integer,
1912 const Standard_Integer,
1913 const Standard_Integer&)
1918 /*--------------------------------------------------------*\
1920 \*--------------------------------------------------------*/
1921 void DrawWindow::WButtonRelease(const Standard_Integer,
1922 const Standard_Integer,
1923 const Standard_Integer&)
1928 /*--------------------------------------------------------*\
1930 \*--------------------------------------------------------*/
1931 void Draw_Window::WMotionNotify(const Standard_Integer ,
1932 const Standard_Integer )
1937 /*--------------------------------------------------------*\
1939 \*--------------------------------------------------------*/
1940 void DrawWindow::WConfigureNotify(const Standard_Integer,
1941 const Standard_Integer,
1942 const Standard_Integer,
1943 const Standard_Integer)
1948 /*--------------------------------------------------------*\
1950 \*--------------------------------------------------------*/
1951 void DrawWindow::WUnmapNotify()
1958 ** IMPLEMENTATION of the CLASS SEGMENT
1961 /*--------------------------------------------------------*\
1963 \*--------------------------------------------------------*/
1965 void Segment::Init(Standard_Integer a1, Standard_Integer a2,
1966 Standard_Integer a3, Standard_Integer a4)
1974 static DWORD WINAPI tkLoop(VOID);
1976 static Tk_Window mainWindow;
1979 //* threads sinchronization *//
1980 DWORD dwMainThreadId;
1981 console_semaphore_value volatile console_semaphore = WAIT_CONSOLE_COMMAND;
1982 //char console_command[1000];
1983 #define COMMAND_SIZE 1000 /* Console Command size */
1984 char console_command[COMMAND_SIZE];
1985 bool volatile isTkLoopStarted = false;
1987 /*--------------------------------------------------------*\
1989 \*--------------------------------------------------------*/
1990 Standard_Boolean Init_Appli(HINSTANCE hInst,
1991 HINSTANCE hPrevInst, int nShow, HWND& hWndFrame )
1995 console_semaphore = STOP_CONSOLE;
1997 interp = theCommands.Interp();
2000 dwMainThreadId = GetCurrentThreadId();
2002 //necessary for normal Tk operation
2003 hThread = CreateThread(NULL, // no security attributes
2004 0, // use default stack size
2005 (LPTHREAD_START_ROUTINE) tkLoop, // thread function
2006 NULL, // no thread function argument
2007 0, // use default creation flags
2010 cout << "Tcl/Tk main loop thread not created. Switching to batch mode..." << endl;
2015 } catch (Standard_Failure) {
2016 cout <<" Pb au lancement de TK_Init "<<endl;
2019 Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
2021 //since the main Tcl/Tk loop wasn't created --> switch to batch mode
2022 return Standard_False;
2025 // san - 06/08/2002 - Time for tkLoop to start; Tk fails to initialize otherwise
2026 while (!isTkLoopStarted)
2029 // Saving of window classes
2031 if(!RegisterAppClass(hInst))
2032 return(Standard_False);
2035 ** Enter the application message-polling loop. This is the anchor for
2038 hWndFrame = !Draw_IsConsoleSubsystem ? CreateAppWindow (hInst) : NULL;
2039 if (hWndFrame != NULL)
2041 ShowWindow(hWndFrame,nShow);
2042 UpdateWindow(hWndFrame);
2045 return Standard_True;
2048 Standard_Boolean Draw_Interprete (const char*);
2050 /*--------------------------------------------------------*\
2051 | readStdinThreadFunc
2052 \*--------------------------------------------------------*/
2053 static DWORD WINAPI readStdinThreadFunc(VOID)
2055 if (!Draw_IsConsoleSubsystem) return 1;
2057 while (console_semaphore != WAIT_CONSOLE_COMMAND)
2059 if (fgets(console_command,COMMAND_SIZE,stdin))
2061 console_semaphore = HAS_CONSOLE_COMMAND;
2066 /*--------------------------------------------------------*\
2067 | exitProc: finalization handler for Tcl/Tk thread. Forces parent process to die
2068 \*--------------------------------------------------------*/
2069 void exitProc(ClientData /*dc*/)
2071 HANDLE proc = GetCurrentProcess();
2072 TerminateProcess(proc, 0);
2075 /*--------------------------------------------------------*\
2076 | tkLoop: implements Tk_Main()-like behaviour in a separate thread
2077 \*--------------------------------------------------------*/
2078 static DWORD WINAPI tkLoop(VOID)
2080 Tcl_CreateExitHandler(exitProc, 0);
2081 #if (TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5))
2082 Tcl_RegisterChannel(theCommands.Interp(), Tcl_GetStdChannel(TCL_STDIN));
2083 Tcl_RegisterChannel(theCommands.Interp(), Tcl_GetStdChannel(TCL_STDOUT));
2084 Tcl_RegisterChannel(theCommands.Interp(), Tcl_GetStdChannel(TCL_STDERR));
2088 // initialize the Tk library if not in 'virtual windows' mode
2089 // (virtual windows are created by OCCT with native APIs,
2090 // thus Tk will be useless)
2091 if (!Draw_VirtualWindows)
2096 Standard_Integer res = Tk_Init (interp);
2099 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
2100 cout << "tkLoop: error in Tk initialization. Tcl reported: " << Tcl_GetStringResult(interp) << endl;
2102 cout << "tkLoop: error in Tk initialization. Tcl reported: " << interp->result << endl;
2106 catch (Standard_Failure)
2108 cout << "tkLoop: exception in TK_Init\n";
2110 Tcl_StaticPackage (interp, "Tk", Tk_Init, (Tcl_PackageInitProc* ) NULL);
2111 mainWindow = Tk_MainWindow (interp);
2112 if (mainWindow == NULL)
2114 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
2115 fprintf (stderr, "%s\n", Tcl_GetStringResult(interp));
2117 fprintf (stderr, "%s\n", interp->result);
2119 cout << "tkLoop: Tk_MainWindow() returned NULL. Exiting...\n";
2122 Tk_Name(mainWindow) = Tk_GetUid (Tk_SetAppName (mainWindow, "Draw"));
2126 // set signal handler in the new thread
2129 // inform the others that we have started
2130 isTkLoopStarted = true;
2132 while (console_semaphore == STOP_CONSOLE)
2133 Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
2135 if (Draw_IsConsoleSubsystem && console_semaphore == WAIT_CONSOLE_COMMAND)
2139 Standard_Boolean toLoop = Standard_True;
2142 while(Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT));
2143 if (console_semaphore == HAS_CONSOLE_COMMAND)
2145 if (Draw_Interprete (console_command))
2147 if (Draw_IsConsoleSubsystem) Prompt (interp, 0);
2151 if (Draw_IsConsoleSubsystem) Prompt (interp, 1);
2153 console_semaphore = WAIT_CONSOLE_COMMAND;
2160 // We should not exit until the Main Tk window is closed
2161 toLoop = (Tk_GetNumMainWindows() > 0) || Draw_VirtualWindows;
2169 /*--------------------------------------------------------*\
2171 \*--------------------------------------------------------*/
2172 void Run_Appli(HWND hWnd)
2175 HACCEL hAccel = NULL;
2179 // if (!(hAccel = LoadAccelerators (hInstance, MAKEINTRESOURCE(ACCEL_ID))))
2180 // MessageBox(hWnd, "MDI: Load Accel failure!", "Error", MB_OK);
2183 if (Draw_IsConsoleSubsystem) {
2184 hThread = CreateThread(NULL, // no security attributes
2185 0, // use default stack size
2186 (LPTHREAD_START_ROUTINE) readStdinThreadFunc, // thread function
2187 NULL, // no thread function argument
2188 0, // use default creation flags
2189 &IDThread); // returns thread identifier
2191 cout << "pb in creation of the thread reading stdin" << endl;
2192 Draw_IsConsoleSubsystem = Standard_False;
2193 Init_Appli(GetModuleHandle(NULL),
2194 GetModuleHandle(NULL),
2195 1, hWnd); // reinit => create MDI client wnd
2199 //turn on the command interpretation mechanism (regardless of the mode)
2200 if (console_semaphore == STOP_CONSOLE)
2201 console_semaphore = WAIT_CONSOLE_COMMAND;
2203 //simple Win32 message loop
2204 while (GetMessage(&msg, NULL, 0, 0) > 0)
2206 if (!TranslateAccelerator(hWnd, hAccel, &msg))
2208 TranslateMessage(&msg);
2209 DispatchMessage(&msg);
2216 /*--------------------------------------------------------*\
2218 \*--------------------------------------------------------*/
2219 void Destroy_Appli(HINSTANCE hInst)
2221 UnregisterAppClass(hInst);
2222 for (int i = 0 ; i < MAXCOLOR ; i++)
2223 DeleteObject(colorPenTab[i]);
2226 /*--------------------------------------------------------*\
2228 \*--------------------------------------------------------*/
2229 void DrawWindow::SelectWait(HANDLE& hWnd, int& x, int& y, int& button)
2235 GetMessage(&msg,NULL,0,0);
2236 while((msg.message != WM_RBUTTONDOWN && msg.message != WM_LBUTTONDOWN) ||
2237 ! ( Draw_IsConsoleSubsystem || IsChild(DrawWindow::hWndClientMDI,msg.hwnd)) )
2238 GetMessage(&msg,NULL,0,0);
2241 x = LOWORD(msg.lParam);
2242 y = HIWORD(msg.lParam);
2243 if (msg.message == WM_LBUTTONDOWN)
2249 /*--------------------------------------------------------*\
2251 \*--------------------------------------------------------*/
2252 void DrawWindow::SelectNoWait(HANDLE& hWnd, int& x, int& y, int& button)
2258 GetMessage(&msg,NULL,0,0);
2259 while((msg.message != WM_RBUTTONDOWN && msg.message != WM_LBUTTONDOWN &&
2260 msg.message != WM_MOUSEMOVE) ||
2261 ! ( Draw_IsConsoleSubsystem || IsChild(DrawWindow::hWndClientMDI,msg.hwnd) ) )
2262 GetMessage(&msg,NULL,0,0);
2264 x = LOWORD(msg.lParam);
2265 y = HIWORD(msg.lParam);
2266 switch (msg.message)
2268 case WM_LBUTTONDOWN :
2272 case WM_RBUTTONDOWN :
2282 Standard_Boolean DrawWindow::DefineColor (const Standard_Integer, const char*)
2284 return Standard_True;