/*
 * tix.h --
 *
 *	This is the standard header file for all tix C code. It
 *	defines many macros and utility functions to make it easier to
 *	write TCL commands and TK widgets in C. No more needs to write
 *	2000 line functions!
 *
 * Copyright (c) 1996, Expert Interface Technologies
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

#ifndef _TIX_H_
#define  _TIX_H_

#ifdef __BORLAND
# ifndef _Windows
#  define _Windows
# endif
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if (TK_MAJOR_VERSION > 4 || (TK_MAJOR_VERSION == 4 && TK_MINOR_VERSION >= 1))
/* TK 4.1 or later */


/* #define PORTABLE_TK */
#define Tix_FreeProc Tcl_FreeProc

#else
/* TK 4.0 */

    /* These portable features were not defined in previous versions of
     * TK but are used in Tix. Let's define them here.
     */

#define TkPutImage(a, b, c, d, e, f, g, h, i, j, k, l) \
	XPutImage(c, d, e, f, g, h, i, j, k, l)

#define TkStringToKeysym XStringToKeysym 
#define Tix_FreeProc Tk_FreeProc

#endif


#define TIX_STDIN_ALWAYS	0
#define TIX_STDIN_OPTIONAL	1
#define TIX_STDIN_NONE		2

typedef struct {
    char *name;			/* Name of command. */
    int (*cmdProc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
				int argc, char **argv));
				/* Command procedure. */
} Tix_TclCmd;


/*----------------------------------------------------------------------
 *
 *
 * 			SUB-COMMAND HANDLING
 *
 *
 *----------------------------------------------------------------------
 */
typedef int (*Tix_SubCmdProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int argc, char ** argv));
typedef int (*Tix_CheckArgvProc) _ANSI_ARGS_((ClientData clientData,
	Tcl_Interp *interp, int argc, char ** argv));

typedef struct _Tix_CmdInfo {
    int		numSubCmds;
    int		minargc;
    int		maxargc;
    char      * info;
} Tix_CmdInfo;


typedef struct _Tix_SubCmdInfo {
    int			namelen;
    char      	      * name;
    int			minargc;
    int			maxargc;
    Tix_SubCmdProc 	proc;
    char      	      * info;
    Tix_CheckArgvProc   checkArgvProc;
} Tix_SubCmdInfo;

/*
 * Tix_ArraySize --
 *
 *	Find out the number of elements inside a C array. The argument "x"
 * must be a valid C array. Pointers don't work.
 */
#define Tix_ArraySize(x) (sizeof(x) / sizeof(x[0]))

/*
 * This is used for Tix_CmdInfo.maxargc and Tix_SubCmdInfo.maxargc,
 * indicating that this command takes a variable number of arguments.
 */
#define TIX_VAR_ARGS	       -1

/* TIX_DEFAULT_LEN --
 *
 * Use this for Tix_SubCmdInfo.namelen and Tix_ExecSubCmds() will try to
 * determine the length of the subcommand name for you.
 */
#define TIX_DEFAULT_LEN	       -1

/* TIX_DEFAULT_SUB_CMD --
 *
 * Use this for Tix_SubCmdInfo.name. This will match any subcommand name,
 * including the empty string, when Tix_ExecSubCmds() finds a subcommand
 * to execute.
 */
#define TIX_DEFAULT_SUBCMD	0

/* TIX_DECLARE_CMD --
 *
 * This is just a handy macro to declare a C function to use as a
 * command function.
 */
#define TIX_DECLARE_CMD(func) \
    int func _ANSI_ARGS_((ClientData clientData,\
	Tcl_Interp *interp, int argc, char ** argv))

/* TIX_DECLARE_SUBCMD --
 *
 * This is just a handy macro to declare a C function to use as a
 * sub command function.
 */
#define TIX_DECLARE_SUBCMD(func) \
    int func _ANSI_ARGS_((ClientData clientData,\
	Tcl_Interp *interp, int argc, char ** argv))

/* TIX_DEFINE_CMD --
 *
 * This is just a handy macro to define a C function to use as a
 * command function.
 */
#define TIX_DEFINE_CMD(func) \
int func(clientData, interp, argc, argv) \
    ClientData clientData;	/* Main window associated with 	\
				 * interpreter. */		\
    Tcl_Interp *interp;		/* Current interpreter. */	\
    int argc;			/* Number of arguments. */	\
    char **argv;		/* Argument strings. */


/*----------------------------------------------------------------------
 *
 *
 * 		    LIST HADLING
 *
 *
 *----------------------------------------------------------------------
 */
typedef struct Tix_ListInfo {
    int nextOffset;		/* offset of the "next" pointer in a list
				 * item */
    int prevOffset;		/* offset of the "next" pointer in a list
				 * item */
} Tix_ListInfo;


