/*
** WINDOWS - Simple but Elegant Window Functions 
**           (Lattice, Computer Innovations, Microsoft, 
**            Datalight, Aztec, Watcom, Mix Power C)
**
** Copyright (c) 1984, 1985, 1986 - Philip A. Mongelluzzo
** All rights reserved.
**
*/

/*
** Truth, Lies, and Compiler Options 
**
** Various equates for the various compilers.
**
** Basic compiler invocation is:
**
** AZTEC C
**
**      cc -DAZTEC -DMSCV3 -DSPTR=1 sourcefile_name  (Small Model)
**
** WATCOM C
**
**      WCC sourcefile_name /dMSCV4=1 /dWATCOM=1
**
** BORLAND Turbo C
**
**      TCC -DBORLAND=1 sourcefile_name;
**
** Microsoft 3.X
**
**      MSC -dMSCV3 sourcefile_name;
**
** Microsoft 4.X
**
**      MSC -dMSCV4 sourcefile_name;
**
** Microsoft 5.X
**
**      cl /DMSCV4=1 sourcefile_name /c;
**
** Microsoft QuickC
**
**      qcl /DMSCV4=1 sourcefile_name /c;
**
** Mix Power C
**
**      pc /DMSCV4=1 /DM_I86CM=1 sourcefile_name
**
** Lattice 2.XX 
**
**      LCS -dLC2 sourcefile_name
**
** Lattice 3.XX
**
**      LCS -dLC3 sourcefile_name
**
** Lattice 6.XX
**
**      LCS -dLC6 sourcefile_name
**
** Datalight
**
**      DLC1 -dDLC -p -w -mS sourcefile_name
**      DLC2 sourcefile_name -S
**
** Computer Innovations CI86
**
**      cc1 -cm -dC86 sourcefile_name
**      cc2 ...
**
*/

/*
** Computer Innovations comes first....
*/

#ifdef C86
#define BORLAND 0
#define MSCV3   0
#define MSCV4   0
#define MSC     0
#define MSC3    0
#define MSC4    0
#define DLC     0
#define CI86    1
#define LC2     0
#define LC3     0
#define LC6     0
#define __ZTC__ 0
#define MIXPC   0
#define AZTEC   0
#define WATCOM  0
#ifdef _C86_BIG
#define LPTR    1
#define SPTR    0
#else
#define LPTR    0
#define SPTR    1
#endif
#define LATTICE 0
#define void int                        /* define void as int */
struct WORDREGS {                       /* register layout is */
        unsigned int ax;                /* different from the rest !! */
        unsigned int bx;
        unsigned int cx;
        unsigned int dx;
        unsigned int si;
        unsigned int di;
        unsigned int ds;                /* <= NB */
        unsigned int es;                /* <= NB */
        unsigned int flags;
        };
struct BYTEREGS {
        unsigned char al, ah;
        unsigned char bl, bh;
        unsigned char cl, ch;
        unsigned char dl, dh;
        };
union REGS {
        struct WORDREGS x;
        struct BYTEREGS h;
        };
struct SREGS {
        unsigned int cs;
        unsigned int ss;
        unsigned int ds;
        unsigned int es;
        };
extern unsigned wns_mtype();            /* make everyone happy */
#endif                                  /* end C86 Stuff */


#if WATCOM
#pragma aux v_stksp "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux _putca "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux _getca "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux _absloc "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_wca "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es];

#pragma aux v_wtty "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_cls "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es];

#pragma aux v_spage "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_smode "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_locate "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_hidec "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_sapu "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_sapd "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_rcpos "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_rcvs "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_getch "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_kflush "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_kstat "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_sctype "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux xferdata "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux v_border "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux _vidblt "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 

#pragma aux _putca "_*" parm caller []                           \
                         value struct float struct routine [ax]   \
                         modify [ax bx cx dx es]; 
#endif

/*
** Microsoft 4.0, 5.X, QuickC, PowerC
*/

