[comp.windows.x] getting CONTROL C to interrupt X application

Francois.Bitz@SAM.CS.CMU.EDU (08/24/89)

I am trying to find a way to be able to 'stop' an X program
by typing CONTROL C such as can be done with any other
'C' program.  Actually I want to use the SIGINT that is generated
by such an action to 'jump' somewhere in my program. This is
sometimes necessary when  displaying (or computing) lots of stuff that 
might takea long time and the user wants to stop (abort) it .

The problem I have is that when I type CONTROL C in the windows created by
my application (which uses SelectInput with KeyPressedMask)  no 
SIGINT is generated (although when I read the bufffer I can see that
there is a CONTROL C in it). If I typed CONTROL C in the xterm shell
where I started my application, then I can get a SIGINT; but this is
not a good solution since the startup shell is sometimes masked by the
application (or could be on another machine).

Alternatively is there a 'simple' way to write a small X program
with a button which when clicked could 'send' a 'signal' to 
my application.

Are there any signals which can be generated by the X server; or
between X clients ?

I hope my message is not too confusing; It might be related to a
question somebody asked about running 'X' processes in parallel without
having to fork (this being op. sys. dependant). 


Thanks

pjs@basalt.dec.com (Philip Schneider) (08/25/89)

In article <8908231747.AA20273@ATHENA.MIT.EDU> Francois.Bitz@SAM.CS.CMU.EDU writes:
>I am trying to find a way to be able to 'stop' an X program
>by typing CONTROL C such as can be done with any other
>'C' program.  Actually I want to use the SIGINT that is generated
>by such an action to 'jump' somewhere in my program. This is
>sometimes necessary when  displaying (or computing) lots of stuff that 
>might takea long time and the user wants to stop (abort) it .
>


  I'm not sure if this is what you wanted, but how about :

if (XPending(dpy)) {
            XNextEvent(dpy, &event);

            if (event.type == KeyPress) {
                XLookupString(&event, &keyPressed, 1, NULL, NULL);
                if (keyPressed == '^C') {
                   exit(0);
                }
            }

  I guess that instead of calling "exit(0)", what you would want here is
the call to whatever routine you execute before you die.

Hope this helps.

- Philip Schneider


Philip J. Schneider			| pjs@decwrl.dec.com
DEC Advanced Technology Development	| decwrl!pjs
100 Hamilton Avenue			| (415)853-6538
Palo Alto, CA  94301			| (415)386-8232

guy@auspex.auspex.com (Guy Harris) (08/30/89)

>  I'm not sure if this is what you wanted,

If he genuinely wanted an asynchronous interrupt, it's probably not. 
The problem is that a polling strategy requires you to poll
periodically.  Such a strategy may be implementable in many
applications, and it may be implementable in his, though.

However, another problem is that any events delivered to the process
before the ^C, but not yet consumed, may be delivered to the program by
XNextEvent before the ^C event, which may also not be what he wanted. 
^C in UNIX (and, I suspect, other OSes) is not only delivered as an
asynchronous signal, but is delivered out-of-band.

marbru@auto-trol.UUCP (Martin Brunecky) (08/31/89)

In article <2395@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
>>  I'm not sure if this is what you wanted,
>
>If he genuinely wanted an asynchronous interrupt, it's probably not. 
>The problem is that a polling strategy requires you to poll
>periodically.  Such a strategy may be implementable in many
>applications, and it may be implementable in his, though.
>

YES, polling is the only answer in the X world. One way of doing it is
to do your own XtMainLoop, i.e. call XtDispatchNextEvent explicitly.
But before this, you can always look if there is anything in the
queue, and if yes, you can look for a key event with control C in it.
When you find one, do whatever is appropriate - kill yourself, discard
the entire X queue etc. 
Be carefull about what X calls you use to scan the queue - you probbably
don't want to flush your output everytime you look for a control C.
Also, you may SCAN the queue for control C even when you are NOT going
to dispatch any event. 


###############################################################################
Martin Brunecky, Auto-trol Technology Corporation,
12500 North Washington Street, Denver, CO-80241-2404
(303) 252-2499                                        ncar!ico!auto-trol!marbru
###############################################################################

rlk@THINK.COM (Robert L. Krawitz) (08/31/89)

   Date: 30 Aug 89 22:41:56 GMT
   From: mailrus!ncar!ico!auto-trol!marbru@ohio-state.arpa  (Martin Brunecky)

   In article <2395@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
   >>  I'm not sure if this is what you wanted,
   >
   >If he genuinely wanted an asynchronous interrupt, it's probably not. 
   >The problem is that a polling strategy requires you to poll
   >periodically.  Such a strategy may be implementable in many
   >applications, and it may be implementable in his, though.

   YES, polling is the only answer in the X world. One way of doing it is
   to do your own XtMainLoop, i.e. call XtDispatchNextEvent explicitly.
   But before this, you can always look if there is anything in the
   queue, and if yes, you can look for a key event with control C in it.
   When you find one, do whatever is appropriate - kill yourself, discard
   the entire X queue etc. 

This, fortunately, is not true.  Gnu Emacs under both X10 and X11 does
use signals (SIGIO, to be precise).  It needs to if the user is to be
able to interrupt the running process.  It's possible for emacs to get
into an infinite loop, or otherwise run continuously for a long time,
and it's essential that the user be able to deliver an interrupt.

Emacs does have a dispatch loop of sorts, but the dispatch loop is
logically based upon the user issuing a command and emacs coming back
after processing it (with some exceptions -- subprocesses can be running
that deliver output asynchronously).  Emacs is an X client when running
under X, but it is not tied to X in the same way that clients such as
xterm are; to emacs, X is just another flavor of I/O device.

Of course, emacs's solution isn't portable to all X client machines,
much less all Unices (I don't believe that SysV implements SIGIO or the
like, even now).  On the other hand, it needs certain capabilities, even
if X doesn't provide them.

ames >>>>>>>>>  |	Robert Krawitz <rlk@think.com>	245 First St.
bloom-beacon >  |think!rlk				Cambridge, MA  02142
harvard >>>>>>  .	Thinking Machines Corp.		(617)876-1111

janssen@holmes (Bill Janssen) (09/02/89)

In article <261@auto-trol.UUCP>, marbru@auto-trol (Martin Brunecky) writes:
>YES, polling is the only answer in the X world.

Not so.  Look at the X11 code in GNU Emacs.  It uses SIGIO to do
asynchronous processing of X events.  A control-C handler could be
implemented similarly.

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