[comp.windows.x] Toolkit question -- XtAddInput semantics

kauffman-jon@CS.YALE.EDU (Jon Kauffman) (07/07/89)

I have been having trouble with adding inputs with XtAddInput.  I am
able to get a procedure invoked whenever there's data pending on a
given descriptor, but my input handler seems to be called too often -- ie, 
when there is no data pending.

When some data appears on the descriptor, my  handler is called, 
just as it should be.  It uses read to grab the data and do something
with it, then returns.  However, when the handler returns, it's
immediately called again, even though there's to be nothing at all 
to be read (ioctl and select say nothing's there).  My read blocks, and
I'm stuck.

What exactly is meant by "pending" in the intrinsics?  In R3, am I guaranteed
that if my input procedure is called, that there's something to be read?

I am obviously missing something:

1) I'm screwing up with my fileio, and X has nothing to do with it.
   (most probable, apologies for the waste of bandwidth)
2) My input mask is wrong (but I tried all the other ones...).
3) There's something I should do to convince everyone that I've read
   everything, and it's in plain black and white in
   TFM.
4) I've found a feature.

Help is appreciated, sample code provided.  Thanks in advance.

I'm running R3 on a Sun 3/50.

/jon kauffman
======================================================================
Yale Computer Science Facility                    kauffman@cs.yale.edu
(203)-432-6428	                        {harvard,decvax}!yale!kauffman
======================================================================


#include <sys/filio.h>

void update_string();
void Askforhelp();

/** Sample code to demonstrate difficulties with XtAddInput
    register a procedure that prints what's on stdin, and 
    set up a timed cycle (askforhelp) that prints something
    every couple of seconds if events are being processed 
    correctly **/

main(argc,argv)
     char **argv;
     int argc;
{
  Widget top;

  top = XtInitialize(argv[0],"Input",NULL,0,&argc,argv);

  XtAddInput(fileno(stdin),XtInputReadMask,update_string,NULL);
  Askforhelp();

  XtMainLoop();
}

/** Try to service pending i/o and return; registered with XtAddInput **/
void update_string(client_data,source,id)
     caddr_t client_data;
     int *source;
     XtInputId *id;
{
  char bufr[BUFSIZ];
  int bytesread;
  long num;
  fd_set bob;
  struct timeval tonia;

  tonia.tv_sec=tonia.tv_usec=0;

/* How much does ioctl say is around */
  ioctl(*source,FIONREAD,&num);
  printf("ioctl says %ld bytes to be read\n",num);

/* does select see any pending bytes? */
  FD_ZERO(&bob);
  FD_SET(*source,&bob);
  printf("select returns a %d\n",select(FD_SETSIZE,&bob,NULL,NULL,&tonia));

/* read what's around */
  bytesread = read(*source,bufr,BUFSIZ);
  bufr[bytesread] = '\0';
  
  printf("%d-%s\n",bytesread,bufr);
}


/* Just something to tell me whether or not it's business as usual */
void Askforhelp()
{
  fprintf(stderr,"timeout, id = %d\n",XtAddTimeOut(2000,Askforhelp,NULL));
}