testPQ

/*
 ============================================================================
 Name        : testPQ.c
 Author      : chuck
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

/*
gcc xmSkeleton.c -o xmSkeleton -I/usr/local/include -I/usr/X11R6/include -L/usr/src/lib -L/usr/local/lib -L/usr/X11R6/lib -lXm -lXt -lX11 -lXpm
*/

#include 
#include 

#include 

int main(void) {

	PGconn *dbConn;
	char *dbIP;
	const char *connInfo;

	//dbIP = "192.168.1.120";
	dbIP = "127.0.0.1";

	/* connect to cnog db */
	asprintf(&connInfo,
		"hostaddr=%s port=%s dbname=%s user=%s\n",
			dbIP, "5432", "init_main", "postgres");
	printf("connInfo = %s\n", connInfo);
	dbConn = PQconnectdb(connInfo);

	/* Check to see that the backend connection was successfully made */
	if(PQstatus(dbConn) != CONNECTION_OK) {
		fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(dbConn));
		return EXIT_SUCCESS;
	}

	return EXIT_SUCCESS;
}

cNotify

/*
 * cNotify.h
 *
 *  Created on: Jun 16, 2014
 *      Author: chuck
 */

#ifndef CNOTIFY_H_
#define CNOTIFY_H_

/*
 * Graphical Skeleton Program 2-18-2012
 * Use at your own risk
 */

#include 

/* sessions */
PGconn *dbConn;
int clientID;
char *dbIP;
char *n_val;
void setClientID();

/**** Widget Creation ****/
Widget createMenuBar(Widget appManager);
void createMenuBarItems(Widget menuBar, String menuName);
Widget createAppContent(Widget appManager, Widget menuBar, Widget statusBar);
Widget createStatusBar(Widget appManager);
void createMsgBox(String title, String msg);

/**** Widget Callbacks ****/
void menuBarCB(Widget widget, XtPointer clientData, XtPointer callData);
Boolean notifyCB(XtPointer appShell);
void msgBoxCB(Widget widget, XtPointer clientData, XtPointer callData);

/**** Sets Status Bar Text ****/
void showStatus(String status);

/**** Gets Menu Item Accelerator For menuBarCB ****/
KeySym getMnemonic(String menuName, String menuItemName);


#endif /* CNOTIFY_H_ */

/*
 ============================================================================
 Name        : cNotify.c
 Author      : chuck
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include 
#include 
#include 

#include "cNotify.h"

/* connect and get db sequence soe, create a file for dialogs */
void setClientID() {

	const char *connInfo;
	PGresult   *res;
	//dbIP = "192.168.1.100";
	dbIP = "192.168.1.120";

	/* connect to cnog db */
	asprintf(&connInfo,
		"hostaddr=%s port=%s dbname=%s user=%s",
			dbIP, "5432", "psqlbsd", "psqlbsd");
	printf("connInfo = %s\n", connInfo);
	dbConn = PQconnectdb(connInfo);

	/* Check to see that the backend connection was successfully made */
	if(PQstatus(dbConn) != CONNECTION_OK) {
		fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(dbConn));
	}

	/* get, set clientID */
	res = PQexec(dbConn, "select nextval('soe_id_seq');");
	printf("PQexec!\n");

	printf("PQgetvalue is %s!\n", PQgetvalue(res, 0, 0));

	char **ptr = NULL;
	//clientID = strtol(PQgetvalue(res, 0, 0), ptr, 10);
	//printf("clientID = %d\n", clientID);
	PQclear(res);

	/* listen - why i'm here */
	PQexec(dbConn, "listen noe;");

}

/**** public ****/
Widget statusTextField;
Widget contentManager;

/**** creates the menu bar then creates each menu item ****/
Widget createMenuBar(Widget appManager) {

	Widget menuBar;

	XmString file;
	XmString edit;

	file = XmStringCreateLocalized ("File");
	edit = XmStringCreateLocalized ("Edit");

	menuBar = XmVaCreateSimpleMenuBar(appManager, "menuBar",
		XmVaCASCADEBUTTON, file, 'F',
		XmVaCASCADEBUTTON, edit, 'E',
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		NULL);

	XmStringFree(file);
	XmStringFree(edit);

	createMenuBarItems(menuBar, "File");
	createMenuBarItems(menuBar, "Edit");

	return menuBar;
}

/**** creates the menu items ****/
void createMenuBarItems(Widget menuBar, String menuName) {

	if(!strcmp(menuName, "File")) {

		XmString open;
		XmString save;
		XmString exit;
		XmString exitAccel;

		open = XmStringCreateLocalized("Open...");
		save = XmStringCreateLocalized("Save...");
		exit = XmStringCreateLocalized("Exit");
		exitAccel = XmStringCreateLocalized("Ctrl+Q");

		XmVaCreateSimplePulldownMenu (menuBar, "fileMenu", 0, (XtCallbackProc)menuBarCB,
			XmVaPUSHBUTTON, open, 'O', NULL, NULL,
			XmVaPUSHBUTTON, save, 'S', NULL, NULL,
			XmVaSEPARATOR,
			XmVaPUSHBUTTON, exit, 'x', "CtrlQ", exitAccel,
			NULL);

		XmStringFree(open);
		XmStringFree(save);
		XmStringFree(exit);

		XmStringFree(exitAccel);

		return;
	}

	if(!strcmp(menuName, "Edit")) {

		XmString cut;
		XmString copy;
		XmString paste;
		XmString clear;

		cut = XmStringCreateLocalized("Cut");
		copy = XmStringCreateLocalized("Copy");
		paste = XmStringCreateLocalized("Paste");
		clear = XmStringCreateLocalized("Clear");

		XmVaCreateSimplePulldownMenu (menuBar, "editMenu", 1, (XtCallbackProc)menuBarCB,
			XmVaPUSHBUTTON, cut, 't', NULL, NULL,
			XmVaPUSHBUTTON, copy, 'C', NULL, NULL,
			XmVaPUSHBUTTON, paste, 'P', NULL, NULL,
			XmVaSEPARATOR,
			XmVaPUSHBUTTON, clear, 'l', NULL, NULL,
			NULL);

		XmStringFree(cut);
		XmStringFree(copy);
		XmStringFree(paste);
		XmStringFree(clear);
	}

	return;
}

