/*   vibwndws.c
* ===========================================================================
*
*                            PUBLIC DOMAIN NOTICE
*            National Center for Biotechnology Information (NCBI)
*
*  This software/database is a "United States Government Work" under the
*  terms of the United States Copyright Act.  It was written as part of
*  the author's official duties as a United States Government employee and
*  thus cannot be copyrighted.  This software/database is freely available
*  to the public for use. The National Library of Medicine and the U.S.
*  Government do not place any restriction on its use or reproduction.
*  We would, however, appreciate having the NCBI and the author cited in
*  any work or product based on this material
*
*  Although all reasonable efforts have been taken to ensure the accuracy
*  and reliability of the software and data, the NLM and the U.S.
*  Government do not and cannot warrant the performance or results that
*  may be obtained by using this software or data. The NLM and the U.S.
*  Government disclaim all warranties, express or implied, including
*  warranties of performance, merchantability or fitness for any particular
*  purpose.
*
* ===========================================================================
*
* File Name:  vibwndws.c
*
* Author:  Jonathan Kans
*
* Version Creation Date:   7/1/91
*
* $Revision: 6.93 $
*
* File Description:
*       Vibrant main, event loop, and window functions
*
* Modifications:
* --------------------------------------------------------------------------
*
* ==========================================================================
*/

#include <vibtypes.h>
#include <vibprocs.h>
#include <vibincld.h>
#include <vibmain.h>

#include <connect/ncbi_core_c.h>

#ifdef WIN_MAC
#ifdef __MWERKS__
#include <Appearance.h>
#include <Navigation.h>
#if __profile__
#include <Profiler.h>
#endif
#include "MoreCarbonAccessors.h"
#endif
#endif

#if defined(WIN_MOTIF) && defined(_DEBUG) && !defined(__hpux)
#include <X11/Xmu/Editres.h>
#endif

#ifdef WIN_X
#include <X11/Xatom.h>
#ifdef OS_AXP_VMS
#include <Xm/StdCmap.h>
#else
#if !defined(__hpux)
#include <X11/Xmu/StdCmap.h>
#endif /* !defined(__hpux) */
#endif
#endif

#ifdef WIN_MAC
/* imported from vibutils.c, not in the header files. rsmith */
extern void Nlm_ConvertFilename ( FSSpec *fss, Nlm_CharPtr filename );
#endif

/* remove this define to remove Quartz/Cocoa cursor handling
   cursor calls will become no-ops if removed */
/*
#define WIN_MAC_QUARTZ_COCOA_CURSORS
*/

#ifdef WIN_MAC_QUARTZ
#ifdef WIN_MAC_QUARTZ_COCOA_CURSORS
/* needed to be able to access a bit of Cocoa */
#include <CoreFoundation/CoreFoundation.h>
char NSApplicationLoad(void);
void *NSClassFromString(CFStringRef aClassName);
void *NSSelectorFromString(CFStringRef aSelectorName);
void *objc_msgSend(void *self, void *_cmd, ...);
#endif
#endif

#ifdef WIN_MAC
#ifndef Nlm_WindowTool
#define Nlm_WindowTool  WindowPtr
#endif
#ifndef Nlm_PortTool
#define Nlm_PortTool    GrafPtr
#endif
#ifndef Nlm_ShellTool
#define Nlm_ShellTool   Nlm_Handle
#endif
#ifndef Nlm_MainTool
#define Nlm_MainTool    Nlm_Handle
#endif
#endif

#ifdef WIN_MSWIN
#ifndef Nlm_WindowTool
#define Nlm_WindowTool  HWND
#endif
#ifndef Nlm_PortTool
#define Nlm_PortTool    HDC
#endif
#ifndef Nlm_ShellTool
#define Nlm_ShellTool   Nlm_Handle
#endif
#ifndef Nlm_MainTool
#define Nlm_MainTool    Nlm_Handle
#endif
#endif

#ifdef WIN_MOTIF
#ifndef Nlm_WindowTool
#define Nlm_WindowTool  Widget
#endif
#ifndef Nlm_PortTool
#define Nlm_PortTool    GC
#endif
#ifndef Nlm_ShellTool
#define Nlm_ShellTool   Widget
#endif
#ifndef Nlm_MainTool
#define Nlm_MainTool    Widget
#endif
#endif

typedef enum {
  USE_FULL_SCREEN = 1,
  USE_LEFT_SCREEN,
  USE_RIGHT_SCREEN,
  USE_PRIMARY_MONITOR
} Nlm_ScreenMode;

static Nlm_ScreenMode Nlm_screenMode = USE_FULL_SCREEN;

typedef  struct  Nlm_shelldata {
  struct Nlm_shelldata PNTR next;
  Nlm_ShellTool             shell;
} Nlm_ShellData, PNTR Nlm_ShellDataPtr;

typedef  struct  Nlm_windowdata {
  Nlm_WindowTool   handle;
  Nlm_ShellTool    shell;
  Nlm_PortTool     port;
  Nlm_MainTool     main;
  Nlm_ColorMTool   cMap;
  Nlm_ShellDataPtr allShells;
  Nlm_Int2         cMapStatus;
  Nlm_RecT         dragArea;
  Nlm_RecT         growArea;
  Nlm_RecT         zoomArea;
  Nlm_WndActnProc  close;
  Nlm_WndActnProc  activate;
  Nlm_WndActnProc  deactivate;
  Nlm_WndActnProc  resize;
  Nlm_DisplaY      charDisplay;
  Nlm_MenuBaR      menuBar;
  Nlm_ButtoN       defaultButton;
  Nlm_Boolean      notYetShown;
  Nlm_Boolean      dying;
  Nlm_CharPtr      title;
  Nlm_VoidPtr      data;
  Nlm_WndFreeProc  cleanup;
  Nlm_WndActnProc  timer;
  Nlm_WindoW       modalOwner; /* esl++ to support nested modal dialogs */
  Nlm_ScreenMode   screenMode;
#ifdef WIN_MOTIF
  Visual      *visual;
  Nlm_Boolean cMap_fixed;
#endif
#ifdef WIN_MSWIN
  Nlm_Uint4        style;
  Nlm_Uint4        ex_style;
  Nlm_Handle       haccel;
#endif
} Nlm_WindowData;

typedef  struct  Nlm_windowrec {
  Nlm_BoxRec      boxR;
  Nlm_WindowData  window;
} Nlm_WindowRec, PNTR Nlm_WndPtr;

Nlm_WindoW   Nlm_desktopWindow;
Nlm_WindoW   Nlm_systemWindow;

Nlm_RecT     Nlm_screenRect;

Nlm_WindoW   Nlm_theWindow;

extern Nlm_Boolean okayToDrawContents;
Nlm_Boolean okayToDrawContents = TRUE; /* set to false by CleanUpWindows */

extern Nlm_Boolean Nlm_usesMacNavServices;
Nlm_Boolean Nlm_usesMacNavServices = FALSE;

#ifdef WIN_MAC
EventRecord  Nlm_currentEvent;
#ifdef WIN_MAC_QUARTZ
static void Nlm_DrawWindow (Nlm_GraphiC w, Nlm_Boolean drawGrowIcon);
#endif
#ifdef __CONDITIONALMACROS__
/* Global RoutineDescriptors - from RasMol */
AEEventHandlerUPP HandleAEIgnorePtr;
AEEventHandlerUPP HandleAEOpenDocPtr;
AEEventHandlerUPP HandleAEQuitAppPtr;
AEEventHandlerUPP HandleAEAnswerPtr;
#endif
typedef SInt32 AERefCon;
/* typedef UInt32 AERefCon; */
#endif

#ifdef WIN_MSWIN
WPARAM       Nlm_currentWParam;
HINSTANCE    Nlm_currentHInst;
LPARAM       Nlm_currentLParam;
MSG          Nlm_currentMssg;
int          Nlm_currentId;
HWND         Nlm_currentHwndCtl;
UINT         Nlm_currentCode;
int          Nlm_currentPos;
#endif

#ifdef WIN_MOTIF
XEvent        Nlm_currentEvent;
XtAppContext  Nlm_appContext;
XmFontList    Nlm_XfontList;
Widget        Nlm_fileDialogShell;

static const char Nlm_VibName[]            = "vibrant";
static const char Nlm_VibClass[]           = "Vibrant";
static       char Nlm_AppName[PATH_MAX+1]  = "vibrant";
#endif

Nlm_WindowTool  Nlm_currentWindowTool;
Nlm_Boolean     Nlm_processUpdatesFirstVal = TRUE;

static Nlm_Boolean     Nlm_showGetArgTag = TRUE;

static Nlm_GphPrcsPtr  gphprcsptr = NULL;

static Nlm_GphPrcsPtr  documentProcs;
static Nlm_GphPrcsPtr  fixedProcs;
static Nlm_GphPrcsPtr  frozenProcs;
static Nlm_GphPrcsPtr  roundProcs;
static Nlm_GphPrcsPtr  alertProcs;
static Nlm_GphPrcsPtr  modalProcs;
static Nlm_GphPrcsPtr  movableModalProcs;
static Nlm_GphPrcsPtr  floatingProcs;
static Nlm_GphPrcsPtr  shadowProcs;
static Nlm_GphPrcsPtr  plainProcs;
static Nlm_GphPrcsPtr  desktopProcs;
static Nlm_GphPrcsPtr  systemProcs;

static Nlm_Boolean     quitProgram;
static Nlm_Boolean     getArgsBoxUp;
static Nlm_Boolean     getArgsOk;

static Nlm_WindoW      recentWindow = NULL;
static Nlm_WindowData  recentWindowData;

#ifdef WIN_MAC
static Nlm_WindoW      chosenWindow;
static Nlm_WindoW      frontWindow;
static Nlm_WindoW      theActiveWindow;
#endif

static Nlm_WindoW      dyingWindow;
static Nlm_RecT        screenBitBounds;

/*
#ifndef WIN_MOTIF
static Nlm_Boolean     inNotice;
#endif
*/

static Nlm_VoidProc    timerAction = NULL;
static Nlm_KeyProc     keyAction = NULL;
static Nlm_ClckProc    mouseMovedAction = NULL;

static Nlm_WndActnProc  appWndAct = NULL;
static Nlm_WndActnProc  appWndDeact = NULL;

static Nlm_DropProc        registeredDropProc = NULL;
static Nlm_ServiceProc  registeredServiceProc = NULL;
static Nlm_ResultProc   registeredResultProc = NULL;

#ifdef WIN_MAC
static Cursor       cross;
static Cursor       iBeam;
static Cursor       plus;
static Cursor       watch;
static Nlm_Int4     lastTimerTime;
static Nlm_Boolean  hasColorQD = FALSE;
#endif

#ifdef WIN_MSWIN
HCURSOR       Nlm_currentCursor;
static UINT          timerID;
static Nlm_Char      windowclass [32];
static int           discard_count = 0;
static Nlm_Boolean   handlechar;
BOOLEAN Nlm_hasBackColor = FALSE;
COLORREF Nlm_crBackColor = 0;
HBRUSH Nlm_hbrWindowBackground = NULL;
#endif

#ifdef WIN_MOTIF
Cursor        Nlm_currentCursor;
static Cursor        arrow;
static Cursor        cross;
static Cursor        iBeam;
static Cursor        plus;
static Cursor        watch;
static XFontStruct   *font;
static XtIntervalId  windowTimer;
static Widget        selectShell;
#endif

#ifdef WIN_MOTIF
#ifdef MISSING_X_SYMBOLS_BUG
int get_wmShellWidgetClass (void)

{
}

int get_applicationShellWidgetClass (void)

{
}

int XShapeCombineMask (void)

{
}
#endif
#endif

static void Nlm_LoadWindowData (Nlm_WindoW w, Nlm_WindowTool hdl,
                                Nlm_ShellTool shl, Nlm_PortTool prt,
                                Nlm_MainTool man, Nlm_RectPtr drag,
                                Nlm_RectPtr grow, Nlm_RectPtr zoom,
                                Nlm_WndActnProc closeProc, Nlm_WndActnProc actProc,
                                Nlm_WndActnProc deactProc, Nlm_WndActnProc resiz,
                                Nlm_DisplaY charDisp, Nlm_MenuBaR mnuBar,
                                Nlm_ButtoN dfltBtn, Nlm_Boolean notYet,
                                Nlm_Boolean die, Nlm_CharPtr ttl,
                                Nlm_VoidPtr dat, Nlm_WndFreeProc cln,
                                Nlm_WndActnProc tmr)

{
  Nlm_WindowData  PNTR wdptr;
  Nlm_WndPtr      wp;

  if (w != NULL) {
    wp = (Nlm_WndPtr) Nlm_HandLock (w);
    wdptr = &(wp->window);
    wdptr->handle = hdl;
    wdptr->shell = shl;
    wdptr->port = prt;
    wdptr->main = man;
    if (drag != NULL) {
      wdptr->dragArea = *drag;
    } else {
      Nlm_LoadRect (&(wdptr->dragArea), 0, 0, 0, 0);
    }
    if (grow != NULL) {
      wdptr->growArea = *grow;
    } else {
      Nlm_LoadRect (&(wdptr->growArea), 0, 0, 0, 0);
    }
    if (zoom != NULL) {
      wdptr->zoomArea = *zoom;
    } else {
      Nlm_LoadRect (&(wdptr->zoomArea), 0, 0, 0, 0);
    }
    wdptr->close = closeProc;
    wdptr->activate = actProc;
    wdptr->deactivate = deactProc;
    wdptr->resize = resiz;
    wdptr->charDisplay = charDisp;
    wdptr->menuBar = mnuBar;
    wdptr->defaultButton = dfltBtn;
    wdptr->notYetShown = notYet;
    wdptr->dying = die;
    wdptr->title = ttl;
    wdptr->data = dat;
    wdptr->cleanup = cln;
    wdptr->timer = tmr;
    wdptr->modalOwner = NULL; /* esl++ */
    wdptr->screenMode = Nlm_screenMode; /* jk */
#ifdef WIN_MOTIF
    wdptr->visual = NULL;
    wdptr->cMap_fixed = FALSE;
#endif
    Nlm_HandUnlock (w);
    recentWindow = NULL;
  }
}

static void Nlm_SetWindowData (Nlm_WindoW w, Nlm_WindowData * wdata)

{
  Nlm_WndPtr  wp;

  if (w != NULL && wdata != NULL) {
    wp = (Nlm_WndPtr) Nlm_HandLock (w);
    wp->window = *wdata;
    Nlm_HandUnlock (w);
    recentWindow = w;
    recentWindowData = *wdata;
  }
}

static void Nlm_GetWindowData (Nlm_WindoW w, Nlm_WindowData * wdata)

{
  Nlm_WndPtr  wp;

  if (w != NULL && wdata != NULL) {
    if (w == recentWindow && NLM_RISKY) {
      *wdata = recentWindowData;
    } else {
      wp = (Nlm_WndPtr) Nlm_HandLock (w);
      *wdata = wp->window;
      Nlm_HandUnlock (w);
      recentWindow = w;
      recentWindowData = *wdata;
    }
  }
}

static Nlm_WindowTool Nlm_GetWindowPtr (Nlm_WindoW w)

{
  Nlm_WindowTool  rsult;
  Nlm_WindowData  wdata;

  rsult = (Nlm_WindowTool) 0;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = wdata.handle;
  }
  return rsult;
}

extern Nlm_ShellTool Nlm_GetWindowShell (Nlm_WindoW w)

{
  Nlm_ShellTool   rsult;
  Nlm_WindowData  wdata;

  rsult = (Nlm_ShellTool) 0;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = wdata.shell;
  }
  return rsult;
}


extern void Nlm_AddSubwindowShell (Nlm_WindoW w, Nlm_ShellTool shell );
extern void Nlm_AddSubwindowShell (Nlm_WindoW w, Nlm_ShellTool shell )
{
  Nlm_WindowData   wdata;
  Nlm_ShellDataPtr sptr;

  sptr = (Nlm_ShellDataPtr)MemNew( sizeof(Nlm_ShellData) );
  sptr->shell = shell;

  Nlm_GetWindowData(w, &wdata);
  sptr->next = wdata.allShells;
  wdata.allShells = sptr;
  Nlm_SetWindowData(w, &wdata);
}


extern void Nlm_DelSubwindowShell (Nlm_WindoW w, Nlm_ShellTool shell );
extern void Nlm_DelSubwindowShell (Nlm_WindoW w, Nlm_ShellTool shell )
{
  Nlm_WindowData   wdata;
  Nlm_ShellDataPtr sptr;
  Nlm_ShellDataPtr sPrevptr = NULL;

  Nlm_GetWindowData(w, &wdata);
  for (sptr = wdata.allShells;
       sptr != NULL  &&  sptr->shell != shell;
       sPrevptr = sptr, sptr = sptr->next) continue;
  if (sptr == NULL)
    return;

  if (sPrevptr == NULL)
    wdata.allShells = sptr->next;
  else
    sPrevptr->next = sptr->next;

  MemFree( sptr );
  Nlm_SetWindowData(w, &wdata);
}


static Nlm_PortTool Nlm_GetWindowPort (Nlm_WindoW w)

{
  Nlm_PortTool    rsult;
  Nlm_WindowData  wdata;

  rsult = NULL;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = wdata.port;
  }
  return rsult;
}

static Nlm_MainTool Nlm_GetWindowMain (Nlm_WindoW w)

{
  Nlm_MainTool    rsult;
  Nlm_WindowData  wdata;

  rsult = (Nlm_MainTool) 0;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = wdata.main;
  }
  return rsult;
}

extern void Nlm_SetWindowCharDisplay (Nlm_WindoW w, Nlm_DisplaY d)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.charDisplay = d;
    Nlm_SetWindowData (w, &wdata);
  }
}

extern Nlm_DisplaY Nlm_GetWindowCharDisplay (Nlm_WindoW w)

{
  Nlm_DisplaY     rsult;
  Nlm_WindowData  wdata;

  rsult = NULL;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = wdata.charDisplay;
  }
  return rsult;
}

extern void Nlm_SetWindowMenuBar (Nlm_WindoW w, Nlm_MenuBaR mb)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.menuBar = mb;
    Nlm_SetWindowData (w, &wdata);
  }
}

extern Nlm_MenuBaR Nlm_GetWindowMenuBar (Nlm_WindoW w)

{
  Nlm_MenuBaR     rsult;
  Nlm_WindowData  wdata;

  rsult = NULL;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = wdata.menuBar;
  }
  return rsult;
}

extern void Nlm_SetButtonDefault (Nlm_ButtoN b, Nlm_Boolean dflt);
extern void Nlm_SetWindowDefaultButton (Nlm_WindoW w, Nlm_ButtoN b)
{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    if (wdata.defaultButton != NULL)
      Nlm_SetButtonDefault(wdata.defaultButton, FALSE);
    wdata.defaultButton = b;
    if (wdata.defaultButton != NULL)
      Nlm_SetButtonDefault(wdata.defaultButton, TRUE);
    Nlm_SetWindowData (w, &wdata);
  }
}

extern Nlm_ButtoN Nlm_GetWindowDefaultButton (Nlm_WindoW w)

{
  Nlm_ButtoN      rsult;
  Nlm_WindowData  wdata;

  rsult = NULL;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = wdata.defaultButton;
  }
  return rsult;
}

static void Nlm_SetNotYetShown (Nlm_WindoW w, Nlm_Boolean notYet)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.notYetShown = notYet;
    Nlm_SetWindowData (w, &wdata);
  }
}

extern Nlm_Boolean Nlm_WindowHasBeenShown (Nlm_WindoW w)

{
  Nlm_Boolean     rsult;
  Nlm_WindowData  wdata;

  rsult = FALSE;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = (Nlm_Boolean) (! wdata.notYetShown);
  }
  return rsult;
}

static void Nlm_SetWindowDying (Nlm_WindoW w, Nlm_Boolean die)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.dying = die;
    Nlm_SetWindowData (w, &wdata);
  }
}

extern Nlm_Boolean Nlm_IsWindowDying (Nlm_WindoW w)

{
  Nlm_Boolean     rsult;
  Nlm_WindowData  wdata;

  rsult = FALSE;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = wdata.dying;
  }
  return rsult;
}

/*
static void Nlm_SetScreenMode (Nlm_WindoW w, Nlm_ScreenMode screenMode)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.screenMode = screenMode;
    Nlm_SetWindowData (w, &wdata);
  }
}
*/

static Nlm_ScreenMode Nlm_GetScreenMode (Nlm_WindoW w)

{
  Nlm_ScreenMode  rsult;
  Nlm_WindowData  wdata;

  rsult = USE_FULL_SCREEN;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = wdata.screenMode;
  }
  return rsult;
}

extern Nlm_WindoW Nlm_GetParentWindow (Nlm_GraphiC a)

{
  Nlm_GraphiC  g;
  Nlm_GraphiC  p;

  g = a;
  if (a != NULL) {
    p = Nlm_GetParent (g);
    while (p != NULL) {
      g = p;
      p = Nlm_GetParent (g);
    }
  }
  return (Nlm_WindoW) g;
}

extern Nlm_WindoW Nlm_ParentWindow (Nlm_Handle a)

{
  return Nlm_GetParentWindow ((Nlm_GraphiC) a);
}

extern Nlm_WindowTool Nlm_ParentWindowPtr (Nlm_GraphiC a)

{
  Nlm_WindowTool  rsult;
  Nlm_WindoW      w;

  rsult = (Nlm_WindowTool) 0;
  if (a != NULL) {
    w = Nlm_GetParentWindow (a);
    rsult = Nlm_GetWindowPtr (w);
  }
  return rsult;
}

extern Nlm_PortTool Nlm_ParentWindowPort (Nlm_GraphiC a)

{
  Nlm_PortTool  rsult;
  Nlm_WindoW    w;

  rsult = NULL;
  if (a != NULL) {
    w = Nlm_GetParentWindow (a);
    rsult = Nlm_GetWindowPort (w);
  }
  return rsult;
}

extern Nlm_MainTool Nlm_ParentWindowMain (Nlm_GraphiC a)

{
  Nlm_MainTool  rsult;
  Nlm_WindoW    w;

  rsult = (Nlm_MainTool) 0;
  if (a != NULL) {
    w = Nlm_GetParentWindow (a);
    rsult = Nlm_GetWindowMain (w);
  }
  return rsult;
}

extern Nlm_ShellTool Nlm_ParentWindowShell (Nlm_GraphiC a)

{
  Nlm_ShellTool  rsult;
  Nlm_WindoW     w;

  rsult = (Nlm_ShellTool) 0;
  if (a != NULL) {
    w = Nlm_GetParentWindow (a);
    rsult = Nlm_GetWindowShell (w);
  }
  return rsult;
}

extern Nlm_WindoW Nlm_SavePortIfNeeded (Nlm_GraphiC a, Nlm_Boolean savePort)

{
  Nlm_WindoW  newwindow;
  Nlm_WindoW  oldwindow;
  Nlm_WindoW  rsult;

  rsult = NULL;
  if (a != NULL && savePort) {
    savePort = Nlm_GetAllParentsVisible (a);
    if (savePort) {
      oldwindow = Nlm_CurrentWindow ();
      newwindow = Nlm_GetParentWindow (a);
      savePort = (Nlm_Boolean) (oldwindow != newwindow);
      if (savePort) {
        Nlm_UseWindow (newwindow);
        rsult = oldwindow;
      }
    }
  }
  return rsult;
}

extern Nlm_WindoW Nlm_SavePort (Nlm_Handle a)

{
  return Nlm_SavePortIfNeeded ((Nlm_GraphiC) a, TRUE);
}

extern void Nlm_RestorePort (Nlm_WindoW w)

{
  if (Nlm_processUpdatesFirstVal) {
    Nlm_Update ();
  }
  if (w != NULL) {
    Nlm_UseWindow (w);
  }
}

extern void Nlm_SetClose (Nlm_WindoW w, Nlm_WndActnProc cls)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.close = cls;
    Nlm_SetWindowData (w, &wdata);
  }
}

extern void Nlm_SetActivate (Nlm_WindoW w, Nlm_WndActnProc act)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.activate = act;
    Nlm_SetWindowData (w, &wdata);
  } else {
    appWndAct = act;
  }
}

extern void Nlm_SetDeactivate (Nlm_WindoW w, Nlm_WndActnProc deact)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.deactivate = deact;
    Nlm_SetWindowData (w, &wdata);
  } else {
    appWndDeact = deact;
  }
}

/*
 * Test X windows to see what kind of color buffer is available.
 * Necessary because Linux supports only the type available
 * from the hardware.  Returns TRUE if match and visinfo.
 */

#ifdef WIN_MOTIF

typedef struct _TNlm_MatchListX {
    int class;
    unsigned int depth;
} TNlm_MatchListX;

#define XMATCHLENGTH 6

/* list of display classes and depths to match, in order.
 * we prefer 8 bit for Cn3D for speed. 
 */
static const TNlm_MatchListX Nlm_MatchListX[] = { 
    { PseudoColor, 8  },
    { GrayScale, 8 },
    { PseudoColor, 16 },
    { TrueColor, 24 },
    { GrayScale, 16 },
    { TrueColor, 16 } };
    
extern Nlm_Boolean Nlm_CheckX(XVisualInfo * visinfo)
{
    int visualsmatched, i, j, defaultdepth;
    XVisualInfo *VisualList, VisualTemplate;
    
    /* check display modes in order of preference */
    
    VisualTemplate.screen = DefaultScreen(Nlm_currentXDisplay);
    
    /* enforce vibrant convention of using default depth for windows */
    defaultdepth = DefaultDepth(Nlm_currentXDisplay, VisualTemplate.screen);
    
    VisualList = XGetVisualInfo(Nlm_currentXDisplay, VisualScreenMask,
            &VisualTemplate, &visualsmatched);
    
    for(j = 0; j < XMATCHLENGTH; j++) {
        for(i = 0; i < visualsmatched; i++) {
         if (VisualList[i].depth == Nlm_MatchListX[j].depth 
                 && VisualList[i].class == Nlm_MatchListX[j].class
                 && VisualList[i].depth == defaultdepth) {
                MemCpy(visinfo, &VisualList[i], sizeof(XVisualInfo));
                XFree(VisualList);
                return TRUE;
            }
        }
    }
    return FALSE;
}
#endif /* WIN_MOTIF */

extern void Nlm_SetResize (Nlm_WindoW w, Nlm_WndActnProc resiz)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.resize = resiz;
    Nlm_SetWindowData (w, &wdata);
  }
}

extern void Nlm_SetColorMap (Nlm_WindoW w, Nlm_Uint2 totalColors,
                             Nlm_Uint1Ptr red, Nlm_Uint1Ptr green,
                             Nlm_Uint1Ptr blue)
{
  Nlm_WindowData  wdata;

#ifdef WIN_MSWIN
  Nlm_Uint2       i;
  LOGPALETTE    * palette;
  PALETTEENTRY  * p;
#endif
#ifdef WIN_MAC
  Nlm_Int2        i;
  RGBColor        col;
#endif


  if (w == NULL  ||  totalColors > 256)
    return;

  Nlm_GetWindowData (w, &wdata);

#ifdef WIN_MSWIN
  if ( GetDeviceCaps (Nlm_currentHDC, RASTERCAPS) &  RC_PALETTE ){
    if ( wdata.cMap != NULL ){
      DeleteObject( wdata.cMap );
      wdata.cMap = NULL;
    }
    if ( totalColors!=0 ) {
      palette = (LOGPALETTE*)MemNew (sizeof(LOGPALETTE) +
                                     totalColors*sizeof(PALETTEENTRY));
      if ( palette != NULL ) {
        palette->palVersion = 0x300;
        palette->palNumEntries = totalColors;
        for( i=0; i<totalColors; i++ ) {
          p = &(palette->palPalEntry[i]);
          p->peFlags = (BYTE)((i != 0) ? 0 : PC_RESERVED);
          p->peRed   = red[i];
          p->peGreen = green[i];
          p->peBlue  = blue[i];
        }
        wdata.cMap = CreatePalette(palette);
        MemFree (palette);
        if ( wdata.cMap != NULL ) {
          SelectPalette ( Nlm_currentHDC,wdata.cMap,FALSE );
          RealizePalette ( Nlm_currentHDC );

        }
      }
    }
  }
#endif

#ifdef WIN_MAC
// QUARTZ_FIXME: there's no replacement for this in CG, does anything
// need to be done?
#ifndef WIN_MAC_QUARTZ
  if ( wdata.cMap != NULL ){
    if ( wdata.cMapStatus ){
      SetPalette( wdata.handle, NULL, FALSE);
    }
    DisposePalette ( wdata.cMap );
    wdata.cMap = NULL;
  }
  wdata.cMapStatus = 0;
  if ( totalColors!=0 ) {
    wdata.cMap = NewPalette(totalColors,(CTabHandle)0,pmTolerant,0);
    if ( wdata.cMap != NULL ) {
      for( i=0; i<totalColors; i++ ) {
        col.red   = (Nlm_Uint2)red[i]<<8 | (Nlm_Uint2)red[i];
        col.green = (Nlm_Uint2)green[i]<<8 | (Nlm_Uint2)green[i];
        col.blue  = (Nlm_Uint2)blue[i]<<8 | (Nlm_Uint2)blue[i];
        SetEntryColor(wdata.cMap,i,&col);
      }
      SetPalette( wdata.handle, wdata.cMap, FALSE);
      ActivatePalette ( wdata.handle );
      wdata.cMapStatus = 1;
    }
  }
#endif
#endif

#ifdef WIN_MOTIF
  do { /* TRY */
    unsigned long  pixel;
    int            n_savedColors = 0;
    XColor         colorCells[256];

    /* Uninstall, store first several colors and free current
     * colormap -- if necessary */ 
    if ( wdata.cMap )
      {
        n_savedColors = 32;
        if (n_savedColors > (int)totalColors)
          return;

        if ( wdata.cMapStatus )
          {
            XUninstallColormap(Nlm_currentXDisplay, wdata.cMap);
            wdata.cMapStatus = 0;
          }

        if ( !wdata.cMap_fixed )
          {
            if (totalColors != 0)
              {            
                for (pixel = 0;  pixel < n_savedColors;  pixel++)
                  colorCells[pixel].pixel = pixel;
                XQueryColors(Nlm_currentXDisplay, wdata.cMap,
                             colorCells, n_savedColors);
              }

            XFreeColormap(Nlm_currentXDisplay, wdata.cMap);
            wdata.cMap = (Nlm_ColorMTool) 0;
          }
      }

    if (totalColors == 0)
      break;    /* no colors specified for the new colormap */

    /* Create new colormap, if necessary */
    if ( !wdata.cMap )
      {
        XVisualInfo    visinfo;
        unsigned long  plane_m[1];
        unsigned long  pixels[256];
        int defaultdepth;

        defaultdepth = DefaultDepth(Nlm_currentXDisplay,
                  DefaultScreen(Nlm_currentXDisplay));
#ifdef OS_UNIX_LINUX
        if(!Nlm_CheckX(&visinfo))
#else /* OS_UNIX_LINUX */
        if( !(XMatchVisualInfo(Nlm_currentXDisplay,
                         DefaultScreen(Nlm_currentXDisplay),
                         8,PseudoColor,&visinfo) ||
            XMatchVisualInfo(Nlm_currentXDisplay,
                         DefaultScreen(Nlm_currentXDisplay),
                         8,GrayScale,&visinfo)) )
#endif /* else OS_UNIX_LINUX */      
        break;  /* no matching visuals found */
          
#ifdef OS_UNIX_LINUX
        if(visinfo.class > PseudoColor) break;  /* no palette needed */  
#endif
        wdata.cMap = XCreateColormap(Nlm_currentXDisplay,
                                     RootWindow(Nlm_currentXDisplay,
                                                Nlm_currentXScreen),
                                     visinfo.visual, AllocNone);
        if (wdata.cMap == DefaultColormap(Nlm_currentXDisplay,
                                          Nlm_currentXScreen))
          {
            wdata.cMap = (Nlm_ColorMTool) 0;
            break;  /* hardware colormap is immutable */
          }

        if ( !XAllocColorCells ( Nlm_currentXDisplay, wdata.cMap, FALSE,
                                 (unsigned long*) plane_m, 0,
                                 (unsigned long*) pixels, totalColors) )
          {
            XFreeColormap (Nlm_currentXDisplay,wdata.cMap);
            wdata.cMap = (Nlm_ColorMTool) 0;
            break;  /* cannot allocate color cells for the new colormap */
          }
      }

    for (pixel = n_savedColors;  pixel < totalColors;  pixel++)
      {
        colorCells[pixel].red   = (((Nlm_Uint2)red  [pixel]) << 8) |
          (Nlm_Uint2)red  [pixel];
        colorCells[pixel].green = (((Nlm_Uint2)green[pixel]) << 8) |
          (Nlm_Uint2)green[pixel];
        colorCells[pixel].blue  = (((Nlm_Uint2)blue [pixel]) << 8) |
          (Nlm_Uint2)blue [pixel];
        
        colorCells[pixel].flags = DoRed | DoGreen | DoBlue;
        colorCells[pixel].pixel = pixel;
        colorCells[pixel].pad = 0;
      }
    XStoreColors(Nlm_currentXDisplay, wdata.cMap,
                 colorCells + n_savedColors,
                 (int)(pixel - n_savedColors));

    XInstallColormap(Nlm_currentXDisplay, wdata.cMap);
    XSetWindowColormap (Nlm_currentXDisplay, XtWindow( wdata.shell ),
                        wdata.cMap);
    {{
      Nlm_ShellDataPtr sptr = wdata.allShells;
      while (sptr != NULL)
        {
          XSetWindowColormap (Nlm_currentXDisplay, XtWindow( sptr->shell ),
                              wdata.cMap);
          sptr = sptr->next;
        }
    }}

    wdata.cMapStatus = 1;
  }  while ( 0 );
#endif

  Nlm_SetWindowData (w, &wdata);
}


extern void Nlm_SetColorCell(Nlm_GraphiC gr, Nlm_Uint1 pixel,
                             Nlm_Uint1 red, Nlm_Uint1 green, Nlm_Uint1 blue)
{
#ifdef WIN_MOTIF
  Colormap cMap;
  XColor colorCell;

  /* get colormap, if fixed */
  if ( !Nlm_GetFixedColormap(gr, &cMap, NULL) )
    return;

  /* compose and store the new color cell */
  colorCell.red   = ((Nlm_Uint2)red   << 8) | (Nlm_Uint2)red;
  colorCell.green = ((Nlm_Uint2)green << 8) | (Nlm_Uint2)green;
  colorCell.blue  = ((Nlm_Uint2)blue  << 8) | (Nlm_Uint2)blue;
  colorCell.flags = DoRed | DoGreen | DoBlue;
  colorCell.pixel = pixel;
  colorCell.pad   = 0;
  XStoreColor(Nlm_currentXDisplay, cMap, &colorCell);
#endif

#ifdef WIN_MSWIN_obsolete
  Nlm_WindowData  wdata;
  PALETTEENTRY    colorCell;
  Nlm_WindoW      w = Nlm_GetParentWindow( gr );     

  if (w == NULL  ||
      (GetDeviceCaps(Nlm_currentHDC, RASTERCAPS) &  RC_PALETTE) == 0)
    return;

  Nlm_GetWindowData (w, &wdata);
  if (wdata.cMap == NULL)
    return;
    
  colorCell.peFlags = PC_RESERVED;
  colorCell.peRed   = red;
  colorCell.peGreen = green;
  colorCell.peBlue  = blue;

  AnimatePalette(wdata.cMap, pixel, 1, &colorCell);
#endif

#if defined(WIN_MAC)  || defined(WIN_MSWIN)
  Nlm_InvalObject ((Nlm_Handle) gr);
#endif
}



#ifdef WIN_MOTIF
static Nlm_CharPtr resource_nm = NULL;
extern void Nlm_SetMotifWindowName (Nlm_CharPtr nm)
{
  resource_nm = (Nlm_CharPtr) Nlm_MemFree (resource_nm);
  if (nm != NULL && *nm != '\0') {
    resource_nm = StringSave (nm);
  }
}

static Nlm_Uchar motif_n_colorcells = (Nlm_Uchar)0;

extern void Nlm_RestrictMotifColorsTo (Nlm_Uchar n_colorcells)
{
  motif_n_colorcells = n_colorcells;
}

extern Nlm_Boolean Nlm_GetFixedColormap(Nlm_GraphiC w,
                                        Colormap *cMap, Visual **visual)
{
  Nlm_WindowData wdata;
  Nlm_GetWindowData(Nlm_ParentWindow( w ), &wdata);
  if ( !wdata.cMap_fixed )
    return FALSE;

  if ( cMap )
    *cMap = wdata.cMap;
  if ( visual )
    *visual = wdata.visual;

  return TRUE;
}