#if MSCV4
#define MSC     1
#define MSCV3   0
#define MSC4    1
#define DLC     0
#define CI86    0
#define LC2     0
#define LC3     0
#define BORLAND 0
#ifndef MIXPC
#define MIXPC   0
#endif
#define AZTEC   0
#ifdef M_I86SM                          /* small code, small data */
#define SPTR    1
#define LPTR    0
#endif
#ifdef M_I86LM                          /* large code, large data */
#define SPTR    0
#define LPTR    1
#endif
#ifdef M_I86CM                          /* small code, large data */
#define SPTR    0
#define LPTR    1
#endif
#ifdef M_I86MM                          /* large code, small data */
#define SPTR    1
#define LPTR    0
#endif
#define LATTICE 1
#endif

/*
** Microsoft 3.00
*/

#if MSCV3
#define MSC     1
#define MSC4    0
#define DLC     0
#define CI86    0
#define LC2     0
#define LC3     0
#define BORLAND 0
#define MIXPC   0
#ifndef AZTEC
#define AZTEC   0
#endif
#ifdef M_I86SM                          /* small code, small data */
#define SPTR    1
#define LPTR    0
#endif
#ifdef M_I86LM                          /* large code, large data */
#define SPTR    0
#define LPTR    1
#endif
#ifdef M_I86CM                          /* small code, large data */
#define SPTR    0
#define LPTR    1
#endif
#ifdef M_I86MM                          /* large code, small data */
#define SPTR    1
#define LPTR    0
#endif
#define LATTICE 1
#endif

/*
** Lattice 6.XX
*/

#if LC6                                 /* Lattice 6 looks like BORLAND! */
#define BORLAND 1                       /* from a code standpoint */
#undef NULL                             /* NULL must be redefined */
#define NULL 0                          /* to avoid useless errors */
#endif                                  /* any changes here must also */
                                        /* be made in "windows.c" */

/*
** Zortech
*/

#if __ZTC__                             /* ZORTECH looks like BORLAND! */
#define BORLAND 1                       /* from a code standpoint */
#undef NULL                             /* NULL must be undefined */
#endif                                  /* any changes here must also */
                                        /* be made in "windows.c" */
/*
** BORLAND
*/

#ifdef __TURBOC__
#ifndef BORLAND
#define BORLAND 1
#endif
#endif

#if BORLAND
#define MSC     1
#define MSC4    1
#define DLC     0
#define CI86    0
#define LC2     0
#define LC3     0
#define MIXPC   0
#define AZTEC   0
#ifdef __SMALL__                        /* small code, small data */
#define SPTR    1
#define LPTR    0
#endif
#ifdef __LARGE__                        /* large code, large data */
#define SPTR    0
#define LPTR    1
#endif
#ifdef __COMPACT__                      /* small code, large data */
#define SPTR    0
#define LPTR    1
#endif
#ifdef __MEDIUM__                       /* large code, small data */
#define SPTR    1
#define LPTR    0
#endif
#ifdef __HUGE__                         /* large code, large data */
#define SPTR    0
#define LPTR    1
#endif
#define LATTICE 1
#endif

#define TRUE    1                       /* truth */
#define FALSE   0                       /* lies */
#define The_BOSS TRUE                   /* convienent equate */

#include "stdio.h"                      /* standard header */
#if CI86
char *malloc(), *calloc();              /* for the OLD TIMER */
#else
#include "stdlib.h"                     /* For the rest */
#endif
#if LC6
#include "string.h"                     /* Now for Lattice 6.XX */
#endif

#if BORLAND | MSC | DLC | LC2 | LC3 | MIXPC | WATCOM | CI86
#if AZTEC
#else
#include "dos.h"                        /* Lattice stuff */
#endif
#endif
#include "ctype.h"                      /* character conversion stuff */
#if MSC4
#include "stdarg.h"                     /* variable arg list marcos */
#endif

#if AZTEC                               /* AZTEC DOS.H */

struct WORDREGS {
    unsigned int ax;
    unsigned int bx;
    unsigned int cx;
    unsigned int dx;
    unsigned int si;
    unsigned int di;
    unsigned int cflag;
    };

struct BYTEREGS {
    unsigned char al, ah;
    unsigned char bl, bh;
    unsigned char cl, ch;
    unsigned char dl, dh;
    };

union REGS {
    struct WORDREGS x;
    struct BYTEREGS h;
    };

