/* dbug needs stdio */
#undef USECONTEXT
#undef HASH
#define LAZY_GETATTRIB

#include <stdio.h>
#include <dbug.h>
#include <tcl.h>
#include <signal.h>

#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/StringDefs.h>

#include <X11/Xos.h>
#include <X11/Xfuncs.h>

#define RETURN_EMSG

#ifdef DEBUG_MALLOC
#include <malloc.h>
#endif

#ifndef X_NOT_STDC_ENV
#include <stdlib.h>
#endif


/*********************** constants and macros **************************/

#define wafeDefaultFileSearchPath "/usr/lib/X11/%L/%T/%N%C%S:/usr/lib/X11/%l/%T/%N%C%S:/usr/lib/X11/%T/%N%C%S:/usr/lib/X11/%L/%T/%N%S:/usr/lib/X11/%l/%T/%N%S:/usr/lib/X11/%T/%N%S:/usr/include/X11/%T/%N:%N"


#define MESSAGE_COMMAND_LENGTH	4096
#ifdef __alpha
#define LONG_AS_STRING 		22
#else
#define LONG_AS_STRING 		12
#endif
#define INT_AS_STRING 		12
#define FLOAT_AS_STRING		20
#define MAX_NAME_LEN		30
#define MAX_TYPE_LEN		30
#define INT_ARRAY_IN_BYTES	4096

#ifndef SIGMAX
#define SIGMAX NSIG
#endif

#define WafeDontManage ((Widget (*)()) -1)

/* user defineable handlers */
#define STDIN   0
#define STDOUT  1
#define STDERR  2
#define XIOERR  3
#define HTMLVISITED 4
#define HANDLERMAX HTMLVISITED+1

#define ParentWidget(w) ((XtParent(w)==NULL)?w:XtParent(w))
#define widget2Name(w)  ((XtParent(w)==NULL)?wafeTopLevelWidget(w):XtName(w))

#define Nil(Typ)                ((Typ *) 0)

#define name2Widget(name)             wafeCvtName2Widget(name,True,NULL,NULL)
#define name2WidgetId(name)           wafeCvtName2Widget(name,False,NULL,NULL)
#define name2WidgetOfClass(name,c,str) wafeCvtName2Widget(name,True,c,str)

#ifdef PRER5
#define WafePermStringToQuark(n) XrmStringToQuark((n))
#else
#define WafePermStringToQuark(n) XrmPermStringToQuark((n))
#endif

#ifdef NEVER
#ifndef PRER5
#define IFCONVERTANDSTORE(w, from,inp, to,outp) \
	if(XtConvertAndStore(w, from, & inp, to, & outp))
#else
#define IFCONVERTANDSTORE(w, from, inp, to, outp) \
	  XtConvert(w, from, & inp, to, & outp); \
	    if (outp.addr)
#endif
#else
#define IFCONVERTANDSTORE(w, from, inp, to, outp) \
	  XtConvert(w, from, & inp, to, & outp); \
	    if (outp.addr)
#endif

#ifdef MOTIF
#include <Xm/Xm.h>
# define MOTIF11
# if (XmVERSION == 1) && (XmREVISION >= 2)
#  define MOTIF12
# endif
#endif

#if !defined(PRER5) && defined(MOTIF11) && defined(MOTIF_EDITRES)
#include <X11/Xmu/Editres.h>
#define MOTIF_EDITRES_HANDLER(w) \
    XtAddEventHandler((w), (EventMask)0, True, _XEditResCheckMessages, NULL);
#else
#define MOTIF_EDITRES_HANDLER(w) 
#endif


#ifdef MAIN 
#define WAFE_EXTERN
#define INITIALIZE(var,value) var = value
#else
#define WAFE_EXTERN extern
#define INITIALIZE(var, value) var
#endif

/************************* global variables *************************/

WAFE_EXTERN Tcl_Interp    *wafeInterpreter;     /* single tcl-interpreter */
WAFE_EXTERN XtAppContext   wafeAppContext;      /* application context    */
WAFE_EXTERN Widget         wafeTopLevel;        /* top level window       */

WAFE_EXTERN int INITIALIZE(wafeClientPid, 0);   /* PID of child process      */
WAFE_EXTERN int INITIALIZE(wafeExtraCom,0);     /* Extra communication chan. */
WAFE_EXTERN int INITIALIZE(wafeExtraClient,0);  /* client side of cannel     */
WAFE_EXTERN int INITIALIZE(wafeToClient,-1);    /* channel to client         */
WAFE_EXTERN int INITIALIZE(wafeFromClient,-1);  /* channel from client       */
WAFE_EXTERN int INITIALIZE(wafeErrorClient,-1); /* error channel from client */

