[comp.windows.x] Processing toolkit events

tom@capella.ucsb.edu (Tom Weinstein) (02/15/90)

I'm trying to process events using the X toolkit in a way that will not
block when the queue is empty.  This is what I'm doing:

  XEvent event;

  while (XtAppPending(context)) {
    XtAppNextEvent(context, &event);
    XtDispatchEvent(&event);
  }

However, this seems to block when there are no events in the queue.  Am
I doing something wrong, or is this a bug?

--
It does not do to leave a dragon | Tom Weinstein  ...ucbvax!hub!ucsbuxa!6600tom
out of your calculations, if you | 6600tom@ucsbuxa.bitnet  tom@bears.ucsb.edu
live near him.  --J.R.R. Tolkien | 6600tom@ucsbuxa.ucsb.edu tomw@cornu.ucsb.edu

asente@decwrl.dec.com (Paul Asente) (02/15/90)

In article <3947@hub.UUCP> tom@bears.ucsb.edu writes:
>I'm trying to process events using the X toolkit in a way that will not
>block when the queue is empty.  This is what I'm doing:
>
>  XEvent event;
>
>  while (XtAppPending(context)) {
>    XtAppNextEvent(context, &event);
>    XtDispatchEvent(&event);
>  }
>
>However, this seems to block when there are no events in the queue.  Am
>I doing something wrong, or is this a bug?

