/*----------------------------------------------------------------------*/
/* xcircuit.h 								*/
/* Copyright (c) 2002  Tim Edwards, Johns Hopkins University        	*/
/*----------------------------------------------------------------------*/

/*----------------------------------------------------------------------*/
/*      written by Tim Edwards, 8/20/93    				*/
/*----------------------------------------------------------------------*/

#ifndef HAVE_U_CHAR
typedef unsigned char	u_char;
typedef unsigned short	u_short;
typedef unsigned int	u_int;
typedef unsigned long	u_long;
#endif

/*----------------------------------------------------------------------*/
/* Redefinition of fprintf() allows redirection of output to a console	*/
/* in the Tcl interpreter-based version.				*/
/*----------------------------------------------------------------------*/

#ifdef TCL_WRAPPER
  #define Fprintf tcl_printf
  #define Flush tcl_stdflush
#else
  #define Fprintf fprintf
  #define Flush fflush
#endif

#ifdef TCL_WRAPPER
  #define malloc Tcl_Alloc
  #define calloc(a,b) Tcl_Alloc(a * b)
  #define free(a) Tcl_Free((char *)(a))
  #define realloc(a,b) Tcl_Realloc((char *)(a), b)
  #undef strdup
  #define strdup Tcl_Strdup
  extern char *Tcl_Strdup(const char *);
#endif

/*----------------------------------------------------------------------*/
/* Deal with 32/64 bit processors based on autoconf results.		*/
/*----------------------------------------------------------------------*/

#if SIZEOF_VOID_P == SIZEOF_UNSIGNED_INT
#define Number(a)		(void *)((u_int) a)
typedef u_int pointertype;
#elif SIZEOF_VOID_P == SIZEOF_UNSIGNED_LONG
#define Number(a)		(void *)((u_long) a)
typedef u_long pointertype;
#else
ERROR: Cannot compile without knowing the size of a pointer.  See xcircuit.h.
#endif

/*----------------------------------------------------------------------*/
/* Basic element types 							*/
/*									*/
/* These values determine how a genericptr should be cast into one of	*/
/* labelptr, polyptr, etc.  To query the element type, use the macros	*/
/* ELEMENTTYPE(), IS_LABEL(), IS_POLYGON(), etc.  These macros mask the	*/
/* bit field.  Note that an element marked with REMOVE_TAG will not be	*/
/* recognized as any valid element, but otherwise, querying the type is	*/
/* transparent to other bit settings (such as NETLIST_INVALID).		*/
/*----------------------------------------------------------------------*/

/* Single-bit flags */
#define	OBJINST		1
#define LABEL		2
#define POLYGON		4
#define ARC		8
#define SPLINE  	16
#define PATH		32

#define REMOVE_TAG	64	/* element to be removed from netlist	*/
#define NETLIST_INVALID 128	/* this element invalidates the netlist	*/
#define SELECT_HIDE	256	/* this element cannot be selected	*/
#define DRAW_HIDE	512	/* this element is not drawn.		*/

/* Bit fields */
#define ALL_TYPES 	(OBJINST | LABEL | POLYGON | ARC | SPLINE | PATH)
#define VALID_TYPES 	(REMOVE_TAG | ALL_TYPES)

/*----------------------------------------------------------------------*/
/* Definition shortcuts 						*/
/*----------------------------------------------------------------------*/

#define XtnSetArg(a,b)  	XtSetArg(wargs[n], a, b); n++
#define abs(a)			((a) < 0 ? -(a) : (a))
#define sign(a)			((a) <= 0 ? -1 : 1)
#define max(a,b)		((a) < (b) ? (b) : (a))
#define min(a,b)		((a) < (b) ? (a) : (b))

/*----------------------------------------------------------------------*/
/* Lengthier define constructs						*/
/*----------------------------------------------------------------------*/

/* Names used for convenience throughout the source code */

#define topobject	areastruct.topinstance->thisobject

#define PLIST_INCR(a) \
	(a)->plist = (genericptr *) realloc ((a)->plist, \
	((a)->parts + 1) * sizeof(genericptr))
#define SELECTTYPE(a)   ((*(topobject->plist + *(a)))->type & ALL_TYPES)
#define SELTOCOLOR(a)	(*(topobject->plist + *(a)))->color
#define GSELTOCOLOR(b, a) (*((b)->plist + *(a)))->color
#define ENDPART		topobject->plist + topobject->parts
#define EDITPART	topobject->plist + areastruct.editpart

/* Type checks (argument "a" is type genericptr) */

#define ELEMENTTYPE(a)	((a)->type & VALID_TYPES)

#define IS_POLYGON(a)   (ELEMENTTYPE(a) == POLYGON)
#define IS_LABEL(a)     (ELEMENTTYPE(a) == LABEL)
#define IS_OBJINST(a)   (ELEMENTTYPE(a) == OBJINST)
#define IS_ARC(a)       (ELEMENTTYPE(a) == ARC)
#define IS_SPLINE(a)    (ELEMENTTYPE(a) == SPLINE)
#define IS_PATH(a)      (ELEMENTTYPE(a) == PATH)

/* Conversions from generic to specific types */
/* specifically, from type (genericptr *) to type (polyptr), etc. */

#define TOPOLY(a)	(*((polyptr *)(a)))
#define TOLABEL(a)	(*((labelptr *)(a)))
#define TOOBJINST(a)	(*((objinstptr *)(a)))
#define TOARC(a)	(*((arcptr *)(a)))
#define TOSPLINE(a)	(*((splineptr *)(a))) 
#define TOPATH(a)	(*((pathptr *)(a)))

/* conversions from a selection to a specific type */

