
/* Copyright (C) 1992  AHPCRC, Univeristy of Minnesota
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program in a file named 'Copying'; if not, write to
 * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139.
 */

/* Author:
 *	Ken Chin-Purcell (ken@ahpcrc.umn.edu)
 *	Army High Performance Computing Research Center (AHPCRC)
 *	Univeristy of Minnesota
 *
 * $Header: /usr/people/ken/gvl/icol/RCS/setup.c,v 2.1 92/10/19 16:59:36 ken Exp $
 *
 * $Log:	setup.c,v $
 * Revision 2.1  92/10/19  16:59:36  ken
 * *** empty log message ***
 * 
 * Revision 1.1  92/10/19  16:58:14  ken
 * Initial revision
 * 
 */

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

#include <Xm/Xm.h>
#include <Xm/ArrowB.h>
#include <Xm/ArrowBG.h>
#include <Xm/BulletinB.h>
#include <Xm/CascadeB.h>
#include <Xm/CascadeBG.h>
#include <Xm/DialogS.h>
#include <Xm/DrawingA.h>
#include <Xm/DrawnB.h>
#include <Xm/FileSB.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/Label.h>
#include <Xm/LabelG.h>
#include <Xm/List.h>
#include <Xm/MessageB.h>
#include <Xm/PanedW.h>
#include <Xm/PushB.h>
#include <Xm/PushBG.h>
#include <Xm/RowColumn.h>
#include <Xm/Scale.h>
#include <Xm/ScrollBar.h>
#include <Xm/ScrolledW.h>
#include <Xm/SeparatoG.h>
#include <Xm/Separator.h>
#include <Xm/Text.h>
#include <Xm/TextF.h>
#include <Xm/ToggleB.h>
#include <Xm/ToggleBG.h>

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

#include "util.h"
#include "xtutil.h"
#include "cbar.h"
#include "file.h"
#include "abar.h"
#include "icol.h"
#include "setup.h"

extern void	exit(int);

#ifdef USE_ANSI_OFFSET
#undef	XtOffsetOf
#define XtOffsetOf(a,b)	(int) offsetof(a, b)
#endif


#define RFileFormat "FileFormat"
#define RColorMode  "ColorMode"

#define IcolOff(member)	XtOffsetOf(struct _Icol, member)

static XtResource resources[] = {
    { "numColor", "NumColor",		XtRInt, sizeof(int),
	  IcolOff(ncolor),		XtRImmediate, (XtPointer) 256 },
    { "maxUndo", "MaxUndo",		XtRInt, sizeof(int),
	  IcolOff(maxundo),		XtRImmediate, (XtPointer) 40 },
    { "rootVisual", "RootVisual",	XtRBoolean, sizeof(int),
	  IcolOff(rootvis),		XtRImmediate, (XtPointer) 0 },
    { "fileFormat", "FileFormat",	RFileFormat, sizeof(FileFormat),
	  IcolOff(format),		XtRImmediate, (XtPointer) ASCII_INDEX },
    { "colorGuide", "ColorGuide",	XtRBoolean, sizeof(int),
	  IcolOff(colorAxis),		XtRImmediate, (XtPointer) 0 },
    { "colorMode", "ColorMode",		RColorMode, sizeof(int),
	  IcolOff(rgbmode),		XtRImmediate, (XtPointer) RGB_MODE },
    { "openName", "OpenName",		XtRString, sizeof(String),
	  IcolOff(openname),		XtRImmediate, (XtPointer) 0 },
    { "output", "Output",		XtRString, sizeof(String),
	  IcolOff(savename),		XtRImmediate, (XtPointer) 0 },
    { "autoSave", "AutoSave",		XtRBoolean, sizeof(int),
	  IcolOff(autosave),		XtRImmediate, (XtPointer) 0 },
    { "stomp", "Stomp",			XtRBoolean, sizeof(int),
	  IcolOff(stomp),		XtRImmediate, (XtPointer) 0 },
    { "help", "Help",			XtRBoolean, sizeof(int),
	  IcolOff(help),		XtRImmediate, (XtPointer) 0 },
    { "bugAddress", "BugAddress",	XtRString, sizeof(String),
	IcolOff(bugAddr), XtRImmediate, (XtPointer) "gvlware@ahpcrc.umn.edu" },
    { "quickSegment", "QuickSegment",	XtRInt, sizeof(int),
	  IcolOff(quickSeg),		XtRImmediate, (XtPointer) 48 },
    { "stompBase", "StompBase",		XtRInt, sizeof(int),
	  IcolOff(stompbase),		XtRImmediate, (XtPointer) 0 },
    { "slopeDiff", "SlopeDiff",		XtRInt, sizeof(int),
	  IcolOff(slopediff),		XtRImmediate, (XtPointer) 10 },
    { "showCopyright", "ShowCopyright",	XtRBoolean, sizeof(int),
	  IcolOff(showCopyright),	XtRImmediate, (XtPointer) 1 },
    { "expert", "Expert",		XtRInt, sizeof(int),
	  IcolOff(expert),		XtRImmediate, (XtPointer) 0 },
};


