[comp.windows.x] World database display program

ebina@urbana.mcd.mot.COM (05/29/91)

I found this nice world map display program for Amiga's, and since I have
seen several requests here for map programs, I did a quick port of the
display program to X11R4.

The source code for the display program follows, the database files can
be ftped from ab20.larc.nasa.gov (128.155.23.64) in the directory
/amiga/graphics/wdb/


---------- cut here ------------
/***************** Display WorldData Base ********************/
#include <stdio.h>
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Scrollbar.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Simple.h>

#define DEF_BLACK	BlackPixel(dsp, DefaultScreen(dsp))
#define DEF_WHITE	WhitePixel(dsp, DefaultScreen(dsp))
#define DEF_GC		DefaultGC(dsp, DefaultScreen(dsp))
#define DEF_CMAP	DefaultColormap(dsp, DefaultScreen(dsp))
#define ABS(X)		(((X)<0)?-(X):(X))

#define	QSPAN	90*6000
#define HSPAN	QSPAN*2
#define WSPAN	QSPAN*4

#define PCount	1024

char *PickFile();
void PlotProc();
void QuitProc();
void LatProc();
void LonProc();
void MagProc();
void ButtonProc();

typedef struct { short Code, Lat, Lon; } PNT ;
#define PNTSiz	sizeof(PNT)

PNT		*p;
double		zoom, stretch = 1.2;
long		Latitude, Longitude,
		Lat, Lon, X_Scale, Y_Scale,
		ymax, ymin, xmax, xmin, xspan, yspan;
short		CTable[] = {
0x0000,0x0ddd,0x0d00,0x00a0,0x0ff0,0x05f5,0x0aaf,0x033f };
long		colr[8];

XtAppContext	app;
Widget		top, view;
Widget		control, panel;
Widget		lat_sc, lat_text, lat_lab;
Widget		lon_sc, lon_text, lon_lab;
Widget		mag_sc, mag_text, mag_lab;
Widget		strch_text, strch_lab;
Widget		plot_btn, quit_btn, file_lab;
Display		*dsp;
Visual		*vis;
Window		Bwindow;
GC		drawGC;
Colormap	Cmap;
int		NumCells;
Arg		arg[30];
Cardinal	argcnt;
short		NewLon, NewLat, deflt = 1;
unsigned short	newCenter = 0;
char		*infile;

XtCallbackRec callplot[] = {
	{PlotProc, NULL},
	{NULL, NULL}
};

XtCallbackRec callquit[] = {
	{QuitProc, NULL},
	{NULL, NULL}
};

XtCallbackRec calllat[] = {
	{LatProc, NULL},
	{NULL, NULL}
};

XtCallbackRec calllon[] = {
	{LonProc, NULL},
	{NULL, NULL}
};

XtCallbackRec callmag[] = {
	{MagProc, NULL},
	{NULL, NULL}
};


/************** convert Minutes to "ddd'mm" *************/
void
MinToStr(str, min)
	char	*str;
	long	min;
{
	short	deg;

	deg = min / 60;
	min = min - deg * 60;
	if(min < 0)
		min = -min;
	sprintf(str,"%d'%d",deg,min);
}


/************* Convert "ddd'mm" to mins ***********/
long
DegToMin(s)
	char	*s;
{
	short	deg,min;
	char	str[10],*strchr(),*cp;

	strcpy(str,s);
	if(cp = strchr(str,'\047'))
	  { *cp = '\0';
		min = atoi(++cp);
	  }
	else
		min = 0;
	if((deg = atoi(str)) < 0)
		min = -min;
	return(deg * 60 + min);
}


void
SetSpecs()
{

	Longitude = Lon * 100;
	Latitude  = Lat * 100;

	/* 120/100 is correction for vertical stretch of 1080 Monitor	*/
	X_Scale   = zoom * 100.0 * stretch * 320.0 / 10800.0;	
	Y_Scale   = zoom * 100.0 * 200.0 /  5400.0;	
	ymax = QSPAN/zoom;
	ymin = -ymax;
	xmax = HSPAN / (zoom * stretch);
	xmin = -xmax;
	xspan = xmax - xmin;
	yspan = ymax - ymin;
}


/*
 * Added this function to get shared colormap entries, or the closest existing
 * entry.  -EJB
 */
