[comp.windows.open-look] XView, C++, and interposition problem

warsaw@nlm.nih.gov (Barry A. Warsaw) (03/23/91)

Hello,

I have been using C++ and XView fairly successfully for a few months
now, however, I've just recently encountered a problem with using
interposition.  For example, I'm trying to interpose a destroy func on
a frame, but am having trouble getting all the arguments to match up
correctly.

BTW, I'm using GUIDE 1.1, Sun C++ 2.0, and XView 2.0 on a Sun SS1+,
SunOS 4.1.  I'm also using ORA7 as my XView reference.  Also X11R4.18
and TWM.

So I have a class "docwin" which is derived from a GUIDE-created
interface window class.  This class' frame is called "base" and in the
constructor of docwin, I want to interpose a destroy func on base.  So
I have a function such as:

static Notify_value docDes( Notify_client client, Destroy_status status )
{
	switch( status ) {
	case DESTROY_CHECKING:
	case DESTROY_PROCESS_DEATH:
	case DESTROY_SAVE_YOURSELF:
		return( NOTIFY_DONE );
	case DESTROY_CLEANUP:
	default:
		docwin* ip = (docwin*)GetKey( client, INSTANCE );
		delete ip;
		return( NOTIFY_DONE );
	}
};


And the docwin constructor looks like:

docwin::docwin( Xv_opaque owner, IrxDocument* doc )
{
	objects_initialize( owner );
	notify_interpose_destroy_func( base, docDes );
	...
};

However, when I compile it, CC gives me these errors:

"document.C", line 24: error: bad argument  2 type for notify_interpose_destroy_func(): Notify_value (*)(Notify_client , Destroy_status ) ( Notify_func  expected)

Looking at <xview/notify.h> I find

/*
 * A pointer to a function returning a Notify_value.
 */
typedef	Notify_value (*Notify_func)();


Now, I was able to kludge around this by putting a function called
docDes_c, and a small function which actually installed the interpose
destroy func into a C file (glue.c). docDes_c calls the C++ function
docDes described above, except that docDes is wrapped in an extern "C"
block.  Also in the extern "C" I declare the function do_interpose
which is in glue.c and actually calls notify_interpose_destroy_func.
This compiles and works, but seems very ugly to me.  Does anyone have
a better way of doing interposition in a C++ program?  Have I missed
something obvious or are the XView headers in need of repair?

Also, in a related matter, it seems that the destroy func does not get
called on a window delete (f.delete) or window destroy (f.destroy),
but does get called on a save-yourself (f.saveyourself).  The reason I
want to interpose the destroy func in the first place is to catch
destruction requests by the user when s/he doesn't hit my Dismiss
button, but instead uses the window manager to destroy the window.

Any suggestions and help will be greatly appreciated.  Thanks.

-Barry

NAME: Barry A. Warsaw                 USMAIL: National Library of Medicine
TELE: (301) 496-1936                          Lister Hill National Center for
INET: warsaw@nlm.nih.gov                          Biomedical Communications
UUCP: uunet!nlm.nih.gov!warsaw                Information Technology Branch
                                              8600 Rockville Pike
                                              Bldg. 38A, Rm. 7s722
                                              Bethesda, Md.  20894

warsaw@nlm.nih.gov (Barry A. Warsaw) (03/27/91)

The very simple workaround is to cast your destroy function to type
Notify_func, as in:

static
Notify_value destroyFunc( Notify_client client, Destroy_status status )
{
	...
};


...
Frame frame = xv_create( NULL, FRAME, ..., NULL );
notify_interpose_destroy_func( frame, (Notify_func)destroyFunc );

Makes cfront happy, and since the arguments are still put on the
stack, they get passed correctly to destroyFunc.

Thanks to Sal Cataudella and Daniel Gieskens for their responses.

-Barry

NAME:  Barry A. Warsaw         INET: warsaw@nlm.nih.gov
TELE:  (301) 496-1936          UUCP: uunet!nlm.nih.gov!warsaw