static  XrmOptionDescRec options[] = {
    { "-help",		"help",		XrmoptionNoArg,		"1" },
    { "-h",		"help",		XrmoptionNoArg,		"1" },
    { "-numcolor",	"numColor",	XrmoptionSepArg,	NULL},
    { "-n",		"numColor",	XrmoptionSepArg,	NULL},
    { "-maxundo",	"maxUndo",	XrmoptionSepArg,	NULL},
    { "-u",		"maxUndo",	XrmoptionSepArg,	NULL},
    { "-rootvis",	"rootVisual",	XrmoptionNoArg,		"1" },
    { "-r",		"rootVisual",	XrmoptionNoArg,		"1" },
    { "-format",	"fileFormat",	XrmoptionSepArg,	NULL},
    { "-f",		"fileFormat",	XrmoptionSepArg,	NULL},
    { "-colorguide",	"colorGuide",	XrmoptionNoArg,		"1" },
    { "-g",		"colorGuide",	XrmoptionNoArg,		"1" },
    { "-output",	"output",	XrmoptionSepArg,	NULL},
    { "-o",   		"output",	XrmoptionSepArg,	NULL},
    { "-colormode",   	"colorMode",	XrmoptionSepArg,	NULL},
    { "-m",  	 	"colorMode",	XrmoptionSepArg,	NULL},
    { "-autosave",	"autoSave",	XrmoptionNoArg,		"1" },
    { "-a",		"autoSave",	XrmoptionNoArg,		"1" },
    { "-stomp",		"stomp",	XrmoptionNoArg,		"1" },
    { "-s",		"stomp",	XrmoptionNoArg,		"1" },
    { "-base",		"stompBase",	XrmoptionSepArg,	NULL},
    { "-b",		"stompBase",	XrmoptionSepArg,	NULL},
    { "-slopediff",	"slopeDiff",	XrmoptionSepArg,	NULL},
    { "-d",		"slopeDiff",	XrmoptionSepArg,	NULL},
    { "-x",		"expert",	XrmoptionNoArg,		"1" },
};


static void Usage(void)
{
    Error("\n");
    Error("  usage: icol [ options ] input_file\n");
    Error("   	-output | -o  file	Output file, - for stdout\n");
    Error("   	-autosave | -a		Write to output after each change\n");
    Error("   	-colormode | -m  mode	Color mode (rgb, hsv, yuv)\n");
    Error("   	-colorguide | -g	Colorize scale background\n");
    Error("   	-stomp | -s		Stomp on the lowest color indecies\n");
    Error("   	-format | -f  name	File format\n");
    Error("   	-numcolor | -n  ##	Colors in map (256 default)\n");
    Error("   	-maxundo | -u  ##	Maximum changes in undo stack\n");
    Error("   	-rootvis | -r		Use the same visual as the root\n");
    Error("	-help | -h		This message\n");
    Error ("\n");
    
    exit(0);
}


