/*
*
* h3600 driver example program - touch screen non blocking read interface
*
* Copyright 2000 Compaq Computer Corporation.
*
* Use consistent with the GNU GPL is permitted,
* provided that this copyright notice is
* preserved in its entirety in all copies and derived works.
*
* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
* FITNESS FOR ANY PARTICULAR PURPOSE.
*
* Author: Charles Flynn.
*
*/

/*
	Test for non blocking reads from touch screen.
	Test for select/poll mechanism.
	Has same usage as ts_read.c and tsraw.c

*/

#include <fcntl.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include <linux/h3600_ts.h>


/* should work on both raw and calibrated */
#if 1
#define DEV_NODE "/dev/ts"
#else
#define DEV_NODE "/dev/tsraw"
#endif

int pollReadBytes (int , char *, int);

main(int argc , char ** argv)
{
	int fd;
	int count;
	int err;
	TS_EVENT event;
	char dummy[4];
	unsigned int lcount=10,temp;


	printf("Opening for read ...\n");
	fd = open(DEV_NODE,O_RDONLY | O_NONBLOCK);
	if( fd < 0 )
	{
		printf("\nUnable to read from %s\n",DEV_NODE);
		exit(0);
	}



        if( argc == 2 )
                lcount = atoi(argv[1]);

	temp=lcount;

	while(temp--)
	{
	  event.pressure=1;
	  while(event.pressure)
	  {
	    count = pollReadBytes (fd, (char *)&event, sizeof(event));
	    if( count < 0 )
	    {
		perror("bad poll");
		close(fd);
		exit(1);
	    }
	    if ( count != sizeof(TS_EVENT) )
	    {
		printf("bad count =%d\n",count);
		close(fd);
		exit(1);
	    }
	
	    printf("TS_POLL:x=%d y=%d p=%d\n",event.x,event.y,event.pressure);
	  }
	  printf("Count=%d\n",temp);
	}

	printf("\nLCOUNT (%d) EXCEEDED\n",lcount);
	close (fd);
}

/*
	loop until all requested bytes have been returned
*/
int pollReadBytes (int fd, char *buf, int len)
{
    int             n, tot;
    fd_set          set,inset;
    struct timeval  tv;

    FD_ZERO (&set);
    FD_SET (fd, &set);
    tv.tv_sec = 0;
    tv.tv_usec = 100 * 1000;

    tot = 0;
    while (len > 0)
    {
	/*
		FD_ISSET returns TRUE if fd is a member of set 
		fd is added to set using FD_SET() - see 210 
		'Linux Application & Development" Johnston&Troan
	*/
	if( !FD_ISSET(fd,&set) )
	{
		printf("You forgot to add fd to 'set' of fds\n");
		return 0;
	}

	/*
	    put in a delay cos we dont want to fill /var/log/messages
	*/
	usleep(100 * 1000);	/* 100 m/s */
	inset=set;	/* select will change set if you dont to this */
	n = select (fd + 1, &inset, 0, 0, &tv);
	if (n < 0)
	{
	    perror("bad select");
	    return -1;
	}

	if ( !FD_ISSET(fd,&inset) )
		continue;

	/* Enter here if there is something to read */

#ifdef DEBUG
	printf("\nreading...\n");
#endif
        n = read (fd, buf, len);
        if (n > 0)
        {
	    if( n != sizeof(TS_EVENT) )
	    {
	      /* TODO we expect to read a whole event and not just a fragment */
	      printf("\nERROR: read %d bytes from %s\n",n,DEV_NODE);
	    }
            tot += n;
            buf += n;
            len -= n;
        }
	else if ( n < 0 )
	{
	    perror("bad read");
	    return -1;
	}
	else
	{
	    /* connection has been closed - return 0 */
	    printf("read() returned 0 meaning pipe closed - must close(fd)\n");
	    return 0;
	}

#ifdef DEBUG
	printf("tot=%d len=%d\n",tot,len);
#endif

    }
    return tot;
}