WAFE_EXTERN String INITIALIZE(wafeScriptName, NULL); /* for fileMode         */
#define fileMode          (wafeScriptName != NULL)
#define frontendMode      (wafeClientPid != 0)


WAFE_EXTERN String INITIALIZE(wafeAppClass, NULL);
WAFE_EXTERN char           wafePackages[100];
WAFE_EXTERN String         wafeFileSearchPath;
WAFE_EXTERN XEvent*        wafeCurrentEvent;    /* current event for actions */
WAFE_EXTERN int    INITIALIZE(wafeInnerEventLoop, 0);

#ifdef USECONTEXT
WAFE_EXTERN XContext INITIALIZE(wafeCtx, 0);
#endif

#ifdef LAZY_GETATTRIB
/* in order to make wafeMMgetAttribList more lazy we use a 
 * global static variable
 */
Widget wafeCurrentWidget;
#endif

/*
 * Some Widgets have subparts or subobjects providing ressources,
 * which are not visible to XtGetResourceList(). For each of them
 * we create a static list containing attribute/type pairs, as defined by
 * the following structure. Anyone who knows a more elegant solution
 * **PLEASE** email it to us!!
 */

typedef struct
    {
    char *resource_name;
    char *resource_type;
    } addResInfo;


typedef long WidgetID;

/* 
 * memory management uses a widget list and 
 * a per widget attibute list keeping the resources to be freed
 * on setValues or destroys
 */

typedef struct _MMattribList
    {
    XrmQuark               attribute;
    char                  *value;
    struct _MMattribList  *next;
    } MMattribList, *MMattribListPtr;


typedef struct _WidgetListItem
    {
    Widget                widget;
    XtPointer             info;
    struct _WidgetListItem *next;
    } WidgetListItem, *WidgetListPtr;

WAFE_EXTERN XrmQuark         wafeCurrentAttrib;
WAFE_EXTERN MMattribListPtr *wafeCurrentAttribList;
WAFE_EXTERN WidgetListPtr    wafeWidgetTrees;


/* 
 * Declare some Quarks for resource types as globals here, 
 * they are initialized by XtGen.c or XmGen.c
 */

WAFE_EXTERN XrmQuark qString;
WAFE_EXTERN XrmQuark qCallback; 
WAFE_EXTERN XrmQuark qPointer;
WAFE_EXTERN XrmQuark qInt; 
WAFE_EXTERN XrmQuark qDimension; 
WAFE_EXTERN XrmQuark qCardinal; 
WAFE_EXTERN XrmQuark qPosition; 
WAFE_EXTERN XrmQuark qFloat; 
WAFE_EXTERN XrmQuark qDouble; 
WAFE_EXTERN XrmQuark qPixel; 
WAFE_EXTERN XrmQuark qBoolean; 
WAFE_EXTERN XrmQuark qWidgetList; 
WAFE_EXTERN XrmQuark qWidget; 


#ifdef MOTIF11
WAFE_EXTERN XrmQuark qWindow; 
WAFE_EXTERN XrmQuark qXmString;
WAFE_EXTERN XrmQuark qXmStringTable;
WAFE_EXTERN XrmQuark qHorizontalDimension;
WAFE_EXTERN XrmQuark qVerticalDimension;
WAFE_EXTERN XrmQuark qHorizontalPosition;
WAFE_EXTERN XrmQuark qVerticalPosition;
WAFE_EXTERN XrmQuark qPrimForegroundPixmap;
WAFE_EXTERN XrmQuark qTextPosition;
WAFE_EXTERN XrmQuark qdropProc;
WAFE_EXTERN XrmQuark qdragProc;
WAFE_EXTERN XrmQuark qtransferProc;
WAFE_EXTERN XrmQuark qconvertProc;
WAFE_EXTERN XrmQuark qclientData; 
#define xmDragContextWidgetClass xmDragContextClass

typedef struct
    {
    String dest;
    XtPointer value;
    } dropTransferCallbackStruct;

#endif

/************** no global variables beyond this point ************/

/*
 * type definition for freeing procedures
 */

typedef void (*freeProc)(
#if NeedFunctionPrototypes
    char *
#endif 
);

/*
 * This  is our version of Xt's XtResource structure, containing only the
 * name of the resource in quark representation and the type as string and 
 * as Quark as well..
 * Compare to resList2QTypeList in resources.c. RESINFO maintains a global
 * List, consisting of several lists, one for each WidgetClass!
 */

typedef struct _QType
     {
     XrmQuark qName;
     char *type;
     XrmQuark  qType;
     struct _QType *next;
     } QType, *QTypeList;


/*************************** externs for callback.c **************/

