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