/**** substitute here with a form or something ****/
Widget createAppContent(Widget appManager, Widget menuBar, Widget statusBar) {

	Widget appContent;

	/* place holder scrolled window */
	appContent = XtVaCreateWidget("appContent",
		xmScrolledWindowWidgetClass, appManager,
		XmNwidth, 400,
		XmNheight, 400,
		XmNscrollingPolicy, XmAUTOMATIC,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, menuBar,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_WIDGET,
		XmNbottomWidget, statusBar,
		NULL);

	contentManager = appContent;

	return appContent;
}

/**** to tell the user what's happening ****/
Widget createStatusBar(Widget appManager) {

	Widget statusBar;

	statusBar = XtVaCreateManagedWidget ("statusBar",
		xmTextFieldWidgetClass, appManager,
		XmNeditable, False,
		XmNcursorPositionVisible, False,
		XmNshadowThickness, 0,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);

	statusTextField = statusBar;

	return statusBar;
}

/**** a simple (yeah right) message box ****/
void createMsgBox(String title, String msg) {

	Widget dialog;
	Arg args[14];
	int n = 0;

	XmString xmTitle = XmStringCreateLocalized(title);
	XmString xmMsg = XmStringCreateLocalized(msg);

	XtSetArg(args[n], XmNdialogTitle, xmTitle); n++;
	XtSetArg(args[n], XmNmessageString, xmMsg); n++;

	dialog = XmCreateMessageDialog(contentManager, "simple", args, n);

	XtManageChild(dialog);

	XtAddCallback(dialog, XmNokCallback, msgBoxCB, (XtPointer)"ok");
	XtAddCallback(dialog, XmNcancelCallback, msgBoxCB, (XtPointer)"cancel");
	XtAddCallback(dialog, XmNhelpCallback, msgBoxCB, (XtPointer)"help");

	XmStringFree(xmTitle);
	XmStringFree(xmMsg);

	return;
}

/**** menuBar handler ****/
void menuBarCB(Widget widget, XtPointer clientData, XtPointer callData) {

        String menuName = XtName(XtParent(widget));
	String menuItemName = XtName(widget);
        KeySym mnemonic = getMnemonic(menuName, menuItemName);

	if(!strcmp(menuName, "fileMenu")) {
                switch(mnemonic) {
                        case 'O':
                                /* printf("you clicked Open\n"); */
				showStatus("Open");
				createMsgBox("Open", "Put open code here");
                                break;
                        case 'S':
                                /* printf("you clicked Save\n"); */
				showStatus("Save");
				createMsgBox("Save", "Put save code here");
                                break;
                        case 'x':
                                /* printf("you clicked Exit\n"); */
                                /* showStatus("Exit"); */
                                /* createMsgBox("Exit", "Put exit code here"); */
                                exit(0);

                                break;

                        default:
                                printf("pg_menu.php\n");
                                return;
                }
        }

        if(!strcmp(menuName, "editMenu")) {
                switch(mnemonic) {
                        case 't':
                                /* printf("you clicked Cut\n"); */
				showStatus("Cut");
				createMsgBox("Cut", "Put cut code here");
                                break;
                        case 'C':
                                /* printf("you clicked Copy\n"); */
				showStatus("Copy");
				createMsgBox("Copy", "Put copy code here");

                                break;
                        case 'P':
                                /* printf("you clicked Paste\n"); */
				showStatus("Paste");
				createMsgBox("Paste", "Put paste code here");
                                break;
                        case 'l':
                                /* printf("you clicked Clear\n"); */
				showStatus("Clear");
				createMsgBox("Clear", "Put clear code here");
                                break;
                        default:
                                printf("pg_menu.php\n");
                                return;
                }
        }

        return;
}

/**** check for notifications ****/
Boolean notifyCB(XtPointer appShell) {

	PGnotify   *notify;
	char *sql;
	PGresult *res;

	PQconsumeInput(dbConn);

	if((notify = PQnotifies(dbConn)) != NULL) {
		if(!strcmp(notify->relname, "noe")) {
			printf("notified\n");
			asprintf(&sql,
				"select n_val from noe where s_id = %d order by n_id desc;", clientID);
			printf("%s\n", sql);
			res = PQexec(dbConn, sql);
			if(PQntuples(res) > 0) {
				printf("more than zero\n");
				n_val = PQgetvalue(res, 0, 0);
				printf("n_val = %s\n", n_val);
			}
			PQclear(res);
		}
	}

	/**** keep checking ****/
	return False;
}

/**** simple menu item dialog handler ****/
void msgBoxCB(Widget widget, XtPointer clientData, XtPointer callData) {

	showStatus("");

	return;
}

/**** what's happening? ****/
void showStatus(String status) {

	XmTextSetString(statusTextField, status);

	return;
}

/**** this is a substitute for an array or something ****/
KeySym getMnemonic(String menuName, String menuItemName) {

        KeySym mnemonic;

	if(!strcmp(menuName, "fileMenu")) {
		if(!strcmp(menuItemName, "button_0")) return XStringToKeysym("O");
		if(!strcmp(menuItemName, "button_1")) return XStringToKeysym("S");
		if(!strcmp(menuItemName, "button_2")) return XStringToKeysym("x");
	}

	if(!strcmp(menuName, "editMenu")) {
		if(!strcmp(menuItemName, "button_0")) return XStringToKeysym("t");
		if(!strcmp(menuItemName, "button_1")) return XStringToKeysym("C");
		if(!strcmp(menuItemName, "button_2")) return XStringToKeysym("P");
		if(!strcmp(menuItemName, "button_3")) return XStringToKeysym("l");
	}

	return NULL;
}

