Logo Search packages:      
Sourcecode: opencascade version File versions  Download package

Draw_Window.cxx

// File:    Draw_Window.cxx
// Created: Wed Jul 27 17:52:01 1994
// Author:  Remi LEQUETTE
//          <rle@bravox>
//
// Updated by GG Tue Oct 22 16:22:10 1996
//          reason : Try to compress the pixel image
//                 in PseudoColor 8 planes format
//          see : Save(filename,compress_flag)
//
// Updated by DPF Fri Mar 21 18:40:58 1997
//              Ajout du casting en void* pour pouvoir compiler
//              sur AO1 int 32 bits -> pointeur 64 bits ????
//
// Robert Boehne 30 May 2000 : Dec Osf

// include windows.h first to have all definitions available
#ifdef WNT
#include <windows.h>
#endif

#include <Standard_ErrorHandler.hxx>

#include <tcl.h>
#include <Draw_Interpretor.hxx>
#include <TCollection_AsciiString.hxx>

extern Draw_Interpretor theCommands;
static Tcl_Interp *interp;    /* Interpreter for this application. */

/*
 *----------------------------------------------------------------------
 *
 * 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)
{

  // MKV 29.03.05
#if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))) && !defined(USE_NON_CONST)
    const char *promptCmd;
#else
    char *promptCmd;
#endif
    int code;
    Tcl_Channel  outChannel, errChannel;
    outChannel = Tcl_GetStdChannel(TCL_STDOUT);
    promptCmd = Tcl_GetVar(Interp,(char*)
      (partial ? "tcl_prompt2" : "tcl_prompt1"), TCL_GLOBAL_ONLY);
//    promptCmd = Tcl_GetVar(Interp,
//    partial ? "tcl_prompt2" : "tcl_prompt1", TCL_GLOBAL_ONLY);
   
    if (promptCmd == NULL) {
defaultPrompt:
      if (!partial && outChannel) {
      Tcl_Write(outChannel, "% ", 2);
      }
    } else {
      code = Tcl_Eval(Interp, promptCmd);
      outChannel = Tcl_GetStdChannel(TCL_STDOUT);
      errChannel = Tcl_GetStdChannel(TCL_STDERR);
      if (code != TCL_OK) {
      if (errChannel) {
        Tcl_Write(errChannel, Interp->result, -1);
        Tcl_Write(errChannel, "\n", 1);
      }
      Tcl_AddErrorInfo(Interp,
                   "\n    (script that generates prompt)");
      goto defaultPrompt;
      }
    }
    if (outChannel) {
      Tcl_Flush(outChannel);
    }
}

#ifndef WNT

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <OSD_Timer.hxx>

#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif

#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#else 
#include <sys/ioctl.h>
#endif

#include <fcntl.h>

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include <Draw_Window.hxx>

#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif

 
#include <Draw_WindowBase.hxx>
#include <X11/XWDFile.h>

#include <stdio.h>
#include <tk.h>



/*
 * Global variables used by the main program:
 */

static Tk_Window mainWindow;  /* The main window for the application.  If
                         * NULL then the application no longer
                         * exists. */
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. */

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";


/*
 * Forward declarations for procedures defined later in this file:
 */

static void StdinProc (ClientData clientData, int mask);


static void Prompt (Tcl_Interp *Interp, int partial);

static XImage* ConvertTrueToPseudo(XImage *pximage,
                           XVisualInfo *pinfo,
                           XWDColor *pcolors,
                           int *ncolors);

static Standard_Boolean tty;  /* Non-zero means standard input is a
                         * terminal-like device.  Zero means it's
                         * a file. */

static unsigned long thePixels[MAXCOLOR];


Display*         Draw_WindowDisplay = NULL;
Standard_Integer Draw_WindowScreen = 0;
Colormap         Draw_WindowColorMap;
Standard_Boolean Draw_BlackBackGround = Standard_True;
Standard_Boolean Draw_LowWindows = Standard_False;

#define SWAPTEST (*(char*)&swaptest)
#define LOWBIT(x) ((x) & (~(x) + 1))

static unsigned long swaptest = 1;
static void SwapLong(char* bp, unsigned n) ;
static void SwapShort(char* bp, unsigned n) ;




// Initialisation des variables statiques de Draw_Window
//======================================================
  Draw_Window* Draw_Window::firstWindow = NULL;


//=======================================================================
//function : Draw_Window
//purpose  : 
//=======================================================================

Draw_Window::Draw_Window() :
       base(*new Base_Window()),
       win(0),
       next(firstWindow),
       previous(NULL),
       withWindowManager(Standard_True)
{
  myMother = RootWindow(Draw_WindowDisplay,
                  Draw_WindowScreen);

  if (firstWindow) firstWindow->previous = this;
  firstWindow = this;
}

//=======================================================================
//function : Draw_Window
//purpose  : 
//=======================================================================

Draw_Window::Draw_Window(Window mother) :
       base(*new Base_Window()),
       win(0),
       next(firstWindow),
       previous(NULL),
       withWindowManager(Standard_True)
{
  myMother = mother;
  
  if (firstWindow) firstWindow->previous = this;
  firstWindow = this;
}


//=======================================================================
//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),
       next(firstWindow),previous(NULL)
{

  myMother = RootWindow(Draw_WindowDisplay,
                  Draw_WindowScreen);
  
  if (firstWindow) firstWindow->previous = this;
  firstWindow = this;
  Init(X,Y,DX,DY);
  SetTitle(title);
}

//=======================================================================
//function : Draw_Window
//purpose  : 
//=======================================================================

Draw_Window::Draw_Window (const char* window ) :
       base(*new Base_Window()),
       win(0),
       next(firstWindow),
       previous(NULL),
       withWindowManager(Standard_True)
{
  sscanf(window,"%lx",&win);
  Standard_Integer X,Y,DX,DY;

  if (firstWindow) firstWindow->previous = this;
  firstWindow = this;
  GetPosition(X,Y);
  DX=HeightWin();
  DY=WidthWin();
  
  Init(X,Y,DX,DY);
}

