/* 

MAIN include file for C language X-Midas X-Windows graphics libraries

  $Revision: 1.1 $
  $Modtime:   28 Mar 1996 17:12:08  $

*/

#if _VMS

#include <decw$include:Xlib.h>
#include <decw$include:Xutil.h>
#include <decw$include:Xos.h>
#include <decw$include:Xatom.h>
#include <decw$include:Keysym.h>
#include <decw$include:Keysymdef.h>
#include <decw$include:Xcms.h>
#include <decw$include:cursorfont.h>
#include <ctype.h>
#define attr noshare

#else

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/keysymdef.h>
#include <X11/cursorfont.h>
#include <X11/Xcms.h>
#if _HPUX
#else
#include <strings.h>
#endif
#define attr

#endif

#include <math.h>
#include <string.h>
#include <stdio.h>
#include "cdefs.h"
#include "fcinterface.h"
#include "xstructures.h"
#include "xfacilities.h"
#include "xwidgets.h"
#include "mjackets.h"

/* These flags are needed only by the C graphics libraries */

#define TRUE 1
#define FALSE 0
#define MAXDISPLAYS 8
#define MESSLINES 100
#define MESSWIDTH 40
#define MAXSHARED 17
#define MAXITEMLEN 30
#define ALLEVENTS 0xFFFFFFFF
#define KBREDRAW L_AvalRedraw
#define TEXT_CENTER (int)(1.3*Mx->text_h)

/* In-line Macros */

#if _SUN
/* because SUNs sprintf is not ansi-C compliant */
#define XSPRINTF(A,B,C)  strlen ( sprintf(A,B,C) )
#define XSPRINTF2(A,B,C,D)  strlen ( sprintf(A,B,C,D) )
#else
#define XSPRINTF(A,B,C)  sprintf(A,B,C)
#define XSPRINTF2(A,B,C,D)  sprintf(A,B,C,D)
#endif

#define XKUP     XK_Up:    case XK_KP_8
#define XKDOWN   XK_Down:  case XK_KP_2
#define XKRIGHT  XK_Right: case XK_KP_6
#define XKLEFT   XK_Left:  case XK_KP_4

#define min(A,B)  ( (A)<(B) ? (A) : (B) )
#define max(A,B)  ( (A)>(B) ? (A) : (B) )
#define bound(A,B,C)  ( (A)<(B) ? (B) : ( (A)>(C) ? (C) : (A) ) )

/*
#define pbug(A,B,C,D)  printf (" A = %d B = %d C = %d D = %d \n", A,B,C,D)
#define sbug(A)  printf (" A \n")
*/

#define NEWEXPOSEORRESIZE  (GEvent.type==Expose||GEvent.type==ConfigureNotify)
#define MXEXPOSEORRESIZE   (Mx->exposure||Mx->resize)
#define XM_BREAK	   (*Mcbreak || Mx->breakflag || \
			      ((*Mcsysunlock) ? (Mx->exposure = TRUE) : FALSE))
#define POLLTIME	   0.1

#define CLEAR_EXPOSE_AND_RESIZE(EXP,RES) \
EXP = Mx->exposure; Mx->exposure = 0; \
RES = Mx->resize; Mx->resize = 0

#define ARROWSHIFTORCONTROL (GEvent.xkey.state&(ShiftMask|ControlMask)) 
#define BUTTONORKEYRELEASE \
  (GEvent.type==KeyRelease||GEvent.type==ButtonRelease)

#define SETLINE(GC,WIDTH,TYPE) \
  XSetLineAttributes (G.D, GC, WIDTH, TYPE, CapButt, FillSolid)

#define EVENTS_ON   (!Mx->noevent||GEvent.xany.send_event)

/* STOREBACK                                                            */
/* if this is the first time the widget is drawn, IP==0, if IP!=0 the   */
/* background pixmap has already been created so we don't need to copy  */
/* it again, if Mx->resize is true then the entire window is black      */
/* anyways so we don't need to bother even creating the pixmap all      */

#define STOREBACK(XC,YC,XS,YS,IP) \
  if (!Mx->resize && IP==0) { \
    IP = XCreatePixmap (G.D, G.W, XS, YS, G.depth); \
    XCopyArea (G.D, G.W, IP, G.gct, XC, YC, XS, YS, 0, 0); } \

/* COPYBACK                                                          */
/* if a pixmap was not created IP==0, this must have been because we */
/* encountered a resize at some point and the window is black, so we */
/* just clear out the area so the widget disappears, same if we did  */
/* create a pixmap but we encountered a resize in our widget, don't  */
/* bother copying back the info because its not in the right place   */
/* anymore anyways.  We also don't need to free up the pixmap unless */
/* it was created to begin with                                      */

