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