0032308: Configuration - make Xlib dependency optional
[occt.git] / src / Draw / Draw_Window.cxx
index e0f3be4..c30c6bd 100644 (file)
 #include <windows.h>
 #endif
 
-#include <Standard_ErrorHandler.hxx>
-
-#include <tcl.h>
-#include <Draw_Interpretor.hxx>
 #include <Draw_Window.hxx>
+
+#include <Aspect_DisplayConnection.hxx>
 #include <Draw_Appli.hxx>
-#include <TCollection_AsciiString.hxx>
-#include <TCollection_ExtendedString.hxx>
+#include <Draw_Interpretor.hxx>
 #include <Image_AlienPixMap.hxx>
 #include <Message.hxx>
 #include <NCollection_List.hxx>
+#include <OSD.hxx>
+#include <OSD_Timer.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TCollection_ExtendedString.hxx>
 
-extern Standard_Boolean Draw_Batch;
-extern Standard_Boolean Draw_VirtualWindows;
-static NCollection_List<Draw_Window::FCallbackBeforeTerminate> MyCallbacks;
-
-void Draw_Window::AddCallbackBeforeTerminate(FCallbackBeforeTerminate theCB)
-{
-  MyCallbacks.Append(theCB);
-}
-
-void Draw_Window::RemoveCallbackBeforeTerminate(FCallbackBeforeTerminate theCB)
-{
-  NCollection_List<Draw_Window::FCallbackBeforeTerminate>::Iterator Iter(MyCallbacks);
-  for(; Iter.More(); Iter.Next())
-  {
-    if (Iter.Value() == theCB)
-    {
-      MyCallbacks.Remove(Iter);
-      break;
-    }
-  }
-}
+#include <tcl.h>
 
-/*
- *----------------------------------------------------------------------
- *
- * Prompt --
- *
- *        Issue a prompt on standard output, or invoke a script
- *        to issue the prompt.
- *
- * Results:
- *        None.
- *
- * Side effects:
- *        A prompt gets output, and a Tcl script may be evaluated
- *        in interp.
- *
- *----------------------------------------------------------------------
- */
-
-static void Prompt(Tcl_Interp *Interp, int partial)
-{
-    Tcl_Channel errChannel;
-    Tcl_Channel outChannel = Tcl_GetStdChannel(TCL_STDOUT);
-    const char* promptCmd = Tcl_GetVar (Interp, partial ? "tcl_prompt2" : "tcl_prompt1", TCL_GLOBAL_ONLY);
-    if (promptCmd == NULL) {
-defaultPrompt:
-      if (!partial && outChannel) {
-        Tcl_Write(outChannel, "% ", 2);
-      }
-    } else {
-      int code = Tcl_Eval(Interp, promptCmd);
-      outChannel = Tcl_GetStdChannel(TCL_STDOUT);
-      errChannel = Tcl_GetStdChannel(TCL_STDERR);
-      if (code != TCL_OK) {
-        if (errChannel) {
-#if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
-          Tcl_Write(errChannel, Tcl_GetStringResult(Interp), -1);
-#else
-          Tcl_Write(errChannel, Interp->result, -1);
+#if !defined(_WIN32)
+  #include <unistd.h>
 #endif
-          Tcl_Write(errChannel, "\n", 1);
-        }
-        Tcl_AddErrorInfo(Interp,
-                         "\n    (script that generates prompt)");
-        goto defaultPrompt;
-      }
-    }
-    if (outChannel) {
-      Tcl_Flush(outChannel);
-    }
-}
-
-#if !defined(_WIN32) && !defined(__WIN32__)
-
-#include <OSD_Timer.hxx>
-#include <Draw_Window.hxx>
-#include <unistd.h>
 
 #ifdef HAVE_TK
-#if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
+#if defined(__APPLE__) && !defined(HAVE_XLIB)
   // use forward declaration for small subset of used Tk functions
   // to workaround broken standard Tk framework installation within OS X SDKs
   // which *HAS* X11 headers in Tk.framework but doesn't install them appropriately
@@ -131,171 +60,216 @@ defaultPrompt:
 #endif
 #endif
 
-/*
- * Global variables used by the main program:
- */
-
-char *tcl_RcFileName = NULL;    /* Name of a user-specific startup script
-                                 * to source if the application is being run
-                                 * interactively (e.g. "~/.wishrc").  Set
-                                 * by Tcl_AppInit.  NULL means don't source
-                                 * anything ever. */
+#if defined(HAVE_XLIB)
+  #include <X11/Xutil.h>
+#endif
 
-static Tcl_DString command;     /* Used to assemble lines of terminal input
-                                 * into Tcl commands. */
-static Tcl_DString line;        /* Used to read the next line from the
-                                 * terminal input. */
-//static char errorExitCmd[] = "exit 1";
+#if defined(_WIN32)
 
-/*
- * Forward declarations for procedures defined later in this file:
- */
+#include "Draw_WNTRessource.pxx"
+#include "Draw_WNTInit.pxx"
 
-static void StdinProc (ClientData clientData, int mask);
+#define PENWIDTH 1
+#define CLIENTWND 0
 
-static void Prompt (Tcl_Interp *Interp, int partial);
+//! Creation of color stylos
+static HPEN Draw_colorPenTab[MAXCOLOR] =
+{
+  CreatePen(PS_SOLID, PENWIDTH, RGB(255,255,255)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(255,0,0)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(0,255,0)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(0,0,255)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(0,255,255)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(255,215,0)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(255,0,255)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(255,52,179)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(255,165,0)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(255,228,225)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(255,160,122)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(199,21,133)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(255,255,0)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(240,230,140)),
+  CreatePen(PS_SOLID, PENWIDTH, RGB(255,127,80))
+};
 
-static Standard_Boolean tty;        /* Non-zero means standard input is a
-                                 * terminal-like device.  Zero means it's
-                                 * a file. */
+// Correspondence mode X11 and WINDOWS NT
+static const int Draw_modeTab[16] =
+{
+  R2_BLACK, R2_MASKPEN, R2_MASKPENNOT, R2_COPYPEN,
+  R2_MASKNOTPEN, R2_NOP, R2_XORPEN, R2_MERGEPEN,
+  R2_NOTMASKPEN, R2_NOTXORPEN, R2_NOT, R2_MERGEPENNOT,
+  R2_NOTCOPYPEN, R2_MERGENOTPEN, R2_NOTMERGEPEN, R2_WHITE
+};
+#endif
 
-Standard_Integer Draw_WindowScreen = 0;
+extern Standard_Boolean Draw_Batch;
+extern Standard_Boolean Draw_VirtualWindows;
 Standard_Boolean Draw_BlackBackGround = Standard_True;
+#if defined(_WIN32)
+// indicates SUBSYSTEM:CONSOLE linker option, to be set to True in main()
+Standard_EXPORT Standard_Boolean Draw_IsConsoleSubsystem = Standard_False;
+HWND Draw_Window::hWndClientMDI = 0;
+#endif
 
-
-// Initialization of static variables of Draw_Window
-//======================================================
-Draw_Window* Draw_Window::firstWindow = NULL;
-
-// X11 specific part
-#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
-#include <X11/Xutil.h>
-#include <Aspect_DisplayConnection.hxx>
-
-static unsigned long thePixels[MAXCOLOR];
-
-Display* Draw_WindowDisplay = NULL;
-Colormap Draw_WindowColorMap;
-static Handle(Aspect_DisplayConnection) Draw_DisplayConnection;
-
-// Base_Window struct definition
-//===================================
-struct Base_Window
+//! Return termination callbacks.
+static NCollection_List<Draw_Window::FCallbackBeforeTerminate>& TermCallbacks()
 {
-  GC gc;
-  XSetWindowAttributes xswa;
-};
+  static NCollection_List<Draw_Window::FCallbackBeforeTerminate> MyCallbacks;
+  return MyCallbacks;
+}
 
 //=======================================================================
-//function : Draw_Window
+//function : AddCallbackBeforeTerminate
 //purpose  :
 //=======================================================================
-Draw_Window::Draw_Window() :
-       base(*new Base_Window()),
-       win(0),
-       myBuffer(0),
-       next(firstWindow),
-       previous(NULL),
-       myUseBuffer(Standard_False),
-       withWindowManager(Standard_True)
+void Draw_Window::AddCallbackBeforeTerminate (FCallbackBeforeTerminate theCB)
 {
-  myMother = RootWindow(Draw_WindowDisplay,
-                        Draw_WindowScreen);
-
-  if (firstWindow) firstWindow->previous = this;
-  firstWindow = this;
+  TermCallbacks().Append (theCB);
 }
 
 //=======================================================================
-//function : Draw_Window
+//function : RemoveCallbackBeforeTerminate
 //purpose  :
 //=======================================================================
-Draw_Window::Draw_Window(Window mother) :
-       base(*new Base_Window()),
-       win(0),
-       myBuffer(0),
-       next(firstWindow),
-       previous(NULL),
-       myUseBuffer(Standard_False),
-       withWindowManager(Standard_True)
+void Draw_Window::RemoveCallbackBeforeTerminate (FCallbackBeforeTerminate theCB)
 {
-  myMother = mother;
-
-  if (firstWindow) firstWindow->previous = this;
-  firstWindow = this;
+  for (NCollection_List<Draw_Window::FCallbackBeforeTerminate>::Iterator anIter (TermCallbacks());
+       anIter.More(); anIter.Next())
+  {
+    if (anIter.Value() == theCB)
+    {
+      TermCallbacks().Remove (anIter);
+      break;
+    }
+  }
 }
 
-//=======================================================================
-//function : Draw_Window
-//purpose  :
-//=======================================================================
-Draw_Window::Draw_Window (const char* title,
-                          Standard_Integer X, Standard_Integer Y,
-                          Standard_Integer DX, Standard_Integer DY) :
-       base(*new Base_Window()),
-       win(0),
-       myBuffer(0),
-       next(firstWindow),
-       previous(NULL),
-       myUseBuffer(Standard_False),
-       withWindowManager(Standard_True)
+//! Issue a prompt on standard output, or invoke a script to issue the prompt.
+//! Side effects: A prompt gets output, and a Tcl script may be evaluated in interp.
+static void Prompt (Tcl_Interp* theInterp, int thePartial)
 {
-  myMother = RootWindow(Draw_WindowDisplay,
-                        Draw_WindowScreen);
-
-  if (firstWindow) firstWindow->previous = this;
-  firstWindow = this;
-  Init(X,Y,DX,DY);
-  SetTitle(title);
+  Tcl_Channel errChannel;
+  Tcl_Channel outChannel = Tcl_GetStdChannel(TCL_STDOUT);
+  const char* promptCmd = Tcl_GetVar (theInterp, thePartial ? "tcl_prompt2" : "tcl_prompt1", TCL_GLOBAL_ONLY);
+  if (promptCmd == NULL)
+  {
+defaultPrompt:
+    if (!thePartial && outChannel)
+    {
+      Tcl_Write(outChannel, "% ", 2);
+    }
+  }
+  else
+  {
+    int code = Tcl_Eval (theInterp, promptCmd);
+    outChannel = Tcl_GetStdChannel (TCL_STDOUT);
+    errChannel = Tcl_GetStdChannel (TCL_STDERR);
+    if (code != TCL_OK)
+    {
+      if (errChannel)
+      {
+#if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
+        Tcl_Write (errChannel, Tcl_GetStringResult (theInterp), -1);
+#else
+        Tcl_Write (errChannel, theInterp->result, -1);
+#endif
+        Tcl_Write (errChannel, "\n", 1);
+      }
+      Tcl_AddErrorInfo (theInterp,
+                        "\n    (script that generates prompt)");
+      goto defaultPrompt;
+    }
+  }
+  if (outChannel)
+  {
+    Tcl_Flush (outChannel);
+  }
 }
 