/**** the main program ****/
main(int argc, char *argv[]) {

	Widget appShell;
	Widget appManager;
	Widget appContent;

	Widget menuBar;
	Widget statusBar;

	XtAppContext appContext;

	setClientID();

	appShell = XtVaOpenApplication(&appContext, "appClass",
		NULL, 0, &argc, argv, NULL, applicationShellWidgetClass,
		NULL);

	appManager = XtVaCreateManagedWidget("appManager",
		xmFormWidgetClass, appShell,
		NULL);

	menuBar = (Widget)createMenuBar(appManager);
	XtManageChild(menuBar);

	statusBar = createStatusBar(appManager);
	XtManageChild(statusBar);

	appContent = createAppContent(appManager, menuBar, statusBar);
	XtManageChild(appContent);

	XtRealizeWidget(appShell);

	XtAppAddWorkProc(appContext, notifyCB, appShell);

	XtAppMainLoop(appContext);

}


xmView

/*
 * xmView.h
 *
 *  Created on: Mar 21, 2017
 *      Author: chuck
 */

#ifndef XMVIEW_H_
#define XMVIEW_H_

#include 
#include 

#define WIDTH 3200
#define HEIGHT 3200

Pixmap viewPixmap;

Boolean gotViewPixmap;

Widget viewArea;

void drawPixmap(String fileName);

void viewAreaCB(Widget widget, XtPointer clientData, XtPointer callData);

void viewAreaExpose(XmDrawingAreaCallbackStruct *cbs);

void viewAreaResize(XmDrawingAreaCallbackStruct *cbs);

void viewAreaInput(XmDrawingAreaCallbackStruct *cbs);

void loadView(Widget parent);

#endif /* XMVIEW_H_ */

/*
 * xmView.c
 *
 *  Created on: Mar 21, 2017
 *      Author: chuck
 */

#include 

#include "xmView.h"

/****  ****/
void drawPixmap(String fileName) {
	//
	Pixel fg, bg;

	//printf("view callDataType = expose\n");

	if (gotViewPixmap != True) {

		bg = 0;			/* black background */
		fg = 9777215;	/* dark red foreground */

		printf("fg = %d, bg = %d\n", (int)fg, (int)bg);

		viewPixmap = XmGetPixmap(XtScreen(viewArea), fileName, fg, bg);

		gotViewPixmap = True;

	}

	XCopyArea(XtDisplay(viewArea), viewPixmap, XtWindow(viewArea),
				XDefaultGCOfScreen(XtScreen(viewArea)), 0, 0, WIDTH, HEIGHT, 0, 0);

	return;
}


/****  ****/
void viewAreaExpose(XmDrawingAreaCallbackStruct *cbs) {
	//
	printf("view callDataType = expose\n");
	//window = cbs->window;
	drawPixmap("src/X11/bitmaps/xlogo64");
	//
}

/****  ****/
void viewAreaResize(XmDrawingAreaCallbackStruct *cbs) {
	//
	printf("view callDataType = resize\n");
	//
}


/****  ****/
void viewAreaInput(XmDrawingAreaCallbackStruct *cbs) {
	//
	XEvent *event = cbs->event;
	Position x = event->xbutton.x;
	Position y = event->xbutton.y;
	printf("view callDataType = input at %d, %d\n", x, y);
	//
}


/****  ****/
void viewAreaCB(Widget widget, XtPointer clientData, XtPointer callData) {
	//
	XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *)callData;
	int reason = cbs->reason;
	switch(reason) {
		case XmCR_EXPOSE:
			viewAreaExpose(cbs);
			break;
		case XmCR_RESIZE:
			viewAreaResize(cbs);
			break;
		case XmCR_INPUT:
			viewAreaInput(cbs);
			break;
	}
}

/****  ****/
void loadView(Widget parent) {
	//
	viewArea = XtVaCreateManagedWidget("drawArea",
		xmDrawingAreaWidgetClass, parent,
		XmNbackground, 0,
		XmNwidth, WIDTH,
		XmNheight, HEIGHT,
		NULL);

	XtAddCallback(viewArea, XmNexposeCallback, viewAreaCB, NULL);
	XtAddCallback(viewArea, XmNresizeCallback, viewAreaCB, NULL);
	XtAddCallback(viewArea, XmNinputCallback, viewAreaCB, NULL);

}


xmTerm

/*
 * xmTerm.h
 *
 *  Created on: Mar 26, 2017
 *      Author: chuck
 */

#ifndef XMTERM_H_
#define XMTERM_H_

#include 
#include 


#define FILE_OPEN  0
#define FILE_SAVE  1
#define FILE_EXIT  2
#define EDIT_CUT   0
#define EDIT_COPY  1
#define EDIT_PASTE 2
#define EDIT_CLEAR 3

Widget termEditor;

/* cut, copy, paste, clear */
void menuEditText(int reason);

/* term is a scrolled text */
void loadTerm(Widget term);
	void newTextFile(String fileName);
	void openTextFile(String fileName);
	void saveTextFile(String fileName);

/* proper */
String getFileContents(String file_name);

/* file to edit */
FILE *termFile;

/* normal, enter does new line */
void changeTermCB(Widget widget, XtPointer clientData, XtPointer callData);

/* numeric side enter key, no new line */
void enterTermCB(Widget widget, XtPointer clientData, XtPointer callData);


#endif /* XMTERM_H_ */

/*
 * xmTerm.c
 *
 *  Created on: Mar 26, 2017
 *      Author: chuck
 */

#include "xmTerm.h"

/*  */
void newTextFile(String fileName) {

	printf("newTextFile\n");
	XmTextSetString(termEditor, "");
}

/*  */
void openTextFile(String fileName) {

	printf("openTextFile\n");
	XmTextSetString(termEditor, getFileContents(fileName));
}

/*  */
void saveTextFile(String fileName) {

	printf("saveTextFile\n");

	FILE *saveFile;
	String saveText;

	XtVaGetValues(termEditor, XmNvalue, &saveText, NULL);

	saveFile = fopen(fileName, "w");
	fprintf(saveFile, saveText);
	fclose(saveFile);

	XtFree(saveText);

}

