[comp.windows.x] event-driven X11

egc@pie1.mach.cs.cmu.edu (eddie caplan) (06/21/89)

i've received several pieces of mail flaming me about my comment:

    >if you are suggesting that X11 can't properly handle [event-driven]
    >programs then its time for X11 to pack its bags and let a real windowing
    >system become the standard.

i haven't been able to respond to all (because of mailer problems) and to hold
back the tide here is my general response:

Colas Nahaboo suggested that the X11 protocol *MANDATES* X11 programs to be
event driven:

        >(Jon Mauney):
        > there are many reasons to want to write code that goes for quite a
        > while before looking at events, and during program development this
        > is especially true.

    >(Colas NAHABOO):
    >No. All well-written (i.e working) programs on X MUST be event driven.

this suggests that an X11 program with a high processing:checking_XEvent
ratio is not a well-written program.  if true, then X11 has missed the boat.
-- 

egc@pie1.mach.cs.cmu.edu (eddie caplan) (06/23/89)

well the mail still hasn't slowed down...

i see it this way: X is just glorified I/O.  just because i want to write a
program that does I/O doesn't mean that i want it to be I/O *driven*.
likewise, if i want to write a program that does some X doesn't mean that i
want it to be XEvent *driven*.

using XCheckIfEvent(), i can have my program be driven by some other factor and
still periodically look for Exposes, etc.  but then i can only pick up XEvents
when my other factor triggers.  if the X protocol would support a scheme where
i could get an interrupt when one of my selected XEvents occurs, then this
problem would be solved.

with XToolkit i am even worse off.  i must call a never-returning XtMainLoop()
which prevents me from using the XCheckIfEvent() solution.  so if i want to be
driven by some other factor AND use XToolkit then my other factor must generate
the interrupts.  but suppose that that other factor is like X and doesn't offer
any method to generate interrupts?  this is exactly the situation for my
project.

so.... please stop telling me that "all X programs MUST/SHOULD be event
*driven*".

-- 

jim@EXPO.LCS.MIT.EDU (Jim Fulton) (06/24/89)

>                                 if the X protocol would support a scheme where
> i could get an interrupt when one of my selected XEvents occurs, then this
> problem would be solved.

The X Protocol has nothing to do with this.  It depends on your operating
system and the transport being used.  Under many UNIX systems you can request
that SIGIO be delivered on ConnectionNumber(dpy). 

boreas@bucsb.UUCP (Michael A. Justice) (06/25/89)

In article <5303@pt.cs.cmu.edu> egc@pie1.mach.cs.cmu.edu (eddie caplan) writes:
>using XCheckIfEvent() i can have my program be driven by some other factor and
>still periodically look for Exposes, etc.  but then i can only pick up XEvents
>when my other factor triggers.  if the X protocol would support a scheme where
>i could get an interrupt when one of my selected XEvents occurs, then this
>problem would be solved.

Assuming you're running UNIX, why not fork your process, and let one of the
two processes do the XNextEvent-loop while the other does your other stuff?
You could then have the XNextEvent-loop's process generate interrupts to tell
the "main" process about any events it needs to hear about.  Shared memory or
pipes or some such scheme for the processes to keep each other informed. . . .

Hmmm, "pie1.mach.cs.cmu.edu", the Mach OS has these capabilities too, no??

			-- Michael.
-- 
BITNet: cscj0ac@buacca \  Michael Andrew Justice @ BU Graduate School (CS)
ARPA: boreas@bucsb.bu.edu  \     "My sophistication surprises you, Zorba?"
CSNET: boreas%bucsb@bu-cs      \  "Your existence surprises me, Bald Ape."
UUCP:...!husc6!bu-cs!bucsb!boreas  \ _The_Architect_of_Sleep_, S.R. Boyett

egc@pie1.mach.cs.cmu.edu (eddie caplan) (06/26/89)

In article <2701@bucsb.UUCP> boreas@bucsb.bu.edu (Michael A. Justice) writes:
    >Assuming you're running UNIX, why not fork your process, and let one of
    >the two processes do the XNextEvent-loop while the other does your other
    >stuff?  You could then have the XNextEvent-loop's process generate
    >interrupts to tell the "main" process about any events it needs to hear
    >about.  Shared memory or pipes or some such scheme for the processes to
    >keep each other informed. . . .

this is precisely what i do now.  but, i would have preferred to have had this
functionality inside the X protocol.

by the way, Jim Fulton's suggestion of setting a SIGIO on ConnectionNumber(dpy)
is not a bad idea.  i might switch to it.
-- 

eddie.caplan@H.GP.CS.CMU.EDU (06/26/89)

In article <2701@bucsb.UUCP> boreas@bucsb.bu.edu (Michael A. Justice) writes:
    >Assuming you're running UNIX, why not fork your process, and let one of
    >the two processes do the XNextEvent-loop while the other does your other
    >stuff?  You could then have the XNextEvent-loop's process generate
    >interrupts to tell the "main" process about any events it needs to hear
    >about.  Shared memory or pipes or some such scheme for the processes to
    >keep each other informed. . . .