struct SREGS {
    unsigned int cs;
    unsigned int ss;
    unsigned int ds;
    unsigned int es;
    };

#define FP_SEG(fp) (*((unsigned *)&(fp) + 1))
#define FP_OFF(fp) (*((unsigned *)&(fp)))

struct RS {
  int ax, bx, cx, dx, si, di, ds, es;
};
#endif                                  /* End AZTEC DOS.H */

#define SAVE    TRUE                    /* similar truth */
#define RESTORE FALSE                   /* fibs */
#define PAINT   TRUE                    /* screen update modes */
#define FLASH   FALSE                   /* ditto */
#define REPLACE 1                       /* for flicker free */
#define ERASE   0                       /* scroll w_sapd & w_sapu */
#define FAST    0x01                    /* fast retrace */
#define SLOW    0x08                    /* slow retrace */

#define NULPTR  (char *) 0              /* null pointer */
#define NUL     '\0'                    /* NUL char */
#define NVAL    0                       /* null value - INTEGER */
#define BEL     0x07                    /* beep */
#define BS      0x08                    /* backspace */
#define ESC     0x1b                    /* Escape */
#define CR      0x0d                    /* carriage return */
#define LF      0x0a                    /* linefeed */
#define RUB     0x7f                    /* delete */
#define NAK     0x15                    /* ^U */
#define ETX     0x03                    /* ^C */
#define CAN     0x18                    /* ^X */
#define Del     0x53                    /* Del key scan code */
#define ECHO    0x8000                  /* echo disable bit */

#define BIOS    0x01                    /* BIOS Scrolling */
#define DMAS    0x02                    /* The BOSS's DMA Scrolling */

#define MO_LEFT   0                     /* Mouse left button */
#define MO_RIGHT  1                     /* Mouse right button */
#define MO_HDW    1                     /* Mouse hardware */
#define MO_SFT    0                     /* Mouse software */

/*
** The following 2 equates are needed by Lattice Ver 2.XX (which is
** no longer "officially" supported.  Lattice Ver 2.XX users that need
** to work with larger Physical screens must change these constants here
** and in "windows.c". Other users can use the wns_ssiz() function.  Refer
** to wn_sup.c for usage.
*/

#define WN_MXROWS 25                    /* MAX PHYSICAL SCREEN */
#define WN_MXCOLS 80                    /* MAX PHYSICAL SCREEN */

/*
** Externals
*/

extern int  wns_mouse;                  /* mouse in use flag */
extern int  wni_mxrows;                 /* maximum PHYSICAL screen size */        
extern int  wni_mxcols;                 /* maximum PHYSICAL screen size */
extern int  wni_mxneed;                 /* maximum memory for screen img */
extern int  wni_mxrbs;                  /* maximum # of bytes in a row */
extern int  wni_mxrbs2;                 /* same as above, times 2 */
extern int  wni_frmflg;                 /* data clerk (frmget) state */
extern int wn_dmaflg;                   /* dma flag */
extern char wn_sbit;                    /* retrace test bit 8 slow, 1 fast */
extern int wn_blank;                    /* vidon & vidoff control flag */
extern int wns_bchars[];                /* box chars */
extern unsigned int wns_mtflg;          /* monitor type flag */
extern int wns_cflag;                   /* close in progress flag */

extern struct SREGS wns_srp;            /* for segread */

extern unsigned wni_seg[];              /* for wns_push/pop */
extern unsigned wni_off[];              /* ditto */
extern unsigned wni_ptr[];              /* ditto */

#define BCUL  wns_bchars[0]             /* some shorthand for later */
#define BCUR  wns_bchars[1]
#define BCTB  wns_bchars[2]
#define BCSD  wns_bchars[3]
#define BCLL  wns_bchars[4]
#define BCLR  wns_bchars[5]

/*
** Misc Stuff
*/

#if LC2
extern unsigned wns_mtype();            /* make everyone happy */
#endif

#define WMR   wn->bsize                 /* shorthand */