#define SELTOPOLY(a)	TOPOLY(topobject->plist + (*(a)))
#define SELTOLABEL(a)	TOLABEL(topobject->plist + (*(a)))
#define SELTOOBJINST(a)	TOOBJINST(topobject->plist + (*(a)))
#define SELTOARC(a)	TOARC(topobject->plist + (*(a)))
#define SELTOSPLINE(a)	TOSPLINE(topobject->plist + (*(a)))
#define SELTOPATH(a)	TOPATH(topobject->plist + (*(a)))
#define SELTOGENERIC(a) (*(topobject->plist + (*(a))))

/* creation of new elements */

#define NEW_POLY(a,b) \
	PLIST_INCR(b); \
	a = (polyptr *)b->plist + b->parts; \
	*a = (polyptr) malloc(sizeof(polygon)); \
	(*a)->type = POLYGON
#define NEW_LABEL(a,b) \
	PLIST_INCR(b); \
	a = (labelptr *)b->plist + b->parts; \
	*a = (labelptr) malloc(sizeof(label)); \
	(*a)->type = LABEL
#define NEW_OBJINST(a,b) \
	PLIST_INCR(b); \
	a = (objinstptr *)b->plist + b->parts; \
	*a = (objinstptr) malloc(sizeof(objinst)); \
	(*a)->type = OBJINST
#define NEW_ARC(a,b) \
	PLIST_INCR(b); \
	a = (arcptr *)b->plist + b->parts; \
	*a = (arcptr) malloc(sizeof(arc)); \
	(*a)->type = ARC
#define NEW_SPLINE(a,b) \
	PLIST_INCR(b); \
	a = (splineptr *)b->plist + b->parts; \
	*a = (splineptr) malloc(sizeof(spline)); \
	(*a)->type = SPLINE
#define NEW_PATH(a,b) \
	PLIST_INCR(b); \
	a = (pathptr *)b->plist + b->parts; \
	*a = (pathptr) malloc(sizeof(path)); \
	(*a)->type = PATH

/*----------------------------------------------------------------------*/
/* Undo mechanism definitions						*/
/*----------------------------------------------------------------------*/

enum UNDO_MODES {UNDO_DONE = 0, UNDO_MORE};

/*----------------------------------------------------------------------*/
/* selection from top-level object 					*/
/*----------------------------------------------------------------------*/

#define select_element(a) genselectelement(a, UNDO_MORE, topobject,\
	areastruct.topinstance)
#define select_add_element(a) genselectelement(a, UNDO_DONE, topobject,\
	areastruct.topinstance)
#define easydraw(a, b)	 geneasydraw(a, b, topobject, areastruct.topinstance)

/*----------------------------------------------------------------------*/

typedef struct {
   float x, y;
} XfPoint;

typedef struct {
   long x, y;
} XlPoint;

typedef struct {
   short width, ascent, descent, base;
} TextExtents;

/*----------------------------------------------------------------------*/
/* Implementation-specific definitions 					*/
/*----------------------------------------------------------------------*/

#define LIBS	    5 /* initial number of library pages 		*/
#define PAGES      10 /* default number of top-level pages 		*/
#define SCALEFAC  1.5 /* zoom in/out scaling multiplier 		*/
#define SUBSCALE 0.67 /* ratio of subscript size to normal script size 	*/
#define SBARSIZE   13 /* Pixel size of the scrollbar 			*/
#define RSTEPS     72 /* Number of points defining a circle approx.	*/
#define SPLINESEGS 20 /* Number of points per spline approximation 	*/
#define DELBUFSIZE 10 /* Number of delete events to save for undeleting */
#define MINAUTOSCALE 0.75 /* Won't automatically scale closer than this */
#define MAXCHANGES 20 /* Number of changes to induce a temp file save	*/
#define STIPPLES    8 /* Number of predefined stipple patterns		*/
#define PADSPACE   10 /* Spacing of pinlabels from their origins	*/

#ifdef HAVE_XPM
#define TBBORDER   1  /* border around toolbar buttons */
#endif

#define TOPLEVEL	0
#define SINGLE		1

#define INTSEGS		(SPLINESEGS - 2)
#define LASTSEG		(SPLINESEGS - 3)

#define FONTHEIGHT(y)	 (y->ascent + y->descent + 6) 
#define ROWHEIGHT	 FONTHEIGHT(appdata.xcfont)
#define FILECHARASCENT   (appdata.filefont->ascent)
#define FILECHARHEIGHT   (FILECHARASCENT + appdata.filefont->descent)
#define LISTHEIGHT	 200
#define TEXTHEIGHT	 28 /* Height of xcircuit vectored font at nominal size */
#define BASELINE	 40 /* Height of baseline */
#define DEFAULTGRIDSPACE 32
#define DEFAULTSNAPSPACE 16

/*----------------------------------------------------------------------*/

#define RADFAC 0.0174532925199   /* pi / 180 */
#define INVRFAC 57.295779       /* 180 / pi */

/*----------------------------------------------------------------------*/

#define INCHSCALE 0.375     /* Scale of .25 inches to PostScript units */
#define CMSCALE 0.35433071  /* Scale of .5 cm to PostScript units */
#define IN_CM_CONVERT 28.3464567	/* 72 (in) / 2.54 (cm/in) */

/*----------------------------------------------------------------------*/
/* Event mode definitions (state of drawing area)			*/
/*----------------------------------------------------------------------*/

