[comp.windows.x] XtAppAddInput and pipes

eejames@cybaswan.UUCP (jw.powrie) (10/09/90)

Hello,

Are there any X-Gurus out there who can assist me with my problem?

I am writing an X-windows program (xgraph) which (amongst other things)
reads data from stdin and uses this data to update a graph.
The data is produced by another program, (data_feed)
and takes the form of one integer
per line e.g.
4
5
4
6
3
etc.

The two programs are executed as a pipe as follows:

prompt% data_feed | xgraph

Previously, I had written the xgraph program using Xlib.
The main loop was something like this:

while (1)
{
  /* poll for X events (say) 20 times */
  for (i=0; i<20; i++ )
    if ( XCheckMaskEvent(dpy,event_mask,%pe)
    {
      /* process X events */
    }

  /* read in the next line of data */
  scanf("%d",&time);
}

Because the Xevents anticipated were few and far between, the above
(rather crude) approach worked fine. However, I am now trying to improve
my program by using a widget based approach.

According to the "X Toolkit Intrinsics - C Language Interface",
I can register an (arbirary?) file as an input (event) source
using the XtAppAddInput() function.
I re-coded the xgraph program (to use widgets) and the program works fine
on its own (ie with stdin connected to the keyboard).
However, if I run a program as part of a UNIX pipe
(e.g. cat | program ), I get the following error message:
	X Toolkit Error: Select failed.

My questions are:
1) Why does the program work fine with the keyboard attached to stdin, but
   not with a pipe attched?
2) Is there a simple fix?
3) If not, is there another/better way in which I can turn piped input
into an X event source?

The relevant extracts of my code are included below:

/************************************************************************
main(argc,argv)
unsigned int argc;
char **argv;
{
  Widget toplevel;
  XtAppContext theAppContext;
  XtInputId input_id;


  toplevel = XtInitialize(argv[0], "Demo", NULL,0, &argc,argv);



  ................................................................
  /* open various widgets etc */
  ................................................................


  theAppContext = XtWidgetToApplicationContext(toplevel);
  input_id = XtAppAddInput(theAppContext,0,XtInputReadMask,input_fn,NULL);
  XtMainLoop();
}

void input_fn(w,client_data,call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
  int time;

  scanf("%d",&time);
  printf("time is %d\n",time);

  /* other processing etc */
}
****************************************************************************


Many thanks for any help.
James.



         			   - - - - - - - - - - - - - - - - - - - -
James Powrie, 			 | UUCP  : ...!ukc!pyr.swan.ac.uk!eejames |
Image Processing Laboratory,	 | JANET : eejames@pyr.swan.ac.uk     	  |
Electrical Engineering Dept.,    |       :                                |
University of Wales,             | voice : +44 792 205678 Ext 4698        |
Swansea, SA2 8PP, U.K.           | Fax	 : +44 792 295532                 |
                                 | Telex : 48358                          |
 			 	   - - - - - - - - - - - - - - - - - - - -

pete@iris49.UUCP (Pete Ware) (10/13/90)

eejames> My questions are:

eejames> 1) Why does the program work fine with the keyboard attached
eejames> to stdin, but not with a pipe attched?
The program providing input is probably exiting which closes the pipe.

eejames> 2) Is there a simple fix?
Yes, change your function, input_fn() to something like:

void input_fn(client_data, source, id)
caddr_t client_data;
int	*source;
XtInputId *id;
{
  int time;

  if (scanf("%d",&time) == EOF) {
	XtRemoveInput (*id);
	return;
  }
  printf("time is %d\n",time);

  /* other processing etc */
}

- You might also consider using using gets() so you don't block if the
  user just enters a return (scanf keeps looking for input).
- You might want to use the client_data to pass in the actual file pointer
  so it can work for any source of input.
- You might want to close the file pointer when EOF is reached.

--pete
Pete Ware / Biosym / San Diego CA / (619) 546-5532
uucp:	  scripps.edu!bioc1!pete
Internet: bioc1!pete@scripps.edu