blbates@AERO36.LARC.NASA.GOV (Brent Bates ViGYAN AAD/TAB) (05/29/91)
I got the tablet daemon working with the Kurta tablet we have. The main thing that needed to be done was to be able to change all the serial port parameters. I also found a bug in the daemon too, and have corrected it. Below is the modified and corrected IRIX 3.2 tablet daemon from /usr/people/4Dgifts/examples/devices. Hopefully, SGI will add these options and corrections to the executable they ship, along with any enhancements they may have. If you have any questions, drop me a line. ------------------------------- Cut Here --------------------------- /* * tablet - * This is the tablet reader for the Hitachi tablet. The * Hitachi tablet is 11" x 11" and has 200 points per inch. * * Define RAWCOORDS to get raw tablet coordinates. In this case, * tablet values will be between 0 and TABLETXMAX in X and between * 0 and TABLETYMAX in Y. If the cursor is attached to the tablet, * the lower left hand corner of the tablet maps into the screen * area, since tablet values exceed XMAXSCREEN and YMAXSCREEN. * * Define MAPTOSCREEN to get tablet coords that map the lower part * of the tablet to screen coordinaes. In this case tablet values * will be between 0 and XMAXSCREEN in X and between 0 and XMAXSCREEN * in Y. If the cursor is attached to the tablet, the whole bottom * area of the tablet maps into the screen area. * * The (default) tablet daemon that is installed in /etc/gl/tabletd * is equivalent to this program with RAWCOORDS defined. If you wish * to map the entire width of the tablet onto the screen, then * recompile this with MAPTOSCREEN defined. Then, become superuser * and move /etc/gl/tabletd to /etc/gl/tabletd.default and move the * new, recomplied version of this program into /etc/gl/tabletd. * You can either reboot to run the new version, or as superuser, * execute "tabletd /dev/tablet &" and the mapping will now reflect * the fulll width of the Hitachi tablet. * * Paul Haeberli - 1986 * * Brent L. Bates, blbates@aero36.larc.nasa.gov: * Added all serial port options; baud rate, character size, * stop bits, and parity * Also corrected bug in status byte usage. Status byte for * first data set was ignored and status byte for next * data set was used for last set of data, etc. * April 18, 1991 */ #include <gl.h> #include <device.h> #include <stdio.h> #include <fcntl.h> #include <termio.h> #include <signal.h> #define RAWCOORDS #define TABLETXMAX 2200 #define TABLETYMAX 2200 #ifdef RAWCOORDS #define COORDMAP(x) (x) #endif #ifdef MAPTOSCREEN #define COORDMAP(x) (((x)*XMAXSCREEN)/TABLETXMAX) #endif #define PARNONE 0 #define STOPONE 0 int l, m, r, f; int x, y; FILE *inf; struct termio term, sterm; tcflag_t controlmodes; main(argc,argv) int argc; char *argv[]; { extern char *optarg; extern int optind; extern tcflag_t controlmodes; register unsigned char c; int option, usage=0; tcflag_t baudrate=B9600,charactersize=CS8,parity=PARNONE,stopbits=STOPONE; /* parse arguments */ while ((option = getopt(argc, argv, "b:c:p:s:")) != -1) { switch (option) { /* -b Baud Rate */ case 'b': if(!strcmp(optarg,"50")){ baudrate=B50; } else if(!strcmp(optarg,"75")){ baudrate=B75; } else if(!strcmp(optarg,"110")){ baudrate=B110; } else if(!strcmp(optarg,"134")){ baudrate=B134; } else if(!strcmp(optarg,"150")){ baudrate=B150; } else if(!strcmp(optarg,"200")){ baudrate=B200; } else if(!strcmp(optarg,"300")){ baudrate=B300; } else if(!strcmp(optarg,"600")){ baudrate=B600; } else if(!strcmp(optarg,"1200")){ baudrate=B1200; } else if(!strcmp(optarg,"1800")){ baudrate=B1800; } else if(!strcmp(optarg,"2400")){ baudrate=B2400; } else if(!strcmp(optarg,"4800")){ baudrate=B4800; } else if(!strcmp(optarg,"9600")){ baudrate=B9600; } else if(!strcmp(optarg,"19200")){ baudrate=B19200; } else if(!strcmp(optarg,"38400")){ baudrate=B38400; } else if(!strcmp(optarg,"exta")){ baudrate=EXTA; } else if(!strcmp(optarg,"extb")){ baudrate=EXTB; } else { fprintf(stderr,"Valid Baud Rates: 50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,exta,extb\n"); exit(1); } /* -c Character Size */ break; case 'c': if(!strcmp("5",optarg)){ charactersize=CS5; } else if(!strcmp("6",optarg)){ charactersize=CS6; } else if(!strcmp("7",optarg)){ charactersize=CS7; } else if(!strcmp("8",optarg)){ charactersize=CS8; } else { fprintf(stderr,"Valid Character Sizes: 5, 6, 7, 8\n"); exit(1); } break; /* -p Parity */ case 'p': if(!strcmp("none",optarg)) { parity=PARNONE; } else if(!strcmp("even",optarg)) { parity=PARENB; } else if(!strcmp("odd",optarg)) { parity=PARENB|PARODD; } else { fprintf(stderr,"Valid Parity Options: none, even, odd\n"); exit(1); } break; /* -s Stop Bits */ case 's': if(!strcmp("1",optarg)){ stopbits=STOPONE; } else if(!strcmp("2",optarg)){ stopbits=CSTOPB; } else { fprintf(stderr,"Valid Stop Bits: 1 and 2\n"); exit(1); } break; default: usage++; } } if(strncmp("/dev/tty",argv[argc-1],8)) usage++; if(usage) { fprintf(stderr,"usage: %s [-b baud rate] [-d character size] [-p parity] [-s stop bits] </dev/ttyf?>\n", argv[0]); exit(1); } controlmodes=baudrate|charactersize|parity|stopbits; inf = fopen(argv[argc-1],"r+"); if(!inf) { fprintf(stderr,"tabletd: can't open %s\n",argv[argc-1]); exit(1); } f = fileno(inf); x = 0; y = 0; init(); while(1) { c = fgetc(inf); bitpad_softchar(c); } } Boolean synced=FALSE; int state=0; int x, y, ox, oy, obut=0; int b0=0,b1=0,b2=0,b3=0; #define SYNCHBIT 0x40 /* * bitpad_softchar - * This inteprets characters in bitpad I compatable format. */ bitpad_softchar( onechar ) register unsigned int onechar; { static short but; onechar &= 0x7f; /* Mask Off Parity Bit */ if(synced) { switch(state) { case 0: x = onechar & 0x3f; state++; break; case 1: x |= (onechar & 0x3f)<<6; state++; break; case 2: y = onechar & 0x3f; state++; break; case 3: y |= (onechar & 0x3f)<<6; if(x != ox) { ox=x; gl_changedevice(BPADX,COORDMAP(x)); } if(y != oy) { oy=y; gl_changedevice(BPADY,COORDMAP(y)); } if(but != obut) { obut = but; if((but&1) != b0) { b0 = but&1 ; gl_changedevice(BPAD0,b0); } but >>= 1; if((but&1) != b1) { b1 = but&1 ; gl_changedevice(BPAD1,b1); } but >>= 1; if((but&1) != b2) { b2 = but&1; gl_changedevice(BPAD2,b2); } but >>= 1; if((but&1) != b3) { b3 = but&1; gl_changedevice(BPAD3,b3); } } state++; break; case 4: if(onechar & SYNCHBIT){ but=(onechar & 0x3f)>>2; /* Mask Off Excess Bits and Shift*/ state=0; } else { synced=FALSE; /* Out of Synch */ state=0; } break; } } else { if(onechar & SYNCHBIT){ but=(onechar & 0x3f)>>2; /* Mask Off Excess Bits and Shift*/ synced=TRUE; /* All Synch'ed Up */ } state=0; } } init() { extern tcflag_t controlmodes; if (ioctl(f, TCGETA, &term) == -1) { fprintf(stderr,"tabletd: ioctl(TCGETA) failed\n"); perror("init"); return(0); } sterm = term; /* change the modes */ term.c_iflag = IGNBRK | IGNPAR; term.c_oflag = 0; term.c_cflag = controlmodes|CREAD; term.c_lflag = 0; term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; if (ioctl(f, TCSETA, &term) == -1) { fprintf(stderr,"tabletd: ioctl(TCSETA) failed\n"); perror("init"); return(0); } gl_changedevice(BPAD0,0); gl_changedevice(BPAD1,0); gl_changedevice(BPAD2,0); gl_changedevice(BPAD3,0); } Brent L. Bates Phone:(804) 864-2854 NASA-Langley Research Center FAX:(804) 864-6792 M.S. 361 Hampton, Virginia 23665-5225 E-mail: blbates@aero36.larc.nasa.gov or blbates@aero8.larc.nasa.gov