[comp.windows.x] Awaiting _non_ X events, was Re : XtAddTimeOut

moghe@husc4.HARVARD.EDU (moghe m) (08/30/90)

In article <141292@sun.Eng.Sun.COM> argv@turnpike.Eng.Sun.COM (Dan Heller) writes:
>In article <9008231943.AA01202@crc.skl.dnd.ca> jgraham@CRC.SKL.DND.CA (Jay Graham) writes:
>>     We are developing an application on 386/ix and will need time
>>     interrupts in the 10s of milleseconds range, however when using
>>     XtAddTimeOut() with a 10ms ....
>>
>>     <stuff deleted>
>
>Don't try to develop something similar -- this is the best resolution
>you're going to get, all things considered.  XtAddTimeOut() is closely
>tied to the select() system call.  this is the ultimate system call that
>returns when either
>    1) there is data on the X connection to read
>    2) select() times out first......
>
>    <stuff deleted>
>dan
>----------------------------------------------------
>O'Reilly && Associates   argv@sun.com / argv@ora.com
>Opinions expressed reflect those of the author only.


In the bad-old-days-before-X one would use this select()
in the main loop to wait on Keys, Mouse, Timeout or
whatever other events on any file descriptors were of
interest. But now, if you have an X application which
also needs to handle events other than X events, how
does one do it? Lets say you want the X application to
await on a message on a socket in addition to handling
events from the X-server. Lets say that the message
on the socket updates the screen.

Now one could use an auxiliary process to collect the message
and XsendEvent() it to the X-applicaion via the X-server,
but that seems such a round-about way to go. Is there a
more direct way to await _NON_ X events in the X main loop?
If so, are there any traps?

Email comments accepted.

moghe@husc4

klee@wsl.dec.com (Ken Lee) (08/31/90)

In article <4039@husc6.harvard.edu>, moghe@husc4.HARVARD.EDU (moghe m) writes:
|> In the bad-old-days-before-X one would use this select()
|> in the main loop to wait on Keys, Mouse, Timeout or
|> whatever other events on any file descriptors were of
|> interest. But now, if you have an X application which
|> also needs to handle events other than X events, how
|> does one do it? Lets say you want the X application to
|> await on a message on a socket in addition to handling
|> events from the X-server.

Use XtAppAddInput to wait on UNIX-style file descriptors.

Ken Lee
DEC Western Software Laboratory, Palo Alto, Calif.
Internet: klee@wsl.dec.com
uucp: uunet!decwrl!klee

janzen@bambi.mpr.ca (Martin Janzen) (08/31/90)

In article <4039@husc6.harvard.edu>, moghe@husc4.HARVARD.EDU (moghe m) writes:
> [stuff about polling and XtAddTimeOut deleted...]
>
> In the bad-old-days-before-X one would use this select()
> in the main loop to wait on Keys, Mouse, Timeout or
> whatever other events on any file descriptors were of
> interest. But now, if you have an X application which
> also needs to handle events other than X events, how
> does one do it? Lets say you want the X application to
> await on a message on a socket in addition to handling
> events from the X-server. Lets say that the message
> on the socket updates the screen.
> 
> Now one could use an auxiliary process to collect the message
> and XsendEvent() it to the X-applicaion via the X-server,
> but that seems such a round-about way to go. Is there a
> more direct way to await _NON_ X events in the X main loop?
> If so, are there any traps?
> 
> Email comments accepted.
> 
> moghe@husc4

As Ken Lee (klee@wsl.dec.com) points out, you can use XtAppAddInput (or
just XtAddInput) to wait for input on sockets, files, pipes and so
forth.  For other kinds of input, such as signals, IPC messages, shared
memory, etc., you may have to do a bit more work.

For example, I just wrote a program that talks to an old server task
through an IPC queue (yeah, I know...).  You probably don't want to
duplicate the kind of inter-process communication I describe here, but
you might find the technique for handling input messages useful.

Anyway, the sequence of events is as follows:

  - My application starts up, creates an IPC queue, registers a SIGUSR2
    handler, and sends an IPC message to the server's queue to register
    my program's new IPC queue id and pid (this part's pretty ugly :-).
  - When the server has data for my program, the server enqueues an IPC
    message and sends a SIGUSR2 signal to my program.
  - My SIGUSR2 handler dequeues all IPC messages and buffers them, then
    registers a work procedure using XtAddWorkProc (see also O'Reilly
    Volume Four, Section 8.5).
  - The work procedure gets called as soon as there are no X events out-
    standing, and processes the next buffered message.
  - If there are more messages, the work procedure returns False so that
    it will get called again.  (It's better to process one message at a
    time, to allow X event processing to continue.)
  - If there are no more messages, the work procedure returns True, so
    that it is deregistered until the next SIGUSR2.

If your application is receiving *huge* numbers of X events continually,
the response time could be affected, but I've found that this works
really well.  Hope this gives you some ideas...

-------------------------------------------------------------------------------
Martin Janzen                  Voice:    (604) 293-5309
MPR Teltech Ltd.               FAX:      (604) 293-5787
8999 Nelson Way                Internet: janzen@mprgate.mpr.ca
Burnaby, B.C. CANADA  V5A 4B5            (134.87.131.13)

klee@wsl.dec.com (Ken Lee) (08/31/90)

In article <2324@kiwi.mpr.ca>, janzen@bambi.mpr.ca (Martin Janzen) writes: 
|>   - My application starts up, creates an IPC queue, registers a SIGUSR2
|>     handler, and sends an IPC message to the server's queue to register
|>     my program's new IPC queue id and pid (this part's pretty ugly :-).
|>   - When the server has data for my program, the server enqueues an IPC
|>     message and sends a SIGUSR2 signal to my program.

On many UNIX systems, signals are fairly inefficient.  An alternative
that is often useful is to open a pipe or socket connection between the
2 processes and send an empty packet across it whenever you have
something on the IPC queue.  The XToolkit allows you to register
callbacks on file descripters (as from pipes and sockets), which can
then handle the IPC queue.  This technique is commonly used in the UNIX
world, not just for X stuff.

Ken Lee
DEC Western Software Laboratory, Palo Alto, Calif.
Internet: klee@wsl.dec.com
uucp: uunet!decwrl!klee