static Nlm_Boolean Nlm_BusyColormap(unsigned long fromColor,
                                    unsigned long toColor,
                                    Colormap *cMap,
                                    Visual  **visual,
                                    int      *depth)
{
#define MAX_toColor 256
#define N_DEF_COL   2
  unsigned long nInherit = N_DEF_COL;

  if (!Nlm_hasColor  ||
      fromColor < N_DEF_COL  || fromColor > toColor  || toColor > MAX_toColor)
    return FALSE;

  if (fromColor == toColor)
    { /* Special case:  create new colormap and inherit
         first "toColor" color from the system colormap */
      nInherit = toColor;
    }

  {{ /* Create new colormap, if possible */
    XVisualInfo visinfo;
    Window      rootwin = RootWindow(Nlm_currentXDisplay, Nlm_currentXScreen);
    if ( !XMatchVisualInfo(Nlm_currentXDisplay,Nlm_currentXScreen,
                           8,PseudoColor,&visinfo)  &&
         !XMatchVisualInfo(Nlm_currentXDisplay,Nlm_currentXScreen,
                           8,GrayScale,&visinfo) )
      return FALSE;

    *cMap = XCreateColormap(Nlm_currentXDisplay, rootwin, visinfo.visual,
                            AllocNone);
    if ( visual )
      *visual = visinfo.visual;
    if ( depth )
      *depth = 8;
  }}

  {{ /* Allocate colors */
    unsigned long  plane_m;
    unsigned long  pixels[MAX_toColor];
    if ( !XAllocColorCells(Nlm_currentXDisplay, *cMap,
                           FALSE, &plane_m, 0, pixels, toColor) )
      {
        if (*cMap != DefaultColormap(Nlm_currentXDisplay,
                                     Nlm_currentXScreen) )
          XFreeColormap(Nlm_currentXDisplay, *cMap);
        return FALSE;
      }
  }}

  {{ /* Inherit first "nInherit" colors from the system default colormap */
    XColor defColors[MAX_toColor];
    unsigned long pixel;
    for (pixel = 0;  pixel < nInherit;  pixel++)
      defColors[pixel].pixel = pixel;
    XQueryColors(Nlm_currentXDisplay,
                 DefaultColormap(Nlm_currentXDisplay, Nlm_currentXScreen),
                 defColors, nInherit);
    XStoreColors(Nlm_currentXDisplay, *cMap, defColors, nInherit);
  }}

  {{ /* Free first "fromColor" but the very first "N_DEF_COL" colorcells */
    unsigned long pixel;
    unsigned long pixels[256];
    for(pixel = nInherit;  pixel < fromColor;  pixel++)
      {
        pixels[pixel-nInherit] = pixel;
      }
    XFreeColors(Nlm_currentXDisplay, *cMap, pixels, fromColor-nInherit, 0);
  }}

  return TRUE;
}


static Boolean Nlm_XGetRGBColormap(VisualID visualid, XStandardColormap *xcmap)
{ /* Look for an already existing XA_RGB_DEFAULT_MAP */
    XStandardColormap *xcmaps;
    int i, n_xcmaps;
    if ( !XGetRGBColormaps(Nlm_currentXDisplay,
                           RootWindow(Nlm_currentXDisplay,
                                      Nlm_currentXScreen),
                           &xcmaps, &n_xcmaps, XA_RGB_DEFAULT_MAP))
      return FALSE;

    for (i = 0;  i < n_xcmaps  &&  xcmaps[i].visualid != visualid;  i++);
    if (i == n_xcmaps  ||  !xcmaps[i].red_max  ||  !xcmaps [i].visualid)
      return FALSE;

    *xcmap = xcmaps[i];
    XFree( xcmaps );
    return TRUE;
}


static XStandardColormap Nlm_stdColormapRGB;
static Boolean           Nlm_stdGrayScale = False;

static Boolean Nlm_StandardColormap(Colormap *cMap,
                                    Visual **visual, int *depth)
{ /* Try use the XA_RGB_DEFAULT_MAP standard colormap of 8-bit depth */
  XVisualInfo visinfo;

  ASSERT ( !Nlm_stdColormapRGB.visualid );

  /* The relevant 8-bit visual */
  if ( !XMatchVisualInfo(Nlm_currentXDisplay, Nlm_currentXScreen,
                        8, PseudoColor, &visinfo) )
    {
      if ( !XMatchVisualInfo(Nlm_currentXDisplay, Nlm_currentXScreen,
                             8, GrayScale, &visinfo) )
        return FALSE;
      Nlm_stdGrayScale = True;
    }

  /* Use already existing or create new default standard colormap*/
  if (Nlm_XGetRGBColormap(visinfo.visualid, &Nlm_stdColormapRGB)  ||
      (XmuLookupStandardColormap(Nlm_currentXDisplay, Nlm_currentXScreen,
                                 visinfo.visualid, visinfo.depth,
                                 XA_RGB_DEFAULT_MAP, False, True)  &&
       Nlm_XGetRGBColormap(visinfo.visualid, &Nlm_stdColormapRGB)))
    {
      *cMap = Nlm_stdColormapRGB.colormap;
      if ( visual )
        *visual = visinfo.visual;
      if ( depth )
        *depth = visinfo.depth;
      return TRUE;
    }

  return FALSE;
}


static Boolean Nlm_XrmGetResource2 PROTO((const char *_basename,
                                          const char *_resource,
                                          XrmValuePtr value));

extern XVisualInfo * Nlm_GetBestOGLVisual(void); /* in vibslate.c */

static Colormap Nlm_VibrantDefaultColormapEx(Visual **visual, int *depth)
{
  static Nlm_Boolean vibrant_cMap_ready = FALSE;
  static Colormap    vibrant_cMap;
  static Visual     *vibrant_visual = NULL;
  static int         vibrant_depth = -1;

  Boolean  privateColormap;
  int      nInheritColors = 64;  /* default */
  char    *value;

  while ( !vibrant_cMap_ready )
    {{ /* THE FIRST TIME ONLY */
      vibrant_cMap_ready = TRUE;

      value = Nlm_XrmGetResource( "privateColormap" );
      privateColormap = (value != NULL  && 
                         (strcmp(value, "true") == 0  ||
                          strcmp(value, "yes" ) == 0  ||
                          strcmp(value, "on"  ) == 0  ||
                          strcmp(value, "1"   ) == 0));
      Nlm_MemFree( value );
      
      if (privateColormap  &&
          (value = Nlm_XrmGetResource( "nInheritColors" )) != NULL )
        {
          int int_value = atoi( value );
          Nlm_MemFree( value );

          if (1 < int_value ||  int_value < 256)
            nInheritColors = int_value;
        }

      /* Compose private colormap, if specified */
      if (privateColormap  &&
          Nlm_BusyColormap(nInheritColors, nInheritColors,
                           &vibrant_cMap, &vibrant_visual, &vibrant_depth))
        break;

#ifdef _OPENGL
      /* we want better-than-8-bit color for OpenGL, if possible, so force
         vibrant to try those first, using glX selection of a visual/depth
         appropriate for OpenGL */
      {
        XVisualInfo *visinfo = Nlm_GetBestOGLVisual();
        if (!visinfo) {
          puts("Can't find OpenGL-appropriate visual!");
          exit(1);
        }
        vibrant_visual = visinfo->visual;
        vibrant_depth = visinfo->depth;
        /* create an X colormap since probably not using default visual */
        vibrant_cMap = XCreateColormap(
          Nlm_currentXDisplay,
          RootWindow(Nlm_currentXDisplay, visinfo->screen), \
          visinfo->visual, AllocNone);
      }
#else
      /* Try use the XA_RGB_DEFAULT_MAP standard colormap of 8-bit depth */
      if ( Nlm_StandardColormap(&vibrant_cMap,&vibrant_visual,&vibrant_depth) )
        break;

      /* By default, use default colormap and visual */
      vibrant_cMap  = DefaultColormap(Nlm_currentXDisplay, Nlm_currentXScreen);
      vibrant_visual= DefaultVisual  (Nlm_currentXDisplay, Nlm_currentXScreen);
      vibrant_depth = DefaultDepth   (Nlm_currentXDisplay, Nlm_currentXScreen);
#endif /* ! _OPENGL */

    }}

  if ( visual )
    *visual = vibrant_visual;
  if ( depth )
    *depth = vibrant_depth;
  return vibrant_cMap;
}

extern Colormap Nlm_VibrantDefaultColormap( void )
{
  return Nlm_VibrantDefaultColormapEx(NULL, NULL);
}

extern Visual *Nlm_VibrantDefaultVisual( void )
{
  Visual *visual;
  Nlm_VibrantDefaultColormapEx(&visual, NULL);
  return visual;
}

extern int Nlm_VibrantDefaultDepth( void )
{
  int depth;
  Nlm_VibrantDefaultColormapEx(NULL, &depth);
  return depth;
}


extern void Nlm_XAllocColor(XColor *xcolor, Colormap colormap,
                            Nlm_Uint1 red, Nlm_Uint1 green, Nlm_Uint1 blue)
{
  if (Nlm_currentXDisplay == NULL)
    return;

  if (Nlm_stdColormapRGB.visualid  &&  Nlm_stdColormapRGB.colormap == colormap)
    { /* Use standard colormap */
      if ( Nlm_stdGrayScale )
        xcolor->pixel = (30 * red + 59 * green + 11 * blue) *
          Nlm_stdColormapRGB.red_max / 25500 * Nlm_stdColormapRGB.red_mult;
      else
        xcolor->pixel =
          ((red   * Nlm_stdColormapRGB.red_max   + 128) / 255) *
           Nlm_stdColormapRGB.red_mult   +
          ((green * Nlm_stdColormapRGB.green_max + 128) / 255) *
          Nlm_stdColormapRGB.green_mult +
          ((blue  * Nlm_stdColormapRGB.blue_max  + 128) / 255) *
          Nlm_stdColormapRGB.blue_mult;

      xcolor->pixel += Nlm_stdColormapRGB.base_pixel;
      XQueryColor(Nlm_currentXDisplay, colormap, xcolor); 
      return;
    }

  xcolor->red   = red   << 8 | red;
  xcolor->green = green << 8 | green;
  xcolor->blue  = blue  << 8 | blue;

  if (!Nlm_hasColor  ||
      !XAllocColor(Nlm_currentXDisplay,
                   (colormap != 0) ? colormap : Nlm_VibrantDefaultColormap(),
                   xcolor))
    {
      xcolor->pixel =
        (30 * (int)red + 59 * (int)green + 11 * (int)blue < 12800) ?
        BlackPixel(Nlm_currentXDisplay, Nlm_currentXScreen) :
        WhitePixel(Nlm_currentXDisplay, Nlm_currentXScreen);
    }
}
#endif /* WIN_MOTIF */


extern void Nlm_SetWindowExtra (Nlm_WindoW w, Nlm_VoidPtr data, Nlm_WndFreeProc cleanup)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.data = data;
    wdata.cleanup = cleanup;
    Nlm_SetWindowData (w, &wdata);
  }
}

extern Nlm_VoidPtr Nlm_GetWindowExtra (Nlm_WindoW w)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    return wdata.data;
  } else {
    return NULL;
  }
}

#ifdef WIN_MAC
static void Nlm_ClearKeys (void)
{
  Nlm_cmmdKey = FALSE;
  Nlm_ctrlKey = FALSE;
  Nlm_optKey = FALSE;
  Nlm_shftKey = FALSE;
  Nlm_dblClick = FALSE;
}
#endif


static Nlm_WindoW Nlm_FindWindowRec (Nlm_WindowTool wptr)

{
  Nlm_WindoW      w;
#ifdef WIN_MAC
  Nlm_WindowData  wdata;
#endif

#ifdef WIN_MAC
  Nlm_GetWindowData (Nlm_systemWindow, &wdata);
  wdata.handle = wptr;
  Nlm_SetWindowData (Nlm_systemWindow, &wdata);
#endif
  w = Nlm_desktopWindow;
  while (w != NULL && Nlm_ParentWindowPtr ((Nlm_GraphiC) w) != wptr) {
    w = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) w);
  }
  if (w == NULL) {
    w = Nlm_desktopWindow;
  }
  return w;
}

static void Nlm_SetWindowTitle (Nlm_GraphiC w, Nlm_Int2 item,
                                Nlm_CharPtr title, Nlm_Boolean savePort)


{
  Nlm_Char        temp [256];
  Nlm_WindowTool  wptr;
#ifdef WIN_MOTIF
  Nlm_ShellTool   shl;
  Nlm_WindowData  wdata;
#endif

  wptr = Nlm_ParentWindowPtr (w);
  Nlm_StringNCpy_0(temp, title, sizeof(temp));
#ifdef WIN_MAC
  Nlm_CtoPstr (temp);
  SetWTitle (wptr, (StringPtr) temp);
#endif
#ifdef WIN_MSWIN
  SetWindowText (wptr, temp);
#endif
#ifdef WIN_MOTIF
  shl = Nlm_GetWindowShell ((Nlm_WindoW) w);
  if (temp [0] != '\0') {
      if(getenv("VIBRANT_USE_APPLICATION_NAME") != NULL && Nlm_StringCmp(getenv("VIBRANT_USE_APPLICATION_NAME"),"0")) {
          Nlm_ProgramPath(temp, sizeof(temp));
          Nlm_StringNCpy_0(temp,Nlm_StringRChr(temp,'/')+1,sizeof(temp));
          Nlm_StringNCat(temp, ": ", sizeof(temp));
          Nlm_StringNCat(temp, title, sizeof(temp));
      }
    XtVaSetValues (shl, XmNtitle, temp, NULL);
  } else {
    XtVaSetValues (shl, XmNtitle, " ", NULL);
  }
  XFlush( Nlm_currentXDisplay );
  Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
  if (wdata.title != NULL) {
    wdata.title = (Nlm_CharPtr) Nlm_MemFree (wdata.title);
  }
  wdata.title = Nlm_StringSave (title);
  Nlm_SetWindowData ((Nlm_WindoW) w, &wdata);
#endif
}

static void Nlm_GetWindowTitle (Nlm_GraphiC w, Nlm_Int2 item,
                                Nlm_CharPtr title, size_t maxsize)

{
  Nlm_Char        temp [256];
  Nlm_WindowTool  wptr;
#ifdef WIN_MOTIF
  Nlm_WindowData  wdata;
#endif

  wptr = Nlm_ParentWindowPtr (w);
  temp [0] = '\0';
#ifdef WIN_MAC
  GetWTitle (wptr, (StringPtr) temp);
  Nlm_PtoCstr (temp);
#endif
#ifdef WIN_MSWIN
  GetWindowText (wptr, temp, sizeof (temp));
#endif
#ifdef WIN_MOTIF
  Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
  Nlm_StringNCpy_0(temp, wdata.title, sizeof(temp));
#endif
  Nlm_StringNCpy_0(title, temp, maxsize);
}

static Nlm_WindoW Nlm_MakeWindowLink (Nlm_RectPtr r, Nlm_Int2 recordSize,
                                      Nlm_GphPrcs PNTR classPtr)

{
  Nlm_GraphiC  n;
  Nlm_WindoW   w;

  w = (Nlm_WindoW) Nlm_HandNew (recordSize);
  if (w != NULL) {
    n = Nlm_GetNext ((Nlm_GraphiC) Nlm_desktopWindow);
    Nlm_LoadGraphicData ((Nlm_GraphiC) w, n, NULL, NULL, NULL,
                         classPtr, NULL, r, TRUE, FALSE, NULL, NULL);
    if (Nlm_nextIdNumber < 32767) {
      Nlm_nextIdNumber++;
    }
    Nlm_SetNext ((Nlm_GraphiC) Nlm_desktopWindow, (Nlm_GraphiC) w);
  }
  return w;
}

#ifdef WIN_MAC
extern void Nlm_SetUpdateRegion (WindowPtr wptr)

{
// QUARTZ_FIXME: what does this do? does it need to do anything?
#ifndef WIN_MAC_QUARTZ
  Rect bounds;

  if (wptr != NULL) {
    GetPortVisibleRegion(GetWindowPort(wptr), Nlm_updateRgn);
    /* HLock ((Handle) Nlm_updateRgn); */
    GetRegionBounds(Nlm_updateRgn, &bounds);
    Nlm_RectToolToRecT (&bounds, &Nlm_updateRect);
    /* HUnlock ((Handle) Nlm_updateRgn); */
  }
#endif
}
#endif

extern Nlm_Int2  Nlm_internalMenuBarHeight;

#ifdef WIN_MOTIF
static void WindowCloseCallback(Widget wd,
                                XtPointer client_data, XtPointer call_data)
{
  Nlm_WndActnProc  cls;
  Nlm_WindoW       w;
  Nlm_WindowData   wdata;

  w = (Nlm_WindoW) client_data;
  Nlm_GetWindowData (w, &wdata);
  cls = wdata.close;
  if (cls != NULL) {
    cls (w);
  }
}


static int ignoreXerror_handler(Display *dpy, XErrorEvent *xerr)
{
  return 0;
}

static int defaultXerror_handler(Display *dpy, XErrorEvent *event)
{
  char buffer[BUFSIZ];
  char mesg[BUFSIZ];
  char number[32];
  char *mtype = "XlibMessage";

  XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
  XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
  fprintf(stderr, "%s:  %s\n  ", mesg, buffer);
  XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", 
                        mesg, BUFSIZ);
  fprintf(stderr, mesg, event->request_code);
  if (event->request_code < 128) {
    sprintf(number, "%d", event->request_code);
    XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
  } else {
    buffer[0] = '\0';
  }
  fprintf(stderr, " (%s)\n", buffer);

  if (event->request_code >= 128) {
    XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
                          mesg, BUFSIZ);
    fputs("  ", stderr);
    fprintf(stderr, mesg, event->minor_code);
    fputs("\n", stderr);

    strcpy(buffer, "Value");
    XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
    if (mesg[0]) {
      fputs("  ", stderr);
      fprintf(stderr, mesg, event->resourceid);
      fputs("\n", stderr);
    }
  } else if ((event->error_code == BadWindow) ||
             (event->error_code == BadPixmap) ||
             (event->error_code == BadCursor) ||
             (event->error_code == BadFont) ||
             (event->error_code == BadDrawable) ||
             (event->error_code == BadColor) ||
             (event->error_code == BadGC) ||
             (event->error_code == BadIDChoice) ||
             (event->error_code == BadValue) ||
             (event->error_code == BadAtom)) {
    if (event->error_code == BadValue)
      XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
                            mesg, BUFSIZ);
    else if (event->error_code == BadAtom)
      XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
                            mesg, BUFSIZ);
    else
      XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
                            mesg, BUFSIZ);
    fputs("  ", stderr);
    fprintf(stderr, mesg, event->resourceid);
    fputs("\n", stderr);
  }

  XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", 
                        mesg, BUFSIZ);
  fputs("  ", stderr);
  fprintf(stderr, mesg, event->serial);
  XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
                        mesg, BUFSIZ);
  fputs("\n  ", stderr);
  fprintf(stderr, mesg, (XNextRequest(dpy) - 1));
  fputs("\n", stderr);

  return (event->error_code == BadImplementation) ? 0 : 1;
}


static void WindowStructFocusCallback (Widget wd, XtPointer client_data,
                                       XEvent *event, Boolean *contin)
{
  Nlm_WindoW w = (Nlm_WindoW)client_data;

  switch ( event->type )
    {
    case FocusOut:
      {
        Nlm_DoDeactivate((Nlm_GraphiC)w, FALSE);
        break;
      }

    case FocusIn:
      {
        Nlm_DoActivate((Nlm_GraphiC)w, FALSE);
        break;
      }

    case MapNotify:
      {
        if (wd == selectShell)
          { /* Set input focus */
            XWindowAttributes attr;
            Window selectWin = XtWindow( selectShell );
      
            XGetWindowAttributes(Nlm_currentXDisplay, selectWin, &attr);
            if (attr.map_state != IsViewable) {
              Nlm_SetVisible((Nlm_GraphiC)w, TRUE);
              return;
            }

            XSetInputFocus(Nlm_currentXDisplay, selectWin,
                           RevertToPointerRoot, CurrentTime);
            selectShell = NULL;
          }
        Nlm_SetVisible((Nlm_GraphiC)w, TRUE);
        XtVaSetValues(wd, XtNiconic, (Boolean)False, NULL);
        break;
      }

    case UnmapNotify:
      {
        Nlm_SetVisible((Nlm_GraphiC)w, FALSE);
        break;
      }

    case ConfigureNotify:
      { /* Move & Resize */
        Nlm_RecT         oldrect;
        Nlm_RecT         r;
        Nlm_RectTool     rtool;
        Window           xw, root, parent, child, *children = NULL;
        unsigned int     nchildren;
        int              x, y;
        Nlm_WindowData   wdata;

        XSetErrorHandler( ignoreXerror_handler );
        for (xw = XtWindow( wd );
             xw  &&  XQueryTree(Nlm_currentXDisplay, xw, &root, &parent,
                                &children, &nchildren)  &&
               root != parent;
             xw = parent)
          {
            XFree( (char *)children );
            children = NULL;
          }
        XSetErrorHandler( defaultXerror_handler );
        if ( children )
          XFree( (char *)children );

        if (root != parent)
          break;

        XTranslateCoordinates(Nlm_currentXDisplay, xw, root,
                              (Position)0, (Position)0,
                              &x, &y,  &child);

        rtool.x = x;
        rtool.y = y;
        rtool.width  = event->xconfigure.width;
        rtool.height = event->xconfigure.height;
        if (Nlm_GetWindowMenuBar( w ) != NULL)
          rtool.height -= Nlm_internalMenuBarHeight;

        Nlm_RectToolToRecT(&rtool, &r);
        Nlm_GetRect((Nlm_GraphiC)w, &oldrect);
        Nlm_SetRect((Nlm_GraphiC)w, &r);
        Nlm_GetWindowData(w, &wdata);

        if (wdata.resize != NULL  &&
            (oldrect.right  - oldrect.left != r.right  - r.left ||
             oldrect.bottom - oldrect.top  != r.bottom - r.top) &&
            Nlm_WindowHasBeenShown( w )  &&
            Nlm_GetVisible((Nlm_GraphiC) w))
          {
            wdata.resize( w );
          }
        break;
      }
    }
}


static void WindowEnterCallback(Widget wd, XtPointer client_data,
                                XEvent *ev, Boolean *contin)
{
  XCrossingEvent  *event;
  Nlm_WindoW       w;
  Nlm_WindowData   wdata;

  event = (XCrossingEvent*) ev;
  if (event->type != EnterNotify) return;
  w = (Nlm_WindoW) client_data;
  Nlm_GetWindowData (w, &wdata);
  if ( wdata.cMapStatus ) return;
  if ( !wdata.cMap )  return;
  XInstallColormap(Nlm_currentXDisplay, wdata.cMap);
  wdata.cMapStatus = 1;
  Nlm_SetWindowData (w, &wdata);
}

static void WindowLeaveCallback(Widget wd, XtPointer client_data,
                                XEvent *ev, Boolean *contin)
{
  XCrossingEvent  *event;
  Nlm_WindoW       w;
  Nlm_WindowData   wdata;

  event = (XCrossingEvent*) ev;
  if (event->type != LeaveNotify) return;
  w = (Nlm_WindoW) client_data;
  Nlm_GetWindowData (w, &wdata);
  if ( wdata.cMapStatus == 0 ) return;
  XUninstallColormap(Nlm_currentXDisplay, wdata.cMap);
  wdata.cMapStatus = 0;
  Nlm_SetWindowData (w, &wdata);
}


static GC vibrant_GC[25];

static GC Nlm_GetGC(int depth)
{
  ASSERT ( 0 <= depth  &&  depth < sizeof(vibrant_GC)/sizeof(GC) );
  if ( !vibrant_GC[depth] )
    {
      Pixmap fake_pixmap = XCreatePixmap(Nlm_currentXDisplay,
                                         RootWindow(Nlm_currentXDisplay,
                                                    Nlm_currentXScreen),
                                         4, 4, depth);
      vibrant_GC[depth] = XCreateGC(Nlm_currentXDisplay, fake_pixmap, 0, NULL);
      XFreePixmap(Nlm_currentXDisplay, fake_pixmap);
    }

  return vibrant_GC[depth];
}

static void Nlm_FreeGCs( void )
{
  size_t depth;
  for (depth = 0;  depth < sizeof(vibrant_GC)/sizeof(GC);  depth++)
    if ( vibrant_GC[depth] )
      {
        XFreeGC(Nlm_currentXDisplay, vibrant_GC[depth]);
        vibrant_GC[depth] = NULL;
      }
}
#endif



#ifdef WIN_MSWIN
static void client2win(Nlm_WindoW w,
                       Nlm_RectPtr client_rect, LPRECT win_rect)
{
  if (client_rect == NULL  ||  win_rect == NULL)
    return;

  win_rect->left   = client_rect->left;
  win_rect->top    = client_rect->top;
  win_rect->right  = client_rect->right;
  win_rect->bottom = client_rect->bottom;

  if (w == NULL)
    return;

  {{
  Nlm_Int2 dXleft, dXright, dYtop, dYbottom;
  Nlm_Int2 dX = 0, dY = 0;

  Nlm_WindowData wdata;
  Nlm_GetWindowData(w, &wdata);

  AdjustWindowRectEx(win_rect, wdata.style, (wdata.menuBar != NULL),
                     wdata.ex_style);

  dXleft  = (Nlm_Int2)(screenBitBounds.left  - win_rect->left );
  dXright = (Nlm_Int2)(screenBitBounds.right - win_rect->right);
  if (dXleft > 0)
    dX = dXleft;
  else if (dXright < 0)
    dX = dXright;
        
  dYtop    = (Nlm_Int2)(screenBitBounds.top    - win_rect->top   );
  dYbottom = (Nlm_Int2)(screenBitBounds.bottom - win_rect->bottom);
  if (dYtop > 0)
    dY = dYtop;
  else if (dYbottom < 0)
    dY = dYbottom;
        
  if (dX == 0  &&  dY == 0)
    return;

  Nlm_OffsetRect(client_rect, dX, dY);
  win_rect->left   += dX;
  win_rect->top    += dY;
  win_rect->right  += dX;
  win_rect->bottom += dY;
  }}
}


static void win2client(Nlm_WindoW w,
                       LPRECT win_rect, Nlm_RectPtr client_rect)
{
  RECT xclient_rect;

  ASSERT ( w           != NULL );
  ASSERT ( client_rect != NULL );
  ASSERT ( win_rect    != NULL );

  xclient_rect.left   = (Nlm_Int2)
    ((screenBitBounds.right - screenBitBounds.left) / 2 - 2);
  xclient_rect.right  = (Nlm_Int2)(xclient_rect.left + 4);
  xclient_rect.top    = (Nlm_Int2)
    ((screenBitBounds.bottom - screenBitBounds.top) / 2 - 2);
  xclient_rect.bottom = (Nlm_Int2)(xclient_rect.top + 4);


  {{
  RECT xwin_rect = xclient_rect;
  int  dXleft, dXright, dYtop, dYbottom;

  Nlm_WindowData wdata;
  Nlm_GetWindowData(w, &wdata);

  AdjustWindowRectEx(&xwin_rect, wdata.style, (wdata.menuBar != NULL),
                     wdata.ex_style);

  dXleft   = xclient_rect.left - xwin_rect.left;
  dXright  = (xwin_rect.right - xwin_rect.left) -
             (xclient_rect.right - xclient_rect.left) - dXleft;
  dYtop    = xclient_rect.top  - xwin_rect.top;
  dYbottom = (xwin_rect.bottom - xwin_rect.top) -
             (xclient_rect.bottom - xclient_rect.top) - dYtop;
    
  client_rect->left   = (Nlm_Int2)(win_rect->left   + dXleft  );
  client_rect->right  = (Nlm_Int2)(win_rect->right  - dXright );
  client_rect->top    = (Nlm_Int2)(win_rect->top    + dYtop   );
  client_rect->bottom = (Nlm_Int2)(win_rect->bottom - dYbottom);
  }}
}
#endif 

#ifdef WIN_MAC_QUARTZ
// QUARTZ_FIXME: this stuff is probably not needed
//static void Nlm_WindowSetProperty (WindowRef wptr, PropertyTag tag, void *ptr)
//{
//  SetWindowProperty (wptr, 'NCBI', tag, sizeof(ptr), &ptr);
//}
//
//static void *Nlm_WindowGetProperty (WindowRef wptr, PropertyTag tag)
//{
//  void *ret = 0;
//  GetWindowProperty (wptr, 'NCBI', tag, sizeof(ret), 0, &ret);
//  return ret;
//}
//
//static void Nlm_EnsureQuartzPort (CGContextRef *ctxPtr, HIViewRef imageView)
//{
//  /* note: the context must actually be a bitmap context, this 
//      is guaranteed since this function is the only one that
//      gets to make it anyway */
//  HIRect bounds;
//  HIViewGetBounds (imageView, &bounds);
//  int good = *ctxPtr != 0;
//  if (good)
//  {
//    
//    if (bounds.size.width != CGBitmapContextGetWidth (*ctxPtr))
//      good = 0;
//    if (bounds.size.height != CGBitmapContextGetHeight (*ctxPtr))
//      good = 0;
//  }
//  if (!good)
//  {
//    CGContextRelease (*ctxPtr);
//    
//    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB ();
//    *ctxPtr = CGBitmapContextCreate (0, bounds.size.width, bounds.size.height, 32, 0, colorSpace, kCGImageAlphaNoneSkipLast);
//    CGColorSpaceRelease (colorSpace);
//  }
//}
//
//CGContextRef Nlm_GetQuartzWindowPort (WindowRef wptr)
//{
//  HIViewRef imageView = Nlm_WindowGetProperty (wptr, 'imgv');
//  CGContextRef ref = Nlm_WindowGetProperty (wptr, 'cntx');
//  CGContextRef old = ref;
//  Nlm_EnsureQuartzPort (&ref, imageView);
//  if (ref != old)
//    Nlm_WindowSetProperty (wptr, 'cntx', ref);
//  return ref;
//}

static OSStatus Nlm_RootHIViewRedrawHandler (EventHandlerCallRef handler, EventRef event, void *userData)
{
  Nlm_WindoW w = userData;
  
  CGContextRef ctx;
  GetEventParameter (event,
                     kEventParamCGContextRef,
                     typeCGContextRef,
                     NULL,
                     sizeof (CGContextRef),
                     NULL,
                     &ctx);
  Nlm_SetPort (ctx);
  Nlm_SetPortWindowPort (Nlm_ParentWindowPtr ((Nlm_GraphiC)w));
  Nlm_DrawWindow ((Nlm_GraphiC)w, 0);
  Nlm_SetPortWindowPort (NULL);
  Nlm_SetPort (NULL);
	
  return noErr;
}

#endif

#define DOCUMENT_STYLE 1
#define FIXED_STYLE    2
#define FROZEN_STYLE   3
#define ROUND_STYLE    4
#define ALERT_STYLE    5
#define MODAL_STYLE    6
#define FLOATING_STYLE 7
#define SHADOW_STYLE   8
#define PLAIN_STYLE    9

