/*****************************************************************************
*   A motif interface driver.						     *
******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                *
******************************************************************************
* Written by:  Offer Kaufman and Gershon Elber	    Ver 0.1, November 1994.  *
*****************************************************************************/

#ifdef __hpux
typedef char *caddr_t;	       /* Awful kludge. Let me know of a better way. */
#endif /* __hpux */

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/Xresource.h>

#include <Xm/MainW.h>
#include <Xm/PushB.h>
#include <Xm/ToggleB.h>
#include <Xm/RowColumn.h>
#include <Xm/Label.h>
#include <Xm/Scale.h>
#include <Xm/Form.h>

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>

#include "irit_sm.h"
#include "genmat.h"
#include "iritprsr.h"
#include "irit_soc.h"
#include "allocate.h"
#include "attribut.h"
#include "ip_cnvrt.h"
#include "cagd_lib.h"
#include "iritgrap.h"
#include "xmtdrvs.h"
#include "xgldrvs.h"

#define X11_FONT_NAME		"8x13"

#define DEFAULT_TRANS_WIDTH	200
#define DEFAULT_TRANS_HEIGHT	500

#define TRANS_FRACTION		25
#define STATE_FRACTION		25

/* X global specific staff goes here: */
Display *XDisplay;
int XScreen,
    ViewHasSize,
    ViewHasPos,
    ViewPosX,
    ViewPosY;
unsigned int
    MaxColors = IG_MAX_COLOR,
    ViewBorderWidth,
    ViewBackGroundPixel,
    ViewBorderPixel,
    ViewTextPixel,
    ViewWidth = DEFAULT_VIEW_WIDTH,
    ViewHeight = DEFAULT_VIEW_HEIGHT;
Colormap XColorMap;
GC XViewGraphContext;

Widget IGTopLevel, MainTransForm;
Window XRoot;
static XFontStruct *XLoadedFont;
static XColor
    *TransCursorColor = NULL;
XColor
    BlackColor,
    *ViewCursorColor = NULL;
static int
    TransPosX = 0,
    TransPosY = 0;
static unsigned int
    TransWidth = DEFAULT_TRANS_WIDTH,
    TransHeight = DEFAULT_TRANS_HEIGHT;

/* X Colors to be used for viewed object (see also iritgrap.h): */
static int XViewColorDefs[IG_MAX_COLOR + 1][3] =
{
    {     0,     0,     0 },  /* 0. IG_IRIT_BLACK */
    {     0,     0, 43350 },  /* 1. IG_IRIT_BLUE */
    {     0, 43350,     0 },  /* 2. IG_IRIT_GREEN */
    {     0, 43350, 43350 },  /* 3. IG_IRIT_CYAN */
    { 43350,     0,     0 },  /* 4. IG_IRIT_RED */
    { 43350,     0, 43350 },  /* 5. IG_IRIT_MAGENTA */
    { 43350, 43350,     0 },  /* 6. IG_IRIT_BROWN */
    { 43350, 43350, 43350 },  /* 7. IG_IRIT_LIGHTGREY */
    { 21675, 21675, 21675 },  /* 8. IG_IRIT_DARKGRAY */
    { 21675, 21675, 65535 },  /* 9. IG_IRIT_LIGHTBLUE */
    { 21675, 65535, 21675 },  /* 10. IG_IRIT_LIGHTGREEN */
    { 21675, 65535, 65535 },  /* 11. IG_IRIT_LIGHTCYAN */
    { 65535, 21675, 21675 },  /* 12. IG_IRIT_LIGHTRED */
    { 65535, 21675, 65535 },  /* 13. IG_IRIT_LIGHTMAGENTA */
    { 65535, 65535, 21675 },  /* 14. IG_IRIT_YELLOW */
    { 65535, 65535, 65535 }   /* 15. IG_IRIT_WHITE */
};
XColor XViewColorsHigh[IG_MAX_COLOR + 1];
XColor XViewColorsLow[IG_MAX_COLOR + 1];
Window ViewWndw;
static RealType OldSliderVal;
static Widget ProjectionButton, DepthCueButton, StateForm,
    LineWidthLabel, ChangeFactorLabel, FineNessLabel,
    NormalLenLabel, NumOfIsolinesLabel;