//=======================================================================
//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),
       next(firstWindow),
       previous(NULL),
       withWindowManager(Standard_True)
{
  myMother = mother; 

  if (firstWindow) firstWindow->previous = this;
  firstWindow = this;
  Init(X,Y,DX,DY);
  SetTitle(title);
}

//=======================================================================
//function : ~Draw_Window
//purpose  : 
//=======================================================================

Draw_Window::~Draw_Window()
{
  if (previous) 
    previous->next = next;
  else
    firstWindow = next;
  if (next)
    next->previous = previous;
  // Liberation pointeur sur Base_Window
  delete &base;
}

//=======================================================================
//function : Init
//purpose  : 
//=======================================================================

void Draw_Window::Init(Standard_Integer X, Standard_Integer Y,
                    Standard_Integer DX, Standard_Integer DY)
{
  unsigned long setmask;
 
  if (Draw_BlackBackGround) 
  {
    base.xswa.background_pixel = BlackPixel(Draw_WindowDisplay,Draw_WindowScreen);
    base.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);
  }
  base.xswa.colormap         = Draw_WindowColorMap;
  setmask               = CWBackPixel | CWBorderPixel ; 

  XSizeHints myHints;
  myHints.flags = USPosition;
  myHints.x = (int) X;
  myHints.y = (int) Y;

  if(win==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 );   
    
    // conseille au window manager de la mettre ou je la veux
    XSetWMNormalHints(Draw_WindowDisplay,win,&myHints);
  }

  base.gc = XCreateGC(Draw_WindowDisplay, win, 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));
  // sauvegarde en cas de recouvrement de la fenetre

  base.xswa.backing_store = Always;
  XChangeWindowAttributes(Draw_WindowDisplay, win, 
                      CWBackingStore, &base.xswa);

  XSetLineAttributes (Draw_WindowDisplay, base.gc,
                  0, LineSolid, CapButt, JoinMiter);
}

//=======================================================================
//function : StopWinManager
//purpose  : 
//=======================================================================
void Draw_Window::StopWinManager() 
{ 
//  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;

  win = XCreateWindow(Draw_WindowDisplay, myMother,
                  winAttr.x, winAttr.y,
                  winAttr.width, winAttr.height,
                  2, 
                  CopyFromParent, InputOutput, CopyFromParent,
                  CWBorderPixel|CWOverrideRedirect|CWBackPixel, &base.xswa);


  // conseille au window manager de la mettre ou je la veux
  XSetWMNormalHints(Draw_WindowDisplay,win,&myHints);
  
  // on reaffecte a la nvelle fenetre tous les mask de l'amcienne.
  XSelectInput(Draw_WindowDisplay,win,winAttr.your_event_mask);
  
}

//=======================================================================
//function : SetPosition
//purpose  : 
//=======================================================================

void Draw_Window::SetPosition(Standard_Integer NewXpos,
                        Standard_Integer NewYpos)
{
  Standard_Integer x,y;
  GetPosition(x, y);

  if ( (x != NewXpos) || (y != NewYpos) )
    XMoveWindow(Draw_WindowDisplay, win, NewXpos, NewYpos);

}

//=======================================================================
//function : SetDimension
//purpose  : 
//=======================================================================

void Draw_Window::SetDimension(Standard_Integer NewDx,
                         Standard_Integer NewDy)
{

  if ( (NewDx != WidthWin() ) || (NewDy != HeightWin() ) )
    XResizeWindow(Draw_WindowDisplay, win, NewDx, NewDy);
}

//=======================================================================
//function : GetPosition
//purpose  : 
//=======================================================================

void Draw_Window::GetPosition(Standard_Integer &PosX,
                        Standard_Integer &PosY)
{
  XWindowAttributes winAttr;
  XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);

  PosX = winAttr.x;
  PosY = winAttr.y;
  
}

//=======================================================================
//function : HeightWin
//purpose  : 
//=======================================================================

Standard_Integer Draw_Window::HeightWin() const
{
  Standard_Integer DY;
  XWindowAttributes winAttr;
  XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);

  DY = winAttr.height;
  return DY;
} 

//=======================================================================
//function : WidthWin
//purpose  : 
//=======================================================================

Standard_Integer Draw_Window::WidthWin() const
{
  Standard_Integer DX;
  XWindowAttributes winAttr;
  XGetWindowAttributes(Draw_WindowDisplay, win, &winAttr);

  DX = winAttr.width;
  return DX;
} 


//=======================================================================
//function : SetTitle
//purpose  : 
//=======================================================================

void Draw_Window::SetTitle(const char* title)
{
  XStoreName(Draw_WindowDisplay, win,title);
}

//=======================================================================
//function : GetTitle
//purpose  : 
//=======================================================================

char* Draw_Window::GetTitle() 
{
  char* title;
  XFetchName(Draw_WindowDisplay, win,&title);
  return title;
}

//=======================================================================
//function :DefineColor 
//purpose  : 
//=======================================================================
Standard_Boolean Draw_Window::DefineColor(const Standard_Integer i, const char* colorName)
{
  XColor color;

  if (!XParseColor(Draw_WindowDisplay,Draw_WindowColorMap,colorName,&color))
    return Standard_False;
  if (!XAllocColor(Draw_WindowDisplay,Draw_WindowColorMap,&color))
    return Standard_False;
  thePixels[i % MAXCOLOR] = color.pixel;
  return Standard_True; 
}

//=======================================================================
//function : DisplayWindow
//purpose  : 
//=======================================================================

void Draw_Window::DisplayWindow()
{
  // la fenetre <win> sera affiche de telle facon qu'elle ne sera 
  // cache par aucune autre fenetre (au top)
  if (Draw_LowWindows) {
    XMapWindow(Draw_WindowDisplay, win);
    XLowerWindow(Draw_WindowDisplay, win);
  }
  else
    XMapRaised(Draw_WindowDisplay, win);
  XFlush(Draw_WindowDisplay);
}

//=======================================================================
//function : Hide
//purpose  : 
//=======================================================================