static void Nlm_NewWindow (Nlm_WindoW w, Nlm_Int2 type, Nlm_Int2 procID,
                           Nlm_Boolean goAway, Nlm_CharPtr windowClass,
                           Nlm_Uint4 style, Nlm_CharPtr title,
                           Nlm_WndActnProc close, Nlm_WndActnProc resize)
{
  Nlm_ShellTool   dlg;
  Nlm_RecT        drag;
  Nlm_RecT        grow;
  Nlm_Int2        hsb;
  Nlm_MainTool    man;
  Nlm_Int2        margin;
  Nlm_RecT        p;
  Nlm_PortTool    prt;
  Nlm_PoinT       pt;
  Nlm_RecT        r;
  Nlm_ShellTool   shl;
  Nlm_Int2        spacing;
  Nlm_Char        temp [256];
  Nlm_CharPtr     ttl;
  Nlm_Int2        vsb;
  Nlm_WindowTool  wptr;
  Nlm_RecT        zoom;
#ifdef WIN_MAC
  Nlm_WindowTool  behindNone;
  CCTabHandle     colorHandle;
  CCTabPtr        colorPtr;
  Nlm_RectTool    rtool;
  WindowClass     winClass = 0;
#if TARGET_API_MAC_CARBON
  WindowAttributes winAttrs = kWindowStandardHandlerAttribute;
#else
  WindowAttributes winAttrs = kWindowCompositingAttribute; /* kWindowStandardHandlerAttribute; */
#endif
  OSStatus        osErr;
#endif
#ifdef WIN_MOTIF
  Atom            atom;
  Cardinal        n;
  Arg             wargs[32];
  int             screen_num;
  int             depth = -1;
  Visual         *visual;
  Colormap        cMap;
  Nlm_Boolean     is_cMap = FALSE;
#endif
#ifdef WIN_MSWIN
  Nlm_Uint4       ex_style = 0;
#endif

  Nlm_StringNCpy_0(temp, title, sizeof(temp));

#ifdef WIN_MAC
  Nlm_CtoPstr (temp);
#endif

  Nlm_LoadRect (&r, 50, 50, 150, 150);

#ifdef WIN_MOTIF
  r = Nlm_screenRect;
  Nlm_InsetRect (&r, 50, 50);
#endif

  Nlm_GetRect ((Nlm_GraphiC) w, &p);
  margin = 10;
  spacing = 10;
  if (p.right < 0)
    margin  = (Nlm_Int2)(-p.right);
  if (p.bottom < 0)
    spacing = (Nlm_Int2)(-p.bottom);
  if (p.right >= 0 || p.bottom >= 0)
    {
      r = p;
      r.bottom = (Nlm_Int2)(r.top  + r.bottom);
      r.right  = (Nlm_Int2)(r.left + r.right );
    }
  Nlm_LoadPt (&pt, margin, margin);
  shl  = (Nlm_ShellTool) 0;
  dlg  = (Nlm_ShellTool) 0;
  wptr = (Nlm_WindowTool) 0;
  prt  = NULL;
  man  = (Nlm_MainTool) 0;
  ttl  = NULL;
  hsb  = 0;
  vsb  = 0;

#ifdef WIN_MAC
    switch (type) {
      case  DOCUMENT_STYLE:
        winClass = kDocumentWindowClass;
        winAttrs |= kWindowStandardDocumentAttributes;
        break;
      case  FIXED_STYLE:
      case  ROUND_STYLE:
        winClass = kDocumentWindowClass;
        winAttrs |= kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute;
        break;
      case  MODAL_STYLE:
      case  ALERT_STYLE:
        winClass = kMovableModalWindowClass;
        winAttrs = kWindowNoAttributes;
        break;
      case  FROZEN_STYLE:
        winClass = kMovableModalWindowClass;
        winAttrs |= kWindowCloseBoxAttribute;
        break;
      case  FLOATING_STYLE:
        winClass = kFloatingWindowClass;
        winAttrs |= kWindowStandardFloatingAttributes;
        break;
      case  PLAIN_STYLE:
      case  SHADOW_STYLE:
        winClass = kPlainWindowClass;
        winAttrs |= kWindowNoAttributes;
        break;
    }

  behindNone = (Nlm_WindowTool) (-1);
#ifndef WIN_MAC_QUARTZ
  TextFont (0);
  TextSize (0);
#endif
  Nlm_RecTToRectTool (&r, &rtool);
  if (close == NULL) {
    goAway = FALSE;
  }
#if 1 /* CreateNewWindow does not set window title */
  if (hasColorQD) {
    wptr = (WindowPtr) NewCWindow (NULL, &rtool, (StringPtr) temp,
                                   FALSE, procID,(Nlm_WindowTool) behindNone,
                                   goAway, 0);
  } else {
    wptr = NewWindow (NULL, &rtool, (StringPtr) temp, FALSE, procID,
                      (Nlm_WindowTool) behindNone, goAway, 0);
  }
#else
  if (! goAway) {
    winAttrs &= ~kWindowCloseBoxAttribute;
  }
  osErr = CreateNewWindow(winClass, winAttrs, &rtool, &wptr);
  if (osErr != noErr) {
    wptr = NULL;
    return;
  }
#endif
#ifdef WIN_MAC_QUARTZ
  HIViewRef root = HIViewGetRoot (wptr);
  HIViewRef content;
  HIViewFindByID (root, kHIViewWindowContentID, &content);
  
  EventTypeSpec updateEventSpec[] = { kEventClassControl, kEventControlDraw };
  InstallEventHandler (GetControlEventTarget (content),
                       Nlm_RootHIViewRedrawHandler,
                       GetEventTypeCount (updateEventSpec),
                       updateEventSpec,
                       w,
                       NULL);
  
// QUARTZ_FIXME: unneeded unless we really do need the triple buffer
//  HIViewRef imageView;
//  HIImageViewCreate (0, &imageView);
//  
//  HIViewAddSubview (root, imageView);
//  HIRect bounds;
//  HIViewGetBounds (root, &bounds);
//  HIViewSetFrame (imageView, &bounds);
//  
//  HILayoutInfo layout;
//  layout.version = kHILayoutInfoVersionZero;
//  
//  HIViewGetLayoutInfo (imageView, &layout);
//  layout.binding.top.toView = root;
//  layout.binding.top.kind = kHILayoutBindTop;
//  layout.binding.bottom.toView = root;
//  layout.binding.bottom.kind = kHILayoutBindBottom;
//  layout.binding.left.toView = root;
//  layout.binding.left.kind = kHILayoutBindLeft;
//  layout.binding.right.toView = root;
//  layout.binding.right.kind = kHILayoutBindRight;
//  HIViewSetLayoutInfo (imageView, &layout);
//  HIViewApplyLayout (imageView);
//  HIViewSetVisible (imageView, 1);
//  
//  char *path = "/Users/mikeash/bob_eggleton_adeepnessinthesky.jpg";
//  CFURLRef url = CFURLCreateFromFileSystemRepresentation (NULL, (const UInt8 *)path, strlen (path), 0);
//  CGDataProviderRef provider = CGDataProviderCreateWithURL (url);
//  CGImageRef img = CGImageCreateWithJPEGDataProvider (provider, NULL, 1, kCGRenderingIntentDefault);
//  HIImageViewSetImage (imageView, img);
  
//  Nlm_WindowSetProperty (wptr, 'imgv', imageView);
  
#else
  Nlm_SetPortWindowPort(wptr);
  Nlm_currentWindowTool = wptr;
  prt = (Nlm_PortTool) wptr;
  Nlm_SetUpdateRegion (wptr);
  PenNormal ();
  Nlm_MoveTo (2, 10);
  if (hasColorQD) {
    colorHandle = (CCTabHandle) GetResource ('cctb', 0);
    if (colorHandle != NULL) {
      LoadResource ((Handle) colorHandle);
      if (ResError () == noErr) {
        HLock ((Handle) colorHandle);
        colorPtr = *(colorHandle);
        if (colorPtr != NULL) {
          RGBForeColor (&(colorPtr->ctTable [2].rgb));
        }
        HUnlock ((Handle) colorHandle);
      }
    }
    GetForeColor (&Nlm_RGBforeColor);
    GetBackColor (&Nlm_RGBbackColor);
  }
#endif
#endif

#ifdef WIN_MSWIN
  if (close == NULL)
    style &= ~WS_SYSMENU;

  switch ( type )
    {
    case FLOATING_STYLE:
      ex_style = WS_EX_TOPMOST;
      break;
    case MODAL_STYLE:
      ex_style = WS_EX_DLGMODALFRAME;
      break;
    default:
      ex_style = 0;
    }
    
  wptr = CreateWindowEx(ex_style, windowClass, temp, style,
                        r.left, r.top, (r.right - r.left),
                        (r.bottom - r.top), NULL, NULL,
                        Nlm_currentHInst, NULL);

  if ( wptr )
    SetProp(wptr, (LPSTR)"Nlm_VibrantProp", (Nlm_HandleTool)w);

  prt = GetDC( wptr );
  ReleaseDC(wptr, prt);
  Nlm_currentHDC  = prt;
  Nlm_currentHWnd = wptr;
#endif

#ifdef WIN_MOTIF
  n = 0;
  if (temp [0] != '\0') {
    if(getenv("VIBRANT_USE_APPLICATION_NAME") != NULL && Nlm_StringCmp(getenv("VIBRANT_USE_APPLICATION_NAME"),"0")) {
      Nlm_ProgramPath(temp, sizeof(temp));
      Nlm_StringNCpy_0(temp,Nlm_StringRChr(temp,'/')+1,sizeof(temp));
      Nlm_StringNCat(temp, ": ", sizeof(temp));
      Nlm_StringNCat(temp, title, sizeof(temp));
    }
    XtSetArg (wargs[n], XmNtitle, temp); n++;
  } else {
    XtSetArg (wargs[n], XmNtitle, " "); n++;
  }
  XtSetArg (wargs[n], XmNx, (Position) r.left); n++;
  XtSetArg (wargs[n], XmNy, (Position) r.top); n++;
  XtSetArg (wargs[n], XmNdefaultFontList, Nlm_XfontList); n++;
  XtSetArg (wargs[n], XmNdeleteResponse,   XmDO_NOTHING); n++;
  XtSetArg (wargs[n], XmNallowShellResize, (Boolean)FALSE); n++;

#ifndef _OPENGL
  if (motif_n_colorcells != 0  &&
      Nlm_BusyColormap(motif_n_colorcells, 256, &cMap, &visual, &depth))
    is_cMap = TRUE;
  else
#endif
    cMap = Nlm_VibrantDefaultColormapEx(&visual, &depth);
  motif_n_colorcells = 0;

  XtSetArg(wargs[n], XtNdepth,    depth );  n++;
  XtSetArg(wargs[n], XtNvisual,   visual);  n++;
  XtSetArg(wargs[n], XtNcolormap, cMap  );  n++;

  shl = XtAppCreateShell ((String) resource_nm, (String) "Vibrant",
                          applicationShellWidgetClass,
                          Nlm_currentXDisplay, wargs, n);

  dlg = shl;
  if ( dlg ) {
    XtSetMappedWhenManaged (shl, FALSE);
#ifdef _DEBUG
    XtAddEventHandler(shl,
                      (EventMask) 0, True,
                      (XtEventHandler) _XEditResCheckMessages, NULL);
#endif
    XtAddEventHandler (shl, StructureNotifyMask|FocusChangeMask, FALSE,
                       WindowStructFocusCallback, (XtPointer) w);
    XtAddEventHandler (shl, EnterWindowMask, FALSE,
                       WindowEnterCallback, (XtPointer) w);
    XtAddEventHandler (shl, LeaveWindowMask, FALSE,
                       WindowLeaveCallback, (XtPointer) w);

    n = 0;
    XtSetArg (wargs[n], XmNwidth,  (Dimension) (r.right - r.left)); n++;
    XtSetArg (wargs[n], XmNheight, (Dimension) (r.bottom - r.top)); n++;
    XtSetArg (wargs[n], XmNmarginHeight, (Dimension)0); n++;
    XtSetArg (wargs[n], XmNmarginWidth,  (Dimension)0); n++;
    XtSetArg (wargs[n], XmNborderWidth,  (Dimension)0); n++;
    man = XmCreateMainWindow (dlg, (String) "", wargs, n);

    n = 0;
    XtSetArg (wargs[n], XmNwidth,  (Dimension) (r.right - r.left)); n++;
    XtSetArg (wargs[n], XmNheight, (Dimension) (r.bottom - r.top)); n++;
    XtSetArg (wargs[n], XmNbuttonFontList, Nlm_XfontList); n++;
    XtSetArg (wargs[n], XmNlabelFontList,  Nlm_XfontList); n++;
    XtSetArg (wargs[n], XmNtextFontList,   Nlm_XfontList); n++;
    XtSetArg (wargs[n], XmNmarginHeight, (Dimension)0); n++;
    XtSetArg (wargs[n], XmNmarginWidth,  (Dimension)0); n++;
    XtSetArg (wargs[n], XmNborderWidth,  (Dimension)0); n++;
    wptr = XmCreateBulletinBoard (man, (String) "", wargs, n);

    screen_num = DefaultScreen (Nlm_currentXDisplay);
    prt = Nlm_GetGC( depth );
    XtManageChild (man);
    XtManageChild (wptr);

    atom = XmInternAtom (Nlm_currentXDisplay, "WM_DELETE_WINDOW", TRUE);
    if (atom != 0) {
      XmAddWMProtocolCallback (shl, atom, WindowCloseCallback, (XtPointer) w);
    }
  }

  if (temp [0] != '\0') {
    ttl = Nlm_StringSave (temp);
  }
#endif

  Nlm_currentWindowTool = wptr;
  r = screenBitBounds;
  Nlm_LoadRect (&drag, (Nlm_Int2)(r.left  + 4), (Nlm_Int2)(r.top    + 24),
                       (Nlm_Int2)(r.right - 4), (Nlm_Int2)(r.bottom -  4));
  Nlm_LoadRect (&grow, r.left, (Nlm_Int2)(r.top + 24), r.right, r.bottom);
  Nlm_LoadRect (&zoom, (Nlm_Int2)(r.left  + 4), (Nlm_Int2)(r.top    + 40),
                       (Nlm_Int2)(r.right - 4), (Nlm_Int2)(r.bottom -  4));
  Nlm_LoadRect (&r, 0, 0, 0, 0);

#ifdef DCLAP
#ifdef WIN_MSWIN
  hsb = 6; vsb = 4;  /* dgg -- patch for mswin sizebar space */
#endif
#endif

  Nlm_LoadBoxData ((Nlm_BoX) w, pt, pt, pt, margin, margin,
                   (Nlm_Int2)(margin + hsb), (Nlm_Int2)(margin + vsb),
                   spacing, spacing, 0, 0);
  Nlm_LoadWindowData (w, wptr, shl, prt, man, &drag, &grow, &zoom,
                      close, NULL, NULL, resize, NULL, NULL, NULL,
                      TRUE, FALSE, ttl, NULL, NULL, NULL);


#ifdef WIN_MSWIN
  {{
  Nlm_WindowData wdata;
  Nlm_GetWindowData(w, &wdata);
  wdata.style    = style;
  wdata.ex_style = ex_style;
  wdata.haccel   = 0;
  Nlm_SetWindowData(w, &wdata);
  }}
#endif
#ifdef WIN_MOTIF
  if ( is_cMap )
    {
      Nlm_WindowData wdata;
      Nlm_GetWindowData(w, &wdata);
      wdata.cMap       = cMap;
      wdata.visual     = visual;
      wdata.cMap_fixed = TRUE;
      Nlm_SetWindowData(w, &wdata);
    }
  Nlm_UseWindow( w );
#endif
}


#ifdef WIN_MAC
static Nlm_WindoW Nlm_NextVisWindow (Nlm_WindoW w)

{
  WindowPtr  p;
  WindowPtr  q = NULL;

  if (w == Nlm_desktopWindow) {
    return Nlm_desktopWindow;
  } else {
    p = Nlm_ParentWindowPtr((Nlm_GraphiC) w);
    while (p != NULL) {
      q = GetNextWindow(p);
      if (q != NULL) {
        if (IsWindowVisible(q)) {
          p = NULL;
        } else {
          p = q;
        }
      } else {
        p = q;
      }
    }
    return Nlm_FindWindowRec ((Nlm_WindowTool) q);
  }
}
#endif

static void Nlm_HideWindow (Nlm_GraphiC w, Nlm_Boolean setFlag, Nlm_Boolean savePort)
{
  Nlm_WindowTool  wptr;
#ifdef WIN_MOTIF
  Nlm_ShellTool   shl;
#endif

  wptr = Nlm_ParentWindowPtr (w);
  Nlm_SetVisible (w, FALSE);
#ifdef WIN_MAC
  HideWindow (wptr);
  if (appWndDeact != NULL) {
    appWndDeact ((Nlm_WindoW) w);
  }
  Nlm_Update ();
#endif
#ifdef WIN_MSWIN
  ShowWindow (wptr, SW_HIDE);
  if (appWndDeact != NULL) {
    appWndDeact ((Nlm_WindoW) w);
  }
  Nlm_Update ();
#endif
#ifdef WIN_MOTIF
  shl = Nlm_GetWindowShell ((Nlm_WindoW) w);
  if (!NLM_QUIET  ||  Nlm_WindowHasBeenShown( (Nlm_WindoW)w ))
    {
      Window focus_win;
      int revert_to;
      XGetInputFocus(Nlm_currentXDisplay, &focus_win, &revert_to);
      if (focus_win == XtWindow( shl ))
        {
          XSetInputFocus(Nlm_currentXDisplay,
                         PointerRoot, RevertToNone, CurrentTime);
          XSync(Nlm_currentXDisplay, FALSE);
        }
      if ( Nlm_IconicWindow( (Nlm_WindoW)w ) )
        {
          XtVaSetValues(shl, XtNiconic, (Boolean)True,  NULL);
          XtVaSetValues(shl, XtNiconic, (Boolean)False, NULL);
          Nlm_Update();
        }
      XtUnmapWidget( shl );
    }
  Nlm_Update ();
#endif
}

/* Thanks to Mike Isaev for suggesting this solution to modal windows. */

static void Nlm_EnableOneWindow (Nlm_WindoW w, Nlm_Boolean onOffFlag)

{
#ifdef WIN_MSWIN
  Nlm_WindowTool  wptr;
#endif
#ifdef WIN_MOTIF
  Nlm_ShellTool   shl;
#endif

  if (w != NULL && w != Nlm_desktopWindow && w != Nlm_systemWindow) {
#ifdef WIN_MSWIN
    wptr = Nlm_GetWindowPtr (w);
    EnableWindow (wptr, onOffFlag);
#endif
#ifdef WIN_MOTIF
    shl = Nlm_GetWindowShell (w);
    XtSetSensitive(shl, onOffFlag);
#endif
  }
}

static void Nlm_EnableOtherWindows (Nlm_WindoW notThisWindow, Nlm_Boolean onOffFlag)

{
  Nlm_WindoW  w;

  w = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) Nlm_desktopWindow);
  while (w != NULL && w != Nlm_systemWindow) {
    if (w != notThisWindow) {
      Nlm_EnableOneWindow (w, onOffFlag);
    }
    w = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) w);
  }
}

/* esl++ */
extern Nlm_Boolean Nlm_IsWindowModal (Nlm_WindoW w)
{
  Nlm_GphPrcsPtr  classPtr;

  if (w != NULL) {
    classPtr = Nlm_GetClassPtr ((Nlm_GraphiC) w);
    if (classPtr == modalProcs || classPtr == movableModalProcs) return TRUE;
  }
  return FALSE;
}

/* esl++ */
static void Nlm_HideAndActivateOwner (Nlm_WindoW w, Nlm_WindoW owner)
{
  /* first of all, select owner window */
  Nlm_Select ((Nlm_GraphiC) owner);
  /* then hide window */
  if (w != NULL && w != Nlm_desktopWindow) {
    Nlm_WindowTool wptr = Nlm_ParentWindowPtr ((Nlm_GraphiC) w);
    if (wptr == Nlm_currentWindowTool) {
      Nlm_HideWindow ((Nlm_GraphiC) w, FALSE, FALSE);
      return;
    }
    if (wptr  &&  !Nlm_IsWindowDying((Nlm_WindoW) w)) {
      Nlm_SetVisible ((Nlm_GraphiC) w, FALSE);
#ifdef WIN_MAC
      ShowHide (wptr, FALSE);
      Nlm_Update ();
#endif
#ifdef WIN_MSWIN
      SetWindowPos (wptr, NULL, 0, 0, 0, 0,
                    SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|
                    SWP_NOZORDER);
      Nlm_Update ();
#endif
#ifdef WIN_MOTIF
      {
        Nlm_ShellTool shl = Nlm_GetWindowShell ((Nlm_WindoW) w);
        if (!NLM_QUIET  ||  Nlm_WindowHasBeenShown( (Nlm_WindoW)w ))
          XtUnmapWidget (shl);
        Nlm_Update ();
      }
#endif
    }
  }
}

static void Nlm_HideModal (Nlm_GraphiC w, Nlm_Boolean setFlag, Nlm_Boolean savePort)
{
  /* esl: handle nested modal dialogs */
  if (w != NULL) {
    Nlm_WindowData wdata;
    Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
    Nlm_HideAndActivateOwner ((Nlm_WindoW) w, wdata.modalOwner);
    if (Nlm_IsWindowModal (wdata.modalOwner)) {
      /* enable previous modal dialog only */
      Nlm_EnableOneWindow (wdata.modalOwner, TRUE);
    } else {
      /* enable all windows */
      Nlm_EnableOtherWindows ((Nlm_WindoW) w, TRUE);
    }
  }
}


static void Nlm_RemoveWindow (Nlm_GraphiC w, Nlm_Boolean savePort)

{
  Nlm_WindoW      nxt;
  Nlm_WindoW      p;
  Nlm_WindoW      q;
  Nlm_WindowData  wdata;
#ifdef WIN_MOTIF
  Nlm_ShellTool   shl;
#endif

  if ((Nlm_WindoW) w != Nlm_desktopWindow && (Nlm_WindoW) w != Nlm_systemWindow) {
    q = Nlm_desktopWindow;
    p = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) Nlm_desktopWindow);
    while (p != NULL && p != (Nlm_WindoW) w) {
      q = p;
      p = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) p);
    }
    if (p != NULL) {
      Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
      wdata.timer = NULL;
      Nlm_SetWindowData ((Nlm_WindoW) w, &wdata);
#ifdef WIN_MAC
      HideWindow (Nlm_GetWindowPtr ((Nlm_WindoW) w));
      Nlm_Update ();
#endif
#ifdef WIN_MSWIN
      ShowWindow (Nlm_GetWindowPtr ((Nlm_WindoW) w), SW_HIDE);
#endif
#ifdef WIN_MOTIF
      shl = Nlm_GetWindowShell ((Nlm_WindoW) w);
      if (NLM_QUIET) {
        if (Nlm_WindowHasBeenShown ((Nlm_WindoW) w)) {
          XtUnmapWidget (shl);
        }
      } else {
        XtUnmapWidget (shl);
      }
#endif
      Nlm_SetWindowDying ((Nlm_WindoW) w, TRUE);
      nxt = (Nlm_WindoW) Nlm_GetNext (w);
      Nlm_SetNext ((Nlm_GraphiC) q, (Nlm_GraphiC) nxt);
      Nlm_SetNext (w, (Nlm_GraphiC) dyingWindow);
      dyingWindow = (Nlm_WindoW) w;
      /* prevents parent lockout under Linux/LessTif, maybe others (thiessen) */
      if (Nlm_IsWindowModal((Nlm_WindoW) w))
        Nlm_HideModal(w, FALSE, FALSE);
    }
  }
  Nlm_Update ();
}

NLM_EXTERN void Nlm_UseFullScreen (void)

{
  Nlm_screenMode = USE_FULL_SCREEN;
}

NLM_EXTERN void Nlm_UseLeftScreen (void)

{
  Nlm_screenMode = USE_LEFT_SCREEN;
}

NLM_EXTERN void Nlm_UseRightScreen (void)

{
  Nlm_screenMode = USE_RIGHT_SCREEN;
}

NLM_EXTERN void Nlm_UsePrimaryMonitor (void)

{
  Nlm_screenMode = USE_PRIMARY_MONITOR;
}

NLM_EXTERN Nlm_Boolean Nlm_HasDualScreen (void)

{
#if(WINVER >= 0x0500)
  int num_monitors = GetSystemMetrics (SM_CMONITORS);
  if (num_monitors == 2) {
    return TRUE;
  }
  return FALSE;
#else
  if (screenBitBounds.right > 2000 && screenBitBounds.bottom < 800) {
    return TRUE;
  } else if (screenBitBounds.right > 2500 && screenBitBounds.bottom < 1100) {
    return TRUE;
  }
  return FALSE;
#endif
}

NLM_EXTERN Nlm_Boolean Nlm_IsRemoteDesktop (void)

{
#if(WINVER >= 0x0500)
  int iRemoteSession = GetSystemMetrics (SM_REMOTESESSION);
  if (iRemoteSession) {
    return TRUE;
  }
  return FALSE;
#else
  return FALSE;
#endif
}

/* esl: extraWidth parameter added */
static void Nlm_ResizeWindow (Nlm_GraphiC w, Nlm_Int2 dragHeight,
                              Nlm_Int2 scrollWidth, Nlm_Int2 minWidth,
                              Nlm_Int2 extraWidth, Nlm_Int2 extraHeight)

{
  Nlm_BoxData     bdata;
  Nlm_Int4        free;
  Nlm_Int4        height, width;
  Nlm_Int4        leftpix;
  Nlm_PoinT       lpt;
  Nlm_Int2        menuHeight = 0;
  Nlm_RecT        r;
  Nlm_Int4        rleft;
  Nlm_Int4        rtop;
  Nlm_ScreenMode  screenMode;
  Nlm_Int4        toppix;
  Nlm_WindowTool  wptr;
#ifdef WIN_MOTIF
  Nlm_MainTool    man;
  Nlm_ShellTool   shl;
  Window          xtw;
#endif

  if ( Nlm_WindowHasBeenShown((Nlm_WindoW) w) )  return;

  Nlm_SetRealized(w, TRUE);

#ifdef WIN_MAC
  menuHeight = 21;
#ifndef WIN_MAC_QUARTZ
  TextFont (0);
  TextSize (0);
#endif
#endif
#ifdef WIN_MOTIF
  if (Nlm_GetWindowMenuBar( (Nlm_WindoW)w ) != NULL)
    menuHeight = Nlm_internalMenuBarHeight;
#endif

  Nlm_GetRect (w, &r);
  if (r.left < 0 || r.right < 0 || r.top < 0 || r.bottom < 0) {
    Nlm_GetBoxData ((Nlm_BoX) w, &bdata);
    lpt = bdata.limitPoint;
    if (r.right < 0)
      {
        width = lpt.x + scrollWidth + bdata.xMargin;
        if (width < minWidth)
          width = minWidth;
      }
    else
      width = r.right;
    width += extraWidth; /* esl */

    if (r.bottom < 0)
      height = lpt.y + scrollWidth + extraHeight + bdata.yMargin;
    else
      height = r.bottom + extraHeight;
    if (r.left < 0)
      {
#if(WINVER >= 0x0500)
        if (Nlm_HasDualScreen ()) {
          screenMode = Nlm_GetScreenMode ((Nlm_WindoW) w);
          if (screenMode == USE_PRIMARY_MONITOR) {
            free = (screenBitBounds.right - screenBitBounds.left) / 2 - width;
            rleft = (Nlm_Int4)r.left;
            leftpix = free * (-rleft) / 100;
            r.left = (Nlm_Int2)leftpix;
      } else if (screenMode == USE_LEFT_SCREEN) {
            free = (screenBitBounds.right - screenBitBounds.left) / 2 - width;
            rleft = (Nlm_Int4)r.left;
            leftpix = free * (-rleft) / 100;
            r.left = (Nlm_Int2)leftpix + screenBitBounds.left;
          } else if (screenMode == USE_RIGHT_SCREEN) {
            free = (screenBitBounds.right - screenBitBounds.left) / 2 - width;
            rleft = (Nlm_Int4)r.left;
            leftpix = free * (-rleft) / 100;
            r.left = (Nlm_Int2)leftpix + screenBitBounds.left;
            r.left += (screenBitBounds.right - screenBitBounds.left) / 2;
          } else {
            free = (screenBitBounds.right - screenBitBounds.left) - width;
            rleft = (Nlm_Int4)r.left;
            leftpix = free * (-rleft) / 100;
            r.left = (Nlm_Int2)leftpix + screenBitBounds.left;
          }
        } else {
          free = screenBitBounds.right - width;
          rleft = (Nlm_Int4)r.left;
          leftpix = free * (-rleft) / 100;
          r.left = (Nlm_Int2)leftpix;
        }
#else
        if (Nlm_HasDualScreen ()) {
          screenMode = Nlm_GetScreenMode ((Nlm_WindoW) w);
          if (screenMode == USE_LEFT_SCREEN) {
            free = screenBitBounds.right / 2 - width;
            rleft = (Nlm_Int4)r.left;
            leftpix = free * (-rleft) / 100;
            r.left = (Nlm_Int2)leftpix;
          } else if (screenMode == USE_RIGHT_SCREEN) {
            free = screenBitBounds.right / 2 - width;
            rleft = (Nlm_Int4)r.left;
            leftpix = free * (-rleft) / 100;
            r.left = (Nlm_Int2)leftpix;
            r.left += screenBitBounds.right / 2;
          } else {
            free = screenBitBounds.right - width;
            rleft = (Nlm_Int4)r.left;
            leftpix = free * (-rleft) / 100;
            r.left = (Nlm_Int2)leftpix;
          }
        } else {
          free = screenBitBounds.right - width;
          rleft = (Nlm_Int4)r.left;
          leftpix = free * (-rleft) / 100;
          r.left = (Nlm_Int2)leftpix;
        }
#endif
      }
    if (r.top < 0)
      {
        free = screenBitBounds.bottom - height - menuHeight - dragHeight;
        rtop = (Nlm_Int4)r.top;
        toppix = free * (-rtop) / 100;
        r.top = (Nlm_Int2)(toppix + menuHeight + dragHeight);
      }
    r.right  = (Nlm_Int2)(r.left + width);
    r.bottom = (Nlm_Int2)(r.top  + height);
#ifdef WIN_MOTIF
    r.bottom -= menuHeight;
#endif
    Nlm_SetRect(w, &r);

    wptr = Nlm_GetWindowPtr( (Nlm_WindoW)w );
#ifdef WIN_MAC
    SizeWindow (wptr, width, height, FALSE);
    MoveWindow (wptr, r.left, r.top, FALSE);
#endif
#ifdef WIN_MSWIN
    {{
    RECT wr;
    client2win((Nlm_WindoW)w, &r, &wr);
    Nlm_SetRect(w, &r);
    MoveWindow(wptr, wr.left, wr.top,
               (wr.right - wr.left), (wr.bottom - wr.top), FALSE);
    }}
#endif
#ifdef WIN_MOTIF
    shl = Nlm_GetWindowShell ((Nlm_WindoW) w);
    man = Nlm_GetWindowMain ((Nlm_WindoW) w);
    XtVaSetValues (shl,
                   XmNx, (Position) r.left,
                   XmNy, (Position) r.top,
                   XmNwidth,  (Dimension) width,
                   XmNheight, (Dimension) height,
                   NULL);
    XtVaSetValues (man,
                   XmNwidth,  (Dimension) width,
                   XmNheight, (Dimension) height,
                   NULL);
    XtVaSetValues (wptr,
                   XmNwidth,  (Dimension) width,
                   XmNheight, (Dimension) height,
                   NULL);
#endif
  }

#ifdef WIN_MOTIF
  if (NLM_QUIET  &&  !Nlm_IsWindowDying((Nlm_WindoW) w))  {
    shl = Nlm_GetWindowShell ((Nlm_WindoW) w);
    XtRealizeWidget (shl);
    man = Nlm_GetWindowMain ((Nlm_WindoW) w);
    xtw = XtWindow( man );
    if ( xtw )
      XDefineCursor(Nlm_currentXDisplay, xtw, Nlm_currentCursor);
  }
#endif
}


static void Nlm_ShowNormal (Nlm_GraphiC w, Nlm_Boolean setFlag, Nlm_Boolean savePort)

{
  Nlm_Char        title [256];
  Nlm_WindowTool  wptr;
#ifdef WIN_MOTIF
  Nlm_Int2        extrah;
  Nlm_ShellTool   shl;
#endif

  wptr = Nlm_ParentWindowPtr (w);
  Nlm_GetWindowTitle (w, 0, title, sizeof (title));
#ifdef WIN_MAC
  Nlm_ResizeWindow (w, 20, 0, Nlm_StringWidth (title) + 70, 0, 0);
  Nlm_SetNotYetShown ((Nlm_WindoW) w, FALSE);
  if (setFlag) {
    Nlm_SetVisible (w, TRUE);
    ShowWindow (wptr);
  }
#endif
#ifdef WIN_MSWIN
  Nlm_ResizeWindow (w, 0, 0, (Nlm_Int2)(Nlm_StringWidth(title) + 80), 0, 0);
  Nlm_SetNotYetShown ((Nlm_WindoW) w, FALSE);
  if (setFlag) {
    Nlm_SetVisible (w, TRUE);
    ShowWindow (wptr, SW_SHOWNORMAL);
    UpdateWindow (wptr);
  }
#endif
#ifdef WIN_MOTIF
  extrah = 0;
  if (Nlm_GetWindowMenuBar ((Nlm_WindoW) w) != NULL) {
    extrah += 31;
  }
  Nlm_ResizeWindow (w, 0, 0, Nlm_StringWidth (title) + 65, 0, extrah);
  Nlm_SetNotYetShown ((Nlm_WindoW) w, FALSE);
  if (setFlag) {
    Nlm_SetVisible (w, TRUE);
    shl = Nlm_GetWindowShell ((Nlm_WindoW) w);
    XtMapWidget (shl);
  }
#endif
  Nlm_Update ();
}

static void Nlm_ShowModal (Nlm_GraphiC w, Nlm_Boolean setFlag, Nlm_Boolean savePort)

{
  Nlm_Char        title [256];
  Nlm_WindowTool  wptr;
#ifdef WIN_MOTIF
  Nlm_Int2        extrah;
  Nlm_ShellTool   shl;
#endif

  wptr = Nlm_ParentWindowPtr (w);
  Nlm_GetWindowTitle (w, 0, title, sizeof (title));
#ifdef WIN_MAC
  Nlm_ResizeWindow (w, 20, 0, Nlm_StringWidth (title) + 70, 0, 0);
  Nlm_SetNotYetShown ((Nlm_WindoW) w, FALSE);
  if (setFlag) {
    Nlm_SetVisible (w, TRUE);
    ShowWindow (wptr);
  }
#endif
#ifdef WIN_MSWIN
  Nlm_ResizeWindow (w, 0, 0, (Nlm_Int2)(Nlm_StringWidth(title) + 80), 0, 0);
  Nlm_SetNotYetShown ((Nlm_WindoW) w, FALSE);
  if (setFlag) {
    Nlm_SetVisible (w, TRUE);
    ShowWindow (wptr, SW_SHOWNORMAL);
    UpdateWindow (wptr);
  }
#endif
#ifdef WIN_MOTIF
  extrah = 0;
  if (Nlm_GetWindowMenuBar ((Nlm_WindoW) w) != NULL) {
    extrah += 31;
  }
  Nlm_ResizeWindow (w, 0, 0, Nlm_StringWidth (title) + 65, 0, extrah);
  Nlm_SetNotYetShown ((Nlm_WindoW) w, FALSE);
  if (setFlag) {
    Nlm_SetVisible (w, TRUE);
    shl = Nlm_GetWindowShell ((Nlm_WindoW) w);
    XtMapWidget (shl);
  }
#endif
  Nlm_Update ();
  Nlm_EnableOtherWindows ((Nlm_WindoW ) w, FALSE);
}

static void Nlm_ShowDocument (Nlm_GraphiC w, Nlm_Boolean setFlag, Nlm_Boolean savePort)

{
  Nlm_Char        title [256];
  Nlm_WindowTool  wptr;
#ifdef WIN_MOTIF
  Nlm_Int2        extrah;
  Nlm_ShellTool   shl;
#endif

  wptr = Nlm_ParentWindowPtr (w);
  Nlm_GetWindowTitle (w, 0, title, sizeof (title));
#ifdef WIN_MAC
  Nlm_ResizeWindow (w, 20, 0, Nlm_StringWidth (title) + 70, 0, 0);
  Nlm_SetNotYetShown ((Nlm_WindoW) w, FALSE);
  if (setFlag) {
    Nlm_SetVisible (w, TRUE);
    ShowWindow (wptr);
  }
#endif
#ifdef WIN_MSWIN
  Nlm_ResizeWindow (w, 0, 0, (Nlm_Int2)(Nlm_StringWidth(title) + 80), 0, 0);
  Nlm_SetNotYetShown ((Nlm_WindoW) w, FALSE);
  if (setFlag) {
    Nlm_SetVisible (w, TRUE);
    ShowWindow (wptr, SW_SHOWNORMAL);
    UpdateWindow (wptr);
  }
#endif
#ifdef WIN_MOTIF
  extrah = 0;
  if (Nlm_GetWindowMenuBar ((Nlm_WindoW) w) != NULL) {
    extrah += 31;
  }
  Nlm_ResizeWindow (w, 0, 0, Nlm_StringWidth (title) + 65, 0, extrah);
  Nlm_SetNotYetShown ((Nlm_WindoW) w, FALSE);
  if (setFlag) {
    Nlm_SetVisible (w, TRUE);
    shl = Nlm_GetWindowShell ((Nlm_WindoW) w);
    XtMapWidget (shl);
  }
#endif
  Nlm_Update ();
}


static void Nlm_SetWindowPosition (Nlm_GraphiC w, Nlm_RectPtr r,
                                   Nlm_Boolean savePort, Nlm_Boolean force)
{
  Nlm_Int2        height;
  Nlm_RecT        rct;
  Nlm_Int2        width;
  Nlm_WindowTool  wptr;
#ifdef WIN_MOTIF
  Nlm_MainTool    man;
  Nlm_ShellTool   shl;
#endif

  if (r == NULL)  return;

  rct = *r;
  width  = (Nlm_Int2)(rct.right  - rct.left);
  height = (Nlm_Int2)(rct.bottom - rct.top );
  if (Nlm_GetWindowMenuBar( (Nlm_WindoW)w ) != NULL)
    rct.bottom -= Nlm_internalMenuBarHeight;
  Nlm_SetRect (w, &rct);

  if ( !Nlm_GetRealized( w ) )  return;

  wptr = Nlm_GetWindowPtr ((Nlm_WindoW) w);
#ifdef WIN_MAC
    MoveWindow (wptr, rct.left, rct.top, FALSE);
    SizeWindow (wptr, width, height, TRUE);
#endif
#ifdef WIN_MSWIN
    {{
    RECT wr;
    client2win((Nlm_WindoW)w, &rct, &wr);
    MoveWindow(wptr, wr.left, wr.top,
               (wr.right - wr.left), (wr.bottom - wr.top), TRUE);
    }}
#endif
#ifdef WIN_MOTIF
    shl = Nlm_GetWindowShell ((Nlm_WindoW) w);
    man = Nlm_GetWindowMain  ((Nlm_WindoW) w);
    XtVaSetValues (shl,
                   XmNx, (Position) rct.left,
                   XmNy, (Position) rct.top,
                   XmNwidth,  (Dimension) width,
                   XmNheight, (Dimension) height,
                   NULL);
    XtVaSetValues (man,
                   XmNwidth,  (Dimension) width,
                   XmNheight, (Dimension) height,
                   NULL);
    XtVaSetValues (wptr,
                   XmNwidth,  (Dimension) width,
                   XmNheight, (Dimension) height,
                   NULL);
#endif
}


static void Nlm_GetWindowPosition (Nlm_GraphiC w, Nlm_RectPtr r)

{
  if (r != NULL) {
    Nlm_GetRect (w, r);
    if (Nlm_GetWindowMenuBar ((Nlm_WindoW) w) != NULL)
      r->bottom += Nlm_internalMenuBarHeight;
  }
}

#if defined(LESSTIF_VERSION)

static void FixVisibilityIssues (Nlm_GraphiC g)
{
  Nlm_GraphiC child;

  for (child = Nlm_GetChild (g);  child != NULL; child = Nlm_GetNext (child))
  {
    if (!Nlm_GetVisible (child))
    {
      Nlm_Show (child);
      FixVisibilityIssues (child);
      Nlm_Hide (child);
    }
    else
    {
      FixVisibilityIssues (child);
    }
  }
}
#endif

extern void Nlm_RealizeWindow (Nlm_WindoW w)

{
  if (w != NULL) {
    Nlm_DoShow ((Nlm_GraphiC) w, FALSE, TRUE);
  }

#if defined(LESSTIF_VERSION)
  FixVisibilityIssues ((Nlm_GraphiC) w);
#endif
}

extern void Nlm_IconifyWindow(Nlm_WindoW w)
{
#if defined(WIN_MOTIF)
  XtVaSetValues(Nlm_GetWindowShell(w), XtNiconic, (Boolean)True, NULL);
  Nlm_Update();
#elif defined(WIN_MSWIN)
  ShowWindow(Nlm_ParentWindowPtr((Nlm_GraphiC)w), SW_MINIMIZE);
  Nlm_SetVisible((Nlm_GraphiC)w, FALSE);
#endif
}


extern Nlm_Boolean Nlm_IconicWindow(Nlm_WindoW w)
{
#if defined(WIN_MOTIF)
  /* (X-technique from Ken Sall's function CheckWinMgrState() */
  unsigned long *property = NULL;
  unsigned long nitems;
  unsigned long leftover;
  Atom          xa_WM_STATE, actual_type;
  int           actual_format;
  int           status;

  Widget   shl = Nlm_GetWindowShell( w );
  Display *dpy = XtDisplay( shl );
  Window   win = XtWindow ( shl );

  if ( !win )
    return FALSE;

  xa_WM_STATE = XInternAtom(dpy, "WM_STATE", False);
  status  = XGetWindowProperty(dpy, win, xa_WM_STATE, 0L, 1L,
                               False, xa_WM_STATE,
                               &actual_type, &actual_format,
                               &nitems, &leftover,
                               (unsigned char **)&property);

  status = (status == Success  &&  actual_type == xa_WM_STATE  &&
            nitems == 1  &&  property  &&  *property == IconicState);

  if ( property )
    XFree( (char *)property );
  return (Nlm_Boolean)status;
#elif defined(WIN_MSWIN)
  return (Nlm_Boolean)IsIconic( Nlm_ParentWindowPtr((Nlm_GraphiC)w) );
#else
  return FALSE;
#endif
}