#define CaseMatch(sa,sb) (strncasecmp(sa, sb, strlen(sb)) == 0)


#define done(address, type) \
        { (*toVal).size = sizeof(type); (*toVal).addr = (caddr_t) address; }

/* ARGSUSED */
static void CvtStringToFileFormat(XrmValue *args, Cardinal *num_args,
				  XrmValuePtr fromVal, XrmValuePtr toVal)
{
    static FileFormat	format;
    char		*xrmStr = (char *) fromVal->addr;
    
    if (CaseMatch(xrmStr, "asciiIndex")) {
	format = ASCII_INDEX;
	done(&format, FileFormat);
    } else if (CaseMatch(xrmStr, "asciiPlain")) {
	format = ASCII_PLAIN;
	done(&format, FileFormat);
    } else if (CaseMatch(xrmStr, "binLeave")) {
	format = BIN_LEAVE;
	done(&format, FileFormat);
    } else if (CaseMatch(xrmStr, "binRow")) {
	format = BIN_ROW;
	done(&format, FileFormat);
    } else
	XtStringConversionWarning(xrmStr, "FileFormat");
}

/* ARGSUSED */
static void CvtStringToColorMode(XrmValue *args, Cardinal *num_args,
				 XrmValuePtr fromVal, XrmValuePtr toVal)
{
    static ColorMode	cmode;
    char		*xrmStr = (char *) fromVal->addr;
    
    if (CaseMatch(xrmStr, "rgb")) {
	cmode = RGB_MODE;
	done(&cmode, ColorMode);
    } else if (CaseMatch(xrmStr, "hsv")) {
	cmode = HSV_MODE;
	done(&cmode, ColorMode);
    } else if (CaseMatch(xrmStr, "yuv")) {
	cmode = YUV_MODE;
	done(&cmode, ColorMode);
    } else if (CaseMatch(xrmStr, "alpha")) {
	cmode = ALPHA_MODE;
	done(&cmode, ColorMode);
    } else
	XtStringConversionWarning(xrmStr, "ColorMode");
}


#include "square.x"
#include "circle.x"
#include "diamond.x"

void CreateBitmap(Widget w, int id)
{
    Window	root = RootWindowOfScreen(XtScreen(w));
    Pixmap	pix = 0;
    int		depth;
    Pixel	fg, bg;

    /* Create the bitmaps using the root window, because
     * This widget may not be realized yet.
     */

    GetValue(XmNdepth, &depth, (Widget) NULL);
    GetValue(XmNforeground, &fg, (Widget) NULL);
    GetValue(XmNbackground, &bg, w);
    
    if (id == 0)
	pix = XCreatePixmapFromBitmapData(XtDisplay(w), root, square_bits, 
					  square_width, square_height,
					  fg, bg, depth);
    else if (id == 1)
	pix = XCreatePixmapFromBitmapData(XtDisplay(w), root, circle_bits, 
					  circle_width, circle_height,
					  fg, bg, depth);
    else if (id == 2)
	pix = XCreatePixmapFromBitmapData(XtDisplay(w), root, diamond_bits,
					  diamond_width, diamond_height,
					  fg, bg, depth);

    if (pix)
	SetValue(XmNlabelPixmap, (XtArgVal) pix, w);
}


/* I suppose I should implement the darn help buttons,
 * instead of removing them...
 */
void RemoveHelp(Widget w)
{
    Widget	help = NULL;

    if (XtIsSubclass(w, xmFileSelectionBoxWidgetClass))
	help = XmFileSelectionBoxGetChild(w, XmDIALOG_HELP_BUTTON);
    else if (XtIsSubclass(w, xmMessageBoxWidgetClass))
	help = XmMessageBoxGetChild(w, XmDIALOG_HELP_BUTTON);
    if (help)
	XtUnmanageChild(help);
}


