[comp.soft-sys.andrew] bug in proctable?

dgross@rchland.iinus1.ibm.com (Dave Gross) (01/05/91)

There seems to be a bug in proctable.  I am trying to add a DeleteWindow
option to my application's menu list.  I want to call the proctableentry
for "frame-delete-window".  The following (simplified)code is from my
InitializeClass:

First I tried:
    struct menulist *myview_menulist = menulist_New();
    struct keymap *myview_keymap = keymap_New();
    struct proctable_Entry *proc;

    proc = proctable_Lookup( "frame-delete-window" ); /* find
    proctable entry */
    if ( proc != NULL )
    {
        keymap_BindToKey( myview_keymap, ATK_CTRL_X ATK_CTRL_D, proc, 0 );
        menulist_AddToML( myview_menulist, ",Delete Window~12",
    proc, 0, MASK1 );
    }

The menu option came up, but selecting it did nothing.  Then I tried
making myown proctable entry which would be passed the frame.  Note
theclass_Load("frame").

    proc = proctable_DefineProc("myview-delete-window",
        deleteWindow, class_Load("frame"), NULL,"delete the current
        window");
    if ( proc != NULL )
    {
        keymap_BindToKey( myview_keymap, ATK_CTRL_X ATK_CTRL_D, proc, 0 );
        menulist_AddToML( myview_menulist, ",Delete Window~12",
    proc, 0, MASK1 );
    }

Again, the menu option came up, but selecting it did nothing.  In fact,
theroutine deleteWindow was not even called!   The prototype looked like:

    static void deleteWindow( struct frame *fr,long ignore );

I also tried inserting a call to proctable_ForceLoaded(proc) in both
ofthe above examples.  No change...

So, I tried passing my own classinfo to the function.  Note
the&myview_classinfo.

    proc = proctable_DefineProc("myview-delete-window",
        deleteWindow, &myview_classinfo, NULL, "deletethe current
        window");
    if ( proc != NULL )
    {
        keymap_BindToKey( myview_keymap, ATK_CTRL_X ATK_CTRL_D, proc, 0 );
        menulist_AddToML( myview_menulist, ",Delete Window~12",
    proc, 0, MASK1 );
    }

with the function prototype as:

    static void deleteWindow( struct myview *self, longignore );

This worked.  My function was called when selected from the menu.  The
problemis, there still is no way for me to call "frame-delete-window". 
Itried "faking" a delete window by destroying the IM, but that just
caused coredumps.

Is this a bug in proctable or is there something else I should be doing.
Note: I don't want to add this to my whole applicationvia an initfile
addmenu.

Any advice would be greatly appreciated.

Thanks,
-- Dave

dgross@rchland.iinus1.ibm.com (Dave Gross) (01/05/91)

Excerpts from mail: 4-Jan-91 Re: bug in proctable?
BillJanssen@RCHGATE.rch (179+0)

> In general, if you are going to call frame-delete-windowthrough the
> proctable mechanism, you had better call it with an instance offrame. 
> Was myview a subclass of frame?

> Bill

No, it's a subclass of view.  I see the problem.  Unfortunately, there's
noway to get a handle on the current frame unless I keep track of it in
aninstance variable.  Even then, how do I pass it to the proctable entry?

I seems that proctable wasn't designed to call other objects in the
currentview tree, just the current object and any inherited class procs.
 Is thatright?

-- Dave

gk5g+@ANDREW.CMU.EDU (Gary Keim) (01/05/91)

Excerpts from misc: 4-Jan-91 bug in proctable? Dave Gross@rchland.iinus
(2311+0)

> So, I tried passing my own classinfo to the function.  Note the
> &myview_classinfo.

	[....]

> This worked.  My function was called when selected from the menu.  The
> problem is, there still is no way for me to call "frame-delete-window". 

A proctableEntry keeps the type of the object that it is associated
with.  That object-type must match the type of object that is associated
with the menulist/keymap that causes it to be called.  So, your third
attempt is correct.  The first two attempts fail because of the
object-type mismatch.

Now, inside of your deleteWindow() call-back you need to get a handle
for the frame you want to destroy. 

void deleteWindow( self, ignore )
struct myview *self;
long ignore;
{
	struct im *im = myview_GetIM(self);
	struct frame *myframe = NULL;

	if(im) 
		myframe = frame_Enumerate(getMyFrame,(long)im);
	if(myframe) {
		frame_SetView(myframe,NULL);
		im_SetView(im,NULL);
		frame_Destroy(myframe);
		im_Destroy(im);
	}
}

boolean getMyFrame( frame, im )
struct frame *frame;
long im;
{
	if(frame_GetIM(frame) == ((struct im *) im))
		return(TRUE);
	else return(FALSE);
}

I don't know if there is an official way to call the function associated
with a given proctableEntry.  Anyway, that should do it.  

Gary Keim
ATK Group

tpn+@ANDREW.CMU.EDU (Tom Neuendorffer) (01/05/91)

Excerpts from mail: 4-Jan-91 Re: bug in proctable? Dave
Gross@rchland.iinus (654+0)


> I seems that proctable wasn't designed to call other objects in the
> current view tree, just the current object and any inherited class
> procs.  Is that right?

Right, proctable knows nothing about the view tree. 
Gary's post demonstrates one way dealing with this problem. However
Excerpts from mail: 4-Jan-91 Re: bug in proctable? Gary Keim (1345+0)

> I don't know if there is an official way to call the function associated
> with a given proctableEntry.  Anyway, that should do it.  

Gary's deleteWindow procedure would be better written as follows. This
takes advantage of the fact that frame's delete window procedure checks
if the current window is the last one. It also will not become obsolete
if we change what delete-window does is some future patch. This
illustrates the 'proper' way to call a proctable entry.

boolean getMyFrame( frame, im )
struct frame *frame;
long im;
{
    if(frame_GetIM(frame) == ((struct im *) im))
	return(TRUE);
    else return(FALSE);
}

void deleteWindow( self, ignore )
struct myview *self;
long ignore;
{
    struct im *im = myview_GetIM(self);
    struct frame *myframe = NULL;
    struct proctable_Entry *pr;
    int (*proc)();

    if(im &&
	((myframe = frame_Enumerate(getMyFrame,(long)im)) != NULL) &&
	(pr = proctable_Lookup("frame-delete-window")) != NULL
	&& proctable_Defined(pr)) {
	proc = proctable_GetFunction(pr) ;
	(*proc)(myframe,0);
    }
}

	Tom

dgross@rchland.iinus1.ibm.com (Dave Gross) (01/05/91)

Thanks for your help.  It seems to me that all this could be solved if
im_Destroy cleaned things up properly.  That way my application wouldn't
have to assume it's under a frame.

-- Dave