#ifdef MOTIF11
#ifdef CALLBACK_C
#include <Xm/Xm.h>
extern void wafeEscapedXmString2String(
#if NeedFunctionPrototypes
     char *, XmString
#endif
);

extern char * wafeCvtXmStringTable2String(
#if NeedFunctionPrototypes
    int, XmStringTable
#endif
);
#endif
#endif


/*************************** externs from mm.c **************/
#ifndef MM_C
extern void wafeMMreplace(
#if NeedFunctionPrototypes
    MMattribListPtr *, XrmQuark, char *, freeProc
#endif
);

extern MMattribListPtr * wafeMMgetAttribList(
#if NeedFunctionPrototypes
    Widget, Boolean
#endif
);

extern Widget wafeMMfreeGarbage(
#if NeedFunctionPrototypes
     Widget
#endif
);

extern char * wafeMMgetValue(
#if NeedFunctionPrototypes
    MMattribListPtr *, XrmQuark
#endif
);

extern void wafeAddToEndOfWidgetList(
#if NeedFunctionPrototypes
     WidgetListPtr *, Widget, XtPointer
#endif
);

extern void wafeMMsetAttribList(
#if NeedFunctionPrototypes
      Widget
#endif
);
#endif


/*************************** externs from handlers.c **************/

#ifndef HANDLERS_C
extern void wafeInit(
#if NeedFunctionPrototypes
    int, char **, Boolean, Boolean
#endif
);

extern void wafeExit(
#if NeedFunctionPrototypes
    int
#endif
);

extern void wafeFatal(
#if NeedFunctionPrototypes
    String, String, String
#endif
);

extern int wafeEval(
#if NeedFunctionPrototypes
     Tcl_Interp *, char *, char *
#endif			 
);

extern Boolean wafeMergeArguments(
#if NeedFunctionPrototypes
     char *, char *, int *, char ***
#endif			 
);


void
wafeConvError (
#if NeedFunctionPrototypes
     char*, char*, char*, char*
#endif
);

void
wafeArgcError (
#if NeedFunctionPrototypes
     char*, char*, int, int
#endif
);

void
wafeNoVarCompError (
#if NeedFunctionPrototypes
     char*, char*, char*
#endif
);

#endif


/*************************** externs from callback.c **************/

#ifndef CALLBACK_C
extern void wafeCallbackQuarkInitialize();

extern void wafeExecCallbackProc(
#if NeedFunctionPrototypes
     Widget, XtPointer, XtPointer
#endif
);
#endif


/*************************** externs from converters.c **************/

#ifndef CONVERTERS_C
/*
 * Functions from file CONVERTERS.C
 */
extern int wafeConvert(
#if NeedFunctionPrototypes
     Widget, WidgetClass, char**, int*, ArgList*, int*, Widget
#endif
);

extern Widget wafeCvtName2Widget(
#if NeedFunctionPrototypes
     char *, Boolean, WidgetClass, char *
#endif
);

extern XtTypeConverter CvtStringToWidget(
#if NeedFunctionPrototypes
     Display*, XrmValue*, Cardinal*, XrmValue*, XrmValue*, XtPointer*
#endif
);

extern void CvtStringToCallback(
#if NeedFunctionPrototypes
     XrmValuePtr, Cardinal *, XrmValuePtr, XrmValuePtr
#endif
);

extern void CvtStringToPointer(
#if NeedFunctionPrototypes
     XrmValuePtr, Cardinal *, XrmValuePtr, XrmValuePtr
#endif
);

extern void CvtStringToWidgetList(
#if NeedFunctionPrototypes
     XrmValuePtr, Cardinal *, XrmValuePtr, XrmValuePtr
#endif
);

extern char * wafeCvtIntsToTcl(
#if NeedFunctionPrototypes
     char *, int, int *
#endif
);

extern void wafeEscapedStrcpy(
#if NeedFunctionPrototypes
     String, String 
#endif
);

extern char * wafeCvtWidgetListToList(
#if NeedFunctionPrototypes
     char *, Cardinal, WidgetList
#endif			 
);

extern String wafeTopLevelWidget(
#if NeedFunctionPrototypes
     Widget
#endif
);
#endif

/*************************** externs from resources.c **************/

#ifndef RESOURCES_C
extern XrmQuark wafeGetQTypeOfAttribute(
#if NeedFunctionPrototypes
     WidgetClass, Widget, XrmQuark
#endif
);
#endif

/*************************** externs from createw.c **************/
#ifndef CREATEW_C
extern void wafeCreateWidgetCommand(
#if NeedFunctionPrototypes
    char *, WidgetClass, Widget (*)(), Boolean
#endif
);
#endif


#ifndef XT_C
extern void wafeRegisterXpmTypeConverter(
#if NeedFunctionPrototypes
      char *, Boolean
#endif
);
#endif