void RemoveCancel(Widget w)
{
    Widget	cancel = NULL;

    if (XtIsSubclass(w, xmFileSelectionBoxWidgetClass))
	cancel = XmFileSelectionBoxGetChild(w, XmDIALOG_CANCEL_BUTTON);
    else if (XtIsSubclass(w, xmMessageBoxWidgetClass))
	cancel = XmMessageBoxGetChild(w, XmDIALOG_CANCEL_BUTTON);
    if (cancel)
	XtUnmanageChild(cancel);
}


#ifdef USEFALLBACK
static String fallbackResources[] = { 
#include "fallback.h"
    NULL,
};
#else
static String *fallbackResources = NULL;
#endif


static void MakeShell(unsigned int *argc, char *argv[])
{
    Display		*display;
    Screen		*screen;
    XVisualInfo		*vinfo;
    XtAppContext	app;
    Arg 		arg[10];
    int			savecolor;
    int			i;
#if XtSpecificationRelease <= 4
    Cardinal		narg = *argc;
#else
    int			narg = *argc;
#endif

    /* Crank up Xt
     */
    XtToolkitInitialize();
    app = XtCreateApplicationContext();

    XtAddConverter(XtRString, RFileFormat, CvtStringToFileFormat, NULL, 0);
    XtAddConverter(XtRString, RColorMode, CvtStringToColorMode, NULL, 0);

    if (fallbackResources)
	XtAppSetFallbackResources(app, fallbackResources);

    display = XtOpenDisplay(app, NULL, NULL, "Icol", 
			    options, XtNumber(options), &narg, argv);
    *argc = narg;
    if (!display) 
	XtAppError(app, "Cannot connect to X server.  Is DISPLAY set?");

    screen = DefaultScreenOfDisplay(display);


    /* Create a phony shell so defaults can be grabbed.
     */
    icol->shell = XtAppCreateShell(NULL, "Icol", applicationShellWidgetClass,
				   display, NULL, 0);
    XtGetApplicationResources(icol->shell, (XtPointer) icol,
			      resources, XtNumber(resources), NULL, 0);
    XtDestroyWidget(icol->shell);

    if (icol->help)
	Usage();
    if (icol->ncolor < 4)
	icol->ncolor = 4;
    if (icol->maxundo < 2)
	icol->maxundo = 2;
    

    /* Now we know what to do to create the real shell.
     * First find the best visual, then make a decision about 
     * how to use the color map (bigmap).
     */
    if (icol->rootvis)
	vinfo = FindRootVisual(display, screen);
    else
	vinfo = FindDeepestPseudoVisual(display, screen);
    if (!vinfo  ||  vinfo->class != PseudoColor)
	XtAppError(app, "Icol needs mapped color (PseudoColor) graphics");

    icol->usualmap = XCreateColormap(display, RootWindowOfScreen(screen), 
				     vinfo->visual, AllocNone);
    icol->stompmap = XCreateColormap(display, RootWindowOfScreen(screen), 
				     vinfo->visual, AllocAll);
    icol->cmap = icol->usualmap;
    icol->mapsize = vinfo->colormap_size;

    savecolor = MIN(256, CellsOfScreen(screen));

    if (icol->mapsize > 
	MAX(savecolor, icol->ncolor) + icol->ncolor + 128) {
	icol->bigmap = 1;
	icol->colorAxis = 1;
    } else
	icol->bigmap = 0;

    if (icol->bigmap) {
	CopyColormap(display, DefaultColormapOfScreen(screen), 
		     icol->cmap, savecolor);
	if (icol->ncolor > savecolor) {
	    Pixel	*holdPix = CallocType(Pixel, icol->ncolor);
	    int		holdNum = icol->ncolor;
	    
	    MemCheck(holdPix);
	    SwallowCells(display, icol->cmap, holdPix, &holdNum);
	    free(holdPix);
	}
    } else
	AllocBlack(display, screen, icol->cmap);
    

    /* Create a shell using the visual and colormap desired.	
     */
    i = 0;
    XtSetArg(arg[i], XmNvisual, vinfo->visual);	i++;
    XtSetArg(arg[i], XmNdepth, vinfo->depth);	i++;
    XtSetArg(arg[i], XmNcolormap, icol->cmap); 	i++;
    XtSetArg(arg[i], XmNscreen, screen);	i++;
    icol->shell = XtAppCreateShell(NULL, "Icol", applicationShellWidgetClass,
				   display, arg, i);

    icol->display = display;
    icol->app = app;
}