/* Singly-linked list */
typedef struct Tix_LinkList {
    int numItems;		/* number of items in this list */
    char * head;		/* (general pointer) head of the list */
    char * tail;		/* (general pointer) tail of the list */
} Tix_LinkList;

typedef struct Tix_ListIterator {
    char * last;
    char * curr;
    unsigned int started : 1;   /* True if the search operation has
				 * already started for this list */
    unsigned int deleted : 1;	/* True if a delete operation has been
				 * performed on the current item (in this
				 * case the curr pointer has already been
				 * adjusted
				 */
} Tix_ListIterator;

#define Tix_IsLinkListEmpty(list)  ((list.numItems) == 0)
#define TIX_UNIQUE 1
#define TIX_UNDEFINED -1

/*----------------------------------------*/
/* General Single Link List		  */
/*----------------------------------------*/

EXTERN void 		Tix_LinkListInit _ANSI_ARGS_((Tix_LinkList * lPtr));
EXTERN void		Tix_LinkListAppend _ANSI_ARGS_((Tix_ListInfo * infoPtr,
			    Tix_LinkList * lPtr, char * itemPtr, int flags));
EXTERN void		Tix_LinkListStart _ANSI_ARGS_((Tix_ListInfo * infoPtr,
			    Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN void		Tix_LinkListNext _ANSI_ARGS_((Tix_ListInfo * infoPtr,
			    Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN void		Tix_LinkListDelete _ANSI_ARGS_((Tix_ListInfo * infoPtr,
			    Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN int		Tix_LinkListDeleteRange _ANSI_ARGS_((
			    Tix_ListInfo * infoPtr, Tix_LinkList * lPtr,
			    char * fromPtr, char * toPtr,
			    Tix_ListIterator * liPtr));
EXTERN int		Tix_LinkListFind _ANSI_ARGS_((
			    Tix_ListInfo * infoPtr, Tix_LinkList * lPtr,
			    char * itemPtr, Tix_ListIterator * liPtr));
EXTERN int		Tix_LinkListDeleteRange _ANSI_ARGS_((
			    Tix_ListInfo * infoPtr,
			    Tix_LinkList * lPtr, char * fromPtr,
			    char * toPtr, Tix_ListIterator * liPtr));
EXTERN void		Tix_LinkListInsert _ANSI_ARGS_((
			    Tix_ListInfo * infoPtr,
			    Tix_LinkList * lPtr, char * itemPtr,
			    Tix_ListIterator * liPtr));
EXTERN void		Tix_LinkListIteratorInit _ANSI_ARGS_((
			    Tix_ListIterator * liPtr));

#define Tix_LinkListDone(liPtr) ((liPtr)->curr == NULL)

/*----------------------------------------*/
/* Simple Single Link List: The next	  */
/*   pointer is always offset 0 in the	  */
/*   link structure			  */
/*----------------------------------------*/

EXTERN void 		Tix_SimpleListInit _ANSI_ARGS_((Tix_LinkList * lPtr));
EXTERN void		Tix_SimpleListAppend _ANSI_ARGS_((
			    Tix_LinkList * lPtr, char * itemPtr, int flags));
EXTERN void		Tix_SimpleListStart _ANSI_ARGS_((
			    Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN void		Tix_SimpleListNext _ANSI_ARGS_((
			    Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN void		Tix_SimpleListDelete _ANSI_ARGS_((
			    Tix_LinkList * lPtr, Tix_ListIterator * liPtr));
EXTERN int		Tix_SimpleListDeleteRange _ANSI_ARGS_((
			    Tix_LinkList * lPtr,
			    char * fromPtr, char * toPtr,
			    Tix_ListIterator * liPtr));
EXTERN int		Tix_SimpleListFind _ANSI_ARGS_((
			    Tix_LinkList * lPtr,
			    char * itemPtr, Tix_ListIterator * liPtr));
EXTERN int		Tix_SimpleListDeleteRange _ANSI_ARGS_((
			    Tix_LinkList * lPtr, char * fromPtr,
			    char * toPtr, Tix_ListIterator * liPtr));
EXTERN void		Tix_SimpleListInsert _ANSI_ARGS_((
			    Tix_LinkList * lPtr, char * itemPtr,
			    Tix_ListIterator * liPtr));
EXTERN void		Tix_SimpleListIteratorInit _ANSI_ARGS_((
			    Tix_ListIterator * liPtr));

#define Tix_SimpleListDone(liPtr) ((liPtr)->curr == NULL)

/*----------------------------------------------------------------------
 *
 *
 * 		    MEGA-WIDGET CONFIG HANDLING
 *
 *
 *----------------------------------------------------------------------
 */
typedef struct _TixConfigSpec  	  	TixConfigSpec;
typedef struct _TixConfigAlias		TixConfigAlias;
typedef struct _TixClassRecord		TixClassRecord;

struct _TixConfigSpec {
    unsigned int isAlias	: 1;
    unsigned int readOnly	: 1;
    unsigned int isStatic	: 1;
    unsigned int forceCall	: 1;

    char * argvName;
    char * defValue;

    char * dbName;		/* The additional parts of a */
    char * dbClass;		/* TixWidgetConfigSpec structure */

    char *verifyCmd;

    TixConfigSpec * realPtr;	/* valid only if this option is an alias */
};


/* Controls the access of root widget and subwidget commands and options
 */
typedef struct _Tix_ExportSpec {
    Tix_LinkList exportCmds;
    Tix_LinkList restrictCmds;
    Tix_LinkList exportOpts;
    Tix_LinkList restrictOpts;
} Tix_ExportSpec;

typedef struct _Tix_SubWidgetSpec {
    struct _Tix_SubWidgetSpec * next;
    char * name;
    Tix_ExportSpec export;
} Tix_SubWidgetSpec;

typedef struct _Tix_StringLink {
    struct _Tix_StringLink *next;
    char * string;
} Tix_StringLink;

typedef struct _Tix_SubwidgetDef {
    struct _TixSubwidgetDef * next;
    char * spec;
    char * value;
} Tix_SubwidgetDef;

struct _TixClassRecord {
    TixClassRecord    * superClass;

    unsigned int	isWidget;
    char	      * className;	/* Instiantiation command */
    char	      * ClassName;	/* used in TK option database */

    int			nSpecs;
    TixConfigSpec    ** specs;
    int			nMethods;
    char	     ** methods;
    Tix_LinkList	subWDefs;	/* the -defaults option */
    Tix_LinkList 	subWidgets;
    Tk_Window		mainWindow;	/* This variable is essentially
					 * a cached variable so that
					 * we can advoid calling
					 * Tk_MainWindow() */
    Tix_ExportSpec	export;		/* controls the export status
					 * of the commands and options
					 * of the root widget
					 */
    int			virtual;	/* is this a virtual base class
					 * (shouldn't be instantiated)*/  
};

/*----------------------------------------------------------------------
 *
 *
 *
 *  			CUSTOM CONFIG OPTIONS
 *
 *
 *----------------------------------------------------------------------
 */
#define TIX_RELIEF_RAISED	1
#define TIX_RELIEF_FLAT		2
#define TIX_RELIEF_SUNKEN	4
#define TIX_RELIEF_GROOVE	8
#define TIX_RELIEF_RIDGE	16
#define TIX_RELIEF_SOLID	32

typedef int Tix_Relief;

extern Tk_CustomOption tixConfigItemType;
extern Tk_CustomOption tixConfigItemStyle;
extern Tk_CustomOption tixConfigRelief;


/************************/
/*     tixInit.c	*/
/************************/

EXTERN int		Tix_AppInit _ANSI_ARGS_((Tcl_Interp *interp));

EXTERN int		Tix_ArgcError _ANSI_ARGS_((Tcl_Interp *interp, 
			    int argc, char ** argv, int prefixCount,
			    char *message));
EXTERN int 		Tix_CallMethod _ANSI_ARGS_((Tcl_Interp *interp,
			    char *context, char *widRec, char *method,
			    int argc, char **argv));
EXTERN int		Tix_ChangeOneOption _ANSI_ARGS_((
			    Tcl_Interp *interp, TixClassRecord *cPtr,
			    char * widRec, TixConfigSpec *spec, char * value,
			    int isDefault, int isInit));
EXTERN void		Tix_CreateCommands _ANSI_ARGS_((
			    Tcl_Interp *interp, Tix_TclCmd *commands,
			    ClientData clientData,
			    Tcl_CmdDeleteProc *deleteProc));
EXTERN Tk_Window	Tix_CreateSubWindow _ANSI_ARGS_((
			    Tcl_Interp * interp, Tk_Window tkwin,
			    char * subPath));
EXTERN void 		Tk_Draw3DArc _ANSI_ARGS_((Display *display,
			    Drawable drawable, Tk_3DBorder border, int x,
			    int y, int width, int height, int angle1,
			    int angle2, int borderWidth, int relief));
EXTERN void		Tix_DrawAnchorLines _ANSI_ARGS_((
			    Display *display, Drawable drawable,
			    GC gc, int x, int y, int w, int h));
EXTERN int 		Tix_ExistMethod _ANSI_ARGS_((Tcl_Interp *interp,
			    char *context, char *method));
EXTERN void		Tix_Exit _ANSI_ARGS_((Tcl_Interp * interp, int code));
EXTERN TixConfigSpec * 	Tix_FindConfigSpecByName _ANSI_ARGS_((
			    Tcl_Interp * interp,
			    TixClassRecord * cPtr, char * name));
EXTERN char  * 		Tix_FindMethod _ANSI_ARGS_((Tcl_Interp *interp,
			    char *context, char *method));
EXTERN char * 		Tix_FindPublicMethod _ANSI_ARGS_((
			    Tcl_Interp *interp, TixClassRecord * cPtr, 
			    char * method));
EXTERN TixClassRecord *	Tix_GetClassByName _ANSI_ARGS_((
			    Tcl_Interp * interp, char * classRec));
EXTERN char  * 		Tix_GetConfigSpecFullName _ANSI_ARGS_((char *clasRec,
			    char *flag));
EXTERN char  * 		Tix_GetContext _ANSI_ARGS_((Tcl_Interp *interp,
			    char *widRec));
EXTERN char  * 		Tix_GetMethodFullName _ANSI_ARGS_((char *context,
			    char *method));
EXTERN Pixmap		Tix_GetRenderBuffer _ANSI_ARGS_((Display *display,
			    Drawable d, int width, int height, int depth));
EXTERN void 		Tix_GetPublicMethods _ANSI_ARGS_((Tcl_Interp *interp,
			    char *widRec, int *numMethods,
			    char *** validMethods));
EXTERN int		Tix_GetWidgetOption _ANSI_ARGS_((
			    Tcl_Interp *interp, Tk_Window tkwin,
			    char *argvName, char *dbName, char *dbClass,
			    char *defValue, int argc, char **argv,
			    int type, char *ptr));

#ifdef TCL_VARARGS
/* This symbol is only defined in Tcl 7.5 or later */
EXTERN int		Tix_GlobalVarEval _ANSI_ARGS_(
			    TCL_VARARGS(Tcl_Interp *,interp));
#else
EXTERN int		Tix_GlobalVarEval _ANSI_ARGS_(
			    VARARGS(Tcl_Interp *interp));
#endif

EXTERN int		Tix_HandleSubCmds _ANSI_ARGS_((
			    Tix_CmdInfo * cmdInfo,
			    Tix_SubCmdInfo * subCmdInfo,
			    ClientData clientData, Tcl_Interp *interp,
			    int argc, char **argv));
EXTERN int 		Tix_Init _ANSI_ARGS_((Tcl_Interp *interp));

EXTERN int		Tix_LoadTclLibrary _ANSI_ARGS_((
			    Tcl_Interp *interp, char *envName,
			    char *tclName, char *initFile,
			    char *defDir, char * appName));
EXTERN void 		Tix_MainLoop _ANSI_ARGS_((Tcl_Interp * interp));

EXTERN void 		Tix_OpenStdin _ANSI_ARGS_((Tcl_Interp *interp));

EXTERN void		Tix_RestoreContext _ANSI_ARGS_((Tcl_Interp *interp,
			    char *widRec, char *oldContext));
EXTERN char  * 		Tix_SaveContext _ANSI_ARGS_((Tcl_Interp *interp,
			    char *widRec));
EXTERN void 		Tix_SetArgv _ANSI_ARGS_((Tcl_Interp *interp, 
			    int argc, char **argv));
EXTERN int 		Tix_SuperClass _ANSI_ARGS_((Tcl_Interp *interp,
			    char *widClass, char ** superClass_ret));
EXTERN int		Tix_SysInit _ANSI_ARGS_((Tcl_Interp *interp,
			    int *argcPtr, char **argv));
EXTERN int		Tix_UnknownPublicMethodError _ANSI_ARGS_((
			    Tcl_Interp *interp, TixClassRecord * cPtr,
			    char * widRec, char * method));
EXTERN int		Tix_ValueMissingError _ANSI_ARGS_((Tcl_Interp *interp,
			    char *spec));
EXTERN Tcl_Interp *	Tix_WishInit _ANSI_ARGS_((int *argcPtr, char **argv,
			    char * rcFileName, int readStdin));

#define SET_RECORD(interp, record, var, value) \
	Tcl_SetVar2(interp, record, var, value, TCL_GLOBAL_ONLY)

#define GET_RECORD(interp, record, var) \
	Tcl_GetVar2(interp, record, var, TCL_GLOBAL_ONLY)


#define TIX_HASHKEY(k) ((sizeof(k)>sizeof(int))?((char*)&(k)):((char*)(k)))

/*----------------------------------------------------------------------
 * Compatibility section
 *----------------------------------------------------------------------	*/

#ifdef NO_STRDUP
#define strdup tixStrDup
EXTERN char * 		tixStrDup _ANSI_ARGS_((
			    char * string));
#endif /* NO_STRDUP */


#ifdef __cplusplus
}
#endif


#endif /* _TIX_H_ */