void
FindColor(colr)
XColor *colr;
{
	int i, match;
	double rd, gd, bd, dist, mindist;
	int cindx;
	XColor def_colrs[256];

	match = XAllocColor(dsp, Cmap, colr);
	if (match == 0)
	{
		for (i=0; i<NumCells; i++)
		{
			def_colrs[i].pixel = i;
		}
		XQueryColors(dsp, Cmap, def_colrs, NumCells);
		mindist = 65536.0 * 65536.0;
		cindx = colr->pixel;
		for (i=0; i<NumCells; i++)
		{
			rd = (def_colrs[i].red - colr->red) / 256.0;
			gd = (def_colrs[i].green - colr->green) / 256.0;
			bd = (def_colrs[i].blue - colr->blue) / 256.0;
			dist = (rd * rd * rd * rd) +
				(gd * gd * gd * gd) +
				(bd * bd * bd * bd);
			if (dist < mindist)
			{
				mindist = dist;
				cindx = def_colrs[i].pixel;
			}
		}
		colr->pixel = cindx;
		colr->red = def_colrs[cindx].red;
		colr->green = def_colrs[cindx].green;
		colr->blue = def_colrs[cindx].blue;
	}
}


void
init_gfx(argc, argv)
	int argc;
	char *argv[];
{
	int i;

	XtToolkitInitialize ();
	app = XtCreateApplicationContext ();
	dsp = XtOpenDisplay (app, NULL, "wdb", "Wdb",
			NULL, 0,
			&argc, argv);
	top = XtAppCreateShell("wdb", "Wdb",
			applicationShellWidgetClass, dsp, NULL, 0);
	vis = DefaultVisual(dsp, DefaultScreen(dsp));
	NumCells = DisplayCells(dsp, DefaultScreen(dsp));

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNtitle, "Micro WorldDataBase-II 
Version 2.0"); argcnt++;
	XtSetArg(arg[argcnt], XtNiconName, "wdb"); argcnt++;
	XtSetValues(top, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNwidth, 640); argcnt++;
	XtSetArg(arg[argcnt], XtNheight, 400); argcnt++;
	XtSetArg(arg[argcnt], XtNbackground, DEF_BLACK); argcnt++;
	view = XtCreateWidget("View", simpleWidgetClass, top,
		arg, argcnt);

	XtManageChild(view);
	XtRealizeWidget(top);

	XtAddEventHandler(view, ButtonPressMask, FALSE, ButtonProc, NULL);

	Bwindow = XtWindow(view);
	Cmap = DEF_CMAP;
	for (i=0; i<8; i++)
	{
		char cname[5];
		XColor tcolr;

		sprintf(cname, "#%03x", CTable[i]);
		XParseColor(dsp, Cmap, cname, &tcolr);
		tcolr.flags = DoRed|DoGreen|DoBlue;
		FindColor(&tcolr);
		colr[i] = tcolr.pixel;
	}
	drawGC = XCreateGC(dsp, Bwindow, 0, NULL);
	XSetForeground(dsp, drawGC, DEF_BLACK);
}


/************************** clean up **********************/
void
quit()
{
	free((char *)p);
	XFreeGC(dsp, drawGC);
	exit(0);
}