void Draw_Window::Hide()
{
   XUnmapWindow(Draw_WindowDisplay, win);
}

//=======================================================================
//function : Destroy
//purpose  : 
//=======================================================================

void Draw_Window::Destroy()
{
  XDestroyWindow(Draw_WindowDisplay, win);
  win = 0;
}

//=======================================================================
//function : Clear
//purpose  : 
//=======================================================================

void Draw_Window::Clear()
{
  XClearWindow(Draw_WindowDisplay, win);
}

//=======================================================================
//function : Flush
//purpose  : 
//=======================================================================

void Draw_Window::Flush()
{
  XFlush(Draw_WindowDisplay);
}


//=======================================================================
//function : DrawString 
//purpose  : 
//=======================================================================
void Draw_Window::DrawString(int X, int Y, char *text)
{
  XDrawString(Draw_WindowDisplay, win, base.gc, X, Y, text, strlen(text));
}

//=======================================================================
//function : DrawSegments 
//purpose  : 
//=======================================================================
void Draw_Window::DrawSegments(Segment *tab, int nbElem)
{
  XDrawSegments(Draw_WindowDisplay, win, base.gc, (XSegment*) tab, nbElem);
}

//=======================================================================
//function : SetColor
//purpose  : 
//=======================================================================
void Draw_Window::SetColor(Standard_Integer color)
{
  XSetForeground(Draw_WindowDisplay, base.gc, thePixels[color]);
}

//=======================================================================
//function : SetMode 
//purpose  : 
//=======================================================================
void Draw_Window::SetMode( int mode)
{
  XSetFunction(Draw_WindowDisplay, base.gc, mode);
}

//=======================================================================
//function : Save
//purpose  : 
//=======================================================================

Standard_Boolean Draw_Window::Save(const char* filename, const Standard_Boolean compress) const
{
  XColor *pcolors = NULL;
  XWDColor *qcolors = NULL;
//  int i,isize,ncolors, lname = strlen(filename)+1;
  int lname = strlen(filename)+1;
  unsigned int i, isize ,ncolors;
  Standard_Boolean status = Standard_True;

  XSync(Draw_WindowDisplay,True);
 
  // open the file

  FILE *fimage = fopen(filename,"w");
  if (!fimage) return Standard_False;

  // the attributes

  XWindowAttributes winAttr;
  XGetWindowAttributes (Draw_WindowDisplay, win, &winAttr);
  Visual *pvisual = winAttr.visual;

  // the color map
  // process the different classes

  switch (pvisual->c_class) {

  case PseudoColor : 
    {
      ncolors = 256;
      if(( pcolors = new XColor[ncolors])) {
      for( i=0 ; i<ncolors ; i++) {
        pcolors[i].pixel = i;
        pcolors[i].pad = 0;
      }
      XQueryColors(Draw_WindowDisplay,
                 Draw_WindowColorMap,pcolors,ncolors);

      if(( qcolors = new XWDColor[ncolors])) {
        for( i=0 ; i<ncolors ; i++) {
          qcolors[i].pixel = pcolors[i].pixel;
          qcolors[i].red = pcolors[i].red;
          qcolors[i].green = pcolors[i].green;
          qcolors[i].blue = pcolors[i].blue;
          qcolors[i].flags = pcolors[i].flags;
          qcolors[i].pad = 0;
        }
        delete [] pcolors;
      } 
      else {
        // bad allocation
        delete [] pcolors;
        fclose(fimage) ;
        return Standard_False;
      }
      } 
      else {
      // bad allocation
      fclose(fimage) ;
      return Standard_False;
      } 
    }
    break ;
    
  case TrueColor :  
    {
      ncolors = 0;
    }
    break ;
    
  case DirectColor :
    {
      ncolors = 256;
      if(( pcolors = new XColor[ncolors] )) {
      unsigned long red = 0,lred = LOWBIT(pvisual->red_mask);
      unsigned long green = 0,lgreen = LOWBIT(pvisual->green_mask);
      unsigned long blue = 0,lblue = LOWBIT(pvisual->blue_mask);
      for( i=0 ; i<ncolors ; i++) {
        pcolors[i].pixel = red|green|blue;
        pcolors[i].pad = 0;
        red += lred;
        if( red > pvisual->red_mask ) red = 0;
        green += lgreen;
        if( green > pvisual->green_mask ) green = 0;
        blue += lblue;
        if( blue > pvisual->blue_mask ) blue = 0;
      }
      XQueryColors(Draw_WindowDisplay,
                 Draw_WindowColorMap,pcolors,ncolors);

      if(( qcolors = new XWDColor[ncolors] )) {
        for( i=0 ; i<ncolors ; i++) {
          qcolors[i].pixel = pcolors[i].pixel;
          qcolors[i].red = pcolors[i].red;
          qcolors[i].green = pcolors[i].green;
          qcolors[i].blue = pcolors[i].blue;
          qcolors[i].flags = pcolors[i].flags;
          qcolors[i].pad = 0;
        }
        delete [] pcolors;
      } 
      else {
        // bad allocation
        delete [] pcolors;
        fclose(fimage) ;
        return Standard_False;
      }
      } 
      else {
      // bad allocation
      fclose(fimage) ;
      return Standard_False;
      } 
    }
    break ;
    
    default :
    // Unimplemented Image Visual class
    fclose(fimage) ;
    return Standard_False;
  }
  
  
  // find the image

  XImage *pximage = XGetImage(Draw_WindowDisplay,win,
                        0,0,WidthWin(),HeightWin(),
                        AllPlanes,ZPixmap);
  if (!pximage) {
    delete [] qcolors;
    return Standard_False;
  } 

  if( compress ) {      // convert ximage to PseudoColor 8 planes
    XImage *qximage = NULL;
    XVisualInfo tinfo;
    int nitem;
    tinfo.screen = Draw_WindowScreen;
    tinfo.c_class = PseudoColor;
    tinfo.depth = 8;
    XVisualInfo *qinfo = XGetVisualInfo(Draw_WindowDisplay,
      VisualScreenMask | VisualDepthMask | VisualClassMask,&tinfo,&nitem);
    int nqcolors = 256;
    if( !qcolors && (qcolors = new XWDColor[nqcolors]) ) {
        for( i=0 ; i<(unsigned int ) nqcolors ; i++) {
          qcolors[i].pixel = 0;
          qcolors[i].red = 0;
          qcolors[i].green = 0;
          qcolors[i].blue = 0;
          qcolors[i].flags = DoRed | DoGreen | DoBlue;
          qcolors[i].pad = 0;
        }
    }

    if( qinfo && qcolors ) switch (pvisual->c_class) {

      case PseudoColor : 
      break;

      case TrueColor : 
        qximage = ConvertTrueToPseudo(pximage,qinfo,qcolors,&nqcolors);
      break;

      case DirectColor : 
      cout << " DirectColor compression is UNIMPLEMENTED " << endl;
      break;
    }
    if( qximage ) {
      XDestroyImage(pximage);
      pximage = qximage;
      pvisual = qinfo->visual;
      ncolors = nqcolors;
    }
    if( qinfo ) {
      XFree(qinfo);
    }
  }
  
  // make the file header
  XWDFileHeader header;
  header.ncolors = ncolors;
  header.header_size = (CARD32) (sizeof(header) + lname);
  header.file_version = (CARD32) XWD_FILE_VERSION;
  header.pixmap_format = (CARD32) ZPixmap;
  header.pixmap_depth = (CARD32) pximage->depth;
  header.pixmap_width = (CARD32) pximage->width;
  header.pixmap_height = (CARD32) pximage->height;
  header.xoffset = (CARD32) pximage->xoffset;
  header.byte_order = (CARD32) pximage->byte_order;
  header.bitmap_unit = (CARD32) pximage->bitmap_unit;
  header.bitmap_bit_order = (CARD32) pximage->bitmap_bit_order;
  header.bitmap_pad = (CARD32) pximage->bitmap_pad;
  header.bits_per_pixel = (CARD32) pximage->bits_per_pixel;
  header.bytes_per_line = (CARD32) pximage->bytes_per_line;
  header.visual_class = (CARD32) pvisual->c_class;
  header.red_mask = (CARD32) pvisual->red_mask;
  header.green_mask = (CARD32) pvisual->green_mask;
  header.blue_mask = (CARD32) pvisual->blue_mask;
  header.bits_per_rgb = (CARD32) pvisual->bits_per_rgb;
  header.colormap_entries = (CARD32) pvisual->map_entries;
  header.window_width = (CARD32) winAttr.width;
  header.window_height = (CARD32) winAttr.height;
  header.window_x = winAttr.x;
  header.window_y = winAttr.y;
  header.window_bdrwidth = (CARD32) winAttr.border_width;
  isize = header.bytes_per_line*header.pixmap_height ;
  
  if( SWAPTEST ) {
    SwapLong((char*)&header,sizeof(header)) ;
    for( i=0 ; i<ncolors ; i++) {
      SwapLong((char *) &qcolors[i].pixel,4);
      SwapShort((char *) &qcolors[i].red, 3*sizeof(short));
    }
  }

  // write the file
  
    if( status && fwrite((char *)&header, sizeof(header), 1, fimage) < 1 ) 
      status = Standard_False;
    if( status && fwrite(filename, lname, 1, fimage) < 1 ) 
      status = Standard_False;
 
    /*
     * Write out the color maps, if any
     */
    
    if( ncolors > 0 ) {    
      if( status && 
       fwrite((char *) qcolors, sizeof(XWDColor), ncolors, fimage) 
       < ncolors ) 
      status = Standard_False;
    }

  if( status && fwrite(pximage->data, 1, isize, fimage) < isize ) 
    status = Standard_False;
       


    fclose(fimage) ;
  

  // destroy the image
  XDestroyImage(pximage);

  delete [] qcolors;

  return status;
}


