/*
 ******************************************************************************
 *
 *	ParcPlace Systems, Inc.
 *	Copyright (c) 1990, ParcPlace Systems, Inc. USA   All rights reserved.
 *
 ****************************************************************************
 *
 *	File:	cb_inf.H
 *
 *	Functions(s):
 *
 *	Description:
 *		OI_d_tech class header
 *		OI_d_tech is the base class for all displayable OI objects
 *		conceptually, although it is actually derived from OI_callback
 *		to allow callbacks to user object member functions to work.
 *
 *	RCSid = "$Id: cb_inf.H,v 4.16.1.2 1993/07/28 16:15:37 garya Exp $"
 *
 ****************************************************************************
 */

#ifndef OI_cb_inf_H
#define OI_cb_inf_H

	// class forward reference declarations
	class OI_cb_class;

		struct	OI_cb_def	{
		const	char		*nam ;			/* callback name, traditionally of form "cbMyCallbackName" */
			XrmQuark	*quarkp ;		/* ptr to place to store cb_nam converted to quark, may be NULL */
		const	char		*ret_val ;		/* ptr to return value type as string */
		const	char		*args ;			/* ptr to callback argument strings, no parens, with commas: "OI_d_tech*, void*,..." */
		} ;
	
	extern		OI_cb_class	**OI_callback_tblp ;	/* ptr to table of callback types */
	extern		OI_number	OI_num_callback ;	/* # active entries in OI_callback_tblp */
	extern		OI_number	OI_mx_callback ;	/* total # slots in OI_callback_tblp */

		class OI_cb_class	{			/* class info for a callback type */
			XrmQuark	q ;			/* quark corresponding to callback type */
		const	char		*pr_rtn ;		/* prototype return type string */
		const	char		*pr_var ;		/* prototype variables string */
		 public:
					OI_cb_class(const char*, const char*, const char*) ;
			XrmQuark	quark()			{ return(q); }
		const	char		*return_type()		{ return(pr_rtn); }
		const	char		*variables()		{ return(pr_var); }
		const	char		*name() ;
		} ;

/* ctl_bits */
#define			OI_cb_disable	0x1L			/* 1 => callback is disabled */
#define			OI_cb_waiting	0x2L			/* 1 => callback is waiting to be processed */
#define			OI_cb_suspend	0x4L			/* 1 => callback is suspended */
#define			OI_cb_clr_argp	0x8L			/* 1 => clear argp after callback (special flag (gag) for dispatching synthetic events */
								/* CAUTION! used only in one kind of callback */