extern Nlm_WindoW Nlm_WhichWindow (Nlm_PoinT mouseLoc)
{
#ifdef WIN_MAC
  Nlm_PoinT       point;
  Nlm_PointTool   ptool;
  Nlm_Int2        windowLoc;
  Nlm_WindowTool  wptr;

  point = mouseLoc;
  Nlm_LocalToGlobal (&point);
  Nlm_PoinTToPointTool (point, &ptool);
  windowLoc = FindWindow (ptool, &wptr);
  return Nlm_FindWindowRec (wptr);
#endif
#ifdef WIN_MSWIN
  Nlm_PoinT       point;
  Nlm_PointTool   ptool;
  Nlm_WindoW      rsult;
  Nlm_WindowTool  wptr;

  rsult = NULL;
  point = mouseLoc;
  Nlm_LocalToGlobal (&point);
  Nlm_PoinTToPointTool (point, &ptool);
  wptr = WindowFromPoint (ptool);
  if ( wptr ) {
    rsult = (Nlm_WindoW) GetProp (wptr, (LPSTR) "Nlm_VibrantProp");
  }
  return rsult;
#endif
#ifdef WIN_MOTIF
  return NULL;
#endif
}

extern Nlm_Boolean Nlm_InWindow (Nlm_PoinT mouseLoc)

{
  return (Nlm_Boolean) (Nlm_WhichWindow (mouseLoc) != Nlm_desktopWindow);
}

extern Nlm_WindoW Nlm_FrontWindow(void)

{
#ifdef WIN_MAC
  return (Nlm_FindWindowRec (FrontWindow ()));
#endif
#ifdef WIN_MSWIN
  return (Nlm_FindWindowRec (Nlm_currentHWnd));
#endif
#ifdef WIN_MOTIF
  return NULL;
#endif
}

extern Nlm_Boolean Nlm_InFront (Nlm_WindoW w)

{
#ifdef WIN_MAC
  return (w == Nlm_FrontWindow ());
#endif
#ifdef WIN_MSWIN
  return FALSE;
#endif
#ifdef WIN_MOTIF
  return FALSE;
#endif
}

extern void Nlm_UseWindow (Nlm_WindoW w)

{
  Nlm_WindowTool  wptr;
#ifdef WIN_MOTIF
  Nlm_ShellTool   shl;
#endif

  if (w != NULL && w != Nlm_desktopWindow) {
    wptr = Nlm_ParentWindowPtr ((Nlm_GraphiC) w);
    if (wptr  &&  !Nlm_IsWindowDying( w )) {
#ifdef WIN_MAC
#ifndef WIN_MAC_QUARTZ
      Nlm_SetPortWindowPort(wptr);
      Nlm_SetUpdateRegion (wptr);
      Nlm_ResetDrawingTools();
#endif
      Nlm_theWindow = w;
#endif
#ifdef WIN_MSWIN
      Nlm_currentHDC = Nlm_GetWindowPort (w);
      Nlm_currentHWnd = wptr;
#endif
#ifdef WIN_MOTIF
      shl = Nlm_GetWindowShell (w);
      Nlm_currentXWindow = XtWindow (shl);
      Nlm_currentXGC = Nlm_GetWindowPort (w);
#endif
      Nlm_currentWindowTool = wptr;
    }
  }
}

extern Nlm_WindoW Nlm_CurrentWindow(void)

{
  Nlm_WindoW  rsult;

  rsult = Nlm_FindWindowRec (Nlm_currentWindowTool);
  return rsult;
}

extern Nlm_Boolean Nlm_UsingWindow (Nlm_WindoW w)

{
  return (Nlm_Boolean) (w == Nlm_CurrentWindow ());
}

extern Nlm_WindoW Nlm_ActiveWindow (void)

{
  Nlm_WindoW      rsult;
#ifdef WIN_MSWIN
  Nlm_WindowTool  wptr;
#endif

  rsult = NULL;
#ifdef WIN_MAC
  rsult = Nlm_theWindow;
#endif
#ifdef WIN_MSWIN
  wptr = GetActiveWindow ();
  if (wptr != NULL) {
    rsult = (Nlm_WindoW) GetProp (wptr, (LPSTR) "Nlm_VibrantProp");
  }
#endif
#ifdef WIN_MOTIF
#endif
  return rsult;
}

#ifdef WIN_MAC
/*
static Nlm_WindoW Nlm_PrevVisWindow (Nlm_WindoW w)

{
  WindowPtr  p;
  WindowPtr  q;
  WindowPtr  t;

  if (frontWindow == Nlm_desktopWindow) {
    return Nlm_desktopWindow;
  } else if (frontWindow == w) {
    return frontWindow;
  } else {
    p = Nlm_ParentWindowPtr ((Nlm_GraphiC) frontWindow);
    q = p;
    t = Nlm_ParentWindowPtr ((Nlm_GraphiC) w);
    while (p != NULL) {
      if (p == t) {
        p = NULL;
      } else if (IsWindowVisible(p)) {
        q = p;
        p = GetNextWindow(p);
      } else {
        p = GetNextWindow(p);
      }
    }
    return (Nlm_FindWindowRec ((Nlm_WindowTool) q));
  }
}
*/
#endif


static void Nlm_SelectWindow(Nlm_GraphiC w, Nlm_Boolean savePort)

{
  Nlm_WindowTool  wptr;

  if (w == NULL  ||  (Nlm_WindoW)w == Nlm_desktopWindow)
    return;

  wptr = Nlm_ParentWindowPtr( w );
  if (wptr == NULL  ||  Nlm_IsWindowDying( (Nlm_WindoW)w ))
    return;

#ifdef WIN_MAC
  SelectWindow (wptr);
#ifndef WIN_MAC_QUARTZ
  Nlm_SetPortWindowPort(wptr);
  Nlm_SetUpdateRegion(wptr);
  Nlm_ResetDrawingTools();
#endif
#endif
#ifdef WIN_MSWIN
  BringWindowToTop (wptr);
/* M.I */
  if( IsIconic( wptr ) )
    ShowWindow( wptr, SW_RESTORE );  /* de-Iconize window */
/* M.I */
  Nlm_currentHDC = Nlm_GetWindowPort ((Nlm_WindoW) w);
  Nlm_currentHWnd = wptr;
#endif
#ifdef WIN_MOTIF
  selectShell = Nlm_GetWindowShell( (Nlm_WindoW)w );
  if (Nlm_currentXDisplay == NULL  ||  !XtIsRealized( selectShell ))
    return;

  {{
    Window selectWin = XtWindow( selectShell );
    Window focus_win;
    int revert_to;
    
    XMapRaised(Nlm_currentXDisplay, selectWin);
    XGetInputFocus(Nlm_currentXDisplay, &focus_win, &revert_to);
    if (focus_win != selectWin)
      {
        XWindowAttributes attr;
        XGetWindowAttributes(Nlm_currentXDisplay, selectWin, &attr);
        if (attr.map_state != IsViewable)
          return;
        
        XSetInputFocus(Nlm_currentXDisplay, selectWin,
                       RevertToPointerRoot, CurrentTime);
        selectShell = NULL;
      }
  }}
  Nlm_UseWindow( (Nlm_WindoW)w );
#endif

  Nlm_currentWindowTool = wptr;
  Nlm_Update ();
}


extern void Nlm_PopupParentWindow(Nlm_Handle a)
{
  Nlm_WindoW     w = Nlm_ParentWindow( a );
  Nlm_WindowTool wptr;

  if (w == NULL  ||  w == Nlm_desktopWindow  ||  Nlm_IsWindowDying( w ))
    return;

  if ( !Nlm_Visible( w ) )
    {
      Nlm_Show( w );
      return;
    }

  wptr = Nlm_ParentWindowPtr( (Nlm_GraphiC)w );
  if ( !wptr )
    return;

#ifdef WIN_MAC
  SelectWindow (wptr);
  Nlm_SetUpdateRegion (wptr);
  Nlm_ResetDrawingTools ();
#endif
#ifdef WIN_MSWIN
  if( IsIconic(wptr) )
    ShowWindow(wptr, SW_RESTORE);
  else
    SetWindowPos(wptr, HWND_TOP, 0, 0, 0, 0,
                 SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_SHOWWINDOW);
#endif
#ifdef WIN_MOTIF
  {{
    Widget selShell = Nlm_GetWindowShell( w );
    if (Nlm_currentXDisplay == NULL  ||  !XtIsRealized( selShell ))
      return;

    XMapRaised(Nlm_currentXDisplay, XtWindow( selShell ));
  }}
#endif

  Nlm_Update ();
}


extern void Nlm_EraseWindow (Nlm_WindoW w)

{
#ifdef WIN_MAC
  Nlm_RecT        r;
  Nlm_PortTool    temp;
  Nlm_WindowTool  wptr;
  Rect bounds;

  if (w != NULL) {
    wptr = Nlm_ParentWindowPtr ((Nlm_GraphiC) w);
#ifdef WIN_MAC_QUARTZ
    HIViewSetNeedsDisplay (HIViewGetRoot (wptr), 1);
#else
    GetPort(&temp);
    Nlm_SetPortWindowPort(wptr);
    Nlm_ResetDrawingTools();
    Nlm_currentWindowTool = wptr;
    GetPortBounds(GetWindowPort(wptr), &bounds);
    Nlm_RectToolToRecT (&bounds, &r);
    Nlm_EraseRect(&r);
    Nlm_SetPort(temp);
    Nlm_currentWindowTool = GetWindowFromPort(temp);
    Nlm_Update();
#endif
  }
#endif
#ifdef WIN_MSWIN
#endif
#ifdef WIN_MOTIF
#endif
}

#ifdef WIN_MAC
static Nlm_Boolean Nlm_DragClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_PointTool   ptool;
  Nlm_RecT        r;
  Nlm_RectTool    rtool;
  Nlm_Boolean     rsult;
  Nlm_Int2        windowLoc;
  Nlm_WindowData  wdata;
  Nlm_WindowTool  wptr;
  Rect bounds;

  rsult = FALSE;
  Nlm_PoinTToPointTool (Nlm_globalMouse, &ptool);
  windowLoc = FindWindow (ptool, &wptr);
  if (windowLoc == inDrag) {
    Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
    Nlm_RecTToRectTool (&(wdata.dragArea), &rtool);
    DragWindow (wptr, ptool, &rtool);
    GetPortBounds(GetWindowPort(wptr), &bounds);
    Nlm_RectToolToRecT (&bounds, &r);
    Nlm_LocalToGlobal ((Nlm_PointPtr) &(r.left));
    Nlm_LocalToGlobal ((Nlm_PointPtr) &(r.right));
    Nlm_SetRect (w, &r);
    rsult = TRUE;
  }
  return rsult;
}

static void Nlm_UpdateScrollBar (Nlm_GraphiC w)

{
  Nlm_RecT        barArea;
  Nlm_WindowTool  wptr;
  Rect bounds;

  wptr = Nlm_ParentWindowPtr (w);
  GetPortBounds(GetWindowPort(wptr), &bounds);
  Nlm_RectToolToRecT (&bounds, &barArea);
  barArea.left = barArea.right - 16;
  if (Nlm_GetWindowMenuBar ((Nlm_WindoW) w) != NULL) {
    barArea.top = barArea.top + 21;
  }
  Nlm_InvalRect (&barArea);
  Nlm_RectToolToRecT (&bounds, &barArea);
  barArea.top = barArea.bottom - 16;
  Nlm_InvalRect (&barArea);
}

static Nlm_Boolean Nlm_GrowClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_Int2         ht;
  Nlm_Int4         newSize;
  Nlm_PointTool    ptool;
  Nlm_RecT         r;
  Nlm_WndActnProc  resize;
  Nlm_RectTool     rtool;
  Nlm_Boolean      rsult;
  Nlm_Int2         wd;
  Nlm_WindowData   wdata;
  Nlm_Int2         windowLoc;
  Nlm_WindowTool   wptr;
  Rect bounds;

  rsult = FALSE;
  Nlm_PoinTToPointTool (Nlm_globalMouse, &ptool);
  windowLoc = FindWindow (ptool, &wptr);
  if (windowLoc == inGrow) {
    Nlm_LoadRect (&r, -32768, -32768, 32767, 32767);
    Nlm_RecTToRectTool (&r, &rtool);
#ifndef WIN_MAC_QUARTZ
    ClipRect (&rtool);
#endif
    Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
    Nlm_RecTToRectTool (&(wdata.growArea), &rtool);
    newSize = GrowWindow (wptr, ptool, &rtool);
    wd = LoWord (newSize);
    ht = HiWord (newSize);
 /* dgg -- bug fix: simple click on grow box caused it to resize to 0 --
    should check here for 0 == no change.  Also make minsize bigger.
 */
    GetPortBounds(GetWindowPort(wptr), &bounds);
    if (! newSize) {
#ifndef WIN_MAC_QUARTZ
      ClipRect (&bounds);
#endif
      return rsult;
    }
    if (wd < 50) {
      wd = 50;
    }
    if (ht < 32) {
      ht = 32;
    }
    bounds.right = bounds.left + wd;
    bounds.bottom = bounds.top + ht;
    Nlm_UpdateScrollBar (w);
    SizeWindow (wptr, wd, ht, TRUE);
    Nlm_UpdateScrollBar (w);
    wptr = Nlm_GetWindowPtr ((Nlm_WindoW) w);
    Nlm_RectToolToRecT (&bounds, &r);
#ifndef WIN_MAC_QUARTZ
    ClipRect (&bounds);
#endif
    Nlm_LocalToGlobal ((Nlm_PointPtr) &(r.left));
    Nlm_LocalToGlobal ((Nlm_PointPtr) &(r.right));
    Nlm_SetRect (w, &r);
    resize = wdata.resize;
    if (resize != NULL) {
      resize ((Nlm_WindoW) w);
    }
    rsult = TRUE;
  }
  return rsult;
}

static void Nlm_DrawGrowIcon (Nlm_GraphiC w, Nlm_Boolean drawgrow, Nlm_Boolean drawbar)

{
  Nlm_RecT        r;
  Nlm_RectTool    rtool;
  PenState        state;
  Nlm_PortTool    temp;
  Nlm_WindowTool  wptr;
  Rect bounds;

#ifndef WIN_MAC_QUARTZ
  GetPort (&temp);
  GetPenState (&state);
#endif
  wptr = Nlm_ParentWindowPtr (w);
  GetPortBounds(GetWindowPort(wptr), &bounds);
  Nlm_RectToolToRecT (&bounds, &r);
  if (drawbar && Nlm_GetWindowMenuBar ((Nlm_WindoW) w) != NULL) {
    Nlm_RecTToRectTool (&r, &rtool);
#ifndef WIN_MAC_QUARTZ
    ClipRect (&rtool);
#endif
    Nlm_MoveTo (r.right - 16, 20);
    Nlm_LineTo (r.right, 20);
    r.top = r.top + 21;
  }
  if (drawgrow) {
    Nlm_RecTToRectTool (&r, &rtool);
    rtool.left = rtool.right - 15;
    rtool.top = rtool.bottom - 15;
#ifndef WIN_MAC_QUARTZ
    ClipRect (&rtool);
#endif
    DrawGrowIcon (wptr);
  }
  Nlm_RecTToRectTool (&r, &rtool);
  r.top = bounds.top;
#ifdef DCLAP
  /* dgg- this cliprect is the culprit for preventing scrollbar updates by subviews */
  /* try clipping a region that excludes just the growicon?? */
#else
  /*
  r.right = r.right - 16;
  r.bottom = r.bottom - 16;
  */
#endif
  Nlm_RecTToRectTool (&r, &rtool);
#ifndef WIN_MAC_QUARTZ
  ClipRect (&rtool);
  Nlm_SetPort(temp);
  Nlm_currentWindowTool = GetWindowFromPort(temp);
  Nlm_SetUpdateRegion (GetWindowFromPort(temp));
  SetPenState (&state);
#endif
}

static Nlm_Boolean Nlm_ZoomClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_PointTool    ptool;
  Nlm_RecT         r;
  Nlm_WndActnProc  resize;
  Nlm_Boolean      rsult;
  Nlm_WindowData   wdata;
  Nlm_Int2         windowLoc;
  Nlm_WindowTool   wptr;

  rsult = FALSE;
  Nlm_PoinTToPointTool (Nlm_globalMouse, &ptool);
  windowLoc = FindWindow (ptool, &wptr);
  if (windowLoc == inZoomIn || windowLoc == inZoomOut) {
#if OPAQUE_TOOLBOX_STRUCTS
    Point idealSize;
    int part;
#else
    Rect stdRect;
    WStateDataHandle wshdl;
#endif
    Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
    r = wdata.zoomArea;
#if OPAQUE_TOOLBOX_STRUCTS
    idealSize.v = r.bottom - r.top;
    idealSize.h = r.right - r.left;
    
    part = IsWindowInStandardState(wptr, &idealSize, NULL) ? inZoomIn : inZoomOut;
    windowLoc = part;
#endif
    
    if (TrackBox (wptr, ptool, windowLoc)) {
      Rect bounds;
      /* WindowPeek::dataHandle is not supported under Carbon. */
#if OPAQUE_TOOLBOX_STRUCTS
      ZoomWindowIdeal(wptr, part, &idealSize);
#else
      wshdl = (WStateDataHandle) ((WindowPeek)wptr)->dataHandle;
      Nlm_RecTToRectTool (&r, &stdRect);
      (*wshdl)->stdState = stdRect;
      GetPortBounds(GetWindowPort(wptr), &bounds);
      Nlm_RectToolToRecT (&bounds, &r);
      ClipRect (&bounds);
      Nlm_EraseRect (&r);
      ZoomWindow (wptr, windowLoc, FALSE);
#endif
      GetPortBounds(GetWindowPort(wptr), &bounds);
      Nlm_UpdateScrollBar (w);
      wptr = Nlm_GetWindowPtr ((Nlm_WindoW) w);
      Nlm_RectToolToRecT (&bounds, &r);
#ifndef WIN_MAC_QUARTZ
      ClipRect (&bounds);
#endif
      Nlm_LocalToGlobal ((Nlm_PointPtr) &(r.left));
      Nlm_LocalToGlobal ((Nlm_PointPtr) &(r.right));
      Nlm_SetRect (w, &r);
      resize = wdata.resize;
      if (resize != NULL) {
        resize ((Nlm_WindoW) w);
      }
    }
    rsult = TRUE;
  }
  return rsult;
}

static Nlm_Boolean Nlm_CloseClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_WndActnProc  cls;
  Nlm_PointTool    ptool;
  Nlm_Boolean      rsult;
  Nlm_WindowData   wdata;
  Nlm_Int2         windowLoc;
  Nlm_WindowTool   wptr;

  rsult = FALSE;
  Nlm_PoinTToPointTool (Nlm_globalMouse, &ptool);
  windowLoc = FindWindow (ptool, &wptr);
  if (windowLoc == inGoAway) {
    if (TrackGoAway (wptr, ptool)) {
      Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
      cls = wdata.close;
      if (cls != NULL) {
        cls ((Nlm_WindoW) w);
      }
    }
    rsult = TRUE;
  }
  return rsult;
}

typedef struct revItem {
  Nlm_GraphiC          graphic;
  struct revItem  PNTR next;
} Nlm_RevItem, PNTR Nlm_RevPtr;

static Nlm_Boolean Nlm_ContentClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_GraphiC    g;
  Nlm_MenuBaR    mb;
  Nlm_RevPtr     next;
  Nlm_Boolean    notInside;
  Nlm_PointTool  ptool;
  Nlm_RevPtr     this;
  Nlm_RevPtr     top;

  Nlm_localMouse = Nlm_globalMouse;
  Nlm_SetPortWindowPort (Nlm_ParentWindowPtr (w));
  Nlm_GlobalToLocal (&Nlm_localMouse);
  g = Nlm_GetChild (w);
  notInside = TRUE;
  mb = Nlm_GetWindowMenuBar ((Nlm_WindoW) w);
  if (mb != NULL) {
    if (Nlm_GetEnabled ((Nlm_GraphiC) mb) && Nlm_GetVisible ((Nlm_GraphiC) mb) &&
        Nlm_DoClick ((Nlm_GraphiC) mb, Nlm_localMouse)) {
      notInside = FALSE;
    }
  }
  /*
  while (g != NULL && notInside) {
    n = Nlm_GetNext (g);
    if (Nlm_GetEnabled (g) && Nlm_GetVisible (g) && Nlm_DoClick (g, Nlm_localMouse)) {
      notInside = FALSE;
    }
    g = n;
  }
  */
  if (g != NULL && notInside) {
    top = NULL;
    while (g != NULL) {
      this = Nlm_MemNew (sizeof (Nlm_RevItem));
      if (this != NULL) {
        this->graphic = g;
        this->next = top;
        top = this;
      }
      g = Nlm_GetNext (g);
    }
    this = top;
    while (this != NULL && notInside) {
      next = this->next;
      g = this->graphic;
      if (Nlm_GetEnabled (g) && Nlm_GetVisible (g) && Nlm_DoClick (g, Nlm_localMouse)) {
        notInside = FALSE;
      }
      this = next;
    }
    this = top;
    while (this != NULL) {
      next = this->next;
      Nlm_MemFree (this);
      this = next;
    }
  }
  if (notInside) {
    GetMouse (&ptool);
    Nlm_PointToolToPoinT (ptool, &Nlm_localMouse);
    if ((Nlm_WindoW) w != Nlm_WhichWindow (Nlm_localMouse)) {
      notInside = FALSE;
    }
  }
  return (! notInside);
}

static Nlm_Boolean Nlm_CommonClick (Nlm_GraphiC w, Nlm_PoinT pt,
                                    Nlm_Boolean close, Nlm_Boolean drag,
                                    Nlm_Boolean grow, Nlm_Boolean zoom)

{
  Nlm_Boolean     rsult;
  PenState        state;
  Nlm_PortTool    temp;
  Nlm_WindowTool  wptr;

  rsult = FALSE;
  if (chosenWindow == (Nlm_WindoW) w) {
    wptr = Nlm_ParentWindowPtr (w);
#ifndef WIN_MAC_QUARTZ
    GetPort (&temp);
    GetPenState (&state);
#endif
#ifndef WIN_MAC_QUARTZ
    Nlm_SetPortWindowPort(wptr);
    Nlm_currentWindowTool = wptr;
    Nlm_SetUpdateRegion (wptr);
    Nlm_ResetDrawingTools ();
#endif
    if ((close && Nlm_CloseClick (w, pt)) ||
       (drag && Nlm_DragClick (w, pt)) ||
       (grow && Nlm_GrowClick (w, pt)) ||
       (zoom && Nlm_ZoomClick (w, pt))) {
      rsult = TRUE;
    } else {
      rsult = Nlm_ContentClick (w, pt);
    }
#ifndef WIN_MAC_QUARTZ
    Nlm_SetPort(temp);
    Nlm_currentWindowTool = GetWindowFromPort(temp);
    Nlm_SetUpdateRegion (GetWindowFromPort(temp));
    SetPenState (&state);
#endif
  } else if (chosenWindow != NULL) {
    Nlm_DoSelect ((Nlm_GraphiC) chosenWindow, TRUE);
  }
  return rsult;
}

static Nlm_Boolean Nlm_DocumentClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  return Nlm_CommonClick (w, pt, TRUE, TRUE, TRUE, TRUE);
}

static Nlm_Boolean Nlm_DialogClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  return Nlm_CommonClick (w, pt, TRUE, TRUE, FALSE, FALSE);
}

static Nlm_Boolean Nlm_FrozenClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  return Nlm_CommonClick (w, pt, TRUE, FALSE, FALSE, FALSE);
}

static Nlm_Boolean Nlm_PlainClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  return Nlm_CommonClick (w, pt, FALSE, FALSE, FALSE, FALSE);
}

static Nlm_Boolean Nlm_ModalClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_WndActnProc  cls;
  Nlm_Boolean      rsult;
  PenState         state;
  Nlm_PortTool     temp;
  Nlm_WindowData   wdata;
  Nlm_WindowTool   wptr;

  rsult = FALSE;
  if (chosenWindow == (Nlm_WindoW) w) {
    rsult = Nlm_CommonClick (w, pt, FALSE, FALSE, FALSE, FALSE);
    if (! rsult) {
      Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
      cls = wdata.close;
      if (cls != NULL) {
        wptr = Nlm_ParentWindowPtr (w);
#ifndef WIN_MAC_QUARTZ
        GetPort (&temp);
        GetPenState (&state);
#endif
        Nlm_SetPortWindowPort(wptr);
        Nlm_currentWindowTool = wptr;
        Nlm_SetUpdateRegion (wptr);
        Nlm_ResetDrawingTools ();
        cls ((Nlm_WindoW) w);
#ifndef WIN_MAC_QUARTZ
        Nlm_SetPort(temp);
        Nlm_currentWindowTool = GetWindowFromPort(temp);
        Nlm_SetUpdateRegion (GetWindowFromPort(temp));
        SetPenState (&state);
#endif
      }
    }
  } else {
    Nlm_Beep ();
  }
  return rsult;
}

static Nlm_Boolean Nlm_MovableModalClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_WndActnProc  cls;
  Nlm_Boolean      rsult;
  PenState         state;
  Nlm_PortTool     temp;
  Nlm_WindowData   wdata;
  Nlm_WindowTool   wptr;

  rsult = FALSE;
  if (chosenWindow == (Nlm_WindoW) w) {
    rsult = Nlm_CommonClick (w, pt, FALSE, TRUE, FALSE, FALSE);
    if (! rsult) {
      Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
      cls = wdata.close;
      if (cls != NULL) {
        wptr = Nlm_ParentWindowPtr (w);
#ifndef WIN_MAC_QUARTZ
        GetPort (&temp);
        GetPenState (&state);
#endif
        Nlm_SetPortWindowPort(wptr);
        Nlm_currentWindowTool = wptr;
        Nlm_SetUpdateRegion (wptr);
        Nlm_ResetDrawingTools ();
        cls ((Nlm_WindoW) w);
#ifndef WIN_MAC_QUARTZ
        Nlm_SetPort(temp);
        Nlm_currentWindowTool = GetWindowFromPort(temp);
        Nlm_SetUpdateRegion(GetWindowFromPort(temp));
        SetPenState (&state);
#endif
      }
    }
  } else {
    Nlm_Beep ();
  }
  return rsult;
}

static Nlm_Boolean Nlm_FloatingClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_WindoW  nw;

  if (chosenWindow == (Nlm_WindoW) w) {
    Nlm_CommonClick (w, Nlm_globalMouse, TRUE, TRUE, FALSE, FALSE);
  } else {
    nw = Nlm_NextVisWindow ((Nlm_WindoW) w);
    Nlm_DoClick ((Nlm_GraphiC) nw, Nlm_globalMouse);
  }
  return TRUE;
}

/* 2001-03-22:  Joshua Juran
 * SystemClick() is not supported in Carbon.  It's unnecessary.
 */
#if TARGET_API_MAC_CARBON
# define SystemClick(event, window)
#endif
static Nlm_Boolean Nlm_SystemClick (Nlm_GraphiC w, Nlm_PoinT pt)
{
  Nlm_WindowTool  wptr;

  if (chosenWindow == (Nlm_WindoW) w) {
    wptr = Nlm_ParentWindowPtr (w);
    SystemClick (&Nlm_currentEvent, wptr);
  } else {
    Nlm_DoSelect ((Nlm_GraphiC) chosenWindow, TRUE);
  }
  return TRUE;
}

static Nlm_Boolean Nlm_DesktopClick (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_MenuBaR  mb;

  mb = Nlm_GetWindowMenuBar ((Nlm_WindoW) w);
  Nlm_localMouse = Nlm_globalMouse;
  Nlm_GlobalToLocal (&Nlm_localMouse);
  (void) (Nlm_GetEnabled ((Nlm_GraphiC) mb) && Nlm_GetVisible ((Nlm_GraphiC) mb) &&
          Nlm_DoClick ((Nlm_GraphiC) mb, Nlm_localMouse));
  return TRUE;
}
#endif

static void Nlm_NormalSelect (Nlm_GraphiC w, Nlm_Boolean savePort)

{
#ifdef WIN_MAC
  if ((! Nlm_DragClick (w, Nlm_localMouse)) || (! Nlm_cmmdKey)) {
    Nlm_SelectWindow (w, FALSE);
  }
#endif
#ifdef WIN_MSWIN
  Nlm_SelectWindow (w, FALSE);
#endif
#ifdef WIN_MOTIF
  Nlm_SelectWindow (w, FALSE);
#endif
}

static void Nlm_PlainSelect (Nlm_GraphiC w, Nlm_Boolean savePort)

{
#ifdef WIN_MAC
  Nlm_SelectWindow (w, FALSE);
#endif
#ifdef WIN_MSWIN
  Nlm_SelectWindow (w, FALSE);
#endif
#ifdef WIN_MOTIF
  Nlm_SelectWindow (w, FALSE);
#endif
}

static void Nlm_FloatingSelect (Nlm_GraphiC w, Nlm_Boolean savePort)

{
#ifdef WIN_MAC
  PenState        state;
  Nlm_PortTool    temp;
  Nlm_WindowTool  wptr;

  wptr = Nlm_ParentWindowPtr (w);
#ifndef WIN_MAC_QUARTZ
  GetPort (&temp);
  GetPenState (&state);
#endif
  Nlm_SetPortWindowPort(wptr);
  Nlm_currentWindowTool = wptr;
  Nlm_SetUpdateRegion (wptr);
  Nlm_ResetDrawingTools ();
  Nlm_localMouse = Nlm_globalMouse;
  Nlm_GlobalToLocal (&Nlm_localMouse);
  if (Nlm_DragClick (w, Nlm_globalMouse) || Nlm_CloseClick (w, Nlm_globalMouse)) {
  } else {
    Nlm_ContentClick (w, Nlm_globalMouse);
  }
#ifndef WIN_MAC_QUARTZ
  Nlm_SetPort(temp);
  Nlm_currentWindowTool = GetWindowFromPort(temp);
  Nlm_SetUpdateRegion (GetWindowFromPort(temp));
  SetPenState (&state);
#endif
  Nlm_localMouse = Nlm_globalMouse;
  Nlm_GlobalToLocal (&Nlm_localMouse);
#endif
#ifdef WIN_MSWIN
  Nlm_SelectWindow (w, FALSE);
#endif
#ifdef WIN_MOTIF
  Nlm_SelectWindow (w, FALSE);
#endif
}

static void Nlm_DesktopSelect (Nlm_GraphiC w, Nlm_Boolean savePort)

{
#ifdef WIN_MAC
  PenState      state;
  Nlm_PortTool  temp;

#ifndef WIN_MAC_QUARTZ
  GetPort (&temp);
  GetPenState (&state);
  PenNormal ();
#endif
  Nlm_DesktopClick (w, Nlm_globalMouse);
#ifndef WIN_MAC_QUARTZ
  Nlm_SetPort(temp);
  Nlm_currentWindowTool = GetWindowFromPort(temp);
  Nlm_SetUpdateRegion (GetWindowFromPort(temp));
  SetPenState (&state);
#endif
#endif
}

#ifdef WIN_MAC
static Nlm_Boolean Nlm_DesktopKey (Nlm_GraphiC w, Nlm_Char ch)

{
  Nlm_MenuBaR  mb;

  mb = Nlm_GetWindowMenuBar ((Nlm_WindoW) w);
  Nlm_localMouse = Nlm_globalMouse;
  Nlm_GlobalToLocal (&Nlm_localMouse);
  if (Nlm_currentKey != '\0') {
    (void) (Nlm_GetEnabled ((Nlm_GraphiC) mb) && Nlm_GetVisible ((Nlm_GraphiC) mb) &&
            Nlm_DoKey ((Nlm_GraphiC) mb, ch));
  }
  return TRUE;
}

static Nlm_Boolean Nlm_NormalKey (Nlm_GraphiC w, Nlm_Char ch)

{
  Nlm_GraphiC     g;
  Nlm_MenuBaR     mb;
  Nlm_GraphiC     n;
  Nlm_Boolean     notInside;
  PenState        state;
  Nlm_PortTool    temp;
  Nlm_WindowTool  wptr;

  wptr = Nlm_ParentWindowPtr (w);
#ifndef WIN_MAC_QUARTZ
  GetPort (&temp);
  GetPenState (&state);
  Nlm_SetPortWindowPort(wptr);
  Nlm_currentWindowTool = wptr;
  Nlm_SetUpdateRegion (wptr);
  Nlm_ResetDrawingTools ();
#endif
  Nlm_localMouse = Nlm_globalMouse;
  Nlm_GlobalToLocal (&Nlm_localMouse);
  if (Nlm_currentKey != '\0') {
    g = Nlm_GetChild (w);
    notInside = TRUE;
    mb = Nlm_GetWindowMenuBar ((Nlm_WindoW) w);
    if (mb != NULL) {
      if (Nlm_GetEnabled ((Nlm_GraphiC) mb) && Nlm_GetVisible ((Nlm_GraphiC) mb) &&
          Nlm_DoKey ((Nlm_GraphiC) mb, ch)) {
        notInside = FALSE;
      }
    }
    while (g != NULL && notInside) {
      n = Nlm_GetNext (g);
      if (Nlm_GetEnabled (g) && Nlm_GetVisible (g) && Nlm_DoKey (g, ch)) {
        notInside = FALSE;
      }
      g = n;
    }
    if (notInside && Nlm_cmmdKey) {
      Nlm_DesktopKey ((Nlm_GraphiC) Nlm_desktopWindow, ch);
    }
  }
#ifndef WIN_MAC_QUARTZ
  Nlm_SetPort(temp);
  Nlm_currentWindowTool = GetWindowFromPort(temp);
  Nlm_SetUpdateRegion(GetWindowFromPort(temp));
  SetPenState (&state);
#endif
  return TRUE;
}

static Nlm_Boolean Nlm_FloatingKey (Nlm_GraphiC w, Nlm_Char ch)

{
  Nlm_GraphiC     g;
  Nlm_MenuBaR     mb;
  Nlm_GraphiC     n;
  Nlm_WindoW      nw;
  Nlm_Boolean     notInside;
  PenState        state;
  Nlm_PortTool    temp;
  Nlm_WindowTool  wptr;

  wptr = Nlm_ParentWindowPtr (w);
#ifndef WIN_MAC_QUARTZ
  GetPort (&temp);
  GetPenState (&state);
#endif
  Nlm_SetPortWindowPort(wptr);
  Nlm_currentWindowTool = wptr;
  Nlm_SetUpdateRegion (wptr);
  Nlm_ResetDrawingTools ();
  Nlm_localMouse = Nlm_globalMouse;
  Nlm_GlobalToLocal (&Nlm_localMouse);
  if (Nlm_currentKey != '\0') {
    g = Nlm_GetChild (w);
    notInside = TRUE;
    mb = Nlm_GetWindowMenuBar ((Nlm_WindoW) w);
    if (mb != NULL) {
      if (Nlm_GetEnabled ((Nlm_GraphiC) mb) && Nlm_GetVisible ((Nlm_GraphiC) mb) &&
          Nlm_DoKey ((Nlm_GraphiC) mb, ch)) {
        notInside = FALSE;
      }
    }
    while (g != NULL && notInside) {
      n = Nlm_GetNext (g);
      if (Nlm_GetEnabled (g) && Nlm_GetVisible (g) && Nlm_DoKey (g, ch)) {
        notInside = FALSE;
      }
      g = n;
    }
    if (notInside) {
      nw = Nlm_NextVisWindow ((Nlm_WindoW) w);
      Nlm_DoKey ((Nlm_GraphiC) nw, ch);
    }
  }
#ifndef WIN_MAC_QUARTZ
  Nlm_SetPort(temp);
  Nlm_currentWindowTool = GetWindowFromPort(temp);
  Nlm_SetUpdateRegion(GetWindowFromPort(temp));
  SetPenState (&state);
#endif
  return TRUE;
}

static Nlm_Boolean Nlm_ModalKey (Nlm_GraphiC w, Nlm_Char ch)

{
  if (Nlm_cmmdKey) {
    Nlm_Beep ();
  } else {
    Nlm_NormalKey (w, ch);
  }
  return TRUE;
}

static void Nlm_DrawWindow (Nlm_GraphiC w, Nlm_Boolean drawGrowIcon)

{
  Nlm_GraphiC     g;
  Nlm_MenuBaR     mb;
  Nlm_GraphiC     n;
  Nlm_RecT        r;
  PenState        state;
  Nlm_PortTool    temp;
  Nlm_WindowTool  wptr;
  Rect bounds;

#ifndef WIN_MAC_QUARTZ
  wptr = Nlm_ParentWindowPtr (w);
  GetPort (&temp);
  GetPenState (&state);
  Nlm_SetPortWindowPort(wptr);
  Nlm_currentWindowTool = wptr;

  Nlm_ResetDrawingTools ();
  Nlm_ResetClip ();
  PenNormal ();

  BeginUpdate (wptr);
  Nlm_SetUpdateRegion (wptr);
  GetPortBounds(GetWindowPort(wptr), &bounds);
  Nlm_RectToolToRecT (&bounds, &r);
  Nlm_EraseRect (&r);

#endif
  if (okayToDrawContents) {
    if (drawGrowIcon) {
      Nlm_DrawGrowIcon (w, FALSE, TRUE);
    }
    mb = Nlm_GetWindowMenuBar ((Nlm_WindoW) w);
    if (mb != NULL) {
      Nlm_DoDraw ((Nlm_GraphiC) mb);
    }
    g = Nlm_GetChild (w);
    while (g != NULL) {
      n = Nlm_GetNext (g);
      Nlm_DoDraw (g);
      g = n;
    }
    if (drawGrowIcon) {
      Nlm_DrawGrowIcon (w, TRUE, FALSE);
    }
  }

#ifndef WIN_MAC_QUARTZ
  EndUpdate (wptr);
#endif
  Nlm_ResetDrawingTools ();
#ifndef WIN_MAC_QUARTZ
  Nlm_ResetClip ();
  Nlm_SetPort(temp);
  Nlm_currentWindowTool = GetWindowFromPort(temp);
  Nlm_SetUpdateRegion(GetWindowFromPort(temp));
  SetPenState (&state);
#endif
}