//=======================================================================
//function : ProcessEvent
//purpose  : 
//=======================================================================

void ProcessEvent(Draw_Window& win, XEvent& xev)
{
  Standard_Integer X,Y,button,lenk;
  char c;
  KeySym keysym;
  XComposeStatus stat;
  char chainekey[10];
 

  switch (xev.type) {

  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 :
    lenk = XLookupString(&(xev.xkey),
                   chainekey,
                   10,
                   &keysym,
                   &stat);
    if (lenk==1) 
      c = chainekey[0];
    else
      c = '\0';
    
    //WKeyPress(c,keysym);
    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)
{
}

//=======================================================================
//function : Wait 
//purpose  : 
//=======================================================================

void Draw_Window::Wait (Standard_Boolean wait)
{
  Flush();
  if (!wait) {
        XSelectInput(Draw_WindowDisplay,win,
                     ButtonPressMask|ExposureMask | StructureNotifyMask |
                     PointerMotionMask);
  }
  else {
        XSelectInput(Draw_WindowDisplay,win,
                     ButtonPressMask|ExposureMask | StructureNotifyMask);
  }
}

//=======================================================================
//function : WUnmapNotify
//purpose  : 
//=======================================================================

void Draw_Window::WUnmapNotify()
{
}

// utilities for save

static void SwapLong (char* bp, unsigned n)
//    Swap long ints depending of CPU
{
  char c;
  char *ep = bp + n;
  char *sp;

    while (bp < ep) {
        sp = bp + 3;
        c = *sp;
        *sp = *bp;
        *bp++ = c;
        sp = bp + 1;
        c = *sp;
        *sp = *bp;
        *bp++ = c;
        bp += 2;
    }
}

static void SwapShort (char* bp, unsigned n)
//   Swap short ints dependong of CPU
{
  char c;
  char *ep = bp + n;

    while (bp < ep) {
        c = *bp;
        *bp = *(bp + 1);
        bp++;
        *bp++ = c;
    }
}

//======================================================
// funtion : ProcessEvents
// purpose : process pending X events
//======================================================

static void ProcessEvents(ClientData,int)
{
  // test for X Event
  
  while (XPending(Draw_WindowDisplay)) {

    XEvent xev;
    xev.type = 0;
    
    XNextEvent(Draw_WindowDisplay,&xev);
    
    /* search the window in the window list */
    Draw_Window* w = Draw_Window::firstWindow;
    Standard_Integer found=0;
    while (w) {
      if (xev.xany.window == w->win) {
      ProcessEvent(*w, xev);
      found=1;
      break;
      }
      w = w->next;
    }
    if (found==0) {
      Tk_HandleEvent(&xev);
    }
  }
}
    
//======================================================
// funtion :Run_Appli
// purpose :
//======================================================


static Standard_Boolean(*Interprete) (char*);

void Run_Appli(Standard_Boolean (*interprete) (char*))
{
  Tcl_Channel outChannel, inChannel ;
  Interprete = interprete;

#ifdef _TK

    /*
     * Commands will come from standard input, so set up an event
     * handler for standard input.  If the input device is aEvaluate the
     * .rc file, if one has been specified, set up an event handler
     * for standard input, and print a prompt if the input
     * device is a terminal.
     */
  inChannel = Tcl_GetStdChannel(TCL_STDIN);
  if (inChannel) {
          Tcl_CreateChannelHandler(inChannel, TCL_READABLE, StdinProc,
                (ClientData) inChannel);
      }

  // Create a handler for the draw display

  // Ajout du casting en void* pour pouvoir compiler sur AO1
  // ConnectionNumber(Draw_WindowDisplay) est un int 32 bits
  //                    (void*) est un pointeur      64 bits ???????

#if TCL_MAJOR_VERSION  < 8  
    Tk_CreateFileHandler((void*) ConnectionNumber(Draw_WindowDisplay), 
                   TK_READABLE, ProcessEvents,(ClientData) 0 );
#else
    Tk_CreateFileHandler(ConnectionNumber(Draw_WindowDisplay), 
                   TK_READABLE, ProcessEvents,(ClientData) 0 );
#endif    

#endif
  
  if (tty) Prompt(theCommands.Interp(), 0);
  Prompt(theCommands.Interp(), 0);

  outChannel = Tcl_GetStdChannel(TCL_STDOUT);
  if (outChannel) {
      Tcl_Flush(outChannel);
    }
  Tcl_DStringInit(&command);
  
  /*
   * Loop infinitely, waiting for commands to execute.  When there
   * are no windows left, Tk_MainLoop returns and we exit.
   */

#ifdef _TK  

  Tk_MainLoop();
  
#else

  fd_set readset;
  Standard_Integer count = ConnectionNumber(Draw_WindowDisplay);
  Standard_Integer numfd;
  while (1) {
      FD_ZERO(&readset);
      FD_SET(0,&readset);
      FD_SET(count,&readset);
#ifdef HPUX
      numfd = select(count+1,(Integer*)&readset,NULL,NULL,NULL);
#else
      numfd = select(count+1,&readset,NULL,NULL,NULL);
#endif
      if (FD_ISSET(0,&readset))     StdinProc((ClientData)0,0);
      if (FD_ISSET(count,&readset)) ProcessEvents((ClientData)0,0);
    }

#endif
}

//======================================================
// funtion : Init_Appli()
// purpose :
//======================================================
Standard_Boolean Init_Appli()
{
  theCommands.Init();
  interp = theCommands.Interp();

  Tcl_Init(interp) ;
  try { 
    OCC_CATCH_SIGNALS
    Tk_Init(interp) ;
  } catch  (Standard_Failure) { 
    cout <<" Pb au lancement de TK_Init "<<endl;
  }

  Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
  
  mainWindow =
  Tk_MainWindow(interp) ;
  if (mainWindow == NULL) {
      fprintf(stderr, "%s\n", interp->result);
      exit(1);
   }
  Tk_Name(mainWindow) = 
  Tk_GetUid(Tk_SetAppName(mainWindow,
                    "Draw")) ;

  Tk_GeometryRequest(mainWindow, 200, 200);

  if (Draw_WindowDisplay == NULL) {
     Draw_WindowDisplay = Tk_Display(mainWindow) ;
  }
  if (Draw_WindowDisplay == NULL) {
    cout << "Cannot open display : "<<XDisplayName(NULL)<<endl;
    cout << "Interpret commands in batch mode."<<endl;
    return Standard_False;
  }
  //
  // 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);
  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;
}

//======================================================
// funtion : Destroy_Appli()
// purpose :
//======================================================
void Destroy_Appli()
{
  //XCloseDisplay(Draw_WindowDisplay); 
}
       
//======================================================
// funtion : GetNextEvent()
// purpose :
//======================================================
void GetNextEvent(Event& ev)
{
  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;
           break;

      case MotionNotify :
         ev.type = 6;
         ev.window = xev.xmotion.window; 
           ev.button = 0;
         ev.x = xev.xmotion.x;
         ev.y = xev.xmotion.y;
           break;
   }
}