Are you using timers or alternate input sources?  XtAppPending returns
non-zero when these exist but XtAppNextEvent still blocks if there are no
X events.  If this is the case, you might try

    while (XtAppPending(context) & XtIMXEvent) {
	...

The Intrinsics will add timers themselves if you or the widgets use the
selection mechanism.  The widgets may be adding timers themselves.

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

tom@capella.ucsb.edu (Tom Weinstein) (02/15/90)

In article <2759@bacchus.dec.com> asente@decwrl.dec.com (Paul Asente) writes:
In article <3947@hub.UUCP> tom@bears.ucsb.edu writes:
>>   while (XtAppPending(context)) {
>>     XtAppNextEvent(context, &event);
>>     XtDispatchEvent(&event);
>>   }

>> However, this seems to block when there are no events in the queue.  Am
>> I doing something wrong, or is this a bug?

> Are you using timers or alternate input sources?  XtAppPending returns
> non-zero when these exist but XtAppNextEvent still blocks if there are no
> X events.  If this is the case, you might try

Yes, I am using timers.

>     while (XtAppPending(context) & XtIMXEvent) {
>         ...

Okay, but if I do this, doesn't that mean that none of my timer events
will get processed?

>    -paul asente
>        asente@decwrl.dec.com	decwrl!asente
--
It does not do to leave a dragon | Tom Weinstein  ...ucbvax!hub!ucsbuxa!6600tom
out of your calculations, if you | 6600tom@ucsbuxa.bitnet  tom@bears.ucsb.edu
live near him.  --J.R.R. Tolkien | 6600tom@ucsbuxa.ucsb.edu tomw@cornu.ucsb.edu

tom@capella.ucsb.edu (Tom Weinstein) (02/15/90)

In article <2759@bacchus.dec.com> asente@decwrl.dec.com (Paul Asente) writes:
In article <3947@hub.UUCP> tom@bears.ucsb.edu writes:
>>  XEvent event;
>>
>>  while (XtAppPending(context)) {
>>    XtAppNextEvent(context, &event);
>>    XtDispatchEvent(&event);
>>  }

>>However, this seems to block when there are no events in the queue.  Am
>>I doing something wrong, or is this a bug?

>Are you using timers or alternate input sources?  XtAppPending returns
>non-zero when these exist but XtAppNextEvent still blocks if there are no
>X events.  If this is the case, you might try

>    while (XtAppPending(context) & XtIMXEvent) {
>        ...

I just figured out the right way to do this:

  XEvent event;
  XtInputMask mask;

  XFlush(XtDisplay(xchippe));

  while (mask = XtAppPending(context))
    XtAppProcessEvent(context, mask);

This way it doesn't block, and it processes everything including timers.
Thanks for the help!

>	   -paul asente
>	       asente@decwrl.dec.com	decwrl!asente
--
It does not do to leave a dragon | Tom Weinstein  ...ucbvax!hub!ucsbuxa!6600tom
out of your calculations, if you | 6600tom@ucsbuxa.bitnet  tom@bears.ucsb.edu
live near him.  --J.R.R. Tolkien | 6600tom@ucsbuxa.ucsb.edu tomw@cornu.ucsb.edu

dpb@viking.UUCP (Don Bennett 433-3311, 408) (02/16/90)

>>>>   while (XtAppPending(context)) {
>>>>     XtAppNextEvent(context, &event);
>>>>     XtDispatchEvent(&event);
>>>>   }
>>
>>>> However, this seems to block when there are no events in the queue.  Am
>>>> I doing something wrong, or is this a bug?
>>
>>> Are you using timers or alternate input sources?  XtAppPending returns
>>> non-zero when these exist but XtAppNextEvent still blocks if there are no
>>> X events.  If this is the case, you might try
>>
>>Yes, I am using timers.
>>
>>>     while (XtAppPending(context) & XtIMXEvent) {
>>>         ...
>>
>>Okay, but if I do this, doesn't that mean that none of my timer events
>>will get processed?
>>
>I just figured out the right way to do this:
>
>  XEvent event;
>  XtInputMask mask;
>
>  XFlush(XtDisplay(xchippe));
>
>  while (mask = XtAppPending(context))
>    XtAppProcessEvent(context, mask);


Actually, I needed to solve a similar problem. 

We have a recursive version of the main loop that looks like

	void myMainLoop(loopTest)
	boolean (*looptest)();
	{
	    XEvent ev;

	    while ((*loopTest)()) {
		XtNextEvent(&ev);
		< do some funky stuff you don't want to know about >
		XtDispatchEvent(&ev);
	    }	 
	}
	
and we were getting screwed because a timer event was setting
the loop termination condition but XtNextEvent was still blocked
waiting for a 'real' event.

We couldn't use XtAppProcessEvent() because we needed to insert
our own code between the event read and the event dispatch.

The fix I used was to write a version of XtNextEvent that 
would either process a single timer/alternate-input event 
or get a real input event and  return a status telling the caller
which had occured.

	/* 
	 * myXtNextEvent - 
	 * 
	 *     Return after processing one timer/alternate-input
	 *     event or after reading a single input event.
	 *
	 *     Return true if an event was read, false otherwise.
	 */

	boolean myXtNextEvent(ev)
	XEvent *ev;
	{	
	    XtAppContext app;
	    XtInputMask mask;

	    app = (XtAppContext) _XtDefaultAppContext();

	    while (1) {
	        mask = XtAppPending(app);
	
	        if (mask & (XtIMTimer|XtIMAlternateInput)) {
	            XtAppProcessEvent(app, (XtIMTimer|XtIMAlternateInput));
	            return(FALSE);
	        }
	
	        if (mask & XtIMXEvent) {
		    /* It looks like this might process additional 
		     * alternate events if XtAppNextEvent() calls
		     * DoOtherSources(), but I don't particularly care;
		     */	
	            XtAppNextEvent(app, ev);
	            return(TRUE);
	        }

	        _XtwaitForSomething(FALSE, FALSE, FALSE, TRUE, NULL, app);
	    }
	}

	/*
	 * myMainLoop -
 	 *
	 *     recursive main loop.
	 */

	void myMainLoop(loopTest)
	boolean (*looptest)();
	{
	    XEvent ev;

	    while ((*loopTest)())
		if (myXtNextEvent(&ev)) {
		    < do some funky stuff you don't want to know about >
		    XtDispatchEvent(&ev);
		}
	}
 

   Don Bennett           (408)433-3311
   dpb@frame.com
   Frame Technology