#define			OI_cb_rslv_arg		0x10L		/* 1 => argument needs resolution */
#define			OI_cb_rslv_arg_always	0x20L		/* 1 => argument needs resolution, always */
#define			OI_cb_rslv_obj		0x40L		/* 1 => object needs resolution */
#define			OI_cb_rslv_obj_always	0x80L		/* 1 => object needs resolution, always */
#define			OI_cb_half_baked	0x100L		/* 1 => this function is half baked */
#define			OI_cb_in_use		0x200L		/* 1 => callback type is being dispatched */
#define			OI_cb_invalid		0x400L		/* 1 => callback is invalid, should be deleted when ref count goes to zero */

		class OI_cb {					/* primitive callback info */
			OI_fnp		fp ;			/* ptr to function */
			OI_callback	*op ;			/* object for member function callback */
			OI_memfnp	memfp ;			/* ptr to member function */
			void		*ap ;			/* arg to pass in callback */
		 protected:
			unsigned long	ctl_bits ;		/* control bits */
		 private:
			OI_bool		is_clear_argp()			{ return((ctl_bits & OI_cb_clr_argp) ? OI_yes : OI_no); }
		 public:
					OI_cb() ;
					OI_cb(OI_fnp fp, void *argp) ;
					OI_cb(OI_callback *objp, OI_memfnp mfp, void *argp) ;
		virtual			~OI_cb() ;
			void		*argp()				{ return(ap); }
			void		callback() ;
			void		callback(void*) ;
			void		callback(void*,OI_number) ;
			void		callback(void*,OI_number,OI_number) ;
			void		callback(void*,OI_number,long) ;
			void		callback(void*,OI_number,long,long) ;
			void		callback(void*,OI_number,OI_number,OI_number) ;
			void		callback(void*,OI_number,OI_number,long) ;
			void		callback(void*,OI_number,OI_number,OI_number,OI_number,OI_number) ;
			void		callback(void*,long,long);
			void		callback(void*,const XEvent*) ;
			void		callback(void*,void*,OI_number) ;
			int		check_callback(void*) ;
			int		check_callback(void*,OI_number) ;
			int		check_callback(void*,OI_number,char) ;
			int		check_callback(void*,OI_number,OI_number,char) ;
			int		check_callback(void*,OI_number,OI_number,OI_number,char) ;
			int		check_callback(void*,OI_number,long,long) ;
			int		check_callback(void*,const XEvent*) ;
			void		*ptr_callback(void*) ;
			OI_bool		cb_defined()			{ return((fp!=NULL || memfp!=NULL) ? OI_yes : OI_no); }
			void		clear_argp()			{ ctl_bits &= ~OI_cb_clr_argp; ap=NULL; }
			void		clear_cb()			{ fp=NULL; op=NULL; memfp=NULL; ap=NULL; ctl_bits=0; }
			void		pseudo_delete()		
						{ fp=NULL; op=NULL; memfp=NULL; ap=NULL; ctl_bits&= (OI_cb_in_use | OI_cb_invalid); }
			void		clear_half_baked()		{ ctl_bits &= ~OI_cb_half_baked; }
			void		clear_resolve_arg()		{ ctl_bits &= ~OI_cb_rslv_arg; }
			void		clear_resolve_object()		{ ctl_bits &= ~OI_cb_rslv_obj; }
			void		clear_suspend()			{ ctl_bits &= ~OI_cb_suspend; }
			void		clear_waiting()			{ ctl_bits &= ~OI_cb_waiting; }
			void		disable()			{ ctl_bits |= OI_cb_disable; }
			void		enable()			{ ctl_bits &= ~(OI_cb_disable | OI_cb_suspend); }
			OI_fnp		fnp()				{ return(fp); }
			OI_bool		is_enable()			{ return((ctl_bits & OI_cb_disable) ? OI_no : OI_yes); }
			OI_bool		is_half_baked()			{ return((ctl_bits & OI_cb_half_baked) ? OI_yes : OI_no); }
			OI_bool		is_resolve_arg()		{ return((ctl_bits & OI_cb_rslv_arg) ? OI_yes : OI_no); }
			OI_bool		is_resolve_arg_always()		{ return((ctl_bits & OI_cb_rslv_arg_always) ? OI_yes : OI_no); }
			OI_bool		is_resolve_object()		{ return((ctl_bits & OI_cb_rslv_obj_always) ? OI_yes : OI_no); }
			OI_bool		is_resolve_object_always()	{ return((ctl_bits & OI_cb_rslv_obj) ? OI_yes : OI_no); }
			OI_bool		is_suspend()			{ return((ctl_bits & OI_cb_suspend) ? OI_yes : OI_no); }
			OI_bool		is_waiting()			{ return((ctl_bits & OI_cb_waiting) ? OI_yes : OI_no); }
			OI_memfnp	memfnp()			{ return(memfp); }
			OI_callback	*objp()				{ return(op); }
		virtual	const char	*proto_inf();
		virtual	const char	*proto_return_type();
		virtual	const char	*proto_variables();
		virtual	const char	*proto_cb_name();
			OI_bool		resolve_callback( void* );
			void		set_argp(void *p)		{ ap=p; }
			void		set_cb(OI_fnp f, void *p)	{ fp=f; op=NULL; memfp=NULL; ap=p; }
			void		set_cb(OI_callback *obp, OI_memfnp mf, void *p)		{ fp=NULL; op=obp; memfp=mf; ap=p; }
			void		set_clear_argp()		{ ctl_bits |= OI_cb_clr_argp; }
			void		set_fnp(OI_fnp f)		{ fp=f; op=NULL; memfp=NULL; }
			void		set_half_baked()		{ ctl_bits |= OI_cb_half_baked; }
			void		set_memfnp(OI_callback *obp, OI_memfnp mf)		{ fp=NULL; op=obp; memfp=mf; }
			void		set_obj(OI_callback *obp)	{ op=obp; }
			void		set_resolve_arg()		{ ctl_bits |= OI_cb_rslv_arg; }
			void		set_resolve_arg_always()	{ ctl_bits |= OI_cb_rslv_arg_always; }
			void		set_resolve_object()		{ ctl_bits |= OI_cb_rslv_obj; }
			void		set_resolve_object_always()	{ ctl_bits |= OI_cb_rslv_obj_always; }
			void		set_suspend()			{ ctl_bits |= OI_cb_suspend; }
			void		set_waiting()			{ ctl_bits |= OI_cb_waiting; }
		} ;

		class OI_cb_inf : public OI_cb {		/* callback information */
			OI_cb_inf	*nxtp ;			/* link to next callback, NULL => end of list */
			char		*proto_infp ;		/* prototype info, "obj<null>fn<null>arg<null>" */
			OI_cb_class	*clsp ;			/* ptr to class record for callback type */
			OI_number	ref_cnt ;		/* reference count of callback processing loops in process */
		 public:
					OI_cb_inf(XrmQuark t)	;
		virtual			~OI_cb_inf();
			char		*arg_name() ;					/* get argument name for callback */
		inline	void		clear_in_use()			{ ctl_bits &= ~OI_cb_in_use; }
			void		dereference() ;
			char		*fn_name() ;					/* get function/member function name for callback */
			OI_bool		is_busy()			{ return(ref_cnt ? OI_yes : OI_no); }
		inline	OI_bool		is_in_use()			{ return((ctl_bits & OI_cb_in_use) ? OI_yes : OI_no); }
			OI_bool		is_valid()			{ return((ctl_bits & OI_cb_invalid) ? OI_no : OI_yes); }
		const	char		*name()				{ return(clsp->name()); }
			OI_cb_inf	*next()				{ return(nxtp); }
			char		*obj_name() ;					/* get object name for member function callback */
		virtual	const	char	*proto_inf();
		virtual	const	char	*proto_return_type();
		virtual	const	char	*proto_variables();
		virtual	const	char	*proto_cb_name();
			void		reference()			{ ref_cnt++; }
		inline	void		set_in_use()			{ ctl_bits |= OI_cb_in_use; }
			void		set_invalid()			{ ctl_bits |= OI_cb_invalid; }
			void		set_next(OI_cb_inf *p)		{ nxtp=p; }
			void		set_proto(const char*,const char*,const char*) ;		/* set prototype info */
			XrmQuark	type()				{ return(clsp->quark()); }
		} ;

//-------------------------------------------------------------------------------------------------		
//		
//	DOCUMENTED FUNCTIONS	
//		Functions below this point are documented in the programmer's manual under this
//		object and are available to the toolkit users.
//		Please maintain alphabetical order to facilitate releases and documentation.
//
//-------------------------------------------------------------------------------------------------		
	OI_cb_inf	*oi_cb_inf(XrmQuark) ;								// create callback object

#endif /* OI_cb_inf_H */