/*
 *----------------------------------------------------------------------
 *
 * 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 moyen pour eviter un SIGBUS en sortie de DRAW 
    // a affiner ulterieurement voir supprimer une fois 
    // le probleme de free sur la variable globale environ
    //
    // 

  Interprete(cmd);
    
  
  Tcl_CreateChannelHandler(chan, TCL_READABLE, StdinProc,
                     (ClientData) chan);
  Tcl_DStringFree(&command);
  
  /*
   * Output a prompt.
   */
  
prompt:
  if (tty) Prompt(interp, gotPartial);
  
 } catch (Standard_Failure) {} 
   
}

/*
 *----------------------------------------------------------------------
 *    Convert True image to 8 planes Pseudo color image
 * Parameters:
 *          wattr -> Window Attributes
 *
 * Results:
 *     returns the converted XImage pointer.
 *
 *----------------------------------------------------------------------
*/
static XImage* ConvertTrueToPseudo(XImage *pximage,
                           XVisualInfo *pinfo,
                           XWDColor *pcolors,
                           int *ncolors) {
XImage *qximage = NULL;
char *qdata = (char*) malloc(pximage->width*pximage->height);
int i,j,x,y,icolors = 0,sred = 0,sgreen = 0,sblue = 0;
unsigned long cmask,ipixel,opixel=0,lpixel = ~0;
unsigned short red,green,blue;

    cmask = pximage->red_mask ;
    while ( !(cmask & 1) ) { cmask >>= 1 ; sred++ ; }
    cmask = pximage->green_mask ;
    while ( !(cmask & 1) ) { cmask >>= 1 ; sgreen++ ; }
    cmask = pximage->blue_mask ;
    while ( !(cmask & 1) ) { cmask >>= 1 ; sblue++ ; }

    if( qdata && (qximage = XCreateImage(Draw_WindowDisplay,
            pinfo->visual,pinfo->depth,ZPixmap,0,qdata,
                  pximage->width,pximage->height,pinfo->depth,0)) ) {
      for( y=0 ; y<pximage->height ; y++ ) {
        for( x=0 ; x<pximage->width ; x++ ) {
          ipixel = XGetPixel(pximage,x,y) ;
          if( ipixel != lpixel ) {
            lpixel = ipixel;
            red = (unsigned short)(65535. * (float)((ipixel >> sred) & cmask)/cmask) ;
            green = (unsigned short)(65535. * (float)((ipixel >> sgreen) & cmask)/cmask) ;
            blue = (unsigned short)(65535. * (float)((ipixel >> sblue) & cmask)/cmask) ;

          j = icolors;
          for( i=0 ; i<icolors ; i++ ) {
            if( (red == pcolors[i].red) &&
                  (green == pcolors[i].green) &&
                    (blue == pcolors[i].blue) ) {
              j = i; break;
            }
          }
          if( j >= icolors ) {
            if( j < *ncolors ) {
              pcolors[j].pixel = j;
              pcolors[j].red = red;
              pcolors[j].green = green;
              pcolors[j].blue = blue;
              icolors++;
            } else {
              j = 0;
            cout << " ConvertTrueToPseudo.TOO many different colors " << endl; 
            }
          } 
          opixel = j;
          }
          XPutPixel(qximage,x,y,opixel) ;
        }
      }
    } else {
      cout << " *ConvertTrueToPseudo*BAD XImage " << endl;
    }

    *ncolors = icolors;

    return qximage;
}

