/*
	$Id: xforge.c,v 1.5 2001/03/04 16:51:12 rogue Exp $

	Copyright (c) 1999 - 2001 Xforge project
*/

#include <Xm/Xm.h>
#include <Xm/AtomMgr.h>
#include <Xm/CascadeB.h>
#include <Xm/DrawingA.h>
#include <Xm/FileSB.h>
#include <Xm/Frame.h>
#include <Xm/Form.h>
#include <Xm/Label.h>
#include <Xm/List.h>
#include <Xm/MainW.h>
#include <Xm/MessageB.h>
#include <Xm/Protocols.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/Scale.h>
#include <Xm/ScrollBar.h>
#include <Xm/SelectioB.h>
#include <Xm/Separator.h>
#include <Xm/Text.h>
#include <Xm/ToggleB.h>
#include <X11/cursorfont.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include "xforge.h"
#include "callback.h"
#include "bufutil.h"
#include "glob.h"

extern String fallback_resources[];		/* fallback resources */

/* common variables */
static XtAppContext app;
Widget top_wid;
Widget quit_dialog, about_dialog, license_dialog;
Cursor xcwatch;
static XmString xmstring1, xmstring2,		/* temporal XmStrings */
		xmstring3, xmstring4;
static int top_argc;				/* copy of initial args */
static char **top_argv;
char *progname;

/*
	syserr_destroy_widget unmanages and destroys the syserr dialog
*/

static void syserr_destroy_widget(Widget w) {
	XtUnmanageChild(w);
	XtDestroyWidget(w);
}

/*
	syserr(msg) spawns an error dialog with msg and string
	representation of errno in dialog
*/

void syserr(const char *msg) {
	char buffer[256];
	Widget widget, w;

	sprintf(buffer, "%.125s: %.125s", msg, strerror(errno));
	widget = XmCreateErrorDialog(top_wid, "errorDialog", NULL, 0);
	/* remove "Cancel" and "Help" buttons */
	w = XmMessageBoxGetChild(widget, XmDIALOG_HELP_BUTTON);
	XtUnmanageChild(w);
	w = XmMessageBoxGetChild(widget, XmDIALOG_CANCEL_BUTTON);
	XtUnmanageChild(w);
	xmstring1 = XmStringCreateLocalized(buffer);
	xmstring2 = XmStringCreateLocalized(DEFAULT_TITLE);
	XtVaSetValues(widget, XmNmessageString, xmstring1,
		XmNdialogTitle, xmstring2, NULL);
	XmStringFree(xmstring1);
	XmStringFree(xmstring2);
	XtAddCallback(widget, XmNokCallback,
			(XtCallbackProc)syserr_destroy_widget, NULL);
	XtManageChild(widget);
}

/*
	xferr(msg) spawns Xforge error dialog which displays msg in
	dialog
*/

void xferr(const char *msg) {
	Widget widget, w;

	widget = XmCreateErrorDialog(top_wid, "errorDialog", NULL, 0);
	/* remove "Cancel" and "Help" buttons */
	w = XmMessageBoxGetChild(widget, XmDIALOG_HELP_BUTTON);
	XtUnmanageChild(w);
	w = XmMessageBoxGetChild(widget, XmDIALOG_CANCEL_BUTTON);
	XtUnmanageChild(w);
	xmstring1 = XmStringCreateLocalized((char *)msg);
	xmstring2 = XmStringCreateLocalized(DEFAULT_TITLE);
	XtVaSetValues(widget, XmNmessageString, xmstring1,
		XmNdialogTitle, xmstring2, NULL);
	XmStringFree(xmstring1);
	XmStringFree(xmstring2);
	XtAddCallback(widget, XmNokCallback,
			(XtCallbackProc)syserr_destroy_widget, NULL);
	XtManageChild(widget);
}

/* menu structures */

static struct menubar_entry {
	String name;
	int id;
} menubar_entries[] = {
	{ "file",	0 },
	{ "edit",	1 },
	{ "view",	2 },
	{ "sound",	3 },
	{ "effects",	4 },
	{ "options",	5 },
	{ "help",	6 },
	{ NULL,		0 }
};

static struct menuitem_entry {
	String name;
#define M_PUSHB 0		/* push button */
#define M_TOGGLEB 1		/* toggle button */
#define M_SEP 2			/* separator */
	int type;
	void (*callback)(Widget, struct buffer *);
	int pid;		/* parent menu */
} menuitem_entries[] = {
	/* File */
	{ "new",	M_PUSHB,	new_window,	0 },
	{ "open",	M_PUSHB,	open_query,	0 },
	{ "save",	M_PUSHB,	save_inst,	0 },
	{ "saveAs",	M_PUSHB,	save_query,	0 },
	{ "revert",	M_PUSHB,	revert_query,	0 },
	{ "--------",	M_SEP,		NULL,		0 },
	{ "exit",	M_PUSHB,	quit_query,	0 },
	/* Edit */
	{ "undo",	M_PUSHB,	buf_undo,	1 },
	{ "--------",	M_SEP,		NULL,		1 },
	{ "copy",	M_PUSHB,	clip_copy,	1 },
	{ "cut",	M_PUSHB,	clip_cut,	1 },
	{ "paste",	M_PUSHB,	clip_paste,	1 },
	{ "swap",	M_PUSHB,	clip_swap,     	1 },
	{ "clear",	M_PUSHB,	clear_query,	1 },
	{ "delete",	M_PUSHB,	clip_delete,	1 },
	{ "--------",	M_SEP,		NULL,		1 },
	{ "selectAll",	M_PUSHB,	select_all,	1 },
	{ "selectLeft",	M_PUSHB,	select_left,	1 },
	{ "selectRight",M_PUSHB,	select_right,	1 },
	{ "deselect",	M_PUSHB,	select_none,	1 },
	{ "--------",	M_SEP,		NULL,		1 },
	{ "beginData",	M_PUSHB,	begin_data,	1 },
	{ "extBegin",	M_PUSHB,	ext_begin_data,	1 },
	{ "endData",	M_PUSHB,	end_data,	1 },
	{ "extEnd",	M_PUSHB,	ext_end_data,	1 },
	{ "--------",	M_SEP,		NULL,		1 },
	{ "removeDC",	M_PUSHB,	clip_remdc,	1 },
	{ "addWS",	M_PUSHB,	addws_query,	1 },
	/* View */
	{ "showRange",	M_PUSHB,	show_range,	2 },
	{ "showAll",	M_PUSHB,	show_all,	2 },
	{ "zoomOut",	M_PUSHB,	zoom_out,	2 },
	{ "--------",	M_SEP,		NULL,		2 },
	{ "closeView",	M_PUSHB,	close_query,	2 },
	{ "--------",	M_SEP,		NULL,		2 },
	{ "refresh",	M_PUSHB,	refresh_window,	2 },
	/* Sound */
	{ "playRange",	M_PUSHB,	play_range,	3 },
	{ "playAll",	M_PUSHB,	play_all,	3 },
	{ "stop",	M_PUSHB,	play_stop,	3 },
	{ "loop",	M_TOGGLEB,	play_loop,	3 },
	{ "sampler",	M_PUSHB,	NULL,		3 },
	{ "--------",	M_SEP,		NULL,		3 },
	{ "params",	M_PUSHB,	param_query,	3 },
	{ "resample",	M_PUSHB,	resample_query,	3 },
	{ "toMono",	M_PUSHB,	mono_query,	3 },
	{ "toStereo",	M_PUSHB,	stereo_really,	3 },
	{ "--------",	M_SEP,		NULL,		3 },
	{ "invert",	M_PUSHB,	phase_invert,	3 },
	{ "reverse",	M_PUSHB,	range_reverse,	3 },
	{ "mix",	M_PUSHB,	mix_query,	3 },
	/* Effects */
	{ "volume",	M_PUSHB,	vol_query,	4 },
	{ "echo",	M_PUSHB,	echo_query,	4 },
	{ "reverb",	M_PUSHB,	reverb_query,	4 },
	{ "flange",	M_PUSHB,	flange_query,	4 },
	{ "filter",	M_PUSHB,	filt_query,	4 },
	{ "compress",	M_PUSHB,	comp_query,	4 },
	/* Options */
	{ "okPrompts",	M_TOGGLEB,	okprompt_set,	5 },
	{ "saveOpts",	M_PUSHB,	NULL,		5 },
	/* Help */
	{ "about",	M_PUSHB,	about_manage,	6 },
	{ "license",	M_PUSHB,	license_manage,	6 },
	{ NULL,		0,		NULL,		0 },
};

