
/* 
 * buttonbox.c: a generic and malleable button box widget
 *
 * This code will:
 *	use the external resource file
 * 	obtain resources from the resource manager
 *	create a button box 
 *      add command buttons to a button box
 *	give each command button a unique return tag and label
 *	provide a simple geometry manager for the button box
 * 
 *
 */

#include	<X10/Xlib.h>
#include	"/mit/StaffTools/include/X10/Xtlib.h"
#include	<stdio.h>


#define max(x,y) ((x) > (y) ? (x) : (y))
#define data (caddr_t)

#include "box.bitmap"

Bitmap	iconbitmap;
Pixmap	iconpixmap;
int	twidth, theight;



static Window pw1, bbw1, icon;
static Pixmap	border;
static Pixmap	bg;
static int	borderwidth = 1;
static char	*resfile = "/mit/visual/tools/mentor/toolbox/toolbox.res";
static char	ButtonName[] = "command";
static char	thisButtonName[32];
static char	thisButtonNum[8];

/* Call back procedure for the command buttons */

static void MyFunc(p)
    caddr_t p;
{
  int func_name;

  func_name = (int) p;

  printf("MyFunc called with %d\n", func_name);
  if (func_name == 0) {
    if (fork() == 0) {
      execlp("/mit/StaffTools/bin/xmore","xmore","/mit/mrose/mm/demo/box.help","=50x20+250+200",(char *) 0);
      exit();
    }
  }
  else if (func_name == 1) {
    if (fork() == 0) {
      execlp("/mit/StaffTools/bin/xcalc","xcalc",(char *) 0);
      exit();
    }
  }
  else if (func_name == 2) {
    if (fork() == 0) {
      execlp("/mit/mrose/xgraph/demotest","demotest",(char *) 0);
      exit();
    }
  }
  else if (func_name == 3) {
    if (fork() == 0) {
      execlp("/usr/bin/X10/xterm","xterm","=100x50+100+100","-e","/usr/athena/2020",(char *) 0);
      exit();
    }
  }
  else if (func_name == 4) {
    if (fork() == 0) {
      execlp("/mit/mrose/mm/demo/ispeld","ispeld",(char *) 0);
      exit();
    }
  }
  else if (func_name == 5) {
    if (fork() == 0) {
      execlp("/usr/bin/X10/xterm","xterm","-bi","-ib","/mit/mrose/mm/demo/webster.bitmap","-n"," ","=80x10+0+50","-e","/mit/sipb/vaxbin/webster",(char *) 0);
      exit();
    }
  }

  else if (func_name == 6)
    IconXlate(pw1);

  else if (func_name == 7) {
    printf("quitting\n");
    exit();
  }
}

/* This handler will perform geometry management on the button box */

static XtEventReturnCode EventHandler(event, eventdata)
XEvent *event;
caddr_t eventdata;
{
    WindowInfo		wi;

    switch (event->type) {
	case ResizeWindow:
	    if (XQueryWindow(bbw1, &wi)) {
		XChangeWindow(bbw1,
		   max(1, ((XExposeEvent *)event)->width-20-2*wi.bdrwidth),
		   max(1, ((XExposeEvent *)event)->height-20-2*wi.bdrwidth));
	    }
            break;

        case DestroyWindow: exit(0); break;
    }
    return (XteventHandled);
}