void menuEditText(int reason) {
	//
	Time when = CurrentTime;
	Boolean result = True;
	//printf("reason = %d, time = %x\n", reason, when);
	//

	switch(reason) {
		case EDIT_CUT:
			result = XmTextCut(termEditor, when);
			break;
		case EDIT_COPY:
			result = XmTextCopy(termEditor, when);
			break;
		case EDIT_PASTE:
			result = XmTextPaste(termEditor);
			break;
		case EDIT_CLEAR:
			XmTextClearSelection(termEditor, when);
			break;
	}


}

/* temp file to store term text and later to act on it */
void changeTermCB(Widget widget, XtPointer clientData, XtPointer callData) {

	String strTerm;

	XtVaGetValues(widget, XmNvalue, &strTerm, NULL);

	/* open file */
	termFile = fopen("src/term.txt", "w");

	/* write to file */
	fprintf(termFile, strTerm);

	/* close file */
	fclose(termFile);

	XtFree(strTerm);

}

/*  */
void enterTermCB(Widget widget, XtPointer clientData, XtPointer callData) {

	printf("enter\n");

}


/**** a Stack Overflow solution ****/
String getFileContents(String file_name) {
	char *file_contents;
	long input_file_size;
	FILE *input_file = fopen(file_name, "rb");
	fseek(input_file, 0, SEEK_END);
	input_file_size = ftell(input_file);
	rewind(input_file);
	file_contents = malloc((input_file_size + 1) * (sizeof(char)));
	fread(file_contents, sizeof(char), input_file_size, input_file);
	fclose(input_file);
	file_contents[input_file_size] = 0;
	return file_contents;
}

/****  ****/
void loadTerm(Widget term) {
	//
	XmTextSetString(term, getFileContents("src/term.txt"));
	//XmTextSetString(term, getFileContents(termFileName));

	XtAddCallback(term, XmNvalueChangedCallback, changeTermCB, NULL);
	XtAddCallback(term, XmNactivateCallback, enterTermCB, NULL);

	termEditor = term;

}

xmTree

#ifndef XMTREE_H_
#define XMTREE_H_

#include 
#include 

#include 



/* toggles arrow direction */
void arrowCB(Widget arrow, XtPointer clientData, XtPointer callData);

/*  */
void nodeCB(Widget node, XtPointer clientData, XtPointer callData);

/*  */
void createNode(String caption, Widget tree, int left, int top);

/*  */
void createSubNode(String caption, Widget tree, int left, int top);

/* plain old right arrow button */
Widget createArrowButton(int left, int top, Widget tree);

/* */
Widget createNodeButton(String caption, Widget tree, int left, int top);

/* parent is fraTreeScrolledWindow */
void loadTree(Widget parent);

#endif /* XMTREE_H_ */

/*
 * xmTree.c
 *
 *  Created on: Apr 14, 2017
 *      Author: chuck
 */

#include "xmTree.h"

/* toggles arrow direction */
void arrowCB(Widget arrow, XtPointer clientData, XtPointer callData) {

	unsigned char direction;

	XtVaGetValues(arrow, XmNarrowDirection, &direction, NULL);

	if(direction == XmARROW_RIGHT) {
		XtVaSetValues(arrow, XmNarrowDirection, XmARROW_DOWN, NULL);
	}
	if(direction == XmARROW_DOWN) {
		XtVaSetValues(arrow, XmNarrowDirection, XmARROW_RIGHT, NULL);
	}

}

/*  */
void nodeCB(Widget node, XtPointer clientData, XtPointer callData) {
	//
	printf("node call back\n");
	XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)callData;
	//

}

/* plain old right arrow button */
Widget createArrowButton(int left, int top, Widget tree) {
	//
	Widget arrow = XtVaCreateManagedWidget("arrow",
		xmArrowButtonWidgetClass, tree,
		XmNarrowDirection, XmARROW_RIGHT,
		XmNx, left,
		XmNy, top,
		XmNbackground, 0,
		XmNshadowThickness, 0,
		NULL);

	XtAddCallback(arrow, XmNactivateCallback, arrowCB, NULL);

	return arrow;
}

/*  */
Widget createNodeButton(String caption, Widget tree, int left, int top) {
	//
	Widget nodeButton = XtVaCreateManagedWidget(caption,
		xmPushButtonWidgetClass, tree,
		XmNx, left,
		XmNy, top,
		XmNbackground, 0,
		XmNshadowThickness, 0,
		NULL);

	XtAddCallback(nodeButton, XmNactivateCallback, nodeCB, NULL);

	return nodeButton;
}


/* with children */
void createNode(String caption, Widget tree, int left, int top) {

	Widget arrow = createArrowButton(left, top, tree);

	Widget node = createNodeButton(caption, tree, left + 25, top);

}

/* without children */
void createSubNode(String caption, Widget tree, int left, int top) {

	Widget node = createNodeButton(caption, tree, left + 10, top);

}


/**** this might be like phpPGAdmin ****/
/* parent is fraTreeScrolledWindow */
void loadTree(Widget parent) {

	Widget tree = XtVaCreateManagedWidget("tree",
		xmFormWidgetClass, parent,
		XmNbackground, 0,
		XmNwidth, 640,
		XmNheight, 1024,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomWidget, XmATTACH_FORM,
		NULL);

	printf("from load tree\n");

	//createNode(caption, tree, x, y);
	createNode("PostgreSQL", tree, 0, 0);
	createNode("init_main", tree, 25, 25);
	createNode("tables", tree, 50, 50);
	createNode("doe", tree, 75, 75);
	createNode("cols", tree, 100, 100);
		//createSubNode(String caption, Widget tree, int left, int top);
		createSubNode("d_id", tree, 125, 125);
		createSubNode("d_l", tree, 125, 150);
		createSubNode("d_nm", tree, 125, 175);
		createSubNode("d_val", tree, 125, 200);
		createSubNode("d_t", tree, 125, 225);
	createNode("moe", tree, 75, 250);
	createNode("noe", tree, 75, 275);

}

xmFrames

/*
 * xmFrames.h
 *
 *  Created on: May 7, 2017
 *      Author: chuck
 */