void spawn_gui(char *path) {
	Widget widget;		/* temporal, general-purpose widget */
	struct menubar_entry *mp = menubar_entries;
	struct menuitem_entry *ip = menuitem_entries;
	struct buffer *buf;
	XtActionsRec canvas_actions;
	String canvas_translations =
		"<Btn1Down>: select_chg(down) ManagerGadgetArm() \n "
		"<Btn1Up>: select_chg(up) ManagerGadgetActivate() \n "
		"<Btn1Motion>: select_chg(motion) ManagerGadgetButtonMotion()";
	Atom delete_window_protocol;
	static int cursor_exists = 0;

	if (!(buf = add_buf()))
		return;

	if (path) {
		if (io_openfile(buf, path) == -1) {
			remove_buf(buf);
			return;
		}
	}

	/* first make a new application shell */
	buf->display = XtOpenDisplay(app, NULL, NULL, "Xforge", NULL, 0,
		&top_argc, top_argv);
	buf->top_wid = XtVaAppCreateShell(NULL, "Xforge",
		applicationShellWidgetClass, buf->display,
		XtNtitle, buf->name, NULL);

	/* catch WM_DELETE_WINDOW and let close_query() handle it */
	delete_window_protocol = XmInternAtom(XtDisplay(buf->top_wid),
		"WM_DELETE_WINDOW", True);
	XtVaSetValues(buf->top_wid,
		XmNdeleteResponse, XmDO_NOTHING,
		NULL);
	XmAddWMProtocolCallback(buf->top_wid, delete_window_protocol,
		(XtCallbackProc)close_query, buf);

	/* create a watch cursor */
	if (!(cursor_exists)) {
		xcwatch = XCreateFontCursor(XtDisplay(buf->top_wid),
			XC_watch);
		cursor_exists = 1;
	}

	/* create main window */
	buf->mainw = XtVaCreateManagedWidget("mainWindow",
		xmMainWindowWidgetClass, buf->top_wid, NULL);

	/* create menubar */
	buf->menubar = XmCreateMenuBar(buf->mainw, "menuBar", NULL, 0);

	/* create menu bar buttons */
	do {
		widget = buf->mbe[mp->id] =
			XtVaCreateManagedWidget(mp->name,
				xmCascadeButtonWidgetClass, buf->menubar,
				NULL);
		buf->pulld[mp->id] =
			XmCreatePulldownMenu(buf->menubar, mp->name, NULL, 0);
		XtVaSetValues(buf->pulld[mp->id],
			XmNtearOffModel, XmTEAR_OFF_ENABLED,
			NULL);
		XtVaSetValues(buf->mbe[mp->id],
			XmNsubMenuId, buf->pulld[mp->id],
			NULL);
		mp++;
	} while (mp->name);
	/* widget now contains the last menu bar button, i.e. Help */
	/* mark it as a menuHelpWidget */
	XtVaSetValues(buf->menubar, XmNmenuHelpWidget, widget, NULL);

	/* create menu entries */
	while (ip->name) {
		switch(ip->type) {
			case M_PUSHB:
				widget = XtVaCreateManagedWidget(ip->name,
					xmPushButtonWidgetClass,
					buf->pulld[ip->pid], NULL);
				if (ip->callback)
					XtAddCallback(widget,
						XmNactivateCallback,
						(XtCallbackProc)ip->callback,
						buf);
				break;
			case M_TOGGLEB:
				widget = XtVaCreateManagedWidget(ip->name,
					xmToggleButtonWidgetClass,
					buf->pulld[ip->pid], NULL);
				if (ip->callback) {
					XtAddCallback(widget,
						XmNarmCallback,
						(XtCallbackProc)ip->callback,
						buf);
					XtAddCallback(widget,
						XmNdisarmCallback,
						(XtCallbackProc)ip->callback,
						buf);
				}
				break;
			case M_SEP:
				widget = XtVaCreateManagedWidget(ip->name,
					xmSeparatorWidgetClass,
					buf->pulld[ip->pid], NULL);
				break;
		}
		ip++;
	}

	XtManageChild(buf->menubar);

	/* create a Form to place work area */
	buf->form = XtVaCreateManagedWidget("form", xmFormWidgetClass,
		buf->mainw, NULL);

	/* status bar */
	buf->statframe = XtVaCreateManagedWidget("statFrame",
		xmFrameWidgetClass, buf->form,
		XmNshadowType, XmSHADOW_OUT,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	buf->statlabel = XtVaCreateManagedWidget("statLabel",
		xmLabelWidgetClass, buf->statframe,
		XmNalignment, XmALIGNMENT_BEGINNING,
		NULL);

	/* scrollbar */
	buf->scrollbar = XtVaCreateManagedWidget("scrollBar",
		xmScrollBarWidgetClass, buf->form,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_WIDGET,
		XmNbottomWidget, buf->statframe,
		XmNorientation, XmHORIZONTAL,
		XmNminimum, 0,
		XmNmaximum, 10,
		XmNsliderSize, 10,
		NULL);
	XtAddCallback(buf->scrollbar, XmNvalueChangedCallback,
		(XtCallbackProc)scroll_canvas, buf);

	/* create a DrawingArea for waveform display */
	canvas_actions.string = "select_chg";
	canvas_actions.proc = (XtActionProc)select_chg;
	XtAppAddActions(app, &canvas_actions, 1);
	buf->canvas = XtVaCreateManagedWidget("canvas",
		xmDrawingAreaWidgetClass, buf->form,
		XmNtranslations, XtParseTranslationTable(canvas_translations),
		XmNuserData, buf,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_WIDGET,
		XmNbottomWidget, buf->scrollbar,
		NULL);
	buf->screen = XtScreen(buf->canvas);

	buf->lgc = XCreateGC(buf->display, RootWindowOfScreen(buf->screen),
		0, &(buf->lgcv));
	buf->sgc = XCreateGC(buf->display, RootWindowOfScreen(buf->screen),
		0, &(buf->sgcv));
	XSetFunction(buf->display, buf->sgc, GXxor);
	XSetBackground(buf->display, buf->sgc, 0);
	XSetForeground(buf->display, buf->sgc,
		WhitePixelOfScreen(buf->screen));

	XtAddCallback(buf->canvas, XmNexposeCallback,
		(XtCallbackProc)render_all, buf);
	XtAddCallback(buf->canvas, XmNresizeCallback,
		(XtCallbackProc)render_all, buf);
	/* initialize selection backup */
	buf->old_selx0 = buf->old_selx1 = buf->old_selw = buf->old_selmask = 0;

	XtVaSetValues(buf->mainw, XmNmenuBar, buf->menubar, XmNworkWindow,
		buf->form, NULL);

	XtRealizeWidget(buf->top_wid);

	/* create an open dialog; don't show it yet */
	buf->open_dialog = XmCreateFileSelectionDialog(buf->top_wid,
		"openDialog", NULL, 0);
	XtAddCallback(buf->open_dialog, XmNcancelCallback,
		(XtCallbackProc)open_hide_dialog, buf);
	XtAddCallback(buf->open_dialog, XmNokCallback,
		(XtCallbackProc)open_really, buf);
	XtAddCallback(buf->open_dialog, XmNhelpCallback,
		(XtCallbackProc)open_help, buf);

	/* create a save dialog; don't show it yet */
	buf->save_dialog = XmCreateFileSelectionDialog(buf->top_wid,
		"saveDialog", NULL, 0);
	XtAddCallback(buf->save_dialog, XmNcancelCallback,
		(XtCallbackProc)save_hide_dialog, buf);
	XtAddCallback(buf->save_dialog, XmNokCallback,
		(XtCallbackProc)save_really, buf);

	/* create a clear dialog; don't show it yet */
	buf->clear_dialog = XmCreateQuestionDialog(buf->top_wid, "clearDialog",
		NULL, 0);
	XtAddCallback(buf->clear_dialog, XmNokCallback,
		(XtCallbackProc)clear_really, buf);

	/* create an add workspace dialog; don't show it yet */
	buf->addws_dialog = XmCreatePromptDialog(buf->top_wid, "addwsDialog",
		NULL, 0);
	XtAddCallback(buf->addws_dialog, XmNokCallback,
		(XtCallbackProc)addws_really, buf);
	XtAddCallback(buf->addws_dialog, XmNhelpCallback,
		(XtCallbackProc)addws_help, buf);

	/* create a close dialog; don't show it yet */
	buf->close_dialog = XmCreateQuestionDialog(buf->top_wid, "closeDialog",
		NULL, 0);
	XtAddCallback(buf->close_dialog, XmNokCallback,
		(XtCallbackProc)close_really, buf);

	/* create a param dialog; don't show it yet */
	buf->param_dialog = XmCreateFormDialog(buf->top_wid, "paramDialog",
		NULL, 0);

	/* rate */
	buf->param_dialog_frate = XtVaCreateManagedWidget("formRate",
		xmFormWidgetClass, buf->param_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	widget = XtVaCreateManagedWidget("rateLabel", xmLabelWidgetClass,
		buf->param_dialog_frate,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_POSITION,
		XmNrightPosition, 20,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNalignment, XmALIGNMENT_BEGINNING,
		NULL);
	buf->param_dialog_srw = XtVaCreateManagedWidget("rateText",
		xmTextWidgetClass, buf->param_dialog_frate,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, widget,
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);

	/* channels */
	buf->param_dialog_fchan = XtVaCreateManagedWidget("formChan",
		xmFormWidgetClass, buf->param_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->param_dialog_frate,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	widget = XtVaCreateManagedWidget("chanLabel", xmLabelWidgetClass,
		buf->param_dialog_fchan,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_POSITION,
		XmNrightPosition, 20,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNalignment, XmALIGNMENT_BEGINNING,
		NULL);
	buf->param_dialog_chm = XmCreateRadioBox(buf->param_dialog_fchan,
		"channels", NULL, 0);
	XtVaSetValues(buf->param_dialog_chm, XmNorientation, XmHORIZONTAL,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, widget,
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	buf->param_dialog_ch1 = XtVaCreateManagedWidget("ch1",
		xmToggleButtonWidgetClass, buf->param_dialog_chm,
		NULL);
	buf->param_dialog_ch2 = XtVaCreateManagedWidget("ch2",
		xmToggleButtonWidgetClass, buf->param_dialog_chm,
		NULL);
	XtManageChild(buf->param_dialog_chm);

	/* bits */
	buf->param_dialog_fbits = XtVaCreateManagedWidget("formBits",
		xmFormWidgetClass, buf->param_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->param_dialog_fchan,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	widget = XtVaCreateManagedWidget("bitsLabel", xmLabelWidgetClass,
		buf->param_dialog_fbits,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_POSITION,
		XmNrightPosition, 20,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNalignment, XmALIGNMENT_BEGINNING,
		NULL);
	buf->param_dialog_bm = XmCreateRadioBox(buf->param_dialog_fbits,
		"bits", NULL, 0);
	XtVaSetValues(buf->param_dialog_bm, XmNorientation, XmHORIZONTAL,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, widget,
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	buf->param_dialog_b8 = XtVaCreateManagedWidget("bits8",
		xmToggleButtonWidgetClass, buf->param_dialog_bm,
		NULL);
	buf->param_dialog_b16 = XtVaCreateManagedWidget("bits16",
		xmToggleButtonWidgetClass, buf->param_dialog_bm,
		NULL);
	buf->param_dialog_b24 = XtVaCreateManagedWidget("bits24",
		xmToggleButtonWidgetClass, buf->param_dialog_bm,
		NULL);
	buf->param_dialog_b32 = XtVaCreateManagedWidget("bits32",
		xmToggleButtonWidgetClass, buf->param_dialog_bm,
		NULL);
	XtManageChild(buf->param_dialog_bm);

	/* file format */
	buf->param_dialog_ffmt = XtVaCreateManagedWidget("formFmt",
		xmFormWidgetClass, buf->param_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->param_dialog_fbits,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	widget = XtVaCreateManagedWidget("fmtLabel", xmLabelWidgetClass,
		buf->param_dialog_ffmt,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_POSITION,
		XmNrightPosition, 20,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNalignment, XmALIGNMENT_BEGINNING,
		NULL);
	buf->param_dialog_fm = XmCreateRadioBox(buf->param_dialog_ffmt,
		"fmt", NULL, 0);
	XtVaSetValues(buf->param_dialog_fm, XmNorientation, XmHORIZONTAL,
		XmNisHomogeneous, False,
		XmNpacking, XmPACK_TIGHT,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, widget,
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	buf->param_dialog_fraw = XtVaCreateManagedWidget("fmtRaw",
		xmToggleButtonWidgetClass, buf->param_dialog_fm,
		NULL);
	buf->param_dialog_fsun = XtVaCreateManagedWidget("fmtSun",
		xmToggleButtonWidgetClass, buf->param_dialog_fm,
		NULL);
	buf->param_dialog_friff = XtVaCreateManagedWidget("fmtRIFF",
		xmToggleButtonWidgetClass, buf->param_dialog_fm,
		NULL);
	buf->param_dialog_frifx = XtVaCreateManagedWidget("fmtRIFX",
		xmToggleButtonWidgetClass, buf->param_dialog_fm,
		NULL);
	buf->param_dialog_faiff = XtVaCreateManagedWidget("fmtAIFF",
		xmToggleButtonWidgetClass, buf->param_dialog_fm,
		NULL);
	buf->param_dialog_faifc = XtVaCreateManagedWidget("fmtAIFC",
		xmToggleButtonWidgetClass, buf->param_dialog_fm,
		NULL);
	XtManageChild(buf->param_dialog_fm);

	buf->param_dialog_sep = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, buf->param_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->param_dialog_ffmt,
		NULL);

	buf->param_dialog_apply = XtVaCreateManagedWidget("apply",
		xmPushButtonWidgetClass, buf->param_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->param_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->param_dialog_apply, XmNactivateCallback,
		(XtCallbackProc)param_set, buf);

	XtVaSetValues(buf->param_dialog,
		XmNdefaultButton, buf->param_dialog_apply,
		NULL);

	buf->param_dialog_cancel = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, buf->param_dialog,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, buf->param_dialog_apply,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->param_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->param_dialog_cancel, XmNactivateCallback,
		(XtCallbackProc)param_hide_dialog, buf);

	buf->param_dialog_help = XtVaCreateManagedWidget("help",
		xmPushButtonWidgetClass, buf->param_dialog,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->param_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->param_dialog_help, XmNactivateCallback,
		(XtCallbackProc)param_help, buf);

	/* create a resample dialog; don't show it yet */
	buf->resample_dialog = XmCreateFormDialog(buf->top_wid,
		"resampleDialog", NULL, 0);

	buf->resample_dialog_rc = XtVaCreateManagedWidget("rowCol",
		xmFormWidgetClass, buf->resample_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		NULL);

	/* data rate */
	buf->resample_dialog_srw = XtVaCreateManagedWidget("rateText",
		xmTextWidgetClass, buf->resample_dialog_rc,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_POSITION,
		XmNleftPosition, 50,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	/* window length */
	buf->resample_dialog_wlw = XtVaCreateManagedWidget("windowLen",
		xmTextWidgetClass, buf->resample_dialog_rc,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->resample_dialog_srw,
		XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
		XmNleftWidget, buf->resample_dialog_srw,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);

	/* window function */
	buf->resample_dialog_wfm = XmCreateRadioBox(buf->resample_dialog_rc,
		"wfunc", NULL, 0);
	XtVaSetValues(buf->resample_dialog_wfm, XmNorientation, XmVERTICAL,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->resample_dialog_wlw,
		XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
		XmNleftWidget, buf->resample_dialog_wlw,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	buf->resample_dialog_rect = XtVaCreateManagedWidget("rect",
		xmToggleButtonWidgetClass, buf->resample_dialog_wfm,
		XmNset, True,
		NULL);
	buf->resample_dialog_bart = XtVaCreateManagedWidget("bart",
		xmToggleButtonWidgetClass, buf->resample_dialog_wfm,
		XmNset, False,
		NULL);
	buf->resample_dialog_black = XtVaCreateManagedWidget("black",
		xmToggleButtonWidgetClass, buf->resample_dialog_wfm,
		XmNset, False,
		NULL);
	buf->resample_dialog_ham = XtVaCreateManagedWidget("hamming",
		xmToggleButtonWidgetClass, buf->resample_dialog_wfm,
		XmNset, False,
		NULL);
	buf->resample_dialog_han = XtVaCreateManagedWidget("hanning",
		xmToggleButtonWidgetClass, buf->resample_dialog_wfm,
		XmNset, False,
		NULL);
	XtManageChild(buf->resample_dialog_wfm);

	/* labels */
	XtVaCreateManagedWidget("rateLabel",
		xmLabelWidgetClass, buf->resample_dialog_rc,
		XmNalignment, XmALIGNMENT_BEGINNING,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_WIDGET,
		XmNrightWidget, buf->resample_dialog_srw,
		XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
		XmNbottomWidget, buf->resample_dialog_srw,
		NULL);
	XtVaCreateManagedWidget("wlenLabel",
		xmLabelWidgetClass, buf->resample_dialog_rc,
		XmNalignment, XmALIGNMENT_BEGINNING,
		XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
		XmNtopWidget, buf->resample_dialog_wlw,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_WIDGET,
		XmNrightWidget, buf->resample_dialog_wlw,
		XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
		XmNbottomWidget, buf->resample_dialog_wlw,
		NULL);
	XtVaCreateManagedWidget("wfuncLabel",
		xmLabelWidgetClass, buf->resample_dialog_rc,
		XmNalignment, XmALIGNMENT_BEGINNING,
		XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
		XmNtopWidget, buf->resample_dialog_wfm,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_WIDGET,
		XmNrightWidget, buf->resample_dialog_wfm,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);

	buf->resample_dialog_sep = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, buf->resample_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->resample_dialog_rc,
		NULL);

	buf->resample_dialog_apply = XtVaCreateManagedWidget("apply",
		xmPushButtonWidgetClass, buf->resample_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->resample_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->resample_dialog_apply, XmNactivateCallback,
		(XtCallbackProc)resample_really, buf);

	XtVaSetValues(buf->resample_dialog,
		XmNdefaultButton, buf->resample_dialog_apply,
		NULL);

	buf->resample_dialog_cancel = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, buf->resample_dialog,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->resample_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->resample_dialog_cancel, XmNactivateCallback,
		(XtCallbackProc)resample_hide_dialog, buf);

	/* create a mono dialog; don't show it yet */
	buf->mono_dialog = XmCreateFormDialog(buf->top_wid, "monoDialog",
		NULL, 0);

	widget = XtVaCreateManagedWidget("left", xmLabelWidgetClass,
		buf->mono_dialog,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		NULL);

	buf->mono_dialog_bal = XtVaCreateManagedWidget("balance",
		xmScaleWidgetClass, buf->mono_dialog,
		XmNminimum, -1000,
		XmNmaximum, 1000,
		XmNvalue, 0,
		XmNdecimalPoints, 3,
		XmNscaleMultiple, 1,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, widget,
		XmNorientation, XmHORIZONTAL,
		NULL);

	XtVaCreateManagedWidget("right", xmLabelWidgetClass, buf->mono_dialog,
		XmNtopAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, buf->mono_dialog_bal,
		NULL);

	buf->mono_dialog_sep = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, buf->mono_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->mono_dialog_bal,
		NULL);

	buf->mono_dialog_apply = XtVaCreateManagedWidget("apply",
		xmPushButtonWidgetClass, buf->mono_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->mono_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->mono_dialog_apply, XmNactivateCallback,
		(XtCallbackProc)mono_really, buf);

	XtVaSetValues(buf->mono_dialog,
		XmNdefaultButton, buf->mono_dialog_apply,
		NULL);

	buf->mono_dialog_cancel = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, buf->mono_dialog,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->mono_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->mono_dialog_cancel, XmNactivateCallback,
		(XtCallbackProc)mono_hide_dialog, buf);

	/* create a mix dialog; don't show it yet */
	buf->mix_dialog = XmCreateFormDialog(buf->top_wid, "mixDialog",
		NULL, 0);

	widget = XtVaCreateManagedWidget("mixWith",
		xmLabelWidgetClass, buf->mix_dialog,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);

	buf->mix_dialog_list = XmCreateScrolledList(buf->mix_dialog, "list",
		NULL, 0);
	XtVaSetValues(XtParent(buf->mix_dialog_list),
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, widget,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	XtVaSetValues(buf->mix_dialog_list,
		XmNselectionPolicy, XmSINGLE_SELECT,
		XmNvisibleItemCount, 8,
		NULL);
	XtManageChild(buf->mix_dialog_list);

	buf->mix_dialog_ratio = XtVaCreateManagedWidget("ratio",
		xmScaleWidgetClass, buf->mix_dialog,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->mix_dialog_list,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNminimum, 0,
		XmNmaximum, 2000,
		XmNvalue, 1000,
		XmNdecimalPoints, 3,
		XmNscaleMultiple, 1,
		NULL);

	buf->mix_dialog_auto = XtVaCreateManagedWidget("auto",
		xmToggleButtonWidgetClass, buf->mix_dialog,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->mix_dialog_ratio,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);

	buf->mix_dialog_sep = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, buf->mix_dialog,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->mix_dialog_auto,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);

	buf->mix_dialog_apply = XtVaCreateManagedWidget("apply",
		xmPushButtonWidgetClass, buf->mix_dialog,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->mix_dialog_sep,
		XmNleftAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->mix_dialog_apply, XmNactivateCallback,
		(XtCallbackProc)mix_really, buf);

	XtVaSetValues(buf->mix_dialog,
		XmNdefaultButton, buf->mix_dialog_apply,
		NULL);

	buf->mix_dialog_cancel = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, buf->mix_dialog,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->mix_dialog_sep,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->mix_dialog_cancel, XmNactivateCallback,
		(XtCallbackProc)mix_hide_dialog, buf);

	/* create a volume dialog; don't show it yet */
	buf->vol_dialog = XmCreateFormDialog(buf->top_wid, "volDialog",
		NULL, 0);

	buf->vol_dialog_rc = XtVaCreateManagedWidget("rowCol",
		xmRowColumnWidgetClass, buf->vol_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNorientation, XmHORIZONTAL,
		NULL);

	buf->vol_dialog_st = XtVaCreateManagedWidget("start",
		xmScaleWidgetClass, buf->vol_dialog_rc,
		XmNminimum, -600,
		XmNmaximum, 200,
		XmNvalue, 0,
		XmNdecimalPoints, 1,
		XmNscaleMultiple, 1,
		NULL);

	buf->vol_dialog_end = XtVaCreateManagedWidget("end",
		xmScaleWidgetClass, buf->vol_dialog_rc,
		XmNminimum, -600,
		XmNmaximum, 200,
		XmNvalue, 0,
		XmNdecimalPoints, 1,
		XmNscaleMultiple, 1,
		NULL);

	buf->vol_dialog_sep = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, buf->vol_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->vol_dialog_rc,
		NULL);

	buf->vol_dialog_apply = XtVaCreateManagedWidget("apply",
		xmPushButtonWidgetClass, buf->vol_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->vol_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->vol_dialog_apply, XmNactivateCallback,
		(XtCallbackProc)vol_really, buf);

	XtVaSetValues(buf->vol_dialog,
		XmNdefaultButton, buf->vol_dialog_apply,
		NULL);

	buf->vol_dialog_cancel = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, buf->vol_dialog,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->vol_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->vol_dialog_cancel, XmNactivateCallback,
		(XtCallbackProc)vol_hide_dialog, buf);

	/* create an echo dialog; don't show it yet */
	buf->echo_dialog = XmCreateFormDialog(buf->top_wid, "echoDialog",
		NULL, 0);

	buf->echo_dialog_rc = XtVaCreateManagedWidget("rowCol",
		xmRowColumnWidgetClass, buf->echo_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNorientation, XmHORIZONTAL,
		NULL);

	buf->echo_dialog_gain = XtVaCreateManagedWidget("gain",
		xmScaleWidgetClass, buf->echo_dialog_rc,
		XmNminimum, -600,
		XmNmaximum, 200,
		XmNdecimalPoints, 1,
		XmNscaleMultiple, 1,
		NULL);

	buf->echo_dialog_fb = XtVaCreateManagedWidget("feedback",
		xmScaleWidgetClass, buf->echo_dialog_rc,
		XmNminimum, -600,
		XmNmaximum, 200,
		XmNvalue, -60,
		XmNdecimalPoints, 1,
		XmNscaleMultiple, 1,
		NULL);

	buf->echo_dialog_delay = XtVaCreateManagedWidget("delay",
		xmScaleWidgetClass, buf->echo_dialog_rc,
		XmNminimum, 0,
		XmNmaximum, 10000,
		XmNvalue, 500,
		XmNdecimalPoints, 3,
		XmNscaleMultiple, 1,
		NULL);

	buf->echo_dialog_sep = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, buf->echo_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->echo_dialog_rc,
		NULL);

	buf->echo_dialog_apply = XtVaCreateManagedWidget("apply",
		xmPushButtonWidgetClass, buf->echo_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->echo_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->echo_dialog_apply, XmNactivateCallback,
		(XtCallbackProc)echo_really, buf);

	XtVaSetValues(buf->echo_dialog,
		XmNdefaultButton, buf->echo_dialog_apply,
		NULL);

	buf->echo_dialog_cancel = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, buf->echo_dialog,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->echo_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->echo_dialog_cancel, XmNactivateCallback,
		(XtCallbackProc)echo_hide_dialog, buf);

	/* create a flange dialog; don't show it yet */
	buf->flan_dialog = XmCreateFormDialog(buf->top_wid, "flanDialog",
		NULL, 0);

	buf->flan_dialog_rc = XtVaCreateManagedWidget("rowCol",
		xmRowColumnWidgetClass, buf->flan_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNorientation, XmHORIZONTAL,
		NULL);

	buf->flan_dialog_delay = XtVaCreateManagedWidget("delay",
		xmScaleWidgetClass, buf->flan_dialog_rc,
		XmNminimum, 0,
		XmNmaximum, 200,
		XmNvalue, 10,
		XmNdecimalPoints, 1,
		XmNscaleHeight, 200,
		XmNscaleMultiple, 1,
		NULL);

	buf->flan_dialog_depth = XtVaCreateManagedWidget("depth",
		xmScaleWidgetClass, buf->flan_dialog_rc,
		XmNminimum, 0,
		XmNmaximum, 200,
		XmNvalue, 10,
		XmNdecimalPoints, 1,
		XmNscaleHeight, 200,
		XmNscaleMultiple, 1,
		NULL);

	buf->flan_dialog_freq = XtVaCreateManagedWidget("freq",
		xmScaleWidgetClass, buf->flan_dialog_rc,
		XmNminimum, 10,
		XmNmaximum, 1000,
		XmNvalue, 100,
		XmNdecimalPoints, 2,
		XmNscaleMultiple, 1,
		NULL);

	buf->flan_dialog_sep = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, buf->flan_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->flan_dialog_rc,
		NULL);

	buf->flan_dialog_apply = XtVaCreateManagedWidget("apply",
		xmPushButtonWidgetClass, buf->flan_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->flan_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->flan_dialog_apply, XmNactivateCallback,
		(XtCallbackProc)flange_really, buf);

	XtVaSetValues(buf->flan_dialog,
		XmNdefaultButton, buf->flan_dialog_apply,
		NULL);

	buf->flan_dialog_cancel = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, buf->flan_dialog,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->flan_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->flan_dialog_cancel, XmNactivateCallback,
		(XtCallbackProc)flange_hide_dialog, buf);

	/* create a reverb dialog; don't show it yet */
	buf->rev_dialog = XmCreateFormDialog(buf->top_wid, "revDialog",
		NULL, 0);

	buf->rev_dialog_rc = XtVaCreateManagedWidget("rowCol",
		xmRowColumnWidgetClass, buf->rev_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNorientation, XmHORIZONTAL,
		NULL);

	buf->rev_dialog_dry = XtVaCreateManagedWidget("dry",
		xmScaleWidgetClass, buf->rev_dialog_rc,
		XmNminimum, -600,
		XmNmaximum, 200,
		XmNvalue, 0,
		XmNdecimalPoints, 1,
		XmNscaleMultiple, 1,
		NULL);

	buf->rev_dialog_wet = XtVaCreateManagedWidget("wet",
		xmScaleWidgetClass, buf->rev_dialog_rc,
		XmNminimum, -600,
		XmNmaximum, 200,
		XmNvalue, 0,
		XmNdecimalPoints, 1,
		XmNscaleMultiple, 1,
		NULL);

	buf->rev_dialog_damp = XtVaCreateManagedWidget("damp",
		xmScaleWidgetClass, buf->rev_dialog_rc,
		XmNminimum, 0,
		XmNmaximum, 100,
		XmNvalue, 20,
		XmNdecimalPoints, 2,
		XmNscaleMultiple, 1,
		NULL);

	buf->rev_dialog_fb = XtVaCreateManagedWidget("fb",
		xmScaleWidgetClass, buf->rev_dialog_rc,
		XmNminimum, -600,
		XmNmaximum, 0,
		XmNvalue, -15,
		XmNdecimalPoints, 1,
		XmNscaleMultiple, 1,
		NULL);

	buf->rev_dialog_sep = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, buf->rev_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->rev_dialog_rc,
		NULL);

	buf->rev_dialog_apply = XtVaCreateManagedWidget("apply",
		xmPushButtonWidgetClass, buf->rev_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->rev_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->rev_dialog_apply, XmNactivateCallback,
		(XtCallbackProc)reverb_really, buf);

	XtVaSetValues(buf->rev_dialog,
		XmNdefaultButton, buf->rev_dialog_apply,
		NULL);

	buf->rev_dialog_cancel = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, buf->rev_dialog,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->rev_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->rev_dialog_cancel, XmNactivateCallback,
		(XtCallbackProc)reverb_hide_dialog, buf);

	/* create a filter dialog; don't show it yet */
	buf->filt_dialog = XmCreateFormDialog(buf->top_wid, "filtDialog",
		NULL, 0);

	buf->filt_dialog_rc = XtVaCreateManagedWidget("rowCol",
		xmRowColumnWidgetClass, buf->filt_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNorientation, XmVERTICAL,
		XmNnumColumns, 2,
		XmNpacking, XmPACK_COLUMN,
		NULL);

	/* labels */
	XtVaCreateManagedWidget("lowLabel", xmLabelWidgetClass,
		buf->filt_dialog_rc, NULL);
	XtVaCreateManagedWidget("hiLabel", xmLabelWidgetClass,
		buf->filt_dialog_rc, NULL);
	XtVaCreateManagedWidget("orderLabel", xmLabelWidgetClass,
		buf->filt_dialog_rc, NULL);
	XtVaCreateManagedWidget("typeLabel", xmLabelWidgetClass,
		buf->filt_dialog_rc, NULL);

	/* lower cutoff frequency */
	buf->filt_dialog_lcw = XtVaCreateManagedWidget("lowText",
		xmTextWidgetClass, buf->filt_dialog_rc,
		NULL);

	/* upper cutoff frequency */
	buf->filt_dialog_ucw = XtVaCreateManagedWidget("hiText",
		xmTextWidgetClass, buf->filt_dialog_rc,
		NULL);

	/* filter order */
	buf->filt_dialog_om = XmCreateRadioBox(buf->filt_dialog_rc,
		"order", NULL, 0);
	XtVaSetValues(buf->filt_dialog_om, XmNorientation, XmHORIZONTAL,
		NULL);
	buf->filt_dialog_o1 = XtVaCreateManagedWidget("order1",
		xmToggleButtonWidgetClass, buf->filt_dialog_om,
		NULL);
	buf->filt_dialog_o2 = XtVaCreateManagedWidget("order2",
		xmToggleButtonWidgetClass, buf->filt_dialog_om,
		NULL);
	XtManageChild(buf->filt_dialog_om);

	/* filter type */
	buf->filt_dialog_tm = XmCreateRadioBox(buf->filt_dialog_rc,
		"type", NULL, 0);
	XtVaSetValues(buf->filt_dialog_tm, XmNorientation, XmHORIZONTAL,
		NULL);
	buf->filt_dialog_tlp = XtVaCreateManagedWidget("lp",
		xmToggleButtonWidgetClass, buf->filt_dialog_tm,
		NULL);
	buf->filt_dialog_thp = XtVaCreateManagedWidget("hp",
		xmToggleButtonWidgetClass, buf->filt_dialog_tm,
		NULL);
	buf->filt_dialog_tbp = XtVaCreateManagedWidget("bp",
		xmToggleButtonWidgetClass, buf->filt_dialog_tm,
		NULL);
	buf->filt_dialog_tbr = XtVaCreateManagedWidget("br",
		xmToggleButtonWidgetClass, buf->filt_dialog_tm,
		NULL);
	XtManageChild(buf->filt_dialog_tm);

	buf->filt_dialog_sep = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, buf->filt_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->filt_dialog_rc,
		NULL);

	buf->filt_dialog_apply = XtVaCreateManagedWidget("apply",
		xmPushButtonWidgetClass, buf->filt_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->filt_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->filt_dialog_apply, XmNactivateCallback,
		(XtCallbackProc)filt_apply, buf);

	XtVaSetValues(buf->filt_dialog,
		XmNdefaultButton, buf->filt_dialog_apply,
		NULL);

	buf->filt_dialog_cancel = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, buf->filt_dialog,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->filt_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->filt_dialog_cancel, XmNactivateCallback,
		(XtCallbackProc)filt_hide_dialog, buf);

	/* set widget states to something basic */
	XtVaSetValues(buf->filt_dialog_lcw,
		XmNvalue, "1000",
		NULL);
	XtVaSetValues(buf->filt_dialog_ucw,
		XmNvalue, "10000",
		NULL);
	XtVaSetValues(buf->filt_dialog_o1,
		XmNset, True,
		NULL);
	XtVaSetValues(buf->filt_dialog_o2,
		XmNset, False,
		NULL);
	XtVaSetValues(buf->filt_dialog_tlp,
		XmNset, True,
		NULL);
	XtVaSetValues(buf->filt_dialog_thp,
		XmNset, False,
		NULL);
	XtVaSetValues(buf->filt_dialog_tbp,
		XmNset, False,
		NULL);
	XtVaSetValues(buf->filt_dialog_tbr,
		XmNset, False,
		NULL);

	/* create a compress dialog; don't show it yet */
	buf->comp_dialog = XmCreateFormDialog(buf->top_wid, "compDialog",
		NULL, 0);

	buf->comp_dialog_rc = XtVaCreateManagedWidget("rowCol",
		xmRowColumnWidgetClass, buf->comp_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNorientation, XmHORIZONTAL,
		NULL);

	buf->comp_dialog_dyn = XtVaCreateManagedWidget("dynamics",
		xmScaleWidgetClass, buf->comp_dialog_rc,
		XmNminimum, -1000,
		XmNmaximum, 1000,
		XmNdecimalPoints, 3,
		XmNscaleHeight, 200,
		XmNscaleMultiple, 1,
		NULL);

	buf->comp_dialog_vel = XtVaCreateManagedWidget("velocity",
		xmScaleWidgetClass, buf->comp_dialog_rc,
		XmNminimum, 10,
		XmNmaximum, 1000,
		XmNvalue, 20,
		XmNdecimalPoints, 0,
		XmNscaleMultiple, 1,
		NULL);

	buf->comp_dialog_sep = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, buf->comp_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->comp_dialog_rc,
		NULL);

	buf->comp_dialog_apply = XtVaCreateManagedWidget("apply",
		xmPushButtonWidgetClass, buf->comp_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->comp_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->comp_dialog_apply, XmNactivateCallback,
		(XtCallbackProc)comp_really, buf);

	XtVaSetValues(buf->comp_dialog,
		XmNdefaultButton, buf->comp_dialog_apply,
		NULL);

	buf->comp_dialog_cancel = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, buf->comp_dialog,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, buf->comp_dialog_sep,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	XtAddCallback(buf->comp_dialog_cancel, XmNactivateCallback,
		(XtCallbackProc)comp_hide_dialog, buf);

	set_window_title(buf);
}