enum editmode {NORMAL_MODE = 0, UNDO_MODE,
PENDING_MODE, PRESS_MODE, DELETE_MODE, COPY_MODE, COPY2_MODE, ROTATE_MODE,
PUSH_MODE, EDIT_MODE, SELAREA_MODE, SELAREA2_MODE, DESEL_MODE, PAN_MODE,
CATPAN_MODE, CATALOG_MODE, CATTEXT_MODE, FONTCAT_MODE, FONTCAT2_MODE,
TEXT1_MODE, TEXT2_MODE, TEXT3_MODE, WIRE_MODE, POLY_MODE, BOX0_MODE,
BOX_MODE, EBOX_MODE, ARC0_MODE, ARC_MODE, EARC_MODE, SPLINE0_MODE,
SPLINE_MODE, ESPLINE_MODE, EPATH_MODE, LPARAM_MODE, IPARAM_MODE,
ULPARAM_MODE, UIPARAM_MODE, CONNECT_MODE, ASSOC_MODE};

/*----------------------------------------------------------------------*/
/* File loading modes							*/
/*----------------------------------------------------------------------*/

enum loadmodes {IMPORT = 1, PSBKGROUND, SCRIPT, RECOVER,
#ifdef ASG
	IMPORTSPICE,
#endif
	LOAD_MODES
};

/*----------------------------------------------------------------------*/
/* Text justification styles and other parameters (bitmask)		*/
/*----------------------------------------------------------------------*/

#define NOTLEFT		1
#define RIGHT		2
#define NOTBOTTOM	4
#define TOP		8
#define FLIPINV		16	/* 1 if text is flip-invariant		*/
#define PINVISIBLE	32	/* 1 if pin visible outside of object	*/
#define PINNOOFFSET	64	/* 0 if pin label offset from position	*/
#define LATEXLABEL	128

#define RLJUSTFIELD	3	/* right-left justification bit field	*/
#define TBJUSTFIELD	12	/* top-bottom justification bit field	*/
#define NONJUSTFIELD	240	/* everything but justification fields	*/

/*----------------------------------------------------------------------*/
/* Text string part: types						*/
/*----------------------------------------------------------------------*/

#define TEXT_STRING	 0  /* data is a text string 			*/
#define SUBSCRIPT	 1  /* start subscript; no data			*/
#define SUPERSCRIPT	 2  /* start superscript; no data		*/
#define NORMALSCRIPT	 3  /* stop super-/subscript; no data		*/
#define UNDERLINE	 4  /* start underline; no data			*/
#define OVERLINE	 5  /* start overline; no data			*/
#define NOLINE		 6  /* stop over-/underline; no data		*/
#define TABSTOP	 	 7  /* insert tab stop position			*/
#define TABFORWARD 	 8  /* insert tab stop position			*/
#define TABBACKWARD 	 9  /* insert tab stop position			*/
#define HALFSPACE	10  /* insert half-space; no data		*/
#define QTRSPACE	11  /* insert quarter space; no data		*/
#define RETURN		12  /* carriage-return character; no data	*/
#define FONT_NAME       13  /* inline font designator; data = font name */
#define FONT_SCALE	14  /* font scale change; data = scale		*/
#define FONT_COLOR	15  /* font color change; data = color		*/
#define KERN		16  /* set new kern values; data = kern x, y	*/
#define PARAM_START	17  /* bounds a parameter; data = param key	*/
#define PARAM_END	18  /* bounds a parameter; no data 		*/

#define SPECIAL		63  /* used only when called from menu		*/
#define NULL_TYPE	255 /* used as a placeholder			*/

/*----------------------------------------------------------------------*/
/* Reset modes								*/
/*----------------------------------------------------------------------*/

#define SAVE		1
#define DESTROY		2

/*----------------------------------------------------------------------*/
/* Coordinate display types						*/
/*----------------------------------------------------------------------*/

#define DEC_INCH	0
#define FRAC_INCH	1
#define CM		2

/*----------------------------------------------------------------------*/
/* Library types							*/
/*----------------------------------------------------------------------*/

#define FONTLIB		0
#define PAGELIB		1
#define LIBLIB		2
#define LIBRARY		3
#define USERLIB		(xobjs.numlibs + LIBRARY - 1)

/*----------------------------------------------------------------------*/
/* Box styles								*/
/*----------------------------------------------------------------------*/

#define NORMAL 0
#define UNCLOSED 1
#define DASHED 2
#define DOTTED 4
#define NOBORDER 8
#define FILLED 16
#define STIP0 32
#define STIP1 64
#define STIP2 128
#define FILLSOLID 224  /* = 32 + 64 + 128 */
#define OPAQUE 256
#define BBOX 512

/*----------------------------------------------------------------------*/
/* Box edit styles							*/
/*----------------------------------------------------------------------*/

#define MANHATTAN 1
#define RHOMBOIDX 2
#define RHOMBOIDY 4
#define RHOMBOIDA 8

#define NONE  0
#define LASTX 1
#define NEXTX 2
#define LASTY 4
#define NEXTY 8

/*----------------------------------------------------------------------*/
/* Arc creation and edit styles						*/
/*----------------------------------------------------------------------*/

#define CENTER 1
#define RADIAL 2

/*----------------------------------------------------------------------*/
/* Delete/undelete draw-mode styles					*/
/*----------------------------------------------------------------------*/

#define ERASE 1
#define DRAW  1

/*----------------------------------------------------------------------*/
/* Schematic object types and pin label types	   			*/
/*----------------------------------------------------------------------*/

#define PRIMARY 0		/* Primary (master) schematic page */
#define SECONDARY 1		/* Secondary (slave) schematic page */
#define TRIVIAL 2		/* Symbol as non-schematic element */
#define SYMBOL 3		/* Symbol associated with a schematic */
#define FUNDAMENTAL 4		/* Standalone symbol */

