/****************************************************************************/
/*	File : xgraphic.c														*/
/*																			*/
/*																1993/10/19	*/
/****************************************************************************/
#include			<stdio.h>
#include			<stdarg.h>

#include			"xwins.h"
#include			"app_glob.c"

#define				WINDMASK		(ExposureMask | ButtonReleaseMask | ButtonPressMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask)

typedef struct{
	char			*label;
	int				(*expose_action)(caddr_t),
					(*buttonpress_action)(caddr_t),
					(*buttonrelease_action)(caddr_t),
					(*motion_action)(caddr_t),
					(*enter_action)(caddr_t),
					(*leave_action)(caddr_t);
	caddr_t			action_args;
}D_GRAPHIC;

typedef int			(*P_ACTION)();

int			_handler(XWIN *);


/****************************************************************************/
/*																			*/
/****************************************************************************/
XWIN *MakeXGraphic(int x, int y,
		unsigned width, unsigned height, unsigned bdwidth,
		unsigned long bdcolor, unsigned long bgcolor,
		Window parent, char *label, caddr_t action_data, int mode,...)
{
	va_list			argp;
	XWIN			*new_button;
	D_GRAPHIC		*p_data;
	P_ACTION		p_action;

	if((p_data = (D_GRAPHIC *)calloc(1,sizeof(D_GRAPHIC))) == NULL){
		fprintf(stderr,"No memory for button's data");
		exit(1);
	}

	if((new_button = (XWIN *)calloc(1,sizeof(XWIN))) == NULL){
		fprintf(stderr,"No memory for button");
		exit(1);
	}

	p_data->action_args          = action_data;
	p_data->label                = label;
	p_data->expose_action        = NULL;
	p_data->buttonpress_action   = NULL;
	p_data->buttonrelease_action = NULL;
	p_data->motion_action        = NULL;
	p_data->enter_action         = NULL;
	p_data->leave_action         = NULL;

	va_start(argp,mode);
	while((p_action = va_arg(argp,P_ACTION)) != NULL){
		switch(va_arg(argp,int)){
			case Expose :
				p_data->expose_action = p_action;
				break;
			case ButtonPress :
				p_data->buttonpress_action = p_action;
				break;
			case ButtonRelease :
				p_data->buttonrelease_action = p_action;
				break;
			case MotionNotify :
				p_data->motion_action = p_action;
				break;
			case EnterNotify :
				p_data->enter_action = p_action;
				break;
			case LeaveNotify :
				p_data->leave_action = p_action;
				break;
		}
	}
	va_end(argp);

	new_button->data          = p_data;
	new_button->event_handler = _handler;
	new_button->xid           = XCreateSimpleWindow(display,parent,x,y,width,height,bdwidth,
									bdcolor,bgcolor);

	if(XSaveContext(display,new_button->xid,xwin_context,(caddr_t)new_button) != 0){
		fprintf(stderr,"Error saving xwin_context data");
		exit(1);
	}

	XSelectInput(display,new_button->xid,WINDMASK);

	XMapRaised(display,new_button->xid);

	return new_button;
}


int _handler(XWIN *p_xwin)
{
	D_GRAPHIC			*p_data = (D_GRAPHIC *)p_xwin->data;

	if(event.xany.window == p_xwin->xid){
		switch(event.type){
			case Expose :
				if(p_data->expose_action != NULL)
					(*p_data->expose_action)(p_data->action_args);
				break;
			case ButtonPress :
				if(p_data->buttonpress_action != NULL)
					(*p_data->buttonpress_action)(p_data->action_args);
				break;
			case ButtonRelease :
				if(p_data->buttonrelease_action != NULL)
					(*p_data->buttonrelease_action)(p_data->action_args);
				break;
			case MotionNotify :
				if(p_data->motion_action != NULL)
					(*p_data->motion_action)(p_data->action_args);
				break;
			case EnterNotify :
				if(p_data->enter_action != NULL)
					(*p_data->enter_action)(p_data->action_args);
				break;
			case LeaveNotify :
				if(p_data->leave_action != NULL)
					(*p_data->leave_action)(p_data->action_args);
				break;
		}
	}
}