#define COPYBACK(XC,YC,XS,YS,IP) \
  if (!Mx->resize && IP!=0) XCopyArea (G.D,IP,G.W,G.gct,0,0,XS,YS,XC,YC); \
  else XClearArea (G.D, G.W, XC, YC, XS, YS, FALSE); \
  if (IP!=0) XFreePixmap (G.D, IP)

/* These next 4 X drawing calls are pretty long and the first 2 or 3 args */
/* are always the same so I used inline macros to make the code neater    */

#define DRAWTEXT(XT,YT,STRING,LENGTH) \
XDrawImageString (G.D, G.W, G.gct, XT, YT, STRING, LENGTH)

#define DRAWITEXT(XT,YT,STRING,LENGTH) \
XDrawImageString (G.D, G.W, G.gcti, XT, YT, STRING, LENGTH)

#define DRAWRECTANGLE(GC,XC,YC,XS,YS) \
XDrawRectangle (G.D, G.W, GC, XC, YC, XS, YS)

#define FILLRECTANGLE(GC,XC,YC,XS,YS) \
XFillRectangle (G.D, G.W, GC, XC, YC, XS, YS)

/* This next set of lines is used in every GCG drawing routine to reset */
/* the GCG color foreground */
#define SETGCGFOREGROUND(IC) \
if ((IC) != Mx->clast && (IC) != L_XORColor) { \
  if ((IC)>L_NoColor+1 && (IC)<=L_color) Mx->clast = IC; \
  else Mx->clast = L_FGColor; \
  XSetForeground(G.D, G.gcg, Mx->pixel[Mx->clast-1]); \
}

/* These next macros are for converting RGB values between percentages */
/* 0%-100% and mask values 0x0-0xFFFF used by X-Windows color routines. */
#define PERC2PIXEL(P) (int_u2)(655.35*(float)(P))
#define PIXEL2PERC(P) (int_2)(((float)(P)+325.0)/655.35)


attr XGLOBALS G;	/* structure containing all the unique globals */
attr char     GNodeName[40];	/* Node name */
attr MX	      *Mx;		/* pointer to the Mx structure */

attr bool_4   *Mcbreak;	    /* Pointer to the Midas common break flag */
attr bool_4   *Mcsysunlock; /* Pointer to the Midas common sys unlock flag */
attr XEvent   GEvent;	    /* Globally allocated event for event processing */
attr KeySym   GKeysym;	    /* Keysym value for keyboard input */
attr char     GKey[16];	    /* character string value for keyboard input */
attr char     *GExbuf_ptr;	 /* image expansion memory address */
attr int      GExbuf_size;	 /* image expansion memory size */
attr int      GMaxLines;   	/* Max number of lines you can send server */
attr int      Gshr_mapped[MAXSHARED];   /* Number of colormap sharers */
attr int      Gshr_cells[MAXSHARED];   	/* Number of cells in shared colormap */
attr XColor   *Gshr_color[MAXSHARED];   /* Pointer to shared array of colors */
attr short    *Gshr_colorp[MAXSHARED];  /* Pointer to shared array of percent */
attr int      GWcount;        /* Number of primitives open on this Display */
attr int      GBorder;        /* Border width on X-Widgets */
attr bool     GErrorVerbose;  /* if TRUE m_warning all non-fatal X Errors */

attr struct {
  Display *id;  
  int count;
  char node[40];
} D[MAXDISPLAYS];

/* Routines written in FORTRAN that need to be accessed by C */

void mx_axis (real_8 xmin, real_8 ymin, real_8 xmax, real_8 ymax,
  real_8 xtic1, real_8 ytic1, real_8 xtic, real_8 ytic,
  real_8 xmult, real_8 ymult,
  int_4 xc, int_4 yc, int_4 w, int_4 h,
  const char *xlabel, const char *ylabel, bool_4 grid,
  int_4 xlen, int_4 ylen);
void mx_control_panel (XFACILITIES *Xf, int mode);
void mx_dopen (const MX *mx_ptr, const char *name, int_4 length);
void mx_dprompt (const char *prompt, real_8 *dval, int_4 length);
void mx_facilities (void *xf, const char *type, int_4 mode, int_4 length);
int_4 mx_files (char *filename, int_4 length);
void mx_fprompt (const char *prompt, real_4 *fval, int_4 length);
int_4 mx_hardcopy_open (const char *filename, int_4 flag, int_4 length);
void mx_label (int_4 units, real_8 mult, char *label, int_4 length);
void mx_lprompt (const char *prompt, int_4 *lval, int_4 length);
void mx_mhelp (const char *menu, const char *item, int_4 mlen, int_4 ilen);
int_4 mx_userfiles (char *filename, const char *userargs,
  int_4 flen, int_4 ulen);