#define LOCAL 1
#define GLOBAL 2
#define INFO 3

#define HIERARCHY_LIMIT 256	/* Stop if recursion goes this deep */

/*----------------------------------------------------------------------*/
/* Save types.	This list incorporates "ALL_PAGES", below.		*/
/*----------------------------------------------------------------------*/

#define CURRENT_PAGE	0	/* Current page + all associated pages	*/
#define NO_SUBCIRCUITS	1	/* Current page w/o subcircuit pages	*/

/*----------------------------------------------------------------------*/
/* Modes used when ennumerating page totals.				*/
/*----------------------------------------------------------------------*/

#define INDEPENDENT	0
#define DEPENDENT	1
#define TOTAL_PAGES	2
#define PAGE_DEPEND	3
#define ALL_PAGES	4

/*----------------------------------------------------------------------*/
/* Color scheme styles (other than NORMAL)				*/
/*----------------------------------------------------------------------*/

#define INVERSE		1

/*----------------------------------------------------------------------*/
/* Cursor definitions 							*/
/*----------------------------------------------------------------------*/

#define NUM_CURSORS	10

#define ARROW 		appcursors[0]
#define CROSS 		appcursors[1]
#define SCISSORS 	appcursors[2]
#define COPYCURSOR	appcursors[3]
#define ROTATECURSOR    appcursors[4]
#define EDCURSOR	appcursors[5]
#define TEXTPTR 	appcursors[6]
#define CIRCLE		appcursors[7]
#define QUESTION	appcursors[8]
#define WAITFOR		appcursors[9]

/*----------------------------------------------------------------------*/
/* selection-mechanism structures					*/
/*----------------------------------------------------------------------*/

typedef XPoint* pointlist;
typedef XfPoint* fpointlist;

/*----------------------------------------------------------------------*/
/* Allowed parameterization types					*/
/*----------------------------------------------------------------------*/

#define P_NUMERIC	0	/* uncommitted numeric parameter */
#define P_SUBSTRING	1
#define P_POSITION_X	2
#define P_POSITION_Y	3
#define P_STYLE		4
#define P_JUSTIFY	5
#define P_ANGLE1	6
#define P_ANGLE2	7
#define P_RADIUS	8
#define P_MINOR_AXIS	9
#define P_ROTATION	10
#define P_SCALE		11
#define P_LINEWIDTH	12
#define P_COLOR		13
#define P_EXPRESSION	14
#define P_POSITION	15	/* mode only, not a real parameter */

/*----------------------------------------------------------------------*/
/* Labels are constructed of strings and executables 			*/
/*----------------------------------------------------------------------*/

typedef struct _stringpart *stringptr;

typedef struct _stringpart {
   stringptr	nextpart;
   u_char	type;
   union {
     u_char	*string;
     int	color;
     int	font;
     float	scale;
     short	kern[2];
   }		data;
} stringpart;

/*----------------------------------------------------------------------*/
/* structures of all main elements which can be displayed & manipulated	*/
/*----------------------------------------------------------------------*/

/*----------------------------------------------------------------------*/
/* Object & object instance parameter structure				*/
/* (Add types as necessary)						*/
/*----------------------------------------------------------------------*/

enum paramtypes {XC_INT = 0, XC_FLOAT, XC_STRING, XC_EXPR};

/* Object parameters: general key:value parameter model */
/* Note that this really should be a hash table, not a linked list. . . */

typedef struct _oparam *oparamptr;

typedef struct _oparam {
   char *	key;		/* name of the parameter */
   u_char	type;		/* type is from paramtypes list above */
   u_char	which;		/* what the parameter represents (P_*) */
   union {
      stringpart *string;	/* xcircuit label type */
      char	 *expr;		/* TCL (string) expression */
      int	  ivalue;	/* also covers type short int by typecasting */
      float	  fvalue;
   } parameter;			/* default or substitution value */
   oparamptr	next;		/* next parameter in linked list */
} oparam;

/* Element parameters: reference back to the object's parameters */
/* These parameters are forward-substituted when descending into */
/* an object instance.						 */
/* Note that this really should be a hash table, not a linked list. . . */

typedef struct _eparam *eparamptr;

typedef struct _eparam {
   char *	key;	    /* name of the parameter */
   union {
      int	pointno;    /* point number in point array, for polygons */
      char	*refkey;    /* parameter reference key, for instances */
   } pdata;
   eparamptr	next;	    /* next parameter in linked list */
} eparam;

/*----------------------------------------------------------------------*/
/* Generic element type	is a superset of all elements.			*/	
/*----------------------------------------------------------------------*/

typedef struct {
   u_short	type;		/* type is LABEL, POLYGON, etc., from below */
   int		color;
   eparamptr	passed;
} generic, *genericptr;		/* (convenience function for retypecasting) */

/*----------------------------------------------------------------------*/
/* Bounding box								*/
/*----------------------------------------------------------------------*/

typedef struct {
   XPoint	lowerleft;
   Dimension	width, height;
} BBox;

/*----------------------------------------------------------------------*/
/* Object instance type							*/
/*----------------------------------------------------------------------*/

typedef struct _xcobject *objectptr;

typedef struct {
   u_short	type;
   int		color;
   eparamptr	passed;		/* numerical parameters passed from above */
   XPoint	position;
   short	rotation;
   float	scale;
   objectptr	thisobject;
   oparamptr	params;		/* parameter substitutions for this instance */
   BBox		bbox;		/* per-instance bounding box information */
   BBox		*schembbox;	/* Extra bounding box for pin labels */
} objinst, *objinstptr;

/* Linked-list for objects */

typedef struct _objlist *objlistptr;

