[comp.windows.x] Basic questions on X Toolkit Intrinsics

josh@mit-vax.LCS.MIT.EDU (Joshua Marantz) (11/21/88)

[Summary:  I would like to call XtMainLoop recursively.]

What are the best ways for a Toolkit client to query the user and wait
for a response?  I understand that this goes against the spirit of the
toolkit, which is to have the program respond to the user rather than
vice versa, but there are situations in which it is necessary:

For example, an exceptional condition is discovered while processing a
user request, such as "disk space full" or "out of memory" or "do you
really want to delete all your files?".

In most cases, it is possible to pop up widgets with callbacks to handle any
of the possible responses, using the user-data-field to pass in some sort
of context to continue processing in the appropriate manner.

However, it is sometimes very difficult (in C) to encapsulate the entire
execution context in a single data structure and restore it in the callback.
It makes it difficult to use stack variables.

In these cases, I would like to be able to pop up a widget and go into a
recursive invocation of XtMainLoop (), which would return when the pop-up
widget is unmapped, or when some routine like XtPopLevel is called.

The only solution I can think of is to write my own main loop:

int recursion_depth = 0;
main_loop() {
    XEvent e;
    recursion_depth++;
    while (recursion_depth > 0) {
	XtNextEvent (&e);
	XtDispatchEvent (&e);
    } /* while */
} /* main_loop */

main_loop can be called recursively, provided XtDispatchEvent can.  Is this
legal?  If it is, an application would "exit" by decrementing recursion_depth,
rather than calling exit().  Is this the best way to prompt-and-block?  Is
there a danger of XtDispatchEvent finding a different widget set present
after it calls the callbacks?  Can this be handled by giving my main_loop
some notion of a sub-tree of widgets that it can process?

Joshua Marantz
Viewlogic Systems, Inc.

kit@athena.mit.edu (Chris D. Peterson) (11/22/88)

[ Question: How can I lock out events in the rest of my applicaion 
  while processing an error condition? ]

Look at the section of the toolkit manual that deals with Popup menus.
I think what you are looking for is provided by:

	XtPopup( widget, XtGrabExclusive );

Ref: X11R3 Toolkit Intrinsic Docs pp 51 - 56.

		
						Chris D. Peterson     
						Project Athena     
						Systems Development

Net:	kit@athena.mit.edu		
Phone: (617) 253 - 1326			
USMail: MIT - Room E40-342C		
	77 Massachusetts Ave.		
	Cambridge, MA 02139		

josh@mit-vax.LCS.MIT.EDU (Joshua Marantz) (11/23/88)

I asked how I could write a routine that would pop up a widget and *block*
until the user closed the widget.

kit@athena.mit.edu (Chris D. Peterson) answered a different question:
[	How can I lock out events in the rest of my applicaion 
  while processing an error condition? ]

He suggested using XtPopup (widget, XtGrabExclusive), and referred me	
to the R3 toolkit docs.  Unfortunately, I don't have the R3 documentation
yet, but my intuition, the R2 documentation, and the R2 source code all seem
to indicate that that routine will not block.  It will just perform
the appropriate grabs to ensure that none of my other widgets' callbacks
get called.

What I want is to write a routine that does not return until a widget
has been closed.  Is that what XtPopup does?

-Joshua Marantz
Viewlogic Systems, Inc.

kit@athena.mit.edu (Chris D. Peterson) (11/23/88)

> What I want is to write a routine that does not return until a widget
> has been closed.  Is that what XtPopup does?

This is not simple, perhaps the following method will serve your
purposes.  ( I realize it seems like I am telling you how to get
around the problem, rather then how to solve it).

Create two routines rather than one, Setup() and Shutdown().

Setup()	This routine pops up your XtGrabExclusive window that 
	has Shutdown() as the proceedure that is called when the user
	acknowledges your message window.  It then exits back 
	to XtMainLoop().

Since you have GrabExclusive set the only routine that can be called is
Shutdown(), so in essence you are blocking until the user acknowledges
your message.

Shutdown()	Pops down the window, allowing the program to continue.

I think this method is cleaner than trying to have a event handler in the 
middle of your code.  As long as you comment it well the program flow
should not be any harder to follow than the other toolkit code :-)

						Chris D. Peterson     
						Project Athena     
						Systems Development

Net:	kit@athena.mit.edu		
Phone: (617) 253 - 1326			
USMail: MIT - Room E40-342C		
	77 Massachusetts Ave.		
	Cambridge, MA 02139		

asente@decwrl.dec.com (Paul Asente) (11/23/88)

In article <5119@mit-vax.LCS.MIT.EDU> josh@mit-vax.LCS.MIT.EDU (Joshua Marantz) writes:
>[Summary:  I would like to call XtMainLoop recursively.]

XtMainLoop is nothing but an infinite loop calling XtNextEvent and
XtDispatchEvent.  You can call these yourself if you want to.

XtDispatchEvent, in R3, is fully reentrant.  You can call it from
anywhere.  In R2, it's not.

	-paul asente
	    asente@decwrl.dec.com	decwrl!asente