void mx_contour (real_4 zstart, real_4 zdelta, int_4 nslices,
  const real_4 zvals[],
  int_4 work[], real_4 lines[], int_4 *npoints, int_4 nbytes,
  int_4 nx, int_4 ny, real_4 xstart, real_4 xdelta,
  real_4 ystart, real_4 ydelta);
void mx_dialog (void *Xf, void *hcb, const void *hcbd, void *lbuf, int_4 mode);
void mx_drawaxis (int_4 xdiv, int_4 ydiv, int_4 xlab, int_4 ylab, bool_4 grid);
void mx_hardcopy_close (void);
int_4 mx_mimic_msg (void *mqh, void *mqd, int_4 mimic);
void mx_msgval_poll (XWIDGET *xw);
void mx_mult (real_8 end1, real_8 end2, real_8 *mult);
void mx_origin (int_4 inorigin, int_4 outorigin,
  const STKSTRUCT *instack, STKSTRUCT *outstack);
void mx_plot (int_4 ic, const real_8 xpoint[], const real_8 ypoint[], 
  int_4 npoint, int_4 skip, int_4 line, int_4 dot, XPoint work[]);
void mx_setup (int_4 width, int_4 height);
void mx_tics (real_8 vmin, real_8 vmax,
  real_8 *tic1, real_8 *dtic, int_4 ndiv);
void mx_ttics (real_8 vmin, real_8 vmax,
  real_8 *tic1, real_8 *dtic, int_4 ndiv);
void mx_trace (int_4 ic, const real_8 xpoint[], const real_8 ypoint[], 
  int_4 npoint, int_4 skip, int_4 line, int_4 symbol, int_4 rad,
  XPoint work[], int_u4 opts);
void mx_trace_msg (void *mqd, int_4 *line, int_4 *thk,
			int_4 *sym, int_4 *rad, int_4 *colr);
Window mx_window_id (int_4 xs, int_4 op);
/*+++                                        */
/* DR 11244                                  */
void mx_display_id (int_4 xs, int_4 op, char *node, int_4 ln);
/*---                                        */
void mx_xc (const int_2 map[7][4], int_2 color[][4], int_4 *ncolors);
void mx_xwidget (int_4 id);
void mx_annotate (int_4 mode);
void mx_boxes (int_4 mode, void (*routine)(), int_4 *iarg, real_8 *darg);
void mx_points (int_4 mode, void (*routine)(), int_4 *iarg, real_8 *darg);
int_4 mx_graphics_msg (MX *mx_ptr, void *mqh, void *mqd, int_4 *msgid,
			int_4 *msgmask);

/* Routines written in C */

void mx_arrow (int x, int y, int d, int orientation);
int mx_bogus_event (void);
int mx_query (char object);
void mx_xflush (void);
void mx_cursor (int shape);
void mx_draw_arc (int ic, int x, int y, int w, int h, int a1, int a2);
void mx_fill_arc (int ic, int x, int y, int w, int h, int a1, int a2);
void mx_colorlab (int ic, const char *text, int length);
void mx_put_image (const char data[], int nx, int ny, int nex, int ney,
                        int xd, int yd, int level);
void mx_map (MAPSTRUCT *cnv, int x, int y, int w, int h, int func);
void mx_zoom (int x, int y, int w, int h, int xd, int yd, int nx, int ny);
void mx_unzoom (void);
void mx_display (MX *mx_ptr, bool_4 *b_ptr, bool_4 *unl_ptr);
void mx_autorepeat (bool_4 *autorepeat, int mode);
void mx_open (const char *name, int lname);
void mx_draw_lines (int ic, const XPoint pix[], int npix);
void mx_draw_dots (int ic, const XPoint pix[], int npix, int rr);
void mx_draw_symbol (int ic, int x, int y, int symb, int rad);
void mx_draw_symbols (int ic, const XPoint pix[], int npix, int symb, int rad);
void mx_setcontext (MX *mx_ptr);
void mx_graphicsinit (void);
void mx_close (void);
int mx_queued (void);
Bool mx_match (const Display *D, const XEvent *E, const int *type);
void mx_event (void);
bool mx_ifevent (void);
void mx_graphics_break (bool_4 *breakflag);
void mx_configmess (void);
bool mx_learn (Window window_id,
  int_4 *left, int_4 *top, int_4 *width, int_4 *height);