typedef struct wcb                      /* Window control block */
{
int ulx,                                /* upper left corner x coordinate */
    uly,                                /* upper left corner y coordinate */
    xsize,                              /* width of window - INSIDE dimension */
    ysize,                              /* height of window -INSIDE dimension */
    ccx,                                /* virtual cursor offset in window */
    ccy,
    style,                              /* attribute to be used in window */
    bstyle,                             /* border attribute */
    bsize;                              /* total border size 0 or 2 only */
char *scrnsave;                         /* pointer to screen save buffer */
int page,                               /* current video page being used */
    oldx,                               /* cursor position when window was */
    oldy,                               /* opened (used for screen restore) */
    wrpflg,                             /* wrap flag */
    synflg;                             /* cursor sync flag */
char *handle;                           /* my own id */
    char *prevptr;                      /* linked list - previous */
    char *nextptr;                      /* linked list - next */
    unsigned tmpseg;                    /* for activate */
    unsigned tmpoff;                    /* ditto */
    int  smeth;                         /* scroll method to use */
} WINDOW, *WINDOWPTR;

extern WINDOWPTR wns_last;              /* last window opened */

typedef struct mcb                      /* Mouse control block */
{
int exists,                             /* TRUE if MOUSE exists */
    nbuts,                              /* number of buttons */
    bstat,                              /* button status */
    nclik,                              /* number of clicks */
    col,                                /* position - column */
    row,                                /* position - row */
    hmove,                              /* net horizontal movement */
    vmove;                              /* net vertical movement */
    char *handle;                       /* my own id */
} MOUSE, *MOUSEPTR;         

union wi_args {                         /* variable arg type union */
  int vi;                               /* (int) */
  int *vip;                             /* (int *) */ 
  unsigned int vui;                     /* (unsigned int) */
  unsigned int *vuip;                   /* (unsigned int *) */
  char vc;                              /* (char) */
  char *vcp;                            /* (char *) */
  long vl;                              /* (long) */
  long *vlp;                            /* (long *) */
  unsigned long vul;                    /* (unsigned long) */
  unsigned long *vulp;                  /* (unsigned long *) */
  float vf;                             /* (float) */
  float *vfp;                           /* (float *) */
  double vd;                            /* (double) */
  double *vdp;                          /* (double *) */
} ;

typedef struct wi_scb {                 /* screen control block */
  char *pself;                          /* pointer to myself */
  int fcode;                            /* input funtion code */
  WINDOWPTR wn;                         /* the window */
  int row;                              /* window (wn) location - row */
  int col;                              /* window (wn) location - col */
  char *prmpt;                          /* prompt string for field */
  unsigned int atrib;                   /* input field attribute */
  char fill;                            /* input field fill character */
  union wi_args v1;                     /* whatever */
  union wi_args v2;                     /* whatever */
  union wi_args v3;                     /* whatever */
  union wi_args v4;                     /* whatever */
  union wi_args v5;                     /* whatever */
  union wi_args v6;                     /* whatever */
  union wi_args v7;                     /* whatever */
  union wi_args v8;                     /* whatever */
} WIFLD, *WIFLDPTR, **WIFORM;

#if MSCV3 | MSCV4 | BORLAND | DLC | LC3 /* allow for LINT_ARGS */
#ifndef GENFNS
#include "windows.fns"                  /* enforce type checking */
#endif
#else                                   /* and almost lint args */
struct wcb *wn_open();
struct wcb *wn_move();
struct wcb *wn_save();
struct mcb *mo_reset();
char *wn_gets();
char *wn_sleftj();
char *wn_srightj();
char *wn_scenter();
char *wn_sdelspc();
struct wcb *wn_save();
struct wi_scb * *wn_frmopn();
unsigned int wns_mtype();
#endif

#define BLACK   0x00                    /* foreground */
#define RED     0x04                    /* background */
#define GREEN   0x02                    /* colors */
#define YELLOW  0x06                    /* bg << 4 | fg */
#define BLUE    0x01
#define MAGENTA 0x05
#define CYAN    0x03
#define WHITE   0x07
#define BLINK   0x80
#define BOLD    0x08
#define NDISPB  0x00                    /* non display black */
#define NDISPW  0x77                    /* non display white */
#define RVIDEO  0x70                    /* reverse video */
#define UNLINE  0x01                    /* under line (BLUE) */