void OpenContrWindow(infile)
	char *infile;
{
	argcnt = 0;
	XtSetArg(arg[argcnt], XtNtitle, "Specs Control"); argcnt++;
	XtSetArg(arg[argcnt], XtNiconName, "specs"); argcnt++;
	control = XtCreatePopupShell("Control",
		transientShellWidgetClass, top, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNwidth, 256); argcnt++;
	XtSetArg(arg[argcnt], XtNheight, 159); argcnt++;
	panel = XtCreateWidget( "Panel", formWidgetClass,
		control, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNhorizDistance, 18); argcnt++;
	XtSetArg(arg[argcnt], XtNvertDistance, 4); argcnt++;
	XtSetArg(arg[argcnt], XtNwidth, 14); argcnt++;
	XtSetArg(arg[argcnt], XtNheight, 100); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNorientation, XtorientVertical); argcnt++;
	XtSetArg(arg[argcnt], XtNjumpProc, calllat); argcnt++;
	lat_sc = XtCreateWidget( "Lat", scrollbarWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromHoriz, lat_sc); argcnt++;
	XtSetArg(arg[argcnt], XtNvertDistance, 4); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, "   0'0"); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainLeft); argcnt++;
	lat_text = XtCreateWidget( "LatText", labelWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromHoriz, lat_text); argcnt++;
	XtSetArg(arg[argcnt], XtNvertDistance, 4); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, "Latitude"); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNborderWidth, 0); argcnt++;
	lat_lab = XtCreateWidget( "LatLab", labelWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNhorizDistance, 60); argcnt++;
	XtSetArg(arg[argcnt], XtNvertDistance, 43); argcnt++;
	XtSetArg(arg[argcnt], XtNwidth, 180); argcnt++;
	XtSetArg(arg[argcnt], XtNheight, 12); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNorientation, XtorientHorizontal); argcnt++;
	XtSetArg(arg[argcnt], XtNjumpProc, calllon); argcnt++;
	lon_sc = XtCreateWidget( "Lon", scrollbarWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromVert, lon_sc); argcnt++;
	XtSetArg(arg[argcnt], XtNhorizDistance, 124); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, "Longitude"); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNborderWidth, 0); argcnt++;
	lon_lab = XtCreateWidget( "LonLab", labelWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromHoriz, lon_lab); argcnt++;
	XtSetArg(arg[argcnt], XtNfromVert, lon_sc); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, "   0'0"); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainTop); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainRight); argcnt++;
	lon_text = XtCreateWidget( "LonText", labelWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromVert, lon_lab); argcnt++;
	XtSetArg(arg[argcnt], XtNhorizDistance, 100); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, "Horiz Stretch:"); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNborderWidth, 0); argcnt++;
	strch_lab = XtCreateWidget( "StrchLab", labelWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromHoriz, strch_lab); argcnt++;
	XtSetArg(arg[argcnt], XtNfromVert, lon_lab); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, " 1.20"); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainRight); argcnt++;
	strch_text = XtCreateWidget( "StrchText", labelWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromVert, strch_lab); argcnt++;
	XtSetArg(arg[argcnt], XtNhorizDistance, 100); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, "Magnification:"); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNborderWidth, 0); argcnt++;
	mag_lab = XtCreateWidget( "MagLab", labelWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromHoriz, mag_lab); argcnt++;
	XtSetArg(arg[argcnt], XtNfromVert, strch_lab); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, " 1.00"); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainRight); argcnt++;
	mag_text = XtCreateWidget( "magText", labelWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNhorizDistance, 19); argcnt++;
	XtSetArg(arg[argcnt], XtNvertDistance, 127); argcnt++;
	XtSetArg(arg[argcnt], XtNwidth, 220); argcnt++;
	XtSetArg(arg[argcnt], XtNheight, 11); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainRight); argcnt++;
	XtSetArg(arg[argcnt], XtNorientation, XtorientHorizontal); argcnt++;
	XtSetArg(arg[argcnt], XtNjumpProc, callmag); argcnt++;
	mag_sc = XtCreateWidget( "Mag", scrollbarWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromVert, mag_sc); argcnt++;
	XtSetArg(arg[argcnt], XtNhorizDistance, 19); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, "Plot"); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNcallback, callplot); argcnt++;
	plot_btn = XtCreateWidget( "Plot", commandWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromVert, mag_sc); argcnt++;
	XtSetArg(arg[argcnt], XtNfromHoriz, plot_btn); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, "Quit"); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNcallback, callquit); argcnt++;
	quit_btn = XtCreateWidget( "Quit", commandWidgetClass,
		panel, arg, argcnt);

	argcnt = 0;
	XtSetArg(arg[argcnt], XtNfromVert, mag_sc); argcnt++;
	XtSetArg(arg[argcnt], XtNfromHoriz, quit_btn); argcnt++;
	XtSetArg(arg[argcnt], XtNlabel, infile); argcnt++;
	XtSetArg(arg[argcnt], XtNtop, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNbottom, XtChainBottom); argcnt++;
	XtSetArg(arg[argcnt], XtNleft, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNright, XtChainLeft); argcnt++;
	XtSetArg(arg[argcnt], XtNborderWidth, 0); argcnt++;
	file_lab = XtCreateWidget( "FileLab", labelWidgetClass,
		panel, arg, argcnt);

	XtManageChild(lat_sc);
	XtManageChild(lat_text);
	XtManageChild(lat_lab);
	XtManageChild(lon_sc);
	XtManageChild(lon_text);
	XtManageChild(lon_lab);
	XtManageChild(mag_sc);
	XtManageChild(mag_text);
	XtManageChild(mag_lab);
	XtManageChild(strch_text);
	XtManageChild(strch_lab);
	XtManageChild(plot_btn);
	XtManageChild(quit_btn);
	XtManageChild(file_lab);
	XtManageChild(panel);
	XtRealizeWidget(control);

	XtMoveWidget(control, 10, 200);
	XtPopup(control, XtGrabNone);

	Lat = 0;
	Lon = 0;
	zoom = 1.0;
}