#else

// Source Specifique WNT

/****************************************************\
*  Draw_Window.cxx :
*
\****************************************************/

#include "Draw_Window.hxx"
#include "DrawRessource.h"
#include "init.h"

#include <Draw_Appli.hxx>
#include <OSD.hxx>

#include <tk.h>

#define PENWIDTH 1
#define CLIENTWND 0     
// Position des informations dans l'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 de stylos de couleur
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))};

// Correspondance mode X11 et 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 = CreateWindow (DRAWCLASS, DRAWTITLE, 
                        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                        1,1,1,1,
                        NULL, NULL,::GetModuleHandle(NULL), NULL);
    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;
#ifndef _WIN64
    hInstance = (HANDLE)GetWindowLong(hWndClient,GWL_HINSTANCE);
#else
    hInstance = (HANDLE)GetWindowLong(hWndClient,GWLP_HINSTANCE);
#endif

    return CreateMDIWindow(DRAWCLASS, DRAWTITLE,
                     WS_CAPTION | WS_CHILD | WS_VISIBLE | WS_THICKFRAME,
                     1,1,0,0,
                     hWndClient, (HINSTANCE)hInstance, nitem);
  }
}


/*--------------------------------------------------------*\
|  DRAW WINDOW PROCEDURE
\*--------------------------------------------------------*/
LONG APIENTRY DrawWindow::DrawProc(HWND hWnd, UINT wMsg, WPARAM wParam, LONG lParam )
{
  DrawWindow* localObjet = (DrawWindow*)GetWindowLong(hWnd, CLIENTWND);
  if (!localObjet)
    {
      if (Draw_IsConsoleSubsystem)
      return (DefWindowProc(hWnd, wMsg, wParam, lParam));
      else
      return(DefMDIChildProc(hWnd, wMsg, wParam, lParam));
    }
  
  PAINTSTRUCT ps;

  switch(wMsg)
  {   
  case WM_PAINT :
    BeginPaint(hWnd, &ps);
    if (localObjet->GetUseBuffer()) 
      localObjet->Redraw();
    else
      localObjet->WExpose();
    EndPaint(hWnd, &ps);
    return 0l;                                              
    break;
    
  case WM_SIZE:
    if (localObjet->GetUseBuffer()) {
      localObjet->InitBuffer();
      localObjet->WExpose();
      localObjet->Redraw();
      return 0l;
      break;
    }

  default:
    if (Draw_IsConsoleSubsystem)
      return (DefWindowProc(hWnd, wMsg, wParam, lParam));
    else
      return(DefMDIChildProc(hWnd, wMsg, wParam, lParam));
  }   
  return (0l);
}



/*
**  IMPLEMENTATION DE LA CLASS DRAWWINDOW
 */

/*--------------------------------------------------------*\
| Initialisation des variables statiques de DrawWindow
\*--------------------------------------------------------*/

DrawWindow* DrawWindow::firstWindow = NULL;
HWND DrawWindow::hWndClientMDI = 0;

/*--------------------------------------------------------*\
| Constructeurs de Draw_Window
\*--------------------------------------------------------*/

// Constructeur par defaut
//________________________
DrawWindow::DrawWindow() :
      win(0),
      next(firstWindow),
      previous(NULL),
        myMemHbm(NULL),
        myUseBuffer(Standard_False)
{
  if (firstWindow) firstWindow->previous = this;
  firstWindow = this;
}

//________________________
DrawWindow::DrawWindow(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(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);
}