static void MakeAxisBar(void)
{
    Widget	*wl;
    Widget	scroll[3];
    Widget	scale[3];
    Cardinal	wn;
    int		i, j;
    
    if (!icol->colorAxis)
	return;
    
    scale[0] = GetWidget("redScale");
    scale[1] = GetWidget("grnScale");
    scale[2] = GetWidget("bluScale");
    
    /* Find scroll bars inside Scales
     */
    for (i = 0; i < 3; ++i) {
	GetValue(XmNchildren, &wl, (Widget) NULL);
	GetValue(XmNnumChildren, &wn, scale[i]);
	for (j = 0; j < wn; ++j)
	    if (XtIsSubclass(wl[j], xmScrollBarWidgetClass)) {
		scroll[i] = wl[j];
		break;
	    }
	if (j == wn)
	    return;
    }
    
    icol->abar = AxisBarNew(scroll);
    icol->colorAxis = icol->abar != NULL;
}


static void MakeScaleString(void)
{
    icol->scaleString[0][0] = MakeXmString("Red");
    icol->scaleString[0][1] = MakeXmString("Green");
    icol->scaleString[0][2] = MakeXmString("Blue");
    
    icol->scaleString[1][0] = MakeXmString("Hue");
    icol->scaleString[1][1] = MakeXmString("Sat.");
    icol->scaleString[1][2] = MakeXmString("Value");

    icol->scaleString[2][0] = MakeXmString("Y");
    icol->scaleString[2][1] = MakeXmString("U");
    icol->scaleString[2][2] = MakeXmString("V");

    icol->scaleString[3][0] = MakeXmString("Alpha");

    icol->snapString[0][0] = MakeXmString("Snap Red");
    icol->snapString[0][1] = MakeXmString("Snap Green");
    icol->snapString[0][2] = MakeXmString("Snap Blue");
    
    icol->snapString[1][0] = MakeXmString("Snap Hue");
    icol->snapString[1][1] = MakeXmString("Snap Saturation");
    icol->snapString[1][2] = MakeXmString("Snap Value");
    
    icol->snapString[2][0] = MakeXmString("Snap Y");
    icol->snapString[2][1] = MakeXmString("Snap U");
    icol->snapString[2][2] = MakeXmString("Snap V");

    icol->snapString[3][0] = MakeXmString("Snap Alpha");
}