typedef struct _objlist {
   objectptr	thisobject;
   objlistptr	next;
} objlist;

/* Linked-list for object instances */

typedef struct _pushlist *pushlistptr;

typedef struct _pushlist {
   objinstptr	thisinst;
   pushlistptr	next;
} pushlist;

/* Same as above, but for the list of instances in a library, so it	*/
/* needs an additional record showing whether or not the instance is	*/
/* "virtual" (not the primary library instance of the object)		*/

typedef struct _liblist *liblistptr;

typedef struct _liblist {
   objinstptr	thisinst;
   u_char	virtual;
   liblistptr	next;
} liblist;

/*----------------------------------------------------------------------*/
/* Label								*/
/*----------------------------------------------------------------------*/

typedef struct {
   u_short	type;
   int		color;
   eparamptr	passed;		/* numerical parameters passed from above */
   XPoint	position;
   short	rotation;
   float	scale;
   short	justify;
   u_char	pin;
   stringpart	*string;
} label, *labelptr;

/*----------------------------------------------------------------------*/
/* Polygon								*/
/*----------------------------------------------------------------------*/

typedef struct {
   u_short	type;
   int		color;
   eparamptr	passed;		/* numerical parameters passed from above */
   u_short	style;
   float	width;
   short	number;
   pointlist	points;
} polygon, *polyptr;

/*----------------------------------------------------------------------*/
/* Bezier Curve								*/
/*----------------------------------------------------------------------*/

typedef struct {
   u_short	type;
   int		color;
   eparamptr	passed;		/* numerical parameters passed from above */
   u_short	style;
   float	width;
   XPoint	ctrl[4];
   /* the following are for rendering only */
   XfPoint	points[INTSEGS];
} spline, *splineptr;

/*----------------------------------------------------------------------*/
/* Arc									*/
/*----------------------------------------------------------------------*/

typedef struct {
   u_short	type;
   int		color;
   eparamptr	passed;		/* numerical parameters passed from above */
   u_short	style;
   float	width;
   short	radius; 	/* x-axis radius */
   short	yaxis;		/* y-axis radius */
   float	angle1;
   float	angle2;
   XPoint	position;
   /* the following are for rendering only */
   short	number;
   XfPoint	points[RSTEPS + 1];
} arc, *arcptr;

/*----------------------------------------------------------------------*/
/* Path									*/
/*----------------------------------------------------------------------*/

typedef struct {
   u_short	type;
   int		color;
   eparamptr	passed;		/* numerical parameters passed from above */
   u_short	style;
   float	width;
   short	parts;
   genericptr	*plist;		/* to be retypecast to polygon, arc, or spline */
} path, *pathptr;

/*----------------------------------------------------------------------*/
/* Netlist structures for schematic capture				*/
/*----------------------------------------------------------------------*/

/* Structure to hold net and subnet IDs for a bus */

typedef struct {
   int netid;
   int subnetid;
} buslist;

/* Structure mimicking the top part of a Polylist or Labellist	*/
/* when we just want the netlist information and don't care	*/
/* which one we're looking at.					*/

typedef struct {
   union {
      int id;
      buslist *list;
   } net;
   int subnets;
} Genericlist; 

/* Linked polygon list */

typedef struct _Polylist *PolylistPtr;
typedef struct _Polylist
{
   union {
      int  id;		/* A single net ID, if subnets == 0	*/
      buslist *list;	/* List of net and subnet IDs for a bus	*/
   } net;
   int subnets;		/* Number of subnets; 0 if no subnets	*/
   objectptr cschem;	/* Schematic containing the polygon	*/
   polyptr poly;
   PolylistPtr next;	/* Next polygon in the linked list	*/
} Polylist;

/* Linked label list */

typedef struct _Labellist *LabellistPtr;
typedef struct _Labellist
{
   union {
      int  id;		/* A single net ID, if subnets == 0	*/
      buslist *list;	/* List of net and subnet IDs for a bus	*/
   } net;
   int subnets;		/* Number of subnets; 0 if no subnets	*/
   objectptr cschem;	/* Schematic containing the label	*/
   objinstptr cinst;	/* Specific label instance, if applicable */
   labelptr label;
   LabellistPtr next;
} Labellist;

/* List of object's networks by (flattened) name */

typedef struct _Netname *NetnamePtr;
typedef struct _Netname
{
   int netid;
   stringpart *localpin;
   NetnamePtr next;
} Netname;

/* List of object's I/O ports */

typedef struct _Portlist *PortlistPtr;
typedef struct _Portlist
{
   int portid;
   int netid;
   PortlistPtr next;
} Portlist;

/* List of calls to instances of objects */
/* or subcircuit objects.		 */

typedef struct _Calllist *CalllistPtr;
typedef struct _Calllist
{
   objectptr   cschem;		/* Schematic containing the instance called */
   objinstptr  callinst;	/* Instance called */
   objectptr   callobj;		/* Object of instance called */
   int         devindex;	/* if non-zero, index of device in netlist */
   PortlistPtr ports;
   CalllistPtr next;
} Calllist;

/* PCB netlist structures */

struct Pnet {
   int numnets;
   int *netidx;
   struct Pnet *next;
};

struct Pstr {
   stringpart *string;
   struct Pstr *next;
};

struct Ptab {
   objectptr cschem;
   struct Pnet *nets;
   struct Pstr *pins;
   struct Ptab *next;
};

/*----------------------------------------------------------------------*/
/* Information needed to highlight a net				*/
/*----------------------------------------------------------------------*/

typedef struct {
   Genericlist	*netlist;
   objinstptr	thisinst;
} Highlight;