static void Nlm_DocumentDraw (Nlm_GraphiC w)

{
  Nlm_DrawWindow (w, TRUE);
}

static void Nlm_NormalDraw (Nlm_GraphiC w)

{
  Nlm_DrawWindow (w, FALSE);
}
#endif

static void Nlm_ActivateWindow (Nlm_GraphiC w, Nlm_Boolean drawGrow)

{
  Nlm_WndActnProc  act;
  Nlm_GraphiC      g;
  Nlm_MenuBaR      mb;
  Nlm_GraphiC      n;
  Nlm_WindowData   wdata;

  Nlm_UseWindow ((Nlm_WindoW) w);
#ifdef WIN_MAC
  if (drawGrow) {
    Nlm_DrawGrowIcon (w, TRUE, TRUE);
  }
#endif
  mb = Nlm_GetWindowMenuBar ((Nlm_WindoW) w);
  if (mb != NULL) {
    Nlm_DoActivate ((Nlm_GraphiC) mb, FALSE);
  }
  g = Nlm_GetChild (w);
  while (g != NULL) {
    n = Nlm_GetNext (g);
    Nlm_DoActivate (g, FALSE);
    g = n;
  }
  Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
  act = wdata.activate;
  if (act != NULL) {
    act ((Nlm_WindoW) w);
  }
  if (appWndAct != NULL) {
    appWndAct ((Nlm_WindoW) w);
  }
}

static void Nlm_DocumentActivate (Nlm_GraphiC w, Nlm_Boolean savePort)

{
  Nlm_ActivateWindow (w, TRUE);
}

static void Nlm_NormalActivate (Nlm_GraphiC w, Nlm_Boolean savePort)

{
  Nlm_ActivateWindow (w, FALSE);
}

static void Nlm_DeactivateWindow (Nlm_GraphiC w, Nlm_Boolean drawGrow)

{
  Nlm_WndActnProc  deact;
  Nlm_GraphiC      g;
  Nlm_MenuBaR      mb;
  Nlm_GraphiC      n;
  Nlm_WindowData   wdata;

  Nlm_UseWindow ((Nlm_WindoW) w);
#ifdef WIN_MAC
  if (drawGrow) {
    Nlm_DrawGrowIcon (w, TRUE, TRUE);
  }
#endif
  mb = Nlm_GetWindowMenuBar ((Nlm_WindoW) w);
  if (mb != NULL) {
    Nlm_DoDeactivate ((Nlm_GraphiC) mb, FALSE);
  }
  g = Nlm_GetChild (w);
  while (g != NULL) {
    n = Nlm_GetNext (g);
    Nlm_DoDeactivate (g, FALSE);
    g = n;
  }
  Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
  deact = wdata.deactivate;
  if (deact != NULL) {
    deact ((Nlm_WindoW) w);
  }
  if (appWndDeact != NULL) {
    appWndDeact ((Nlm_WindoW) w);
  }
}

static void Nlm_DocumentDeactivate (Nlm_GraphiC w, Nlm_Boolean savePort)

{
  Nlm_DeactivateWindow (w, TRUE);
}

static void Nlm_NormalDeactivate (Nlm_GraphiC w, Nlm_Boolean savePort)

{
  Nlm_DeactivateWindow (w, FALSE);
}

#ifdef WIN_MAC
static Nlm_Boolean Nlm_NormalIdle (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_GraphiC  g;
  Nlm_GraphiC  n;

  g = Nlm_GetChild (w);
  while (g != NULL) {
    n = Nlm_GetNext (g);
    Nlm_DoIdle (g, Nlm_localMouse);
    g = n;
  }
  return TRUE;
}

static Nlm_Boolean Nlm_FloatingIdle (Nlm_GraphiC w, Nlm_PoinT pt)

{
  Nlm_WindoW   nw;

  nw = Nlm_NextVisWindow ((Nlm_WindoW) w);
  Nlm_DoIdle ((Nlm_GraphiC) nw, pt);
  return TRUE;
}
#endif

static void Nlm_NormalDrawChar (Nlm_GraphiC w, Nlm_Char ch, Nlm_Boolean savePort)

{
  Nlm_DisplaY     d;
  Nlm_WindowData  wdata;

  Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
  d = wdata.charDisplay;
  if (d != NULL) {
    Nlm_DoSendChar ((Nlm_GraphiC) d, ch, TRUE);
  }
}

static void Nlm_FloatingDrawChar (Nlm_GraphiC w, Nlm_Char ch, Nlm_Boolean savePort)

{
  Nlm_DisplaY     d;
  Nlm_WindowData  wdata;
#ifdef WIN_MAC
  Nlm_WindoW      nw;
#endif

  Nlm_GetWindowData ((Nlm_WindoW) w, &wdata);
  d = wdata.charDisplay;
  if (d != NULL) {
    Nlm_DoSendChar ((Nlm_GraphiC) d, ch, TRUE);
  } else {
#ifdef WIN_MAC
    nw = Nlm_NextVisWindow ((Nlm_WindoW) w);
    Nlm_DoSendChar ((Nlm_GraphiC) nw, ch, TRUE);
#endif
#ifdef WIN_MOTIF
#endif
  }
}

static void Nlm_AdjustWindow (Nlm_GraphiC w, Nlm_RectPtr r,
                              Nlm_Boolean align, Nlm_Boolean savePort)

{
  Nlm_GraphiC  g;
  Nlm_WindoW   tempPort;

  tempPort = Nlm_SavePortIfNeeded (w, savePort);
  if (align) {
    g = Nlm_GetParent (w);
    Nlm_RecordRect (g, r);
    Nlm_NextPosition (g, r);
  }
  Nlm_RestorePort (tempPort);
}

static Nlm_GraphiC Nlm_WindowGainFocus (Nlm_GraphiC w, Nlm_Char ch, Nlm_Boolean savePort)

{
  Nlm_GraphiC  p;
  Nlm_GraphiC  q;
  Nlm_GraphiC  n;

  q = NULL;
  p = Nlm_GetChild (w);
  while (p != NULL && q == NULL) {
    n = Nlm_GetNext (p);
    q = Nlm_DoGainFocus (p, ch, savePort);
    p = n;
  }
  return q;
}

static void Nlm_WindowLoseFocus (Nlm_GraphiC w, Nlm_GraphiC excpt, Nlm_Boolean savePort)

{
  Nlm_GraphiC  p;

  p = Nlm_GetChild (w);
  while (p != NULL) {
    Nlm_DoLoseFocus (p, excpt, savePort);
    p = Nlm_GetNext (p);
  }
}

extern Nlm_WindoW Nlm_DocumentWindow (Nlm_Int2 left, Nlm_Int2 top,
                                      Nlm_Int2 width, Nlm_Int2 height,
                                      Nlm_CharPtr title,
                                      Nlm_WndActnProc close,
                                      Nlm_WndActnProc resize)

{
  Nlm_RecT    r;
  Nlm_WindoW  w;

  Nlm_LoadRect (&r, left, top, width, height);
  w = Nlm_MakeWindowLink (&r, sizeof (Nlm_WindowRec), documentProcs);
  if (w != NULL) {
#ifdef WIN_MAC
    Nlm_NewWindow (w, DOCUMENT_STYLE, 8, TRUE, NULL, 0, title, close, resize);
#endif
#ifdef WIN_MSWIN
    Nlm_NewWindow (w, DOCUMENT_STYLE, 0, FALSE, windowclass, WS_OVERLAPPEDWINDOW, title, close, resize);
#endif
#ifdef WIN_MOTIF
    Nlm_NewWindow (w, DOCUMENT_STYLE, 0, FALSE, NULL, 0, title, close, resize);
#endif
  }
  return w;
}

extern Nlm_WindoW Nlm_FixedWindow (Nlm_Int2 left, Nlm_Int2 top,
                                   Nlm_Int2 width, Nlm_Int2 height,
                                   Nlm_CharPtr title, Nlm_WndActnProc close)

{
  Nlm_RecT    r;
  Nlm_WindoW  w;

  Nlm_LoadRect (&r, left, top, width, height);
  w = Nlm_MakeWindowLink (&r, sizeof (Nlm_WindowRec), fixedProcs);
  if (w != NULL) {
#ifdef WIN_MAC
    Nlm_NewWindow (w, FIXED_STYLE, 4, TRUE, NULL, 0, title, close, NULL);
#endif
#ifdef WIN_MSWIN
    Nlm_NewWindow (w, FIXED_STYLE, 0, FALSE, windowclass, WS_OVERLAPPED |
                   WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, title, close, NULL);
#endif
#ifdef WIN_MOTIF
    Nlm_NewWindow (w, FIXED_STYLE, 0, FALSE, NULL, 0, title, close, NULL);
#endif
  }
  return w;
}

extern Nlm_WindoW Nlm_FrozenWindow (Nlm_Int2 left, Nlm_Int2 top,
                                    Nlm_Int2 width, Nlm_Int2 height,
                                    Nlm_CharPtr title, Nlm_WndActnProc close)

{
  Nlm_RecT    r;
  Nlm_WindoW  w;

  Nlm_LoadRect (&r, left, top, width, height);
  w = Nlm_MakeWindowLink (&r, sizeof (Nlm_WindowRec), frozenProcs);
  if (w != NULL) {
#ifdef WIN_MAC
    Nlm_NewWindow (w, FROZEN_STYLE, 4, TRUE, NULL, 0, title, close, NULL);
#endif
#ifdef WIN_MSWIN
    Nlm_NewWindow (w, FROZEN_STYLE, 0, FALSE, windowclass, WS_OVERLAPPED |
                   WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, title, close, NULL);
#endif
#ifdef WIN_MOTIF
    Nlm_NewWindow (w, FROZEN_STYLE, 0, FALSE, NULL, 0, title, close, NULL);
#endif
  }
  return w;
}

extern Nlm_WindoW Nlm_RoundWindow (Nlm_Int2 left, Nlm_Int2 top,
                                   Nlm_Int2 width, Nlm_Int2 height,
                                   Nlm_CharPtr title, Nlm_WndActnProc close)

{
  Nlm_RecT    r;
  Nlm_WindoW  w;

  Nlm_LoadRect (&r, left, top, width, height);
  w = Nlm_MakeWindowLink (&r, sizeof (Nlm_WindowRec), roundProcs);
  if (w != NULL) {
#ifdef WIN_MAC
    Nlm_NewWindow (w, ROUND_STYLE, 16, TRUE, NULL, 0, title, close, NULL);
#endif
#ifdef WIN_MSWIN
    Nlm_NewWindow (w, ROUND_STYLE, 0, FALSE, windowclass, WS_OVERLAPPED |
                   WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, title, close, NULL);
#endif
#ifdef WIN_MOTIF
    Nlm_NewWindow (w, ROUND_STYLE, 0, FALSE, NULL, 0, title, close, NULL);
#endif
  }
  return w;
}

extern Nlm_WindoW Nlm_AlertWindow (Nlm_Int2 left, Nlm_Int2 top,
                                   Nlm_Int2 width, Nlm_Int2 height,
                                   Nlm_WndActnProc close)

{
  Nlm_RecT    r;
  Nlm_WindoW  w;

  Nlm_LoadRect (&r, left, top, width, height);
  w = Nlm_MakeWindowLink (&r, sizeof (Nlm_WindowRec), alertProcs);
  if (w != NULL) {
#ifdef WIN_MAC
    Nlm_NewWindow (w, ALERT_STYLE, 1, FALSE, NULL, 0, NULL, close, NULL);
#endif
#ifdef WIN_MSWIN
    Nlm_NewWindow (w, ALERT_STYLE, 0, FALSE, windowclass, WS_OVERLAPPED, "", close, NULL);
#endif
#ifdef WIN_MOTIF
    Nlm_NewWindow (w, ALERT_STYLE, 0, FALSE, NULL, 0, "", close, NULL);
#endif
  }
  return w;
}

/* esl: set the "owner" window of modal dialog */
extern void Nlm_SetModalWindowOwner (Nlm_WindoW w, Nlm_WindoW owner)
{
  if (w != NULL) {
    Nlm_WindowData wdata;
    Nlm_GetWindowData (w, &wdata);
    wdata.modalOwner = owner;
    Nlm_SetWindowData (w, &wdata);
  }
}

extern Nlm_WindoW Nlm_ModalWindow (Nlm_Int2 left, Nlm_Int2 top,
                                   Nlm_Int2 width, Nlm_Int2 height,
                                   Nlm_WndActnProc close)

{
  Nlm_RecT    r;
  Nlm_WindoW  w;
  Nlm_WindoW  owner = Nlm_ActiveWindow (); /* esl: reasonable guess */

  Nlm_LoadRect (&r, left, top, width, height);
  w = Nlm_MakeWindowLink (&r, sizeof (Nlm_WindowRec), modalProcs);
  if (w != NULL) {
#ifdef WIN_MAC
    Nlm_NewWindow (w, MODAL_STYLE, 1, FALSE, NULL, 0, NULL, close, NULL);
#endif
#ifdef WIN_MSWIN
    Nlm_NewWindow (w, MODAL_STYLE, 0, FALSE, windowclass, WS_POPUP |
                   WS_CAPTION | WS_SYSMENU, "", close, NULL);
#endif
#ifdef WIN_MOTIF
    Nlm_NewWindow (w, MODAL_STYLE, 0, FALSE, NULL, 0, "", close, NULL);
#endif
  }
  Nlm_SetModalWindowOwner (w, owner); /* esl */
  return w;
}

extern Nlm_WindoW Nlm_ResizableModalWindow(Nlm_Int2 left, Nlm_Int2 top,
    Nlm_Int2 width, Nlm_Int2 height,
    Nlm_CharPtr title,
    Nlm_WndActnProc close,
    Nlm_WndActnProc resize)
{
    Nlm_RecT    r;
    Nlm_WindoW  w = 0;
    Nlm_WindoW  owner = Nlm_ActiveWindow(); 

    Nlm_LoadRect(&r, left, top, width, height);
    w = Nlm_MakeWindowLink(&r, sizeof(Nlm_WindowRec), movableModalProcs);
    if (w != NULL) {
#ifdef WIN_MAC
        Nlm_NewWindow(w, MODAL_STYLE, 5, FALSE, NULL, 0, title, close, resize);
#endif
#ifdef WIN_MSWIN
        Nlm_NewWindow(w, MODAL_STYLE, 0, FALSE, windowclass, WS_POPUP |
            WS_CAPTION | WS_SYSMENU | WS_THICKFRAME, title, close, resize);
#endif
#ifdef WIN_MOTIF
        Nlm_NewWindow(w, MODAL_STYLE, 0, FALSE, NULL, 0, title, close, resize);
#endif
    }
    Nlm_SetModalWindowOwner(w, owner); 

    return w;
}

/* esl: movable dialog with caption */
extern Nlm_WindoW Nlm_MovableModalWindow (Nlm_Int2 left, Nlm_Int2 top,
                                          Nlm_Int2 width, Nlm_Int2 height,
                                          Nlm_CharPtr title,
                                          Nlm_WndActnProc close)
{
  Nlm_RecT    r;
  Nlm_WindoW  w;
  Nlm_WindoW  owner = Nlm_ActiveWindow (); /* esl: reasonable guess */

  Nlm_LoadRect (&r, left, top, width, height);
  w = Nlm_MakeWindowLink (&r, sizeof (Nlm_WindowRec), movableModalProcs);
  if (w != NULL) {
#ifdef WIN_MAC
    Nlm_NewWindow (w, MODAL_STYLE, 5, FALSE, NULL, 0, title, close, NULL);
#endif
#ifdef WIN_MSWIN
    Nlm_NewWindow (w, MODAL_STYLE, 0, FALSE, windowclass, WS_POPUP |
                   WS_CAPTION | WS_SYSMENU, title, close, NULL);
#endif
#ifdef WIN_MOTIF
    Nlm_NewWindow (w, MODAL_STYLE, 0, FALSE, NULL, 0, title, close, NULL);
#endif
  }
  Nlm_SetModalWindowOwner (w, owner); /* esl */
  return w;
}

extern Nlm_WindoW Nlm_FloatingWindow (Nlm_Int2 left, Nlm_Int2 top,
                                      Nlm_Int2 width, Nlm_Int2 height,
                                      Nlm_WndActnProc close)

{
  Nlm_RecT    r;
  Nlm_WindoW  w;

  Nlm_LoadRect (&r, left, top, width, height);
  w = Nlm_MakeWindowLink (&r, sizeof (Nlm_WindowRec), floatingProcs);
  if (w != NULL) {
#ifdef WIN_MAC
    Nlm_NewWindow (w, FLOATING_STYLE, 17, TRUE, NULL, 0, NULL, close, NULL);
#endif
#ifdef WIN_MSWIN
    Nlm_NewWindow (w, FLOATING_STYLE, 0, FALSE, windowclass, WS_POPUP |
                   WS_CAPTION | WS_SYSMENU, "", close, NULL);
#endif
#ifdef WIN_MOTIF
    Nlm_NewWindow (w, FLOATING_STYLE, 0, FALSE, NULL, 0, "", close, NULL);
#endif
  }
  return w;
}

extern Nlm_WindoW Nlm_ShadowWindow (Nlm_Int2 left, Nlm_Int2 top,
                                    Nlm_Int2 width, Nlm_Int2 height,
                                    Nlm_WndActnProc close)

{
  Nlm_RecT    r;
  Nlm_WindoW  w;

  Nlm_LoadRect (&r, left, top, width, height);
  w = Nlm_MakeWindowLink (&r, sizeof (Nlm_WindowRec), shadowProcs);
  if (w != NULL) {
#ifdef WIN_MAC
    Nlm_NewWindow (w, SHADOW_STYLE, 3, FALSE, NULL, 0, NULL, close, NULL);
#endif
#ifdef WIN_MSWIN
    Nlm_NewWindow (w, SHADOW_STYLE, 0, FALSE, windowclass,
      WS_CAPTION|WS_BORDER, "", close, NULL);
#endif
#ifdef WIN_MOTIF
    Nlm_NewWindow (w, SHADOW_STYLE, 0, FALSE, NULL, 0, "", close, NULL);
#endif
  }
  return w;
}

extern Nlm_WindoW Nlm_PlainWindow (Nlm_Int2 left, Nlm_Int2 top,
                                   Nlm_Int2 width, Nlm_Int2 height,
                                   Nlm_WndActnProc close)

{
  Nlm_RecT    r;
  Nlm_WindoW  w;

  Nlm_LoadRect (&r, left, top, width, height);
  w = Nlm_MakeWindowLink (&r, sizeof (Nlm_WindowRec), plainProcs);
  if (w != NULL) {
#ifdef WIN_MAC
    Nlm_NewWindow (w, PLAIN_STYLE, 2, FALSE, NULL, 0, NULL, close, NULL);
#endif
#ifdef WIN_MSWIN
    Nlm_NewWindow (w, PLAIN_STYLE, 0, FALSE, windowclass, WS_OVERLAPPED, "", close, NULL);
#endif
#ifdef WIN_MOTIF
    Nlm_NewWindow (w, PLAIN_STYLE, 0, FALSE, NULL, 0, "", close, NULL);
#endif
  }
  return w;
}

extern void Nlm_Metronome (Nlm_VoidProc actn)

{
  timerAction = actn;
}

extern void Nlm_SetWindowTimer (Nlm_WindoW w, Nlm_WndActnProc actn)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.timer = actn;
    Nlm_SetWindowData (w, &wdata);
  }
}

static void Nlm_CallWindowTimers (void)

{
  Nlm_WindoW      w;
  Nlm_WindowData  wdata;

  w = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) Nlm_desktopWindow);
  while (w != NULL && w != Nlm_systemWindow) {
    Nlm_GetWindowData (w, &wdata);
    if (wdata.timer != NULL) {
      wdata.timer (w);
    }
    w = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) w);
  }
}


#ifdef WIN_MOTIF
static void Nlm_SetCursor (Cursor cursor)

{
  Nlm_MainTool  man;
  Nlm_WindoW    w;
  Window        xtw;

  if (Nlm_currentXDisplay != NULL) {
    w = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) Nlm_desktopWindow);
    while (w != NULL) {
      if (! Nlm_IsWindowDying (w)) {
        man = Nlm_GetWindowMain (w);
        xtw = XtWindow (man);
        if ( xtw ) {
          XDefineCursor (Nlm_currentXDisplay, xtw, cursor);
        }
      }
      w = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) w);
    }
    Nlm_currentCursor = cursor;
    XFlush( Nlm_currentXDisplay );
  }
}
#endif

#ifdef WIN_MAC_QUARTZ
#ifdef WIN_MAC_QUARTZ_COCOA_CURSORS
/* these support functions make life a bit easier and centralize the
   ugly Cocoa access */

/* objc_msgSend is actually a trampoline which is effectively has no real prototype
   but actually just takes on the prototype of the target method;
   in order to shut the compiler up about methods which return char and generate
   the correct machine code at the call site, we define this global function pointer
   which points to the same function but with a different prototype */
static char (*objc_msgSend_charRetFptr)(void *, void *, ...) = (void *)objc_msgSend;

/* handy shortcut macros for invoking NSCursor methods */
#define COCOA_SELECTOR(name) NSSelectorFromString(CFSTR(name))

/* NSCursor does not define all of the methods we use when running
   on 10.2, so we check to ensure it responds before calling anything.
   If it does not respond, we'll return 0 (nil) and the following
   set operation will be a no-op. */
#define COCOA_NSCURSOR_CLASS_RESPONDS(name) objc_msgSend_charRetFptr(Nlm_NSCursorClass(), COCOA_SELECTOR("respondsToSelector:"), COCOA_SELECTOR(name))

#define COCOA_NAMED_CURSOR(name) (COCOA_NSCURSOR_CLASS_RESPONDS(name "Cursor") \
                                  ? objc_msgSend(Nlm_NSCursorClass(), COCOA_SELECTOR(name "Cursor")) \
                                  : 0)

static void *Nlm_NSCursorClass (void)
{
  static int didLoadApplication = 0;
  if (!didLoadApplication)
  {
    didLoadApplication = 1;
    NSApplicationLoad();
  }
  
  return NSClassFromString(CFSTR("NSCursor"));
}

static void Nlm_SetCursor (void *cursor)
{
  objc_msgSend(cursor, NSSelectorFromString(CFSTR("set")));
}

#endif
#endif

extern void Nlm_ArrowCursor (void)

{
#ifdef WIN_MAC
#ifdef WIN_MAC_QUARTZ
#ifdef WIN_MAC_QUARTZ_COCOA_CURSORS
  Nlm_SetCursor(COCOA_NAMED_CURSOR("arrow"));
#endif
#else
  Cursor cursor;
  GetQDGlobalsArrow(&cursor);
  SetCursor (&cursor);
#endif
#endif
#ifdef WIN_MSWIN
  Nlm_currentCursor = LoadCursor (NULL, IDC_ARROW);
  SetCursor (Nlm_currentCursor);
#endif
#ifdef WIN_MOTIF
  Nlm_SetCursor (arrow);
#endif
}

extern void Nlm_CrossCursor (void)

{
#ifdef WIN_MAC
#ifdef WIN_MAC_QUARTZ
#ifdef WIN_MAC_QUARTZ_COCOA_CURSORS
  Nlm_SetCursor(COCOA_NAMED_CURSOR("crosshair"));
#endif
#else
  SetCursor (&cross);
#endif
#endif
#ifdef WIN_MSWIN
  Nlm_currentCursor = LoadCursor (NULL, IDC_CROSS);
  SetCursor (Nlm_currentCursor);
#endif
#ifdef WIN_MOTIF
  Nlm_SetCursor (cross);
#endif
}

extern void Nlm_IBeamCursor (void)

{
#ifdef WIN_MAC
#ifdef WIN_MAC_QUARTZ
#ifdef WIN_MAC_QUARTZ_COCOA_CURSORS
  Nlm_SetCursor(COCOA_NAMED_CURSOR("IBeam"));
#endif
#else
  SetCursor (&iBeam);
#endif
#endif
#ifdef WIN_MSWIN
  Nlm_currentCursor = LoadCursor (NULL, IDC_IBEAM);
  SetCursor (Nlm_currentCursor);
#endif
#ifdef WIN_MOTIF
  Nlm_SetCursor (iBeam);
#endif
}

extern void Nlm_PlusCursor (void)

{
#ifdef WIN_MAC
#ifdef WIN_MAC_QUARTZ
#ifdef WIN_MAC_QUARTZ_COCOA_CURSORS
  Nlm_SetCursor(COCOA_NAMED_CURSOR("crosshair"));
#endif
#else
  SetCursor (&plus);
#endif
#endif
#ifdef WIN_MSWIN
  Nlm_currentCursor = LoadCursor (NULL, IDC_CROSS);
  SetCursor (Nlm_currentCursor);
#endif
#ifdef WIN_MOTIF
  Nlm_SetCursor (plus);
#endif
}

extern void Nlm_WatchCursor (void)

{
#ifdef WIN_MAC
#ifdef WIN_MAC_QUARTZ
#ifdef WIN_MAC_QUARTZ_COCOA_CURSORS
// QUARTZ_FIXME: do we even need or want a watch cursor?
#endif
#else
  SetCursor (&watch);
#endif
#endif
#ifdef WIN_MSWIN
  Nlm_currentCursor = LoadCursor (NULL, IDC_WAIT);
  SetCursor (Nlm_currentCursor);
#endif
#ifdef WIN_MOTIF
  Nlm_SetCursor (watch);
#endif
}


typedef void (*Nlm_SetCursorFuncPtr)( void );

static enumCursorShape curr_cursor_shape = CURSOR_DEFAULT;
static Nlm_SetCursorFuncPtr Nlm_CursorArray[ N_CURSORS ];


static Nlm_Boolean Nlm_AddCursorShape(enumCursorShape      cursor_shape,
                                      Nlm_SetCursorFuncPtr set_function)
{
  if (cursor_shape < 0  ||  N_CURSORS <= cursor_shape  ||
      Nlm_CursorArray[cursor_shape] != NULL  ||
      set_function == NULL)
    return FALSE;

  Nlm_CursorArray[cursor_shape] = set_function;
  return TRUE;
}


Nlm_Boolean Nlm_InitCursorShapes( void )
{
  int i;
  for (i = 0;  i < N_CURSORS;  i++)
    Nlm_CursorArray[i] = NULL;

  {{
    Nlm_Boolean ok = (Nlm_Boolean)(
      Nlm_AddCursorShape (CURSOR_ARROW, Nlm_ArrowCursor)  &&
      Nlm_AddCursorShape (CURSOR_CROSS, Nlm_CrossCursor)  &&
      Nlm_AddCursorShape (CURSOR_IBEAM, Nlm_IBeamCursor)  &&
      Nlm_AddCursorShape (CURSOR_PLUS,  Nlm_PlusCursor )  &&
      Nlm_AddCursorShape (CURSOR_WATCH, Nlm_WatchCursor));
    ASSERT ( ok );
    if ( !ok )  return FALSE;
  }}

  for (i = 0;  i < N_CURSORS;  i++)
    if (Nlm_CursorArray[i] == NULL)
      {
        ASSERT ( FALSE );
        return FALSE;
      }

  return  (Nlm_Boolean)(SetCursorShape( curr_cursor_shape )  !=  BAD_CURSOR);
}


enumCursorShape Nlm_SetCursorShape(enumCursorShape cursor_shape)
{
  if (cursor_shape == WHAT_CURSOR)
    return curr_cursor_shape;

  if (0 <= cursor_shape  &&  cursor_shape < N_CURSORS  &&
      Nlm_CursorArray[cursor_shape] != NULL)
    {
      enumCursorShape prev_cursor_shape = curr_cursor_shape;
      (*Nlm_CursorArray[curr_cursor_shape = cursor_shape])();
      return prev_cursor_shape;
    }
  else
    {
      ASSERT ( FALSE );
      return BAD_CURSOR;
    }
}


extern void LIBCALL
Nlm_RegisterDropProc (Nlm_DropProc dropProc)
{
  registeredDropProc = dropProc;
}

extern void LIBCALL
Nlm_RegisterServiceProc (Nlm_ServiceProc serviceProc)
{
  registeredServiceProc = serviceProc;
}

extern void LIBCALL
Nlm_RegisterResultProc (Nlm_ResultProc resultProc)
{
  registeredResultProc = resultProc;
}

#ifdef WIN_MAC
static pascal OSErr HandleAEQuitApp (const AppleEvent *event, AppleEvent *reply, AERefCon ref)

{
  Nlm_QuitProgram ();
  return noErr;
}

static pascal OSErr HandleAEIgnore (const AppleEvent *event, AppleEvent *reply, AERefCon ref)

{
  return noErr;
}

#if 0
/* AppleEvent handlers modified from Roger Sayle's RasMol code */
static void ConvertFilename ( FSSpec *fss, Nlm_CharPtr filename )

{
  register char *src;
  register char *dst;
  register int i;
  char buffer [256];
  
  Str255 dirname;
  DirInfo dinfo;
  
  src = buffer;
  dinfo.ioDrParID = fss->parID;
  dinfo.ioNamePtr = dirname;
  do {
    dinfo.ioVRefNum = fss->vRefNum;
    dinfo.ioFDirIndex = -1;
    dinfo.ioDrDirID = dinfo.ioDrParID;
    PBGetCatInfo ((CInfoPBPtr) &dinfo, 0);
    
    *src++ = ':';
    for ( i=dirname[0]; i; i-- )
      *src++ = dirname [i];
  } while ( dinfo.ioDrDirID != 2 );
  
  /* Reverse the file path! */
  dst = filename;
  while ( src != buffer )
    *dst++ = *(--src);
  for( i = 1; i <= fss->name [0]; i++ )
    *dst++ = fss->name [i];
  *dst = '\0';
}
#endif

static pascal OSErr HandleAEOpenDoc (const AppleEvent *event, AppleEvent *reply, AERefCon ref)

{
  register OSErr stat;
  register long i;
  AEDescList list;
  AEKeyword keywd;
  DescType dtype;
  FSSpec fss;
  long count;
  Size size;
  char filename [256];
  char tempfile [PATH_MAX];
  AEDesc docDesc;
  AEDescList theList;
  CFURLRef cfurl;
  OSErr theErr;
  
  stat = AEGetParamDesc (event, keyDirectObject, typeAEList, &list);
  if ( stat ) return ( stat );
  
  stat = AEGetAttributePtr (event, keyMissedKeywordAttr, typeWildCard,
                            &dtype, 0, 0, &size );
  if ( stat != errAEDescNotFound ) {   
    AEDisposeDesc( &list );
    return ( stat? stat : errAEEventNotHandled );
  }
  
  AECountItems ( &list, &count );
  for ( i = 1; i <= count; i++ ) {   
    stat = AEGetNthPtr (&list, i, typeFSS, &keywd,
                        &dtype, (Ptr) &fss, sizeof (fss),
                        &size);
    if ( !stat ) {   
      Nlm_ConvertFilename (&fss, filename);

      if (registeredDropProc != NULL) {
        registeredDropProc (filename);
      }

      if (registeredServiceProc != NULL) {
        Nlm_TmpNam (tempfile);
        registeredServiceProc (filename, tempfile);

        theErr = AECreateList(NULL, 0, FALSE, &theList);
        if (theErr == noErr) {
          cfurl = CFURLCreateFromFileSystemRepresentation (NULL, (const UInt8 *)tempfile, strlen (tempfile), 0);
          if (cfurl) {
            CFDataRef cfdata = CFURLCreateData (NULL, cfurl, kCFStringEncodingUTF8, 1);
            theErr = AECreateDesc(typeFileURL, CFDataGetBytePtr (cfdata), CFDataGetLength (cfdata), &docDesc);
            CFRelease (cfdata);
            if (theErr == noErr) {
              theErr = AEPutDesc(&theList, 0, &docDesc);
              if (theErr == noErr) {
                theErr = AEPutParamDesc(reply, keyDirectObject, &theList);
              }
            }
          }
        }

      }
    }
  }
  AEDisposeDesc ( &list );         
  return noErr;
}

static pascal OSErr HandleAEAnswer (const AppleEvent *event, AppleEvent *reply, AERefCon ref)

{
  register OSErr stat;
  register long i;
  AEDescList list;
  AEKeyword keywd;
  DescType dtype;
  FSSpec fss;
  long count;
  Size size;
  char filename [256];
  
  stat = AEGetParamDesc (event, keyDirectObject, typeAEList, &list);
  if ( stat ) return ( stat );
  
  stat = AEGetAttributePtr (event, keyMissedKeywordAttr, typeWildCard,
                            &dtype, 0, 0, &size );
  if ( stat != errAEDescNotFound ) {   
    AEDisposeDesc( &list );
    return ( stat? stat : errAEEventNotHandled );
  }
  
  AECountItems ( &list, &count );
  for ( i = 1; i <= count; i++ ) {   
    stat = AEGetNthPtr (&list, i, typeFSS, &keywd,
                        &dtype, (Ptr) &fss, sizeof (fss),
                        &size);
    if ( !stat ) {   
      Nlm_ConvertFilename (&fss, filename);
      if (registeredResultProc != NULL) {
        registeredResultProc (filename);
        Nlm_FileRemove (filename); /* ? */
      } else if (registeredDropProc != NULL) {
        registeredDropProc (filename);
      }
    }
  }
  AEDisposeDesc ( &list );         
  return noErr;
}


static void Nlm_HandleEvent (void)

{
  OSErr           err;
  Nlm_Int2        key;
  Nlm_Uint4       mess;
  Nlm_PointTool   ptool;
  Nlm_Int2        windowLoc;
  Nlm_WindowTool  wptr;

  Nlm_PointToolToPoinT (Nlm_currentEvent.where, &Nlm_globalMouse);
  Nlm_localMouse = Nlm_globalMouse;
  Nlm_GlobalToLocal (&Nlm_localMouse);
  Nlm_currentKey = '\0';
  key = Nlm_currentEvent.modifiers;
  Nlm_cmmdKey = ((key & 256) != 0);
  Nlm_ctrlKey = ((key & 4096) != 0);
  Nlm_shftKey = ((key & 512) != 0);
  Nlm_optKey = ((key & 2048) != 0);
  Nlm_dblClick = FALSE;
  frontWindow = Nlm_FindWindowRec (FrontWindow ());
  Nlm_theWindow = Nlm_FindWindowRec ((Nlm_WindowTool) Nlm_currentEvent.message);
  chosenWindow = Nlm_theWindow;
  switch (Nlm_currentEvent.what) {
    case mouseDown:
      Nlm_PoinTToPointTool (Nlm_globalMouse, &ptool);
      windowLoc = FindWindow (ptool, &wptr);
      chosenWindow = Nlm_FindWindowRec (wptr);
      Nlm_DoClick ((Nlm_GraphiC) frontWindow, Nlm_globalMouse);
      break;
    case keyDown:
      Nlm_currentKey = (Nlm_Char) (Nlm_currentEvent.message % 256);
      if (keyAction != NULL) {
        keyAction (Nlm_currentKey);
      }
      Nlm_DoKey ((Nlm_GraphiC) frontWindow, Nlm_currentKey);
      break;
    case autoKey:
      if (! Nlm_cmmdKey) {
        Nlm_currentKey = (Nlm_Char) (Nlm_currentEvent.message % 256);
        Nlm_DoKey ((Nlm_GraphiC) frontWindow, Nlm_currentKey);
      }
      break;
    case updateEvt:
#ifndef WIN_MAC_QUARTZ
/* this gets handled by the HIView infrastructure behind our backs in Quartz */
      Nlm_DoDraw ((Nlm_GraphiC) Nlm_theWindow);
#endif
      break;
    case osEvt:
      mess = (Nlm_currentEvent.message & osEvtMessageMask) >> 24;
      if (mess == suspendResumeMessage) {
        if (Nlm_currentEvent.message & resumeFlag) {
          /* Resume */
#if !TARGET_API_MAC_CARBON
          if (Nlm_currentEvent.message & convertClipboardFlag) {
            /* 2001-05-14:  JDJ
             * We always convert the clipboard.
             * If it turns out that pasting is noticeably slow, I'll change it.
             */
          }
#endif
        } else {
          /* Suspend
           */
        }
      } else if (mess == mouseMovedMessage) {
        if (mouseMovedAction != NULL) {
          Nlm_PoinTToPointTool (Nlm_globalMouse, &ptool);
          windowLoc = FindWindow (ptool, &wptr);
          chosenWindow = Nlm_FindWindowRec (wptr);
          mouseMovedAction ((Nlm_GraphiC) frontWindow, Nlm_globalMouse);
        }
      }
      break;
    case activateEvt:
      if (Nlm_currentEvent.modifiers & 01) {
        Nlm_DoActivate ((Nlm_GraphiC) Nlm_theWindow, FALSE);
      } else {
        Nlm_DoDeactivate ((Nlm_GraphiC) Nlm_theWindow, FALSE);
      }
      break;
/* 2001-03-22:  Joshua Juran
 * Carbon doesn't support DIBadMount() and will not send diskEvt in the first place.
 */
#if !TARGET_API_MAC_CARBON
    case diskEvt:
      if (HiWord (Nlm_currentEvent.message) != 0) {
        Nlm_PoinT where;
        where.x = 90;
        where.y = 100;
        Nlm_PoinTToPointTool (where, &ptool);
        DIBadMount (ptool, Nlm_currentEvent.message);
      }
      break;
#endif
    case kHighLevelEvent:
      err = AEProcessAppleEvent (&Nlm_currentEvent);
      break;
    default:
      break;
  }
}