static WidgetSpec widgetSpec[] = {
    { 0x110, "main",		XmCreateForm },
    
    { 0x101, "fsBox",		XmCreateFileSelectionDialog },
    { 0x110, "radioForm",	XmCreateForm },
    { 0x000, "radioLabel",	XmCreateLabel },
    { 0x110, "radioFrame",	XmCreateFrame },
    { 0x110, "radio",		XmCreateRadioBox },
    { 0x000, "asciiIndex",	XmCreateToggleButtonGadget },
    { 0x000, "asciiPlain",	XmCreateToggleButtonGadget },
    { 0x000, "binLeave",	XmCreateToggleButtonGadget },
    { 0x010, "binRow",		XmCreateToggleButtonGadget },
    
    { 0x001, "quitBox",		XmCreateQuestionDialog },
    
    { 0x101, "bugBox",		XmCreateFormDialog },
    { 0x000, "send",		XmCreatePushButtonGadget },
    { 0x000, "cancel",		XmCreatePushButtonGadget },
    { 0x000, "sep",		XmCreateSeparatorGadget },
    { 0x010, "bugText",		XmCreateText },
    
    { 0x001, "fileError",	XmCreateErrorDialog },
    
    { 0x001, "copyright",	XmCreateInformationDialog },
    
    { 0x100, "menuBar",		XmCreateMenuBar },

    { 0x000, "control",		XmCreateCascadeButtonGadget },
    { 0x101, "controlMenu",	XmCreatePulldownMenu },
    { 0x000, "open",		XmCreatePushButtonGadget },
    { 0x000, "save",		XmCreatePushButtonGadget },
    { 0x000, "sepMenu",		XmCreateSeparatorGadget },
    { 0x000, "geti",		XmCreatePushButtonGadget },
    { 0x000, "seti",		XmCreatePushButtonGadget },
    { 0x000, "sepMenu",		XmCreateSeparatorGadget },
    { 0x000, "grabColor",	XmCreatePushButtonGadget },
    { 0x000, "setColor",	XmCreatePushButtonGadget },
    { 0x000, "pickColor",	XmCreatePushButtonGadget },
    { 0x000, "sepMenu",		XmCreateSeparatorGadget },
    { 0x010, "quit",		XmCreatePushButtonGadget },
	   
    { 0x000, "edit",		XmCreateCascadeButtonGadget },
    { 0x101, "editMenu",	XmCreatePulldownMenu },
    { 0x000, "undo",		XmCreatePushButtonGadget },
    { 0x000, "redo",		XmCreatePushButtonGadget },
    { 0x000, "sepMenu",		XmCreateSeparatorGadget },
    { 0x000, "snap",		XmCreatePushButtonGadget },
    { 0x000, "snapAll",		XmCreatePushButtonGadget },
    { 0x000, "placeKnot",	XmCreatePushButtonGadget },
    { 0x000, "sepMenu",		XmCreateSeparatorGadget },
    { 0x000, "snap1",		XmCreatePushButton },
    { 0x000, "snap2",		XmCreatePushButton },
    { 0x010, "snap3",		XmCreatePushButton },

    { 0x000, "mode",		XmCreateCascadeButtonGadget },
    { 0x101, "modeMenu",	XmCreatePulldownMenu },
    { 0x000, "rgb",		XmCreateToggleButton },
    { 0x000, "hsv",		XmCreateToggleButton },
    { 0x000, "yuv",		XmCreateToggleButton },
    { 0x000, "alpha",		XmCreateToggleButton },
    { 0x000, "sepMenu",		XmCreateSeparatorGadget },
    { 0x000, "auto",		XmCreateToggleButton },
    { 0x000, "autoi",		XmCreateToggleButton },
    { 0x010, "stomp",		XmCreateToggleButton },

    { 0x000, "brush",		XmCreateCascadeButtonGadget },
    { 0x110, "brushMenu",	XmCreatePulldownMenu },
    { 0x000, "square",		XmCreateToggleButton },
    { 0x000, "circle",		XmCreateToggleButton },
    { 0x010, "diamond",		XmCreateToggleButton },

    { 0x000, "ahpcrc",		XmCreatePushButton },

    { 0x100, "rgbForm",		XmCreateForm },
    { 0x000, "cellLabel",	XmCreateLabel },
    { 0x000, "redLabel",	XmCreateLabel },
    { 0x000, "grnLabel",	XmCreateLabel },
    { 0x000, "bluLabel",	XmCreateLabel },
    { 0x000, "redScale",	XmCreateScale },
    { 0x000, "grnScale",	XmCreateScale },
    { 0x010, "bluScale",	XmCreateScale },

    { 0x000, "paneSep",		XmCreateSeparator },

    { 0x110, "pane",		XmCreatePanedWindow },

    { 0x100, "chartFrame",	XmCreateFrame },
    { 0x010, "chart",		XmCreateDrawingArea },

    { 0x110, "buttonFrame",	XmCreateFrame },
    { 0x010, "button",		XmCreateDrawingArea },
    { 0x000, NULL,		NULL }			/*ENDTABLE*/
};


