Newsgroups: comp.windows.x.motif,comp.os.vms,comp.windows.x
Subject: Re: event flags in X/Motif
From: tp@mccall.com (Terry Poot)
Date: Fri, 22 Jan 1993 09:10:01 CST
Reply-To: tp@mccall.com (Terry Poot)
Organization: The McCall Pattern Co., Manhattan, KS, USA
Nntp-Posting-User: tp


In article <1993Jan22.000239.1435@mprgate.mpr.ca>, vli@mpr.ca (Vincent Li)
writes:
>   I'm running on VMS 5.5-1, Motif 1.0 (I think).

Assuming you are correct...

>   Got 3 questions I can't find in the FAQ's
>
>1) Could my X/Motif application exe generated in this environment be able to
>   run under VMS5.5-1 with DECwindows with XUI? If not, what should I look
>   out for? I've seen some discussions concerning DECwindows & Motif already,
>   but couldn't figure out a clear yes/no on this issue.

A clear no. Your Motif application will be linked against shareable images that
do not exist unless the system has Motif. You can go the other way, however. XUI
applications will run on Motif. DEC was careful to provide look-alike shareable
images for XUI.

>2) A real easy one, how do I ghost out a button (pushbutton widget/gadget) to
>   prevent unprivileged user from selecting an option?

XtSetSensitive. Look it up.

>3) Can I have my Motif application be notified when a VMS event flag is set?
>   (ie. one you get with sys$getef.) I've seen codes to work with VMS
>mailboxes
>   before, but I would like, and have, all those $QIO code hidden well away.
>   All my application does is make a call to connect and pass an event flag
>   as the parameter. When something is in the mailbox, for example, the event
>   flag get set. Currently, I simply wait for the event flags in the main
>line.
>   (For some uses, I have an AST set the event flag which I wait for in the
>   mainline.) Is there a way I can tell the X server the event flag set is an
>   X event and add a callback of some kine to process it, or am I stuck with
>   the processing in AST (which I can do now)?

Four things I can think of: 

1) Use XtAppAddInput. This is complicated. Look at the examples in the manual
(don't remember _which_ manual) VERY carefully. I've done this. It works. It
isn't simple, and it isn't portable (the concept is, but not the
implementation), but then, neither are event flags.

2) Instead of calling XtAppMainLoop, you can write your application's main loop
something like:

   for(;;){
      if(XtAppPending(app_context))XtAppProcessEvent(app_context, XtIMAll);
      <code here to check your event flag and handle it>
      }

This has the disadvantage that it implements a CPU busy loop. You can't wait on
either type of event without potentially causing the other type to stack up
waiting to be serviced. This loop never waits.

3) In your AST routine, call XSendEvent, or queue a timeout event with a time of
0, or otherwise tickle the Xt event loop into dispatching your event for you.
This is not guaranteed to work, because Xt and Motif aren't reentrant. If the
AST hits at the wrong time, you could corrupt things. One way to solve this is
to do all your X processing at AST level. Bob Gezelter has mentioned that he
does this. I haven't done it, so I won't speculate about how it is accomplished.
(Pretty easy, if I recall). If one AST is running, another will be queued. If X
runs at AST level, it can't be interrupted by an AST, and the reentrancy problem
is solved.

4) If it is acceptable in your application for there to be a slight delay
servicing the event signaled by the event flag, you can use XtAppAddTimer to add
a timer event, which can then check to see if the event flag has been set.

Option 1 is "best", but a pain to do well in any kind of open-ended manner. You
need one event flag for each event stream (i.e. each mailbox or other class of
event). You have to hard code the value of the event flag, so you are
susceptible to conflicts with other software (you can't use lib$get_ef, because
it returns event flags in a range unacceptable to XtAppAddInput(). If you need
an example besides the one in the book, get a copy of the VMS port of Ghostview,
which does precisely what you are asking about (connecting mailbox I/O to the Xt
event dispatcher) using XtAppAddInput. It uses one event flag just for
signalling Xt and then the callback has to figure out which event triggered.

The one in the manual is an extremely general example that will work for almost
every conceivable use (kudos to whoever at DEC wrote that code!), but it has
some overhead, so I didn't use it directly (I did use it to learn the technique,
of course).

Option 4 is easy, if it's acceptable to your application. Option 2 stinks, it
keeps your machine nailed at 100% cpu. If you put a time delay in it, your
application gets real sluggish when there are events. (If you must do that, put
the XtAppProcessEvent in a while(XtAppPending(app_context)) loop so you do _all_
the pending X events, then yours, and then wait.

Option 3 is dangerous, unless you use Bob Gezelter's trick, or some other way of
synchronizing. I won't tell you it won't work, it might most of the time, but
nobody will guarantee it unless it is synchronized. (As someone else recently
quiped, if you have any questions call or write to Bob Gezelter :-) Maybe he'll
follow up here and describe how to make all X event handling run at AST level).
If properly syncronized, this may be the simplest solution to your problem.

Bet you didn't think that question would be such a can of worms, eh?
--
Terry Poot <tp@mccall.com>                   The McCall Pattern Company
(uucp: ...!rutgers!depot!mccall!tp)          615 McCall Road
(800)255-2762, in KS (913)776-4041           Manhattan, KS 66502, USA
Newsgroups: comp.windows.x.motif