/*--------------------------------------------------------*\
| Destructeur de 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 X, Standard_Integer Y,
                  Standard_Integer dX, Standard_Integer dY)
{
  if (win == 0)
  {
    win = CreateDrawWindow(hWndClientMDI, 0);
  }
  SetPosition(X,Y);
  SetDimension(dX,dY);
  // Enregistre le pointeur sur l`instance associČe Ä la fenetre
  SetWindowLong(win, CLIENTWND, (LONG)this);
  HDC hDC = GetDC(win);
  SetBkColor(hDC, RGB(0, 0, 0));
  myCurrPen  = 3;
  myCurrMode = 3;
  SelectObject(hDC, colorPenTab[myCurrPen]); // Crayon par defaut
  SelectObject(hDC, GetStockObject(BLACK_BRUSH));
  SetTextColor(hDC, RGB(0,0,255));
  ReleaseDC(win, hDC);
}

/*--------------------------------------------------------*\
|  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;
      GetObject(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)
{
  SetWindowPos(win, 0,
             posX, posY,
             0, 0,
             SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
}


/*--------------------------------------------------------*\
|  SetDimension
\*--------------------------------------------------------*/
void DrawWindow::SetDimension(Standard_Integer dimX, Standard_Integer dimY)
{
  SetWindowPos(win, 0,
             0, 0,
             dimX, dimY,
             SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
}


/*--------------------------------------------------------*\
|  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(char* title)
{
  SetWindowText(win, title);
}


/*--------------------------------------------------------*\
|  GetTitle
|    Attention ne pas oublier de desallouer la memoire
\*--------------------------------------------------------*/
char* DrawWindow::GetTitle()
{
  char* title=new char[31];
  GetWindowText(win, title, 30);
  return title;
}


/*--------------------------------------------------------*\
|  DisplayWindow
\*--------------------------------------------------------*/
void DrawWindow::DisplayWindow()
{
  SetActiveWindow(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;

  int debug = GetROP2(aWorkDC); 
  SaveDC(aWorkDC);
  SelectObject(aWorkDC,GetStockObject(BLACK_PEN));
  Rectangle(aWorkDC, 0, 0, WidthWin(), HeightWin());
  RestoreDC(aWorkDC,-1);
  
  if (myUseBuffer) ReleaseMemDC(aWorkDC);
  ReleaseDC(win,hDC);
}


/*--------------------------------------------------------*\
|  DrawString
\*--------------------------------------------------------*/
void DrawWindow::DrawString(int x,int y, char* text)
{
  HDC hDC = GetDC(win);
  HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
  
  TextOut(aWorkDC, x, y, text, strlen(text)); 
  
  if (myUseBuffer) ReleaseMemDC(aWorkDC);
  ReleaseDC(win,hDC);
}

/*--------------------------------------------------------*\
|  DrawSegments
\*--------------------------------------------------------*/
void DrawWindow::DrawSegments(Segment *tab, int nbElem)
{
  HDC hDC = GetDC(win);
  HDC aWorkDC = myUseBuffer ? GetMemDC(hDC) : hDC;
  
  for(int i = 0 ; i < nbElem ; i++)
  {
    MoveToEx(aWorkDC, tab[i].x1, tab[i].y1, NULL);
    LineTo(aWorkDC, tab[i].x2, tab[i].y2);
  }
  
  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);
  }
}

/*--------------------------------------------------------*\
|  SetMode
\*--------------------------------------------------------*/
void DrawWindow::SetMode(int mode)
{
  HDC hDC = GetDC(win);
  myCurrMode = mode;
  SetROP2(hDC, modeTab[mode]); 
  ReleaseDC(win,hDC);
}


/*--------------------------------------------------------*\
|  SetColor
\*--------------------------------------------------------*/
void DrawWindow::SetColor(Standard_Integer color)
{
  HDC hDC = GetDC(win);
  myCurrPen = color;
  SelectObject(hDC,colorPenTab[color]);
  ReleaseDC(win,hDC);
}


/*--------------------------------------------------------*\
|  WExpose
\*--------------------------------------------------------*/
void DrawWindow::WExpose()
{
}


/*--------------------------------------------------------*\
|  WButtonPress
\*--------------------------------------------------------*/
void DrawWindow::WButtonPress(const Standard_Integer,
                         const Standard_Integer,
                         const Standard_Integer&)
{
}


/*--------------------------------------------------------*\
|  WButtonRelease
\*--------------------------------------------------------*/
void DrawWindow::WButtonRelease(const Standard_Integer,
                         const Standard_Integer,
                         const Standard_Integer&)
{
}


/*--------------------------------------------------------*\
|  WMotionNotify
\*--------------------------------------------------------*/
void Draw_Window::WMotionNotify(const Standard_Integer ,
                        const Standard_Integer )
{
}


/*--------------------------------------------------------*\
|  WConfigureNotify
\*--------------------------------------------------------*/
void DrawWindow::WConfigureNotify(const Standard_Integer,
                           const Standard_Integer,
                           const Standard_Integer,
                           const Standard_Integer)
{
}


/*--------------------------------------------------------*\
|  WUnmapNotify
\*--------------------------------------------------------*/
void DrawWindow::WUnmapNotify()
{
}



/*
**  IMPLEMENTATION DE LA CLASS SEGMENT
 */

/*--------------------------------------------------------*\
|  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(VOID);
#ifdef _TK
static Tk_Window mainWindow;  
#endif

//* threads sinchronization *//
DWORD  dwMainThreadId;
console_semaphore_value volatile console_semaphore = WAIT_CONSOLE_COMMAND;
char console_command[1000];

bool volatile isTkLoopStarted = false;

