/* 
 * pentest.c - written by Rene K. Mueller <kiwi@the-labs.com>
 *
 * Version 0.10 - Jul 27, 2001
 *    http://the-labs.com/Stylistic/1000.html
 *
 * Infos extracted from
 *    xf86fpit.c as available at http://www.linuxslate.org/
 *
 * Compiles under FreeBSD + Linux, other UNIXes not tested
 * 
 * Horribly hacked to provide click info to a waiting process,
 * simply writing data to STDOUT.
 *
 * --Rob Flickenger, 4/19/02
 *
 */
 
#include <stdio.h>
#include <errno.h>
#include <termios.h>
#include <fcntl.h>
#include <ctype.h>

/* 
 * pen-modes:
 *    "A" send config
 *    "F" abs mode
 *    "E" relative mode
 *    "b" uper-left coord
 *    "B" prompt-mode
 *    "@" stream-mode
 *    "I" set increment
 *   "zb" binary reporting
 */

main(int argc, char *argv[]) {
   struct termios tty;
   unsigned char buff[5]; int i = 0; int fd; int current = 0; int last = 0; int p = 0;

   if(argc > 1) {
     if(!strcmp(argv[1], "-p")) {
       p = 1;
     } else {
       fprintf(stderr,"simplepen, a lobotomized pen driver for the Fujitsu Stylistic 1000 (and Linux)\n\n/dev/ttyS3 should already be set up with these commands:\n\n  setserial /dev/ttyS3 irq 15\n  setserial /dev/ttyS3 baud_base 115200\n\nWe print the following to STDOUT on each mouse click event:\n\n  Xpos Ypos Button1 Button2\n\nIf called with -p, it will exit after the first event.\n\n"), exit(1);
     }
   }
      
   fd = open("/dev/ttyS3",O_RDWR|O_NDELAY,0);
   if(fd<0)
      fprintf(stderr,"Pen initialization failed: cannot open /dev/ttyS3!\n"), exit(0);
   if(tcgetattr(fd,&tty)<0) 
      fprintf(stderr,"Couldn't probe defaults of /dev/ttyS3!  Try 'simplepen help'.\n"), exit(0);

   tty.c_iflag = 0;
   tty.c_cflag = B19200|CRTSCTS|CS8|CLOCAL|CREAD;
   tty.c_lflag = 0;
   tty.c_cc[VINTR] = 0;
   tty.c_cc[VQUIT] = 0;
   tty.c_cc[VKILL] = 0;
   tty.c_cc[VEOF] = 0;
   tty.c_cc[VEOL] = 0;
   tty.c_cc[VMIN] = 1;
   tty.c_cc[VTIME] = 0;
#ifdef VWERASE
    tty.c_cc[VWERASE] = 0;
#endif
#ifdef VREPRINT
    tty.c_cc[VREPRINT] = 0;
#endif

#ifdef VEOL2
    tty.c_cc[VEOL2] = 0;
#endif
    tty.c_cc[VSUSP] = 0;
#ifdef VDISCARD
    tty.c_cc[VDISCARD] = 0;
#endif
#ifdef VLNEXT
    tty.c_cc[VLNEXT] = 0; 
#endif
   if(tcsetattr(fd,TCSANOW,&tty)<0)
      fprintf(stderr,"pen settings failed.\n"), exit(1);

   /* init pen */
   write(fd,"\0",1);
   usleep(400000);
   tcflush(fd,TCIFLUSH);

   /* set streaming mode */
   write(fd,"zb@",3);
   usleep(400000);
   tcflush(fd,TCIFLUSH);
   while(1) {
      if(read(fd,buff+i,1)==1) {
         //fprintf(stderr,"%d (%dth byte)\n",buff[i],i+1);

/* Format of 5 bytes data packet for FPIT Tablets
       Byte 1
       bit 7  Phasing bit always 1
       bit 6  Switch status change
       bit 5  Proximity
       bit 4  Always 0
       bit 3  Test data
       bit 2  Sw3 (2nd side sw) 
       bit 1  Sw2 (1st side sw) 
       bit 0  Sw1 (Pen tip sw) 

       Byte 2
       bit 7  Always 0
       bits 6-0 = X6 - X0

       Byte 3
       bit 7  Always 0
       bits 6-0 = X13 - X7

       Byte 4
       bit 7  Always 0
       bits 6-0 = Y6 - Y0

       Byte 5
       bit 7  Always 0
       bits 6-0 = Y13 - Y7
*/
         if(i==4) {
            int x = buff[1]|(buff[2]<<7);
            int y = buff[3]|(buff[4]<<7);

            current = buff[0]&0x03;	//check if either button is pressed

            if(last != current) {
              fprintf(stdout,"%d %d %s %s\n", x, y, buff[0]&0x01?"1":"0",buff[0]&0x02?"1":"0");

              if(p)
                exit(1);
            }
                
            last = current;
            i = 0;

         } else {
            if(i&&buff[i]&0x80) 
               i = 1;
            else 
               i++;
         }
      }
   }
}