static void CreateControlPanel(Widget TopLevel);
static char *ReadOneXDefault(char *Entry);
static void ReadXDefaults(void);
static void CreatePopupWindow(Widget w);
static void TransformCB(Widget w, IGGraphicEventType state);
static void SetCB(Widget w, int State, XmScaleCallbackStruct *CallData);
static int ExposeCB(Widget w); 
static void ScaleCB(Widget w, IGGraphicEventType EventType);
static void DragCB(Widget w, IGGraphicEventType EventType);

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Pop up all windows, read input and display.				     M
*                                                                            *
* PARAMETERS:                                                                M
*   argc, argv:  command line parameters ( *.dat files )                     M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   main					       			     M
*****************************************************************************/
void main(int argc, char **argv)
{
    int i;
    XGCValues Values;
    XtAppContext App;

    IGConfigureGlobals(argv[0], argc, argv);

    /* Lets see if we can get access to the X server before we even start: */
    if ((XDisplay = (Display *) XOpenDisplay(NULL)) == NULL) {
	fprintf(stderr, "%s: Failed to access X server, abored.\n", argv[0]);
        exit(-1);
    }
    if ((XLoadedFont = XLoadQueryFont(XDisplay, X11_FONT_NAME)) == NULL) {
	fprintf(stderr,
		"%s: Failed to load required X font \"%s\", aborted.\n",
		argv[0], X11_FONT_NAME);
	exit(-1);
    }

    XScreen = DefaultScreen(XDisplay);
    XRoot = RootWindow(XDisplay, XScreen);
    XColorMap = DefaultColormap(XDisplay, XScreen);
    Values.foreground = WhitePixel(XDisplay, XScreen);
    Values.background = BlackPixel(XDisplay, XScreen);
    Values.font = XLoadedFont -> fid;
    XViewGraphContext = XCreateGC(XDisplay, XRoot,
				  GCForeground | GCBackground, &Values);
    
    if (XrmGetDatabase(XDisplay) == NULL)
	XGetDefault(XDisplay, "", "");
    ReadXDefaults();

    for (i = 0; i <= IG_MAX_COLOR; i++) {
	XViewColorsHigh[i].red   = XViewColorDefs[i][0];
	XViewColorsHigh[i].green = XViewColorDefs[i][1];
	XViewColorsHigh[i].blue  = XViewColorDefs[i][2];

	/* If fails to allocate the color - take WHITE instead. */
	if (!XAllocColor(XDisplay, XColorMap, &XViewColorsHigh[i]))
	    XViewColorsHigh[i].pixel = WhitePixel(XDisplay, XScreen);

	XViewColorsLow[i].red   = XViewColorDefs[i][0] / 2;
	XViewColorsLow[i].green = XViewColorDefs[i][1] / 2;
	XViewColorsLow[i].blue  = XViewColorDefs[i][2] / 2;

	/* If fails to allocate the color - take WHITE instead. */
	if (!XAllocColor(XDisplay, XColorMap, &XViewColorsLow[i]))
	    XViewColorsLow[i].pixel = WhitePixel(XDisplay, XScreen);
    }

#ifdef __GL__
    {
	static String FallbackResources[] = {
	    "*glwidget*rgba:		TRUE",
	    "*glwidget*doublebuffer:	TRUE",
	    "*glwidget*allocateBackground: TRUE",
	    NULL
	};

	IGTopLevel = XtAppInitialize(&App, argv[0], NULL, 0, &argc, argv,
				     FallbackResources, NULL, 0);
    }
#else
    IGTopLevel = XtVaAppInitialize(&App, argv[0], NULL, 0,
				   &argc, argv, NULL, NULL);
#endif /* __GL__ */
    CreateControlPanel(IGTopLevel);
    CreatePopupWindow(MainTransForm);
    CreateAnimation(MainTransForm);

    SetViewWindow(argc, argv);

    sleep(1); /* Some systems get confused if we draw immediately. */

    IGRedrawViewWindow();

    XtAppAddWorkProc(App, (XtWorkProc) ExposeCB, NULL);

    XtRealizeWidget(IGTopLevel);
    XtAppMainLoop(App);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Handles the state events.		 				     M
*                                                                            *
* PARAMETERS:                                                                M
*   State:    State to be treated.				             M
*   Refresh:  Wether state change requires screen refreshing.                M
*                                                                            *
* RETURN VALUE:                                                              M
*   UpdateView               				                     M
*                                                                            *
* KEYWORDS:                                                                  M
*    IGHandleState				       			     M
*****************************************************************************/
int IGHandleState(int State, int Refresh)
{
    int UpdateView = TRUE;

    UpdateView = IGDefaultStateHandler(State, Refresh);

    XtDestroyWidget(StateForm); 
    CreatePopupWindow(IGTopLevel);

    return UpdateView;
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Creates Motif Based Control Panel. 					     *
*                                                                            *
* PARAMETERS:                                                                *
*   w:  Parent widget.			                                     *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void CreateControlPanel(Widget TopLevel)
{
    static char *SlideTitle[] = {
	" PERSPECTIVE",
	" ROTATE",
	" TRANSLATE",
	" SCALE",
	" FAR/NEAR CLIP",
	" MATRIX",
	" PROJECTIONS"
    };
    static char SlideLabel[][2] = {
	"Z",
	"X",
	"Y",
	"Z",
	"X",
	"Y",
	"Z",
	" ",
	"N",
	"F"
    };    
    Widget Form, SubForm, Label, Button, Scale, TransForm;
    int i,
	Pos = 0,
	t = 0;
    IGGraphicEventType EventType;

    MainTransForm = XtVaCreateManagedWidget("TransWindow",
					    xmMainWindowWidgetClass, TopLevel,
					    NULL);
    TransForm = XtVaCreateManagedWidget("TransForm",
					xmFormWidgetClass,   MainTransForm,
					XmNtopAttachment,    XmATTACH_WIDGET,
					XmNtopWidget, 	     MainTransForm,
					XmNbottomAttachment, XmATTACH_WIDGET,
					XmNbottomWidget,     MainTransForm,  
					XmNleftAttachment,   XmATTACH_WIDGET,
					XmNleftWidget, 	     MainTransForm,
					XmNrightAttachment,  XmATTACH_WIDGET,
					XmNrightWidget,      MainTransForm,
					XmNfractionBase,     TRANS_FRACTION,
					NULL);

    /* Construct all slide bars (Scales) */
    for (i = 0, EventType = IG_EVENT_PERS_ORTHO_Z; i < 10; i++, EventType++) {
	if (EventType == IG_EVENT_ROTATE || EventType == IG_EVENT_TRANSLATE)
	    EventType++;			       /* Skip these events. */
        if (i == 0 || i == 1 || i == 4 || i == 7 || i == 8) {
            Form = CreateSubForm(TransForm, Pos++); 
            Label = XtVaCreateManagedWidget(SlideTitle[t++],
					    xmLabelWidgetClass,  Form,
					    XmNleftAttachment,   XmATTACH_FORM,
					    XmNrightAttachment,  XmATTACH_FORM,
					    NULL);              
        }
        Form = CreateSubForm(TransForm, Pos++); 	
        Label = XtVaCreateManagedWidget(SlideLabel[i],
					xmLabelWidgetClass, Form,
					NULL);
        Scale = XtVaCreateManagedWidget("Scale",
					xmScaleWidgetClass,  Form,
					XmNorientation,	     XmHORIZONTAL,
					XmNminimum,          -100,
					XmNrightAttachment,  XmATTACH_FORM,
					XmNleftAttachment,   XmATTACH_WIDGET,
					XmNleftWidget,       Label,
					XmNmaximum,	     100,
					NULL);	
        XtAddCallback(Scale, XmNvalueChangedCallback,
		      (XTC) ScaleCB, (XTP) EventType);
        XtAddCallback(Scale, XmNdragCallback, (XTC) DragCB, (XTP) EventType);
    }
    
    Form = CreateSubForm(TransForm, Pos++); 
    Label = XtVaCreateManagedWidget(SlideTitle[t++],
				    xmLabelWidgetClass,  	Form,
				    XmNleftAttachment,  	XmATTACH_FORM,
				    XmNrightAttachment,  	XmATTACH_FORM,
				    NULL);
 
    Form = CreateSubForm(TransForm, Pos++);         
    SubForm = XtVaCreateManagedWidget("MatrixOpFoundation",
				      xmFormWidgetClass,  	Form,
				      XmNleftAttachment,  	XmATTACH_FORM,
				      XmNrightAttachment, 	XmATTACH_FORM,
				      XmNfractionBase,   	3,
				      NULL);
               
    Button = XtVaCreateManagedWidget("Save",
				     xmPushButtonWidgetClass,SubForm, 
				     XmNleftAttachment,      XmATTACH_POSITION,
				     XmNleftPosition,        0,
				     XmNrightAttachment,     XmATTACH_POSITION,
				     XmNrightPosition,       1,
				     NULL);
    XtAddCallback(Button, XmNactivateCallback,
		  (XTC) TransformCB, (XTP) IG_EVENT_SAVE_MATRIX);
 
    Button = XtVaCreateManagedWidget("Push",
				     xmPushButtonWidgetClass,SubForm, 
				     XmNleftAttachment,      XmATTACH_POSITION,
				     XmNleftPosition,        1,
				     XmNrightAttachment,     XmATTACH_POSITION,
				     XmNrightPosition,       2,
				     NULL);
    XtAddCallback(Button, XmNactivateCallback,
		  (XTC) TransformCB, (XTP) IG_EVENT_PUSH_MATRIX);
 
    Button = XtVaCreateManagedWidget("Pop",
				     xmPushButtonWidgetClass,SubForm, 
				     XmNleftAttachment,      XmATTACH_POSITION,
				     XmNleftPosition,        2,
				     XmNrightAttachment,     XmATTACH_POSITION,
				     XmNrightPosition,       3,
				     NULL);
    XtAddCallback(Button, XmNactivateCallback,
		  (XTC) TransformCB, (XTP) IG_EVENT_POP_MATRIX);

    Pos++;
    Form = CreateSubForm(TransForm, Pos++);
    SubForm = XtVaCreateManagedWidget("SubForm",
				      xmFormWidgetClass,   	Form,
				      XmNrightAttachment,  	XmATTACH_FORM,
				      XmNleftAttachment,   	XmATTACH_FORM,
				      XmNfractionBase,     	2,
				      NULL);

    Button = XtVaCreateManagedWidget("Top",
				     xmPushButtonWidgetClass,SubForm,
				     XmNleftAttachment,      XmATTACH_POSITION,
				     XmNleftPosition,        0,
				     XmNrightAttachment,     XmATTACH_POSITION,
				     XmNrightPosition,       1,
				     NULL);
    XtAddCallback(Button, XmNactivateCallback,
		  (XTC) SetCB, (XTP)IG_STATE_VIEW_TOP);

    Button = XtVaCreateManagedWidget("Side",
				     xmPushButtonWidgetClass,SubForm,
				     XmNleftAttachment,      XmATTACH_POSITION,
				     XmNleftPosition, 	     1,
				     XmNrightAttachment,     XmATTACH_POSITION,
				     XmNrightPosition, 	     2,
				     NULL);

    Form = CreateSubForm(TransForm, Pos++);
    SubForm = XtVaCreateManagedWidget("Subform",
				      xmFormWidgetClass, 	Form,
				      XmNrightAttachment,	XmATTACH_FORM,
				      XmNleftAttachment, 	XmATTACH_FORM,
				      XmNfractionBase, 		2,
				      NULL);
    XtAddCallback(Button, XmNactivateCallback,
		  (XTC) SetCB, (XTP)IG_STATE_VIEW_SIDE);

    Button = XtVaCreateManagedWidget("Front",
				     xmPushButtonWidgetClass,SubForm,
				     XmNleftAttachment,      XmATTACH_POSITION,
				     XmNleftPosition, 	     0,
				     XmNrightAttachment,     XmATTACH_POSITION,
				     XmNrightPosition, 	     1,
				     NULL);
    XtAddCallback(Button, XmNactivateCallback,
		  (XTC) SetCB, (XTP)IG_STATE_VIEW_FRONT);

    Button = XtVaCreateManagedWidget("Iso",
				     xmPushButtonWidgetClass,SubForm,
				     XmNleftAttachment,      XmATTACH_POSITION,
				     XmNleftPosition, 	     1,
				     XmNrightAttachment,     XmATTACH_POSITION,
				     XmNrightPosition, 	     2,
				     NULL);
    XtAddCallback(Button, XmNactivateCallback,
		  (XTC) SetCB, (XTP)IG_STATE_VIEW_ISOMETRY);

    Pos++;
    Form = CreateSubForm(TransForm, Pos++);        
    Button = XtVaCreateManagedWidget("Animation",
				     xmPushButtonWidgetClass,	Form, 
				     XmNleftAttachment, 	XmATTACH_FORM,
				     XmNrightAttachment, 	XmATTACH_FORM,
				     NULL);
    XtAddCallback(Button, XmNactivateCallback,
		  (XTC) AnimationCB, (XTP) IG_EVENT_ANIMATION);

    Form = CreateSubForm(TransForm, Pos++);        
    Button = XtVaCreateManagedWidget("Environment",
				     xmPushButtonWidgetClass, 	Form, 
				     XmNleftAttachment, 	XmATTACH_FORM,
				     XmNrightAttachment, 	XmATTACH_FORM,
				     NULL);
    XtAddCallback(Button, XmNactivateCallback,
		  (XTC) TransformCB, (XTP) IG_EVENT_STATE);

    Pos++;
    Form = CreateSubForm(TransForm, Pos++);        
    Button = XtVaCreateManagedWidget("Quit",
				     xmPushButtonWidgetClass, 	Form, 
				     XmNleftAttachment, 	XmATTACH_FORM,
				     XmNrightAttachment, 	XmATTACH_FORM,
				     NULL);
    XtAddCallback(Button, XmNactivateCallback,
		  (XTC) TransformCB, (XTP) IG_EVENT_QUIT);

    if (TRANS_FRACTION < Pos)
	fprintf(stderr,
		"Initialization of Transformation is not complete (%d).\n",
		Pos);
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Create and activate pop up window.  				     *
*                                                                            *
* PARAMETERS:                                                                *
*   w:  Calling widget.                                  		     *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void CreatePopupWindow(Widget w)
{
    int Pos = 0;
    char NewLabel[30];
    Arg args[10];

    XtSetArg(args[0], XmNfractionBase, STATE_FRACTION);
    StateForm = XmCreateFormDialog(w, "StateMenu", args, 1);

    AddButton(StateForm, IGGlblTransformMode == IG_TRANS_OBJECT ?
	      "Object Trans" : "Screen Trans", Pos++,
	      (XTC) TransformCB, (XTP) IG_EVENT_SCR_OBJ_TGL);
    DepthCueButton = AddButton(StateForm,
			       IGGlblDepthCue ? "Depth Cue On"
					      : "No Depth Cue",
			       Pos++, (XTC) TransformCB,
			       (XTP) IG_EVENT_DEPTH_CUE);
    ProjectionButton = AddButton(StateForm,
				 IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
				     "Perspective" : "Orthographic",
				 Pos++, (XTC) TransformCB,
				 (XTP) IG_EVENT_PERS_ORTHO_TGL);
    AddButton(StateForm, IGGlblDrawSolid ? "Draw Solid" : "Draw Wireframe",
	      Pos++, (XTC) SetCB, (XTP) IG_STATE_DRAW_SOLID);
    switch (IGGlblShadingModel) {
	case IG_SHADING_NONE:
	    AddButton(StateForm, "No Shading", Pos++,
		      (XTC) SetCB, (XTP) IG_STATE_SHADING_MODEL);
	    break;
	case IG_SHADING_FLAT:
	    AddButton(StateForm, "Flat Shading", Pos++,
		      (XTC) SetCB, (XTP) IG_STATE_SHADING_MODEL);
	    break;
	case IG_SHADING_GOURAUD:
	    AddButton(StateForm, "Gouraud Shading", Pos++,
		      (XTC) SetCB, (XTP) IG_STATE_SHADING_MODEL);
	    break;
	case IG_SHADING_PHONG:
	    AddButton(StateForm, "Phong Shading", Pos++,
		      (XTC) SetCB, (XTP) IG_STATE_SHADING_MODEL);
	    break;
    }
    AddButton(StateForm, IGGlblBackFaceCull ? "Cull Back Face"
					    : "No Cull Back Face",
	      Pos++, (XTC) SetCB, (XTP) IG_STATE_BACK_FACE_CULL);
    AddButton(StateForm, IGGlblDoDoubleBuffer ? "Double Buffer"
					      : "Single Buffer",
	      Pos++, (XTC) SetCB, (XTP) IG_STATE_DOUBLE_BUFFER);
    AddButton(StateForm, IGGlblAntiAliasing ? "Anti Aliasing"
					    : "No Anti Aliasing",
	      Pos++, (XTC) SetCB, (XTP) IG_STATE_ANTI_ALIASING);
    AddButton(StateForm, IGGlblDrawInternal ? "Draw Internal Edges"
					    : "No Internal Edges",
	      Pos++, (XTC) SetCB, (XTP) IG_STATE_DRAW_INTERNAL);
    AddButton(StateForm, IGGlblDrawVNormal ? "Draw Vrtx Normals"
					   : "No Vrtx Normals",
	      Pos++, (XTC) SetCB, (XTP) IG_STATE_DRAW_VNORMAL);
    AddButton(StateForm, IGGlblDrawPNormal ? "Draw Poly Normals"
					   : "No Poly Normals",
	      Pos++, (XTC) SetCB, (XTP) IG_STATE_DRAW_PNORMAL);
    AddButton(StateForm, IGGlblDrawSurfaceMesh ? "Draw Surface Mesh"
					       : "No Surface Mesh",
	      Pos++, (XTC) SetCB, (XTP) IG_STATE_DRAW_SRF_MESH);
    AddButton(StateForm, IGGlblDrawSurfacePoly ? "Surface Poly"
					       : "Surface Isolines",
	      Pos++, (XTC) SetCB, (XTP) IG_STATE_DRAW_SRF_POLY);
    AddButton(StateForm, IGGlblFourPerFlat ? "Four Per Flat" : "Two Per Flat",
	      Pos++, (XTC) SetCB, (XTP) IG_STATE_FOUR_PER_FLAT);

    sprintf(NewLabel, "Normal Len %2.2f", IGGlblNormalLen);
    NormalLenLabel = AddLabel(StateForm, NewLabel, Pos++);
    AddSlide(StateForm, Pos++, 100,
	     (XTC) SetCB, (XTP) IG_STATE_LONGER_VECTORS);
    sprintf(NewLabel, "Lines Width %d", IGGlblLineWidth);
    LineWidthLabel = AddLabel(StateForm, NewLabel, Pos++);
    AddSlide(StateForm, Pos++, 20,
	     (XTC) SetCB, (XTP) IG_STATE_WIDER_LINES);
    sprintf(NewLabel, "Sensitivity %2.2f", IGGlblChangeFactor);
    ChangeFactorLabel = AddLabel(StateForm, NewLabel, Pos++);
    AddSlide(StateForm, Pos++, 100,
	     (XTC) SetCB, (XTP) IG_STATE_MORE_SENSITIVE);
    sprintf(NewLabel, "Isolines %2d", IGGlblNumOfIsolines);
    NumOfIsolinesLabel = AddLabel(StateForm, NewLabel, Pos++);
    AddSlide(StateForm, Pos++, 1000,
	     (XTC) SetCB, (XTP) IG_STATE_MORE_ISOLINES);
    sprintf(NewLabel, "Samples %2d", IGGlblSamplesPerCurve);
    FineNessLabel = AddLabel(StateForm, NewLabel, Pos++);
    AddSlide(StateForm, Pos++, 1000,
	     (XTC) SetCB, (XTP) IG_STATE_FINER_APPROX);

    AddButton(StateForm, "Dismiss", Pos++, (XTC) SetCB, (XTP) IG_STATE_OOPS);

    if (STATE_FRACTION < Pos)
	fprintf(stderr,
		"Initialization of Popup State is not complete (%d).\n",
		Pos);
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Handles transformation window Buttons.  				     *
*                                                                            *
* PARAMETERS:                                                                *
*   w:      Calling widget.                                  		     *
*   State:  State represented by the widget.			             *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void TransformCB(Widget w, IGGraphicEventType State)
{
    Position MainWindowX, MainWindowY;
    Dimension MainWindowW;
    RealType ChangeFactor[2];

    switch (State) {
	case IG_EVENT_DEPTH_CUE:
	    IGGlblDepthCue = !IGGlblDepthCue;
	    SetLabel(w, IGGlblDepthCue ? "Depth Cue On" : "No Depth Cue");
	    IGRedrawViewWindow();
	    break;
	case IG_EVENT_SCR_OBJ_TGL:
	    IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ? 
					    IG_TRANS_SCREEN : IG_TRANS_OBJECT;
	    SetLabel(w, IGGlblTransformMode == IG_TRANS_SCREEN ? 
					     "Screen Trans" :"Object Trans");
	    break;
	case IG_EVENT_PERS_ORTHO_TGL:
	    IGGlblViewMode = IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
				   IG_VIEW_ORTHOGRAPHIC : IG_VIEW_PERSPECTIVE;
	    IGRedrawViewWindow();
	    SetLabel(w, IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
					     "Perspective": "Orthographic");
	    break;
	case IG_EVENT_STATE:
	    XtVaGetValues(IGTopLevel,
			  XmNwidth, &MainWindowW,
			  XmNx,     &MainWindowX,
			  XmNy,     &MainWindowY,
			  NULL);
	    XtVaSetValues(StateForm,
			  XmNdefaultPosition, FALSE,
			  XmNx,               MainWindowX + MainWindowW + 16,
			  XmNy,               MainWindowY,
			  NULL); 
	    XtManageChild(StateForm); 
	    break;	
	case IG_EVENT_QUIT:
	    if (!IGGlblStandAlone)
		IritPrsrClntCloseConnect(IGGlblPrgmInput, IGGlblPrgmOutput);
	    exit(0);
	default:
	    ChangeFactor[0] = ChangeFactor[1] = 1.0;
	    if (IGProcessEvent(State, ChangeFactor)) 
		IGRedrawViewWindow();
    }
}       

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Treat exposure event.		  				     *
*                                                                            *
* PARAMETERS:                                                                *
*   w:  Calling widget.                                                      *
*                                                                            *
* RETURN VALUE:                                                              *
*   FALSE:  Keep the working function alive.   			             *
*****************************************************************************/
static int ExposeCB(Widget w)
{
    XEvent Event;
    XWindowAttributes WinAttr;

    if (!IGGlblStandAlone &&
        IGReadObjectsFromSocket(IGGlblViewMode, &IGGlblDisplayList))
        IGRedrawViewWindow();

    IGHandleInternalEvents();

    if (XPending(XDisplay)) {
	XNextEvent(XDisplay, &Event);

	switch (Event.type) {
	    case Expose:      /* Get rid of all Expose events in the queue. */
		while (XCheckWindowEvent(XDisplay, Event.xbutton.window,
					 ExposureMask, &Event));
		if (Event.xbutton.window == ViewWndw) {
		    XGetWindowAttributes(XDisplay, ViewWndw, &WinAttr);
		    ViewWidth = WinAttr.width;
		    ViewHeight = WinAttr.height;
		    IGRedrawViewWindow();
		}
	    case ResizeRequest:/* Get rid of all Resize events in the queue.*/
		while (XCheckWindowEvent(XDisplay, Event.xbutton.window,
					 ResizeRedirectMask, &Event));
		if (Event.xbutton.window == ViewWndw) {
		    XGetWindowAttributes(XDisplay, ViewWndw, &WinAttr);
		    ViewWidth = WinAttr.width;
		    ViewHeight = WinAttr.height;
		    IGRedrawViewWindow();
		}
	}
    }

    IritSleep(10);

    return FALSE;     /* Make sure it will be called next time we are idle. */
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Responds to settings commands.	  				     *
*                                                                            *
* PARAMETERS:                                                                *
*   w:         Calling widget.                                 		     *
*   State:     State represented by widget.				     *
*   CallData:  For detecting drag/click action on scales.		     *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void SetCB(Widget w, int State, XmScaleCallbackStruct *CallData)
{    
    int Value, NewValue;
    char NewLabel[30];
 
    switch (State) {
	case IG_STATE_LONGER_VECTORS: 
            XmScaleGetValue(w, &NewValue);
	    IGGlblNormalLen *= (float) exp(IGGlblChangeFactor *
					(NewValue - OldSliderVal) / 75);
	    IGGlblPointWidth *= (float) exp(IGGlblChangeFactor *
					(NewValue - OldSliderVal) / 75);
	    IGRedrawViewWindow();
	    sprintf(NewLabel, "Normal Len %2.2f", IGGlblNormalLen);
	    SetLabel(NormalLenLabel, NewLabel);
	    break;
	case IG_STATE_OOPS:
	    XtUnmanageChild(StateForm); 
	    break;
	case IG_STATE_MORE_SENSITIVE:
	    XmScaleGetValue(w, &NewValue);
	    IGGlblChangeFactor *= (float) exp((NewValue - OldSliderVal) / 75);
	    sprintf(NewLabel, "Sensitivity %2.2f", IGGlblChangeFactor);
	    SetLabel(ChangeFactorLabel, NewLabel);
	    break;
	case IG_STATE_SHADING_MODEL:
	    switch (IGGlblShadingModel) {
		case IG_SHADING_NONE:
		    IGGlblShadingModel = IG_SHADING_FLAT;
		    SetLabel(w, "Flat Shading");
		    break;
		case IG_SHADING_FLAT:
		    IGGlblShadingModel = IG_SHADING_GOURAUD;
		    SetLabel(w, "Gouraud Shading");
		    break;
		case IG_SHADING_GOURAUD:
		    IGGlblShadingModel = IG_SHADING_PHONG;
		    SetLabel(w, "Phong Shading");
		    break;
		case IG_SHADING_PHONG:
		    IGGlblShadingModel = IG_SHADING_NONE;
		    SetLabel(w, "No Shading");
		    break;
	    }
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_DRAW_SOLID:
	    IGGlblDrawSolid = !IGGlblDrawSolid;
	    SetLabel(w, IGGlblDrawSolid ? "Draw Solid" : "Draw Wireframe");

	    /* And disable depth cueing. */
	    IGGlblDepthCue = TRUE;
	case IG_STATE_DEPTH_CUE:
	    IGGlblDepthCue = !IGGlblDepthCue;
	    SetLabel(DepthCueButton,
		     IGGlblDepthCue ? "Depth Cue On" : "No Depth Cue");
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_BACK_FACE_CULL:
	    IGGlblBackFaceCull = !IGGlblBackFaceCull;
	    SetLabel(w, IGGlblBackFaceCull ? "Cull Back Face"
					   : "No Cull Back Face");
	    IGRedrawViewWindow();
	    break;	
	case IG_STATE_DOUBLE_BUFFER: 
	    IGGlblDoDoubleBuffer = !IGGlblDoDoubleBuffer;
	    SetLabel(w, IGGlblDoDoubleBuffer ? "Double Buffer"
					     : "Single Buffer");
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_WIDER_LINES:
	    XmScaleGetValue(w, &NewValue);
	    IGGlblLineWidth += (int) ((NewValue - OldSliderVal) *
				      IGGlblChangeFactor);
	    IGGlblLineWidth = (IGGlblLineWidth > 1) ? IGGlblLineWidth : 1;
	    sprintf(NewLabel, "Lines Width %d", IGGlblLineWidth);
	    SetLabel(LineWidthLabel, NewLabel);
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_MORE_ISOLINES:
	    XmScaleGetValue(w, &NewValue);
	    Value = (int) (IGGlblNumOfIsolines * 
			   exp(IGGlblChangeFactor * (NewValue - OldSliderVal)
								   / 1000.0));
	    IGGlblNumOfIsolines = Value != IGGlblNumOfIsolines ? Value :
	      Value + SIGN(NewValue - OldSliderVal);
	    IGGlblNumOfIsolines = IGGlblNumOfIsolines > 2 ?
						      IGGlblNumOfIsolines : 2;
	    sprintf(NewLabel, "Isolines %d", IGGlblNumOfIsolines);
	    SetLabel(NumOfIsolinesLabel, NewLabel);
	    IGActiveListFreeNamedAttribute(IGGlblDisplayList, "_isoline");
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_FINER_APPROX:
	    XmScaleGetValue(w, &NewValue);
	    Value = (int) (IGGlblSamplesPerCurve *
			   exp(IGGlblChangeFactor * (NewValue - OldSliderVal)
								   / 1000.0));
	    IGGlblSamplesPerCurve = Value != IGGlblSamplesPerCurve ?
				Value :	Value + SIGN(NewValue - OldSliderVal);
	    IGGlblSamplesPerCurve = IGGlblSamplesPerCurve > 2 ?
						    IGGlblSamplesPerCurve : 2;
	    
	    Value = (int) (IGGlblFineNess *
			   exp( IGGlblChangeFactor * (NewValue - OldSliderVal)
								   / 1000.0));
	    IGGlblFineNess = Value != IGGlblFineNess ?
				Value : Value + SIGN(NewValue - OldSliderVal);
	    if (IGGlblFineNess < 2.0)
	        IGGlblFineNess = 2.0;

	    sprintf(NewLabel, "Samples %2d", IGGlblSamplesPerCurve);
	    SetLabel(FineNessLabel, NewLabel);
	    IGActiveListFreeNamedAttribute(IGGlblDisplayList, "_polygons");
	    IGActiveListFreeNamedAttribute(IGGlblDisplayList, "_isoline");
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_ANTI_ALIASING:
	    IGGlblAntiAliasing = !IGGlblAntiAliasing;
	    SetLabel(w, IGGlblAntiAliasing ? "Anti Aliasing"
					   : "No Anti Aliasing");
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_DRAW_INTERNAL:
	    IGDefaultStateHandler(State, FALSE);
	    SetLabel(w, IGGlblDrawInternal ? "Draw Internal Edges"
					   : "No Internal Edges");
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_DRAW_VNORMAL:
	    IGDefaultStateHandler(State, FALSE);	
	    SetLabel(w, IGGlblDrawVNormal ? "Draw Vrtx Normals"
					  : "No Vrtx Normals");
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_DRAW_PNORMAL:
	    IGDefaultStateHandler(State, FALSE);
	    SetLabel(w, IGGlblDrawPNormal ? "Draw Poly Normals"
					  : "No Poly Normals"); 
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_DRAW_SRF_MESH:
	    IGDefaultStateHandler(State, FALSE);
	    SetLabel(w, IGGlblDrawSurfaceMesh ? "Draw Surface Mesh"
					      : "No Surface Mesh");
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_DRAW_SRF_POLY:
	    IGDefaultStateHandler(State, FALSE); 
	    SetLabel(w, IGGlblDrawSurfacePoly ? "Surface Poly"
					      : "Surface Isolines"); 
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_FOUR_PER_FLAT:
	    IGDefaultStateHandler(State, FALSE);
	    SetLabel(w, IGGlblFourPerFlat ? "Four Per Flat" : "Two Per Flat");
	    IGRedrawViewWindow();
	    break;
	case IG_STATE_VIEW_FRONT:
	case IG_STATE_VIEW_SIDE:
	case IG_STATE_VIEW_TOP:
	case IG_STATE_VIEW_ISOMETRY:
	    SetLabel(ProjectionButton, "Orthographic");
	default:
	    IGDefaultStateHandler(State, FALSE);
	    IGRedrawViewWindow();
    }

    if (CallData -> reason == XmCR_DRAG) 
	OldSliderVal = NewValue;

    if (CallData -> reason == XmCR_VALUE_CHANGED) {
        XmScaleSetValue(w, 0);
	OldSliderVal =0;
    }
}  
/*****************************************************************************
* DESCRIPTION:                                                               *
*   Treats scales mouse-click movements.  				     *
*                                                                            *
* PARAMETERS:                                                                *
*   w:          Calling scale.			                             *
*   EventType:  Event represented by the calling scale.			     *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void ScaleCB(Widget w, IGGraphicEventType EventType)
{
    int NewValue;
    RealType ChangeFactor[2];

    XmScaleGetValue(w, &NewValue);
    XmScaleSetValue(w, 0);

    ChangeFactor[0] = IGGlblChangeFactor * (NewValue - OldSliderVal) / 100;
    ChangeFactor[1] = 0.0;
    if (IGProcessEvent(EventType, ChangeFactor))
	IGRedrawViewWindow(); 

    OldSliderVal = 0;
}
/*****************************************************************************
* DESCRIPTION:                                                               *
*   Treats scales mouse-drag movements.  				     *
*                                                                            *
* PARAMETERS:                                                                *
*   w:          Calling scale.		                                     *
*   EventType:  Event represented by the calling scale.			     *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void DragCB(Widget w, IGGraphicEventType EventType)
{
    int NewValue;
    RealType ChangeFactor[2];

    XmScaleGetValue(w, &NewValue);
    ChangeFactor[0] = IGGlblChangeFactor * (NewValue - OldSliderVal) / 100;
    ChangeFactor[1] = 0.0;
    if (IGProcessEvent(EventType, ChangeFactor))
        IGRedrawViewWindow();

    OldSliderVal = NewValue;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Creates a horizontal SubForm.	  				     M
*                                                                            *
* PARAMETERS:                                                                M
*   w:    Parent widget.			                             M
*   pos:  Position of SubForm within parent form.			     M
*                                                                            *
* RETURN VALUE:                                                              M
*   The positioned SubForm widget.					     M
*                                                                            *
* KEYWORDS:                                                                  M
*   CreateSubForm				       			     M
*****************************************************************************/
Widget CreateSubForm(Widget Parent, int Pos)
{
    return XtVaCreateManagedWidget("Form",
				   xmFormWidgetClass, 	Parent, 
				   XmNtopAttachment,	XmATTACH_POSITION,
				   XmNtopPosition,	Pos,
				   XmNbottomAttachment, XmATTACH_POSITION,
				   XmNbottomPosition,	Pos + 1,
				   XmNleftAttachment, 	XmATTACH_FORM,
				   XmNrightAttachment,  XmATTACH_FORM,
				   XmNresizable, 	FALSE,
				   NULL);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   A new label to an old widget.	  				     M
*                                                                            *
* PARAMETERS:                                                                M
*   w:         Calling widget.                                 		     M
*   NewLabel:  Widget's new Label.					     M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   SetLabel					       			     M
*****************************************************************************/
void SetLabel(Widget w, char *NewLabel)
{ 
    XmString LabelText;
    Arg Args[10];

    LabelText = XmStringCreate(NewLabel, "CharSet1");
    XtSetArg(Args[0], XmNlabelString, LabelText);
    XtSetValues(w, Args, 1);
    XmStringFree(LabelText);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Adds a push button to pop up menu.   				     M
*                                                                            *
* PARAMETERS:                                                                M
*   w:               Calling widget                        		     M
*   Label -	     The Label on the push button.			     M
*   Pos:  	     The position of the push button within the menu.	     M
*   FuncPtr, FuncEvent:  Call back function/event.			     M
*                                                                            *
* RETURN VALUE:                                                              M
*   A push button widget.                                                    M
*                                                                            *
* KEYWORDS:                                                                  M
*   AddButton					       			     M
*****************************************************************************/
Widget AddButton(Widget Parent,
		 char *Label,
		 int Pos,
		 XTC FuncPtr,
		 XTP FuncEvent)
{
    Widget
	Button = XtVaCreateManagedWidget(Label, 
		xmPushButtonWidgetClass,	CreateSubForm(Parent, Pos),
		XmNleftAttachment, 		XmATTACH_FORM,
		XmNrightAttachment, 		XmATTACH_FORM,
		NULL);

    XtAddCallback(Button, XmNactivateCallback, FuncPtr, FuncEvent);

    return Button;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Adds a label widget to the pop up menu.  				     M
*                                                                            *
* PARAMETERS:                                                                M
*   w:      Calling widget.      		                             M
*   Label:  The Label on the Label widget.				     M
*   Pos:    Widgets position within parent form.			     M
*                                                                            *
* RETURN VALUE:                                                              M
*   The newly created Label.                                                 M
*                                                                            *
* KEYWORDS:                                                                  M
*   AddLabel					       			     M
*****************************************************************************/
Widget AddLabel(Widget Parent, char *Label, int Pos)
{
    return XtVaCreateManagedWidget(Label,
			xmLabelWidgetClass,	CreateSubForm(Parent, Pos),
		 	XmNleftAttachment, 	XmATTACH_FORM,
			XmNrightAttachment, 	XmATTACH_FORM,
			NULL);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Adds a scale to the pop up menu.	  				     M
*                                                                            *
* PARAMETERS:                                                                M
*   w:               Parent widget.                                          M
*   pos:             Scale's position within menu.                           M
*   Range:           Scale's range.                                          M
*   FuncPtr, FuncEvent:  Call back function/event.			     M
*                                                                            *
* RETURN VALUE:                                                              M
*   The scale widget.                                                        M
*                                                                            *
* KEYWORDS:                                                                  M
*   AddSlide					       			     M
*****************************************************************************/
Widget AddSlide(Widget Parent,
		int Pos,
		int Range,
		XTC FuncPtr,
		XTP FuncEvent)
{
    Widget
	Slide = XtVaCreateManagedWidget("Slide",
			xmScaleWidgetClass, 	CreateSubForm(Parent, Pos),
			XmNorientation,		XmHORIZONTAL,
			XmNminimum,  		-Range,
			XmNrightAttachment, 	XmATTACH_FORM,
			XmNleftAttachment,   	XmATTACH_FORM,
			XmNmaximum,		Range,  NULL);

    XtAddCallback(Slide, XmNvalueChangedCallback, FuncPtr, FuncEvent);
    XtAddCallback(Slide, XmNdragCallback, FuncPtr, FuncEvent);

    return Slide;
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Reads one default from X resource data base.  			     *
*                                                                            *
* PARAMETERS:                                                                *
*  Entry:  The entry seeked.		                                     *
*                                                                            *
* RETURN VALUE:                                                              *
*   The entry's value.                                                       *
*****************************************************************************/
static char *ReadOneXDefault(char *Entry)
{
    XrmString Type;
    XrmValue Result;
    char Line[LINE_LEN_LONG];

    sprintf(Line, "%s.%s", RESOURCE_NAME, Entry);
    if (XrmGetResource(XrmGetDatabase(XDisplay), Line,
		       "Program.Name", &Type, &Result))
	return Result.addr;
    else
	return NULL;
}

/*****************************************************************************
* DESCRIPTION:                                                               *
*   Reads Defaults from X data base.  					     *
*                                                                            *
* PARAMETERS:                                                                *
*   void				                                     *
*                                                                            *
* RETURN VALUE:                                                              *
*   void                                                                     *
*****************************************************************************/
static void ReadXDefaults(void)
{
    int i;
    XColor Color;
    char *PanelBackGroundColor = ReadOneXDefault("Panel.BackGround"),
         *TransGeometry = ReadOneXDefault("Trans.Geometry"),
         *TransCursorColorStr = ReadOneXDefault("Trans.CursorColor"),
         *ViewBackGroundColor = ReadOneXDefault("View.BackGround"),
         *ViewTextColor = ReadOneXDefault("View.TextColor"),
         *ViewBorderColor = ReadOneXDefault("View.BorderColor"),
         *ViewBorderWidthStr = ReadOneXDefault("View.BorderWidth"),
         *ViewGeometry = ReadOneXDefault("View.Geometry"),
         *ViewCursorColorStr = ReadOneXDefault("View.CursorColor"),
         *MaxColorsStr = ReadOneXDefault("MaxColors");
    if (XParseColor(XDisplay, XColorMap, "Black", &BlackColor))
	XAllocColor(XDisplay, XColorMap, &BlackColor);

    if (PanelBackGroundColor != NULL)
       printf("Found Panel Backgoround \n");
		
    if (IGGlblTransPrefPos &&
	sscanf(IGGlblTransPrefPos, "%d,%d,%d,%d",
	       &TransPosX, &TransWidth, &TransPosY, &TransHeight) == 4) {
	TransWidth -= TransPosX;
	TransHeight -= TransPosY;
    }
    else if ((IGGlblTransPrefPos == NULL || strlen(IGGlblViewPrefPos) == 0) &&
	     TransGeometry) {
	i = XParseGeometry(TransGeometry, &TransPosX, &TransPosY,
		                          &TransWidth, &TransHeight);
    }

    if (TransCursorColorStr != NULL &&
	XParseColor(XDisplay, XColorMap, TransCursorColorStr, &Color) &&
	XAllocColor(XDisplay, XColorMap, &Color)) {
	TransCursorColor = (XColor *) IritMalloc(sizeof(XColor));
	*TransCursorColor = Color;
    }
    else
	TransCursorColor = NULL;

    if (ViewBackGroundColor &&
	XParseColor(XDisplay, XColorMap, ViewBackGroundColor, &Color) &&
	XAllocColor(XDisplay, XColorMap, &Color))
	ViewBackGroundPixel = Color.pixel;
    else
	ViewBackGroundPixel = BlackPixel(XDisplay, XScreen);

    if (ViewBorderColor &&
	XParseColor(XDisplay, XColorMap, ViewBorderColor, &Color) &&
	XAllocColor(XDisplay, XColorMap, &Color))
	ViewBorderPixel = Color.pixel;
    else
	ViewBorderPixel = WhitePixel(XDisplay, XScreen);

    if (ViewTextColor != NULL &&
	XParseColor(XDisplay, XColorMap, ViewTextColor, &Color) &&
	XAllocColor(XDisplay, XColorMap, &Color))
	ViewTextPixel = Color.pixel;
    else
	ViewTextPixel = WhitePixel(XDisplay, XScreen);

    if (ViewBorderWidthStr)
	ViewBorderWidth = atoi(ViewBorderWidthStr);
    else
	ViewBorderWidth = 1;

    if (IGGlblViewPrefPos &&
	sscanf(IGGlblViewPrefPos, "%d,%d,%d,%d",
	       &ViewPosX, &ViewWidth, &ViewPosY, &ViewHeight) == 4) {
	ViewWidth -= ViewPosX;
	ViewHeight -= ViewPosY;
	ViewHasSize = ViewHasPos = TRUE;
    }
    else if ((IGGlblViewPrefPos == NULL || strlen(IGGlblViewPrefPos) == 0) &&
	     ViewGeometry) {
	i = XParseGeometry(ViewGeometry, &ViewPosX, &ViewPosY,
		                         &ViewWidth, &ViewHeight);
	ViewHasPos = i & XValue && i & YValue;
	ViewHasSize = i & WidthValue && i & HeightValue;
    }
    else
	ViewHasSize = ViewHasPos = FALSE;

    if (ViewCursorColorStr != NULL &&
	XParseColor(XDisplay, XColorMap, ViewCursorColorStr, &Color) &&
	XAllocColor(XDisplay, XColorMap, &Color)) {
	ViewCursorColor = (XColor *) IritMalloc(sizeof(XColor));
	*ViewCursorColor = Color;
    }
    else
	ViewCursorColor = NULL;

    if (MaxColorsStr)
	MaxColors = atoi(MaxColorsStr);
    else
	MaxColors = IG_MAX_COLOR;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Makes some sound.                                                        M
*                                                                            *
* PARAMETERS:                                                                M
*   None                                                                     M
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGIritBeep                                                               M
*****************************************************************************/
void IGIritBeep(void)
{
    XBell(XDisplay, 0);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   Optionally construct a state pop up menu for the driver, if has one.     M
*                                                                            *
* PARAMETERS:                                                                M
*   None                                                                     *
*                                                                            *
* RETURN VALUE:                                                              M
*   void                                                                     M
*                                                                            *
* KEYWORDS:                                                                  M
*   IGCreateStateMenu                                                        M
*****************************************************************************/
void IGCreateStateMenu(void)
{
}