void mx_setbar (const char *text, int length);
void mx_title (const char *text, int mask, int length);
void mx_unsetbar (void);
void mx_setbgfg (int black, int white, int xi);
void mx_setfont (int width);
void mx_putbackevent (void);
void mx_wakeup (Window window_id, int mode, int value);
bool mx_client_event (Window window_id, int mesg,
  const int_4 vals[], int nvals);
void mx_clear_area (int x, int y, int w, int h);
void mx_clear_window (void);
void mx_draw_box (int ic, int x, int y, int w, int h);
void mx_fill_box (int ic, int x, int y, int w, int h);
void mx_clip (int x, int y, int w, int h);
void mx_rclip (int x, int y, int w, int h);
void mx_rubberdot (int x, int y, int rr);
void mx_rubberline (int x1, int y1, int x2, int y2);
void mx_rubberbox (int_4 *x1, int_4 *y1, int_4 *x2, int_4 *y2, void (*func)());
void mx_rubberwarpbox (int_4 *x1, int_4 *y1, int_4 *x2, int_4 *y2,
  void (*func)());
void mx_dragbox (int_4 *x, int_4 *y, int w, int h,
  int xmin, int xmax, int ymin, int ymax, void (*func)());
void mx_warpbox (int_4 *x1, int_4 *y1, int_4 *x2, int_4 *y2,
  int xmin, int ymin, int xmax, int ymax, void (*func)(), int mode);
void mx_draw_mode (int mode);
void mx_draw_line (int ic, int x1, int y1, int x2, int y2);
void mx_fill_poly (int ic, const XPoint pix[], int npix, int mode);
void mx_colortext (int ic, int x, int y, const char *text, int length);
void mx_text (int x, int y, const char *text, int length);
void mx_rubbertext (int x, int y, const char *text, int length);
void mx_textline (int x1, int y1, int x2, int y2);
void mx_get_image (int_4 data[], int xc, int yc, int w, int h, int ncolors);
void mx_getrgb (int ic, int_4 *red, int_4 *green, int_4 *blue);
void mx_putlat_image (const char data[], int nx, int ny,
                        int nex, int ney, int xd, int yd, int level);
void mx_tdraw (XFANNOTATION *tn);
void mx_tselect (XFANNOTATION *tn, int task);
void mx_tfont (XFANNOTATION *tn, int task);
bool mx_pointer (void);
bool redraw_widget (bool exposure, bool resize);
bool drag_widget (int x, int y, int w, int h, int y2,
                        int *xadj, int *yadj, Pixmap *ip);
void mx_colormap (int_2 map[7][4], int_4 *pcolors);
int_4 mx_colormap_id (int_2 map[7][4], int_4 ncolors);
void mx_colortab (int ic, int_2 map[7][4], int pos);
void mx_message (const char *text, float time, int length);
void mx_pipe_monitor (const char *name, const HEADER *hcb, int length);
void mx_scrollbox (const char *text, const int_4 line[],
	      int_4 *lines, int_4 *maxlen, int type);
void mx_widgetbox (int xc, int yc, int xs, int ys, int xcc, int ycc,
        int xss, int yss, const char *name, int length);
void mx_shadowbox (int x, int y, int w, int h, int type, int func, 
  const char *label, int length);
void mx_psdashes (char *s, int offset, const char *dashes, 
		  int ndashes, int factor);
void mx_psopen (const char *fname, int_4 *status, char *errstr, 
		int interact, int lfname, int lerrstr);
void mx_psclip (int ic, short x, short y, short w, short h);
void mx_psdraw_line (int ic, short x1, short y1, short x2, short y2);
void mx_psdraw_objects (int ic, const XPoint pix[], int npix,
			int radius, const char *kind);
void mx_psdraw_vector (int ic, const XPoint pix[], int npix, const char *kind);
void mx_psdraw_arc (int ic, int x, int y, int w, int h,
		    int a1, int a2, bool filled);
void mx_psdraw_rect (int ic, int x, int y, int w, int h, const char *kind);
void mx_pstextline (short x1, short y1, short x2, short y2);
void mx_pstext (int ic, int x, int y, const char *s, int ls, bool fill);
void mx_pstdraw (const XFANNOTATION *tn, short xpos, short ypos, bool filled);
void mx_psclose (void);

bool getevent (void);
void geteventw (void);
bool peelevents (int type);
int lookupstring (const XEvent *event, char key[], KeySym *keysym);