/*--------------------------------------------------------*\
|  Init_Appli
\*--------------------------------------------------------*/
Standard_Boolean Init_Appli(HINSTANCE hInst, 
                            HINSTANCE hPrevInst, int nShow, HWND& hWndFrame )
{
  DWORD IDThread;
  HANDLE hThread;
  console_semaphore = STOP_CONSOLE;
  
  theCommands.Init();
  interp = theCommands.Interp();
  Tcl_Init(interp) ;
  
  dwMainThreadId = GetCurrentThreadId();
  
  //necessary for normal Tk operation
  hThread = CreateThread(NULL, // no security attributes 
                     0,                           // use default stack size 
                     (LPTHREAD_START_ROUTINE) tkLoop, // thread function 
                     NULL,                    // no thread function argument 
                     0,                       // use default creation flags 
                     &IDThread);
  if (!hThread) {
    cout << "Tcl/Tk main loop thread not created. Switching to batch mode..." << endl;
#ifdef _TK
    try { 
      OCC_CATCH_SIGNALS
      Tk_Init(interp) ;
    } catch  (Standard_Failure) { 
      cout <<" Pb au lancement de TK_Init "<<endl;
    }

    Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
#endif    
    //since the main Tcl/Tk loop wasn`t created --> switch to batch mode
    return Standard_False;
  }
  
  // san - 06/08/2002 - Time for tkLoop to start; Tk fails to initialize otherwise
  while (!isTkLoopStarted)
    Sleep(10);

  // Enregistrement des classes de fenetre
  if(!hPrevInst)
    if(!RegisterAppClass(hInst))
      return(Standard_False);

  /*
   ** Enter the application message-polling loop.  This is the anchor for
   ** the application.
  */
  if(Draw_IsConsoleSubsystem)

    hWndFrame = NULL;
      
  else if (hWndFrame = CreateAppWindow(hInst))
  {
    ShowWindow(hWndFrame,nShow);
    UpdateWindow(hWndFrame);
  }
  return Standard_True;
}

Standard_Boolean Draw_Interprete (char*);

/*--------------------------------------------------------*\
|  readStdinThreadFunc
\*--------------------------------------------------------*/
static DWORD WINAPI readStdinThreadFunc(VOID)
{ 
  if (!Draw_IsConsoleSubsystem) return 1;
  
  while (1) {
    while (console_semaphore != WAIT_CONSOLE_COMMAND)
      Sleep(100);
    if (gets(console_command)) 
      {
      console_semaphore = HAS_CONSOLE_COMMAND;
      }
                  
  }
  return 0;
}

/*--------------------------------------------------------*\
|  exitProc: finalization handler for Tcl/Tk thread. Forces parent process to die
\*--------------------------------------------------------*/
void exitProc(ClientData /*dc*/)
{
  HANDLE proc = GetCurrentProcess();
  TerminateProcess(proc, 0);
}

/*--------------------------------------------------------*\
|  tkLoop: implements Tk_Main()-like behaviour in a separate thread
\*--------------------------------------------------------*/
static DWORD WINAPI tkLoop(VOID)
{ 
  Tcl_CreateExitHandler(exitProc, 0);

#ifdef _TK
  try { 
    OCC_CATCH_SIGNALS
    Standard_Integer res = Tk_Init(interp) ;    
    if (res != TCL_OK)
      cout << "tkLoop: error in Tk initialization. Tcl reported: " << interp->result << endl;
    
  } catch  (Standard_Failure) { 
    cout <<"tkLoop: exception in TK_Init "<<endl;
  }
  Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
  
  mainWindow =
    Tk_MainWindow(interp) ;
  if (mainWindow == NULL) {
      fprintf(stderr, "%s\n", interp->result);
      cout << "tkLoop: Tk_MainWindow() returned NULL. Exiting..." << endl;
      Tcl_Exit(0);
   }
  Tk_Name(mainWindow) = 
    Tk_GetUid(Tk_SetAppName(mainWindow,
                    "Draw")) ;
#endif  //#ifdef _TK

  // msv - 16/09/2004 - set signal handler in the new thread
  OSD::SetSignal();

  // san - 06/08/2002 - inform the others that we have started
  isTkLoopStarted = true;

  while (console_semaphore == STOP_CONSOLE)
    Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
 
  if (Draw_IsConsoleSubsystem && console_semaphore == WAIT_CONSOLE_COMMAND) 
    Prompt(interp, 0);
  
  //process a command
#ifdef _TK
  // san - 10/07/02 -- We should not exit until the Main Tk window is closed
  while (Tk_GetNumMainWindows() > 0) {
#else
  while (1) {
#endif
    while(Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT));
    if (console_semaphore == HAS_CONSOLE_COMMAND) {
      if (Draw_Interprete(console_command))
      if (Draw_IsConsoleSubsystem) Prompt(interp, 0);
      else
      if (Draw_IsConsoleSubsystem) Prompt(interp, 1);
      console_semaphore = WAIT_CONSOLE_COMMAND;
    }
    else
      Sleep(100);
    
  }

  Tcl_Exit(0);
      
  return 0;
}


/*--------------------------------------------------------*\
|  Run_Appli
\*--------------------------------------------------------*/
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) {
    hThread = CreateThread(NULL, // no security attributes 
                     0,                           // use default stack size 
                     (LPTHREAD_START_ROUTINE) readStdinThreadFunc, // thread function 
                     NULL,                    // no thread function argument 
                     0,                       // use default creation flags 
                     &IDThread);              // returns thread identifier 
    if (!hThread) {
      cout << "pb in creation of the thread reading stdin" << endl;
      Draw_IsConsoleSubsystem = Standard_False;
      Init_Appli(GetModuleHandle(NULL),
             GetModuleHandle(NULL),
             1, hWnd); // reinit => create MDI client wnd
    }
  }

  //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 (GetMessage(&msg, NULL, 0, 0) > 0)
  {
    if (!TranslateAccelerator(hWnd, hAccel, &msg)) 
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }
  ExitProcess(0);
}


/*--------------------------------------------------------*\
|  Destroy_Appli
\*--------------------------------------------------------*/
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;

  GetMessage(&msg,NULL,0,0);
  while((msg.message != WM_RBUTTONDOWN && msg.message != WM_LBUTTONDOWN) ||
        ! ( Draw_IsConsoleSubsystem || IsChild(DrawWindow::hWndClientMDI,msg.hwnd)) )
    GetMessage(&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;

  GetMessage(&msg,NULL,0,0);
  while((msg.message != WM_RBUTTONDOWN && msg.message != WM_LBUTTONDOWN &&
        msg.message != WM_MOUSEMOVE) || 
        ! ( Draw_IsConsoleSubsystem || IsChild(DrawWindow::hWndClientMDI,msg.hwnd) ) )
    GetMessage(&msg,NULL,0,0);
  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

Generated by  Doxygen 1.6.0   Back to index