/*----------------------------------------------------------------------*/
/* Main object structure						*/
/*----------------------------------------------------------------------*/

typedef struct _xcobject {
   char		name[80];
   u_short	changes;	/* Number of unsaved changes to object */
   Boolean	hidden;
   float	viewscale;
   XPoint	pcorner;	/* position relative to window */
   BBox		bbox;		/* bounding box information (excluding */
				/* parameterized elements) */
   short	parts;
   genericptr	*plist;	 	/* to be retypecast to label, polygon, etc. */
   oparamptr	params;		/* list of parameters, with default values */
   
   Highlight	highlight;	/* net to be highlighted on redraw */
   u_char	schemtype;
   objectptr	symschem;	/* schematic page support */
   char		*devname;	/* if non-null, name of device in netlist */
   Boolean	valid;		/* Is current netlist valid? */
   Boolean	traversed;	/* Flag to indicate object was processed */
   LabellistPtr	labels;		/* Netlist pins	 */
   PolylistPtr	polygons;	/* Netlist wires */
   PortlistPtr  ports;		/* Netlist ports */
   CalllistPtr  calls;		/* Netlist subcircuits and connections */
   NetnamePtr   netnames;	/* Local names for flattening */
				/* (this probably shouldn't be here. . .) */
} object;

/*----------------------------------------------------------------------*/
/* Transformation matrices						*/
/* Works like this (see also PostScript reference manual):		*/
/*   [x' y' 1] = [x y 1] * | a  d  0 |					*/
/*			   | b  e  0 |					*/
/*			   | c  f  1 |					*/
/*----------------------------------------------------------------------*/

typedef struct _matrix *Matrixptr;

typedef struct _matrix {
   float a, b, c, d, e, f;
   Matrixptr nextmatrix;
} Matrix;

/*----------------------------------------------------------------------*/
/* Some convenience functions for matrix manipulation			*/
/*----------------------------------------------------------------------*/

#define DCTM  areastruct.MatStack

/*----------------------------------------------------------------------*/
/* button tap/press definitions 					*/
/*----------------------------------------------------------------------*/

#define PRESSTIME	150	/* milliseconds of push to be a "press" */

/*----------------------------------------------------------------------*/
/* object name alias structures						*/
/*----------------------------------------------------------------------*/

typedef struct _stringlist *slistptr;

typedef struct _stringlist {
   char *alias;
   slistptr next;
} stringlist;

typedef struct _alias *aliasptr;

typedef struct _alias {
   objectptr baseobj;       /* pointer to object (actual name) */
   slistptr aliases;    /* linked list of alias names */
   aliasptr next;
} alias;    

/*----------------------------------------------------------------------*/
/* To facilitate compiling the Tcl/Tk version, we make some convenient	*/
/* definitions for types "xc..." and "Xc..." which can be mapped both	*/
/* to X and Xt or to Tk functions and types.				*/
/*----------------------------------------------------------------------*/

#ifdef TCL_WRAPPER

#define xcWidget 			Tk_Window
#define xcWidgetList 			Tk_Window *
#define xcAddEventHandler(a,b,c,d,e) 	Tk_CreateEventHandler(a,b,d,e)
#define xcRemoveEventHandler(a,b,c,d,e) Tk_DeleteEventHandler(a,b,d,e)
#define xcEventHandler			Tk_EventProc *
#define xcWindow			Tk_WindowId
#define xcIsRealized			Tk_IsMapped  /* not sure this is right */
#define xcScreen			Tk_Screen
#define xcParent			Tk_Parent
#define xcDispatchEvent(a)		Tk_HandleEvent(a)
#define xcAddTimeOut(a, b, c, d)	Tcl_CreateTimerHandler(b, c, d)
#define xcRemoveTimeOut			Tcl_DeleteTimerHandler
#define xcTimeOutProc			Tcl_TimerProc *
#define xcIntervalId			Tcl_TimerToken

#else

#define xcWidget 			Widget
#define xcWidgetList 			WidgetList
#define xcAddEventHandler 		XtAddEventHandler
#define xcRemoveEventHandler 		XtRemoveEventHandler
#define xcEventHandler			XtEventHandler
#define xcWindow			XtWindow
#define xcIsRealized			XtIsRealized
#define xcScreen			XtScreen
#define xcParent			XtParent
#define xcDispatchEvent(a)		XtDispatchEvent(a)
#define xcAddTimeOut			XtAppAddTimeOut
#define xcRemoveTimeOut			XtRemoveTimeOut
#define xcTimeOutProc			XtTimerCallbackProc
#define xcIntervalId			XtIntervalId

#endif

/*----------------------------------------------------------------------*/
/* structures for managing the popup prompt widgets 			*/
/*----------------------------------------------------------------------*/

typedef struct {
   xcWidget	button;
   int		foreground;
   void		(*buttoncall)();
   void		*dataptr;
} buttonsave;

typedef struct {
   xcWidget	popup;		/* Popup widget		*/
   xcWidget	textw;		/* Text entry widget	*/
   xcWidget	filew;		/* File list window 	*/
   xcWidget	scroll;		/* Scrollbar widget	*/
   void		(*setvalue)();	/* Callback function	*/
   buttonsave	*buttonptr;	/* Button widget calling popup	     */
   char		*filter;	/* Extension filter for highlighting */
				/*  files. NULL for no file window.  */
				/*  NULL-string for no highlights.   */
} popupstruct;

typedef struct {
   xcWidget	textw;
   xcWidget	buttonw;
   void		(*setvalue)();
   void		*dataptr;
} propstruct;

typedef struct {
   char		*filename;
   int		filetype;
} fileliststruct;