#ifndef XMFRAMES_H_
#define XMFRAMES_H_

#include 

/**** close connections ****/
void exitNicely();

/**** X ****/
Display *display;

/**** handle mouse movement ****/
void mouseCB(XtPointer appShell);
	int app_x;
	int app_y;

/* mouse down inside of separator button */
void vSepMouseDownCB(Widget vSep, XtPointer clientData, XtPointer callData);

/* works for mouse up outside of separator button */
void vSepMouseUpCB(Widget vSep, XtPointer clientData, XtPointer callData);

/* mouse down inside of separator button */
void hSepMouseDownCB(Widget hSep, XtPointer clientData, XtPointer callData);

/* works for mouse up outside of separator button */
void hSepMouseUpCB(Widget hSep, XtPointer clientData, XtPointer callData);

/**** vertical separator ****/
void vSepMouseMoveCB(XtPointer appShell);
	Boolean vSepMouseMoving;

/**** horizontal separator ****/
void hSepMouseMoveCB(XtPointer appShell);
	Boolean hSepMouseMoving;
	Boolean hSepMouseMoved;

/**** creates the menu bar then creates each menu item ****/
Widget createMenuBar(Widget appManager);

/**** creates the menu items ****/
void createMenuBarItems(Widget menuBar, String menuName);

/**** substituted here with a Form ****/
Widget createAppContent(Widget appManager, Widget menuBar, Widget statusBar);

/**** this is where the content is to be put ****/
Widget createContent();
	int v, h;
	Widget vSep;
	Widget hSep;
	Widget label;
	Widget fraTree;
		Widget fraTreeScrolledWindow;
			/* moved to xmTree */
			//void loadTreeForm(Widget parent);
	Widget fraView;
		Widget fraViewScrolledWindow;
			/* moved to xmView */
			//void loadView(Widget parent);
	Widget fraTerm;
		Widget fraTermScrolledWindow;
			//void loadTerm(Widget parent);
				//String getFileContents(String file_name);
void resizeContent();
void destroyContent();

/**** to tell the user what's happening ****/
Widget createStatusBar(Widget appManager);

/**** a simple (yeah right) message box ****/
void createMsgBox(String title, String msg);

/**** menuBar handling ****/
void menuBarCB(Widget widget, XtPointer clientData, XtPointer callData);
	Widget createFileDialog(Widget parent, XmString button, XmString title);
void popdownCB(Widget widget, XtPointer clientData, XtPointer callData);
void fileSelectCB(Widget widget, XtPointer clientData, XtPointer callData);

/**** check for notifications ****/
Boolean notifyCB(XtPointer appShell);

/**** simple menu item dialog handler ****/
void msgBoxCB(Widget widget, XtPointer clientData, XtPointer callData);

/**** what's happening? ****/
void showStatus(String status);

/**** this is a substitute for an array or something ****/
KeySym getMnemonic(String menuName, String menuItemName);


#endif /* XMFRAMES_H_ */

/*
 ============================================================================
 Name        : xmFrames.c
 Author      : chuck
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include 

#include 

#include "xmFrames.h"

#include "xmTree.h"
#include "xmView.h"
#include "xmTerm.h"

//#include 

/*
gcc xmSkeleton.c -o xmSkeleton -I/usr/local/include -I/usr/X11R6/include -L/usr/src/lib -L/usr/local/lib -L/usr/X11R6/lib -lXm -lXt -lX11 -lXpm
*/

/**** public ****/
Widget statusTextField;
Widget statusTimeField;
Widget statusFileName;
Widget contentManager;
Widget dataView;

/**** close connections ****/
void exitNicely() {
	//
	printf("exiting nicely\n");
	//
	printf("done\n");
	exit(0);

}

/**** handle mouse movement ****/
void mouseCB(XtPointer appShell) {

	Window root, ret_root, ret_child;
	int root_x, root_y, win_x, win_y;
	unsigned int mask;

	Position shell_x, shell_y;

	static int last_app_x;
	static int last_app_y;

	char *status;
	root = XDefaultRootWindow(display);
	XQueryPointer(display, root, &ret_root, &ret_child, &root_x, &root_y, &win_x, &win_y, &mask);

	XtVaGetValues(appShell, XmNx, &shell_x, XmNy, &shell_y, NULL);

	app_x = win_x - shell_x;
	app_y = win_y - shell_y;

	//do status if different x, y, else return
	if((app_x != last_app_x) || (app_y != last_app_y)) {
		asprintf(&status, "%d, %d", app_x, app_y);
		showStatus(status);
		last_app_x = app_x;
		last_app_y = app_y;
	} else {
		return;
	}

	return;
}

/**** creates the menu bar then creates each menu item ****/
Widget createMenuBar(Widget appManager) {

	Widget menuBar;

	XmString file;
	XmString edit;

	file = XmStringCreateLocalized ("File");
	edit = XmStringCreateLocalized ("Edit");

	menuBar = XmVaCreateSimpleMenuBar(appManager, "menuBar",
		XmNbackground, 0,
		XmVaCASCADEBUTTON, file, 'F',
		XmVaCASCADEBUTTON, edit, 'E',
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNtopAttachment, XmATTACH_FORM,
		NULL);

	XmStringFree(file);
	XmStringFree(edit);

	createMenuBarItems(menuBar, "File");
	createMenuBarItems(menuBar, "Edit");

	return menuBar;
}

