[comp.windows.x] Interrupting an X program... how?

egr@contact.uucp (Gordan Palameta) (03/01/91)

Here's a relatively simple question, I hope.

A traditional program under Unix can be interrupted by hitting Control-C
(or whatever other character defined by stty).

How do you send a signal to an X program?

Specifically, a program which goes off and does lengthy
calculations, and doesn't check for X events until the calculations
are complete.

Recasting this (existing) program to check for X events during the
aforesaid lengthy computations is not really an option (among other
things, the computations are in Fortran).  :-( 

So how can I arrange for the window manager or whatever to send a signal
to a program running in an X window?

Thanks in advance...........

mouse@lightning.mcrcim.mcgill.EDU (03/02/91)

> A traditional program under Unix can be interrupted by hitting
> Control-C (or whatever other character defined by stty).

> How do you send a signal to an X program?

The same way you send a signal to any other program.  Use kill (the
command or the syscall) or type one of the signal-generating characters
on the process' control tty when it's in the foreground.

> Specifically, a program which goes off and does lengthy calculations,
> and doesn't check for X events until the calculations are complete.

> Recasting this (existing) program to check for X events during the
> aforesaid lengthy computations is not really an option (among other
> things, the computations are in Fortran).  :-(

> So how can I arrange for the window manager or whatever to send a
> signal to a program running in an X window?

This is more or less impossible.  The program may be on a different
machine; it may even be running under an OS that doesn't have the
notion of signals at all.

In your particular case, since you have source to the program, you may
be able to do something like attaching a property to your top-level
window giving your process ID and some sort of machine identifier, then
implementing something which checks for these and, if running on the
same machine, sends the desired signal.

With a bit of care (ok, with a good deal of care :-), you should be
able to get away with checking for X events inside a SIGALRM handler,
then arranging for SIGALRM to be delivered periodically while inside
the crunching loop.  (This assumes (a) that you aren't already using
SIGALRM for anything, or can overload it, and (b) that you go to some
trouble to make certain you don't trip over any of the landmines
lurking in the use of Xlib from both mainline and signal handlers.)

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

cjmchale@cs.tcd.ie (Ciaran McHale) (03/03/91)

In <1991Mar1.045842.21676@contact.uucp>
egr@contact.uucp (Gordan Palameta) writes:

>A traditional program under Unix can be interrupted by hitting Control-C
>(or whatever other character defined by stty).
>
>How do you send a signal to an X program?
>
>Specifically, a program which goes off and does lengthy
>calculations, and doesn't check for X events until the calculations
>are complete.
>
>Recasting this (existing) program to check for X events during the
>aforesaid lengthy computations is not really an option (among other
>things, the computations are in Fortran).  :-( 
>
>So how can I arrange for the window manager or whatever to send a signal
>to a program running in an X window?

Several approaches spring to mind.

1. Many window managers will popup a menu if you press a
mouse button in the root window. One of the choices on this
menu is likely to be labelled something like "Kill window."
Choose this (the cursor will probably change it's appearance
to show it has been selected) and then press the cursor in
the application you want to kill.

2. Split your application up into two processes; a
"fron-end" process which handles the X interface, and a
"back-end" process will does a lot of CPU intensive work.
These two processes can communicate with each other via
pipes/sockets/FIFO/whatever-IPC-mechanism-your-OS-supports.
All :-) that need be done then is to get the front-end
process to listen to both the X server and the back-end
process at the same time. If you want to take this approach
then email me and I'll send you a collection of emails
(about 25k long) which discuss how to do this in detail.



Ciaran.
-- 
Ciaran McHale		"Verbosity says it all"			      ____
Department of Computer Science, Trinity College, Dublin 2, Ireland.   \  /
Telephone: +353-1-772941 ext 1538	FAX: +353-1-772204	       \/
Telex: 93782 TCD EI			email: cjmchale@cs.tcd.ie

mikep@progress.COM (Mike Pacholec) (03/03/91)

egr@contact.uucp (Gordan Palameta) writes:

>A traditional program under Unix can be interrupted by hitting Control-C
>(or whatever other character defined by stty).
>
>How do you send a signal to an X program?
>
>Specifically, a program which goes off and does lengthy
>calculations, and doesn't check for X events until the calculations
>are complete.
>
>Recasting this (existing) program to check for X events during the
>aforesaid lengthy computations is not really an option (among other
>things, the computations are in Fortran).  :-( 
>
>So how can I arrange for the window manager or whatever to send a signal
>to a program running in an X window?

You are responsible for emulating the control-c functionality yourself.
Outside of polling, the options aren't pretty.

On BSD systems, you can arrange to have SIGIO sent to your program when
data is ready on the display connection.  The signal handler can then
query the event queue and check for control-c.  This way, you only check
for control-c when some event arrives.

It is also possible to have a partner process monitor your client's event
queue.  If the partner process sees a control-c, then it can SIGINT your
client.

I haven't seen any other suggestions.
 
--
-------------------------------------------------------------------------------
Mike Pacholec                                    UUCP: mit-eddie!progress!mikep
Progress Software Corp.                      Internet: mikep@progress.com
Bedford, MA 

cjmchale@cs.tcd.ie (Ciaran McHale) (03/03/91)

I forgot to say something...

I write:
>>[How do interrupt a X application which is doing CPU
>>intensive calculations]
>
>2. Split your application up into two processes; a
>"fron-end" process which handles the X interface, and a
>"back-end" process will does a lot of CPU intensive work.
>These two processes can communicate with each other via
>pipes/sockets/FIFO/whatever-IPC-mechanism-your-OS-supports.
>All :-) that need be done then is to get the front-end
>process to listen to both the X server and the back-end
>process at the same time. If you want to take this approach
>then email me and I'll send you a collection of emails
>(about 25k long) which discuss how to do this in detail.

Since the front end no longer does any of the CPU intensive
calculations it can quickly respond to the user pressing a
"quit" button and act appropriately.


Ciaran.
-- 
Ciaran McHale		"Verbosity says it all"			      ____
Department of Computer Science, Trinity College, Dublin 2, Ireland.   \  /
Telephone: +353-1-772941 ext 1538	FAX: +353-1-772204	       \/
Telex: 93782 TCD EI			email: cjmchale@cs.tcd.ie

dce@smsc.sony.com (David Elliott) (03/03/91)

In article <1991Mar2.183352.29822@progress.com> mikep@progress.COM (Mike Pacholec) writes:
>egr@contact.uucp (Gordan Palameta) writes:
>>Specifically, a program which goes off and does lengthy
>>calculations, and doesn't check for X events until the calculations
>>are complete.

>I haven't seen any other suggestions.

I mailed mine, but I know of two ways to handle this type of situation.

The first is to code the lengthy processing such that it can go for a
while and then suspend processing to allow for events.  Under Xt, a
WorkProc can be used for this.  With Xlib, you just call the routine
when there are no pending X events.

The second is to split the entire program into two Unix processes, one
handling the user interface and the other doing the calculations.  If
you have shared memory or if the interaction can be done simply with
pipes (i.e., not a lot of complex data needs to be shipped around),
this isn't bad at all.

Personally, I prefer the first method, but it can be tough to code and
require a lot of state data.  The second method has the advantage that
the meat of the task is separated completely from the interface, which
can be great if you need to provide multiple interfaces eventually.