home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / sys / sgi / 11573 < prev    next >
Encoding:
Text File  |  1992-07-29  |  11.3 KB  |  362 lines

  1. Path: sparky!uunet!dtix!relay!afterlife!adm!news
  2. From: marks@aivax.rl.af.mil (David Marks)
  3. Newsgroups: comp.sys.sgi
  4. Subject: tablet driver
  5. Message-ID: <31572@adm.brl.mil>
  6. Date: 29 Jul 92 11:37:02 GMT
  7. Sender: news@adm.brl.mil
  8. Lines: 352
  9.  
  10. I modified the old example graphics tablet driver which used to be included
  11. in 4Dgifts to work with a SummaGraphics tablet.  Towards the end of the program
  12. the code initializes a serial port, then sends commands to the serial port to
  13. configure the tablet.  This was done while 3.2 (or 3.3.2) was runnign, back
  14. when the WAS a tabletd running.  Now its done as part of the X-Server.
  15. All I did was change the Hitatchi codes to the Summagraphics codes, which I
  16. got from the Summagraphics manual, and add some more flexible serial I/O
  17. code, and allowed one to change the MODE that the tablet uses (send while
  18. in proximity, send on contact, send on button press, etc...)  And, try
  19. as I could, I just couldn't squeeze the state of 4 buttons into 3 bits...
  20.  
  21.  
  22.  
  23. Dave Marks
  24. Rome Laboratory
  25. marks@ra.rl.af.mil
  26.  
  27. -------------------------
  28. tabletd.c
  29. -------------------------
  30. /*
  31.  *    I modified this to work with a Summagraphics Summasketch 
  32.  *    tablet.  Tally-Ho! 
  33.  *                David L. Marks - 1991
  34.  */
  35.  
  36. /*
  37.  *      tablet -
  38.  *              This is the tablet reader for the Hitachi tablet.  The 
  39.  *      Hitachi tablet is 11" x 11" and has 200 points per inch.
  40.  *
  41.  *      Define RAWCOORDS to get raw tablet coordinates.  In this case,
  42.  *      tablet values will be between 0 and TABLETXMAX in X and between
  43.  *      0 and TABLETYMAX in Y.  If the cursor is attached to the tablet,
  44.  *      the lower left hand corner of the tablet maps into the screen
  45.  *      area, since tablet values exceed XMAXSCREEN and YMAXSCREEN.
  46.  *
  47.  *      Define MAPTOSCREEN to get tablet coords that map the lower part
  48.  *      of the tablet to screen coordinaes.  In this case tablet values 
  49.  *      will be between 0 and XMAXSCREEN in X and between 0 and XMAXSCREEN 
  50.  *      in Y.  If the cursor is attached to the tablet, the whole bottom
  51.  *      area of the tablet maps into the screen area.
  52.  *
  53.  *      The (default) tablet daemon that is installed in /etc/gl/tabletd 
  54.  *      is equivalent to this program with RAWCOORDS defined.  If you wish 
  55.  *      to map the entire width of the tablet onto the screen, then 
  56.  *      recompile this with MAPTOSCREEN defined.  Then, become superuser 
  57.  *      and move /etc/gl/tabletd to /etc/gl/tabletd.default and move the
  58.  *      new, recomplied version of this program into /etc/gl/tabletd.
  59.  *      You can either reboot to run the new version, or as superuser,
  60.  *      execute "tabletd /dev/tablet &" and the mapping will now reflect
  61.  *      the fulll width of the Hitachi tablet.
  62.  *
  63.  *                                Paul Haeberli - 1986
  64.  */
  65.  
  66.  
  67. #include "gl.h" 
  68. #include "device.h"
  69. #include <stdio.h>
  70. #include <fcntl.h>
  71. #include <termio.h>
  72. #include <signal.h>
  73.  
  74. #define MAPTOSCREEN
  75.  
  76.  
  77. #define TABLETXMAX        2900
  78. #define TABLETYMAX        2900
  79.  
  80. #ifdef RAWCOORDS
  81. #define COORDMAP(x)        (x)
  82. #endif
  83.  
  84. #ifdef MAPTOSCREEN
  85. #define COORDMAP(x)        (((x)*XMAXSCREEN)/TABLETXMAX)
  86. #endif
  87.  
  88. int l, m, r, f;
  89. int x, y;
  90. FILE *inf;
  91. struct termio term, sterm;
  92.  
  93. main(argc,argv)
  94. int argc;
  95. char **argv;
  96. {
  97.     register unsigned char c;
  98.  
  99.     if(argc<2) {
  100.         fprintf(stderr,"usage: tabletd </dev/tty?>\n");
  101.         exit(1);
  102.     }
  103.     inf = fopen(argv[1],"r+");
  104.     if(!inf) {
  105.         fprintf(stderr,"tabletd: can't open %s\n",argv[1]);
  106.         exit(1);
  107.     }
  108.     f = fileno(inf);
  109.     x = 0;
  110.     y = 0;
  111.     init();
  112.     while(1) {
  113.         c = fgetc(inf);
  114.         bitpad_softchar(c);
  115.     }
  116. }
  117.  
  118. int synced, state;
  119. int x, y, ox, oy, obut;
  120. int b0, b1, b2, b3;
  121. int     but;
  122. /* The old driver interfaced to gl using a 4-bit code for the button status */
  123. /* The summasketch uses a 3-bit code (information loss??) for its four */
  124. /*   buttons, so, lets map the 3-bit code to the four bit code */
  125. /* The only multi-button combinations I support are 1&4, 2&4, 1&2&4 */
  126. /* Note: it is tough to get a multi-button hit reliably. Try 2&4 and you */
  127. /*   get 2 then 4 or vice versa.  */
  128. int    new_but[8]=  {0x00, 0x01, 0x02, 0x04,
  129.               0x08, 0x09, 0x0A, 0x0B };
  130.  
  131. #define SYNCHBIT        0x80
  132. #define LOW_3_BITS    0x07
  133.  
  134. /*
  135.  *        bitpad_softchar -
  136.  *                This inteprets characters in bitpad I compatable format.
  137.  */
  138.  
  139. bitpad_softchar( onechar )
  140. register unsigned int onechar;
  141. {
  142.     int        xsign, ysign;
  143.     int        tbut;
  144.  
  145.     onechar &= 0xff;
  146.     if(synced) {
  147.         switch(state) {
  148.             case 0: x = onechar & 0x3f;
  149.                     state++;
  150.                     break;
  151.             case 1: x |= (onechar & 0x3f)<<6;
  152.                     state++;
  153.                     break;
  154.              case 2: y = onechar & 0x3f;
  155.                     state++;
  156.                     break;
  157.             case 3: y |= (onechar & 0x3f)<<6;
  158.                     state++;
  159.  
  160. #define X_SIGN_SHIFT 4
  161. #define Y_SIGN_SHIFT 3
  162.                     /* but has the sign information for x and y */
  163.                     xsign = (but >>X_SIGN_SHIFT) & 0x01;
  164.                     /* one (1) is positive, zero (0) negative */
  165.                     if (!xsign)
  166.                         x *= -1;
  167.                     ysign = (but >>Y_SIGN_SHIFT) & 0x01;
  168.                     if (!ysign)
  169.                         y *= -1;
  170.                     if(x != ox) {  /* low x */
  171.                         ox = x;
  172.                         gl_changedevice(BPADX,COORDMAP(x));        
  173.                     }
  174.                     if(y != oy) {
  175.                         oy = y;
  176.                         gl_changedevice(BPADY,COORDMAP(y));        
  177.                     }
  178. #ifdef DEBUG
  179.                    printf(" x = %d, y = %d, button = %x (hex)\n", x, y, but);
  180. #endif
  181.                     tbut = but;
  182.                     tbut &= LOW_3_BITS;  /* take the low three bits */
  183.                     /* now translate the bits to what the SGI driver wants */
  184.             but = new_but[tbut];
  185.                     if(but != obut) {
  186.                         obut = but;
  187.                         if((but&1) != b0) {
  188.                             b0 = but&1 ;
  189.                             gl_changedevice(BPAD0,b0);
  190.                         }
  191.                          but >>= 1;
  192.                         if((but&1) != b1) {
  193.                             b1 = but&1 ;
  194.                             gl_changedevice(BPAD1,b1);
  195.                         }
  196.                          but >>= 1;
  197.                         if((but&1) != b2) {
  198.                             b2 = but&1;
  199.                             gl_changedevice(BPAD2,b2);
  200.                         }
  201.                          but >>= 1;
  202.                         if((but&1) != b3) {
  203.                             b3 = but&1;
  204.                             gl_changedevice(BPAD3,b3);
  205.                         }
  206.                     }
  207.                     break;
  208.             case (4):
  209.                     if ( (onechar & SYNCHBIT) == 0 ) {  
  210.                         /* if the synch bit IS NOT on this char */
  211.                     synced = 0; /* then we ARE NOT synched */
  212.                     state = 0;
  213.                     break;
  214.             }
  215.             /* otherwise, we are in synch */
  216.                 but = (onechar & 0xff); /* save the whole status, not just buttons*/
  217.  
  218.                 state = 0;
  219.                     break;
  220.         } /* end switch */
  221.     } else {
  222.         if(onechar & SYNCHBIT) {  /* if the synch bit is on this char */
  223.             synced = 1; /* then we are synched */
  224.             /* It is from this character that we get the button info */
  225.             /* and things that the old driver didn't care about (apparently) */
  226.             /* like proximity, tablet identifier, coordinate sign. */
  227.             but = (onechar & 0xff); /* save the whole status, not just buttons*/
  228.         }
  229.         state = 0;
  230.     }
  231. } /* end bitpad_softchar */
  232.  
  233. init()
  234. {
  235.  
  236. /* Primary Modes */
  237.  
  238. /* Send reports continuously (and quickly !) whether or not button is pressed */
  239. #define STREAM_MODE        0x40
  240.  
  241. /* Send reports continuously only when button is pressed (pencil mode?) */
  242. #define SWITCH_STREAM_MODE    0x41
  243.  
  244. /* Send one (1) report only when a button is pressed */
  245. #define POINT_MODE        0x42
  246.  
  247. /* Send one (1) report only when the host asks for one via the request report*/
  248. /*   command. */
  249. #define REMOTE_REQUEST_MODE    0x44
  250.  
  251.  
  252. /* Modifiers (Secondary Modes) */
  253.  
  254. /* The report contains only button, delta-x, delta-y info */
  255. /* THIS DRIVER DOES NOT SUPPORT THIS MODE RIGHT NOW!!! DON'T EVEN THINK */
  256. /*   ABOUT "TRYING IT OUT", SINCE THIS MODE YIELDS 3-BYTE REPORTS, WHILE */
  257. /*   NON-DELTA MODE YIELDS 5-BYTE REPORTS.   Thank You... */
  258. #define DELTA_MODE        0x45
  259.  
  260. /* This mode sets a threshold level that must be met before a report is */
  261. /*   sent.  This only makes sense when the primary mode is either continuous */
  262. /*   or switch continuous. The tablet generates a report only after the stylus */
  263. /*   has been moved the specified number of units.  Setting the increment to */
  264. /*   one has the nice property of generating reports only when the stylus is */
  265. /*   moved. */
  266. #define INCREMENT_MODE        0x49
  267.     
  268. /* After setting the secondary mode to INCREMENT_MODE, you must say what the */
  269. /*   threshold level (increment) is.  You can choose 0-32 (decimal, 0-20 hex)*/
  270. /*   Add your chosen threshold level to the INCREMENT_BASE and send that */
  271. /*   to the tablet. */
  272. #define INCREMENT_BASE    0x20
  273.  
  274. /* used to get the tablet report when in REMOTE_REQUEST primary mode */
  275. #define REMOTE_TRIGGER_CMD    0x50
  276.  
  277. /* Factor to reduce the rate of report transmission.  At 9600 BPS, the tablet */
  278. /*   generates about 120 reports/second, which may be too much.  Send the */
  279. /*   tablet one of these below to reduce the rate by a factor of 0, 2, 8 or 32 */
  280. #define MAX_RATE    0x51
  281. #define MAX_RATE_DIV_2    0x52   
  282. #define MAX_RATE_DIV_8    0x53   
  283. #define MAX_RATE_DIV_32    0x54   
  284.  
  285.  
  286. /* user defineable parameters */
  287.  
  288. /*  Only matters if you use INCREMENT_MODE.  Change this at will, but make sure */
  289. /*   the value is  0 < x < 33 (decimal). */
  290. #define DESIRED_INCREMENT    1
  291.  
  292.     char    tab_msg;
  293.  
  294.     if (ioctl(f, TCGETA, &term) == -1) {
  295.         fprintf(stderr,"tabletd: ioctl(TCGETA) failed\n");
  296.         perror("init");
  297.         return(0);
  298.     }
  299.     sterm = term;
  300.  
  301.     /* change the modes */
  302.     term.c_iflag = IGNBRK | IGNPAR;
  303.     term.c_oflag = 0;
  304.     term.c_lflag = 0;
  305.     
  306.     /* If its not obvious, this is where you would change the baud rate */
  307.     /*   if you want something other than 9600 */
  308.     term.c_cflag = B9600 | CS8 | CREAD ;
  309.     term.c_cc[VMIN] = 1;
  310.     term.c_cc[VTIME] = 0;
  311.  
  312.     if (ioctl(f, TCSETA, &term) == -1) {
  313.         fprintf(stderr,"tabletd: ioctl(TCSETA) failed\n");
  314.         perror("init");
  315.         return(0);
  316.     }
  317.     
  318.    /* put the tablet into the right modes */
  319.    
  320.    /* set the appropriate primary mode */
  321.    /* I chose POINT_MODE because it sends a report only when a button is */
  322.    /*   pressed.  */
  323.    tab_msg = POINT_MODE;
  324.    write(f, &tab_msg, 1);
  325.    
  326.    /* set the secondary mode, if desired. if not, comment out */
  327. /*   tab_msg = INCREMENT_MODE; */
  328. /*   write(f, &tab_msg, 1); */
  329.  
  330.    
  331.    /* sets the increment value , only if the secondary mode is INCREMENT*/
  332. /*   tab_msg = INCREMENT_BASE + DESIRED_INCREMENT; */
  333. /*   write(f, &tab_msg, 1); */
  334.  
  335.    
  336.    /* set the report rate */
  337.    tab_msg = MAX_RATE_DIV_8;
  338.    write(f, &tab_msg, 1);
  339.  
  340. }
  341.  
  342. ----------------------------
  343. Makefile
  344. ----------------------------
  345. SHELL = /bin/sh
  346. # the iristools/include is for rasterfile.h for iisc
  347. # The include directory under 
  348. CFLAGS = -g -I/usr/include/gl  -DDEBUG
  349. LDFLAGS = -lgl_s -lm
  350. ALL = tabletd 
  351.  
  352. all: $(ALL)
  353.  
  354. clean:
  355.     rm -f *.o  $(ALL)
  356.  
  357. tabletd : $$@.c
  358.     $(CC) $(CFLAGS) -o $@ $@.c $(LDFLAGS)
  359.  
  360.  
  361. ---------------------------
  362.