enum {DIRECTORY = 0, MATCH, NONMATCH};	/* file types */

/*----------------------------------------------------------------------*/
/* Initial Resource Management						*/
/*----------------------------------------------------------------------*/

typedef struct {
   /* schematic layout colors */
   Pixel	globalcolor, localcolor, infocolor, ratsnestcolor;

   /* non-schematic layout color(s) */
   Pixel	bboxpix;

   /* color scheme 1 */
   Pixel	fg, bg;
   Pixel	gridpix, snappix, selectpix, axespix;
   Pixel	buttonpix, querypix, filterpix;
   Pixel	auxpix, barpix, parampix;

   /* color scheme 2 */

   Pixel	fg2, bg2;
   Pixel	gridpix2, snappix2, selectpix2, axespix2;
   Pixel	buttonpix2, querypix2, filterpix2;
   Pixel	auxpix2, barpix2, parampix2;

   int		width, height, timeout;
   XFontStruct	*helpfont, *filefont;

#ifndef TCL_WRAPPER
   XFontStruct	*xcfont, *textfont, *titlefont;
#endif

} ApplicationData, *ApplicationDataPtr;

/*----------------------------------------------------------------------*/
/* Macros for GC color and function handling				*/
/*----------------------------------------------------------------------*/

#define XTopSetForeground(a) if (a == DEFAULTCOLOR) XSetForeground(dpy, \
	areastruct.gc, FOREGROUND); else XSetForeground(dpy, areastruct.gc, a)

#define XSetXORFg(a,b) if (a == DEFAULTCOLOR) XSetForeground(dpy, \
	areastruct.gc, FOREGROUND ^ b); else XSetForeground(dpy, areastruct.gc,\
	a ^ b)

#define XcSetFunction(z) XSetFunction(dpy, areastruct.gc, z); \
	areastruct.gctype = z

#define XcSetForeground(z) XTopSetForeground(z); areastruct.gccolor = \
	((z) == DEFAULTCOLOR) ? FOREGROUND : (z)

#define XcSetXORFg(y,z) XSetXORFg(y,z); areastruct.gccolor = \
	((y) == DEFAULTCOLOR) ? (FOREGROUND ^ z) : (y ^ z)

/*----------------------------------------------------------------------*/
/* Structure for maintaining list of colors				*/
/*----------------------------------------------------------------------*/

typedef struct {
   xcWidget	cbutton;
   XColor	color;
} colorindex;

/*----------------------------------------------------------------------*/
/* Font information structure						*/
/*----------------------------------------------------------------------*/
/* Flags:   bit  description						*/
/* 	    0    bold = 1,  normal = 0					*/
/*	    1    italic = 1, normal = 0					*/
/*	    2    <reserved, possibly for narrow font type>		*/
/*	    3    drawn = 1,  PostScript = 0				*/
/* 	    4	 <reserved, possibly for LaTeX font type>		*/
/*	    5    special encoding = 1, Standard Encoding = 0		*/
/*	    6	 ISOLatin1 = 2, ISOLatin2 = 3				*/
/*	    7    <reserved for other encoding schemes>			*/
/*----------------------------------------------------------------------*/

typedef struct {
   char *psname;
   char *family;
   float scale;
   u_short flags;
   objectptr *encoding;
} fontinfo;

/*----------------------------------------------------------------------*/

typedef struct {
   char *name;
   BBox bbox;
} psbkground;

/*----------------------------------------------------------------------*/
/* Key macro information						*/
/*----------------------------------------------------------------------*/

typedef struct _keybinding *keybindingptr;

typedef struct _keybinding {
   int keywstate;
   int function;
   short value;
   keybindingptr nextbinding;
} keybinding;

/*----------------------------------------------------------------------*/
/* Enumeration of functions available for binding to keys/buttons	*/
/*----------------------------------------------------------------------*/

enum {
   XCF_ENDDATA = -2, XCF_SPACER,
   XCF_Page, XCF_Justify, XCF_Superscript, XCF_Subscript, XCF_Normalscript,
   XCF_Nextfont, XCF_Boldfont, XCF_Italicfont, XCF_Normalfont, XCF_Underline,
   XCF_Overline, XCF_ISO_Encoding, XCF_Halfspace, XCF_Quarterspace,
   XCF_Special, XCF_TabStop, XCF_TabForward, XCF_TabBackward,
   XCF_Text_Return, XCF_Text_Delete, XCF_Text_Right, XCF_Text_Left,
   XCF_Text_Up, XCF_Text_Down, XCF_Text_Split,
   XCF_Text_Home, XCF_Text_End, XCF_Linebreak, XCF_Parameter,
   XCF_Edit_Param,XCF_Edit_Break, XCF_Edit_Delete, XCF_Edit_Insert,
   XCF_Edit_Append, XCF_Edit_Next, XCF_Attach,
   XCF_Next_Library, XCF_Library_Directory,
   XCF_Library_Move, XCF_Library_Copy, XCF_Library_Edit, XCF_Library_Delete,
   XCF_Library_Duplicate, XCF_Library_Hide, XCF_Library_Virtual,
   XCF_Page_Directory, XCF_Library_Pop, XCF_Virtual,
   XCF_Help, XCF_Redraw, XCF_View, XCF_Zoom_In, XCF_Zoom_Out, XCF_Pan,
   XCF_Double_Snap, XCF_Halve_Snap, XCF_Pan_Left, XCF_Pan_Right, XCF_Pan_Up,
   XCF_Pan_Down, XCF_Write, XCF_Rotate, XCF_Flip_X, XCF_Flip_Y, XCF_Snap,
   XCF_SnapTo, XCF_Pop, XCF_Push, XCF_Delete, XCF_Select, XCF_Box, XCF_Arc,
   XCF_Text, XCF_Exchange, XCF_Copy, XCF_Move, XCF_Join, XCF_Unjoin, XCF_Spline,
   XCF_Edit, XCF_Undo, XCF_Redo, XCF_Select_Save, XCF_Unselect, XCF_Dashed,
   XCF_Dotted, XCF_Solid, XCF_Prompt, XCF_Dot, XCF_Wire, XCF_Start,
   XCF_Finish, XCF_Cancel, XCF_Nothing, XCF_Exit,
   XCF_Netlist, XCF_Swap, XCF_Pin_Label, XCF_Pin_Global, XCF_Info_Label,
   XCF_Connectivity, XCF_Sim, XCF_SPICE, XCF_PCB, XCF_SPICEflat,
   NUM_FUNCTIONS
};