extern Nlm_Boolean Nlm_RegisterWindows (void)

{
  return TRUE;
}

#ifndef WIN_MAC_QUARTZ
static void Nlm_ReturnCursor (Cursor *cursor, Nlm_Int2 cursorID)

{
  CursHandle  hCurs;
  CursPtr     pCurs;

  hCurs = GetCursor (cursorID);
  if (hCurs != NULL) {
    HLock ((Handle) hCurs);
    pCurs = (CursPtr) *((Handle) hCurs);
    *cursor = *pCurs;
    HUnlock ((Handle) hCurs);
  } else {
    GetQDGlobalsArrow(cursor);
  }
}
#endif

static Nlm_Boolean Nlm_SetupWindows (void)

{
  Nlm_PoinT  pt;
  Nlm_RecT   r;
  long  gval;
#ifdef WIN_MAC_QUARTZ
  CGDirectDisplayID display;
  CGDisplayCount displayCount;
#else
  BitMap myScreenBits;

  Nlm_ReturnCursor (&cross, 2);
  Nlm_ReturnCursor (&iBeam, 1);
  Nlm_ReturnCursor (&plus, 3);
  Nlm_ReturnCursor (&watch, 4);
#endif
  Nlm_WatchCursor ();
  Nlm_ClearKeys ();
  Nlm_LoadPt (&pt, 0, 0);
#ifdef WIN_MAC_QUARTZ
  CGGetActiveDisplayList (1, &display, &displayCount);
  screenBitBounds = Nlm_CGRectToRecT (CGDisplayBounds (display));
#else
  GetQDGlobalsScreenBits(&myScreenBits);
  Nlm_RectToolToRecT (&(myScreenBits.bounds), &screenBitBounds);
#endif
  r = screenBitBounds;
  Nlm_screenRect = screenBitBounds;
  Nlm_desktopWindow = (Nlm_WindoW) Nlm_HandNew (sizeof (Nlm_WindowRec));
  Nlm_systemWindow = (Nlm_WindoW) Nlm_HandNew (sizeof (Nlm_WindowRec));
  Nlm_LoadGraphicData ((Nlm_GraphiC) Nlm_desktopWindow, (Nlm_GraphiC) Nlm_systemWindow,
                       NULL, NULL, NULL, desktopProcs, NULL, &r, TRUE, TRUE, NULL, NULL);
  Nlm_LoadBoxData ((Nlm_BoX) Nlm_desktopWindow, pt, pt, pt, 0, 0, 0, 0, 0, 0, 0, 0);
  Nlm_LoadWindowData (Nlm_desktopWindow, NULL, NULL, NULL, NULL, &r, &r, &r, NULL, NULL,
                      NULL, NULL, NULL, NULL, NULL, TRUE, FALSE, NULL, NULL, NULL, NULL);
  Nlm_LoadRect (&r, 0, 0, 0, 0);
  Nlm_LoadGraphicData ((Nlm_GraphiC) Nlm_systemWindow, NULL, NULL,
                       NULL, NULL, systemProcs, NULL, &r, TRUE, TRUE, NULL, NULL);
  Nlm_LoadBoxData ((Nlm_BoX) Nlm_systemWindow, pt, pt, pt, 0, 0, 0, 0, 0, 0, 0, 0);
  Nlm_LoadWindowData (Nlm_systemWindow, NULL, NULL, NULL, NULL, &r, &r, &r, NULL, NULL,
                      NULL, NULL, NULL, NULL, NULL, TRUE, FALSE, NULL, NULL, NULL, NULL);
  dyingWindow = NULL;
  frontWindow = Nlm_desktopWindow;
  theActiveWindow = Nlm_desktopWindow;
  chosenWindow = Nlm_desktopWindow;
  Nlm_theWindow = Nlm_desktopWindow;
  Nlm_currentWindowTool = (Nlm_WindowTool) 0;
  quitProgram = FALSE;

  Nlm_SetUpDrawingTools ();

  Nlm_hScrollBarHeight = 16;
  Nlm_vScrollBarWidth = 16;

  Nlm_popupMenuHeight = Nlm_stdLineHeight + 4;
  Nlm_dialogTextHeight = Nlm_stdLineHeight + 4;
  
  lastTimerTime = Nlm_ComputerTime ();
  timerAction = NULL;
  keyAction = NULL;
  mouseMovedAction = NULL;
  registeredDropProc = NULL;
  registeredServiceProc = NULL;
  registeredResultProc = NULL;

    /* gestalt for quickdraw features are defined as bits in a bitfield
       for example gestaltHasColor = 0, thus we need to test for lsb set
     */
  if( Gestalt( gestaltQuickdrawFeatures, &gval) == noErr){
      hasColorQD = (gval && (1 << gestaltHasColor));
  }
  return TRUE;
}
#endif

#ifdef WIN_MSWIN

/* Message cracker functions */

static void MyCls_OnMouseMove (HWND hwnd, int x, int y, UINT keyFlags)

{
  SetCursor (Nlm_currentCursor);
}

static void MyCls_OnShowWindow(HWND hwnd, BOOL fShow, UINT status)
{
  Nlm_SetVisible((Nlm_GraphiC)Nlm_theWindow, (Nlm_Boolean)
                 (fShow ? (status != SW_PARENTCLOSING) : FALSE));
}

static void MyCls_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)

{
  Nlm_GraphiC  g;
  Nlm_MenuBaR  mb;

  Nlm_currentId = id;
  Nlm_currentHwndCtl = hwndCtl;
  Nlm_currentCode = codeNotify;

  if (hwndCtl == NULL) {
    mb = Nlm_GetWindowMenuBar (Nlm_theWindow);
    Nlm_DoCommand ((Nlm_GraphiC) mb);
  } else {
    g = (Nlm_GraphiC) GetProp (hwndCtl, (LPSTR) "Nlm_VibrantProp");
    (void) (Nlm_GetEnabled (g) &&
            Nlm_GetVisible (g) &&
            Nlm_DoCommand (g));
  }
}

static void MyCls_OnHVScroll (HWND hwnd, HWND hwndCtl, UINT code, int pos)

{
  Nlm_GraphiC  g;

  Nlm_currentHwndCtl = hwndCtl;
  Nlm_currentCode = code;
  Nlm_currentPos = pos;

  if (hwndCtl != NULL) {
    g = (Nlm_GraphiC) GetProp (hwndCtl, (LPSTR) "Nlm_VibrantProp");
    (void) (Nlm_GetEnabled (g) &&
            Nlm_GetVisible (g) &&
            Nlm_DoCommand (g));
  }
}

static void MyCls_OnClose (HWND hwnd)

{
  Nlm_WndActnProc  cls;
  Nlm_WindowData   wdata;

  Nlm_GetWindowData (Nlm_theWindow, &wdata);
  cls = wdata.close;
  if (cls != NULL) {
    cls (Nlm_theWindow);
  }
}

static void MyCls_OnActivate(HWND hwnd, UINT state, HWND hwndActDeact, BOOL fMinimized)
{
  switch ( state )
    {
    case WA_ACTIVE:
    case WA_CLICKACTIVE:
      {
        Nlm_WindowData  wdata;
        Nlm_GetWindowData(Nlm_theWindow, &wdata);
        if ( wdata.cMap ) {
          SelectPalette(Nlm_currentHDC, wdata.cMap, FALSE);
          RealizePalette( Nlm_currentHDC );
        }
        Nlm_SetVisible((Nlm_GraphiC)Nlm_theWindow,
                       (Nlm_Boolean)(!fMinimized));
        Nlm_DoActivate((Nlm_GraphiC)Nlm_theWindow, FALSE);
        break;
      }
    case WA_INACTIVE:
      {
        Nlm_DoDeactivate((Nlm_GraphiC)Nlm_theWindow, FALSE);
        break;     
      }
    }
}


static void OnSizeMove(HWND hwnd, Nlm_Boolean resized)
{
  Nlm_RectTool rtool;

  if (!Nlm_WindowHasBeenShown( Nlm_theWindow )  ||
      !Nlm_GetVisible( (Nlm_GraphiC)Nlm_theWindow ))
    return;

  {{
  Nlm_RecT r;
  GetWindowRect(hwnd, &rtool);
  win2client(Nlm_theWindow, &rtool, &r);
  Nlm_SetRect((Nlm_GraphiC)Nlm_theWindow, &r);
  }}

  if ( resized )
    {
      Nlm_WindowData wdata;
      Nlm_GetWindowData(Nlm_theWindow, &wdata);
      if (wdata.resize == NULL)
        return;
      (*wdata.resize)( Nlm_theWindow );
      InvalidateRect(hwnd, &rtool, FALSE);
    }
}

static void MyCls_OnSize(HWND hwnd, UINT state, int cx, int cy)
{
  if ( !Nlm_GetVisible( (Nlm_GraphiC)Nlm_theWindow ) )
    return;

  Nlm_SetVisible((Nlm_GraphiC)Nlm_theWindow,
                 (Nlm_Boolean)(state != SIZE_MINIMIZED));
  OnSizeMove(hwnd, TRUE);
}

static void MyCls_OnMove(HWND hwnd, int x, int y)
{
  OnSizeMove(hwnd, FALSE);
}


static void MyCls_OnChar (HWND hwnd, UINT ch, int cRepeat)

{
  handlechar = FALSE;
  if (ch == '\t') {
    Nlm_DoSendFocus ((Nlm_GraphiC) Nlm_theWindow, (Nlm_Char) ch);
  } else if (ch == '\n' || ch == '\r') {
    Nlm_DoSendFocus ((Nlm_GraphiC) Nlm_theWindow, (Nlm_Char) ch);
  } else {
    handlechar = TRUE;
  }
}

/*
*  Note that the WM_SIZE message will trigger the resize callback whenever
*  a visible window is resized, including the initial sizing when a window
*  is first displayed.
*/

static LRESULT CALLBACK EXPORT MainProc (HWND hwnd, UINT message,
                                  WPARAM wParam, LPARAM lParam)

{
  MINMAXINFO FAR*  lpmmi;
  HDC              tempHDC;
  HWND             tempHWnd;
  LRESULT          mainwndrsult = 0;

  if (Nlm_VibrantDisabled ()) {
    return DefWindowProc (hwnd, message, wParam, lParam);
  }

  tempHWnd = Nlm_currentHWnd;
  tempHDC = Nlm_currentHDC;
  Nlm_theWindow = (Nlm_WindoW) GetProp (hwnd, (LPSTR) "Nlm_VibrantProp");
  Nlm_currentHWnd = hwnd;
  Nlm_currentHDC = Nlm_GetWindowPort (Nlm_theWindow);
  Nlm_currentWindowTool = hwnd;
  Nlm_currentKey = '\0';
  Nlm_currentWParam = wParam;
  Nlm_currentLParam = lParam;
  Nlm_cmmdKey = FALSE;
  Nlm_optKey = FALSE;
  Nlm_ctrlKey = (Nlm_Boolean) ((GetKeyState (VK_CONTROL) & 0x8000) != 0);
  Nlm_shftKey = (Nlm_Boolean) ((GetKeyState (VK_SHIFT)   & 0x8000) != 0);
  Nlm_dblClick = FALSE;

  switch ( message )
    {
    case WM_MOUSEMOVE:
      HANDLE_WM_MOUSEMOVE (hwnd, wParam, lParam, MyCls_OnMouseMove);
      break;
    case WM_SHOWWINDOW:
      HANDLE_WM_SHOWWINDOW (hwnd, wParam, lParam, MyCls_OnShowWindow);
      break;
    case WM_COMMAND:
      HANDLE_WM_COMMAND (hwnd, wParam, lParam, MyCls_OnCommand);
      break;
    case WM_HSCROLL:
      HANDLE_WM_HSCROLL (hwnd, wParam, lParam, MyCls_OnHVScroll);
      break;
    case WM_VSCROLL:
      HANDLE_WM_VSCROLL (hwnd, wParam, lParam, MyCls_OnHVScroll);
      break;
    case WM_CLOSE:
      HANDLE_WM_CLOSE (hwnd, wParam, lParam, MyCls_OnClose);
      break;
    case WM_ACTIVATE:
      mainwndrsult = DefWindowProc (hwnd, message, wParam, lParam);
      HANDLE_WM_ACTIVATE (hwnd, wParam, lParam, MyCls_OnActivate);
      break;
    case WM_SIZE:
      HANDLE_WM_SIZE (hwnd, wParam, lParam, MyCls_OnSize);
      break;
    case WM_MOVE:
      HANDLE_WM_MOVE (hwnd, wParam, lParam, MyCls_OnMove);
      break;
    case WM_GETMINMAXINFO:
      lpmmi = (MINMAXINFO FAR*) lParam;
      lpmmi->ptMaxTrackSize.x = 30000;
      lpmmi->ptMaxTrackSize.y = 30000;
      break;
    case WM_DESTROY:
      break;

#ifdef WIN32
    case WM_CTLCOLORSTATIC:
      {
              HDC hdc = GetDC( hwnd );
              SetBkMode((HDC)wParam, TRANSPARENT);
              ReleaseDC(hwnd, hdc); 
              mainwndrsult = GetClassLongPtr(hwnd, GCLP_HBRBACKGROUND);
              break;
      }
    case WM_CTLCOLORLISTBOX:
    case WM_CTLCOLOREDIT:
      {
          if(Nlm_hasBackColor)
          {
        SetBkColor((HDC)wParam, Nlm_crBackColor);
        mainwndrsult = (long)Nlm_hbrWindowBackground;
          }
          else
          {
        SetBkColor((HDC)wParam, RGB(255, 255, 255));
        mainwndrsult = (long)GetStockObject( WHITE_BRUSH );
          }
              break;
      }
    case WM_CTLCOLORDLG:
    case WM_CTLCOLORBTN:
      {
          if(Nlm_hasBackColor)
          {
        SetBkColor((HDC)wParam, Nlm_crBackColor);
        mainwndrsult = (long)Nlm_hbrWindowBackground;
          }
          else
        mainwndrsult = DefWindowProc (hwnd, message, wParam, lParam);
              break;
      }
#else
    case WM_CTLCOLOR:
      switch ( lParam )
            {
            case CTLCOLOR_STATIC:
              {
                HDC hdc = GetDC( hwnd );
                SetBkMode((HDC)wParam, TRANSPARENT);
                ReleaseDC(hwnd, hdc); 
                mainwndrsult = GetClassLongPtr(hwnd, GCLP_HBRBACKGROUND);
                break;
              }
            case CTLCOLOR_LISTBOX:
            case CTLCOLOR_EDIT:
              {
                SetBkColor((HDC)wParam, RGB(255, 255, 255));
                mainwndrsult = (long)(int)GetStockObject( WHITE_BRUSH );
                break;
              }
            default:
              mainwndrsult = DefWindowProc(hwnd, message, wParam, lParam);
            }
      break;
#endif

    case WM_KEYDOWN:
      if ( !Nlm_ProcessKeydown((Nlm_GraphiC)Nlm_theWindow, wParam,
                                VERT_PAGE|VERT_ARROW|HORIZ_PAGE|HORIZ_ARROW) )
        mainwndrsult = DefWindowProc(hwnd, message, wParam, lParam);
      break;
    case WM_CHAR:
      HANDLE_WM_CHAR (hwnd, wParam, lParam, MyCls_OnChar);
      if (handlechar) {
        mainwndrsult = DefWindowProc (hwnd, message, wParam, lParam);
      }
      break;
    case WM_DROPFILES:
      {
        Nlm_Char fnamebuf[PATH_MAX];

        DragQueryFile((HDROP)wParam,0,fnamebuf,sizeof(fnamebuf));
        if (registeredDropProc != NULL)
        {
          registeredDropProc(fnamebuf);
        }
        DragFinish((HDROP)wParam);
      }
      break;
    default:
      mainwndrsult = DefWindowProc (hwnd, message, wParam, lParam);
      break;
  }
  Nlm_currentHWnd = tempHWnd;
  Nlm_currentHDC = tempHDC;
  Nlm_currentWindowTool = tempHWnd;
  return mainwndrsult;
}

static void FAR PASCAL EXPORT MetronomeProc (HWND hwnd, UINT message,
                                      WPARAM wParam, LPARAM lParam)

{
  if (Nlm_VibrantDisabled ()) {
    return;
  }
  if (message == WM_TIMER) {
    if (timerAction != NULL) {
      timerAction ();
    }
    Nlm_CallWindowTimers ();
  }
}

extern Nlm_Boolean Nlm_RegisterWindows (void)
{
  WNDCLASS     wc;

  wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc = MainProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = Nlm_currentHInst;
  wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  wc.hCursor = NULL;
  wc.hbrBackground = Nlm_hasBackColor ?
                   CreateSolidBrush( Nlm_crBackColor ) :
                       CreateSolidBrush( GetSysColor(COLOR_ACTIVEBORDER) );
  wc.lpszMenuName = NULL;
  sprintf (windowclass, "Nlm_WindowClass%ld", (long) (int) Nlm_currentHInst);
  wc.lpszClassName = windowclass;

  return (Nlm_Boolean)(RegisterClass(&wc) != 0);
}


#include "vibrgb.h"


static Nlm_RGBName* Nlm_FindRGBName(const Nlm_Char* name)

{
  Nlm_RGBName* p;
  for(p = RGBNames; p->name; ++p) {
    if (StringICmp(p->name, name) == 0)
      return p;
  }

  return NULL;
}


static void Nlm_ParseXArguments(int* argc, char** argv)

{
  int i, j;

  if (argc == 0 || argv == NULL)
    return;

  for(i = 0, j = 0; i < *argc; ) {
    if (StringCmp(argv[i], "-bg") == 0 && argv[i+1] != NULL) {
      Nlm_RGBName* p = Nlm_FindRGBName(argv[i+1]);
      if (p != NULL) {
    /* Set user-defined background color */
    Nlm_hasBackColor = TRUE;
    Nlm_crBackColor = RGB(p->red, p->green, p->blue);
    Nlm_hbrWindowBackground = CreateSolidBrush( Nlm_crBackColor );
    i += 2;
    continue;
      }
    }
    argv[j++] = argv[i++];
  }
  *argc = j;
}


static Nlm_Boolean Nlm_SetupWindows (void)

{
  Nlm_Int2   height;
  WNDPROC    lpfnTimerProc;
  Nlm_PoinT  pt;
  Nlm_RecT   r;
  Nlm_Int2   width;

  int        xx_argc = (int)Nlm_GetArgc();
  char     **xx_argv =      Nlm_GetArgv();

  /*
    Using SM_CXVIRTUALSCREEN to accomodate dual monitors effectively limits target platform 
    to Windows2000 or later (i.e. Win95/98/ME are NOT supported).
    In order to use these identifiers, must define WINVER=0x0500.
  */
#if(WINVER >= 0x0500)
  int x = (Nlm_Int2)GetSystemMetrics (SM_XVIRTUALSCREEN);
  int y = (Nlm_Int2)GetSystemMetrics (SM_YVIRTUALSCREEN);
  width  = (Nlm_Int2)GetSystemMetrics (SM_CXVIRTUALSCREEN);
  height = (Nlm_Int2)GetSystemMetrics (SM_CYVIRTUALSCREEN);
  Nlm_LoadRect (&screenBitBounds, x, y, x+width, y+height);
  Nlm_LoadPt (&pt, x, y);
#else
  width  = (Nlm_Int2)GetSystemMetrics (SM_CXSCREEN);
  height = (Nlm_Int2)GetSystemMetrics (SM_CYSCREEN);
  Nlm_LoadRect (&screenBitBounds, 0, 0, width, height);
  Nlm_LoadPt (&pt, 0, 0);
#endif
  r = screenBitBounds;
  Nlm_screenRect = screenBitBounds;
  Nlm_desktopWindow = (Nlm_WindoW) Nlm_HandNew (sizeof (Nlm_WindowRec));
  Nlm_LoadGraphicData ((Nlm_GraphiC) Nlm_desktopWindow, NULL, NULL,
                       NULL, NULL, desktopProcs, NULL, &r, TRUE, TRUE, NULL, NULL);
  Nlm_LoadBoxData ((Nlm_BoX) Nlm_desktopWindow, pt, pt, pt, 0, 0, 0, 0, 0, 0, 0, 0);
  Nlm_LoadWindowData (Nlm_desktopWindow, NULL, NULL, NULL, NULL, &r, &r, &r, NULL, NULL,
                      NULL, NULL, NULL, NULL, NULL, TRUE, FALSE, NULL, NULL, NULL, NULL);
  Nlm_systemWindow = NULL;
  Nlm_currentHWnd = NULL;
  Nlm_currentHDC = NULL;
  Nlm_currentWindowTool = (Nlm_WindowTool) 0;
  quitProgram = FALSE;
  
  Nlm_ParseXArguments(&xx_argc, xx_argv);
  Nlm_SetupArguments(xx_argc, xx_argv);

  Nlm_SetUpDrawingTools ();

  Nlm_hScrollBarHeight = (Nlm_Int2)GetSystemMetrics (SM_CYHSCROLL);
  Nlm_vScrollBarWidth  = (Nlm_Int2)GetSystemMetrics (SM_CXVSCROLL);

  Nlm_popupMenuHeight  = (Nlm_Int2)(Nlm_stdLineHeight + 8);
  Nlm_dialogTextHeight = (Nlm_Int2)(Nlm_stdFontHeight * 3 / 2);
  
  Nlm_currentCursor = LoadCursor (NULL, IDC_WAIT);
  
  lpfnTimerProc = (WNDPROC) MakeProcInstance ((FARPROC) MetronomeProc, Nlm_currentHInst);
  if (lpfnTimerProc != NULL) {
    timerID = SetTimer (NULL, 1, 50, (TIMERPROC) lpfnTimerProc);
  }
  timerAction = NULL;
  keyAction = NULL;
  mouseMovedAction = NULL;
  registeredDropProc = NULL;
  registeredServiceProc = NULL;
  registeredResultProc = NULL;
  return TRUE;
}
#endif  /* WIN_MSWIN */


#ifdef WIN_MOTIF
static void Nlm_WindowTimer (XtPointer client_data, XtIntervalId *id)

{
  if (! quitProgram) {
    windowTimer = XtAppAddTimeOut (Nlm_appContext, 50, Nlm_WindowTimer, NULL);
  }
  if (timerAction != NULL) {
    timerAction ();
  }
  Nlm_CallWindowTimers ();
}

extern Nlm_Boolean Nlm_RegisterWindows (void)

{
  windowTimer = XtAppAddTimeOut (Nlm_appContext, 50, Nlm_WindowTimer, NULL);
  return TRUE;
}

char * defFallbackRes[] =
{
  "Vibrant*background:                      light grey",
  "Vibrant*foreground:                      black",
  "Vibrant*XmPushButton.background:         grey",
  "Vibrant*XmToggleButton.foreground:       blue",
  "Vibrant*XmText.background:               white",
  "Vibrant*XmTextField.background:          white",
  "Vibrant*XmScrolledWindow.background:     white",
  "Vibrant*XmList.background:               white",
  "Vibrant*XmDrawingArea.background:        white",
  "Vibrant*XmOptionButtonGadget.background: grey",

  NULL
};


static Boolean Nlm_XrmGetResource1(const char *_basename,
                                   const char *_resource,
                                   XrmValuePtr value)
{
  XrmDatabase rdb = XtDatabase( Nlm_currentXDisplay );
  XrmString type_str;
  Boolean ok;

  size_t basename_len = Nlm_StringLen( _basename );
  size_t resource_len = Nlm_StringLen( _resource );
  size_t len = basename_len + resource_len + 2;

  char *xx_name  = XtMalloc( len );
  char *xx_class = XtMalloc( len );

  Nlm_StrCpy(xx_name, _basename);
  xx_name[basename_len] = '.';
  Nlm_StrCpy(xx_name + basename_len + 1, _resource);

  Nlm_StrCpy(xx_class, xx_name);
  xx_class[0]                = TO_UPPER( _basename[0] );
  xx_class[basename_len + 1] = TO_UPPER( _resource[0] );

  ok = XrmGetResource(rdb, xx_name, xx_class, &type_str, value);

  XtFree( xx_class );
  XtFree( xx_name  );

  return ok;
}


static Boolean Nlm_XrmGetResource2(const char *_basename,
                                   const char *_resource,
                                   XrmValuePtr value)
{
  ASSERT ( _basename  &&  *_basename );
  ASSERT ( _resource  &&  *_resource );
  ASSERT ( value );

  return
    Nlm_XrmGetResource1(_basename,   _resource, value)  ||
    Nlm_XrmGetResource1(Nlm_VibName, _resource, value);
}


extern Nlm_CharPtr Nlm_XrmGetResource(const Nlm_Char PNTR _resource)
{
  XrmValue value;
  if (_resource  && Nlm_XrmGetResource2(Nlm_AppName, _resource, &value))
    return Nlm_StringSave( (Nlm_CharPtr)value.addr );

  return NULL;
}


extern XFontStruct *Nlm_XLoadStandardFont(void); /* <-- see in "ncbidraw.c" */

static Nlm_Boolean Nlm_SetupWindows (void)
{
  Nlm_Int4   height;
  Nlm_PoinT  pt;
  Nlm_RecT   r;
  Nlm_Int4   width;
  int        xx_argc = (int)Nlm_GetArgc();
  char     **xx_argv =      Nlm_GetArgv();
  XmFontListEntry font_entry;

  Nlm_desktopWindow = NULL;
  Nlm_systemWindow = NULL;
  Nlm_currentXDisplay = NULL;
  Nlm_currentXScreen = 0;
  Nlm_currentXWindow = 0;
  Nlm_currentXGC = NULL;
  Nlm_currentWindowTool = (Nlm_WindowTool) 0;
  quitProgram = FALSE;
  timerAction = NULL;
  keyAction = NULL;
  mouseMovedAction = NULL;
  registeredDropProc = NULL;
  registeredServiceProc = NULL;
  registeredResultProc = NULL;
  XtToolkitInitialize ();
  Nlm_appContext = XtCreateApplicationContext ();
  if (Nlm_appContext == NULL) {
    return FALSE;
  }

  if (xx_argc  &&  *xx_argv[0])
    {/* Get the application basename(cut off path and extention(s), locase) */
      const char *s     = xx_argv[0];
      const char *start = s;

      while ( *s )
        if (*s++ == '/') {
          while (*s  &&  (*s == '/'  ||  *s == '.'))
            s++;
          start = s;
        }

      for (s = start;  *s && *s != '.';  s++);
      ASSERT ( s  >=  start );

      if (s != start) {
        size_t len = s - start;
        ASSERT ( len  <  sizeof(Nlm_AppName) );
        Nlm_AppName[len] = '\0';
        while (len-- > 0)
          Nlm_AppName[len] = TO_LOWER( start[len] );
      }
    }

  {{
#define disp_opTable_SIZE 2
    static XrmOptionDescRec disp_opTable[disp_opTable_SIZE] = {
      {"-display", ".display", XrmoptionSepArg, 0},
      {"-dpy",     ".display", XrmoptionSepArg, 0}
    };
    XrmString type_str;
    XrmDatabase disp_db = NULL;
    XrmValue value;
    XrmInitialize();
    XrmParseCommand(&disp_db, disp_opTable, disp_opTable_SIZE,
                    "vibrant", &xx_argc, xx_argv);
    if ( !XrmGetResource(disp_db,  "vibrant.display", "Vibrant.Display",
                         &type_str, &value) )
      value.addr = NULL;
    Nlm_currentXDisplay = XOpenDisplay( (char *)value.addr );
    XrmDestroyDatabase( disp_db );
  }}

  if (Nlm_currentXDisplay == NULL) {
    fprintf (stderr, "Vibrant applications require X Windows\n");
    return FALSE;
  }

  XSetErrorHandler( defaultXerror_handler );

  Nlm_currentXScreen = DefaultScreen (Nlm_currentXDisplay);
  width =  DisplayWidth (Nlm_currentXDisplay, Nlm_currentXScreen);
  height = DisplayHeight (Nlm_currentXDisplay, Nlm_currentXScreen);

  Nlm_LoadRect (&screenBitBounds, 0, 0, (Nlm_Int2) width, (Nlm_Int2) height);
  Nlm_LoadPt (&pt, 0, 0);
  r = screenBitBounds;
  Nlm_screenRect = screenBitBounds;
  Nlm_desktopWindow = (Nlm_WindoW) Nlm_HandNew (sizeof (Nlm_WindowRec));
  Nlm_LoadGraphicData((Nlm_GraphiC)Nlm_desktopWindow, NULL, NULL,
                      NULL, NULL, desktopProcs, NULL, &r,
                      TRUE, TRUE, NULL, NULL);
  Nlm_LoadBoxData((Nlm_BoX)Nlm_desktopWindow,
                  pt, pt, pt, 0, 0, 0, 0, 0, 0, 0, 0);
  Nlm_LoadWindowData(Nlm_desktopWindow,
                     NULL, NULL, NULL, NULL, &r, &r, &r, NULL, NULL,
                     NULL, NULL, NULL, NULL, NULL, TRUE, FALSE, NULL,
                     NULL, NULL, NULL);

  if (DisplayPlanes(Nlm_currentXDisplay, Nlm_currentXScreen) != 1)
    XtAppSetFallbackResources (Nlm_appContext, (String*)defFallbackRes );

  XtDisplayInitialize (Nlm_appContext, Nlm_currentXDisplay,
                       (String)Nlm_AppName, (String)Nlm_VibClass,
                       (XrmOptionDescRec *)NULL, (Cardinal)0,
                       &xx_argc, xx_argv);
  Nlm_SetupArguments(xx_argc, xx_argv);

  Nlm_currentXGC = Nlm_GetGC(DefaultDepth(Nlm_currentXDisplay,
                                          Nlm_currentXScreen));
                             
  Nlm_SetUpDrawingTools();

  Nlm_RegisterStdTranslations();

  Nlm_hScrollBarHeight = 15;
  Nlm_vScrollBarWidth  = 15;

  Nlm_popupMenuHeight  = Nlm_stdLineHeight + 18;
  Nlm_dialogTextHeight = Nlm_stdLineHeight + 6;
  
  arrow = XCreateFontCursor (Nlm_currentXDisplay, XC_top_left_arrow);
  cross = XCreateFontCursor (Nlm_currentXDisplay, XC_cross);
  iBeam = XCreateFontCursor (Nlm_currentXDisplay, XC_xterm);
  plus  = XCreateFontCursor (Nlm_currentXDisplay, XC_crosshair);
  watch = XCreateFontCursor (Nlm_currentXDisplay, XC_watch);

  Nlm_currentCursor = arrow;
  
  font = Nlm_XLoadStandardFont();

  font_entry = XmFontListEntryCreate  ("dummy", XmFONT_IS_FONT, font);
  Nlm_XfontList = XmFontListAppendEntry(NULL, font_entry);

  Nlm_fileDialogShell = NULL;

  return TRUE;
}
#endif  /* WIN_MOTIF */


/*
#ifndef WIN_MOTIF
static void Nlm_WindowGo (Nlm_WindoW w)
{
  inNotice = FALSE;
  Nlm_DoRemove ((Nlm_GraphiC) w, TRUE);
}

static void Nlm_PanelGo (Nlm_PaneL p, Nlm_PoinT pt)
{
  Nlm_WindoW  w;

  inNotice = FALSE;
  w = Nlm_ParentWindow (p);
  Nlm_DoRemove ((Nlm_GraphiC) w, TRUE);
}


static void Nlm_CenterLine (Nlm_RectPtr rptr, Nlm_CharPtr text, Nlm_FonT fnt)
{
  if (fnt != NULL) {
    Nlm_SelectFont (fnt);
  }
  rptr->bottom = (Nlm_Int2)(rptr->top + Nlm_LineHeight());
  Nlm_DrawString (rptr, text, 'c', FALSE);
  rptr->top = rptr->bottom;
}


static void Nlm_DrawAbout (Nlm_PaneL p)

{
  Nlm_RecT  r;

  Nlm_ObjectRect (p, &r);
  Nlm_InsetRect (&r, 4, 4);
  r.top += 10;
  Nlm_Blue ();
  Nlm_CenterLine (&r, "VIBRANT", Nlm_systemFont);
  r.top += 10;
  Nlm_Red ();
  Nlm_CenterLine (&r, "National Center for Biotechnology Information", Nlm_systemFont);
  r.top += 5;
  Nlm_CenterLine (&r, "National Library of Medicine", Nlm_systemFont);
  r.top += 5;
  Nlm_CenterLine (&r, "National Institutes of Health", Nlm_systemFont);
  r.top += 10;
  Nlm_CenterLine (&r, "(301) 496-2475", Nlm_systemFont);
  r.top += 5;
  Nlm_CenterLine (&r, "info@ncbi.nlm.nih.gov", Nlm_systemFont);
}


static void Nlm_GetSet (void)
{
  Nlm_PaneL   p;
  Nlm_WindoW  w;

  w = Nlm_ModalWindow (-50, -33, -1, -1, Nlm_WindowGo);
  p = Nlm_SimplePanel (w, (Nlm_Int2)(28 * Nlm_stdCharWidth),
                          (Nlm_Int2)(10 * Nlm_stdLineHeight), Nlm_DrawAbout);
  Nlm_SetPanelClick (p, NULL, NULL, NULL, Nlm_PanelGo);
  Nlm_DoShow ((Nlm_GraphiC) w, TRUE, TRUE);
  inNotice = TRUE;
  while (inNotice) {
    Nlm_ProcessAnEvent ();
  }
}
#endif
*/

#ifdef WIN_MSWIN
static void ParseSetupArguments(HINSTANCE hInstance, Nlm_CharPtr lpszCmdLine)
{
  int    xx_argc;
  char **xx_argv;

  static char winfile[128];
  char *p;

  GetModuleFileName(hInstance, winfile, sizeof(winfile));

  if ((p = strrchr(winfile, DIRDELIMCHR)) != NULL)
    p++;
  else
    p = winfile;
  SetProgramName(p);

  if (!lpszCmdLine  ||  !*lpszCmdLine)
    {
      xx_argc = 1;
      xx_argv = (char **)Nlm_MemNew( sizeof(char*) );
      xx_argv[0] = winfile;
      Nlm_SetupArguments(xx_argc, xx_argv);
      return;
    }

  /* Count command-line arguments and separate them by '\0' */
  xx_argc = 1;
  for (p = lpszCmdLine;  *p; )
    {
      if ( isspace(*p) )
        {
          *p++ = '\0';
          continue;
        }

      if (*p == '\''  ||  *p == '"')
        {
          char quote = *p;
          xx_argc++;
          while (*(++p)  &&  *p != quote) continue;
          if ( *p )
            *p++ = '\0';
          continue;
        }

      xx_argc++;
      while (*p  &&  !isspace(*p))
        p++;
    }

  /* Allocate and fill out "xx_argv" */
  {{
    int   n = 0;
    char *s = lpszCmdLine;
    xx_argv = (char **)Nlm_MemNew(xx_argc * sizeof(char*));
    xx_argv[n++] = winfile;
    while (n < xx_argc)
      {
        while ( !*s )
          s++;
        if (*s == '\''  ||  *s == '"')
          s++; /* -- skip the leading quote */
        xx_argv[n++] = s;
        while ( *s )
          s++;
      }
#ifdef _DEBUG
    while (s < p  &&  !*s)
      s++;
    ASSERT ( s == p );
#endif
  }}

  Nlm_SetupArguments(xx_argc, xx_argv);
}
#endif


static void Nlm_GetReady (void)
{
  Nlm_VibrantSetGUI();
  Nlm_InitCursorShapes();
  Nlm_textScrapFull = FALSE;
  Nlm_processUpdatesFirstVal = TRUE;
}

static void Nlm_CleanUpWindows (void)