#define NVIDEO  0x07                    /* normal video */
#define NORMAL  0x03                    /* cyan is normal for me */

/*
** Display Mode Atributes
*/

#define B4025  0                        /* black & white 40 x 25 */
#define C4025  1                        /* color 40 x 25 */
#define B8025  2                        /* black & white 80 x 25 */
#define C8025  3                        /* color 80 x 25 */
#define C320   4                        /* color graphics 320 x 200 */
#define B320   5                        /* black & white graphics */
#define HIRES  6                        /* B&W hi res 640 * 200 */
#define MONO   7                        /* monocrome 80 x 25 */

/*
** Macro to set attribute byte
*/

#define v_setatr(bg,fg,blink,bold) ((blink|(bg<<4))|(fg|bold))

/*
** Key Scan Scodes & Window Input Stuff 
*/

#define BELL            0x0007          /* ring a ding */
#define LARROW          0x4b00          /* left arrow */
#define RARROW          0x4d00          /* right arrow */
#define DARROW          0x5000          /* down arrow */
#define UARROW          0x4800          /* up arrow */
#define HOME            0x4700          /* home key */
#define END             0x4f00          /* end key */
#define INS             0x5200          /* insert key */
#define DEL             0x5300          /* delete key */        
#define F1              0x3b00          /* F1 aka HELP */
#define HELP            F1              /* same as F1 */
#define TAB             0x0f09          /* tab */
#define BKTAB           0x0f00          /* back (shift) tab */

                                        /* 0 to 100 are reserved!! */
#define GDONE  0                        /* end of list */
#define GDATE  10                       /* wn_gdate */
#define GTIME  11                       /* wn_gtime */
#define GINT   12                       /* wn_gint */
#define GUINT  13                       /* wn_guint */
#define GLONG  14                       /* wn_glong */
#define GFLOAT 15                       /* wn_gfloat */
#define GPHONE 16                       /* wn_gphone */
#define GTEXT  17                       /* wn_gtext */
#define GBOOL  18                       /* wn_gbool */
#define DTEXT  19                       /* Display text only */
#define GPWORD 20                       /* wn_gpword */
#define GULONG 21                       /* wn_gulong */
#define GDOUBL 22                       /* wn_gdouble */
#define GUTEXT 23                       /* wn_gutext */
#define GLTEXT 24                       /* wn_gltext */
                                        /* from above to 100 are reserved!! */

#define NSTR ""                         /* null string */
#define NFRM (WIFORM)(0)                /* null form pointer */
#define NFLD 0                          /* must be int 0 */
#define SET  1                          /* form setup */
#define XEQ  2                          /* immediate execution */
#define MAXSTR 80                       /* max size - wn_gtext, wn_input */         

#define WNLPTR (WINDOWPTR) 0            /* A TRUE NULL WINDOW POINTER */
#define MOLPTR (MOUSEPTR) 0             /* A TRUE NULL MOUSE POINTER */

/*
** FAR MEMORY MACROS
*/

#if MSCV3 | MSCV4
#define FPSEG(fp) (*((unsigned *)&(fp) + 1))
#define FPOFF(fp) (*((unsigned *)&(fp)))
#endif

#if DLC
#define FPOFF(fp) ((unsigned) ((char *)(fp) - (char *)0))
#define FPSEG(fp) (((unsigned *) (&(fp)))[1])
#endif

#if BORLAND 
#define FPOFF(fp) ((unsigned)(fp))
#define FPSEG(fp) ((unsigned)((unsigned long)(fp) >> 16))
#endif

#if LC3
#define FPOFF(fp) (unsigned)FP_OFF( (char far *) fp)
#define FPSEG(fp) (unsigned)FP_SEG( (char far *) fp)
#endif

#if CI86
unsigned wns_off();
unsigned wns_seg();
#define intdos  sysint21
#define FPOFF(fp) (unsigned)wns_off(fp)
#define FPSEG(fp) (unsigned)wns_seg(fp)
#endif

#if LC2
#define FPOFF(fp) wns_off(fp)
#define FPSEG(fp) wns_seg(fp)
#endif

/* End */