void main(argc, argv)
int argc;
char **argv;
{
    Display	*d;
    Window	ww;
    Arg		buttons[8];
    int		buttoncount, x, y, width;
    XtNameList	name;
    XtClassList class;
    WindowInfo	wi;

/* Arglists for creating the widgets */

    static Arg commandarglist[] = {
	{XtNname,	data thisButtonName},
	{XtNfunction,	data MyFunc},
	{XtNparameter,	data NULL},
    };


    static Arg bbarglist[] = {
	{NULL, NULL}
    };


/* Resource List for obtaining width and background color */

static Resource resourcelist[] = {
    {XtNborderWidth, XtCBorderWidth, XtRInt,
        sizeof(int), data &borderwidth, data NULL},
    {XtNborder, XtCColor, XtRPixmap,
        sizeof(Pixmap), data &border, data NULL},
    {XtNbackground, XtCColor, XtRPixmap,
        sizeof(Pixmap), data &bg, data NULL},
};

    ResourceDataBase	db;
    FILE		*rdbFile;
    XrmValue		val;
    int	i;
    XEvent	event;

/* Macro to add button to button array and increment button count */

#define addbutton(w) \
    buttons[buttoncount].name = XtNwindow; \
    buttons[buttoncount].value = data w; \
    buttoncount++;


/* Initiialize the display and the toolkit */

  if (XOpenDisplay("") == NULL) {
        fprintf(stderr, "error opening display\n");
        exit();
  }
  XtInitialize();

/* Read resource file and get resources */

    rdbFile = fopen(resfile, "r");
    if (rdbFile == NULL) {
        fprintf (stderr, "Can't open resource file %s\n", resfile);
        exit();
    }
    XtGetDataBase(rdbFile, &db);
    XtSetCurrentDataBase(db);
    fclose(rdbFile);

    bg = WhitePixmap;
    border = BlackPixmap;
    XtGetResources(  resourcelist, XtNumber(resourcelist), NULL, 0, RootWindow,
	"buttonTest", "App", &name, &class);




/* Parent window for the button box  */
    pw1 = XCreateWindow(
	RootWindow,
        100,100,
        175,200,
	borderwidth, border, bg);


	iconbitmap = XStoreBitmap(box_width,box_height,box_bits );
	iconpixmap = XMakePixmap( iconbitmap,BlackPixel,WhitePixel );

	twidth = box_width + 10;
	theight = box_height + 15;
	icon = XCreateWindow( RootWindow, DisplayWidth()-(100+twidth),100,
		twidth, theight,
		2,BlackPixmap,WhitePixmap );
	XSetIconWindow( pw1, icon );
	XSelectInput( icon, ExposeWindow|ExposeRegion|ButtonPressed );
	
/* Create the button box */

    bbw1 = XtButtonBoxCreate(pw1, bbarglist, XtNumber(bbarglist));


/*  Create 10 command buttons with unique tags and add to button box*/

    buttoncount = 0;
    for (i=0; i<8; i++) {
        sprintf(thisButtonNum, "%d", i);
        strcat(strcpy(thisButtonName,ButtonName), thisButtonNum);
        commandarglist[2].value = data i;
	ww = XtCommandCreate(bbw1, commandarglist, XtNumber(commandarglist));
	XMapWindow(ww);
	addbutton(ww);
    }
    (void) XtButtonBoxAddButton(bbw1, buttons, buttoncount);


/* Map the button box window, set event handler for the parent window,
   and map the parent window */

    XMoveWindow(bbw1, 10, 10);
    XMapWindow(bbw1);
    XtSetEventHandler(
	pw1, (XtEventHandler)EventHandler, ExposeWindow, data NULL);
    XMapWindow(pw1);

/* Get and dispatch events */

    for(;;) {
	XEvent event;
	XNextEvent(&event);
	if( event.window == icon )
	{
		if( event.type == ExposeRegion
		|| event.type == ExposeWindow )
		{
			XPixmapPut( icon, 0,0,
			twidth/2 - box_width/2,5,
			box_width,box_height,
			iconpixmap,GXcopy,AllPlanes);
		}
		else if( event.type == ButtonPressed )
		{
			IconXlate( icon );
		}
	      }
	(void) XtDispatchEvent(&event);
      }

	
  }


int
IconXlate( w )

	Window	w;
{
WindowInfo	wi1, wi2;
int		steps = 20;
int		xs,ys,ws,hs,i,j;

	XQueryWindow( w, &wi1 );
	if( !wi1.assoc_wind )
	{
		fprintf(stderr,"IconXlate: window has no associate\n");
		return -1;
	}

	XQueryWindow( wi1.assoc_wind, &wi2 );
	XUnmapWindow( w );
	XFlush();

	for( j=0, i=0; i<steps; i++ )
	{
		xs = (wi2.x - wi1.x)/steps;
		ys = (wi2.y - wi1.y)/steps;
		ws = (wi2.width - wi1.width)/steps;
		hs = (wi2.height - wi1.height)/steps;

		DrawBox( RootWindow,
			wi1.x + (i*xs),
			wi1.y + (i*ys),
			wi1.width + (i*ws),
			wi1.height + (i*hs),
			2,
			BlackPixel,
			GXinvert,
			AllPlanes );

		if( i>2 )
		{
		DrawBox( RootWindow,
			wi1.x + (j*xs),
			wi1.y + (j*ys),
			wi1.width + (j*ws),
			wi1.height + (j*hs),
			2,
			BlackPixel,
			GXinvert,
			AllPlanes );
		j++;
		}

		XFlush();

	}

	for( ; j<steps; j++ )
		DrawBox( RootWindow,
			wi1.x + (j*xs),
			wi1.y + (j*ys),
			wi1.width + (j*ws),
			wi1.height + (j*hs),
			2,
			BlackPixel,
			GXinvert,
			AllPlanes );
	
	XMapWindow( wi1.assoc_wind );
	return 0;
}

int
DrawBox( win, x,y, w,h, thickness, pixel, func, planes )

	Window 	win;
	int	x,y,w,h,thickness,pixel,func,planes;
{
static Vertex	vlist[5];

	vlist[0].x = x;
	vlist[0].y = y;
	vlist[1].x = (x+w)-1;
	vlist[1].y = y;
	vlist[2].x = (x+w)-1;
	vlist[2].y = (y+h)-1;
	vlist[3].x = x;
	vlist[3].y = (y+h)-1;
	vlist[4].x = x;
	vlist[4].y = y;
	XDraw( win, vlist, 5, thickness, thickness, pixel, func, planes );
	return 0;
}