int main(int argc, char **argv) {
	Widget w, v;
	int c;

	/* initialize application */
	progname = *argv;
	top_argc = argc;
	top_argv = argv;
	top_wid = XtVaAppInitialize(&app, "Xforge", NULL, 0, &argc, argv,
		fallback_resources, NULL);

	while ((c = getopt(argc, argv, "B:D:")) != EOF) {
		switch (c) {
			case 'B':
				dspbuf = atoi(optarg);
				if (dspbuf < 1) {
					fprintf(stderr, "%s: audio buffer size"
						" not positive, aborting\n",
						progname);
					exit(EXIT_FAILURE);
				}
				break;
			case 'D':
				dspdev = optarg;
				break;
			default:
				exit(EXIT_FAILURE);
		}
	}

	argc -= optind;
	argv += optind;

	/* set up clipboard */
	if (!(clip = malloc(sizeof(struct buffer)))) {
		fprintf(stderr, "%s: %s\n", progname, EMEM_MSG);
		exit(EXIT_FAILURE);
	}
	clip->data = NULL;
	clip->channels = 1;
	clip->len = 0;
	clip->rate = 44100;

#ifdef OSSPLAY
	/* allocate audio buffers */
	if (!(b1 = malloc(dspbuf))) {
		fprintf(stderr, "%s: %s\n", progname, EMEM_MSG);
		free(clip);
		exit(EXIT_FAILURE);
	}
	if (!(b2 = malloc(dspbuf))) {
		fprintf(stderr, "%s: %s\n", progname, EMEM_MSG);
		free(clip);
		free(b1);
		exit(EXIT_FAILURE);
	}
#endif

	/* spawn a new gui for each name on command line */
	/* if no names exist, spawn a single empty wave gui */
	do {
		spawn_gui(*argv);
		if (argc) {
			argc--;
			argv++;
		}
	} while (argc);

	/* create a quit dialog; don't show it yet */
	quit_dialog = XmCreateQuestionDialog(top_wid, "quitDialog", NULL, 0);
	/* remove "Help" button */
	w = XmMessageBoxGetChild(quit_dialog, XmDIALOG_HELP_BUTTON);
	XtUnmanageChild(w);
	XtAddCallback(quit_dialog, XmNokCallback,
		(XtCallbackProc)quit_really, NULL);

	/* create an about dialog; don't show it yet */
	about_dialog = XmCreateInformationDialog(top_wid, "aboutDialog", NULL,
		0);
	/* remove "Cancel" and "Help" buttons */
	w = XmMessageBoxGetChild(about_dialog, XmDIALOG_HELP_BUTTON);
	XtUnmanageChild(w);
	w = XmMessageBoxGetChild(about_dialog, XmDIALOG_CANCEL_BUTTON);
	XtUnmanageChild(w);
	xmstring1 = XmStringCreateLocalized(DEFAULT_TITLE);
	XtVaSetValues(about_dialog, XmNdialogTitle, xmstring1, NULL);
	XmStringFree(xmstring1);
	xmstring2 = XmStringSeparatorCreate();
	xmstring1 = XmStringCreateLocalized(ABOUT_STRING_1);
	xmstring3 = XmStringConcat(xmstring1, xmstring2);
	XmStringFree(xmstring1);
	xmstring1 = XmStringCreateLocalized(ABOUT_STRING_2);
	xmstring4 = XmStringConcat(xmstring3, xmstring1);
	XmStringFree(xmstring1);
	XmStringFree(xmstring3);
	xmstring3 = XmStringConcat(xmstring4, xmstring2);
	XmStringFree(xmstring4);
	xmstring1 = XmStringCreateLocalized(ABOUT_STRING_3);
	xmstring4 = XmStringConcat(xmstring3, xmstring1);
	XmStringFree(xmstring1);
	XmStringFree(xmstring3);
	xmstring3 = XmStringConcat(xmstring4, xmstring2);
	XmStringFree(xmstring4);
	xmstring1 = XmStringCreateLocalized(ABOUT_STRING_4);
	xmstring4 = XmStringConcat(xmstring3, xmstring1);
	XmStringFree(xmstring1);
	XmStringFree(xmstring2);
	XmStringFree(xmstring3);
	XtVaSetValues(about_dialog, XmNmessageString, xmstring4,
		NULL);
	XmStringFree(xmstring4);
	XtAddCallback(about_dialog, XmNokCallback,
		(XtCallbackProc)about_unmanage, NULL);

	/* create a license dialog; don't show it yet */
	license_dialog = XmCreateFormDialog(top_wid, "licenseDialog",
		NULL, 0);

	w = XtVaCreateManagedWidget("dismiss",
		xmPushButtonWidgetClass, license_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);

	v = w = XtVaCreateManagedWidget("separator",
		xmSeparatorWidgetClass, license_dialog,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_WIDGET,
		XmNbottomWidget, w,
		NULL);

	/* can't set XmNscrollingPolicy after widget is generated! */
	/* this widget should be manually built! */
	w = XmCreateScrolledText(license_dialog, "licenseText", NULL, 0);
	XtVaSetValues(w,
		XmNvalue, license,
		XmNeditable, False,
		XmNcursorPositionVisible, False,
		NULL);
	XtVaSetValues(XtParent(w),
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_WIDGET,
		XmNbottomWidget, v,
		NULL);
	XtManageChild(w);

	XtVaSetValues(license_dialog,
		XmNdefaultButton, w,
		NULL);

	/* spawn an empty buffer if no initial files could be opened */
	if (!root)
		spawn_gui(NULL);

	XtAppMainLoop(app);

	exit(EXIT_SUCCESS);
	/* NOTREACHED */
	return 0;
}