this is precisely what i do now.  but, i would have preferred to have had this
functionality inside the X protocol.

by the way, Jim Fulton's suggestion of setting a SIGIO on ConnectionNumber(dpy)
is not a bad idea.  i might switch to it.

Richard.Draves@CS.CMU.EDU (06/27/89)

> Excerpts from ext.in.xpert: 26-Jun-89 Re: event-driven X11 eddie
> caplan@pt.cs.cmu.e (740)

> by the way, Jim Fulton's suggestion of setting a SIGIO on
> ConnectionNumber(dpy)
> is not a bad idea.  i might switch to it.


This can be made to work (GNU Emacs does it), but it takes care to get
the locking right if you do X operations in your signal handler.  It's
especially difficult if you care about performance (something the Emacs
implementation falls down on).

Rich

swick@ATHENA.MIT.EDU (Ralph R. Swick) (06/29/89)

> Date: 23 Jun 89 15:56:22 GMT
> From: pie1.mach.cs.cmu.edu!egc@pt.cs.cmu.edu  (eddie caplan)

> with XToolkit i am even worse off.  i must call a never-returning XtMainLoop()
> which prevents me from using the XCheckIfEvent() solution.

No, there's no requirement that every application call XtMainLoop;
it's merely there as a convenience for those applications which
choose to be event-driven.  There's nothing at all preventing you
from learning in some way that there are X events in the queue,
fetching one of those events, and then giving it to Xt to process.
If your application also uses Xt timers or alternate inputs, then
you'll have to be careful to call XtAppProcessEvent occasionally to
get them processed, but it doesn't seem likely you'll be using
event-driven timers & input callbacks if you're writing an application
in some other style.

What I suspect you really need is an entire operating (system)
environment that gives real semantics for asynchronous i/o.
X already exists (happily) for such worlds. :-)

janssen@holmes (Bill Janssen) (07/01/89)

SIGIO's are also hard to catch (impossible?) if your process is not
the process group leader.  There seems to be a bug in SunOS that
makes setting the asynch flag on a socket a no-op for non-process-group
leaders.

Bill
--
Bill Janssen        janssen@xerox.com      (415) 494-4763
Xerox Palo Alto Research Center
3333 Coyote Hill Road, Palo Alto, California   94304

hvr%kimba@Sun.COM (Heather Rose) (07/08/89)

In article <5303@pt.cs.cmu.edu> you write:
>
>with XToolkit i am even worse off.  i must call a never-returning XtMainLoop()
>which prevents me from using the XCheckIfEvent() solution.  so if i want to be
>driven by some other factor AND use XToolkit then my other factor must generate
>the interrupts.  but suppose that that other factor is like X and doesn't offer
>any method to generate interrupts?  this is exactly the situation for my
>project.
>
>so.... please stop telling me that "all X programs MUST/SHOULD be event
>*driven*".

In Sunview, there are three ways to get events from the window system.  1)
implicit dispatching, 2) explicit dispatching, or 3) roll your own.  

The implicit dispatching mechanism allows one to dispatch window events while
getting input via read from some other source such as stdin, a socket, or
a pipe.  This type of input system works well when the program wants to be
getting input from a constant stream and periodically be interrupted with
window system events.

The explicit dispatching mechanism is the most common.  This can be used with
varying degrees of control.  window_main_loop puts the event distribution into
an infinite loop and calls your registered functions when an event happens.
notify_dispatch will dispatch one event each time it is called which allows the
programmer to intersperse notification with code.  The pair notify_start and
notify_stop allow one to affect the window_main_loop in a start and stop manner.

For example, using explicit dispatching, you get the equivalent of SIGIO on some
file descriptor by using the function call notify_set_input_func.  And using
implicit dispatching with either select/read or notify_set_input_func.  The
call to notify_set_input_func tells the notifier that when it gets a SIGIO on
this file descriptor to call your function which then does a read.  If you have
a lot to read, you can just read N bytes and your function will be called again
and again while you still have something to read.  When your reader receives
EOF, you unregister the reader function.

If one wants to by-pass the entire notification scheme, there are functions to
read the events directly; however, beware...there be dragons.

In general, the Sunview notifier is very full-featured.  In addition to
window system events, you can also receive signals, input on a file descriptor,
timers, pass events between clients in the same process, interpose on a
notifier client to change its behavior, receive notification on a process's
death.  So, whatever interrupt the system generates, there is a way to
register a call back function for that interrupt.

The Sunview notifier does apply to X11 applications since this notification
system will be present in the XView toolkit.

A couple of common gotchas with a notification based window system:  1) when
you are in a call back function, all event distribution is suspended until
you exit.  This could be worked around.  You can affect your own concurancy 
by calling yourself N times while saving some state,  (for example, only reading
N bytes as above), or use two processes--one to service the user and the second
to do the main body of work for the application.  2) UNIX and window systems 
are not "real time", this also applies to Sunview.

The Sunview notification system is not perfect; however, it has been worked on
and tested for several years which generally means things improve and become
more stable.  For more details, see chapter 17 of the Sunview Programmer's
Guide (release 4.0).

I hope this broadens your possibilities,

Heather