static char dragTranslations[] =
"<BtnDown>: 	DrawingAreaInput() \n\
 <BtnUp>: 	DrawingAreaInput() \n\
 <BtnMotion>: 	DrawingAreaInput()";

static void DressWidgetTree(void)
{
#define AC(wn,rn,cb,cd)	XtAddCallback(GetWidget(wn),rn,cb,(XtPointer)cd)

    SetValue(XmNsubMenuId, (XtArgVal) GetWidget("controlMenu"),
	     GetWidget("control"));
    SetValue(XmNsubMenuId, (XtArgVal) GetWidget("editMenu"), 
	     GetWidget("edit"));
    SetValue(XmNsubMenuId, (XtArgVal) GetWidget("modeMenu"), 
	     GetWidget("mode"));
    SetValue(XmNsubMenuId, (XtArgVal) GetWidget("brushMenu"), 
	     GetWidget("brush"));
    
    SetValue(XmNshadowThickness, (XtArgVal) 0, GetWidget("main"));

    XtOverrideTranslations(GetWidget("chart"), 
			   XtParseTranslationTable(dragTranslations));
    XtOverrideTranslations(GetWidget("button"), 
			   XtParseTranslationTable(dragTranslations));

    CreateBitmap(GetWidget("square"), 0);
    CreateBitmap(GetWidget("circle"), 1);
    CreateBitmap(GetWidget("diamond"), 2);

    RemoveHelp(GetWidget("fsBox"));
    RemoveHelp(GetWidget("quitBox"));
    RemoveHelp(GetWidget("fileError"));
    RemoveHelp(GetWidget("copyright"));

    XtAddCallback(XtParent(GetWidget("quitBox")), 
		  XmNpopupCallback, PositionDialogCB, NULL);

    AC("fsBox",		XmNokCallback,		FileCB, FILE_OK);
    AC("fsBox",		XmNokCallback,		UnmanageCB, 0);
    AC("fsBox",		XmNcancelCallback, 	FileCB, FILE_CANCEL);
    AC("fsBox",		XmNcancelCallback, 	UnmanageCB, 0);
    AC("quitBox",	XmNokCallback,		UnmanageCB, 0); 
    AC("quitBox",	XmNokCallback,		ManageCB, GetWidget("fsBox"));
    AC("quitBox",	XmNokCallback,		FileCB, FILE_QUIT);
    AC("quitBox",	XmNcancelCallback, 	QuitCB, 1);
    AC("fileError",	XmNokCallback,		ManageCB, GetWidget("fsBox"));
    AC("fileError",	XmNokCallback,		UnmanageCB, 0);
    AC("fileError",	XmNcancelCallback,	FileCB, FILE_CANCEL);
    AC("fileError",	XmNcancelCallback,	UnmanageCB, 0);
    AC("send",		XmNactivateCallback,	BugCB, 0);

    AC("copyright",	XmNcancelCallback,   ManageCB, GetWidget("bugBox"));

    AC("ahpcrc",	XmNactivateCallback, ManageCB, GetWidget("copyright"));
    AC("open",		XmNactivateCallback,	ManageCB, GetWidget("fsBox"));
    AC("open",		XmNactivateCallback,	FileCB, FILE_OPEN);
    AC("save",		XmNactivateCallback,	ManageCB, GetWidget("fsBox"));
    AC("save",		XmNactivateCallback,	FileCB, FILE_SAVE);
    AC("seti",		XmNactivateCallback,	PropCB, PROP_SET);
    AC("geti",		XmNactivateCallback,	PropCB, PROP_GET);
    AC("pickColor",	XmNactivateCallback,	PickCB, 0);
    AC("grabColor",	XmNactivateCallback,	GrabColorCB, 0);
    AC("setColor",	XmNactivateCallback,	SetColorCB, 0);
    AC("quit",		XmNactivateCallback,	QuitCB, 0);

    AC("asciiIndex",	XmNarmCallback,		FormatCB, ASCII_INDEX);
    AC("asciiPlain",	XmNarmCallback,		FormatCB, ASCII_PLAIN);
    AC("binLeave",	XmNarmCallback,		FormatCB, BIN_LEAVE);
    AC("binRow",	XmNarmCallback,		FormatCB, BIN_ROW);

    AC("edit",		XmNcascadingCallback,	CascadeCB, MENU_EDIT);
    AC("undo",		XmNactivateCallback,	UndoCB, 0);
    AC("redo",		XmNactivateCallback,	RedoCB, 0);
    AC("placeKnot",	XmNactivateCallback,	PlaceKnotsCB, 0);
    AC("snap",		XmNactivateCallback,	SnapCB, SNAP_THIS);
    AC("snapAll",	XmNactivateCallback,	SnapCB, SNAP_ALL);
    AC("snap1",		XmNactivateCallback,	SnapCB, 0);
    AC("snap2",		XmNactivateCallback,	SnapCB, 1);
    AC("snap3",		XmNactivateCallback,	SnapCB, 2);

    AC("mode",		XmNcascadingCallback,	CascadeCB, MENU_MODE);
    AC("rgb",		XmNvalueChangedCallback,ModeCB, MODE_RGB);
    AC("hsv",		XmNvalueChangedCallback,ModeCB, MODE_HSV);
    AC("yuv",		XmNvalueChangedCallback,ModeCB, MODE_YUV);
    AC("alpha",		XmNvalueChangedCallback,ModeCB, MODE_ALPHA);
    AC("auto",		XmNvalueChangedCallback,ModeCB, MODE_AUTO);
    AC("stomp",		XmNvalueChangedCallback,ModeCB, MODE_STOMP);

    AC("brush",		XmNcascadingCallback,	CascadeCB, MENU_BRUSH);
    AC("square",	XmNvalueChangedCallback,BrushCB, 0);
    AC("circle",	XmNvalueChangedCallback,BrushCB, 1);
    AC("diamond",	XmNvalueChangedCallback,BrushCB, 2);
    AC("chart",		XmNexposeCallback,	ChartCB, 0);
    AC("chart",		XmNinputCallback,	ChartCB, 0);
    AC("chart",		XmNresizeCallback,	ChartCB, 0);
    AC("button",	XmNexposeCallback,	ButtonCB, 0);
    AC("button",	XmNinputCallback,	ButtonCB, 0);
    AC("button",	XmNresizeCallback,	ButtonCB, 0);
    AC("redScale",	XmNvalueChangedCallback,ScaleCB, 0);
    AC("redScale",	XmNdragCallback,	ScaleCB, 0);
    AC("grnScale",	XmNvalueChangedCallback,ScaleCB, 1);
    AC("grnScale",	XmNdragCallback,	ScaleCB, 1);
    AC("bluScale",	XmNvalueChangedCallback,ScaleCB, 2);
    AC("bluScale",	XmNdragCallback,	ScaleCB, 2);
}

static void AddConverters(XtAppContext app);

void SetupIcol(unsigned int *argc, char *argv[])
{
    icol = MallocType(Icol);

    MemCheck(icol);
    ZeroType(icol, Icol);
    
    MakeShell(argc, argv);

    AddWidgetConverter(icol->app);
    BuildWidgetTree(icol->shell, widgetSpec);
    DressWidgetTree();
    
    if (icol->expert) {
	SetValue(XmNwidth,  (XtArgVal) 332, (Widget) NULL);
	SetValue(XmNheight, (XtArgVal) 92, GetWidget("button"));
	SetValue(XmNheight, (XtArgVal) 120, GetWidget("chart"));
    }

    MakeAxisBar();
    MakeScaleString();
}