-//=======================================================================
-//function : Draw_Window
-//purpose  :
-//=======================================================================
-Draw_Window::Draw_Window (const char* window ) :
-       base(*new Base_Window()),
-       win(0),
-       myBuffer(0),
-       next(firstWindow),
-       previous(NULL),
-       myUseBuffer(Standard_False),
-       withWindowManager(Standard_True)
-{
-  sscanf(window,"%lx",&win);
-  Standard_Integer X,Y,DX,DY;
+#if !defined(_WIN32)
+
+//! Used to assemble lines of terminal input into Tcl commands.
+static Tcl_DString Draw_TclCommand;
+//! Used to read the next line from the terminal input.
+static Tcl_DString Draw_TclLine;
+
+//! Forward declarations for procedures defined later in this file:
+static void StdinProc (ClientData theClientData, int theMask);
+static void Prompt (Tcl_Interp* theInterp, int thePartial);
+
+//! Non-zero means standard input is a terminal-like device.
+//! Zero means it's a file.
+static Standard_Boolean tty;
+
+#if defined(HAVE_XLIB)
+static unsigned long thePixels[MAXCOLOR];
 
-  if (firstWindow) firstWindow->previous = this;
-  firstWindow = this;
-  GetPosition(X,Y);
-  DX=HeightWin();
-  DY=WidthWin();
+Display* Draw_WindowDisplay = NULL;
+Colormap Draw_WindowColorMap;
+static Standard_Integer Draw_WindowScreen = 0;
+static Handle(Aspect_DisplayConnection) Draw_DisplayConnection;
 
-  Init(X,Y,DX,DY);
+//! Return list of windows.
+static NCollection_List<Draw_Window*>& getDrawWindowList()
+{
+  static NCollection_List<Draw_Window*> MyWindows;
+  return MyWindows;
 }
 
+//! Base_Window struct definition
+struct Draw_Window::Base_Window
+{
+  GC gc;
+  XSetWindowAttributes xswa;
+};
+#endif
+#endif
+
+#if !defined(__APPLE__) || defined(HAVE_XLIB) // implementation for Apple resides in .mm file
 //=======================================================================
 //function : Draw_Window
 //purpose  :
 //=======================================================================
-Draw_Window::Draw_Window (Window mother,
-                          char* title,
-                          Standard_Integer X, Standard_Integer Y,
-                          Standard_Integer DX, Standard_Integer DY) :
-       base(*new Base_Window()),
-       win(0),
-       myBuffer(0),
-       next(firstWindow),
-       previous(NULL),
-       myUseBuffer(Standard_False),
-       withWindowManager(Standard_True)
-{
-  myMother = mother;
+Draw_Window::Draw_Window (const char* theTitle,
+                          const NCollection_Vec2<int>& theXY,
+                          const NCollection_Vec2<int>& theSize,
+                          Aspect_Drawable theParent,
+                          Aspect_Drawable theWin)
+: myWindow (0),
+#if defined(_WIN32)
+  myMemHbm (NULL),
+  myCurrPen  (0),
+  myCurrMode (0),
+#elif defined(HAVE_XLIB)
+  myMother ((Window )theParent),
+  myImageBuffer (0),
+  myBase (new Base_Window()),
+#endif
+  myCurrentColor (0),
+  myUseBuffer (Standard_False)
+{
+  NCollection_Vec2<int> anXY = theXY, aSize = theSize;
+#if defined(_WIN32)
+  myWindow = (HWND )theWin;
+  (void )theParent;
+#elif defined(HAVE_XLIB)
+  myWindow = (Window )theWin;
+  if (theParent == 0)
+  {
+    myMother = RootWindow (Draw_WindowDisplay, Draw_WindowScreen);
+  }
+  if (theWin != 0)
+  {
+    GetPosition (anXY.x(), anXY.y());
+    aSize.x() = HeightWin();
+    aSize.y() = WidthWin();
+  }
+
+  getDrawWindowList().Append (this);
+#endif
 
-  if (firstWindow) firstWindow->previous = this;
-  firstWindow = this;
-  Init(X,Y,DX,DY);
-  SetTitle(title);
+  init (anXY, aSize);
+  SetTitle (theTitle);
 }
 
 //=======================================================================
@@ -304,68 +278,103 @@ Draw_Window::Draw_Window (Window mother,
 //=======================================================================
 Draw_Window::~Draw_Window()
 {
-  if (previous)
-    previous->next = next;
-  else
-    firstWindow = next;
-  if (next)
-    next->previous = previous;
-
-  if (myBuffer != 0)
+#ifdef _WIN32
+  // Delete 'off-screen drawing'-related objects
+  if (myMemHbm)
+  {
+    DeleteObject (myMemHbm);
+    myMemHbm = NULL;
+  }
+#elif defined(HAVE_XLIB)
+  getDrawWindowList().Remove (this);
+  if (myImageBuffer != 0)
   {
-    XFreePixmap(Draw_WindowDisplay, myBuffer);
-    myBuffer = 0;
+    XFreePixmap (Draw_WindowDisplay, myImageBuffer);
+    myImageBuffer = 0;
   }
-  // Liberation pointer on Base_Window
-  delete &base;
+#endif
 }
 
 //=======================================================================
-//function : Init
+//function : init
 //purpose  :
 //=======================================================================
-void Draw_Window::Init(Standard_Integer X, Standard_Integer Y,
-                       Standard_Integer DX, Standard_Integer DY)
+void Draw_Window::init (const NCollection_Vec2<int>& theXY,
+                        const NCollection_Vec2<int>& theSize)
 {
-  unsigned long setmask;
+#ifdef _WIN32
+  if (myWindow == NULL)
+  {
+    myWindow = createDrawWindow (hWndClientMDI, 0);
+  }
+
+  // include decorations in the window dimensions
+  // to reproduce same behaviour of Xlib window.
+  DWORD aWinStyle   = GetWindowLongW (myWindow, GWL_STYLE);
+  DWORD aWinStyleEx = GetWindowLongW (myWindow, GWL_EXSTYLE);
+  HMENU aMenu       = GetMenu (myWindow);
+
+  RECT aRect;
+  aRect.top    = theXY.y();
+  aRect.bottom = theXY.y() + theSize.y();
+  aRect.left   = theXY.x();
+  aRect.right  = theXY.x() + theSize.x();
+  AdjustWindowRectEx (&aRect, aWinStyle, aMenu != NULL ? TRUE : FALSE, aWinStyleEx);
+
+  SetPosition  (aRect.left, aRect.top);
+  SetDimension (aRect.right - aRect.left, aRect.bottom - aRect.top);
+  // Save the pointer at the instance associated to the window
+  SetWindowLongPtrW (myWindow, CLIENTWND, (LONG_PTR)this);
+  HDC hDC = GetDC (myWindow);
+  SetBkColor (hDC, RGB(0, 0, 0));
+  myCurrPen  = 3;
+  myCurrMode = 3;
+  SelectObject (hDC, Draw_colorPenTab[myCurrPen]); // Default pencil
+  SelectObject (hDC, GetStockObject(BLACK_BRUSH));
+  SetTextColor (hDC, RGB(0,0,255));
+  ReleaseDC (myWindow, hDC);
 
+  if (Draw_VirtualWindows)
+  {
+    // create a virtual window
+    SetUseBuffer (Standard_True);
+  }
+#elif defined(HAVE_XLIB)
   if (Draw_BlackBackGround)
   {
-    base.xswa.background_pixel = BlackPixel(Draw_WindowDisplay,Draw_WindowScreen);
-    base.xswa.border_pixel     = WhitePixel(Draw_WindowDisplay,Draw_WindowScreen);
+    myBase->xswa.background_pixel = BlackPixel(Draw_WindowDisplay, Draw_WindowScreen);
+    myBase->xswa.border_pixel     = WhitePixel(Draw_WindowDisplay, Draw_WindowScreen);
   }
   else
   {
-    base.xswa.background_pixel = WhitePixel(Draw_WindowDisplay,Draw_WindowScreen);
-    base.xswa.border_pixel     = BlackPixel(Draw_WindowDisplay,Draw_WindowScreen);
+    myBase->xswa.background_pixel = WhitePixel(Draw_WindowDisplay, Draw_WindowScreen);
+    myBase->xswa.border_pixel     = BlackPixel(Draw_WindowDisplay, Draw_WindowScreen);
   }
-  base.xswa.colormap         = Draw_WindowColorMap;
-  setmask               = CWBackPixel | CWBorderPixel ;
-
-  XSizeHints myHints;
-  myHints.flags = USPosition;
-  myHints.x = (int) X;
-  myHints.y = (int) Y;
+  myBase->xswa.colormap = Draw_WindowColorMap;
+  unsigned long aSetMask = CWBackPixel | CWBorderPixel;
 
-  if (win == 0)
+  XSizeHints aWinHints;
+  aWinHints.flags = USPosition;
+  aWinHints.x = theXY.x();
+  aWinHints.y = theXY.y();
+  if (myWindow == 0)
   {
-    win = XCreateWindow(Draw_WindowDisplay,
-                        myMother,
-                        (int) X,(int) Y,
-                        (unsigned int) DX,(unsigned int) DY,
-                        5,
-                        DefaultDepth(Draw_WindowDisplay,Draw_WindowScreen),
-                        InputOutput,
-                        DefaultVisual(Draw_WindowDisplay,Draw_WindowScreen),
-                        setmask,&base.xswa);
-    XSelectInput(Draw_WindowDisplay, win, ButtonPressMask|ExposureMask|
-                                          StructureNotifyMask);
+    myWindow = XCreateWindow (Draw_WindowDisplay,
+                              myMother,
+                              theXY.x(), theXY.y(),
+                              (unsigned int )theSize.x(), (unsigned int )theSize.y(),
+                              5,
+                              DefaultDepth(Draw_WindowDisplay, Draw_WindowScreen),
+                              InputOutput,
+                              DefaultVisual(Draw_WindowDisplay, Draw_WindowScreen),
+                              aSetMask, &myBase->xswa);
+    XSelectInput (Draw_WindowDisplay, myWindow, ButtonPressMask | ExposureMask | StructureNotifyMask);
 
     // advise to the window manager to place it where I need
-    XSetWMNormalHints(Draw_WindowDisplay,win,&myHints);
+    XSetWMNormalHints (Draw_WindowDisplay, myWindow, &aWinHints);
 
     Atom aDeleteWindowAtom = Draw_DisplayConnection->GetAtom (Aspect_XA_DELETE_WINDOW);
-    XSetWMProtocols (Draw_WindowDisplay, win, &aDeleteWindowAtom, 1);
+    XSetWMProtocols (Draw_WindowDisplay, myWindow, &aDeleteWindowAtom, 1);
 
     if (Draw_VirtualWindows)
     {
@@ -374,120 +383,215 @@ void Draw_Window::Init(Standard_Integer X, Standard_Integer Y,
     }
   }
 
-  base.gc = XCreateGC(Draw_WindowDisplay, win, 0, NULL);
+  myBase->gc = XCreateGC (Draw_WindowDisplay, myWindow, 0, NULL);
 
-  XSetPlaneMask(Draw_WindowDisplay,base.gc,AllPlanes);
-  XSetForeground(Draw_WindowDisplay,
-                 base.gc, WhitePixel(Draw_WindowDisplay,Draw_WindowScreen));
-  XSetBackground(Draw_WindowDisplay,
-                 base.gc, BlackPixel(Draw_WindowDisplay,Draw_WindowScreen));
+  XSetPlaneMask (Draw_WindowDisplay, myBase->gc, AllPlanes);
+  XSetForeground (Draw_WindowDisplay,
+                  myBase->gc, WhitePixel(Draw_WindowDisplay, Draw_WindowScreen));
+  XSetBackground (Draw_WindowDisplay,
+                  myBase->gc, BlackPixel(Draw_WindowDisplay, Draw_WindowScreen));
   // save in case of window recovery
 
-  base.xswa.backing_store = Always;
-  XChangeWindowAttributes(Draw_WindowDisplay, win,
-                          CWBackingStore, &base.xswa);
+  myBase->xswa.backing_store = Always;
+  XChangeWindowAttributes (Draw_WindowDisplay, myWindow,
+                           CWBackingStore, &myBase->xswa);
 
-  XSetLineAttributes (Draw_WindowDisplay, base.gc,
+  XSetLineAttributes (Draw_WindowDisplay, myBase->gc,
                       0, LineSolid, CapButt, JoinMiter);
+#else
+  (void )theXY;
+  (void )theSize;
+#endif
 }
 
 //=======================================================================
-//function : InitBuffer
+//function : SetUseBuffer
 //purpose  :
 //=======================================================================
-void Draw_Window::InitBuffer()
+void Draw_Window::SetUseBuffer (Standard_Boolean theToUse)
 {
-  if (myUseBuffer) {
-    if (myBuffer != 0) {
-      XFreePixmap (Draw_WindowDisplay, myBuffer);
-    }
-    XWindowAttributes winAttr;
-    XGetWindowAttributes (Draw_WindowDisplay, win, &winAttr);
-    myBuffer = XCreatePixmap (Draw_WindowDisplay, win, winAttr.width, winAttr.height, winAttr.depth);
-  }
-  else if (myBuffer != 0)
-  {
-    XFreePixmap (Draw_WindowDisplay, myBuffer);
-    myBuffer = 0;
-  }
+  myUseBuffer = theToUse;
+  InitBuffer();
 }
 
+#ifdef _WIN32
 //=======================================================================
-//function : StopWinManager
+//function : getMemDC
 //purpose  :
 //=======================================================================
-void Draw_Window::StopWinManager()
+HDC Draw_Window::getMemDC (HDC theWinDC)
 {
-//  XGCValues winGc;
-  XWindowAttributes winAttr;
-  XGetWindowAttributes (Draw_WindowDisplay, win, &winAttr);
-  Destroy();
-
-  XSizeHints myHints;
-  myHints.flags = USPosition;
-  myHints.x = (int) 30;
-  myHints.y = (int) 100;
-
-  base.xswa.override_redirect = 1;
-  base.xswa.border_pixel = BlackPixel(Draw_WindowDisplay,
-                                 Draw_WindowScreen);
-  base.xswa.background_pixel = WhitePixel(Draw_WindowDisplay,
-                               Draw_WindowScreen);
-
-  withWindowManager = Standard_False;
+  if (!myUseBuffer)
+  {
+    return NULL;
+  }
 
-  win = XCreateWindow(Draw_WindowDisplay, myMother,
-                      winAttr.x, winAttr.y,
-                      winAttr.width, winAttr.height,
-                      2,
-                      CopyFromParent, InputOutput, CopyFromParent,
-                      CWBorderPixel|CWOverrideRedirect|CWBackPixel, &base.xswa);
+  HDC aWorkDC = CreateCompatibleDC (theWinDC);
+  myOldHbm = (HBITMAP )SelectObject (aWorkDC, myMemHbm);
+  SetROP2 (aWorkDC, Draw_modeTab[myCurrMode]);
+  SelectObject (aWorkDC, Draw_colorPenTab[myCurrPen]);
+  SetBkColor   (aWorkDC, RGB(0, 0, 0));
+  SelectObject (aWorkDC, GetStockObject(BLACK_BRUSH));
+  SetTextColor (aWorkDC, RGB(0,0,255));
+  return aWorkDC;
+}
 
+//=======================================================================
+//function : releaseMemDC
+//purpose  :
+//=======================================================================
+void Draw_Window::releaseMemDC (HDC theMemDC)
+{
+  if (!myUseBuffer || !theMemDC)
+  {
+    return;
+  }
 
-  // adwise to the window manager to place it where I wish
-  XSetWMNormalHints(Draw_WindowDisplay,win,&myHints);
+  if (myOldHbm)
+  {
+    SelectObject (theMemDC, myOldHbm);
+  }
+  DeleteDC (theMemDC);
+}
+#endif
 
-  // all masks of the old window are reassigned to the new one.
-  XSelectInput(Draw_WindowDisplay,win,winAttr.your_event_mask);
+//=======================================================================
+//function : InitBuffer
+//purpose  :
+//=======================================================================
+void Draw_Window::InitBuffer()
+{
+#ifdef _WIN32
+  if (myUseBuffer)
+  {
+    RECT aRect;
+    HDC hDC = GetDC (myWindow);
+    GetClientRect (myWindow, &aRect);
+    if (myMemHbm)
+    {
+      BITMAP aBmp;
+      GetObjectW (myMemHbm, sizeof(BITMAP), &aBmp);
+      if ((aRect.right - aRect.left) == aBmp.bmWidth
+       && (aRect.bottom - aRect.top) == aBmp.bmHeight)
+      {
+        return;
+      }
+      DeleteObject (myMemHbm);
+    }
+    myMemHbm = (HBITMAP )CreateCompatibleBitmap (hDC,
+                                                 aRect.right - aRect.left,
+                                                 aRect.bottom - aRect.top);
+    HDC aMemDC = getMemDC (hDC);
+    FillRect (aMemDC, &aRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
+    releaseMemDC (aMemDC);
+    ReleaseDC (myWindow, hDC);
+  }
+  else
+  {
+    if (myMemHbm)
+    {
+      DeleteObject (myMemHbm);
+      myMemHbm = NULL;
+    }
+  }
+#elif defined(HAVE_XLIB)
+  if (myUseBuffer)
+  {
+    if (myImageBuffer != 0)
+    {
+      XFreePixmap (Draw_WindowDisplay, myImageBuffer);
+    }
+    XWindowAttributes aWinAttr;
+    XGetWindowAttributes (Draw_WindowDisplay, myWindow, &aWinAttr);
+    myImageBuffer = XCreatePixmap (Draw_WindowDisplay, myWindow, aWinAttr.width, aWinAttr.height, aWinAttr.depth);
+  }
+  else if (myImageBuffer != 0)
+  {
+    XFreePixmap (Draw_WindowDisplay, myImageBuffer);
+    myImageBuffer = 0;
+  }
+#endif
 }
 
 //=======================================================================
 //function : SetPosition
 //purpose  :
 //=======================================================================
-void Draw_Window::SetPosition(Standard_Integer NewXpos,
-                              Standard_Integer NewYpos)
+void Draw_Window::SetPosition (Standard_Integer theNewXpos,
+                               Standard_Integer theNewYpos)
 {
-  Standard_Integer x,y;
-  GetPosition(x, y);
-
-  if ( (x != NewXpos) || (y != NewYpos) )
-    XMoveWindow(Draw_WindowDisplay, win, NewXpos, NewYpos);
+#ifdef _WIN32
+  UINT aFlags = SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER;
+  if (Draw_VirtualWindows)
+  {
+    aFlags |= SWP_NOSENDCHANGING;
+  }
+  SetWindowPos (myWindow, 0, theNewXpos, theNewYpos, 0, 0, aFlags);
+#elif defined(HAVE_XLIB)
+  Standard_Integer aPosX = 0, aPosY = 0;
+  GetPosition (aPosX, aPosY);
+  if (aPosX != theNewXpos
+   || aPosY != theNewYpos)
+  {
+    XMoveWindow (Draw_WindowDisplay, myWindow, theNewXpos, theNewYpos);
+  }
+#else
+  (void )theNewXpos;
+  (void )theNewYpos;
+#endif
 }
 
 //=======================================================================
 //function : SetDimension
 //purpose  :
 //=======================================================================
-void Draw_Window::SetDimension(Standard_Integer NewDx,
-                               Standard_Integer NewDy)
+void Draw_Window::SetDimension (Standard_Integer theNewDx,
+                                Standard_Integer theNewDy)
 {
-  if ( (NewDx != WidthWin() ) || (NewDy != HeightWin() ) )
-    XResizeWindow(Draw_WindowDisplay, win, NewDx, NewDy);
+#ifdef _WIN32
+  UINT aFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER;
+  if (Draw_VirtualWindows)
+  {
+    aFlags |= SWP_NOSENDCHANGING;
+  }
+  SetWindowPos (myWindow, 0, 0, 0, theNewDx, theNewDy, aFlags);
+#elif defined(HAVE_XLIB)
+  if (theNewDx != WidthWin()
+   || theNewDy != HeightWin())
+  {
+    XResizeWindow (Draw_WindowDisplay, myWindow, theNewDx, theNewDy);
+  }
+#else
+  (void )theNewDx;
+  (void )theNewDy;
+#endif
 }
 
 //=======================================================================
 //function : GetPosition
 //purpose  :
 //=======================================================================
-void Draw_Window::GetPosition(Standard_Integer &PosX,
-                              Standard_Integer &PosY)
+void Draw_Window::GetPosition (Standard_Integer& thePosX,
+                               Standard_Integer& thePosY)
 {
-  XWindowAttributes winAttr;
-  XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);
+  thePosX = thePosY = 0;
+#ifdef _WIN32
+  RECT aRect;
+  GetWindowRect (myWindow, &aRect);
 
-  PosX = winAttr.x;
-  PosY = winAttr.y;
+  POINT aPoint;
+  aPoint.x = aRect.left;
+  aPoint.y = aRect.top;
+
+  ScreenToClient (hWndClientMDI, &aPoint);
+  thePosX = aPoint.x;
+  thePosY = aPoint.y;
+#elif defined(HAVE_XLIB)
+  XWindowAttributes aWinAttr;
+  XGetWindowAttributes (Draw_WindowDisplay, myWindow, &aWinAttr);
+  thePosX = aWinAttr.x;
+  thePosY = aWinAttr.y;
+#endif
 }
 
 //=======================================================================
@@ -496,12 +600,17 @@ void Draw_Window::GetPosition(Standard_Integer &PosX,
 //=======================================================================
 Standard_Integer Draw_Window::HeightWin() const
 {
-  Standard_Integer DY;
-  XWindowAttributes winAttr;
-  XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);
-
-  DY = winAttr.height;
-  return DY;
+#ifdef _WIN32
+  RECT aRect;
+  GetClientRect (myWindow, &aRect);
+  return aRect.bottom - aRect.top;
+#elif defined(HAVE_XLIB)
+  XWindowAttributes aWinAttr;
+  XGetWindowAttributes (Draw_WindowDisplay, myWindow, &aWinAttr);
+  return aWinAttr.height;
+#else
+  return 1;
+#endif
 }
 
 //=======================================================================
@@ -510,21 +619,33 @@ Standard_Integer Draw_Window::HeightWin() const
 //=======================================================================
 Standard_Integer Draw_Window::WidthWin() const
 {
-  Standard_Integer DX;
-  XWindowAttributes winAttr;
-  XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);
-
-  DX = winAttr.width;
-  return DX;
-}
-
-//=======================================================================
-//function : SetTitle
+#ifdef _WIN32
+  RECT aRect;
+  GetClientRect (myWindow, &aRect);
+  return aRect.right - aRect.left;
+#elif defined(HAVE_XLIB)
+  XWindowAttributes aWinAttr;
+  XGetWindowAttributes (Draw_WindowDisplay, myWindow, &aWinAttr);
+  return aWinAttr.width;
+#else
+  return 1;
+#endif
+}
+
+//=======================================================================
+//function : SetTitle
 //purpose  :
 //=======================================================================
-void Draw_Window::SetTitle(const TCollection_AsciiString& theTitle)
+void Draw_Window::SetTitle (const TCollection_AsciiString& theTitle)
 {
-  XStoreName (Draw_WindowDisplay, win, theTitle.ToCString());
+#ifdef _WIN32
+  const TCollection_ExtendedString aTitleW (theTitle);
+  SetWindowTextW (myWindow, aTitleW.ToWideString());
+#elif defined(HAVE_XLIB)
+  XStoreName (Draw_WindowDisplay, myWindow, theTitle.ToCString());
+#else
+  (void )theTitle;
+#endif
 }
 
 //=======================================================================
@@ -533,34 +654,43 @@ void Draw_Window::SetTitle(const TCollection_AsciiString& theTitle)
 //=======================================================================
 TCollection_AsciiString Draw_Window::GetTitle() const
 {
+#ifdef _WIN32
+  wchar_t aTitleW[32];
+  GetWindowTextW (myWindow, aTitleW, 30);
+  return TCollection_AsciiString (aTitleW);
+#elif defined(HAVE_XLIB)
   char* aTitle = NULL;
-  XFetchName (Draw_WindowDisplay, win, &aTitle);
+  XFetchName (Draw_WindowDisplay, myWindow, &aTitle);
   return TCollection_AsciiString (aTitle);
-}
-
-//=======================================================================
-//function : GetDrawable
-//purpose  :
-//=======================================================================
-Drawable Draw_Window::GetDrawable() const
-{
-  return myUseBuffer ? myBuffer : win;
+#else
+  return TCollection_AsciiString();
+#endif
 }
 
 //=======================================================================
 //function :DefineColor
 //purpose  :
 //=======================================================================
-Standard_Boolean Draw_Window::DefineColor(const Standard_Integer i, const char* colorName)
+Standard_Boolean Draw_Window::DefineColor (const Standard_Integer theIndex,
+                                           const char* theColorName)
 {
-  XColor color;
-
-  if (!XParseColor(Draw_WindowDisplay,Draw_WindowColorMap,colorName,&color))
+#if defined(HAVE_XLIB)
+  XColor aColor;
+  if (!XParseColor (Draw_WindowDisplay, Draw_WindowColorMap, theColorName, &aColor))
+  {
     return Standard_False;
-  if (!XAllocColor(Draw_WindowDisplay,Draw_WindowColorMap,&color))
+  }
+  if (!XAllocColor (Draw_WindowDisplay, Draw_WindowColorMap, &aColor))
+  {
     return Standard_False;
-  thePixels[i % MAXCOLOR] = color.pixel;
+  }
+  thePixels[theIndex % MAXCOLOR] = aColor.pixel;
+  return Standard_True;
+#else
+  (void )theIndex;
+  (void )theColorName;
   return Standard_True;
+#endif
 }
 
 //=======================================================================
@@ -570,16 +700,24 @@ Standard_Boolean Draw_Window::DefineColor(const Standard_Integer i, const char*
 bool Draw_Window::IsMapped() const
 {
   if (Draw_VirtualWindows
-   || win == 0)
+   || myWindow == 0)
   {
     return false;
   }
 
+#ifdef _WIN32
+  LONG aWinStyle = GetWindowLongW (myWindow, GWL_STYLE);
+  return (aWinStyle & WS_VISIBLE)  != 0
+      && (aWinStyle & WS_MINIMIZE) == 0;
+#elif defined(HAVE_XLIB)
   XFlush (Draw_WindowDisplay);
   XWindowAttributes aWinAttr;
-  XGetWindowAttributes (Draw_WindowDisplay, win, &aWinAttr);
+  XGetWindowAttributes (Draw_WindowDisplay, myWindow, &aWinAttr);
   return aWinAttr.map_state == IsUnviewable
       || aWinAttr.map_state == IsViewable;
+#else
+  return false;
+#endif
 }
 
 //=======================================================================
@@ -592,11 +730,14 @@ void Draw_Window::DisplayWindow()
   {
     return;
   }
-  else
-  {
-    XMapRaised(Draw_WindowDisplay, win);
-  }
-  XFlush(Draw_WindowDisplay);
+
+#ifdef _WIN32
+  ShowWindow (myWindow, SW_SHOW);
+  UpdateWindow (myWindow);
+#elif defined(HAVE_XLIB)
+  XMapRaised (Draw_WindowDisplay, myWindow);
+  XFlush (Draw_WindowDisplay);
+#endif
 }
 
 //=======================================================================
@@ -605,7 +746,11 @@ void Draw_Window::DisplayWindow()
 //=======================================================================
 void Draw_Window::Hide()
 {
-   XUnmapWindow(Draw_WindowDisplay, win);
+#ifdef _WIN32
+  ShowWindow (myWindow, SW_HIDE);
+#elif defined(HAVE_XLIB)
+  XUnmapWindow (Draw_WindowDisplay, myWindow);
+#endif
 }
 
 //=======================================================================
@@ -614,14 +759,18 @@ void Draw_Window::Hide()
 //=======================================================================
 void Draw_Window::Destroy()
 {
-  XFreeGC (Draw_WindowDisplay, base.gc);
-  XDestroyWindow(Draw_WindowDisplay, win);
-  win = 0;
-  if (myBuffer != 0)
+#ifdef _WIN32
+  DestroyWindow (myWindow);
+#elif defined(HAVE_XLIB)
+  XFreeGC (Draw_WindowDisplay, myBase->gc);
+  XDestroyWindow (Draw_WindowDisplay, myWindow);
+  myWindow = 0;
+  if (myImageBuffer != 0)
   {
-    XFreePixmap(Draw_WindowDisplay, myBuffer);
-    myBuffer = 0;
+    XFreePixmap (Draw_WindowDisplay, myImageBuffer);
+    myImageBuffer = 0;
   }
+#endif
 }
 
 //=======================================================================
@@ -630,19 +779,35 @@ void Draw_Window::Destroy()
 //=======================================================================
 void Draw_Window::Clear()
 {
+#ifdef _WIN32
+  HDC hDC = GetDC (myWindow);
+  HDC aWorkDC = myUseBuffer ? getMemDC(hDC) : hDC;
+
+  SaveDC (aWorkDC);
+  SelectObject (aWorkDC, GetStockObject(BLACK_PEN));
+  Rectangle (aWorkDC, 0, 0, WidthWin(), HeightWin());
+  RestoreDC (aWorkDC,-1);
+
+  if (myUseBuffer)
+  {
+    releaseMemDC (aWorkDC);
+  }
+  ReleaseDC (myWindow, hDC);
+#elif defined(HAVE_XLIB)
   if (myUseBuffer)
   {
     // XClearArea only applicable for windows
-    XGCValues currValues;
-    XGetGCValues(Draw_WindowDisplay, base.gc, GCBackground | GCForeground, &currValues);
-    XSetForeground(Draw_WindowDisplay, base.gc, currValues.background);
-    XFillRectangle(Draw_WindowDisplay, myBuffer, base.gc, 0, 0, WidthWin(), HeightWin());
-    XSetForeground(Draw_WindowDisplay, base.gc, currValues.foreground);
+    XGCValues aCurrValues;
+    XGetGCValues (Draw_WindowDisplay, myBase->gc, GCBackground | GCForeground, &aCurrValues);
+    XSetForeground (Draw_WindowDisplay, myBase->gc, aCurrValues.background);
+    XFillRectangle (Draw_WindowDisplay, myImageBuffer, myBase->gc, 0, 0, WidthWin(), HeightWin());
+    XSetForeground (Draw_WindowDisplay, myBase->gc, aCurrValues.foreground);
   }
   else
   {
-    XClearArea(Draw_WindowDisplay, win, 0, 0, 0, 0, False);
+    XClearArea (Draw_WindowDisplay, myWindow, 0, 0, 0, 0, False);
   }
+#endif
 }
 
 //=======================================================================
@@ -651,25 +816,65 @@ void Draw_Window::Clear()
 //=======================================================================
 void Draw_Window::Flush()
 {
-  XFlush(Draw_WindowDisplay);
+#if defined(HAVE_XLIB)
+  XFlush (Draw_WindowDisplay);
+#endif
 }
 
 //=======================================================================
 //function : DrawString
 //purpose  :
 //=======================================================================
-void Draw_Window::DrawString(int X, int Y, char *text)
+void Draw_Window::DrawString (Standard_Integer theX, Standard_Integer theY,
+                              const char* theText)
 {
-  XDrawString(Draw_WindowDisplay, GetDrawable(), base.gc, X, Y, text, strlen(text));
+#ifdef _WIN32
+  HDC hDC = GetDC (myWindow);
+  HDC aWorkDC = myUseBuffer ? getMemDC(hDC) : hDC;
+
+  const TCollection_ExtendedString aTextW (theText);
+  TextOutW (aWorkDC, theX, theY, aTextW.ToWideString(), aTextW.Length());
+
+  if (myUseBuffer)
+  {
+    releaseMemDC (aWorkDC);
+  }
+  ReleaseDC (myWindow, hDC);
+#elif defined(HAVE_XLIB)
+  XDrawString (Draw_WindowDisplay, GetDrawable(), myBase->gc, theX, theY, (char* )theText, strlen(theText));
+#else
+  //
+#endif
 }
 
 //=======================================================================
 //function : DrawSegments
 //purpose  :
 //=======================================================================
-void Draw_Window::DrawSegments(Segment *tab, int nbElem)
+void Draw_Window::DrawSegments (const Draw_XSegment* theSegments,
+                                Standard_Integer theNbElems)
 {
-  XDrawSegments(Draw_WindowDisplay, GetDrawable(), base.gc, (XSegment*) tab, nbElem);
+#ifdef _WIN32
+  HDC hDC = GetDC (myWindow);
+  HDC aWorkDC = myUseBuffer ? getMemDC(hDC) : hDC;
+  for (int aSegIter = 0; aSegIter < theNbElems; ++aSegIter)
+  {
+    const Draw_XSegment& aSeg = theSegments[aSegIter];
+    MoveToEx(aWorkDC, aSeg[0].x(), aSeg[0].y(), NULL);
+    LineTo  (aWorkDC, aSeg[1].x(), aSeg[1].y());
+  }
+  if (myUseBuffer)
+  {
+    releaseMemDC (aWorkDC);
+  }
+  ReleaseDC (myWindow, hDC);
+#elif defined(HAVE_XLIB)
+  Standard_STATIC_ASSERT(sizeof(Draw_XSegment) == sizeof(XSegment));
+  XDrawSegments (Draw_WindowDisplay, GetDrawable(), myBase->gc, (XSegment* )theSegments, theNbElems);
+#else
+  (void )theSegments;
+  (void )theNbElems;
+#endif
 }
 
 //=======================================================================
@@ -678,33 +883,113 @@ void Draw_Window::DrawSegments(Segment *tab, int nbElem)
 //=======================================================================
 void Draw_Window::Redraw()
 {
-  if (myUseBuffer) {
+#ifdef _WIN32
+  if (myUseBuffer)
+  {
+    HDC hDC = GetDC (myWindow);
+    RECT aRect;
+    GetClientRect (myWindow, &aRect);
+    HDC aMemDC = getMemDC (hDC);
+    BitBlt (hDC,
+            aRect.left, aRect.top,
+            aRect.right - aRect.left, aRect.bottom - aRect.top,
+            aMemDC,
+            0, 0, SRCCOPY);
+    releaseMemDC (aMemDC);
+    ReleaseDC (myWindow, hDC);
+  }
+#elif defined(HAVE_XLIB)
+  if (myUseBuffer)
+  {
     XCopyArea (Draw_WindowDisplay,
-               myBuffer, win, // source, destination Drawables
-               base.gc,
-               0, 0,  // source x, y
+               myImageBuffer, myWindow,
+               myBase->gc,
+               0, 0,
                WidthWin(), HeightWin(),
-               0, 0); // destination x, y
+               0, 0);
   }
+#endif
 }
 
 //=======================================================================
 //function : SetColor
 //purpose  :
 //=======================================================================
-void Draw_Window::SetColor(Standard_Integer color)
+void Draw_Window::SetColor (Standard_Integer theColor)
 {
-  XSetForeground(Draw_WindowDisplay, base.gc, thePixels[color]);
+#ifdef _WIN32
+  HDC hDC = GetDC (myWindow);
+  myCurrPen = theColor;
+  SelectObject (hDC, Draw_colorPenTab[theColor]);
+  ReleaseDC (myWindow, hDC);
+#elif defined(HAVE_XLIB)
+  XSetForeground (Draw_WindowDisplay, myBase->gc, thePixels[theColor]);
+#endif
+  myCurrentColor = theColor;
 }
 
 //=======================================================================
 //function : SetMode
 //purpose  :
 //=======================================================================
-void Draw_Window::SetMode( int mode)
+void Draw_Window::SetMode (int theMode)
+{
+#ifdef _WIN32
+  HDC hDC = GetDC (myWindow);
+  myCurrMode = theMode;
+  SetROP2 (hDC, Draw_modeTab[theMode]);
+  ReleaseDC (myWindow, hDC);
+#elif defined(HAVE_XLIB)
+  XSetFunction (Draw_WindowDisplay, myBase->gc, theMode);
+#else
+  (void )theMode;
+#endif
+}
+
+#ifdef _WIN32
+/*--------------------------------------------------------*\
+|  SaveBitmap
+\*--------------------------------------------------------*/
+static Standard_Boolean SaveBitmap (HBITMAP     theHBitmap,
+                                    const char* theFileName)
 {
-  XSetFunction(Draw_WindowDisplay, base.gc, mode);
+  // Get information about the bitmap
+  BITMAP aBitmap;
+  if (GetObjectW (theHBitmap, sizeof(BITMAP), &aBitmap) == 0)
+  {
+    return Standard_False;
+  }
+
+  Image_AlienPixMap anImage;
+  const Standard_Size aSizeRowBytes = ((Standard_Size(aBitmap.bmWidth) * 24 + 31) / 32) * 4; // 4 bytes alignment for GetDIBits()
+  if (!anImage.InitTrash (Image_Format_BGR, Standard_Size(aBitmap.bmWidth), Standard_Size(aBitmap.bmHeight), aSizeRowBytes))
+  {
+    return Standard_False;
+  }
+  anImage.SetTopDown (false);
+
+  // Setup image data
+  BITMAPINFOHEADER aBitmapInfo;
+  memset (&aBitmapInfo, 0, sizeof(BITMAPINFOHEADER));
+  aBitmapInfo.biSize        = sizeof(BITMAPINFOHEADER);
+  aBitmapInfo.biWidth       = aBitmap.bmWidth;
+  aBitmapInfo.biHeight      = aBitmap.bmHeight; // positive means bottom-up!
+  aBitmapInfo.biPlanes      = 1;
+  aBitmapInfo.biBitCount    = 24;
+  aBitmapInfo.biCompression = BI_RGB;
+
+  // Copy the pixels
+  HDC aDC = GetDC (NULL);
+  Standard_Boolean isSuccess = GetDIBits (aDC, theHBitmap,
+                                          0,                           // first scan line to set
+                                          aBitmap.bmHeight,            // number of scan lines to copy
+                                          anImage.ChangeData(),        // array for bitmap bits
+                                          (LPBITMAPINFO )&aBitmapInfo, // bitmap data info
+                                          DIB_RGB_COLORS) != 0;
+  ReleaseDC (NULL, aDC);
+  return isSuccess && anImage.Save (theFileName);
 }
+#endif
 
 //=======================================================================
 //function : Save
@@ -712,27 +997,55 @@ void Draw_Window::SetMode( int mode)
 //=======================================================================
 Standard_Boolean Draw_Window::Save (const char* theFileName) const
 {
+#ifdef _WIN32
+  if (myUseBuffer)
+  {
+    return SaveBitmap (myMemHbm, theFileName);
+  }
+
+  RECT aRect;
+  GetClientRect (myWindow, &aRect);
+  int aWidth  = aRect.right  - aRect.left;
+  int aHeight = aRect.bottom - aRect.top;
+
+  // Prepare the DCs
+  HDC aDstDC = GetDC (NULL);
+  HDC aSrcDC = GetDC (myWindow); // we copy only client area
+  HDC aMemDC = CreateCompatibleDC (aDstDC);
+
+  // Copy the screen to the bitmap
+  HBITMAP anHBitmapDump = CreateCompatibleBitmap (aDstDC, aWidth, aHeight);
+  HBITMAP anHBitmapOld = (HBITMAP )SelectObject (aMemDC, anHBitmapDump);
+  BitBlt (aMemDC, 0, 0, aWidth, aHeight, aSrcDC, 0, 0, SRCCOPY);
+
+  Standard_Boolean isSuccess = SaveBitmap (anHBitmapDump, theFileName);
+
+  // Free objects
+  DeleteObject (SelectObject (aMemDC, anHBitmapOld));
+  DeleteDC (aMemDC);
+
+  return isSuccess;
+#elif defined(HAVE_XLIB)
   // make sure all draw operations done
   XSync (Draw_WindowDisplay, True);
 
   // the attributes
-  XWindowAttributes winAttr;
-  XGetWindowAttributes (Draw_WindowDisplay, win, &winAttr);
+  XWindowAttributes aWinAttr;
+  XGetWindowAttributes (Draw_WindowDisplay, myWindow, &aWinAttr);
 
   if (!myUseBuffer)
   {
     // make sure that the whole window fit on display to prevent BadMatch error
-    XWindowAttributes winAttrRoot;
-    XGetWindowAttributes (Draw_WindowDisplay, XRootWindowOfScreen (winAttr.screen), &winAttrRoot);
+    XWindowAttributes aWinAttrRoot;
+    XGetWindowAttributes (Draw_WindowDisplay, XRootWindowOfScreen (aWinAttr.screen), &aWinAttrRoot);
 
-    Window winChildDummy;
-    int winLeft = 0;
-    int winTop = 0;
-    XTranslateCoordinates (Draw_WindowDisplay, win, XRootWindowOfScreen (winAttr.screen),
-                           0, 0, &winLeft, &winTop, &winChildDummy);
+    Window aWinChildDummy;
+    int aWinLeft = 0, aWinTop = 0;
+    XTranslateCoordinates (Draw_WindowDisplay, myWindow, XRootWindowOfScreen (aWinAttr.screen),
+                           0, 0, &aWinLeft, &aWinTop, &aWinChildDummy);
 
-    if (((winLeft + winAttr.width) > winAttrRoot.width)  || winLeft < winAttrRoot.x ||
-        ((winTop + winAttr.height) > winAttrRoot.height) || winTop  < winAttrRoot.y)
+    if (((aWinLeft + aWinAttr.width) > aWinAttrRoot.width)  || aWinLeft < aWinAttrRoot.x
+     || ((aWinTop + aWinAttr.height) > aWinAttrRoot.height) || aWinTop  < aWinAttrRoot.y)
     {
       std::cerr << "The window not fully visible! Can't create the snapshot.\n";
       return Standard_False;
@@ -749,19 +1062,19 @@ Standard_Boolean Draw_Window::Save (const char* theFileName) const
 
   Image_AlienPixMap anImage;
   bool isBigEndian = Image_PixMap::IsBigEndianHost();
-  const Standard_Size aSizeRowBytes = Standard_Size(winAttr.width) * 4;
+  const Standard_Size aSizeRowBytes = Standard_Size(aWinAttr.width) * 4;
   if (!anImage.InitTrash (isBigEndian ? Image_Format_RGB32 : Image_Format_BGR32,
-                          Standard_Size(winAttr.width), Standard_Size(winAttr.height), aSizeRowBytes))
+                          Standard_Size(aWinAttr.width), Standard_Size(aWinAttr.height), aSizeRowBytes))
   {
     return Standard_False;
   }
   anImage.SetTopDown (true);
 
   XImage* anXImage = XCreateImage (Draw_WindowDisplay, aVInfo.visual,
-                                   32, ZPixmap, 0, (char* )anImage.ChangeData(), winAttr.width, winAttr.height, 32, int(aSizeRowBytes));
+                                   32, ZPixmap, 0, (char* )anImage.ChangeData(), aWinAttr.width, aWinAttr.height, 32, int(aSizeRowBytes));
   anXImage->bitmap_bit_order = anXImage->byte_order = (isBigEndian ? MSBFirst : LSBFirst);
   if (XGetSubImage (Draw_WindowDisplay, GetDrawable(),
-                    0, 0, winAttr.width, winAttr.height,
+                    0, 0, aWinAttr.width, aWinAttr.height,
                     AllPlanes, ZPixmap, anXImage, 0, 0) == NULL)
   {
     anXImage->data = NULL;
@@ -775,183 +1088,62 @@ Standard_Boolean Draw_Window::Save (const char* theFileName) const
 
   // save the image
   return anImage.Save (theFileName);
+#else
+  (void )theFileName;
+  return false;
+#endif
 }
 
+#endif // !__APPLE__
+
+#if defined(HAVE_XLIB)
 //=======================================================================
 //function : Wait
 //purpose  :
 //=======================================================================
-
-void Draw_Window::Wait (Standard_Boolean wait)
+void Draw_Window::Wait (Standard_Boolean theToWait)
 {
   Flush();
-  if (!wait) {
-    XSelectInput(Draw_WindowDisplay,win,
-                 ButtonPressMask|ExposureMask | StructureNotifyMask |
-                 PointerMotionMask);
-  }
-  else {
-    XSelectInput(Draw_WindowDisplay,win,
-                 ButtonPressMask|ExposureMask | StructureNotifyMask);
-  }
-}
-
-//=======================================================================
-//function : ProcessEvent
-//purpose  :
-//=======================================================================
-
-void ProcessEvent(Draw_Window& win, XEvent& xev)
-{
-  Standard_Integer X,Y,button;
-  KeySym keysym;
-  XComposeStatus stat;
-  char chainekey[10];
-
-  switch (xev.type)
-  {
-  case ClientMessage:
-  {
-    if (xev.xclient.data.l[0] == (int )Draw_DisplayConnection->GetAtom (Aspect_XA_DELETE_WINDOW))
-    {
-      // just hide the window
-      win.Hide();
-    }
-    return;
-  }
-  case Expose :
-    win.WExpose();
-    break;
-
-  case ButtonPress :
-    X = xev.xbutton.x;
-    Y = xev.xbutton.y;
-    button = xev.xbutton.button;
-    win.WButtonPress(X,Y,button);
-    break;
-
-  case ButtonRelease :
-    X = xev.xbutton.x;
-    Y = xev.xbutton.y;
-    button = xev.xbutton.button;
-    win.WButtonRelease(X,Y,button);
-    break;
-
-  case KeyPress :
-    XLookupString(&(xev.xkey),
-                         chainekey,
-                         10,
-                         &keysym,
-                         &stat);
-    break;
-
-  case MotionNotify :
-    X = xev.xmotion.x;
-    Y = xev.xmotion.y;
-    win.WMotionNotify(X,Y);
-    break;
-
-  case ConfigureNotify :
-    if (win.withWindowManager)
-      win.WConfigureNotify(xev.xconfigure.x, xev.xconfigure.y,
-                           xev.xconfigure.width,
-                           xev.xconfigure.height);
-    break;
-
-  case UnmapNotify :
-
-    win.WUnmapNotify();
-    break;
-  }
-}
-
-//=======================================================================
-//function : WExpose
-//purpose  :
-//=======================================================================
-void Draw_Window::WExpose()
-{
-}
-
-//=======================================================================
-//function : WButtonPress
-//purpose  :
-//=======================================================================
-void Draw_Window::WButtonPress(const Standard_Integer,
-                               const Standard_Integer,
-                               const Standard_Integer&)
-{
-}
-
-//=======================================================================
-//function : WButtonRelease
-//purpose  :
-//=======================================================================
-void Draw_Window::WButtonRelease(const Standard_Integer,
-                                 const Standard_Integer,
-                                 const Standard_Integer&)
-{
-}
-
-/**************************
-//=======================================================================
-//function : WKeyPress
-//purpose  :
-//=======================================================================
-
-void Draw_Window::WKeyPress(char, KeySym&)
-{
-}
-***************************/
-
-//=======================================================================
-//function : WMotionNotify
-//purpose  :
-//=======================================================================
-void Draw_Window::WMotionNotify(const Standard_Integer ,
-                                const Standard_Integer )
-{
-}
-
-//=======================================================================
-//function : WConfigureNotify
-//purpose  :
-//=======================================================================
-
-void Draw_Window::WConfigureNotify(const Standard_Integer,
-                                   const Standard_Integer,
-                                   const Standard_Integer,
-                                   const Standard_Integer)
-{
+  long aMask = ButtonPressMask | ExposureMask | StructureNotifyMask;
+  if (!theToWait) { aMask |= PointerMotionMask; }
+  XSelectInput (Draw_WindowDisplay, myWindow, aMask);
 }
 
-//=======================================================================
-//function : WUnmapNotify
-//purpose  :
-//=======================================================================
-void Draw_Window::WUnmapNotify()
-{
-}
-
-//======================================================
-// function : ProcessEvents
-// purpose  : process pending X events
-//======================================================
-static void ProcessEvents(ClientData,int)
+//! Process pending X events.
+static void processXEvents (ClientData , int )
 {
   // test for X Event
   while (XPending (Draw_WindowDisplay))
   {
-    XEvent anEvent = {};
+    XEvent anEvent;
     XNextEvent (Draw_WindowDisplay, &anEvent);
 
     // search the window in the window list
     bool isFound = false;
-    for (Draw_Window* aWinIter = Draw_Window::firstWindow; aWinIter != NULL; aWinIter = aWinIter->next)
+
+    for (NCollection_List<Draw_Window*>::Iterator aWinIter (getDrawWindowList());
+         aWinIter.More(); aWinIter.Next())
     {
-      if (anEvent.xany.window == aWinIter->win)
+      Draw_Window* aDrawWin = aWinIter.Value();
+      if (aDrawWin->IsEqualWindows (anEvent.xany.window))
       {
-        ProcessEvent (*aWinIter, anEvent);
+        switch (anEvent.type)
+        {
+          case ClientMessage:
+          {
+            if (anEvent.xclient.data.l[0] == (int )Draw_DisplayConnection->GetAtom (Aspect_XA_DELETE_WINDOW))
+            {
+              aDrawWin->Hide(); // just hide the window
+            }
+            break;
+          }
+          case Expose:
+          {
+            aDrawWin->WExpose();
+            break;
+          }
+        }
+
         isFound = true;
         break;
       }
@@ -969,31 +1161,35 @@ static void ProcessEvents(ClientData,int)
 // function : GetNextEvent()
 // purpose :
 //======================================================
-void GetNextEvent(Event& ev)
+void Draw_Window::GetNextEvent (Draw_Window::Draw_XEvent& theEvent)
 {
-  XEvent xev;
-  XNextEvent(Draw_WindowDisplay, &xev);
-  switch(xev.type)
-  {
-    case ButtonPress :
-      ev.type = 4;
-      ev.window = xev.xbutton.window;
-      ev.button = xev.xbutton.button;
-      ev.x = xev.xbutton.x;
-      ev.y = xev.xbutton.y;
+  XEvent anXEvent;
+  XNextEvent (Draw_WindowDisplay, &anXEvent);
+  switch (anXEvent.type)
+  {
+    case ButtonPress:
+    {
+      theEvent.type = 4;
+      theEvent.window = anXEvent.xbutton.window;
+      theEvent.button = anXEvent.xbutton.button;
+      theEvent.x = anXEvent.xbutton.x;
+      theEvent.y = anXEvent.xbutton.y;
       break;
-
-    case MotionNotify :
-      ev.type = 6;
-      ev.window = xev.xmotion.window;
-      ev.button = 0;
-      ev.x = xev.xmotion.x;
-      ev.y = xev.xmotion.y;
+    }
+    case MotionNotify:
+    {
+      theEvent.type = 6;
+      theEvent.window = anXEvent.xmotion.window;
+      theEvent.button = 0;
+      theEvent.x = anXEvent.xmotion.x;
+      theEvent.y = anXEvent.xmotion.y;
       break;
+    }
   }
 }
-#endif //__APPLE__
+#endif
 
+#ifndef _WIN32
 //======================================================
 // function :Run_Appli
 // purpose :
@@ -1014,8 +1210,8 @@ void Run_Appli(Standard_Boolean (*interprete) (const char*))
   }
 
   // Create a handler for the draw display
-#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
-  Tcl_CreateFileHandler (ConnectionNumber(Draw_WindowDisplay), TCL_READABLE, ProcessEvents, (ClientData) 0);
+#if defined(HAVE_XLIB)
+  Tcl_CreateFileHandler (ConnectionNumber(Draw_WindowDisplay), TCL_READABLE, processXEvents, (ClientData) 0);
 #endif // __APPLE__
 
   Draw_Interpretor& aCommands = Draw::GetInterpretor();
@@ -1028,7 +1224,7 @@ void Run_Appli(Standard_Boolean (*interprete) (const char*))
   {
     Tcl_Flush (anOutChannel);
   }
-  Tcl_DStringInit (&command);
+  Tcl_DStringInit (&Draw_TclCommand);
 
 #ifdef _TK
   if (Draw_VirtualWindows)
@@ -1047,7 +1243,7 @@ void Run_Appli(Standard_Boolean (*interprete) (const char*))
   }
 #endif
 
-  for (NCollection_List<Draw_Window::FCallbackBeforeTerminate>::Iterator anIter (MyCallbacks);
+  for (NCollection_List<Draw_Window::FCallbackBeforeTerminate>::Iterator anIter (TermCallbacks());
        anIter.More(); anIter.Next())
   {
     (*anIter.Value())();
@@ -1083,905 +1279,328 @@ Standard_Boolean Init_Appli()
 #if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 5)))
     fprintf(stderr, "%s\n", Tcl_GetStringResult(interp));
 #else
-    fprintf(stderr, "%s\n", interp->result);
-#endif
-    exit(1);
-  }
-#if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
-  Tk_SetAppName(aMainWindow, "Draw");
-#else
-  Tk_Name(aMainWindow) = Tk_GetUid(Tk_SetAppName(aMainWindow, "Draw"));
-#endif
-
-  Tk_GeometryRequest (aMainWindow, 200, 200);
-#endif
-
-#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
-  if (Draw_DisplayConnection.IsNull())
-  {
-    try
-    {
-      Draw_DisplayConnection = new Aspect_DisplayConnection();
-    }
-    catch (Standard_Failure const& theFail)
-    {
-      std::cout << "Cannot open display (" << theFail << "). Interpret commands in batch mode." << std::endl;
-      return Standard_False;
-    }
-  }
-  if (Draw_WindowDisplay == NULL)
-  {
-    Draw_WindowDisplay = Draw_DisplayConnection->GetDisplay();
-  }
-  //
-  // synchronize the display server : could be done within Tk_Init
-  //
-  XSynchronize(Draw_WindowDisplay, True);
-  XSetInputFocus(Draw_WindowDisplay,
-                 PointerRoot,
-                 RevertToPointerRoot,
-                 CurrentTime);
-
-  Draw_WindowScreen   = DefaultScreen(Draw_WindowDisplay);
-  Draw_WindowColorMap = DefaultColormap(Draw_WindowDisplay,
-                                        Draw_WindowScreen);
-#endif // __APPLE__
-
-  tty = isatty(0);
-  Tcl_SetVar(interp,"tcl_interactive",(char*)(tty ? "1" : "0"), TCL_GLOBAL_ONLY);
-//  Tcl_SetVar(interp,"tcl_interactive",tty ? "1" : "0", TCL_GLOBAL_ONLY);
-  return Standard_True;
-}
-
-//======================================================
-// function : Destroy_Appli()
-// purpose  :
-//======================================================
-void Destroy_Appli()
-{
-  //XCloseDisplay(Draw_WindowDisplay);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * StdinProc --
- *
- *        This procedure is invoked by the event dispatcher whenever
- *        standard input becomes readable.  It grabs the next line of
- *        input characters, adds them to a command being assembled, and
- *        executes the command if it's complete.
- *
- * Results:
- *        None.
- *
- * Side effects:
- *        Could be almost arbitrary, depending on the command that's
- *        typed.
- *
- *----------------------------------------------------------------------
- */
-
-    /* ARGSUSED */
-//static void StdinProc(ClientData clientData, int mask)
-static void StdinProc(ClientData clientData, int )
-{
-  static int gotPartial = 0;
-  char *cmd;
-//  int code, count;
-  int count;
-  Tcl_Channel chan = (Tcl_Channel) clientData;
-
-  // MSV Nov 2, 2001: patch for TCL 8.3: initialize line to avoid exception
-  //                  when first user input is an empty string
-  Tcl_DStringFree(&line);
-  count = Tcl_Gets(chan, &line);
-
-  // MKV 26.05.05
-#if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)))
-  Tcl_DString linetmp;
-  Tcl_DStringInit(&linetmp);
-  Tcl_UniChar * UniCharString;
-  UniCharString = Tcl_UtfToUniCharDString(Tcl_DStringValue(&line),-1,&linetmp);
-  Standard_Integer l = Tcl_UniCharLen(UniCharString);
-  TCollection_AsciiString AsciiString("");
-  Standard_Character Character;
-  Standard_Integer i;
-  for (i=0; i<l; i++) {
-    Character = UniCharString[i];
-    AsciiString.AssignCat(Character);
-  }
-  Tcl_DStringInit(&line);
-  Tcl_DStringAppend(&line, AsciiString.ToCString(), -1);
-#endif
-  if (count < 0) {
-    if (!gotPartial) {
-      if (tty) {
-        Tcl_Exit(0);
-      } else {
-        Tcl_DeleteChannelHandler(chan, StdinProc, (ClientData) chan);
-      }
-      return;
-    } else {
-      count = 0;
-    }
-  }
-
-  (void) Tcl_DStringAppend(&command, Tcl_DStringValue(&line), -1);
-  cmd = Tcl_DStringAppend(&command, "\n", -1);
-  Tcl_DStringFree(&line);
-  try {
-    OCC_CATCH_SIGNALS
-  if (!Tcl_CommandComplete(cmd)) {
-    gotPartial = 1;
-    goto prompt;
-  }
-  gotPartial = 0;
-
-  /*
-   * Disable the stdin channel handler while evaluating the command;
-   * otherwise if the command re-enters the event loop we might
-   * process commands from stdin before the current command is
-   * finished.  Among other things, this will trash the text of the
-   * command being evaluated.
-   */
-
-  Tcl_CreateChannelHandler(chan, 0, StdinProc, (ClientData) chan);
-
-
-  /*
-   * Disable the stdin file handler while evaluating the command;
-   * otherwise if the command re-enters the event loop we might
-   * process commands from stdin before the current command is
-   * finished.  Among other things, this will trash the text of the
-   * command being evaluated.
-   */
-
-#ifdef _TK
-   //  Tk_CreateFileHandler(0, 0, StdinProc, (ClientData) 0);
-#endif
-    //
-    // xab average to avoid an output SIGBUS of DRAW
-    // to ultimately prescise or remove once
-    // the problem of free on the global variable at the average
-    //
-    //
-
-  Interprete(cmd);
-
-
-  Tcl_CreateChannelHandler(chan, TCL_READABLE, StdinProc,
-                           (ClientData) chan);
-  Tcl_DStringFree(&command);
-
-  /*
-   * Output a prompt.
-   */
-
-prompt:
-  if (tty) Prompt(Draw::GetInterpretor().Interp(), gotPartial);
-
- } catch (Standard_Failure const&) {}
-
-}
-
-#else
-
-// Source Specifique WNT
-
-/****************************************************\
-*  Draw_Window.cxx :
-*
-\****************************************************/
-
-#include "Draw_Window.hxx"
-#include "DrawRessource.h"
-#include "init.h"
-
-#include <Draw_Appli.hxx>
-#include <OSD.hxx>
-
-#ifdef HAVE_TK
-  #include <tk.h>
-#endif
-
-#define PENWIDTH 1
-#define CLIENTWND 0
-// Position of information in the extra memory
-
-// indicates SUBSYSTEM:CONSOLE linker option, to be set to True in main()
-Standard_EXPORT
-Standard_Boolean Draw_IsConsoleSubsystem = Standard_False;
-
-
-Standard_Boolean Draw_BlackBackGround = Standard_True;
-
-// Creation of color stylos
-HPEN colorPenTab[MAXCOLOR] = {CreatePen(PS_SOLID, PENWIDTH, RGB(255,255,255)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(255,0,0)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(0,255,0)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(0,0,255)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(0,255,255)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(255,215,0)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(255,0,255)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(255,52,179)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(255,165,0)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(255,228,225)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(255,160,122)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(199,21,133)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(255,255,0)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(240,230,140)),
-                              CreatePen(PS_SOLID, PENWIDTH, RGB(255,127,80))};
-
-// Correspondence mode X11 and WINDOWS NT
-int modeTab[16] = {R2_BLACK, R2_MASKPEN, R2_MASKPENNOT, R2_COPYPEN,
-                   R2_MASKNOTPEN, R2_NOP, R2_XORPEN, R2_MERGEPEN,
-                   R2_NOTMASKPEN, R2_NOTXORPEN, R2_NOT, R2_MERGEPENNOT,
-                   R2_NOTCOPYPEN, R2_MERGENOTPEN, R2_NOTMERGEPEN, R2_WHITE};
-
-/*--------------------------------------------------------*\
-|  CREATE DRAW WINDOW PROCEDURE
-\*--------------------------------------------------------*/
-HWND DrawWindow::CreateDrawWindow(HWND hWndClient, int nitem)
-{
-  if (Draw_IsConsoleSubsystem) {
-    HWND aWin = CreateWindowW (DRAWCLASS, DRAWTITLE,
-                              WS_OVERLAPPEDWINDOW,
-                              1,1,1,1,
-                              NULL, NULL,::GetModuleHandle(NULL), NULL);
-    if (!Draw_VirtualWindows)
-    {
-      SetWindowPos(aWin, HWND_TOPMOST, 1,1,1,1, SWP_NOMOVE);
-      SetWindowPos(aWin, HWND_NOTOPMOST, 1,1,1,1, SWP_NOMOVE);
-    }
-    return aWin;
-  }
-  else {
-    HANDLE hInstance = (HANDLE )GetWindowLongPtrW (hWndClient, GWLP_HINSTANCE);
-
-    return CreateMDIWindowW(DRAWCLASS, DRAWTITLE,
-                           WS_CAPTION | WS_CHILD | WS_THICKFRAME,
-                           1,1,0,0,
-                           hWndClient, (HINSTANCE)hInstance, nitem);
-  }
-}
-
-
-/*--------------------------------------------------------*\
-|  DRAW WINDOW PROCEDURE
-\*--------------------------------------------------------*/
-LRESULT APIENTRY DrawWindow::DrawProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam )
-{
-  DrawWindow* localObjet = (DrawWindow* )GetWindowLongPtrW (hWnd, CLIENTWND);
-  if (!localObjet)
-  {
-    return Draw_IsConsoleSubsystem
-         ? DefWindowProcW   (hWnd, wMsg, wParam, lParam)
-         : DefMDIChildProcW (hWnd, wMsg, wParam, lParam);
-  }
-
-  switch (wMsg)
-  {
-    case WM_CLOSE:
-    {
-      localObjet->Hide();
-      return 0; // do nothing - window destruction should be performed by application
-    }
-    case WM_PAINT:
-    {
-      PAINTSTRUCT ps;
-      BeginPaint (hWnd, &ps);
-      if (localObjet->GetUseBuffer())
-      {
-        localObjet->Redraw();
-      }
-      else
-      {
-        localObjet->WExpose();
-      }
-      EndPaint (hWnd, &ps);
-      return 0;
-    }
-    case WM_SIZE:
-    {
-      if (localObjet->GetUseBuffer())
-      {
-        localObjet->InitBuffer();
-        localObjet->WExpose();
-        localObjet->Redraw();
-        return 0;
-      }
-      break;
-    }
-  }
-  return Draw_IsConsoleSubsystem
-       ? DefWindowProcW   (hWnd, wMsg, wParam, lParam)
-       : DefMDIChildProcW (hWnd, wMsg, wParam, lParam);
-}
-
-
-
-/*
-**  IMPLEMENTATION of the CLASS DRAWWINDOW
- */
-
-/*--------------------------------------------------------*\
-| Initialization of static variables of DrawWindow
-\*--------------------------------------------------------*/
-
-DrawWindow* DrawWindow::firstWindow = NULL;
-HWND DrawWindow::hWndClientMDI = 0;
-
-/*--------------------------------------------------------*\
-| Constructors of Draw_Window
-\*--------------------------------------------------------*/
-
-// Default Constructor
-//________________________
-DrawWindow::DrawWindow() :
-        win(0),
-        next(firstWindow),
-        previous(NULL),
-        myMemHbm(NULL),
-        myUseBuffer(Standard_False),
-        myCurrPen(0),
-        myCurrMode(0)
-{
-  if (firstWindow) firstWindow->previous = this;
-  firstWindow = this;
-}
-
-//________________________
-DrawWindow::DrawWindow(const char* title,
-                       Standard_Integer X, Standard_Integer Y,
-                       Standard_Integer dX,Standard_Integer dY) :
-       win(0),        next(firstWindow), previous(NULL), myMemHbm(NULL), myUseBuffer(Standard_False)
-{
-  if (firstWindow) firstWindow->previous = this;
-  firstWindow = this;
-  Init(X, Y, dX, dY);
-  SetTitle(title);
-}
-DrawWindow::DrawWindow(const char* title,
-                       Standard_Integer X, Standard_Integer Y,
-                       Standard_Integer dX,Standard_Integer dY,
-                       HWND theWin) :
-       win(theWin),next(firstWindow), previous(NULL), myMemHbm(NULL), myUseBuffer(Standard_False)
-{
-  if (firstWindow) firstWindow->previous = this;
-  firstWindow = this;
-  Init(X, Y, dX, dY);
-  SetTitle(title);
-}
-
-
-
-/*--------------------------------------------------------*\
-| Destructor of DrawWindow
-\*--------------------------------------------------------*/
-DrawWindow::~DrawWindow()
-{
-  if (previous)
-    previous->next = next;
-  else
-    firstWindow = next;
-  if (next)
-    next->previous = previous;
-
-  // Delete 'off-screen drawing'-related objects
-  if (myMemHbm) {
-    DeleteObject(myMemHbm);
-    myMemHbm = NULL;
-  }
-}
-
-
-
-/*--------------------------------------------------------*\
-|  Init
-\*--------------------------------------------------------*/
-void DrawWindow::Init(Standard_Integer theXLeft, Standard_Integer theYTop,
-                      Standard_Integer theWidth, Standard_Integer theHeight)
-{
-  if (win == NULL)
-  {
-    win = CreateDrawWindow(hWndClientMDI, 0);
-  }
-
-  // include decorations in the window dimensions
-  // to reproduce same behaviour of Xlib window.
-  DWORD aWinStyle   = GetWindowLongW (win, GWL_STYLE);
-  DWORD aWinStyleEx = GetWindowLongW (win, GWL_EXSTYLE);
-  HMENU aMenu       = GetMenu (win);
-
-  RECT aRect;
-  aRect.top    = theYTop;
-  aRect.bottom = theYTop + theHeight;
-  aRect.left   = theXLeft;
-  aRect.right  = theXLeft + theWidth;
-  AdjustWindowRectEx (&aRect, aWinStyle, aMenu != NULL ? TRUE : FALSE, aWinStyleEx);
-
-  SetPosition  (aRect.left, aRect.top);
-  SetDimension (aRect.right - aRect.left, aRect.bottom - aRect.top);
-  // Save the pointer at the instance associated to the window
-  SetWindowLongPtrW (win, CLIENTWND, (LONG_PTR)this);
-  HDC hDC = GetDC(win);
-  SetBkColor(hDC, RGB(0, 0, 0));
-  myCurrPen  = 3;
-  myCurrMode = 3;
-  SelectObject(hDC, colorPenTab[myCurrPen]); // Default pencil
-  SelectObject(hDC, GetStockObject(BLACK_BRUSH));
-  SetTextColor(hDC, RGB(0,0,255));
-  ReleaseDC(win, hDC);
-
-  if (Draw_VirtualWindows)
-  {
-    // create a virtual window
-    SetUseBuffer (Standard_True);
-  }
-}
-
-/*--------------------------------------------------------*\
-|  SetUseBuffer
-\*--------------------------------------------------------*/
-void DrawWindow::SetUseBuffer(Standard_Boolean use)
-{
-  myUseBuffer = use;
-  InitBuffer();
-}
-
-/*--------------------------------------------------------*\
-|  InitBuffer
-\*--------------------------------------------------------*/
-void DrawWindow::InitBuffer()
-{
-  if (myUseBuffer) {
-    RECT rc;
-    HDC hDC = GetDC(win);
-    GetClientRect(win, &rc);
-    if (myMemHbm) {
-      BITMAP aBmp;
-      GetObjectW (myMemHbm, sizeof(BITMAP), &aBmp);
-      if (rc.right-rc.left == aBmp.bmWidth && rc.bottom-rc.top == aBmp.bmHeight) return;
-      DeleteObject(myMemHbm);
-    }
-    myMemHbm = (HBITMAP)CreateCompatibleBitmap(hDC,
-                                      rc.right-rc.left,
-                                      rc.bottom-rc.top);
-    HDC aMemDC      = GetMemDC(hDC);
-    FillRect(aMemDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
-    ReleaseMemDC(aMemDC);
-    ReleaseDC(win, hDC);
-  }
-  else {
-    if (myMemHbm) {
-      DeleteObject(myMemHbm);
-      myMemHbm = NULL;
-    }
-  }
-}
-
-/*--------------------------------------------------------*\
-|  GetMemDC
-\*--------------------------------------------------------*/
-HDC DrawWindow::GetMemDC(HDC theWinDC)
-{
-  if (!myUseBuffer) return NULL;
-
-  HDC aWorkDC = CreateCompatibleDC(theWinDC);
-  myOldHbm = (HBITMAP)SelectObject(aWorkDC, myMemHbm);
-  SetROP2(aWorkDC, modeTab[myCurrMode]);
-  SelectObject(aWorkDC, colorPenTab[myCurrPen]);
-  SetBkColor(aWorkDC, RGB(0, 0, 0));
-  SelectObject(aWorkDC, GetStockObject(BLACK_BRUSH));
-  SetTextColor(aWorkDC, RGB(0,0,255));
-  return aWorkDC;
-}
-
-
-/*--------------------------------------------------------*\
-|  ReleaseMemDC
-\*--------------------------------------------------------*/
-void DrawWindow::ReleaseMemDC(HDC theMemDC)
-{
-  if (!myUseBuffer || !theMemDC) return;
-
-  if (myOldHbm) SelectObject(theMemDC, myOldHbm);
-  DeleteDC(theMemDC);
-}
-
-
-/*--------------------------------------------------------*\
-|  SetPosition
-\*--------------------------------------------------------*/
-void DrawWindow::SetPosition(Standard_Integer posX, Standard_Integer posY)
-{
-  UINT aFlags = SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER;
-  if (Draw_VirtualWindows)
-  {
-    aFlags |= SWP_NOSENDCHANGING;
-  }
-  SetWindowPos (win, 0, posX, posY, 0, 0, aFlags);
-}
-
-
-/*--------------------------------------------------------*\
-|  SetDimension
-\*--------------------------------------------------------*/
-void DrawWindow::SetDimension(Standard_Integer dimX, Standard_Integer dimY)
-{
-  UINT aFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER;
-  if (Draw_VirtualWindows)
-  {
-    aFlags |= SWP_NOSENDCHANGING;
-  }
-  SetWindowPos (win, 0, 0, 0, dimX, dimY, aFlags);
-}
-
-
-/*--------------------------------------------------------*\
-|  GetPosition
-\*--------------------------------------------------------*/
-void DrawWindow::GetPosition(Standard_Integer &dimX,
-                             Standard_Integer &dimY)
-{
-  RECT rect;
-  GetWindowRect(win, &rect);
-
-  POINT point;
-  point.x = rect.left;
-  point.y = rect.top;
-
-  ScreenToClient(hWndClientMDI, &point);
-  dimX = point.x;
-  dimY = point.y;
-}
-
-
-/*--------------------------------------------------------*\
-|  HeightWin
-\*--------------------------------------------------------*/
-Standard_Integer DrawWindow::HeightWin() const
-{
-  RECT rect;
-  GetClientRect(win, &rect);
-  return(rect.bottom-rect.top);
-}
-
-
-/*--------------------------------------------------------*\
-|  WidthWin
-\*--------------------------------------------------------*/
-Standard_Integer DrawWindow::WidthWin() const
-{
-  RECT rect;
-  GetClientRect(win, &rect);
-  return(rect.right-rect.left);
-}
-
-
-/*--------------------------------------------------------*\
-|  SetTitle
-\*--------------------------------------------------------*/
-void DrawWindow::SetTitle (const TCollection_AsciiString& theTitle)
-{
-  const TCollection_ExtendedString aTitleW (theTitle);
-  SetWindowTextW (win, aTitleW.ToWideString());
-}
-
-
-/*--------------------------------------------------------*\
-|  GetTitle
-\*--------------------------------------------------------*/
-TCollection_AsciiString DrawWindow::GetTitle() const
-{
-  wchar_t aTitleW[32];
-  GetWindowTextW (win, aTitleW, 30);
-  return TCollection_AsciiString (aTitleW);
-}
-
-//=======================================================================
-//function : IsMapped
-//purpose  :
-//=======================================================================
-bool Draw_Window::IsMapped() const
-{
-  if (Draw_VirtualWindows
-   || win == NULL)
-  {
-    return false;
-  }
-
-  LONG aWinStyle = GetWindowLongW (win, GWL_STYLE);
-  return (aWinStyle & WS_VISIBLE)  != 0
-      && (aWinStyle & WS_MINIMIZE) == 0;
-}
-
-/*--------------------------------------------------------*\
-|  DisplayWindow
-\*--------------------------------------------------------*/
-void DrawWindow::DisplayWindow()
-{
-  if (Draw_VirtualWindows)
-  {
-    return;
-  }
-  ShowWindow (win, SW_SHOW);
-  UpdateWindow (win);
-}
-
-
-/*--------------------------------------------------------*\
-|  Hide
-\*--------------------------------------------------------*/
-void DrawWindow::Hide()
-{
-  ShowWindow(win, SW_HIDE);
-}
-
-
-/*--------------------------------------------------------*\
-|  Destroy
-\*--------------------------------------------------------*/
-void DrawWindow::Destroy()
-{
-  DestroyWindow(win);
-}
-
-
-
-/*--------------------------------------------------------*\
-|  Clear
-\*--------------------------------------------------------*/
-void DrawWindow::Clear()
-{
-  HDC hDC = GetDC(win);
-  HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
-
-  SaveDC(aWorkDC);
-  SelectObject(aWorkDC,GetStockObject(BLACK_PEN));
-  Rectangle(aWorkDC, 0, 0, WidthWin(), HeightWin());
-  RestoreDC(aWorkDC,-1);
-
-  if (myUseBuffer) ReleaseMemDC(aWorkDC);
-  ReleaseDC(win,hDC);
-}
-
-/*--------------------------------------------------------*\
-|  SaveBitmap
-\*--------------------------------------------------------*/
-static Standard_Boolean SaveBitmap (HBITMAP     theHBitmap,
-                                    const char* theFileName)
-{
-  // Get information about the bitmap
-  BITMAP aBitmap;
-  if (GetObjectW (theHBitmap, sizeof(BITMAP), &aBitmap) == 0)
-  {
-    return Standard_False;
-  }
-
-  Image_AlienPixMap anImage;
-  const Standard_Size aSizeRowBytes = ((Standard_Size(aBitmap.bmWidth) * 24 + 31) / 32) * 4; // 4 bytes alignment for GetDIBits()
-  if (!anImage.InitTrash (Image_Format_BGR, Standard_Size(aBitmap.bmWidth), Standard_Size(aBitmap.bmHeight), aSizeRowBytes))
-  {
-    return Standard_False;
-  }
-  anImage.SetTopDown (false);
-
-  // Setup image data
-  BITMAPINFOHEADER aBitmapInfo;
-  memset (&aBitmapInfo, 0, sizeof(BITMAPINFOHEADER));
-  aBitmapInfo.biSize        = sizeof(BITMAPINFOHEADER);
-  aBitmapInfo.biWidth       = aBitmap.bmWidth;
-  aBitmapInfo.biHeight      = aBitmap.bmHeight; // positive means bottom-up!
-  aBitmapInfo.biPlanes      = 1;
-  aBitmapInfo.biBitCount    = 24;
-  aBitmapInfo.biCompression = BI_RGB;
-
-  // Copy the pixels
-  HDC aDC = GetDC (NULL);
-  Standard_Boolean isSuccess = GetDIBits (aDC, theHBitmap,
-                                          0,                           // first scan line to set
-                                          aBitmap.bmHeight,            // number of scan lines to copy
-                                          anImage.ChangeData(),        // array for bitmap bits
-                                          (LPBITMAPINFO )&aBitmapInfo, // bitmap data info
-                                          DIB_RGB_COLORS) != 0;
-  ReleaseDC (NULL, aDC);
-  return isSuccess && anImage.Save (theFileName);
-}
-
-/*--------------------------------------------------------*\
-|  Save
-\*--------------------------------------------------------*/
-Standard_Boolean DrawWindow::Save (const char* theFileName) const
-{
-  if (myUseBuffer)
-  {
-    return SaveBitmap (myMemHbm, theFileName);
-  }
-
-  RECT aRect;
-  GetClientRect (win, &aRect);
-  int aWidth  = aRect.right  - aRect.left;
-  int aHeight = aRect.bottom - aRect.top;
-
-  // Prepare the DCs
-  HDC aDstDC = GetDC (NULL);
-  HDC aSrcDC = GetDC (win); // we copy only client area
-  HDC aMemDC = CreateCompatibleDC (aDstDC);
+    fprintf(stderr, "%s\n", interp->result);
+#endif
+    exit(1);
+  }
+#if defined(__APPLE__) && !defined(HAVE_XLIB)
+  Tk_SetAppName(aMainWindow, "Draw");
+#else
+  Tk_Name(aMainWindow) = Tk_GetUid(Tk_SetAppName(aMainWindow, "Draw"));
+#endif
 
-  // Copy the screen to the bitmap
-  HBITMAP anHBitmapDump = CreateCompatibleBitmap (aDstDC, aWidth, aHeight);
-  HBITMAP anHBitmapOld = (HBITMAP )SelectObject (aMemDC, anHBitmapDump);
-  BitBlt (aMemDC, 0, 0, aWidth, aHeight, aSrcDC, 0, 0, SRCCOPY);
+  Tk_GeometryRequest (aMainWindow, 200, 200);
+#endif
 
-  Standard_Boolean isSuccess = SaveBitmap (anHBitmapDump, theFileName);
+#if defined(HAVE_XLIB)
+  if (Draw_DisplayConnection.IsNull())
+  {
+    try
+    {
+      Draw_DisplayConnection = new Aspect_DisplayConnection();
+    }
+    catch (Standard_Failure const& theFail)
+    {
+      std::cout << "Cannot open display (" << theFail << "). Interpret commands in batch mode." << std::endl;
+      return Standard_False;
+    }
+  }
+  if (Draw_WindowDisplay == NULL)
+  {
+    Draw_WindowDisplay = (Display* )Draw_DisplayConnection->GetDisplayAspect();
+  }
+  //
+  // synchronize the display server : could be done within Tk_Init
+  //
+  XSynchronize (Draw_WindowDisplay, True);
+  XSetInputFocus (Draw_WindowDisplay,
+                  PointerRoot,
+                  RevertToPointerRoot,
+                  CurrentTime);
 
-  // Free objects
-  DeleteObject (SelectObject (aMemDC, anHBitmapOld));
-  DeleteDC (aMemDC);
+  Draw_WindowScreen   = DefaultScreen(Draw_WindowDisplay);
+  Draw_WindowColorMap = DefaultColormap(Draw_WindowDisplay,
+                                        Draw_WindowScreen);
+#endif // __APPLE__
 
-  return isSuccess;
+  tty = isatty(0);
+  Tcl_SetVar(interp,"tcl_interactive",(char*)(tty ? "1" : "0"), TCL_GLOBAL_ONLY);
+//  Tcl_SetVar(interp,"tcl_interactive",tty ? "1" : "0", TCL_GLOBAL_ONLY);
+  return Standard_True;
 }
 
-/*--------------------------------------------------------*\
-|  DrawString
-\*--------------------------------------------------------*/
-void DrawWindow::DrawString(int x,int y, char* text)
+//======================================================
+// function : Destroy_Appli()
+// purpose  :
+//======================================================
+void Destroy_Appli()
 {
-  HDC hDC = GetDC(win);
-  HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
-
-  TCollection_ExtendedString textW (text);
-  TextOutW(aWorkDC, x, y, (const wchar_t*)textW.ToExtString(), (int )strlen(text));
-
-  if (myUseBuffer) ReleaseMemDC(aWorkDC);
-  ReleaseDC(win,hDC);
+  //XCloseDisplay(Draw_WindowDisplay);
 }
 
-/*--------------------------------------------------------*\
-|  DrawSegments
-\*--------------------------------------------------------*/
-void DrawWindow::DrawSegments(Segment *tab, int nbElem)
+//! This procedure is invoked by the event dispatcher whenever standard input becomes readable.
+//! It grabs the next line of input characters, adds them to a command being assembled,
+//! and executes the command if it's complete.
+//! Side effects: Could be almost arbitrary, depending on the command that's typed.
+static void StdinProc (ClientData clientData, int theMask)
 {
-  HDC hDC = GetDC(win);
-  HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
+  (void )theMask;
+  static int gotPartial = 0;
+//  int code, count;
+  Tcl_Channel chan = (Tcl_Channel) clientData;
 
-  for(int i = 0 ; i < nbElem ; i++)
+  // MSV Nov 2, 2001: patch for TCL 8.3: initialize line to avoid exception
+  //                  when first user input is an empty string
+  Tcl_DStringFree (&Draw_TclLine);
+  int count = Tcl_Gets(chan, &Draw_TclLine);
+
+  // MKV 26.05.05
+#if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)))
+  Tcl_DString aLineTmp;
+  Tcl_DStringInit (&aLineTmp);
+  Tcl_UniChar* aUniCharString = Tcl_UtfToUniCharDString (Tcl_DStringValue (&Draw_TclLine), -1, &aLineTmp);
+  Standard_Integer l = Tcl_UniCharLen (aUniCharString);
+  TCollection_AsciiString anAsciiString;
+  for (Standard_Integer i = 0; i < l; ++i)
   {
-    MoveToEx(aWorkDC, tab[i].x1, tab[i].y1, NULL);
-    LineTo(aWorkDC, tab[i].x2, tab[i].y2);
+    Standard_Character aCharacter = aUniCharString[i];
+    anAsciiString.AssignCat (aCharacter);
   }
-
-  if (myUseBuffer) ReleaseMemDC(aWorkDC);
-  ReleaseDC(win,hDC);
-}
-
-/*--------------------------------------------------------*\
-|  Redraw
-\*--------------------------------------------------------*/
-void DrawWindow::Redraw()
-{
-  if (myUseBuffer) {
-    HDC hDC = GetDC(win);
-    RECT rc;
-    GetClientRect(win, &rc);
-    HDC aMemDC = GetMemDC(hDC);
-    BitBlt(hDC,
-           rc.left, rc.top,
-           rc.right-rc.left, rc.bottom-rc.top,
-           aMemDC,
-           0, 0, SRCCOPY);
-    ReleaseMemDC(aMemDC);
-    ReleaseDC(win,hDC);
+  Tcl_DStringInit (&Draw_TclLine);
+  Tcl_DStringAppend (&Draw_TclLine, anAsciiString.ToCString(), -1);
+#endif
+  if (count < 0)
+  {
+    if (!gotPartial)
+    {
+      if (tty)
+      {
+        Tcl_Exit(0);
+      }
+      else
+      {
+        Tcl_DeleteChannelHandler(chan, StdinProc, (ClientData) chan);
+      }
+      return;
+    }
+    else
+    {
+      count = 0;
+    }
   }
-}
 
-/*--------------------------------------------------------*\
-|  SetMode
-\*--------------------------------------------------------*/
-void DrawWindow::SetMode(int mode)
-{
-  HDC hDC = GetDC(win);
-  myCurrMode = mode;
-  SetROP2(hDC, modeTab[mode]);
-  ReleaseDC(win,hDC);
-}
+  (void) Tcl_DStringAppend (&Draw_TclCommand, Tcl_DStringValue (&Draw_TclLine), -1);
+  char* cmd = Tcl_DStringAppend (&Draw_TclCommand, "\n", -1);
+  Tcl_DStringFree (&Draw_TclLine);
+  try
+  {
+    OCC_CATCH_SIGNALS
+    if (!Tcl_CommandComplete (cmd))
+    {
+      gotPartial = 1;
+      goto prompt;
+    }
+    gotPartial = 0;
 
+    /*
+     * Disable the stdin channel handler while evaluating the command;
+     * otherwise if the command re-enters the event loop we might
+     * process commands from stdin before the current command is finished.
+     * Among other things, this will trash the text of the command being evaluated.
+     */
+    Tcl_CreateChannelHandler(chan, 0, StdinProc, (ClientData) chan);
 
-/*--------------------------------------------------------*\
-|  SetColor
-\*--------------------------------------------------------*/
-void DrawWindow::SetColor(Standard_Integer color)
-{
-  HDC hDC = GetDC(win);
-  myCurrPen = color;
-  SelectObject(hDC,colorPenTab[color]);
-  ReleaseDC(win,hDC);
-}
+    /*
+     * Disable the stdin file handler while evaluating the command;
+     * otherwise if the command re-enters the event loop we might
+     * process commands from stdin before the current command is finished.
+     * Among other things, this will trash the text of the command being evaluated.
+     */
 
+#ifdef _TK
+    // Tk_CreateFileHandler (0, 0, StdinProc, (ClientData) 0);
+#endif
+    // xab average to avoid an output SIGBUS of DRAW
+    // to ultimately precise or remove once
+    // the problem of free on the global variable at the average
+    //
+    Interprete (cmd);
 
-/*--------------------------------------------------------*\
-|  WExpose
-\*--------------------------------------------------------*/
-void DrawWindow::WExpose()
-{
-}
+    Tcl_CreateChannelHandler (chan, TCL_READABLE, StdinProc, (ClientData) chan);
+    Tcl_DStringFree (&Draw_TclCommand);
 
+  /*
+   * Output a prompt.
+   */
+prompt:
+    if (tty)
+    {
+      Prompt (Draw::GetInterpretor().Interp(), gotPartial);
+    }
 
-/*--------------------------------------------------------*\
-|  WButtonPress
-\*--------------------------------------------------------*/
-void DrawWindow::WButtonPress(const Standard_Integer,
-                               const Standard_Integer,
-                               const Standard_Integer&)
-{
+  } catch (Standard_Failure const&) {}
 }
 
+#else
+
+// Source Specifique WNT
 
 /*--------------------------------------------------------*\
-|  WButtonRelease
+|  CREATE DRAW WINDOW PROCEDURE
 \*--------------------------------------------------------*/
-void DrawWindow::WButtonRelease(const Standard_Integer,
-                                 const Standard_Integer,
-                                 const Standard_Integer&)
+HWND Draw_Window::createDrawWindow (HWND hWndClient, int nitem)
 {
+  if (Draw_IsConsoleSubsystem)
+  {
+    HWND aWin = CreateWindowW (DRAWCLASS, DRAWTITLE,
+                               WS_OVERLAPPEDWINDOW,
+                               1,1,1,1,
+                               NULL, NULL,::GetModuleHandle(NULL), NULL);
+    if (!Draw_VirtualWindows)
+    {
+      SetWindowPos (aWin, HWND_TOPMOST,   1,1,1,1, SWP_NOMOVE);
+      SetWindowPos (aWin, HWND_NOTOPMOST, 1,1,1,1, SWP_NOMOVE);
+    }
+    return aWin;
+  }
+  else
+  {
+    HANDLE hInstance = (HANDLE )GetWindowLongPtrW (hWndClient, GWLP_HINSTANCE);
+    return CreateMDIWindowW (DRAWCLASS, DRAWTITLE,
+                             WS_CAPTION | WS_CHILD | WS_THICKFRAME,
+                             1,1,0,0,
+                             hWndClient, (HINSTANCE)hInstance, nitem);
+  }
 }
 
-
 /*--------------------------------------------------------*\
-|  WMotionNotify
+|  DRAW WINDOW PROCEDURE
 \*--------------------------------------------------------*/
-void Draw_Window::WMotionNotify(const Standard_Integer ,
-                                const Standard_Integer )
+LRESULT APIENTRY Draw_Window::DrawProc (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {
-}
+  Draw_Window* aLocWin = (Draw_Window* )GetWindowLongPtrW (hWnd, CLIENTWND);
+  if (aLocWin == NULL)
+  {
+    return Draw_IsConsoleSubsystem
+         ? DefWindowProcW   (hWnd, wMsg, wParam, lParam)
+         : DefMDIChildProcW (hWnd, wMsg, wParam, lParam);
+  }
 
+  switch (wMsg)
+  {
+    case WM_CLOSE:
+    {
+      aLocWin->Hide();
+      return 0; // do nothing - window destruction should be performed by application
+    }
+    case WM_PAINT:
+    {
+      PAINTSTRUCT ps;
+      BeginPaint (hWnd, &ps);
+      if (aLocWin->GetUseBuffer())
+      {
+        aLocWin->Redraw();
+      }
+      else
+      {
+        aLocWin->WExpose();
+      }
+      EndPaint (hWnd, &ps);
+      return 0;
+    }
+    case WM_SIZE:
+    {
+      if (aLocWin->GetUseBuffer())
+      {
+        aLocWin->InitBuffer();
+        aLocWin->WExpose();
+        aLocWin->Redraw();
+        return 0;
+      }
+      break;
+    }
+  }
+  return Draw_IsConsoleSubsystem
+       ? DefWindowProcW   (hWnd, wMsg, wParam, lParam)
+       : DefMDIChildProcW (hWnd, wMsg, wParam, lParam);
+}
 
 /*--------------------------------------------------------*\
-|  WConfigureNotify
+|  SelectWait
 \*--------------------------------------------------------*/
-void DrawWindow::WConfigureNotify(const Standard_Integer,
-                                   const Standard_Integer,
-                                   const Standard_Integer,
-                                   const Standard_Integer)
-{
-}
+void Draw_Window::SelectWait (HANDLE& theWindow,
+                              int& theX, int& theY,
+                              int& theButton)
+{
+  MSG aMsg;
+  aMsg.wParam = 1;
+  GetMessageW (&aMsg, NULL, 0, 0);
+  while ((aMsg.message != WM_RBUTTONDOWN
+       && aMsg.message != WM_LBUTTONDOWN)
+       || !(Draw_IsConsoleSubsystem || IsChild(Draw_Window::hWndClientMDI, aMsg.hwnd)))
+  {
+    GetMessageW (&aMsg, NULL, 0, 0);
+  }
 
+  theWindow = aMsg.hwnd;
+  theX = LOWORD(aMsg.lParam);
+  theY = HIWORD(aMsg.lParam);
+  if (aMsg.message == WM_LBUTTONDOWN)
+  {
+    theButton = 1;
+  }
+  else
+  {
+    theButton = 3;
+  }
+}
 
 /*--------------------------------------------------------*\
-|  WUnmapNotify
+|  SelectNoWait
 \*--------------------------------------------------------*/
-void DrawWindow::WUnmapNotify()
-{
-}
-
-
+void Draw_Window::SelectNoWait (HANDLE& theWindow,
+                                int& theX, int& theY,
+                                int& theButton)
+{
+  MSG aMsg;
+  aMsg.wParam = 1;
+  GetMessageW (&aMsg, NULL, 0, 0);
+  while ((aMsg.message != WM_RBUTTONDOWN
+       && aMsg.message != WM_LBUTTONDOWN
+       && aMsg.message != WM_MOUSEMOVE)
+       || !(Draw_IsConsoleSubsystem || IsChild(Draw_Window::hWndClientMDI, aMsg.hwnd)))
+  {
+    GetMessageW (&aMsg, NULL, 0, 0);
+  }
 
-/*
-**  IMPLEMENTATION of the CLASS SEGMENT
- */
+  theWindow = aMsg.hwnd;
+  theX = LOWORD(aMsg.lParam);
+  theY = HIWORD(aMsg.lParam);
+  switch (aMsg.message)
+  {
+    case WM_LBUTTONDOWN:
+      theButton = 1;
+      break;
+    case WM_RBUTTONDOWN:
+      theButton = 3;
+      break;
+    case WM_MOUSEMOVE:
+      theButton = 0;
+      break;
+  }
+}
 
 /*--------------------------------------------------------*\
 |  Init
 \*--------------------------------------------------------*/
 
-void Segment::Init(Standard_Integer a1, Standard_Integer a2,
-                   Standard_Integer a3, Standard_Integer a4)
-{
-  x1=a1;
-  y1=a2;
-  x2=a3;
-  y2=a4;
-}
-
 static DWORD WINAPI tkLoop (LPVOID theThreadParameter);
 #ifdef _TK
 static Tk_Window mainWindow;
 #endif
 
-//* threads sinchronization *//
-DWORD  dwMainThreadId;
+//* threads synchronization *//
+static DWORD dwMainThreadId;
 console_semaphore_value volatile console_semaphore = WAIT_CONSOLE_COMMAND;
 wchar_t console_command[DRAW_COMMAND_SIZE + 1];
 bool volatile isTkLoopStarted = false;
@@ -2028,12 +1647,18 @@ Standard_Boolean Init_Appli(HINSTANCE hInst,
 
   // san - 06/08/2002 - Time for tkLoop to start; Tk fails to initialize otherwise
   while (!isTkLoopStarted)
-    Sleep(10);
+  {
+    Sleep (10);
+  }
 
   // Saving of window classes
-  if(!hPrevInst)
-    if(!RegisterAppClass(hInst))
-      return(Standard_False);
+  if (!hPrevInst)
+  {
+    if (!RegisterAppClass (hInst))
+    {
+      return Standard_False;
+    }
+  }
 
   /*
    ** Enter the application message-polling loop.  This is the anchor for
@@ -2042,8 +1667,8 @@ Standard_Boolean Init_Appli(HINSTANCE hInst,
   hWndFrame = !Draw_IsConsoleSubsystem ? CreateAppWindow (hInst) : NULL;
   if (hWndFrame != NULL)
   {
-    ShowWindow(hWndFrame,nShow);
-    UpdateWindow(hWndFrame);
+    ShowWindow (hWndFrame, nShow);
+    UpdateWindow (hWndFrame);
   }
 
   return Standard_True;
@@ -2119,10 +1744,10 @@ static DWORD WINAPI readStdinThreadFunc (const LPVOID theThreadParameter)
 \*--------------------------------------------------------*/
 void exitProc(ClientData /*dc*/)
 {
-  NCollection_List<Draw_Window::FCallbackBeforeTerminate>::Iterator Iter(MyCallbacks);
-  for(; Iter.More(); Iter.Next())
+  for (NCollection_List<Draw_Window::FCallbackBeforeTerminate>::Iterator anIter (TermCallbacks());
+       anIter.More(); anIter.Next())
   {
-      (*Iter.Value())();
+    (*anIter.Value())();
   }
   HANDLE proc = GetCurrentProcess();
   TerminateProcess(proc, 0);
@@ -2130,10 +1755,7 @@ void exitProc(ClientData /*dc*/)
 
 // This is fixed version of TclpGetDefaultStdChannel() defined in tclWinChan.c
 // See https://core.tcl.tk/tcl/tktview/91c9bc1c457fda269ae18595944fc3c2b54d961d
-static Tcl_Channel
-TclpGetDefaultStdChannel(
-    int type)                  /* One of TCL_STDIN, TCL_STDOUT, or
-                                * TCL_STDERR. */
+static Tcl_Channel TclpGetDefaultStdChannel (int type) // One of TCL_STDIN, TCL_STDOUT, or TCL_STDERR.
 {
     Tcl_Channel channel;
     HANDLE handle;
@@ -2205,7 +1827,7 @@ TclpGetDefaultStdChannel(
     return channel;
 }
 
-// helper functuion
+// helper function
 static void ResetStdChannel (int type)
 {
   Tcl_Channel aChannel = TclpGetDefaultStdChannel (type);
@@ -2226,8 +1848,8 @@ static DWORD WINAPI tkLoop (const LPVOID theThreadParameter)
   
   Draw_Interpretor& aCommands = Draw::GetInterpretor();
   aCommands.Init();
-  Tcl_Interp *interp = aCommands.Interp();
-  Tcl_Init(interp);
+  Tcl_Interpinterp = aCommands.Interp();
+  Tcl_Init (interp);
 
   // Work-around against issue with Tcl standard channels on Windows.
   // These channels by default use OS handles owned by the system which
@@ -2310,10 +1932,15 @@ static DWORD WINAPI tkLoop (const LPVOID theThreadParameter)
   isTkLoopStarted = true;
 
   while (console_semaphore == STOP_CONSOLE)
-    Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
+  {
+    Tcl_DoOneEvent (TCL_ALL_EVENTS | TCL_DONT_WAIT);
+  }
 
-  if (Draw_IsConsoleSubsystem && console_semaphore == WAIT_CONSOLE_COMMAND)
-    Prompt(interp, 0);
+  if (Draw_IsConsoleSubsystem
+   && console_semaphore == WAIT_CONSOLE_COMMAND)
+  {
+    Prompt (interp, 0);
+  }
 
   //process a command
   Standard_Boolean toLoop = Standard_True;
@@ -2347,29 +1974,29 @@ static DWORD WINAPI tkLoop (const LPVOID theThreadParameter)
   return 0;
 }
 
-
 /*--------------------------------------------------------*\
 |  Run_Appli
 \*--------------------------------------------------------*/
-void Run_Appli(HWND hWnd)
+void Run_Appli (HWND hWnd)
 {
   MSG msg;
   HACCEL hAccel = NULL;
-
   msg.wParam = 1;
 
 //  if (!(hAccel = LoadAccelerators (hInstance, MAKEINTRESOURCE(ACCEL_ID))))
 //        MessageBox(hWnd, "MDI: Load Accel failure!", "Error", MB_OK);
   DWORD IDThread;
   HANDLE hThread;
-  if (Draw_IsConsoleSubsystem) {
+  if (Draw_IsConsoleSubsystem)
+  {
     hThread = CreateThread (NULL,                // no security attributes
                             0,                   // use default stack size
                             readStdinThreadFunc, // thread function
                             NULL,                // no thread function argument
                             0,                   // use default creation flags
                             &IDThread);          // returns thread identifier
-    if (!hThread) {
+    if (!hThread)
+    {
       std::cout << "pb in creation of the thread reading stdin" << std::endl;
       Draw_IsConsoleSubsystem = Standard_False;
       Init_Appli (GetModuleHandleW (NULL),
@@ -2380,7 +2007,9 @@ void Run_Appli(HWND hWnd)
 
   //turn on the command interpretation mechanism (regardless of the mode)
   if (console_semaphore == STOP_CONSOLE)
+  {
     console_semaphore = WAIT_CONSOLE_COMMAND;
+  }
 
   //simple Win32 message loop
   while (GetMessageW (&msg, NULL, 0, 0) > 0)
@@ -2394,80 +2023,16 @@ void Run_Appli(HWND hWnd)
   ExitProcess(0);
 }
 
-
 /*--------------------------------------------------------*\
 |  Destroy_Appli
 \*--------------------------------------------------------*/
-void Destroy_Appli(HINSTANCE hInst)
+void Destroy_Appli (HINSTANCE hInst)
 {
-  UnregisterAppClass(hInst);
-  for (int i = 0 ; i < MAXCOLOR ; i++)
-    DeleteObject(colorPenTab[i]);
-}
-
-/*--------------------------------------------------------*\
-|  SelectWait
-\*--------------------------------------------------------*/
-void DrawWindow::SelectWait(HANDLE& hWnd, int& x, int& y, int& button)
-{
-  MSG msg;
-
-  msg.wParam = 1;
-
-  GetMessageW (&msg, NULL, 0, 0);
-  while((msg.message != WM_RBUTTONDOWN && msg.message != WM_LBUTTONDOWN) ||
-        ! ( Draw_IsConsoleSubsystem || IsChild(DrawWindow::hWndClientMDI,msg.hwnd)) )
-  {
-    GetMessageW (&msg, NULL, 0, 0);
-  }
-
-  hWnd = msg.hwnd;
-  x = LOWORD(msg.lParam);
-  y = HIWORD(msg.lParam);
-  if (msg.message == WM_LBUTTONDOWN)
-    button = 1;
-  else
-    button = 3;
-}
-
-/*--------------------------------------------------------*\
-|  SelectNoWait
-\*--------------------------------------------------------*/
-void DrawWindow::SelectNoWait(HANDLE& hWnd, int& x, int& y, int& button)
-{
-  MSG msg;
-
-  msg.wParam = 1;
-
-  GetMessageW (&msg,NULL,0,0);
-  while((msg.message != WM_RBUTTONDOWN && msg.message != WM_LBUTTONDOWN &&
-        msg.message != WM_MOUSEMOVE) ||
-        ! ( Draw_IsConsoleSubsystem || IsChild(DrawWindow::hWndClientMDI,msg.hwnd) ) )
+  UnregisterAppClass (hInst);
+  for (int i = 0; i < MAXCOLOR; ++i)
   {
-    GetMessageW(&msg,NULL,0,0);
+    DeleteObject (Draw_colorPenTab[i]);
   }
-  hWnd = msg.hwnd;
-  x = LOWORD(msg.lParam);
-  y = HIWORD(msg.lParam);
-  switch (msg.message)
-  {
-    case WM_LBUTTONDOWN :
-                    button = 1;
-                    break;
-
-    case WM_RBUTTONDOWN :
-                    button = 3;
-                    break;
-
-    case WM_MOUSEMOVE :
-                    button = 0;
-                    break;
-  }
-}
-
-Standard_Boolean DrawWindow::DefineColor (const Standard_Integer, const char*)
-{
-  return Standard_True;
 }
 
 #endif