/*----------------------------------------------------------------------*/
/* Per-drawing-page parameters						*/
/*----------------------------------------------------------------------*/

typedef struct {
   /* per-drawing-page parameters */
   objinstptr	pageinst;
   char		*filename;	/* file to save as */
   psbkground	background;	/* background rendered file info */
   float	wirewidth;
   float	outscale;
   float	gridspace;
   float	snapspace;
   short	orient;
   short	pmode;
   short	coordstyle;
   XPoint	drawingscale;
   XPoint	pagesize;	/* size of page to print on */
} Pagedata;

/*----------------------------------------------------------------------*/
/* The main globally-accessible data structure.  This structure holds	*/
/* all the critical data needed by the drawing window 			*/
/*----------------------------------------------------------------------*/

typedef struct {

   /* widgets and X11 parameters */
   xcWidget	area;
   xcWidget	scrollbarh, scrollbarv;
   Window	areawin;
   GC 		gc;
   int		gccolor, gctype;
   xcIntervalId time_id;

   /* global page parameters */
   short	width, height;
   short	page;
   float	*vscale;	/* pointer to proper scale */
   XPoint	*pcorner;	/* pointer to page position */

   /* global option defaults */
   float	textscale;
   float	linewidth;
   float	zoomfactor;
   short	psfont;
   short	justify;
   u_short	style;
   short	filter;		/* selection filter */
   int		color;
   Boolean	manhatn;
   Boolean	boxedit;
   Boolean	snapto;
   Boolean	bboxon;
   Boolean	center;
   Boolean	gridon;
   Boolean	axeson;
   Boolean	invert;
   Boolean	mapped;		/* indicates if window is drawable */
   Boolean	filefilter;	/* Is the file list filtered? */
   char		buschar;	/* Character indicating vector notation */
   Boolean	editinplace;
   Boolean	schemon;
   Boolean	pinpointon;
#ifdef HAVE_XPM
   Boolean	toolbar_on;
#endif

   /* buffers and associated variables */
   XPoint	save, origin;
   short	selects;
   short	*selectlist;
   short	lastlibrary;
   objinstptr	topinstance;
   objectptr	editstack;
   Matrixptr	MatStack;
   pushlistptr	stack;
   short	editcycle;
   short	editpart, editsubpart;
   char		*lastbackground;
} Clientdata;

/* Record for undo function */ 

typedef struct _undostack *Undoptr;

typedef struct _undostack {
   Undoptr next;	/* next record in undo stack */
   Undoptr last;	/* double-linked for "redo" function */
   u_int type;		/* type of event */
   short idx;		/* counter for undo event */
   objinstptr thisinst;	/* instance of object in which event occurred */
   int idata;		/* simple undedicated integer datum */
   char *undodata;	/* free space to be malloc'd */
			/* (size dependent on "type") */
} Undostack;

/* This whole thing needs to be cleaned up. . . now I've got objects in */
/* "library" which are repeated both in the "instlist" pair and the	*/
/* "thisobject" pointer in each instance.  The instance is repeated on	*/
/* the library page.  Ideally, the instance list should only exist on	*/
/* the library page, and not be destroyed on every call to "composelib"	*/

typedef struct {
   short	number;
   objectptr	*library;
   liblistptr	instlist;  /* List of instances */
} Library;

/*----------------------------------------------------------------------*/
/* A convenient structure for holding all the object lists		*/
/*----------------------------------------------------------------------*/

typedef struct {
   char		*tempfile;
   char		*tempdir;
   xcIntervalId	timeout_id;
   int		save_interval;
   u_short	new_changes;
   short	pages;
   short	numlibs;
   Pagedata	**pagelist;
   Undoptr	undostack;	/* actions to undo */
   Undoptr	redostack;	/* actions to redo */
   Library	fontlib;
   Library	*userlibs;
   objinstptr   *libtop;
} Globaldata;

/*----------------------------------------------------------------------*/
/* structures previously defined in menudefs.h				*/
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* Menu Definitions for hierarchical pulldown menus                     */
/*----------------------------------------------------------------------*/

#ifndef TCL_WRAPPER

typedef struct _menustruct *menuptr;

typedef struct _menustruct {
        char *name;
        menuptr submenu;
        short size;
        XtCallbackProc func;
        void *passeddata;
} menustruct;

/*----------------------------------------------------------------------*/
/* Structure for calling routines from the Toolbar icons		*/
/*----------------------------------------------------------------------*/

typedef struct _toolbarstruct {
	char *name;
	char **icon_data;
        XtCallbackProc func;
        void *passeddata;
	char *hint;
} toolbarstruct;

#endif
/* Menus and Toolbars are taken care of entirely by scripts in the Tcl/	*/
/* Tk version of xcircuit.						*/
/*----------------------------------------------------------------------*/