/*
*  Since submenus goes into the Macintosh desktop menu bar, to allow for
*  command key equivalents, it can be very dangerous to remove the menu
*  bar.  The submenu linked into the menu bar now no longer removes its
*  children, leaving that up to the submenu item.
*/

{
  Nlm_GraphiC  g;
  Nlm_MenuBaR  mb;
  Nlm_GraphiC  n;
  Nlm_WindoW   w;

  okayToDrawContents = FALSE; /* suppress all further slate content drawing */

  Nlm_RemoveDyingWindows();

#ifdef WIN_MSWIN
  if (timerID != 0) {
    KillTimer (NULL, timerID);
  }
#endif
#ifdef WIN_MOTIF
  XtRemoveTimeOut (windowTimer);
#endif
  w = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) Nlm_desktopWindow);
  while (w != NULL && w != Nlm_systemWindow) {
    Nlm_UseWindow (w);
    Nlm_DoHide ((Nlm_GraphiC) w, TRUE, FALSE);
    g = Nlm_GetChild ((Nlm_GraphiC) w);
    while (g != NULL) {
      n = Nlm_GetNext (g);
      Nlm_DoRemove (g, FALSE);
      g = n;
    }
    mb = Nlm_GetWindowMenuBar (w);
    if (mb != NULL) {
      Nlm_DoRemove ((Nlm_GraphiC) mb, FALSE);
      Nlm_SetWindowMenuBar (w, NULL);
    }
    w = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) w);
  }
  w = Nlm_desktopWindow;
  mb = Nlm_GetWindowMenuBar (w);
  if (mb != NULL) {
    Nlm_DoRemove ((Nlm_GraphiC) mb, FALSE);
    Nlm_SetWindowMenuBar (w, NULL);
  }
#ifdef WIN_MOTIF
  resource_nm = (Nlm_CharPtr) Nlm_MemFree (resource_nm);
#endif
}


#ifdef WIN_MSWIN
#ifdef WIN32
#ifndef __MINGW32__
static int Nlm_HandleException (DWORD code)

{
  Nlm_Message (MSG_OK, "WIN32 exception %ld", (long)code);
  return EXCEPTION_CONTINUE_SEARCH;
}
#endif
#endif
#endif

#ifdef WIN_MOTIF
#if defined(OS_UNIX) && defined(COMP_SUNPRO)
static char **tenvp = NULL;

extern void Nlm_DisplayEnvironmentVariables (void);
extern void Nlm_DisplayEnvironmentVariables (void)

{
  FILE  *f;
  int   i;

  if (tenvp == NULL) return;
  f = Nlm_FileOpen ("EnvLogFile", "a");
  if (f == NULL) return;
  for (i = 0; tenvp [i] != NULL; i++) {
    fprintf (f, "%s\n", tenvp [i]);
  }
  Nlm_FileClose (f);
}
#endif
#endif




#ifdef WIN_MAC
#ifdef OS_UNIX_DARWIN
extern int Nlm_VibMainPrelude (int argc, char *argv[])
{
  long   gval;
  OSStatus  err;

  Nlm_SetupArguments (argc, argv);
# else /* ! OS_UNIX_DARWIN */
extern void Nlm_VibMainPrelude ()
{
  long   gval;
  OSErr  err;
# endif

#if __profile__
  ProfilerInit (collectDetailed, bestTimeBase, 1000, 50);
  ProfilerSetStatus (FALSE);
#endif

#if TARGET_API_MAC_CARBON >= 1
  /*
   carbon changes the API: pass the number of master pointers to allocate
   MoreMasters (1280);
   2001-03-22:  Joshua Juran
   CarbonDater report says to use MoreMasterPointers() instead of MoreMasters().
   Universal Interfaces 3.3.2 declares MoreMasters(void) under Carbon.
  */
  /* MoreMasterPointers(1280); Don't need this under OSX. */
  FlushEvents (everyEvent, 0);
  /* the rest of the toolbox is done for us can't init them...
   */
#else
  MaxApplZone ();
  if (1) {
    Nlm_Int2 i;
    for (i = 0; i < 20; i++) {
      MoreMasters ();
    }
  }
  InitGraf (&qd.thePort);
  InitFonts ();
  FlushEvents (everyEvent, 0);
  InitWindows ();
  InitMenus ();
  TEInit ();
  InitDialogs (0);
#endif
#ifdef WIN_MAC_QUARTZ
  err = TXNInitTextension (NULL, 0, 0);
  if(err) abort();
#else
  InitCursor ();
#endif

  err = Gestalt (gestaltAppleEventsAttr, &gval);
  if (err == noErr && ((short) gval & (1 << gestaltAppleEventsPresent)) != 0) {
    /* Create Routine Descriptors - from RasMol */
    HandleAEIgnorePtr = NewAEEventHandlerUPP(HandleAEIgnore);
    HandleAEOpenDocPtr = NewAEEventHandlerUPP(HandleAEOpenDoc);
    HandleAEQuitAppPtr = NewAEEventHandlerUPP(HandleAEQuitApp);
    HandleAEAnswerPtr = NewAEEventHandlerUPP(HandleAEAnswer);

    /* Install Required Event Handlers */
    AEInstallEventHandler(kCoreEventClass,kAEOpenApplication,
                          HandleAEIgnorePtr, 0, FALSE);
    AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,
                          HandleAEOpenDocPtr, 0, FALSE);
    AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments,
                          HandleAEIgnorePtr, 1, FALSE);
    AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,
                          HandleAEQuitAppPtr, 0, FALSE);
    AEInstallEventHandler(kCoreEventClass,kAEAnswer,
                          HandleAEAnswerPtr, 0, FALSE);
  }

  Nlm_usesMacNavServices = FALSE;
  err = Gestalt (gestaltAppleEventsAttr, &gval);
  if (err == noErr && ((short) gval & (1 << gestaltAppearanceExists)) != 0) {
    if (NavServicesAvailable ()) {
      Nlm_usesMacNavServices = TRUE;
    }
  }
  if (Nlm_usesMacNavServices) {
    NavLoad ();
  }

  Nlm_InitVibrantHooks ();

  Nlm_InitWindows ();
  Nlm_InitBars ();
  Nlm_InitButtons ();
  Nlm_InitExtras ();
  Nlm_InitForms ();
  Nlm_InitGroup ();
  Nlm_InitLists ();
  Nlm_InitMenus ();
  Nlm_InitPrompt ();
  Nlm_InitSlate ();
  Nlm_InitTexts ();
  Nlm_SetupWindows ();
  Nlm_RegisterWindows ();
  Nlm_RegisterTexts ();
  Nlm_RegisterSlates ();
#ifndef OS_UNIX_DARWIN
  Nlm_SetupArguments(0, NULL);
#endif
  Nlm_GetReady ();

  /* Initialize connection library's logger, registry and lock */
  CONNECT_Init(0);

  /* There is no need to initialize the TE private scrap because
   * we never assume it's current.
   */
}




#ifdef OS_UNIX_DARWIN
extern int Nlm_VibMainFinale (int argc, char *argv[])
{
# else /* ! OS_UNIX_DARWIN */
extern void Nlm_VibMainFinale ()
{
# endif

  Nlm_CleanUpWindows ();
  Nlm_CleanUpDrawingTools ();
  Nlm_FreeWindows ();
  Nlm_FreeBars ();
  Nlm_FreeButtons ();
  Nlm_FreeExtras ();
  Nlm_FreeForms ();
  Nlm_FreeGroup ();
  Nlm_FreeLists ();
  Nlm_FreeMenus ();
  Nlm_FreePrompt ();
  Nlm_FreeSlate ();
  Nlm_FreeTexts ();
  Nlm_FreeConfigStruct ();
  Nlm_ErrSetLogfile (NULL,0);
  if (Nlm_usesMacNavServices) {
    NavUnload ();
  }

#if __profile__
  ProfilerDump ("\pvibrant.prof");
  ProfilerTerm ();
#endif
}
#endif




#ifdef WIN_MSWIN
extern int CALLBACK Nlm_VibMainPrelude (
  HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  LPSTR lpszCmdLine,
  int nCmdShow
)
{
  Nlm_Char  str [32];

#ifdef WIN32
#ifndef __MINGW32__
  __try {
#endif
#endif

  Nlm_currentHInst = hInstance;
  ParseSetupArguments(Nlm_currentHInst, StringSave(lpszCmdLine));

  Nlm_InitVibrantHooks ();

  Nlm_InitWindows ();
  Nlm_InitBars ();
  Nlm_InitButtons ();
  Nlm_InitExtras ();
  Nlm_InitForms ();
  Nlm_InitGroup ();
  Nlm_InitLists ();
  Nlm_InitMenus ();
  Nlm_InitPrompt ();
  Nlm_InitSlate ();
  Nlm_InitTexts ();
  Nlm_SetupWindows ();
  if (! (Nlm_RegisterWindows ())) {
    return FALSE;
  }
  if (! (Nlm_RegisterTexts ())) {
    return FALSE;
  }

  if (! (Nlm_RegisterSlates ())) {
    sprintf (str, "Nlm_WindowClass%ld", (long) (int) Nlm_currentHInst);
    UnregisterClass (str, Nlm_currentHInst);
    return FALSE;
  }


  Nlm_GetReady ();

  /* Initialize connection library's logger, registry and lock */
  CONNECT_Init(0);

#ifdef WIN32
#ifndef __MINGW32__
  }
  __except ( Nlm_HandleException( GetExceptionCode() ) )  { }
#endif
#endif

  return TRUE;
}


extern int CALLBACK Nlm_VibMainFinale (
  HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  LPSTR lpszCmdLine,
  int nCmdShow
)
{
  Nlm_Char  str [32];
  WNDCLASS  wc;

#ifdef WIN32
#ifndef __MINGW32__
  __try {
#endif
#endif

  Nlm_CleanUpWindows ();
  Nlm_CleanUpDrawingTools ();
  Nlm_FreeWindows ();
  Nlm_FreeBars ();
  Nlm_FreeButtons ();
  Nlm_FreeExtras ();
  Nlm_FreeForms ();
  Nlm_FreeGroup ();
  Nlm_FreeLists ();
  Nlm_FreeMenus ();
  Nlm_FreePrompt ();
  Nlm_FreeSlate ();
  Nlm_FreeTexts ();
  Nlm_FreeConfigStruct ();
  Nlm_ErrSetLogfile (NULL,0);

  sprintf (str, "Nlm_WindowClass%ld", (long) (int) Nlm_currentHInst);
  if (GetClassInfo (Nlm_currentHInst, str, &wc)) {
    /* WNDCLASS description says application should not destroy background brush */
    /* DeleteObject (wc.hbrBackground); */
  }
  UnregisterClass (str, Nlm_currentHInst);
  sprintf (str, "Nlm_SlateClass%ld", (long) (int) Nlm_currentHInst);
  UnregisterClass (str, Nlm_currentHInst);
  Nlm_MemFree( Nlm_GetArgv() );

#ifdef WIN32
#ifndef __MINGW32__
  }
  __except ( Nlm_HandleException( GetExceptionCode() ) )  { }
#endif
#endif

  return TRUE;
}
#endif



#ifdef WIN_MOTIF
#if defined(OS_UNIX) && defined(COMP_SUNPRO)
extern void Nlm_VibMainPrelude (int argc, char *argv[], char *envp[])
#else
extern void Nlm_VibMainPrelude (int argc, char *argv[])
#endif
{
  Nlm_Int2  retval;

  Nlm_SetupArguments(argc, argv);

#if defined(OS_UNIX) && defined(COMP_SUNPRO)
  tenvp = envp;
#endif

  Nlm_InitVibrantHooks ();

  Nlm_InitWindows ();
  Nlm_InitButtons ();
  Nlm_InitExtras ();
  Nlm_InitForms ();
  Nlm_InitGroup ();
  Nlm_InitBars ();
  Nlm_InitLists ();
  Nlm_InitMenus ();
  Nlm_InitPrompt ();
  Nlm_InitSlate ();
  Nlm_InitTexts ();
  if (! Nlm_SetupWindows ()) return;
  Nlm_RegisterWindows ();
  Nlm_RegisterTexts ();
  Nlm_RegisterSlates ();

  Nlm_GetReady ();

  /* Initialize connection library's logger, registry and lock */
  CONNECT_Init(0);
}



#if defined(OS_UNIX) && defined(COMP_SUNPRO)
extern void Nlm_VibMainFinale (int argc, char *argv[], char *envp[])
#else
extern void Nlm_VibMainFinale (int argc, char *argv[])
#endif
{
  Nlm_CleanUpWindows ();
  Nlm_CleanUpDrawingTools ();
  Nlm_FreeWindows ();
  Nlm_FreeBars ();
  Nlm_FreeButtons ();
  Nlm_FreeExtras ();
  Nlm_FreeForms ();
  Nlm_FreeGroup ();
  Nlm_FreeLists ();
  Nlm_FreeMenus ();
  Nlm_FreePrompt ();
  Nlm_FreeSlate ();
  Nlm_FreeTexts ();
  Nlm_FreeConfigStruct ();
  Nlm_currentWindowTool = (Nlm_WindowTool) 0;
  Nlm_currentXWindow = 0;
  Nlm_currentXGC = NULL;
  if (Nlm_currentXDisplay != NULL) {
    if (Nlm_fileDialogShell != NULL) {
      XtDestroyWidget (Nlm_fileDialogShell);
    }
    if (Nlm_XfontList != NULL) {
      XmFontListFree (Nlm_XfontList);
    }
    XFreeCursor (Nlm_currentXDisplay, arrow);
    XFreeCursor (Nlm_currentXDisplay, cross);
    XFreeCursor (Nlm_currentXDisplay, iBeam);
    XFreeCursor (Nlm_currentXDisplay, plus);
    XFreeCursor (Nlm_currentXDisplay, watch);
    Nlm_FreeGCs ();
    XCloseDisplay (Nlm_currentXDisplay);
  }
  Nlm_ErrSetLogfile (NULL,0);
}
#endif




#ifdef WIN_MOTIF 
static Nlm_Boolean IsXParentOf(Window is_parent, Window w)
{
  Window root, parent, *children;
  unsigned int nchildren, i;

  if (is_parent == (Window)0  ||  w == (Window)0) 
    return FALSE;
  else if (is_parent == w)
    return TRUE;

  if ( !XQueryTree(Nlm_currentXDisplay, is_parent, &root, &parent,
                   &children, &nchildren) )
    return FALSE;

  for (i = 0;  i < nchildren  &&  !IsXParentOf(children[i], w);  i++);
  if ( children )
    XFree( children );

  return (i != nchildren);
}
#endif


extern void Nlm_RemoveDyingWindows (void)

/*
*  Since submenus goes into the Macintosh desktop menu bar, to allow for
*  command key equivalents, it can be very dangerous to remove the menu
*  bar.  The submenu linked into the menu bar now no longer removes its
*  children, leaving that up to the submenu item.
*/

{
  Nlm_GraphiC      g;
  Nlm_GraphicData  gdata;
  Nlm_MenuBaR      mb;
  Nlm_GraphiC      n;
#ifndef WIN_MOTIF
  Nlm_PortTool     tempPort;
#endif
  Nlm_WindoW       w;
  Nlm_WindowData   wdata;
  Nlm_WindowTool   wptr;
#ifdef WIN_MAC
  PenState         state;
#endif

  while (dyingWindow != NULL) {
    w = dyingWindow;
    wptr = Nlm_ParentWindowPtr ((Nlm_GraphiC) w);
#ifdef WIN_MAC
#ifndef WIN_MAC_QUARTZ
    GetPort (&tempPort);
    GetPenState (&state);
#endif
    Nlm_SetPortWindowPort(wptr);
    Nlm_currentWindowTool = wptr;
    Nlm_SetUpdateRegion (wptr);
#endif
#ifdef WIN_MSWIN
    tempPort = Nlm_currentHDC;
    Nlm_currentHDC = Nlm_ParentWindowPort ((Nlm_GraphiC) w);
    Nlm_currentWindowTool = wptr;
#endif
#ifdef WIN_MOTIF
    XSync (Nlm_currentXDisplay, FALSE);
    {{
      Window xw = XtWindow(  Nlm_GetWindowShell(w) );
      if ( IsXParentOf(xw, Nlm_currentXWindow) )
        {
          Nlm_currentWindowTool = (Nlm_WindowTool)0;
          Nlm_currentXWindow = 0;
        }
    }}
#endif
    g = Nlm_GetChild ((Nlm_GraphiC) w);
    while (g != NULL) {
      n = Nlm_GetNext (g);
      Nlm_DoRemove (g, FALSE);
      g = n;
    }

    mb = Nlm_GetWindowMenuBar (w);
    if (mb != NULL) {
      Nlm_DoRemove ((Nlm_GraphiC) mb, FALSE);
      Nlm_SetWindowMenuBar (w, NULL);
    }

#if !defined(WIN_MOTIF) && !defined(WIN_MAC_QUARTZ)
    Nlm_ResetDrawingTools ();
#endif

    Nlm_GetWindowData (w, &wdata);
    if (wdata.data != NULL && wdata.cleanup != NULL) {
      wdata.cleanup (w, wdata.data);
    }
#ifdef WIN_MAC
#ifndef WIN_MAC_QUARTZ
    if ( wdata.cMap != NULL ){
      DisposePalette ( wdata.cMap );
      wdata.cMap = NULL;
    }
    Nlm_SetPort(tempPort);
    Nlm_currentWindowTool = GetWindowFromPort(tempPort);
    Nlm_SetUpdateRegion (GetWindowFromPort(tempPort));
    SetPenState (&state);
#endif
    /* 2001-03-22:  Joshua Juran
       Carbon does not support application-supplied storage for windows. */
    DisposeWindow(wptr);
#endif
#ifdef WIN_MSWIN
    if ( wdata.cMap != NULL ){
      DeleteObject( wdata.cMap );
      wdata.cMap = NULL;
    }
    if ( wdata.haccel != NULL ){
      DestroyAcceleratorTable(wdata.haccel);
      wdata.haccel = NULL;
    }
    Nlm_currentHDC = tempPort;
    RemoveProp (wptr, (LPSTR) "Nlm_VibrantProp");
    DestroyWindow (wptr);
#endif
#ifdef WIN_MOTIF
    if ( wdata.cMap )  {
      if ( wdata.cMapStatus ) {
        XUninstallColormap(Nlm_currentXDisplay,wdata.cMap);
        wdata.cMapStatus = 0;
      }
      XFreeColormap (Nlm_currentXDisplay,wdata.cMap);
      wdata.cMap = (Nlm_ColorMTool) 0;
    }
    if (wdata.title != NULL) {
      Nlm_MemFree (wdata.title);
    }

    {{
      Nlm_ShellTool shl = Nlm_GetWindowShell( w );
      XtUnrealizeWidget(shl);
      if (
#ifdef NLM_MOTIF_CASCADEB_BUG
          !mb  &&
#endif
          (!NLM_QUIET  ||  Nlm_WindowHasBeenShown( w ))) {
        XtDestroyWidget( shl );
      }
    }}
    XSync (Nlm_currentXDisplay, FALSE);
#endif
    dyingWindow = (Nlm_WindoW) Nlm_GetNext ((Nlm_GraphiC) w);
    Nlm_GetGraphicData ((Nlm_GraphiC) w, &gdata);
    if (gdata.data != NULL && gdata.cleanup != NULL) {
      gdata.cleanup ((Nlm_GraphiC) w, gdata.data);
    }
    Nlm_HandFree (w);
    recentWindow = NULL;
    Nlm_Update ();
  }
}


#ifdef WIN_X
static Boolean Nlm_XCheckUpdateEvent(XEvent *event)
{
  return XCheckMaskEvent(Nlm_currentXDisplay, ExposureMask|StructureNotifyMask,
                         event);
}
#endif


#ifdef WIN_MAC
static Nlm_RegioN macMouseRgn = NULL;
#endif

extern void Nlm_SetMouseMoveCallback (Nlm_ClckProc actn)

{
  mouseMovedAction = actn;
}

extern void Nlm_SetMouseMoveRegion (Nlm_RegioN rgn)

{
#ifdef WIN_MAC
  if (macMouseRgn != NULL) {
    macMouseRgn = Nlm_DestroyRgn (macMouseRgn);
  }
  if (rgn == NULL) return;
  macMouseRgn = Nlm_CreateRgn ();
  Nlm_UnionRgn (macMouseRgn, rgn, macMouseRgn);
#endif
}

extern void Nlm_Update (void)
{
#ifdef WIN_MAC
  while (EventAvail (updateMask, &Nlm_currentEvent)) {
    if (WaitNextEvent (updateMask, &Nlm_currentEvent, 0, (Nlm_RgnTool) macMouseRgn)) {
      Nlm_HandleEvent ();
    }
  }
#endif
#ifdef WIN_MSWIN
  while (PeekMessage (&Nlm_currentMssg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE)) {
    if (GetMessage (&Nlm_currentMssg, NULL, WM_PAINT, WM_PAINT)) {
      if (Nlm_VibrantDisabled ()) {
        discard_count++; /* really just a place to set a breakpoint */
      }
      TranslateMessage (&Nlm_currentMssg);
      DispatchMessage (&Nlm_currentMssg);
    }
  }
#endif
#ifdef WIN_MOTIF
  XEvent event;
  XSync (Nlm_currentXDisplay, FALSE);
  while ( Nlm_XCheckUpdateEvent(&event) )
    {
      XtDispatchEvent (&event);
    }
  XFlush( Nlm_currentXDisplay );
#endif
}

extern void Nlm_KeyboardView (Nlm_KeyProc key)

{
  keyAction = key;
}

#ifdef WIN_MSWIN
static void Nlm_ProcessKeyPress (LPMSG lpMsg)

{
  Nlm_Char  ch, sp_ch;
  
  if (keyAction == NULL) return;

  ch = (Nlm_Char) lpMsg->wParam;
  if (lpMsg->message == WM_CHAR) 
  {
    keyAction (ch);
  }
  else if (lpMsg->message == WM_KEYDOWN)
  {
    sp_ch = Nlm_KeydownToChar ((Nlm_Uchar)ch);
    if (sp_ch != 0)
    {
      keyAction (sp_ch);    
    }
  }
}
#endif

#ifdef WIN_MOTIF
static void Nlm_ProcessKeyPress (XEvent *event)

{
  Nlm_Char ch;

  if (event->type == KeyPress  &&  keyAction != NULL)
  {
    ch = Nlm_GetInputChar (&event->xkey);
    Nlm_ctrlKey  = ((event->xkey.state & ControlMask) != 0);
    Nlm_shftKey  = ((event->xkey.state & ShiftMask  ) != 0);
    Nlm_cmmdKey = FALSE;
    Nlm_optKey = FALSE;
    keyAction( ch );
  }
}
#endif

#ifdef WIN_MSWIN

typedef void (LIBCALLBACK *CallbackProc)(void* data);
static UINT idWMVibrantCallback = 0;

static void Nlm_InitVibrantCallback ()

{
  idWMVibrantCallback = RegisterWindowMessage("VibrantCallback");
}


static Nlm_Boolean Nlm_ProcessVibrantCallback (LPMSG lpMsg)

{
  if(idWMVibrantCallback && idWMVibrantCallback == lpMsg->message)
  {
    CallbackProc proc = (CallbackProc)lpMsg->wParam;
    proc((void*)(lpMsg->lParam));
    return TRUE;
  }
  else
    return FALSE;
}
#endif

#ifdef WIN_MSWIN

extern Nlm_Handle Nlm_GetWindowHAccel (Nlm_WindoW w);
extern Nlm_Handle Nlm_GetWindowHAccel (Nlm_WindoW w)

{
  Nlm_Handle      rsult;
  Nlm_WindowData  wdata;

  rsult = (Nlm_Handle) 0;
  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    rsult = wdata.haccel;
  }
  return rsult;
}


extern void Nlm_SetWindowHAccel (Nlm_WindoW w, Nlm_Handle h);
extern void Nlm_SetWindowHAccel (Nlm_WindoW w, Nlm_Handle h)

{
  Nlm_WindowData  wdata;

  if (w != NULL) {
    Nlm_GetWindowData (w, &wdata);
    wdata.haccel = h;
    Nlm_SetWindowData (w, &wdata);
  }
}


static Nlm_Boolean Nlm_ProcessAccelerator (LPMSG lpMsg)

{
  if(lpMsg->hwnd != NULL &&
     (lpMsg->message == WM_KEYDOWN ||
      lpMsg->message == WM_KEYUP ||
      lpMsg->message == WM_SYSKEYDOWN ||
      lpMsg->message == WM_SYSKEYUP ||
      lpMsg->message == WM_CHAR))
  {
    Nlm_WindoW w = (Nlm_WindoW) GetProp (lpMsg->hwnd, (LPSTR) "Nlm_VibrantProp");
    if(w != NULL)
    {
      Nlm_WindoW p = Nlm_GetParentWindow((Nlm_GraphiC)w);
      if(p != NULL)
      {
        Nlm_WindowData wdata;
        Nlm_GetWindowData(p, &wdata);
        if(wdata.haccel != NULL)
        {
          int ret = TranslateAccelerator(wdata.handle, wdata.haccel, lpMsg);
          return ret != 0;
        }
      }
    }
  }
  
  return FALSE;
}
#endif

extern void Nlm_ProcessAnEvent (void)

{
#ifdef WIN_MAC
  if (EventAvail (everyEvent, &Nlm_currentEvent)) {
    if (WaitNextEvent (everyEvent, &Nlm_currentEvent, 0, (Nlm_RgnTool) macMouseRgn)) {
      Nlm_HandleEvent ();
    }
  }
#endif
#ifdef WIN_MSWIN
  if (PeekMessage (&Nlm_currentMssg, NULL, 0, 0, PM_NOREMOVE)) {
    if (GetMessage (&Nlm_currentMssg, NULL, 0, 0)) {
      TranslateMessage (&Nlm_currentMssg);
      Nlm_ProcessKeyPress (&Nlm_currentMssg);
      Nlm_ProcessVibrantCallback(&Nlm_currentMssg);
      DispatchMessage (&Nlm_currentMssg);
    }
  }
#endif
#ifdef WIN_MOTIF
  XEvent  event;

  if (XtAppPending (Nlm_appContext) & XtIMXEvent) {
    XtAppNextEvent (Nlm_appContext, &event);
    Nlm_ProcessKeyPress (&event);
    XtDispatchEvent (&event);
  }
#endif
}

extern void Nlm_ProcessTimerEvent (void)

{
#ifdef WIN_MAC
  Nlm_Int4  delta;
  Nlm_Int4  ticks;

  ticks = Nlm_ComputerTime ();
  delta = ticks - lastTimerTime;
  if (delta >= 3) {
    lastTimerTime = ticks;
    if (timerAction != NULL) {
      timerAction ();
    }
    Nlm_CallWindowTimers ();
  }
#endif
}

#ifdef WIN_MAC
static void Nlm_ProcessIdle (void)

{
  Nlm_PointTool  ptool;

  Nlm_ProcessTimerEvent ();
  GetMouse (&ptool);
  Nlm_PointToolToPoinT (ptool, &Nlm_globalMouse);
  Nlm_LocalToGlobal (&Nlm_globalMouse);
  frontWindow = Nlm_FindWindowRec (FrontWindow ());
  Nlm_DoIdle ((Nlm_GraphiC) frontWindow, Nlm_globalMouse);
  Nlm_ClearKeys ();
}
#endif

extern void Nlm_ProcessEventOrIdle (void)

{
#ifdef WIN_MAC
  if (EventAvail (everyEvent, &Nlm_currentEvent)) {
    if (WaitNextEvent (everyEvent, &Nlm_currentEvent, 0, (Nlm_RgnTool) macMouseRgn)) {
      Nlm_HandleEvent ();
    }
  } else {
    Nlm_ProcessIdle ();
  }
#endif
#ifdef WIN_MSWIN
  if (Nlm_processUpdatesFirstVal &&
      PeekMessage (&Nlm_currentMssg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE)) {
    if (GetMessage (&Nlm_currentMssg, NULL, WM_PAINT, WM_PAINT)) {
      TranslateMessage (&Nlm_currentMssg);
      DispatchMessage (&Nlm_currentMssg);
    }
  } else if (PeekMessage (&Nlm_currentMssg, NULL, 0, 0, PM_NOREMOVE)) {
    if (GetMessage (&Nlm_currentMssg, NULL, 0, 0)) {
      TranslateMessage (&Nlm_currentMssg);
      Nlm_ProcessKeyPress (&Nlm_currentMssg);
      Nlm_ProcessVibrantCallback(&Nlm_currentMssg);
      DispatchMessage (&Nlm_currentMssg);
    }
  }
#endif
#ifdef WIN_MOTIF
  XEvent  event;

  if (XtAppPending (Nlm_appContext) & XtIMXEvent) {
    if (Nlm_processUpdatesFirstVal &&
        Nlm_XCheckUpdateEvent(&event)) {
      XtDispatchEvent (&event);
    } else {
      XtAppNextEvent (Nlm_appContext, &event);
      Nlm_ProcessKeyPress (&event);
      XtDispatchEvent (&event);
    }
  }
#endif
}

#if 1
extern void Nlm_ProcessExternalEvent (void)

{
#ifdef WIN_MAC
  if (WaitNextEvent (everyEvent, &Nlm_currentEvent, 10, (Nlm_RgnTool) macMouseRgn)) {
    Nlm_HandleEvent ();
  }
#endif
#ifdef WIN_MSWIN
  /* Yield to other processes and threads */
  MsgWaitForMultipleObjectsEx(0, NULL, 10, QS_ALLEVENTS, MWMO_INPUTAVAILABLE);

  if (Nlm_processUpdatesFirstVal &&
      PeekMessage (&Nlm_currentMssg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE)) {
    if (GetMessage (&Nlm_currentMssg, NULL, WM_PAINT, WM_PAINT)) {
      TranslateMessage (&Nlm_currentMssg);
      DispatchMessage (&Nlm_currentMssg);
    }
  } else if (PeekMessage (&Nlm_currentMssg, NULL, 0, 0, PM_NOREMOVE)) {
    if (GetMessage (&Nlm_currentMssg, NULL, 0, 0)) {
      TranslateMessage (&Nlm_currentMssg);
      Nlm_ProcessKeyPress (&Nlm_currentMssg);
      Nlm_ProcessVibrantCallback(&Nlm_currentMssg);
      DispatchMessage (&Nlm_currentMssg);
    }
  }
#endif
#ifdef WIN_MOTIF
  XEvent  event;

  if (XtAppPending (Nlm_appContext) & XtIMXEvent) {
    if (Nlm_processUpdatesFirstVal && 
        Nlm_XCheckUpdateEvent(&event)) {
      XtDispatchEvent (&event);
    } else {
      XtAppNextEvent (Nlm_appContext, &event);
      Nlm_ProcessKeyPress (&event);
      XtDispatchEvent (&event);
    }
  }
#endif
}
#else
extern void Nlm_ProcessExternalEvent (void)

{
#ifdef WIN_MAC
  if (WaitNextEvent (everyEvent, &Nlm_currentEvent, 10, (Nlm_RgnTool) macMouseRgn)) {
    Nlm_HandleEvent ();
  }
#endif
#ifdef WIN_MSWIN
  if (Nlm_processUpdatesFirstVal &&
      PeekMessage (&Nlm_currentMssg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE)) {
    if (GetMessage (&Nlm_currentMssg, NULL, WM_PAINT, WM_PAINT)) {
      TranslateMessage (&Nlm_currentMssg);
      DispatchMessage (&Nlm_currentMssg);
    }
  } else if (PeekMessage (&Nlm_currentMssg, NULL, 0, 0, PM_NOREMOVE)) {
    if (GetMessage (&Nlm_currentMssg, NULL, 0, 0)) {
      TranslateMessage (&Nlm_currentMssg);
      Nlm_ProcessKeyPress (&Nlm_currentMssg);
      Nlm_ProcessVibrantCallback(&Nlm_currentMssg);
      DispatchMessage (&Nlm_currentMssg);
    }
  }
#endif
#ifdef WIN_MOTIF
  XEvent  event;

  if (XtAppPending (Nlm_appContext) & XtIMXEvent) {
    if (Nlm_processUpdatesFirstVal && 
        Nlm_XCheckUpdateEvent(&event)) {
      XtDispatchEvent (&event);
    } else {
      XtAppNextEvent (Nlm_appContext, &event);
      Nlm_ProcessKeyPress (&event);
      XtDispatchEvent (&event);
    }
  }
#endif
}
#endif

extern void Nlm_ProcessEvents (void)

{
#ifdef WIN_MAC
  while (! quitProgram) {
    if (! EventAvail (everyEvent, &Nlm_currentEvent)) {
      Nlm_ProcessIdle ();
    }
    while (WaitNextEvent (everyEvent, &Nlm_currentEvent, 1, (Nlm_RgnTool) macMouseRgn)) {
      Nlm_HandleEvent ();
      Nlm_RemoveDyingWindows ();
    }
  }
#endif
#ifdef WIN_MSWIN
  Nlm_InitVibrantCallback ();
  if (registeredDropProc != NULL) {
    DragAcceptFiles(Nlm_currentHWnd, TRUE);
  }
  while (! quitProgram) {
    while (Nlm_processUpdatesFirstVal &&
           PeekMessage (&Nlm_currentMssg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE)) {
      if (GetMessage (&Nlm_currentMssg, NULL, WM_PAINT, WM_PAINT)) {
        TranslateMessage (&Nlm_currentMssg);
        DispatchMessage (&Nlm_currentMssg);
      }
    }
    if (GetMessage (&Nlm_currentMssg, NULL, 0, 0)) {
      if (!Nlm_ProcessAccelerator(&Nlm_currentMssg)) {
        TranslateMessage (&Nlm_currentMssg);
        Nlm_ProcessKeyPress (&Nlm_currentMssg);
        Nlm_ProcessVibrantCallback(&Nlm_currentMssg);
        DispatchMessage (&Nlm_currentMssg);
      }
      Nlm_RemoveDyingWindows ();
    }
  }
#endif
#ifdef WIN_MOTIF
  XEvent       event;
  XtInputMask  mask;

  while (! quitProgram) {
    mask = XtAppPending (Nlm_appContext);
    if (mask != 0) { 
      while (Nlm_processUpdatesFirstVal &&
             Nlm_XCheckUpdateEvent(&event)) {
        XtDispatchEvent (&event);
      }
    }
    XtAppNextEvent (Nlm_appContext, &event);
    Nlm_ProcessKeyPress (&event);
    XtDispatchEvent (&event);
    Nlm_RemoveDyingWindows ();
  }
  if (Nlm_currentXDisplay != NULL) {
    XSync (Nlm_currentXDisplay, TRUE);
  }
#endif
  Nlm_RemoveDyingWindows ();
}

extern Nlm_Boolean Nlm_EventAvail (void)

{
#ifdef WIN_MAC
  return (EventAvail (everyEvent, &Nlm_currentEvent));
#endif
#ifdef WIN_MSWIN
  return (Nlm_Boolean) (PeekMessage (&Nlm_currentMssg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD));
#endif
#ifdef WIN_MOTIF
  XtInputMask  mask;
  mask = XtAppPending (Nlm_appContext);
  return ((mask & XtIMXEvent) != 0); /* M.Gouy */
#endif
}

extern void Nlm_FlushEvents (void)

{
#ifdef WIN_MAC
  FlushEvents (everyEvent - updateMask, 0);
#endif
#ifdef WIN_MSWIN
  Nlm_Boolean  goOn;

  goOn = TRUE;
  while (goOn) {
    goOn = (Nlm_Boolean) PeekMessage (&Nlm_currentMssg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD);
    if (goOn && Nlm_currentMssg.message == WM_PAINT) {
      goOn = FALSE;
    }
  }
#endif
#ifdef WIN_MOTIF
  if (Nlm_currentXDisplay != NULL) {
    XSync (Nlm_currentXDisplay, FALSE);
  }
#endif
}

extern void Nlm_ProcessUpdatesFirst (Nlm_Boolean val)

{
  Nlm_processUpdatesFirstVal = val;
}


extern void Nlm_QuitProgram (void)
{
  quitProgram = TRUE;
#ifdef WIN_MSWIN
  PostQuitMessage (0);
#endif
}

extern Nlm_Boolean Nlm_QuittingProgram (void)
{
  return quitProgram;
}


extern void Nlm_UnloadSegment (Nlm_VoidProc routineAddr)

{
#if defined(WIN_MAC) && !defined(OS_UNIX_DARWIN)
  if (routineAddr != NULL) {
    UnloadSeg ((void *) routineAddr);
  }
#endif
}

static void Nlm_GetArgsOkProc (Nlm_ButtoN b)

{
  getArgsBoxUp = FALSE;
  getArgsOk = TRUE;
}

static void Nlm_GetArgsCancelProc (Nlm_ButtoN b)

{
  getArgsBoxUp = FALSE;
}

static Nlm_GraphiC Nlm_GetPrevObject (Nlm_GraphiC g)