/**** creates the menu items ****/
void createMenuBarItems(Widget menuBar, String menuName) {

	if(!strcmp(menuName, "File")) {

		XmString new;
		XmString newAccel;
		XmString open;
		XmString openAccel;
		XmString save;
		XmString saveAccel;
		XmString run;
		XmString runAccel;
		XmString exit;
		XmString exitAccel;

		new = XmStringCreateLocalized("New...");
		newAccel = XmStringCreateLocalized("Ctrl+N");
		open = XmStringCreateLocalized("Open...");
		openAccel = XmStringCreateLocalized("Ctrl+O");
		save = XmStringCreateLocalized("Save...");
		saveAccel = XmStringCreateLocalized("Ctrl+S");
		run = XmStringCreateLocalized("Run...");
		runAccel = XmStringCreateLocalized("Ctrl+R");
		exit = XmStringCreateLocalized("Exit");
		exitAccel = XmStringCreateLocalized("Ctrl+Q");

		XmVaCreateSimplePulldownMenu (menuBar, "fileMenu", 0, (XtCallbackProc)menuBarCB,
			XmNbackground, 0,
			XmVaPUSHBUTTON, new, 'N', "CtrlN", newAccel,
			XmVaPUSHBUTTON, open, 'O', "CtrlO", openAccel,
			XmVaPUSHBUTTON, save, 'S', "CtrlS", saveAccel,
			XmVaSEPARATOR,
			XmVaPUSHBUTTON, run, 'R', "CtrlR", runAccel,
			XmVaSEPARATOR,
			XmVaPUSHBUTTON, exit, 'x', "CtrlQ", exitAccel,
			NULL);

		XmStringFree(new);
		XmStringFree(newAccel);
		XmStringFree(open);
		XmStringFree(openAccel);
		XmStringFree(save);
		XmStringFree(saveAccel);
		XmStringFree(run);
		XmStringFree(runAccel);
		XmStringFree(exit);
		XmStringFree(exitAccel);

		return;
	}

	if(!strcmp(menuName, "Edit")) {

		XmString cut;
		XmString cutAccel;
		XmString copy;
		XmString copyAccel;
		XmString paste;
		XmString pasteAccel;
		XmString clear;
		XmString clearAccel;

		cut = XmStringCreateLocalized("Cut");
		cutAccel = XmStringCreateLocalized("Ctrl+X");
		copy = XmStringCreateLocalized("Copy");
		copyAccel = XmStringCreateLocalized("Ctrl+C");
		paste = XmStringCreateLocalized("Paste");
		pasteAccel = XmStringCreateLocalized("Ctrl+V");
		clear = XmStringCreateLocalized("Clear");
		clearAccel = XmStringCreateLocalized("Delete");

		XmVaCreateSimplePulldownMenu (menuBar, "editMenu", 1, (XtCallbackProc)menuBarCB,
			XmNbackground, 0,
			XmVaPUSHBUTTON, cut, 't', "CtrlX", cutAccel,
			XmVaPUSHBUTTON, copy, 'C', "CtrlC", copyAccel,
			XmVaPUSHBUTTON, paste, 'P', "CtrlV", pasteAccel,
			XmVaSEPARATOR,
			XmVaPUSHBUTTON, clear, 'l', "Delete", clearAccel,
			NULL);

		XmStringFree(cut);
		XmStringFree(cutAccel);
		XmStringFree(copy);
		XmStringFree(copyAccel);
		XmStringFree(paste);
		XmStringFree(pasteAccel);
		XmStringFree(clear);
		XmStringFree(clearAccel);
	}

	return;
}

/**** substituted here with a Form ****/
Widget createAppContent(Widget appManager, Widget menuBar, Widget statusBar) {

	Widget appContent;

	appContent = XtVaCreateWidget("appContent",
		xmFormWidgetClass, appManager,
		XmNbackground, BlackPixelOfScreen(XtScreen(appManager)),
		XmNwidth, 640,
		XmNheight, 320,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, menuBar,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_WIDGET,
		XmNbottomWidget, statusBar,
		NULL);

	contentManager = appContent;

	return appContent;
}


/* mouse down inside of separator button */
void vSepMouseDownCB(Widget vSep, XtPointer clientData, XtPointer callData) {

	vSepMouseMoving = True;

	XtVaGetValues(hSep, XmNy, &h, NULL);

	showStatus("mouse down");

	return;
}


/* works for mouse up outside of separator button */
void vSepMouseUpCB(Widget vSep, XtPointer clientData, XtPointer callData) {

	vSepMouseMoving = False;

	showStatus("mouse up");

	app_y = h;

	resizeContent();

	return;
}

/* mouse down inside of separator button */
void hSepMouseDownCB(Widget hSep, XtPointer clientData, XtPointer callData) {

	hSepMouseMoving = True;

	XtVaGetValues(vSep, XmNx, &v, NULL);

	showStatus("mouse down");

	return;
}


/* works for mouse up outside of separator button */
void hSepMouseUpCB(Widget hSep, XtPointer clientData, XtPointer callData) {

	hSepMouseMoving = False;

	showStatus("mouse up");

	app_x = v;

	resizeContent();

	return;
}


