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