void
load(fn)
	char	*fn;
{
	int Px, Py;
	long x, y, LonPrv, LatPrv;
	PNT	*pp;
	PNT	*pend;
	FILE	*fp;
	long	z, xprv=0, yprv;
	short	is_out=0, was_out=0, n, ColorNum, newseg;

	LonPrv = LatPrv = 0;
	if ((fp = fopen(fn, "r")) != NULL)
	{
		while (n = (short) fread(p, PNTSiz, PCount, fp))
		{
			for (pp = p,pend = p+n; pp < pend; pp++)
			{
				/* do displacement	*/
				x = pp->Lon*100 - Longitude;
				y = pp->Lat*100 - Latitude;

				/* wrap around for East-West	*/
				if (x < -HSPAN)
					x += WSPAN;
				else if (x > HSPAN)
					x -= WSPAN;

				if (pp->Code > (int)5)
				{	
				  	ColorNum = (pp->Code / 1000);
					XSetForeground(dsp, drawGC, colr[ColorNum]);
				  	newseg = 1;
				}

				/* ignore pts outside magnified area	*/
				if((x < xmin || x > xmax || y < ymin || y > ymax))
				{	
				  	is_out = 1;
					if(was_out)
					/* out to out	*/
					{
						LonPrv = x;
						LatPrv = y;
					  	goto go_on;
					}
					/* in to out	*/
					Px = 320 + (LonPrv * X_Scale)/10000;
					Py = 200 - (LatPrv * Y_Scale)/10000;
				}
				else
				{
					/* out to in	*/
					is_out = 0;
					if(was_out)
					{
						Px = 320 + (LonPrv * X_Scale)/10000;
						Py = 200 - (LatPrv * Y_Scale)/10000;
					}
								
						/* in to in	*/
				}
				LonPrv = x;
				LatPrv = y;

				/* scale pts w/in area to interlace screen */
				x = 320 + (x * X_Scale)/10000;
				y = 200 - (y * Y_Scale)/10000;

				/* ignore duplicates	*/
				if (newseg  == 0 && x == xprv && y == yprv)
					continue;

				/* if new segment, move to place	*/
				if (newseg == 1 || ABS(z - pp->Lon) > 10800)
				{	
					Px = x;
					Py = y;
					XDrawPoint(dsp, Bwindow, drawGC, Px,Py);
				}
				else
				{
					/* draw next point of seg	*/
					XDrawLine(dsp, Bwindow, drawGC,
						Px, Py, x, y);
					Px = x;
					Py = y;
				}

				xprv = x;
				yprv = y;
				z = pp->Lon;
go_on:
				was_out = is_out;
				newseg = 0;
			}
		}
		fclose(fp);
	}
}


void
PlotProc(w, client_data, call_data)
        Widget w;
        caddr_t client_data, call_data;
{
	if(newCenter)
	{
		Lon = NewLon;
		Lat = NewLat;
		newCenter = 0;
	}
	SetSpecs();				 /* redo parameters	*/
	XClearArea(dsp, Bwindow, 0, 0, 0, 0, FALSE);
	load(infile);		 /* redisplay map	*/
}


void
QuitProc(w, client_data, call_data)
        Widget w;
        caddr_t client_data, call_data;
{
	quit();
}