/**** this is where the content is to be put ****/
Widget createContent() {

	Arg args[10];
	int n = 0;

	if(app_x == 0) app_x = 160;
	if(app_y == 0) app_y = 200;

	if(hSepMouseMoved) {
		app_y = app_y - 32;
		hSepMouseMoved = False;
	}

	display = XOpenDisplay(NULL);

	vSep = XtVaCreateManagedWidget("v",
		xmPushButtonWidgetClass, contentManager,
		XmNx, app_x,
		XmNwidth, 12,
		XmNbackground, 0,
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);

	hSep = XtVaCreateManagedWidget("h",
		xmPushButtonWidgetClass, contentManager,
		XmNy, app_y,
		XmNheight, 12,
		XmNbackground, 0,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, vSep,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);

	fraTree = XtVaCreateManagedWidget("fraTree",
		xmFrameWidgetClass, contentManager,
		XmNbackground, 0,
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_WIDGET,
		XmNrightWidget, vSep,
		NULL);

	label = XtVaCreateManagedWidget("Data Tree",
		xmLabelWidgetClass, fraTree,
		XmNbackground, 0,
		XmNframeChildType, XmFRAME_TITLE_CHILD,
		NULL);

	fraTreeScrolledWindow = XtVaCreateManagedWidget("fraTreeScrolledWindow",
		xmScrolledWindowWidgetClass, fraTree,
		XmNbackground, 0,
		//XmNscrollingPolicy, XmAUTOMATIC,
		NULL);

	//fraView = XtVaCreateManagedWidget("fraView",
	fraView = XtVaCreateWidget("fraView",
		xmFrameWidgetClass, contentManager,
		XmNbackground, 0,
		XmNtopAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_WIDGET,
		XmNbottomWidget, hSep,
		XmNrightAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, vSep,
		NULL);

	label = XtVaCreateManagedWidget("Data View",
		xmLabelWidgetClass, fraView,
		XmNbackground, 0,
		XmNframeChildType, XmFRAME_TITLE_CHILD,
		NULL);

	fraViewScrolledWindow = XtVaCreateManagedWidget("fraViewScrolledWindow",
		xmScrolledWindowWidgetClass, fraView,
		XmNbackground, 0,
		XmNscrollingPolicy, XmAUTOMATIC,
		NULL);

	fraTerm = XtVaCreateManagedWidget("fraTerm",
		xmFrameWidgetClass, contentManager,
		XmNbackground, 0,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, hSep,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, vSep,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);

	label = XtVaCreateManagedWidget("Data Term",
		xmLabelWidgetClass, fraTerm,
		XmNbackground, 0,
		XmNframeChildType, XmFRAME_TITLE_CHILD,
		NULL);

	/* fraTermScrolledWindow */
	XtSetArg(args[n], XmNrows, 40); n++;
	XtSetArg(args[n], XmNcolumns, 80); n++;
	XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
	XtSetArg(args[n], XmNbackground, 0); n++;
	XtSetArg(args[n], XmNresizeHeight, True); n++;
	XtSetArg(args[n], XmNresizeWidth, True); n++;
	fraTermScrolledWindow = XmCreateScrolledText(fraTerm, "fraTermScrolledWindow", args, n);
	XtManageChild(fraTermScrolledWindow);


	XtAddCallback(vSep, XmNarmCallback, vSepMouseDownCB, NULL);
	XtAddCallback(vSep, XmNdisarmCallback, vSepMouseUpCB, NULL);

	XtAddCallback(hSep, XmNarmCallback, hSepMouseDownCB, NULL);
	XtAddCallback(hSep, XmNdisarmCallback, hSepMouseUpCB, NULL);

	loadTree(fraTreeScrolledWindow);

	loadView(fraViewScrolledWindow);

	loadTerm(fraTermScrolledWindow);

	return fraView;
}

/****  ****/
void resizeContent() {
	destroyContent();
	Widget content = createContent();
	XtManageChild(content);
}

/****  ****/
void destroyContent() {
	//
	XtDestroyWidget(fraTerm);
	XtDestroyWidget(fraView);
	XtDestroyWidget(fraTree);
	XtDestroyWidget(hSep);
	XtDestroyWidget(vSep);
}

/**** to tell the user what's happening, mod ****/
Widget createStatusBar(Widget appManager) {

	Widget statusBar;
	Widget statusField;
	Widget statusTime;
	Widget statusFile;

	statusBar = XtVaCreateManagedWidget ("statusBar",
		xmFormWidgetClass, appManager,
		XmNbackground, BlackPixelOfScreen(XtScreen(appManager)),
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);

	statusField = XtVaCreateManagedWidget ("statusField",
		xmTextFieldWidgetClass, statusBar,
		XmNeditable, False,
		XmNcursorPositionVisible, False,
		XmNbackground, BlackPixelOfScreen(XtScreen(appManager)),
		XmNleftAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);

	statusTime = XtVaCreateManagedWidget ("statusTime",
		xmTextFieldWidgetClass, statusBar,
		XmNeditable, False,
		XmNcursorPositionVisible, False,
		XmNbackground, BlackPixelOfScreen(XtScreen(appManager)),
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);

	statusFile = XtVaCreateManagedWidget ("statusFile",
		xmTextFieldWidgetClass, statusBar,
		XmNeditable, False,
		XmNcursorPositionVisible, False,
		XmNbackground, BlackPixelOfScreen(XtScreen(appManager)),
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, statusField,
		XmNrightAttachment, XmATTACH_WIDGET,
		XmNrightWidget, statusTime,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);

	statusTextField = statusField;
	statusTimeField = statusTime;
	statusFileName = statusFile;

	XmTextSetString(statusFileName, "src/term.txt");

	showStatus("status");

	return statusBar;
}

/**** a simple (yeah right) message box ****/
void createMsgBox(String title, String msg) {

	Widget dialog;
	Arg args[14];
	int n = 0;

	XmString xmTitle = XmStringCreateLocalized(title);
	XmString xmMsg = XmStringCreateLocalized(msg);

	XtSetArg(args[n], XmNdialogTitle, xmTitle); n++;
	XtSetArg(args[n], XmNmessageString, xmMsg); n++;
	XtSetArg(args[n], XmNbackground, 0); n++;

	dialog = XmCreateMessageDialog(contentManager, "simple", args, n);

	XtManageChild(dialog);

	XtAddCallback(dialog, XmNokCallback, msgBoxCB, (XtPointer)"ok");
	XtAddCallback(dialog, XmNcancelCallback, msgBoxCB, (XtPointer)"cancel");
	XtAddCallback(dialog, XmNhelpCallback, msgBoxCB, (XtPointer)"help");

	XmStringFree(xmTitle);
	XmStringFree(xmMsg);

	return;
}