{
  Nlm_GraphiC  prev = NULL;
  if (g != NULL) {
    Nlm_GraphiC prnt = Nlm_GetParent (g);
    Nlm_GraphiC chld = Nlm_GetChild (prnt);
    while (chld  &&  chld != g) {
      prev = chld;
      chld = Nlm_GetNext(chld);
    }
  }
  return prev;
}

static void Nlm_GetArgsFileInProc (Nlm_ButtoN b)

{
  Nlm_Char  path [PATH_MAX];
  Nlm_TexT  t;

  t = (Nlm_TexT) Nlm_GetPrevObject ((Nlm_GraphiC) b);
  if (t != NULL) {
    if (Nlm_GetInputFileName (path, sizeof (path), "", "")) {
      Nlm_SetTitle ((Nlm_Handle) t, path);
    }
  }
}

static void Nlm_GetArgsFileOutProc (Nlm_ButtoN b)

{
  Nlm_Char  path [PATH_MAX];
  Nlm_TexT  t;

  t = (Nlm_TexT) Nlm_GetPrevObject ((Nlm_GraphiC) b);
  if (t != NULL) {
    if (Nlm_GetOutputFileName (path, sizeof (path), "")) {
      Nlm_SetTitle ((Nlm_Handle) t, path);
    }
  }
}


typedef Nlm_Handle PNTR Nlm_HandlePtr;

static void Nlm_MultiLinePrompt (Nlm_GrouP prnt, Nlm_CharPtr str, Nlm_Int2 width,
                                 Nlm_Int2 height, Nlm_FonT fnt, Nlm_Char just)

{
  Nlm_CharPtr    buf;
  Nlm_Char       ch;
  Nlm_Boolean    go_on;
  Nlm_Int2       k;
  Nlm_Int2       l;
  Nlm_Int2       num;
  Nlm_GrouP      pg;

  if (prnt != NULL && str != NULL) {
    pg = Nlm_HiddenGroup (prnt, 0, 10, NULL);
    Nlm_SetGroupMargins (pg, 1, 1);
    Nlm_SetGroupSpacing (pg, 1, 1);
    buf = StringSave (str);
    k = 0;
    num = 0;
    go_on = TRUE;
    while (Nlm_StringLen (buf + k) > 0 && go_on) {
      l = 0;
      ch = buf [k + l];
      while (ch != '\0' && ch != '\n' && ch != '\r') {
        l++;
        ch = buf [k + l];
      }
      num++;
      if (num >= 20) {
        go_on = FALSE;
        Nlm_StaticPrompt (pg, "...", width, height, fnt, just);
      } else if (ch == '\n' || ch == '\r') {
        buf [k + l] = '\0';
        if (Nlm_StringLen (buf + k) > 0) {
          Nlm_StaticPrompt (pg, buf + k, width, height, fnt, just);
        }
        k += l + 1;
      } else {
        if (Nlm_StringLen (buf + k) > 0) {
          Nlm_StaticPrompt (pg, buf + k, width, height, fnt, just);
        }
        k += l;
      }
    }
    MemFree (buf);
  }
}


typedef enum
{
  FetchArg_SILENT,
  FetchArg_ERRPOST,
  FetchArg_MESSAGE
}  enumFetchArgDiag;

static Nlm_Boolean FetchArg(Nlm_ArgPtr arg, const char *str,
                            enumFetchArgDiag diag, Nlm_Boolean check_range)
{
  static char *xxx = "...";
  char *min_str = arg->from ? arg->from : xxx;
  char *max_str = arg->to   ? arg->to   : xxx;
  Nlm_Boolean valid = TRUE;

  switch ( arg->type )
    {
    case ARG_BOOLEAN:
      {
        arg->intvalue =
          (str == NULL  ||  *str == '\0'  ||  TO_UPPER(*str) == 'T') ? 1 : 0;
        break;
      }

    case ARG_INT:
      {
        long value;
        if (str == NULL  ||  sscanf(str, "%ld", &value) != 1)
          valid = FALSE;

        if (valid  &&  !check_range) {
          arg->intvalue = value;
          break;
        }

        /* range checking */
        if (valid  &&  arg->from != NULL)
          {
            long min_value;
            if (sscanf(arg->from, "%ld", &min_value) != 1  ||
                value < min_value)
              valid = FALSE;
          }
        if (valid  &&  arg->to != NULL)
          {
            long max_value;
            if (sscanf(arg->to,   "%ld", &max_value) != 1  ||
                value > max_value)
              valid = FALSE;
          }

        if ( valid )
          arg->intvalue = value;
        break;
      }

    case ARG_FLOAT:
      {
        double value;
        if (str == NULL  ||  sscanf(str, "%lf", &value) != 1)
          valid = FALSE;

        if (valid  &&  !check_range) {
          arg->floatvalue = value;
          break;
        }

        /* range checking */
        if (valid  &&  arg->from != NULL)
          {
            double min_value;
            if (sscanf(arg->from, "%lg", &min_value) != 1  ||
                value < min_value)
              valid = FALSE;
          }
        if (valid  &&  arg->to != NULL)
          {
            double max_value;
            if (sscanf(arg->to,   "%lg", &max_value) != 1  ||
                value > max_value)
              valid = FALSE;
          }

        if ( valid )
          arg->floatvalue = value;
        break;
      }

    case ARG_STRING:
    case ARG_FILE_IN:
    case ARG_FILE_OUT:
    case ARG_DATA_IN:
    case ARG_DATA_OUT:
      if (str == NULL  ||  *str == '\0')
        arg->strvalue = NULL;
      else
        arg->strvalue = StringSave( str );
      break;

    default:
      valid = FALSE;
    }

  if ( !valid )
    {
      switch ( diag )
        {
        case FetchArg_SILENT:
          break;
        case FetchArg_ERRPOST:
          ErrPostEx(SEV_ERROR, 0,0,
                    "%s ::  '%s' is bad or out of range [%s to %s]",
                    arg->prompt, str, min_str, max_str);
          break;
        case FetchArg_MESSAGE:
          Message(MSG_ERROR,
                  "%s ::  '%s' is bad or out of range [%s to %s]",
                  arg->prompt, str, min_str, max_str);
          break;
        }
      return FALSE;
    }

  return TRUE;
}


static Nlm_Int2 NumReturnsIn (Nlm_CharPtr prompt)

{
  Nlm_Char  ch;
  Nlm_Int2  count = 0;

  if (StringHasNoText (prompt)) return 0;

  ch = *prompt;
  while (ch != '\0') {
    if (ch == '\r' || ch == '\n') {
      count++;
    }
    prompt++;
    ch = *prompt;
  }

  return count;
}


static Nlm_Boolean GetArgs_ST(const char* progname,
                              Nlm_Int2 numargs, Nlm_ArgPtr ap,
                              Nlm_Boolean silent)
{
  static const char* s_TypeStrings[] = {
    "",
    "",
    "Integer: ",
    "Float: ",
    "String: ",
    "File In: ",
    "File Out: ",
    "Data In: ",
    "Data Out: "
  };

#ifdef WIN_MOTIF
static const char* s_ValueStrings[] = {
    "",
    "T/F",
    "Integer",
    "Float",
    "String",
    "Input-File",
    "Output-File",
    "Input-Data",
    "Output-Data"
  };
#endif

  Nlm_Int2       i, j;
  Nlm_ArgPtr     curarg;
  Nlm_Boolean   *resolved;
  Nlm_Char       arg[512];
  Nlm_Int2       delta;
  Nlm_GrouP      g;
  Nlm_GrouP      h;
  Nlm_HandlePtr  hp;
  Nlm_RecT       r1;
  Nlm_RecT       r2;
  Nlm_Boolean    new_line;
  Nlm_Boolean    largeScreen;
  Nlm_Boolean    smallScreen;
  Nlm_Char       tag [16];
  Nlm_WindoW     w;
  Nlm_TexT       firstText;
  Nlm_CharPtr    tmp;

  int    xx_argc = (int)Nlm_GetArgc();
  char **xx_argv =      Nlm_GetArgv();

  if (ap == NULL  &&  numargs == 0)
    return TRUE;

  if (ap == NULL  ||  numargs <= 0)
    return FALSE;

  resolved = (Nlm_Boolean*) Nlm_MemNew(numargs * sizeof(Nlm_Boolean));
  if ( !resolved )
    return FALSE;

  /* Initialize arguments using default value */
  for (i = 0, curarg = ap;  i < numargs;  i++, curarg++)
    {
      curarg->intvalue   = 0;
      curarg->floatvalue = 0.0;
      curarg->strvalue   = NULL;

      if (curarg->defaultvalue == NULL)
        continue;

      switch ( curarg->type )
        {
        case ARG_BOOLEAN:
        case ARG_INT:
        case ARG_FLOAT:
        case ARG_STRING:
        case ARG_FILE_IN:
        case ARG_FILE_OUT:
        case ARG_DATA_IN:
        case ARG_DATA_OUT:
          resolved[i] = FetchArg(curarg, curarg->defaultvalue,
                                 FetchArg_ERRPOST, FALSE);
          break;
        default:
          ErrPostEx(SEV_ERROR, 0,0, "Invalid Arg->type in %s", curarg->prompt);
          Nlm_MemFree( resolved );
          return FALSE;
      }
    }


  /* Print the usage info */
#ifdef WIN_MOTIF
  if (xx_argc == 2
      &&  (xx_argv[1][1] == '\0'  ||  !strcmp(xx_argv[1], "--help")))
    {
      printf("\n%s   arguments:\n\n", progname);
      curarg = ap;

      for (i = 0, j = 0;  i < numargs;  i++, j++, curarg++)
        {
          printf("  -%c  %s [%s]",
                 curarg->tag, curarg->prompt, s_ValueStrings[curarg->type]);
          if (curarg->optional )
            printf( "  Optional" );
          printf("\n");
          if (curarg->defaultvalue != NULL)
            printf("    default = %s\n", curarg->defaultvalue);
          if (curarg->from != NULL  ||  curarg->to != NULL)
            {
              if (curarg->type == ARG_DATA_IN  || curarg->type == ARG_DATA_OUT)
                printf("    Data Type = %s\n",
                       (curarg->from ? curarg->from : "<NULL>"));
              else
                printf("    range from %s to %s\n",
                       (curarg->from ? curarg->from : "<NULL>"),
                       (curarg->to   ? curarg->to   : "<NULL>"));
            }
        }

      printf("\n");
      Nlm_MemFree( resolved );
      return FALSE;
    }
#endif


  /* Parse command-line arguments */
  for (i = 1;  i < xx_argc;  i++)
    {
      Nlm_CharPtr arg_str = xx_argv[i];

#ifdef WIN_MAC
      if (Nlm_StringCmp (arg_str, "-NSDocumentRevisionsDebugMode") == 0) {
        ++i;
        if (i < xx_argc) {
          arg_str = xx_argv[i];
          if (Nlm_StringCmp (arg_str, "YES") == 0) continue;
          if (Nlm_StringCmp (arg_str, "NO") == 0) continue;
        }
      }
#endif

      if (*arg_str != '-') {
        ErrPostEx(SEV_ERROR, 0, 0,
                  "\n%s\n(offending argument #%d was: '%s')",
                  "Vibrant command line arguments must start with '-'",
                  (int)i, arg_str);
        Nlm_MemFree( resolved );
        return FALSE;
      }

      arg_str++;
      curarg = ap;
      for (j = 0;  j < numargs  &&  *arg_str != curarg->tag;  j++, curarg++) continue;
      if (j == numargs) {
        ErrPostEx(SEV_ERROR, 0, 0, "Invalid argument: %s", xx_argv[i]);
        Nlm_MemFree( resolved );
        return FALSE;
      }

      arg_str++;
      if (*arg_str == '\0'  &&  curarg->type != ARG_BOOLEAN)
        {
          if (++i == xx_argc)  {
            ErrPostEx(SEV_ERROR, 0, 0,
                      "No argument given for %s", curarg->prompt);
            Nlm_MemFree( resolved );
            return FALSE;
          }
          arg_str = xx_argv[i];
          ASSERT( arg_str  &&  *arg_str );
      }

      if ( !FetchArg(curarg, arg_str, FetchArg_ERRPOST, TRUE) )
        {
          Nlm_MemFree( resolved );
          return FALSE;
        }
      resolved[j] = TRUE;
    }       

/*
  silent = (Nlm_Boolean)(silent  ||  xx_argc > 1);
*/

  if ( silent )
    {
      for (i = 0;
           i < numargs  &&  (ap[i].optional  ||  resolved[i]);
           i++) continue;
      if (i == numargs) {
        Nlm_MemFree( resolved );
        return TRUE; /* all args resolved from command line or by default */
      }
    }


  /* Arg-Query Dialog Box */ 
  w = Nlm_FixedWindow (-50, -33, -10, -10, (Nlm_CharPtr) progname, NULL);
  smallScreen = FALSE;
  largeScreen = FALSE;
#ifdef WIN_MAC
  if (Nlm_screenRect.right < 513  ||  Nlm_screenRect.bottom < 343) {
    smallScreen = TRUE;
  }
  if (Nlm_screenRect.right > 1200  &&  Nlm_screenRect.bottom > 800) {
    largeScreen = TRUE;
  }
#endif
#ifdef WIN_MSWIN
  if (Nlm_screenRect.bottom < 352) {
    smallScreen = TRUE;
  }
  if (Nlm_screenRect.bottom > 800) {
    largeScreen = TRUE;
  }
#endif
  g = Nlm_HiddenGroup (w, 5, 0, NULL);
  hp = (Nlm_HandlePtr) Nlm_MemNew (numargs * sizeof (Nlm_Handle));

  firstText = NULL;
  curarg = ap;
  for (i = 0, j = 0; i < numargs; i++, curarg++) {
    new_line = FALSE;
    if (smallScreen) {
      if (j >= 10) {
        new_line = TRUE;
      }
    } else if (largeScreen) {
      if (j >= 30) {
        new_line = TRUE;
      }
    } else {
      if (j >= 15) {
        new_line = TRUE;
      }
    }
    if (new_line) {
      j = 0;
      Nlm_Advance (w);
      g = Nlm_HiddenGroup (w, 5, 0, NULL);
    }
    j++;
    j += NumReturnsIn ((Nlm_CharPtr) curarg->prompt);

    Nlm_StaticPrompt(g, (char*)s_TypeStrings[curarg->type], 0,
                     Nlm_dialogTextHeight, Nlm_systemFont, 'l');


    tag [0] = '\0';
    if (Nlm_showGetArgTag) {
      sprintf (tag, " -%c", (char) curarg->tag);
    }

    /* Populate the Arg-Query Dialog Box's input controls and
       initialize these by default values */

    switch (curarg->type) {
      case ARG_BOOLEAN:
        hp[i] = (Nlm_Handle)
          Nlm_CheckBox(g, (Nlm_CharPtr) curarg->prompt, NULL);
        Nlm_StaticPrompt(g, tag, 0, Nlm_dialogTextHeight, Nlm_systemFont, 'l');
        Nlm_StaticPrompt (g, "", 0, 0, Nlm_systemFont, 'l');
        if (curarg->intvalue == 1) {
          Nlm_SetStatus (hp [i], TRUE);
        }
        break;
      case ARG_INT:
      case ARG_FLOAT:
      case ARG_STRING:
      case ARG_FILE_IN:
      case ARG_FILE_OUT:
      case ARG_DATA_IN:
      case ARG_DATA_OUT:
        Nlm_MultiLinePrompt (g, (Nlm_CharPtr) curarg->prompt, 0, Nlm_dialogTextHeight, Nlm_systemFont, 'l');
        Nlm_StaticPrompt(g, tag, 0, Nlm_dialogTextHeight, Nlm_systemFont, 'l');
        hp[i] = (Nlm_Handle) Nlm_DialogText(g, (Nlm_CharPtr) curarg->defaultvalue, 10, NULL);
        if (firstText == NULL) {
          firstText = (Nlm_TexT) hp[i];
        }
        break;
    }

    arg[0] = '\0';
    if ((curarg->from != NULL) || (curarg->to != NULL)) {
      tmp = Nlm_StringMove(arg, " (");
      tmp = Nlm_StringMove(tmp, ((curarg->from) != NULL ? (curarg->from): "<NULL>"));
      if ((curarg->type == ARG_INT) || (curarg->type == ARG_FLOAT)) {
        tmp = Nlm_StringMove(tmp, " to ");
        tmp = Nlm_StringMove(tmp, ((curarg->to) != NULL ? ( curarg->to): "<NULL>"));
      }
      Nlm_StringMove(tmp, ")");
    }

    if (curarg->type == ARG_FILE_IN) {
      Nlm_PushButton (g, "File IN", Nlm_GetArgsFileInProc);
    } else if (curarg->type == ARG_FILE_OUT) {
      Nlm_PushButton (g, "File OUT", Nlm_GetArgsFileOutProc);
    } else {
      Nlm_StaticPrompt(g, arg, 0,  Nlm_dialogTextHeight, Nlm_systemFont, 'l');
    }
  }

  Nlm_Break (w);
  h = Nlm_HiddenGroup (w, 10, 0, NULL);
  Nlm_PushButton (h, "OK", Nlm_GetArgsOkProc);
  Nlm_PushButton (h, "Cancel", Nlm_GetArgsCancelProc);
  Nlm_GetRect ((Nlm_GraphiC) g, &r1);
  Nlm_DoGetPosition ((Nlm_GraphiC) h, &r2);
  delta = (Nlm_Int2)(r1.right - r2.right);
  if (delta > 0) {
    Nlm_OffsetRect (&r2, (Nlm_Int2)(delta / 2), 0);
    Nlm_DoSetPosition ((Nlm_GraphiC) h, &r2, TRUE, FALSE);
  }
  Nlm_DoShow ((Nlm_GraphiC) w, TRUE, TRUE);
  if (firstText != NULL)
    Nlm_DoSelect ((Nlm_GraphiC) firstText, TRUE);

  /* Get & handle user input */
  getArgsBoxUp = TRUE;
  while ( getArgsBoxUp )
    {
      getArgsOk = FALSE;
      while (getArgsBoxUp  &&  !getArgsOk)
        Nlm_ProcessEventOrIdle();

      if ( !getArgsOk )
        continue;

      curarg = ap;
      for (i = 0;  i < numargs  &&  !getArgsBoxUp;  i++, curarg++)
        {
          resolved[i] = TRUE;
          switch ( curarg->type )
            {
            case ARG_BOOLEAN:
              {
                if ( Nlm_GetStatus( hp[i] ) )
                  curarg->intvalue = 1;
                else
                  curarg->intvalue = 0;
                break;
              }

            case ARG_INT:
            case ARG_FLOAT:
            case ARG_STRING:
            case ARG_FILE_IN:
            case ARG_FILE_OUT:
            case ARG_DATA_IN:
            case ARG_DATA_OUT:
              {
                Nlm_Char str_value[256];
                Nlm_GetTitle(hp[i], str_value, sizeof(str_value));
                if ( !FetchArg(curarg, str_value, FetchArg_MESSAGE, TRUE) )
                  {
                    Nlm_DoSelect((Nlm_GraphiC)hp[i], TRUE);
                    getArgsBoxUp = TRUE;
                  }
                break;
              }

            default:
              ASSERT ( FALSE );
              Nlm_MemFree( resolved );
              return FALSE;
            }
        }

      curarg = ap;
      if ( getArgsBoxUp )
        continue;

      for (i = 0;  i < numargs;  i++, curarg++)
        if (!curarg->optional  &&  !resolved[i])
          {
            Message(MSG_ERROR, "%s was not given an argument", curarg->prompt);
            getArgsBoxUp = TRUE;
            Nlm_DoSelect((Nlm_GraphiC)hp[i], TRUE);
            break;
          }
    }  
  Nlm_DoRemove ((Nlm_GraphiC) w, TRUE);
  Nlm_Update ();

  if (getArgsOk) {  /* leave up a little window with the program name */
    w = Nlm_FixedWindow (-50, -33, -10, -10, (Nlm_CharPtr) progname, NULL);
    Nlm_DoShow ((Nlm_GraphiC) w, TRUE, TRUE);
  }

  Nlm_MemFree( resolved );
  return getArgsOk;
}


extern Nlm_Boolean Nlm_GetArgs(const char* progname,
                               Nlm_Int2 numargs, Nlm_ArgPtr ap)
{
  return GetArgs_ST(progname, numargs, ap, FALSE);
}


extern Nlm_Boolean Nlm_GetArgsSilent(const char* progname,
                                     Nlm_Int2 numargs, Nlm_ArgPtr ap)
{
  return GetArgs_ST(progname, numargs, ap, TRUE);
}


extern void Nlm_FreeWindows (void)
{
  gphprcsptr = (Nlm_GphPrcsPtr) Nlm_MemFree (gphprcsptr);
}

extern void Nlm_InitWindows (void)
{
  gphprcsptr = (Nlm_GphPrcsPtr) Nlm_MemNew (sizeof (Nlm_GphPrcs) * 12);

  documentProcs = &(gphprcsptr [0]);
#ifdef WIN_MAC
  documentProcs->click = Nlm_DocumentClick;
  documentProcs->key = Nlm_NormalKey;
  documentProcs->draw = Nlm_DocumentDraw;
  documentProcs->idle = Nlm_NormalIdle;
#endif
  documentProcs->show = Nlm_ShowDocument;
  documentProcs->hide = Nlm_HideWindow;
  documentProcs->activate = Nlm_DocumentActivate;
  documentProcs->deactivate = Nlm_DocumentDeactivate;
  documentProcs->remove = Nlm_RemoveWindow;
  documentProcs->select = Nlm_NormalSelect;
  documentProcs->linkIn = Nlm_LinkIn;
  documentProcs->adjustPrnt = Nlm_AdjustWindow;
  documentProcs->setTitle = Nlm_SetWindowTitle;
  documentProcs->getTitle = Nlm_GetWindowTitle;
  documentProcs->setPosition = Nlm_SetWindowPosition;
  documentProcs->getPosition = Nlm_GetWindowPosition;
  documentProcs->gainFocus = Nlm_WindowGainFocus;
  documentProcs->loseFocus = Nlm_WindowLoseFocus;
  documentProcs->sendChar = Nlm_NormalDrawChar;

  fixedProcs = &(gphprcsptr [1]);
#ifdef WIN_MAC
  fixedProcs->click = Nlm_DialogClick;
  fixedProcs->key = Nlm_NormalKey;
  fixedProcs->draw = Nlm_NormalDraw;
  fixedProcs->idle = Nlm_NormalIdle;
#endif
  fixedProcs->show = Nlm_ShowNormal;
  fixedProcs->hide = Nlm_HideWindow;
  fixedProcs->activate = Nlm_NormalActivate;
  fixedProcs->deactivate = Nlm_NormalDeactivate;
  fixedProcs->remove = Nlm_RemoveWindow;
  fixedProcs->select = Nlm_NormalSelect;
  fixedProcs->countItems = NULL;
  fixedProcs->linkIn = Nlm_LinkIn;
  fixedProcs->adjustPrnt = Nlm_AdjustWindow;
  fixedProcs->setTitle = Nlm_SetWindowTitle;
  fixedProcs->getTitle = Nlm_GetWindowTitle;
  fixedProcs->setPosition = Nlm_SetWindowPosition;
  fixedProcs->getPosition = Nlm_GetWindowPosition;
  fixedProcs->gainFocus = Nlm_WindowGainFocus;
  fixedProcs->loseFocus = Nlm_WindowLoseFocus;
  fixedProcs->sendChar = Nlm_NormalDrawChar;

  frozenProcs = &(gphprcsptr [2]);
#ifdef WIN_MAC
  frozenProcs->click = Nlm_FrozenClick;
  frozenProcs->key = Nlm_NormalKey;
  frozenProcs->draw = Nlm_NormalDraw;
  frozenProcs->idle = Nlm_NormalIdle;
#endif
  frozenProcs->show = Nlm_ShowNormal;
  frozenProcs->hide = Nlm_HideWindow;
  frozenProcs->activate = Nlm_NormalActivate;
  frozenProcs->deactivate = Nlm_NormalDeactivate;
  frozenProcs->remove = Nlm_RemoveWindow;
  frozenProcs->select = Nlm_NormalSelect;
  frozenProcs->linkIn = Nlm_LinkIn;
  frozenProcs->adjustPrnt = Nlm_AdjustWindow;
  frozenProcs->setTitle = Nlm_SetWindowTitle;
  frozenProcs->getTitle = Nlm_GetWindowTitle;
  frozenProcs->setPosition = Nlm_SetWindowPosition;
  frozenProcs->getPosition = Nlm_GetWindowPosition;
  frozenProcs->gainFocus = Nlm_WindowGainFocus;
  frozenProcs->loseFocus = Nlm_WindowLoseFocus;
  frozenProcs->sendChar = Nlm_NormalDrawChar;

  roundProcs = &(gphprcsptr [3]);
#ifdef WIN_MAC
  roundProcs->click = Nlm_DialogClick;
  roundProcs->key = Nlm_NormalKey;
  roundProcs->draw = Nlm_NormalDraw;
  roundProcs->idle = Nlm_NormalIdle;
#endif
  roundProcs->show = Nlm_ShowNormal;
  roundProcs->hide = Nlm_HideWindow;
  roundProcs->activate = Nlm_NormalActivate;
  roundProcs->deactivate = Nlm_NormalDeactivate;
  roundProcs->remove = Nlm_RemoveWindow;
  roundProcs->select = Nlm_NormalSelect;
  roundProcs->linkIn = Nlm_LinkIn;
  roundProcs->adjustPrnt = Nlm_AdjustWindow;
  roundProcs->setTitle = Nlm_SetWindowTitle;
  roundProcs->getTitle = Nlm_GetWindowTitle;
  roundProcs->setPosition = Nlm_SetWindowPosition;
  roundProcs->getPosition = Nlm_GetWindowPosition;
  roundProcs->gainFocus = Nlm_WindowGainFocus;
  roundProcs->loseFocus = Nlm_WindowLoseFocus;
  roundProcs->sendChar = Nlm_NormalDrawChar;

  alertProcs = &(gphprcsptr [4]);
#ifdef WIN_MAC
  alertProcs->click = Nlm_PlainClick;
  alertProcs->key = Nlm_NormalKey;
  alertProcs->draw = Nlm_NormalDraw;
  alertProcs->idle = Nlm_NormalIdle;
#endif
  alertProcs->show = Nlm_ShowNormal;
  alertProcs->hide = Nlm_HideWindow;
  alertProcs->activate = Nlm_NormalActivate;
  alertProcs->deactivate = Nlm_NormalDeactivate;
  alertProcs->remove = Nlm_RemoveWindow;
  alertProcs->select = Nlm_PlainSelect;
  alertProcs->linkIn = Nlm_LinkIn;
  alertProcs->adjustPrnt = Nlm_AdjustWindow;
  alertProcs->setTitle = Nlm_SetWindowTitle;
  alertProcs->getTitle = Nlm_GetWindowTitle;
  alertProcs->setPosition = Nlm_SetWindowPosition;
  alertProcs->getPosition = Nlm_GetWindowPosition;
  alertProcs->gainFocus = Nlm_WindowGainFocus;
  alertProcs->loseFocus = Nlm_WindowLoseFocus;
  alertProcs->sendChar = Nlm_NormalDrawChar;

  modalProcs = &(gphprcsptr [5]);
#ifdef WIN_MAC
  modalProcs->click = Nlm_ModalClick;
  modalProcs->key = Nlm_ModalKey;
  modalProcs->draw = Nlm_NormalDraw;
  modalProcs->idle = Nlm_NormalIdle;
#endif
  modalProcs->show = Nlm_ShowModal;
  modalProcs->hide = Nlm_HideModal;
  modalProcs->activate = Nlm_NormalActivate;
  modalProcs->deactivate = Nlm_NormalDeactivate;
  modalProcs->remove = Nlm_RemoveWindow;
  modalProcs->select = Nlm_PlainSelect;
  modalProcs->linkIn = Nlm_LinkIn;
  modalProcs->adjustPrnt = Nlm_AdjustWindow;
  modalProcs->setTitle = Nlm_SetWindowTitle;
  modalProcs->getTitle = Nlm_GetWindowTitle;
  modalProcs->setPosition = Nlm_SetWindowPosition;
  modalProcs->getPosition = Nlm_GetWindowPosition;
  modalProcs->gainFocus = Nlm_WindowGainFocus;
  modalProcs->loseFocus = Nlm_WindowLoseFocus;
  modalProcs->sendChar = Nlm_NormalDrawChar;

  movableModalProcs = &(gphprcsptr [6]);
#ifdef WIN_MAC
  movableModalProcs->click = Nlm_MovableModalClick;
  movableModalProcs->key = Nlm_ModalKey;
  movableModalProcs->draw = Nlm_NormalDraw;
  movableModalProcs->idle = Nlm_NormalIdle;
#endif
  movableModalProcs->show = Nlm_ShowModal;
  movableModalProcs->hide = Nlm_HideModal;
  movableModalProcs->activate = Nlm_NormalActivate;
  movableModalProcs->deactivate = Nlm_NormalDeactivate;
  movableModalProcs->remove = Nlm_RemoveWindow;
  movableModalProcs->select = Nlm_PlainSelect;
  movableModalProcs->linkIn = Nlm_LinkIn;
  movableModalProcs->adjustPrnt = Nlm_AdjustWindow;
  movableModalProcs->setTitle = Nlm_SetWindowTitle;
  movableModalProcs->getTitle = Nlm_GetWindowTitle;
  movableModalProcs->setPosition = Nlm_SetWindowPosition;
  movableModalProcs->getPosition = Nlm_GetWindowPosition;
  movableModalProcs->gainFocus = Nlm_WindowGainFocus;
  movableModalProcs->loseFocus = Nlm_WindowLoseFocus;
  movableModalProcs->sendChar = Nlm_NormalDrawChar;

  floatingProcs = &(gphprcsptr [7]);
#ifdef WIN_MAC
  floatingProcs->click = Nlm_FloatingClick;
  floatingProcs->key = Nlm_FloatingKey;
  floatingProcs->draw = Nlm_NormalDraw;
  floatingProcs->idle = Nlm_FloatingIdle;
#endif
  floatingProcs->show = Nlm_ShowNormal;
  floatingProcs->hide = Nlm_HideWindow;
  floatingProcs->activate = Nlm_NormalActivate;
  floatingProcs->deactivate = Nlm_NormalDeactivate;
  floatingProcs->remove = Nlm_RemoveWindow;
  floatingProcs->select = Nlm_FloatingSelect;
  floatingProcs->linkIn = Nlm_LinkIn;
  floatingProcs->adjustPrnt = Nlm_AdjustWindow;
  floatingProcs->setTitle = Nlm_SetWindowTitle;
  floatingProcs->getTitle = Nlm_GetWindowTitle;
  floatingProcs->setPosition = Nlm_SetWindowPosition;
  floatingProcs->getPosition = Nlm_GetWindowPosition;
  floatingProcs->gainFocus = Nlm_WindowGainFocus;
  floatingProcs->loseFocus = Nlm_WindowLoseFocus;
  floatingProcs->sendChar = Nlm_FloatingDrawChar;

  shadowProcs = &(gphprcsptr [8]);
#ifdef WIN_MAC
  shadowProcs->click = Nlm_PlainClick;
  shadowProcs->key = Nlm_NormalKey;
  shadowProcs->draw = Nlm_NormalDraw;
  shadowProcs->idle = Nlm_NormalIdle;
#endif
  shadowProcs->show = Nlm_ShowNormal;
  shadowProcs->hide = Nlm_HideWindow;
  shadowProcs->activate = Nlm_NormalActivate;
  shadowProcs->deactivate = Nlm_NormalDeactivate;
  shadowProcs->remove = Nlm_RemoveWindow;
  shadowProcs->select = Nlm_PlainSelect;
  shadowProcs->linkIn = Nlm_LinkIn;
  shadowProcs->adjustPrnt = Nlm_AdjustWindow;
  shadowProcs->setTitle = Nlm_SetWindowTitle;
  shadowProcs->getTitle = Nlm_GetWindowTitle;
  shadowProcs->setPosition = Nlm_SetWindowPosition;
  shadowProcs->getPosition = Nlm_GetWindowPosition;
  shadowProcs->gainFocus = Nlm_WindowGainFocus;
  shadowProcs->loseFocus = Nlm_WindowLoseFocus;
  shadowProcs->sendChar = Nlm_NormalDrawChar;

  plainProcs = &(gphprcsptr [9]);
#ifdef WIN_MAC
  plainProcs->click = Nlm_PlainClick;
  plainProcs->key = Nlm_NormalKey;
  plainProcs->draw = Nlm_NormalDraw;
  plainProcs->idle = Nlm_NormalIdle;
#endif
  plainProcs->show = Nlm_ShowNormal;
  plainProcs->hide = Nlm_HideWindow;
  plainProcs->activate = Nlm_NormalActivate;
  plainProcs->deactivate = Nlm_NormalDeactivate;
  plainProcs->remove = Nlm_RemoveWindow;
  plainProcs->select = Nlm_PlainSelect;
  plainProcs->linkIn = Nlm_LinkIn;
  plainProcs->adjustPrnt = Nlm_AdjustWindow;
  plainProcs->setTitle = Nlm_SetWindowTitle;
  plainProcs->getTitle = Nlm_GetWindowTitle;
  plainProcs->setPosition = Nlm_SetWindowPosition;
  plainProcs->getPosition = Nlm_GetWindowPosition;
  plainProcs->gainFocus = Nlm_WindowGainFocus;
  plainProcs->loseFocus = Nlm_WindowLoseFocus;
  plainProcs->sendChar = Nlm_NormalDrawChar;

  desktopProcs = &(gphprcsptr [10]);
#ifdef WIN_MAC
  desktopProcs->click = Nlm_DesktopClick;
  desktopProcs->key = Nlm_DesktopKey;
#endif
  desktopProcs->show = Nlm_ShowNormal;
  desktopProcs->hide = Nlm_HideWindow;
  desktopProcs->remove = Nlm_RemoveWindow;
  desktopProcs->select = Nlm_DesktopSelect;
  desktopProcs->linkIn = Nlm_LinkIn;

  systemProcs = &(gphprcsptr [11]);
#ifdef WIN_MAC
  systemProcs->click = Nlm_SystemClick;
  systemProcs->draw = Nlm_NormalDraw;
#endif
  systemProcs->show = Nlm_ShowNormal;
  systemProcs->hide = Nlm_HideWindow;
  systemProcs->remove = Nlm_RemoveWindow;
  systemProcs->select = Nlm_NormalSelect;
  systemProcs->linkIn = Nlm_LinkIn;
}

#ifdef WIN_MOTIF
/**********************************************************/
static void WindowStructFocusCallbackEx(Widget wd, XtPointer client_data,
                                        XEvent *event, Boolean *contin)
{
    Nlm_WindowData wdata;
    Nlm_RectTool   rtool;
    Nlm_WindoW     w;
    Nlm_RecT       r;
    Window         xw;
    Window         root;
    Window         parent;
    Window         child;
    Window         *children = NULL;
    unsigned int   nchildren;
    int            x;
    int            y;

    if(event->type != ConfigureNotify)
    {
        WindowStructFocusCallback(wd, client_data, event, contin);
        return;
    }

    XSetErrorHandler(ignoreXerror_handler);
    for(xw = XtWindow(wd); xw; xw = parent)
    {
        if(!XQueryTree(Nlm_currentXDisplay, xw, &root, &parent, &children,
                       &nchildren) || root == parent)
            break;
        XFree((char *) children);
        children = NULL;
    }
    XSetErrorHandler(defaultXerror_handler);
    if(children != NULL)
        XFree((char *) children);

    if(root != parent)
        return;

    w = (Nlm_WindoW) client_data;

    XTranslateCoordinates(Nlm_currentXDisplay, xw, root, (Position) 0,
                          (Position) 0, &x, &y, &child);

    rtool.x = x;
    rtool.y = y;
    rtool.width = event->xconfigure.width;
    rtool.height = event->xconfigure.height;
    if(Nlm_GetWindowMenuBar(w) != NULL)
        rtool.height -= Nlm_internalMenuBarHeight;

    Nlm_RectToolToRecT(&rtool, &r);
    Nlm_SetRect((Nlm_GraphiC) w, &r);
    Nlm_GetWindowData(w, &wdata);

    if(wdata.resize != NULL && Nlm_WindowHasBeenShown(w) &&
       Nlm_GetVisible((Nlm_GraphiC) w))
    {
        wdata.resize(w);
    }
}

#endif

/**********************************************************/
extern void Nlm_SetWindowConfigureCallback(Nlm_WindoW w)
{
#ifdef WIN_MOTIF
    Widget wd;

    if(w == NULL)
        return;

    wd = (Widget) Nlm_GetWindowShell(w);
    XtRemoveEventHandler(wd, (StructureNotifyMask | FocusChangeMask), FALSE,
                         WindowStructFocusCallback, (XtPointer) w);
    XtAddEventHandler(wd, (StructureNotifyMask | FocusChangeMask), FALSE,
                      WindowStructFocusCallbackEx, (XtPointer) w);
#endif
    return;
}