void
LatProc(w, client_data, call_data)
        Widget w;
        XtPointer client_data, call_data;
{
	float percent;
	int newy;
	char label[10];

	percent = *((float *)call_data);
	newy = (int)(10800.0 * percent);
	newy = 10800 - newy;
	newy = newy - 5400;;
	MinToStr(label, newy);
	argcnt = 0;
	XtSetArg(arg[argcnt], XtNlabel, label); argcnt++;
	XtSetValues(lat_text, arg, argcnt);
	Lat = newy;
}


void
LonProc(w, client_data, call_data)
        Widget w;
        XtPointer client_data, call_data;
{
	float percent;
	int newx;
	char label[10];

	percent = *((float *)call_data);
	newx = (int)(21600.0 * percent);
	newx = newx - 10800;;
	MinToStr(label, newx);
	argcnt = 0;
	XtSetArg(arg[argcnt], XtNlabel, label); argcnt++;
	XtSetValues(lon_text, arg, argcnt);
	Lon = newx;
}


void
MagProc(w, client_data, call_data)
        Widget w;
        XtPointer client_data, call_data;
{
	float percent;
	int newx;
	double mag;
	char label[10];

	percent = *((float *)call_data);
	newx = (int)(11900.0 * percent) + 100;
	mag = newx / 100.0;
	sprintf(label, "%5.2f", mag);
	argcnt = 0;
	XtSetArg(arg[argcnt], XtNlabel, label); argcnt++;
	XtSetValues(mag_text, arg, argcnt);
	if(deflt)
	{
		infile = PickFile(mag);
		argcnt = 0;
		XtSetArg(arg[argcnt], XtNlabel, infile); argcnt++;
		XtSetValues(file_lab, arg, argcnt);
	}
	zoom = mag;
}


void
ButtonProc(w, data, event)
	Widget w;
	caddr_t data;
	XEvent *event;
{
	XButtonPressedEvent *BuEvent = (XButtonPressedEvent *)event;
	float percent;
	int newx, newy;
	char label[10];

	NewLon = Lon + ((BuEvent->x - 320.0) * 10800.0) /
		(320.0 * zoom * stretch);
	newx = NewLon + 10800;
	percent = (float)newx / 21600.0;
	XawScrollbarSetThumb(lon_sc, percent, -1.0);
	MinToStr(label, NewLon);
	argcnt = 0;
	XtSetArg(arg[argcnt], XtNlabel, label); argcnt++;
	XtSetValues(lon_text, arg, argcnt);

	NewLat = Lat + ((200.0 - BuEvent->y) * 5400.0) /
		(200.0 * zoom);
	newy = NewLat + 5400;;
	newy = 10800 - newy;
	percent = (float)newy / 10800.0;
	XawScrollbarSetThumb(lat_sc, percent, -1.0);
	MinToStr(label, newy);
	argcnt = 0;
	XtSetArg(arg[argcnt], XtNlabel, label); argcnt++;
	XtSetValues(lat_text, arg, argcnt);

	newCenter = 1;
}


/***************************** main routine ********************************/
main(argc, argv)
	int argc;
	char *argv[];
{
	unsigned short code;

	if (argv[1][1] == '?')
	{
		fprintf(stderr, "Usage: WDB [data_file]\n");
		exit(1);
	}

	if (argc == 2)
	{
		if (access(argv[1], R_OK) < 0)
		{
			fprintf(stderr, "Cannot find data file(%s)\n", argv[1]);
			exit(1);
		}
		infile = argv[1];
		deflt = 0;
	}
	else if ((infile = PickFile(1.0)) == NULL)
	{
		fprintf(stderr, "Cannot find data file\n");
		exit(1);
	}
	if ((p = (PNT *)malloc(code = PCount*PNTSiz)) == NULL)
	{
		fprintf(stdout, "Insufficient memory for buffer\n");
		exit(1);
	}

	init_gfx(argc, argv);
	OpenContrWindow(infile);

	XtAppMainLoop(app);
}


char *
PickFile(mag)
	double	mag;
{
	static double	maglvl[] = { 0.0, 36.0, 12.0, 6.0, 2.0 };
	static char	filename[12];
	short	level;

	for(level = 1; level < 5; level++)
	{
		if (mag > maglvl[level])
			break;
	}

	for( ; level < 6; level++)
	{
		sprintf(filename, "wdb.%d.all", level);
		if (access(filename, R_OK) == 0)
		{
			return(filename);
		}
	}
	return(NULL);
}