/**** menuBar handlers, tricky returns for static widgets ****/
void menuBarCB(Widget widget, XtPointer clientData, XtPointer callData) {

	String menuName = XtName(XtParent(widget));
	String menuItemName = XtName(widget);
	KeySym mnemonic = getMnemonic(menuName, menuItemName);

	static Widget openDialog, saveDialog;

	if(!strcmp(menuName, "fileMenu")) {
		Widget fileDialog = NULL;
		XmString button, title;
		switch(mnemonic) {
			case 'N':
				showStatus("New");
				XmTextSetString(statusFileName, "New File");
				newTextFile("");
				break;
			case 'O':
				showStatus("Open");
				if(openDialog) {
					fileDialog = openDialog;
					XtManageChild(fileDialog);
					return;
				} else {
					button = XmStringCreateLocalized("Open");
					title = XmStringCreateLocalized("Open File");
					openDialog = createFileDialog(XtParent(widget), button, title);
					XtManageChild(openDialog);
				}

				break;
			case 'S':
				showStatus("Save");
				if(saveDialog) {
					fileDialog = saveDialog;
					XtManageChild(fileDialog);
					return;
				} else {
					button = XmStringCreateLocalized("Save");
					title = XmStringCreateLocalized("Save File");
					saveDialog = createFileDialog(XtParent(widget), button, title);
					XtManageChild(saveDialog);
				}

				break;

			case 'R':
				showStatus("Run");
				createMsgBox("Run", "Put run code here");
				break;
			case 'x':
				exitNicely();
				break;
			default:
				printf("pg_menu.php\n");
				return;
			XmStringFree(button);
			XmStringFree(title);
		}
	}

	if(!strcmp(menuName, "editMenu")) {
		switch(mnemonic) {
			case 't':
				showStatus("Cut");
				//createMsgBox("Cut", "Put cut code here");
				menuEditText(EDIT_CUT);
				break;
			case 'C':
				showStatus("Copy");
				//createMsgBox("Copy", "Put copy code here");
				menuEditText(EDIT_COPY);
				break;
			case 'P':
				showStatus("Paste");
				//createMsgBox("Paste", "Put paste code here");
				menuEditText(EDIT_PASTE);
				break;
			case 'l':
				showStatus("Clear");
				//createMsgBox("Clear", "Put clear code here");
				menuEditText(EDIT_CLEAR);
				break;
			default:
				printf("pg_menu.php\n");
				return;
		}
	}

	return;
}

/****  ****/
Widget createFileDialog(Widget parent, XmString button, XmString title) {
	//
	Widget fileDialog = XmCreateFileSelectionDialog(parent, "Files", NULL, 0);
	XtVaSetValues(fileDialog, XmNdialogTitle, title, NULL);
	XtAddCallback(fileDialog, XmNcancelCallback, popdownCB, NULL);
	XtAddCallback(fileDialog, XmNokCallback, fileSelectCB, title);
	return fileDialog;

}

/**** FileSelectionDialog Cancel ****/
void popdownCB(Widget widget, XtPointer clientData, XtPointer callData) {
	//
	XtUnmanageChild(widget);
}

/**** FileSelectionDialog OK ****/
void fileSelectCB(Widget widget, XtPointer clientData, XtPointer callData) {

	XmFileSelectionBoxCallbackStruct *cbs =
			(XmFileSelectionBoxCallbackStruct *)callData;
	String fileName = XmStringUnparse(cbs->value, XmFONTLIST_DEFAULT_TAG,
			XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL);
	String title = XmStringUnparse(clientData, XmFONTLIST_DEFAULT_TAG,
			XmCHARSET_TEXT, XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL);

	printf("title = %s\n", title);

	if(!strcmp(title, "Open File")) {
		XmTextSetString(statusFileName, fileName);
		openTextFile(fileName);
	}

	if(!strcmp(title, "Save File")) {
		saveTextFile(fileName);
	}

	XtUnmanageChild(widget);

	return;
}

/****  ****/



/**** vertical separator ****/
void vSepMouseMoveCB(XtPointer appShell) {
	//
return;
}

/**** horizontal separator ****/
void hSepMouseMoveCB(XtPointer appShell) {

	hSepMouseMoved = True;

	return;
}

/**** check for notifications ****/
Boolean notifyCB(XtPointer appShell) {

	mouseCB(appShell);

	if (vSepMouseMoving == True) {
		vSepMouseMoveCB(appShell);
	} else if (hSepMouseMoving == True) {
		hSepMouseMoveCB(appShell);
	}


	/**** keep checking ****/
	return False;
}

/**** simple menu item dialog handler ****/
void msgBoxCB(Widget widget, XtPointer clientData, XtPointer callData) {

	showStatus("");

	return;
}

/**** what's happening? ****/
void showStatus(String status) {

	XmTextSetString(statusTextField, status);

	return;
}

/**** this is a substitute for an array or something ****/
KeySym getMnemonic(String menuName, String menuItemName) {

        KeySym mnemonic;

	if(!strcmp(menuName, "fileMenu")) {
		if(!strcmp(menuItemName, "button_0")) return XStringToKeysym("N");
		if(!strcmp(menuItemName, "button_1")) return XStringToKeysym("O");
		if(!strcmp(menuItemName, "button_2")) return XStringToKeysym("S");
		if(!strcmp(menuItemName, "button_3")) return XStringToKeysym("R");
		if(!strcmp(menuItemName, "button_4")) return XStringToKeysym("x");
	}

	if(!strcmp(menuName, "editMenu")) {
		if(!strcmp(menuItemName, "button_0")) return XStringToKeysym("t");
		if(!strcmp(menuItemName, "button_1")) return XStringToKeysym("C");
		if(!strcmp(menuItemName, "button_2")) return XStringToKeysym("P");
		if(!strcmp(menuItemName, "button_3")) return XStringToKeysym("l");
	}

	return NULL;
}

/**** the main program ****/
main(int argc, char *argv[]) {

	Widget appShell;
	Widget appManager;
	Widget appContent;
	Widget content;
	Widget menuBar;
	Widget statusBar;

	XtAppContext appContext;

	appShell = XtVaOpenApplication(&appContext, "appClass",
		NULL, 0, &argc, argv, NULL, applicationShellWidgetClass,
		NULL);

	appManager = XtVaCreateManagedWidget("appManager",
		xmFormWidgetClass, appShell,
		NULL);

	menuBar = (Widget)createMenuBar(appManager);
	XtManageChild(menuBar);

	statusBar = createStatusBar(appManager);
	XtManageChild(statusBar);

	appContent = createAppContent(appManager, menuBar, statusBar);
	XtManageChild(appContent);

	content = createContent();
	XtManageChild(content);

	XtRealizeWidget(appShell);

	XtAppAddWorkProc(appContext, notifyCB, appShell);

	XtAppMainLoop(appContext);

}