home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume6 / xscan / part01 next >
Internet Message Format  |  1990-04-11  |  58KB

  1. Path: uunet!cs.utexas.edu!sun-barr!newstop!sun!Aus
  2. From: richb@Aus (Rich Burridge)
  3. Newsgroups: comp.sources.x
  4. Subject: v06i071: Scantool -- Read from a scanner, Part01/03
  5. Message-ID: <134361@sun.Eng.Sun.COM>
  6. Date: 12 Apr 90 09:12:46 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1707
  9. Approved: argv@sun.com
  10.  
  11. Submitted-by: richb@Aus (Rich Burridge)
  12. Posting-number: Volume 6, Issue 71
  13. Archive-name: xscan/part01
  14.  
  15.  
  16. This is version 1.4 of the scantool program. It can interface to a Microtek
  17. MS300A scanner, scan the document, and turn the image into a Sun rasterfile,
  18. which can be read by dtp programs such as Frame Maker.
  19.  
  20. There are grtaphical interfaces for XView and SunView, and it would be fairly
  21. easy to "knock up" an interface to other X11 toolkits that supported frames,
  22. drawing canvases and popup menus.
  23.  
  24. The software is now divided into two programs; scantool a frontend window
  25. based program for setting the scanning options, and scan, the program that
  26. will actually perform the scan. It should also be possible to run this
  27. scan program on it's own, but there are several command line options to
  28. setup, so it's probably easier through scantool.
  29.  
  30. **IMPORTANT NOTE**
  31.  
  32. I no longer have access to a Microtek MS300A scanner. If you find problems
  33. in this area, then you are on your own. I will be very happy to incorporate
  34. any fixes you make, so other people can enjoy them as well.
  35.  
  36. Suggestions for furthur improvement would be most welcome, plus bugs,
  37. comments and flames.
  38.  
  39. Rich Burridge,          DOMAIN: richb@Aus.Sun.COM
  40. PHONE: +61 2 413 2666   ACSNET: richb@sunaus.sun.oz
  41.                         UUCP:   {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
  42.  
  43.    File Name        Archive #    Description
  44. ----------------------------------------------------------
  45.  scantool                   1    
  46.  scantool/CHANGES           3    
  47.  scantool/Imakefile         3    
  48.  scantool/Makefile          2    
  49.  scantool/README            3    
  50.  scantool/black.codes       3    
  51.  scantool/button.invert.icon  3    
  52.  scantool/button.normal.icon  3    
  53.  scantool/exclaim.icon      3    
  54.  scantool/frame.cursor      3    
  55.  scantool/graphics.c        2    
  56.  scantool/help.cursor       3    
  57.  scantool/images.h          3    
  58.  scantool/main.cursor       3    
  59.  scantool/misc.c            2    
  60.  scantool/patchlevel.h      3    
  61.  scantool/scan.1            3    
  62.  scantool/scan.c            1    
  63.  scantool/scan.h            3    
  64.  scantool/scan_compress.c   2    
  65.  scantool/scan_extern.h     2    
  66.  scantool/scantool.1        2    
  67.  scantool/scantool.c        2    
  68.  scantool/scantool.h        3    
  69.  scantool/scantool.help     3    
  70.  scantool/scantool.icon     3    
  71.  scantool/scantool_extern.h  3    
  72.  scantool/sunview.c         1    
  73.  scantool/switch.invert.cursor  3    
  74.  scantool/switch.normal.cursor  1    
  75.  scantool/white.codes       3    
  76.  scantool/xview.c           1    
  77. ------CUT HERE------Part1of3------CUT HERE------
  78.  
  79. #! /bin/sh
  80. # This is a shell archive.  Remove anything before this line, then feed it
  81. # into a shell via "sh file" or similar.  To overwrite existing files,
  82. # type "sh file -c".
  83. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  84. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  85. # If this archive is complete, you will see the following message at the end:
  86. #        "End of archive 1 (of 3)."
  87. # Contents:  scantool scantool/scan.c scantool/sunview.c
  88. #   scantool/switch.normal.cursor scantool/xview.c
  89. # Wrapped by argv@turnpike on Thu Apr 12 02:08:22 1990
  90. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  91. if test ! -d 'scantool' ; then
  92.     echo shar: Creating directory \"'scantool'\"
  93.     mkdir 'scantool'
  94. fi
  95. if test -f 'scantool/scan.c' -a "${1}" != "-c" ; then 
  96.   echo shar: Will not clobber existing file \"'scantool/scan.c'\"
  97. else
  98. echo shar: Extracting \"'scantool/scan.c'\" \(19805 characters\)
  99. sed "s/^X//" >'scantool/scan.c' <<'END_OF_FILE'
  100. X
  101. X/*  @(#)scan.c 1.4 90/04/04
  102. X *
  103. X *  Program which will read a scanned image from a Microtek
  104. X *  MS-300A scanner and convert it to a Sun rasterfile.
  105. X *
  106. X *  Copyright (c) Rich Burridge.
  107. X *                Sun Microsystems, Australia - All rights reserved.
  108. X *
  109. X *  Permission is given to distribute these sources, as long as the
  110. X *  copyright messages are not removed, and no monies are exchanged.
  111. X *
  112. X *  No responsibility is taken for any errors or inaccuracies inherent
  113. X *  either to the comments or the code of this program, but if
  114. X *  reported to me, then an attempt will be made to fix them.
  115. X */
  116. X
  117. X#include <stdio.h>
  118. X#include <strings.h>
  119. X#include <signal.h>
  120. X#include <sgtty.h>
  121. X#include <rasterfile.h>
  122. X#include <sys/time.h>
  123. X#include <sys/types.h>
  124. X#include "patchlevel.h"
  125. X#include "scan.h"
  126. X
  127. Xchar cksum ;               /* Packets checksum. */
  128. Xchar cntbytes ;            /* Number of count bytes received. */
  129. Xchar finalimage[MAXLINE] ; /* Name of uncompressed image file. */
  130. Xchar from_rs[BUFSIZE] ;    /* Data received from the RS232. */
  131. Xchar line[MAXLINE] ;
  132. Xchar picname[MAXLINE] ;    /* Picture name for rasterfile output. */
  133. Xchar progname[MAXLINE] ;   /* Name of this program. */
  134. Xchar rscksum ;             /* RS232 read packet checksum. */
  135. Xchar rsdata[BUFSIZE] ;     /* Latest packet to/from the scanner. */
  136. Xchar rsrhold = XON ;       /* RS232 host hand shaking state. */
  137. Xchar rsrstate = RSSOR ;    /* State of RS232 read automation. */
  138. Xchar rsrtype ;             /* Record type received. */
  139. Xchar rswstate ;            /* RS232 write acknowledgement state. */
  140. Xchar scantype[MAXLINE] ;   /* Scanner details. */
  141. Xchar temphead[MAXLINE] ;   /* Temporary filename for header file. */
  142. Xchar tempimage[MAXLINE] ;  /* Temporary filename for saved scanned data. */
  143. X
  144. Xint brightness ;           /* Brightness value. */
  145. Xint cancel ;               /* Indicates if should cancel current scan. */
  146. Xint complete ;             /* Indicates if scanning is completed. */
  147. Xint contrast ;             /* Contrast value. */
  148. Xint error ;                /* Has an error report has been received? */
  149. Xint fd = -1 ;              /* File descriptor for RS232 line. */
  150. Xint finished ;             /* Indicates if we have finished uncompressing. */
  151. Xint fwidth ;               /* Final width of rasterfile. */
  152. Xint height ;               /* Height in scan lines of raster file image. */
  153. Xint pic_compressed = 0 ;   /* Whether any picture data was compressed. */
  154. Xint pkt_started = 0 ;      /* Is a data packet coming from the scanner? */
  155. Xint pktdone ;              /* Indicates if a complete packet received. */
  156. Xint rc ;                   /* Current character from scanned file. */
  157. Xint rcount ;               /* Count of bit position within read character. */
  158. Xint rscnt ;                /* Number of data bytes to read. */
  159. Xint rsptr ;                /* Character buffer pointer. */
  160. Xint wc ;                   /* Current character to write to final image file. */
  161. Xint wcount ;               /* Count of bit position within write character. */
  162. Xint width ;                /* Width in pixels of rasterfile image. */
  163. Xint grain ;                /* Grain value. */
  164. Xint resolution ;           /* Resolution value. */
  165. Xint retval ;               /* This programs exit status. */
  166. Xint rf ;                   /* File descriptor for raster image. */
  167. X
  168. Xint switches[4] =
  169. X      {
  170. X        0,                 /* Mode (Line Art). */
  171. X        1,                 /* Data Transfer (Compressed). */
  172. X        0,                 /* Serial Port (A). */
  173. X        1                  /* Baud Rate (19200). */
  174. X      } ;
  175. X
  176. Xint framevals[4] =            /* Initial frame in 1/8th inch intervals. */
  177. X      {
  178. X        16,                /* X1. */
  179. X        16,                /* Y1. */
  180. X        48,                /* X2. */
  181. X        48,                /* Y2. */
  182. X     } ;
  183. X
  184. XFILE *rd ;                 /* File descriptor for input files. */
  185. XFILE *wd ;                 /* File descriptor for final image. */
  186. X
  187. X#ifdef NO_4.3SELECT
  188. Xint readmask ;                /* File descriptors with outstanding reads. */
  189. X#else
  190. Xfd_set readmask ;             /* Readmask used in select call. */
  191. X#endif NO_4.3SELECT
  192. X
  193. Xstruct timeval timeout = { MAXTIME, 0 } ;
  194. X
  195. Xstruct code *whites[16] ;   /* White initial starting pointers. */
  196. Xstruct code *blacks[4] ;    /* Black initial starting pointers. */
  197. X
  198. X
  199. X/*  The scan program can exit is a variety of ways. These are:
  200. X *
  201. X *  0          - successful   - image saved in picname.
  202. X *  1          - unsuccessful - cannot open ttyline.
  203. X *  2          - unsuccessful - cannot open temporary image file.
  204. X *  3          - unsuccessful - cannot open raster header file.
  205. X *  4          - unsuccessful - scanner not responding. Aborting this scan.
  206. X *  5          - unsuccessful - invalid command line argument.
  207. X *  100 + 0xnn - unsuccessful - scanning error 0xnn received. Scan aborted.
  208. X *  200 + n    - unsuccessful - scan program terminated with signal n.
  209. X *
  210. X *  It is upto the calling program or shell script to display the
  211. X *  appropriate message back to the user.
  212. X */
  213. X
  214. Xmain(argc, argv)
  215. Xint argc ;
  216. Xchar *argv[] ;
  217. X{
  218. X  retval = 0 ;
  219. X  set_signals() ;              /* Set up a signal handler. */
  220. X  STRCPY(progname, argv[0]) ;  /* Save program name. */
  221. X  get_options(argc, argv) ;    /* Extract scanning parameters. */
  222. X  do_scan() ;                  /* Perform a scan using given parameters. */
  223. X  exit(retval) ;
  224. X}
  225. X
  226. X
  227. XSIGRET
  228. Xdo_exit(sig)   /* Signal received; exit gracefully. */
  229. Xint sig ;
  230. X{
  231. X  char outval ;
  232. X
  233. X  if (fd != -1)     /* Terminate the scan properly, if started. */
  234. X    {
  235. X      outval = ETX ;
  236. X      WRITE(fd, &outval, 1) ;
  237. X      CLOSE(fd) ;
  238. X    }
  239. X  exit(200 + sig) ;
  240. X}
  241. X
  242. X
  243. Xdo_handshake(value)            /* Send RS232 handshake XON/XOFF. */
  244. Xchar value ;
  245. X{
  246. X  WRITE(fd, &value, 1) ;
  247. X  rsrhold = value ;
  248. X}
  249. X
  250. X
  251. Xdo_scan()                      /* Perform a scan using given parameters. */
  252. X{
  253. X  char c ;                     /* Next character for RS232 output. */
  254. X
  255. X  pic_compressed = 0 ;
  256. X  height = 0 ;
  257. X  error = 0 ;                           /* Set to 1 on error. */
  258. X  if (open_temp_file() < 0) return ;    /* Open file for raster image. */
  259. X  if (init_rs_port(SERIAL_PORT, BAUD_RATE) < 0) return ;
  260. X/* Set scanning parameters. */
  261. X  if (make_packet('!', 1, 0) < 0) return ;    /* Get scanner model number. */
  262. X  if (make_packet('X', 1, 0) < 0) return ; ;  /* Reset scanning parameters. */
  263. X  if (make_packet('C', 2, DATA_TRANSFER) < 0) return ;
  264. X  if (MODE)
  265. X    {
  266. X      if (make_packet('H', 2, 0) < 0) return ;
  267. X    }
  268. X  else if (make_packet('T', 2, 0) < 0) return ;
  269. X  if (make_packet('G', 2, grain) < 0) return ;         /* Set up grain. */
  270. X  if (make_packet('B', 2, brightness) < 0) return ;    /* Set up brightness. */
  271. X  if (make_packet('K', 2, contrast) < 0) return ;      /* Set up contrast. */
  272. X  if (make_packet('R', 2, resolution+16) < 0) return ; /* Set up resolution. */
  273. X  if (make_frame_packet() < 0) return ;
  274. X  if (make_packet('S', 1, 0) < 0) return ;     /* Send a start scan packet. */ 
  275. X  complete = 0 ;
  276. X  cancel = 0 ;
  277. X  for (;;)
  278. X    {
  279. X#ifdef NO_4.3SELECT
  280. X      readmask = 1 << fd ;
  281. X      SELECT(32, &readmask, (int *) 0,(int *) 0, &timeout) ;
  282. X      if (readmask & (1 << fd))
  283. X#else
  284. X      FD_ZERO(&readmask) ;
  285. X      FD_SET(fd, &readmask) ;
  286. X      SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &timeout) ;
  287. X      if (FD_ISSET(fd, &readmask))
  288. X#endif NO_4.3SELECT
  289. X
  290. X        read_rs232() ;
  291. X      else
  292. X        { 
  293. X          if (rsrhold == XOFF) do_handshake(XON) ;
  294. X          if (pkt_started)
  295. X            {
  296. X              c = NAK ;
  297. X              WRITE(fd, &c, 1) ;
  298. X              rsrstate = RSSOR ;
  299. X              pkt_started = 0 ;
  300. X            }
  301. X        }    
  302. X      if (complete || error || cancel) break ;
  303. X    }
  304. X  CLOSE(rf) ;                     /* Close temporary image file. */
  305. X  if (!error)
  306. X    {
  307. X      save_picture() ;            /* Create Sun rasterfile picture. */
  308. X      retval = 0 ;                /* Successful exit - image saved. */
  309. X    }
  310. X  else UNLINK(tempimage) ;
  311. X  CLOSE(fd) ;
  312. X}
  313. X
  314. X
  315. Xget_options(argc, argv)        /* Extract command line options. */
  316. Xint argc ;
  317. Xchar *argv[] ;
  318. X{
  319. X  char next[MAXLINE] ;    /* The next command line parameter. */
  320. X
  321. X  INC ;
  322. X  while (argc > 0)
  323. X    {
  324. X      if (argv[0][0] == '-')
  325. X        switch (argv[0][1])
  326. X          {
  327. X            case 'b' : INC ;                         /* Brightness. */
  328. X                       getparam(next, argv, "-b needs brightness value") ;
  329. X                       brightness = atoi(next) ;
  330. X                       break ;
  331. X            case 'c' : INC ;                         /* Contrast. */
  332. X                       getparam(next, argv, "-c needs contrast value") ;
  333. X                       contrast = atoi(next) ;
  334. X                       break ;
  335. X            case 'd' : INC ;                         /* Data transfer. */
  336. X                       getparam(next, argv, "-d needs data transfer value") ;
  337. X                       switches[DATA_TRANSFER] = atoi(next) ;
  338. X                       break ;
  339. X            case 'f' : INC ;                         /* Frame. */
  340. X                       getparam(next, argv, "-f needs X1 coordinate") ;
  341. X                       framevals[X1] = atoi(next) ;
  342. X                       INC ;
  343. X                       getparam(next, argv, "-f needs Y1 coordinate") ;
  344. X                       framevals[Y1] = atoi(next) ;
  345. X                       INC ;
  346. X                       getparam(next, argv, "-f needs X2 coordinate") ;
  347. X                       framevals[X2] = atoi(next) ;
  348. X                       INC ;
  349. X                       getparam(next, argv, "-f needs Y2 coordinate") ;
  350. X                       framevals[Y2] = atoi(next) ;
  351. X                       break ;
  352. X            case 'g' : INC ;                         /* Grain. */
  353. X                       getparam(next, argv, "-g needs grain value") ;
  354. X                       grain = atoi(next) ;
  355. X                       break ;
  356. X            case 'm' : INC ;                         /* Mode. */
  357. X                       getparam(next, argv, "-m needs mode value") ;
  358. X                       switches[MODE] = atoi(next) ;
  359. X                       break ;
  360. X            case 'p' : INC ;                         /* Picture name. */
  361. X                       getparam(picname, argv, "-p needs picture name") ;
  362. X                       break ;
  363. X            case 'r' : INC ;                         /* Resolution. */
  364. X                       getparam(next, argv, "-r needs resolution value") ;
  365. X                       break ;
  366. X            case 's' : INC ;              /* Speed of RS232 connection. */
  367. X                       getparam(next, argv, "-s needs speed value") ;
  368. X                       switches[BAUD_RATE] = atoi(next) ;
  369. X                       break ;
  370. X            case 't' : INC ;                         /* Tty port. */
  371. X                       getparam(next, argv, "-t needs tty port") ;
  372. X                       switches[SERIAL_PORT] = atoi(next) ;
  373. X                       break ;
  374. X            case 'v' : FPRINTF(stderr, "%s version 1.4.%1d\n",
  375. X                                       progname, PATCHLEVEL) ;
  376. X                       break ;
  377. X            case '?' : usage() ;
  378. X          }
  379. X      INC ;
  380. X    }
  381. X}
  382. X
  383. X
  384. Xgetparam(s, argv, errmes)
  385. Xchar *s, *argv[], *errmes ;
  386. X{
  387. X  if (*argv != NULL && argv[0][0] != '-') STRCPY(s, *argv) ;
  388. X  else
  389. X    { 
  390. X      FPRINTF(stderr,"%s: %s as next argument.\n", progname, errmes) ;
  391. X      exit(5) ;
  392. X    }
  393. X}
  394. X
  395. X
  396. Xinit_rs_port(port, speed)              /* Initialise RS232 port. */
  397. Xint port, speed ;
  398. X{
  399. X  char ttyline[MAXLINE] ;
  400. X  struct sgttyb sgttyb ;
  401. X  if (port) STRCPY(ttyline, "/dev/ttyb") ;
  402. X  else      STRCPY(ttyline, "/dev/ttya") ;
  403. X  if ((fd = open(ttyline,2)) < 0)
  404. X    {
  405. X      retval = 1 ;      /* Cannot open ttyline. */
  406. X      return(-1) ;
  407. X    }
  408. X  GTTY(fd, &sgttyb) ;
  409. X  sgttyb.sg_flags |= RAW ;
  410. X  sgttyb.sg_flags &= ~(ECHO | CRMOD) ;
  411. X  if (speed) sgttyb.sg_ispeed = sgttyb.sg_ospeed = EXTA ;
  412. X  else       sgttyb.sg_ispeed = sgttyb.sg_ospeed = B9600 ;
  413. X  STTY(fd, &sgttyb) ;             /* Implement tty line setup changes. */
  414. X  return(0) ;
  415. X}
  416. X
  417. X
  418. Xmake_frame_packet()        /* Construct and send scanning frame packet. */
  419. X{
  420. X  char cksum ;             /* For creating the packet checksum. */
  421. X  int i ;
  422. X
  423. X  rsdata[0] = '\\' ;       /* Construct packet. */
  424. X  rsdata[1] = 0x80 ;
  425. X  rsdata[2] = 0x00 ;
  426. X  rsdata[3] = 5 ;
  427. X  rsdata[4] = 'F' ;
  428. X  rsdata[5] = framevals[X1] ;
  429. X  rsdata[6] = framevals[Y1] ;
  430. X  rsdata[7] = framevals[X2] ;
  431. X  rsdata[8] = framevals[Y2] ;
  432. X  cksum = 0 ;
  433. X  for (i = 1; i < 9; i++) cksum += rsdata[i] ;
  434. X  rsdata[9] = (~cksum) + 1 ;
  435. X  return(send_packet('F', 10)) ;
  436. X}
  437. X
  438. X
  439. Xmake_header(width, height)       /* Make Sun rasterfile header. */
  440. Xint width, height ;
  441. X{
  442. X  struct rasterfile header ;
  443. X  FILE *hd ;                    /* File descriptor for header file. */
  444. X
  445. X  SPRINTF(temphead, "/usr/tmp/%s.header", mktemp("XXXXXX")) ;
  446. X  if ((hd = fopen(temphead,"w")) == NULL)
  447. X    {
  448. X      retval = 3 ;              /* Can't open raster header file. */
  449. X      return(-1) ;
  450. X    }
  451. X  header.ras_magic = 0x59a66a95 ;        /* Generate rasterfile header. */
  452. X  header.ras_width = width ;
  453. X  header.ras_height = height ;
  454. X  header.ras_depth = 1 ;
  455. X  header.ras_length = width * height ;
  456. X  header.ras_type = RT_STANDARD ;
  457. X  header.ras_maptype = RMT_RAW ;
  458. X  header.ras_maplength = 0 ;
  459. X  FWRITE((char *) &header, sizeof(struct rasterfile), 1, hd) ;
  460. X  FCLOSE(hd) ;
  461. X  return(0) ;
  462. X}
  463. X
  464. X
  465. Xmake_packet(ptype, count, value)   /* Sent a packet to the scanner. */
  466. Xchar ptype, count, value ;
  467. X{
  468. X  char cksum ;                     /* For creating the packet checksum. */
  469. X  int i ;
  470. X  int len ;                        /* Length of this scanner packet. */
  471. X
  472. X  len = count + 5 ;
  473. X  rsdata[0] = '\\' ;               /* Construct packet. */
  474. X  rsdata[1] = 0x80 ;
  475. X  rsdata[2] = 0x00 ;
  476. X  rsdata[3] = count ;
  477. X  rsdata[4] = ptype ;
  478. X  if (count == 2) rsdata[5] = value ;
  479. X  cksum = 0 ;
  480. X  for (i = 1; i < len-1; i++) cksum += rsdata[i] ;
  481. X  rsdata[len-1] = (~cksum) + 1 ;
  482. X  return(send_packet(ptype, len)) ;
  483. X}
  484. X
  485. X
  486. Xopen_temp_file()          /* Open a temporary file for the scanned image. */
  487. X{
  488. X  SPRINTF(tempimage, "/usr/tmp/%s.image", mktemp("XXXXXX")) ;
  489. X  if ((rf = open(tempimage, 2)) < 0)
  490. X    if ((rf = creat(tempimage, 0777)) < 0)
  491. X      {
  492. X        retval = 2 ;   /* Can't open temporary image file. */
  493. X        return(-1) ;
  494. X      }
  495. X  return(0) ;
  496. X}
  497. X
  498. X
  499. Xprocess_packet(ptype)     /* Process RS232 packet received. */
  500. Xchar ptype ;
  501. X{
  502. X  int errorval ;          /* To extract error value. */
  503. X  char outval ;           /* ACK or NAK value to be sent. */
  504. X
  505. X  if (rscksum == cksum)
  506. X    {
  507. X      outval = ACK ;
  508. X      switch (ptype)
  509. X        {
  510. X          case 'D' : if ((rsrtype >> 5) & 1) pic_compressed++ ;
  511. X                     height++ ;
  512. X                     if (!((rsrtype >> 5) & 1)) rsptr = ((rsptr >> 2) << 2) ;
  513. X                     WRITE(rf, from_rs, rsptr) ;
  514. X                     width = rsptr * 8 ;
  515. X                     break ;
  516. X          case 'E' : outval = ETX ;    /* Complete scanning and eject paper. */
  517. X                     WRITE(fd, &outval, 1) ;
  518. X                     complete = 1 ;
  519. X                     break ;
  520. X          case '!' : STRNCPY(scantype, from_rs, rsptr) ;
  521. X                     break ;
  522. X          case '?' : errorval = (from_rs[1] & 0xFF) ;
  523. X                     retval = 100 + errorval ;  /* Scanning error received. */
  524. X                     outval = ETX ;
  525. X                     WRITE(fd, &outval, 1) ;
  526. X                     error = 1 ;
  527. X        }
  528. X    }    
  529. X  else outval = NAK ;
  530. X  WRITE(fd, &outval, 1) ;        /* Send ACK or NAK. */
  531. X  pktdone = 1 ;
  532. X}
  533. X
  534. X
  535. Xread_rs232()      /* Read upto end of next packet. */
  536. X{
  537. X  char c ;        /* Next character read from RS232. */
  538. X  int count ;     /* Number of RS232 characters to read. */
  539. X  int i ;
  540. X
  541. X  IOCTL(fd,(int) FIONREAD,(char *) &count) ;   /* Any data to read. */
  542. X  if (count > MAXREAD) do_handshake(XOFF) ;
  543. X  else if (count < 20 && rsrhold == XOFF) do_handshake(XON) ;
  544. X  if (!count) return ;                         /* NO: exit routine. */
  545. X  for (i = 0; i < count; i++)
  546. X    {
  547. X      READ(fd, &c, 1) ;                        /* Read next character. */
  548. X      if (rsrstate == RSSOR && (c == ACK || c == NAK)) rswstate = c ;
  549. X      else
  550. X        switch (rsrstate)
  551. X          {
  552. X            case RSSOR   : rscksum = 0 ;
  553. X                           if (c == SOR) rsrstate = RSRTYPE ;
  554. X                           break ;
  555. X            case RSRTYPE : rsrtype = c ;
  556. X                           rscksum += c ;
  557. X                           cntbytes = 0 ;
  558. X                           rscnt = 0 ;
  559. X                           rsrstate = RSCOUNT ;
  560. X                           break ;
  561. X            case RSCOUNT : rscksum += c ;
  562. X                           rscnt = rscnt*256 + c ;
  563. X                           if (++cntbytes == 2)
  564. X                             {
  565. X                               rsrstate = RSDATA ;
  566. X                               rsptr = 0 ;
  567. X                             }
  568. X                           pkt_started = 1 ;
  569. X                           break ;
  570. X            case RSDATA  : from_rs[rsptr++] = c ;  /* Save data character. */
  571. X                           rscksum += c ;
  572. X                           if (!--rscnt) rsrstate = RSCKSUM ;
  573. X                           break ;
  574. X            case RSCKSUM : rscksum = (~rscksum) + 1 ;
  575. X                           cksum = c ;
  576. X                           if (rsrtype >> 7) process_packet(from_rs[0]) ;
  577. X                           else process_packet('D') ;
  578. X                           pkt_started = 0 ;
  579. X                           rsrstate = RSSOR ;
  580. X                           return ;
  581. X          }
  582. X    }
  583. X}
  584. X
  585. X
  586. Xsave_picture()    /* Combine header file and image to make a Sun rasterfile. */
  587. X{
  588. X  char line[MAXLINE] ;          /* For constructing the system command. */
  589. X
  590. X  if (pic_compressed)
  591. X    {
  592. X      initialise_white("white.codes") ;
  593. X      initialise_black("black.codes") ;
  594. X      uncompress(tempimage) ;
  595. X    }
  596. X  else
  597. X    { 
  598. X      if (!make_header(width, height))   /* Write out Sun rasterfile header. */
  599. X        {
  600. X          SPRINTF(line, "cat %s %s > %s", temphead, tempimage, picname) ;
  601. X          SYSTEM(line) ;                 /* Create Sun rasterfile. */
  602. X          UNLINK(temphead) ;             /* Remove header file. */
  603. X        }
  604. X      UNLINK(tempimage) ;                /* Remove image file. */
  605. X    }
  606. X}
  607. X
  608. X
  609. Xsend_packet(ptype, len)
  610. Xchar ptype,len ;
  611. X{
  612. X  int done ;        /* Packet read or ACK/NAK found. */
  613. X  int i ;
  614. X
  615. X  for (i = 0; i < MAXRETRIES; i++)
  616. X    {
  617. X      WRITE(fd, rsdata, len) ;
  618. X      rswstate = NOANSWER ;
  619. X      pktdone = 0 ;
  620. X      done = 0 ;
  621. X      do
  622. X        {
  623. X#ifdef NO_4.3SELECT
  624. X          readmask = 1 << fd ;
  625. X          SELECT(32, &readmask, (int *) 0, (int *) 0, &timeout) ;
  626. X          if (readmask & (1 << fd))
  627. X#else
  628. X          FD_ZERO(&readmask) ;
  629. X          FD_SET(fd, &readmask) ;
  630. X          SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &timeout) ;
  631. X          if (FD_ISSET(fd, &readmask))
  632. X#endif NO_4.3SELECT
  633. X            {
  634. X              read_rs232() ;
  635. X              switch (ptype)
  636. X                {
  637. X                  case '!' : if (pktdone) done = 1 ;
  638. X                             break ;
  639. X                  default  : if (rswstate == ACK || rswstate == NAK) done = 1 ;
  640. X                }
  641. X              if (done) break ;
  642. X            }
  643. X          else break ;
  644. X        }
  645. X      while (!done) ;
  646. X      if (rswstate == ACK) return(0) ;
  647. X    }
  648. X  retval = 4 ;   /* Scanner not responding. Aborting this scan. */
  649. X  CLOSE(rf) ;
  650. X  return(-1) ;
  651. X}
  652. X
  653. X
  654. Xset_signals()   /* Setup a signal handler for a range of signals. */
  655. X{
  656. X  SIGNAL(SIGHUP,  do_exit) ;
  657. X  SIGNAL(SIGQUIT, do_exit) ;
  658. X  SIGNAL(SIGILL,  do_exit) ;
  659. X  SIGNAL(SIGTRAP, do_exit) ;
  660. X  SIGNAL(SIGIOT,  do_exit) ;
  661. X  SIGNAL(SIGEMT,  do_exit) ;
  662. X  SIGNAL(SIGFPE,  do_exit) ;
  663. X  SIGNAL(SIGBUS,  do_exit) ;
  664. X  SIGNAL(SIGSEGV, do_exit) ;
  665. X}
  666. X
  667. X
  668. Xusage()
  669. X{
  670. X  FPRINTF(stderr, "Usage: %s: [-b brightness] [-c contrast] ", progname) ;
  671. X  FPRINTF(stderr, "[-d] [-f x1 y1 x2 y2] [-g grain] [-m] [-p picname]\n") ;
  672. X  FPRINTF(stderr, "[-s] [-t] [-v] [-?] [-Wi] [-Wp x y] [-WP x y]\n") ;
  673. X  exit(5) ;
  674. X}
  675. END_OF_FILE
  676. if test 19805 -ne `wc -c <'scantool/scan.c'`; then
  677.     echo shar: \"'scantool/scan.c'\" unpacked with wrong size!
  678. fi
  679. # end of 'scantool/scan.c'
  680. fi
  681. if test -f 'scantool/sunview.c' -a "${1}" != "-c" ; then 
  682.   echo shar: Will not clobber existing file \"'scantool/sunview.c'\"
  683. else
  684. echo shar: Extracting \"'scantool/sunview.c'\" \(13868 characters\)
  685. sed "s/^X//" >'scantool/sunview.c' <<'END_OF_FILE'
  686. X/*  @(#)sunview.c 1.4 90/04/04
  687. X *
  688. X *  SunView dependent graphics routines used by scantool.
  689. X *
  690. X *  Copyright (c) Rich Burridge.
  691. X *                Sun Microsystems, Australia - All rights reserved.
  692. X *
  693. X *  Permission is given to distribute these sources, as long as the
  694. X *  copyright messages are not removed, and no monies are exchanged.
  695. X *
  696. X *  No responsibility is taken for any errors or inaccuracies inherent
  697. X *  either to the comments or the code of this program, but if
  698. X *  reported to me, then an attempt will be made to fix them.
  699. X */
  700. X
  701. X#include <stdio.h>
  702. X#include <sys/fcntl.h>
  703. X#include <sys/wait.h>
  704. X#include <sys/time.h>
  705. X#include <sys/resource.h>
  706. X#include "scantool.h"
  707. X#include "images.h"
  708. X#include "scantool_extern.h"
  709. X#include <suntool/sunview.h>
  710. X#include <suntool/canvas.h>
  711. X
  712. X#define  MENU_SET                       (void) menu_set
  713. X#define  NOTIFY_DISPATCH                (void) notify_dispatch
  714. X#define  NOTIFY_INTERPOSE_DESTROY_FUNC  (void) notify_interpose_destroy_func
  715. X#define  NOTIFY_INTERPOSE_EVENT_FUNC    (void) notify_interpose_event_func
  716. X#define  NOTIFY_SET_WAIT3_FUNC          (void) notify_set_wait3_func
  717. X#define  PR_DESTROY                     (void) pr_destroy
  718. X#define  PW_REPLROP                     (void) pw_replrop
  719. X#define  PW_ROP                         (void) pw_rop
  720. X#define  PW_TEXT                        (void) pw_text
  721. X#define  PW_TTEXT                       (void) pw_ttext
  722. X#define  PW_VECTOR                      (void) pw_vector
  723. X#define  PW_WRITEBACKGROUND             (void) pw_writebackground
  724. X#define  WINDOW_READ_EVENT              (void) window_read_event
  725. X#define  WINDOW_SET                     (void) window_set
  726. X
  727. X/* Fonts used by scantool. */
  728. X#define  BOLD_FONT      "/usr/lib/fonts/fixedwidthfonts/screen.b.14"
  729. X#define  NORMAL_FONT    "/usr/lib/fonts/fixedwidthfonts/screen.r.14"
  730. X
  731. Xstruct pixfont *open_font() ;
  732. Xvoid repaint_show_canvas() ;
  733. X
  734. XCanvas canvas, show_canvas ;
  735. XCursor cursor[MAXCURSORS] ;
  736. XEvent *cur_event ;
  737. XFrame base_frame, show_frame ;
  738. XIcon scantool_icon ;
  739. XMenu menus[MAXMENUS] ;
  740. XNotify_value destroy(), handle_resize() ;
  741. XPixfont *font[MAXFONTS] ;
  742. XPixrect *images[MAXIMAGES] ;
  743. XPixrect *spr ;
  744. XPixwin *spw, *wpw ;
  745. X
  746. Xint firsttime ;      /* Set if we haven't resized the window yet. */
  747. Xint init_height ;    /* Initial height of the scantool window. */
  748. Xint init_width ;     /* Initial width of the scantool window. */
  749. X
  750. Xstruct rasterfile hdr ;
  751. X
  752. Xmpr_static(grey_pr,          16, 16, 1, grey_image) ;
  753. Xmpr_static(icon_pr,          64, 64, 1, icon_image) ;
  754. Xmpr_static(exclaim_pr,       64, 64, 1, exclaim_image) ;
  755. Xmpr_static(button_normal_pr, 64, 64, 1, button_normal_image) ;
  756. Xmpr_static(button_invert_pr, 64, 64, 1, button_invert_image) ;
  757. Xmpr_static(switch_normal_pr, 16, 16, 1, switch_normal_image) ;
  758. Xmpr_static(switch_invert_pr, 16, 16, 1, switch_invert_image) ;
  759. Xmpr_static(main_cursor_pr,   16, 16, 1, main_cursor_array) ;
  760. Xmpr_static(hour_cursor_pr,   16, 16, 1, hour_cursor_array) ;
  761. Xmpr_static(help_cursor_pr,   16, 16, 1, help_cursor_array) ;
  762. Xmpr_static(frame_cursor_pr,  16, 16, 1, frame_cursor_array) ;
  763. X
  764. X/*ARGSUSED*/
  765. Xvoid
  766. Xcanvas_proc(canvas, event)
  767. XCanvas canvas ;
  768. XEvent *event ;
  769. X{
  770. X  cur_event = event ;
  771. X  handle_event() ;       /* Determine what kind of event it is. */
  772. X  process_event() ;      /* And process it. */
  773. X}
  774. X
  775. Xcreate_menu(mtype, title, values)    /* Create popup menus for cycle items. */
  776. Xenum menu_type mtype ;
  777. Xchar *title, *values[] ;
  778. X{
  779. X  int i = 0 ;
  780. X  int more = 1 ;   /* Cleared when current menu is complete.*/
  781. X
  782. X  menus[(int) mtype] = menu_create(MENU_TITLE_ITEM, title,
  783. X                                   MENU_FONT,       font[(int) NFONT],
  784. X                                   0) ;
  785. X  do
  786. X    {
  787. X      if (values[i] != NULL)
  788. X        MENU_SET(menus[(int) mtype], MENU_STRING_ITEM, values[i], i+1, 0) ;
  789. X      else more = 0 ;
  790. X      i++ ;
  791. X    }
  792. X  while (more) ;
  793. X}
  794. X
  795. X/*ARGSUSED*/
  796. XNotify_value
  797. Xdestroy(client, status)
  798. XNotify_client client ;
  799. XDestroy_status status ;
  800. X{
  801. X  stop_scan() ;        /* Stop the current scan (if there is one). */
  802. X  exit(0) ;
  803. X}
  804. X
  805. Xdisplay_menu(menuno)
  806. Xenum menu_type menuno ;
  807. X{
  808. X  return((int) menu_show(menus[(int) menuno], canvas,
  809. X                         canvas_window_event(canvas, cur_event), 0)) ;
  810. X}
  811. X
  812. Xdraw_area(x, y, width, height, op)
  813. Xint x, y, width, height ;
  814. Xenum op_type op ;
  815. X{
  816. X  PW_WRITEBACKGROUND(wpw, x, y, width, height, ops[(int) op]) ;
  817. X}
  818. X
  819. Xdraw_image(x, y, width, height, image)
  820. Xint x, y, width, height ;
  821. Xenum image_type image ;
  822. X{
  823. X  PW_ROP(wpw, x, y, width, height, PIX_SRC, images[(int) image], 0, 0) ;
  824. X}
  825. X
  826. Xdraw_line(x1, y1, x2, y2, op)
  827. Xint x1, y1, x2, y2 ;
  828. Xenum op_type op ;
  829. X{
  830. X  PW_VECTOR(wpw, x1, y1, x2, y2, ops[(int) op], 1) ;
  831. X}
  832. X
  833. Xdraw_text(x, y, stencil, ftype, str)
  834. Xint x, y ;
  835. Xenum sten_type stencil ;
  836. Xenum font_type ftype ;
  837. Xchar *str ;
  838. X{
  839. X  switch (stencil)
  840. X    {
  841. X      case STEN_OFF : PW_TEXT(wpw,  x, y, PIX_SRC, font[(int) ftype], str) ;
  842. X                      break ;
  843. X      case STEN_ON  : PW_TTEXT(wpw, x, y, PIX_SET, font[(int) ftype], str) ;
  844. X                      break ;
  845. X      case STEN_INV : PW_TTEXT(wpw, x, y, PIX_CLR, font[(int) ftype], str) ;
  846. X    }
  847. X}
  848. X
  849. Xget_event()       /* Get the next SunView event. */
  850. X{
  851. X  WINDOW_READ_EVENT(canvas, cur_event) ;
  852. X}
  853. X
  854. Xget_strwidth(ftype, str)    /* Get width in pixels of string value. */
  855. Xenum font_type ftype ;
  856. Xchar *str ;
  857. X{
  858. X  struct pr_size size ;
  859. X
  860. X  size = pf_textwidth(strlen(str), font[(int) ftype], str) ;
  861. X  return(size.x) ;
  862. X}
  863. X
  864. Xgrey_area(x, y, width, height)
  865. X{
  866. X  PW_REPLROP(wpw, x, y, width, height, PIX_SRC, &grey_pr, 0, 0) ;
  867. X}
  868. X
  869. Xhandle_event()        /* Work out what kind of event this is. */
  870. X{
  871. X  curx = event_x(cur_event) ;
  872. X  cury = event_y(cur_event) ;
  873. X  cur_ch = event_id(cur_event) ;
  874. X
  875. X  if (event_is_button(cur_event) && event_is_down(cur_event))
  876. X    {
  877. X           if (cur_ch == MS_LEFT)     type = LEFT_DOWN ;
  878. X      else if (cur_ch == MS_MIDDLE)   type = MIDDLE_DOWN ;
  879. X      else if (cur_ch == MS_RIGHT)    type = RIGHT_DOWN ;
  880. X    }
  881. X  else if (event_is_button(cur_event) && event_is_up(cur_event))
  882. X    {
  883. X           if (cur_ch == MS_LEFT)     type = LEFT_UP ;
  884. X      else if (cur_ch == MS_MIDDLE)   type = MIDDLE_UP ;
  885. X      else if (cur_ch == MS_RIGHT)    type = RIGHT_UP ;
  886. X    }
  887. X  else if (event_is_ascii(cur_event)) type = KEYBOARD ;
  888. X  else if (cur_ch == LOC_MOVE)        type = MOUSE_MOVE ;
  889. X  else if (cur_ch == LOC_DRAG)        type = MOUSE_DRAG ;
  890. X  else if (cur_ch == WIN_REPAINT)     type = REPAINT ;
  891. X  else                                type = IGNORE ;
  892. X}
  893. X
  894. XNotify_value
  895. Xhandle_resize(frame, event, arg, type)
  896. XFrame frame ;
  897. XEvent *event ;
  898. XNotify_arg arg ;
  899. XNotify_event_type type ;
  900. X{
  901. X  Notify_value value ;
  902. X  Rect *r ;
  903. X
  904. X  value = notify_next_event_func(frame, (Notify_event) event, arg, type) ;
  905. X  if (event_id(event) == WIN_RESIZE)
  906. X    if (firsttime)
  907. X      {
  908. X        init_width = (int) window_get(base_frame, WIN_WIDTH) ;
  909. X        init_height = (int) window_get(base_frame, WIN_HEIGHT) ;
  910. X        firsttime = 0 ;
  911. X      }
  912. X    else
  913. X      {
  914. X        r = (Rect *) LINT_CAST(window_get(frame, WIN_RECT)) ;
  915. X        r->r_width  = init_width ;
  916. X        r->r_height = init_height ;
  917. X        WINDOW_SET(frame, FRAME_OPEN_RECT, r, 0) ;
  918. X        do_repaint() ;
  919. X      }   
  920. X  return(value) ;
  921. X}
  922. X
  923. Xinit_fonts()
  924. X{
  925. X  font[(int) NFONT] = open_font(NORMAL_FONT) ;
  926. X  font_width = font[(int) NFONT]->pf_defaultsize.x ;
  927. X  font[(int) BFONT] = open_font(BOLD_FONT) ;
  928. X}
  929. X
  930. Xinit_ws_type()
  931. X{
  932. X  ops[(int) GSET] = PIX_SET ;
  933. X  ops[(int) GCLR] = PIX_CLR ;
  934. X  ops[(int) GXOR] = PIX_SRC ^ PIX_DST ;
  935. X  ops[(int) GSRC] = PIX_SRC ;
  936. X  ops[(int) GOR]  = PIX_SRC | PIX_DST ;
  937. X  ops[(int) GNOT] = PIX_NOT(PIX_DST) ;
  938. X
  939. X  firsttime = 1 ;
  940. X}
  941. X
  942. Xmake_frames(argc, argv)
  943. Xint argc ;
  944. Xchar *argv[] ;
  945. X{
  946. X  scantool_icon = icon_create(ICON_IMAGE, &icon_pr, 0) ;
  947. X  base_frame = window_create((Window) 0,           FRAME,
  948. X                             FRAME_ICON,           scantool_icon,
  949. X                             FRAME_LABEL,          progname,
  950. X                             FRAME_EMBOLDEN_LABEL, TRUE,
  951. X                             FRAME_ARGS,           argc,argv,
  952. X                             0) ;
  953. X
  954. X  show_frame = window_create(base_frame,       FRAME,
  955. X                             FRAME_SHOW_LABEL, TRUE,
  956. X                             WIN_WIDTH,        650,
  957. X                             WIN_HEIGHT,       900,
  958. X                             WIN_X,            0,
  959. X                             WIN_Y,            0,
  960. X                             WIN_SHOW,         FALSE,
  961. X                             0) ;
  962. X  NOTIFY_INTERPOSE_EVENT_FUNC(base_frame, handle_resize, NOTIFY_SAFE) ;
  963. X}
  964. X
  965. Xmake_subframes()
  966. X{
  967. X  cursor[(int) FRAME_CUR] = cursor_create(CURSOR_IMAGE, &frame_cursor_pr,
  968. X                                          CURSOR_XHOT,  7,
  969. X                                          CURSOR_YHOT,  7,
  970. X                                          0) ;
  971. X  cursor[(int) HELP_CUR]  = cursor_create(CURSOR_IMAGE, &help_cursor_pr, 0) ;
  972. X  cursor[(int) HOUR_CUR]  = cursor_create(CURSOR_IMAGE, &hour_cursor_pr, 0) ;
  973. X  cursor[(int) MAIN_CUR]  = cursor_create(CURSOR_IMAGE, &main_cursor_pr, 0) ;
  974. X  canvas = window_create(base_frame, CANVAS,
  975. X                         WIN_EVENT_PROC,      canvas_proc,
  976. X                         WIN_CURSOR,          cursor[(int) MAIN_CUR],
  977. X                         WIN_WIDTH,           SCAN_WIDTH,
  978. X                         WIN_HEIGHT,          SCAN_HEIGHT,
  979. X                         CANVAS_RETAINED,     FALSE,
  980. X                         CANVAS_FIXED_IMAGE,  FALSE,
  981. X                         0) ;
  982. X  WINDOW_SET(canvas, WIN_CONSUME_KBD_EVENTS, WIN_ASCII_EVENTS,
  983. X                     WIN_UP_EVENTS, 0, 0) ;
  984. X  WINDOW_SET(canvas, WIN_CONSUME_PICK_EVENTS, LOC_DRAG, LOC_MOVE, 0, 0) ;
  985. X  wpw = canvas_pixwin(canvas) ;
  986. X
  987. X  show_canvas = window_create(show_frame, CANVAS,
  988. X                              CANVAS_REPAINT_PROC, repaint_show_canvas,
  989. X                              0) ;
  990. X  spw = canvas_pixwin(show_canvas) ;
  991. X  spr = NULL ;
  992. X
  993. X  images[(int) B_NORMAL]      = &button_normal_pr ;
  994. X  images[(int) B_INVERT]      = &button_invert_pr ;
  995. X  images[(int) S_NORMAL]      = &switch_normal_pr ;
  996. X  images[(int) S_INVERT]      = &switch_invert_pr ;
  997. X  images[(int) EXCLAIM_IMAGE] = &exclaim_pr ;
  998. X}
  999. X
  1000. XPixfont *
  1001. Xopen_font(fontname)
  1002. Xchar *fontname ;
  1003. X{
  1004. X  Pixfont *f ;
  1005. X
  1006. X  if ((f = pf_open(fontname)) == NULL)
  1007. X    if ((f = pf_default()) == NULL)
  1008. X      {
  1009. X        perror("couldn't get the default font.") ;
  1010. X        exit(1) ;
  1011. X      }
  1012. X  return(f) ;
  1013. X}
  1014. X
  1015. X/*ARGSUSED*/
  1016. Xvoid
  1017. Xrepaint_show_canvas(canvas, pw, repaint_area)     /* Show current picture. */
  1018. XCanvas canvas ;
  1019. XPixwin *pw ;
  1020. XRectlist *repaint_area ;
  1021. X{
  1022. X  PW_ROP(pw, 0, 0, hdr.ras_width, hdr.ras_height, PIX_SRC, spr, 0, 0) ;
  1023. X}
  1024. X
  1025. Xset_cursor(ctype)
  1026. Xenum cur_type ctype ;
  1027. X{
  1028. X  WINDOW_SET(canvas, WIN_CURSOR, cursor[(int) ctype], 0) ;
  1029. X}
  1030. X
  1031. Xshow()      /* Display scanned image. */
  1032. X{
  1033. X  Rect *temprect ;
  1034. X  char errmes[MAXLINE] ;
  1035. X  int fd ;
  1036. X
  1037. X  showing = 1 ;
  1038. X  make_button(SCAN_WIDTH-150, 4*SWITCH_HEIGHT+100, "Show", B_INVERT) ;
  1039. X  if (spr) PR_DESTROY(spr) ;
  1040. X  if ((fd = open(picname, O_RDONLY | O_NDELAY, 0644)) == -1)
  1041. X    {
  1042. X      SPRINTF(errmes, "Cannot open %s.", picname) ;
  1043. X      make_display(errmes) ;
  1044. X    }
  1045. X  else
  1046. X    { 
  1047. X      READ(fd, (char *) &hdr, sizeof(struct rasterfile)) ;
  1048. X      if (hdr.ras_maplength)
  1049. X        {
  1050. X          make_display("Color rasterfiles currently not supported.") ;
  1051. X          return ;
  1052. X        }
  1053. X      spr = mem_create(hdr.ras_width, hdr.ras_height, hdr.ras_depth) ;
  1054. X      READ(fd, (char *) (mpr_d(spr)->md_image),
  1055. X           hdr.ras_width * hdr.ras_height) ;
  1056. X      CLOSE(fd) ;
  1057. X      temprect = (Rect *) LINT_CAST(window_get(show_frame, FRAME_OPEN_RECT)) ;
  1058. X      temprect->r_left = temprect->r_top = 0 ;
  1059. X      temprect->r_height = hdr.ras_height ;
  1060. X      temprect->r_width = hdr.ras_width ;
  1061. X      WINDOW_SET(show_frame, FRAME_OPEN_RECT, temprect, 0) ;
  1062. X      WINDOW_SET(show_frame, FRAME_LABEL, picname, 0) ;
  1063. X      WINDOW_SET(show_frame, WIN_SHOW, TRUE, 0) ;
  1064. X    }
  1065. X  make_button(SCAN_WIDTH-150, 4*SWITCH_HEIGHT+100, "Show", B_NORMAL) ;
  1066. X  showing = 0 ;
  1067. X}
  1068. X
  1069. Xstart_tool()
  1070. X{
  1071. X  window_fit(base_frame) ;
  1072. X  NOTIFY_INTERPOSE_DESTROY_FUNC(base_frame, destroy) ;
  1073. X  window_main_loop(base_frame) ;
  1074. X}
  1075. X
  1076. X/*ARGSUSED*/
  1077. XNotify_value
  1078. Xwait_child(frame, pid, status, rusage)
  1079. XWindow frame ;
  1080. Xint pid ;
  1081. Xunion wait *status ;
  1082. Xstruct rusage *rusage ;
  1083. X{
  1084. X  char output[MAXLINE] ;
  1085. X  int high, low ;
  1086. X
  1087. X  if (WIFSTOPPED(*status)) return (NOTIFY_IGNORED) ;
  1088. X
  1089. X  high = (status->w_status & 0xFF00) >> 8 ;
  1090. X  low = status->w_status & 0xFF ;
  1091. X  if (low) SPRINTF(output, "Scan: terminated with signal %1d", (low & 0x3F)) ;
  1092. X  else
  1093. X    {
  1094. X      switch (high)
  1095. X        {
  1096. X          case 0  : SPRINTF(output, "Scan: successful. %s saved",
  1097. X                                     picname) ;
  1098. X                    break ;
  1099. X          case 1  : SPRINTF(output, "Scan: cannot open tty port %c",
  1100. X                                     switches[SERIAL_PORT] + 'A') ;
  1101. X                    break ;
  1102. X          case 2  : SPRINTF(output, "Scan: cannot open temporary image file") ;
  1103. X                    break ;
  1104. X          case 3  : SPRINTF(output, "Scan: cannot open raster header file") ;
  1105. X                    break ;
  1106. X          case 4  : SPRINTF(output, "Scan: scanner not responding; aborting") ;
  1107. X                    break ;
  1108. X          case 5  : SPRINTF(output, "Scan: invalid command line argument") ;
  1109. X                    break ;
  1110. X          default : if (high >= 100 && high < 200)
  1111. X                      SPRINTF(output, "Scan: scanner error %1d; aborting",
  1112. X                                       high - 100) ;
  1113. X                    else
  1114. X                      SPRINTF(output, "Scan: terminated with signal %1d",
  1115. X                                       high - 200) ;
  1116. X        }
  1117. X    }
  1118. X  make_display(output) ;
  1119. X  make_button(SCAN_WIDTH-150, 4*SWITCH_HEIGHT+20, "Scan",   B_NORMAL) ;
  1120. X  make_button(SCAN_WIDTH-150, 4*SWITCH_HEIGHT+60, "Cancel", B_NORMAL) ;
  1121. X  scanning = 0 ;
  1122. X  return (NOTIFY_DONE) ;
  1123. X}
  1124. X
  1125. Xwait_on_child(pid)      /* Wait on child scan process. */
  1126. Xint pid ;
  1127. X{
  1128. X  NOTIFY_SET_WAIT3_FUNC(base_frame, wait_child, pid) ;
  1129. X}
  1130. END_OF_FILE
  1131. if test 13868 -ne `wc -c <'scantool/sunview.c'`; then
  1132.     echo shar: \"'scantool/sunview.c'\" unpacked with wrong size!
  1133. fi
  1134. # end of 'scantool/sunview.c'
  1135. fi
  1136. if test -f 'scantool/switch.normal.cursor' -a "${1}" != "-c" ; then 
  1137.   echo shar: Will not clobber existing file \"'scantool/switch.normal.cursor'\"
  1138. else
  1139. echo shar: Extracting \"'scantool/switch.normal.cursor'\" \(193 characters\)
  1140. sed "s/^X//" >'scantool/switch.normal.cursor' <<'END_OF_FILE'
  1141. X/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16
  1142. X */
  1143. X    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFFE0,0x8020,
  1144. X    0x8020,0x8020,0x8020,0x8020,0x8020,0x8020,0x8020,0xFFE0
  1145. END_OF_FILE
  1146. if test 193 -ne `wc -c <'scantool/switch.normal.cursor'`; then
  1147.     echo shar: \"'scantool/switch.normal.cursor'\" unpacked with wrong size!
  1148. fi
  1149. # end of 'scantool/switch.normal.cursor'
  1150. fi
  1151. if test -f 'scantool/xview.c' -a "${1}" != "-c" ; then 
  1152.   echo shar: Will not clobber existing file \"'scantool/xview.c'\"
  1153. else
  1154. echo shar: Extracting \"'scantool/xview.c'\" \(16921 characters\)
  1155. sed "s/^X//" >'scantool/xview.c' <<'END_OF_FILE'
  1156. X
  1157. X/*  @(#)xview.c 1.5 90/04/10
  1158. X *
  1159. X *  XView dependent graphics routines used by scantool.
  1160. X *
  1161. X *  Copyright (c) Rich Burridge.
  1162. X *                Sun Microsystems, Australia - All rights reserved.
  1163. X *
  1164. X *  Permission is given to distribute these sources, as long as the
  1165. X *  copyright messages are not removed, and no monies are exchanged.
  1166. X *
  1167. X *  No responsibility is taken for any errors or inaccuracies inherent
  1168. X *  either to the comments or the code of this program, but if
  1169. X *  reported to me, then an attempt will be made to fix them.
  1170. X */
  1171. X
  1172. X#include <stdio.h>
  1173. X#include <sys/fcntl.h>
  1174. X#include <sys/wait.h>
  1175. X#include <sys/time.h>
  1176. X#include <sys/resource.h>
  1177. X#include "scantool.h"
  1178. X#include "scantool_extern.h"
  1179. X#include "images.h"
  1180. X#include <rasterfile.h>
  1181. X#include <xview/xview.h>
  1182. X#include <xview/canvas.h>
  1183. X#include <xview/font.h>
  1184. X#include <xview/fullscreen.h>
  1185. X#include <xview/cursor.h>
  1186. X#include <xview/svrimage.h>
  1187. X#include <X11/Xlib.h>
  1188. X
  1189. X#define  NOTIFY_INTERPOSE_DESTROY_FUNC  (void) notify_interpose_destroy_func
  1190. X#define  NOTIFY_SET_SIGNAL_FUNC         (void) notify_set_signal_func
  1191. X#define  NOTIFY_SET_WAIT3_FUNC          (void) notify_set_wait3_func
  1192. X#define  PR_DESTROY                     (void) pr_destroy
  1193. X#define  PW_WRITE                       (void) pw_write
  1194. X#define  XV_INPUT_READEVENT             (void) xv_input_readevent
  1195. X#define  XV_SET                         (void) xv_set
  1196. X
  1197. X#define  BOLDFONT    "lucidasanstypewriter-bold-12"
  1198. X#define  DEFFONT     "fixed"
  1199. X#define  NORMALFONT  "lucidasanstypewriter-12"
  1200. X
  1201. Xint menu_proc() ;
  1202. Xvoid repaint_show_canvas() ;
  1203. X
  1204. XCanvas canvas, show_canvas ;
  1205. XCanvas_paint_window spw, wpw ;
  1206. XEvent *cur_event ;
  1207. XFrame base_frame, show_frame ;
  1208. XFullscreen fs ;
  1209. XIcon scantool_icon ;
  1210. XMenu menus[MAXMENUS] ;
  1211. XNotify_value destroy() ;
  1212. XPixrect *spr ;
  1213. XServer_image frame_cursor_pr, help_cursor_pr, hour_cursor_pr, main_cursor_pr ;
  1214. XServer_image make_server_image() ;
  1215. X
  1216. XXv_cursor cursor[MAXCURSORS] ;
  1217. X
  1218. XDisplay *dpy ;                  /* Display id of scantool frame. */
  1219. XDrawable xid ;                  /* Xid for scantool canvas. */
  1220. XDrawable grey_pr ;
  1221. XDrawable images[MAXIMAGES] ;    /* Xids for various graphical images. */
  1222. XGC backgc ;                     /* Graphics context for pw_writebackground. */
  1223. XGC gc ;                         /* Graphics context for text and lines. */
  1224. XGC ropgc ;                      /* Graphics context for rops. */
  1225. XWindow root ;
  1226. XXFontStruct *font[MAXFONTS] ;   /* Xlib handles to the fonts. */
  1227. XXGCValues gc_val ;              /* Used to setup graphics context values. */
  1228. Xint gc_flags ;                  /* Used to set up graphics context flags. */
  1229. Xint screen ;                    /* Default graphics display screen. */
  1230. Xunsigned long backgnd ;         /* Default background color. */
  1231. Xunsigned long foregnd ;         /* Default foreground color. */
  1232. Xunsigned long gc_mask ;         /* Mask for setting graphic context values. */
  1233. X
  1234. Xenum menu_type cur_menu ;     /* Current menu type being processed. */
  1235. X
  1236. Xint init_height ;             /* Initial height of the scantool window. */
  1237. Xint init_width ;              /* Initial width of the scantool window. */
  1238. Xint started ;                 /* Kludge to correct handle repaints. */
  1239. X
  1240. Xstruct rasterfile hdr ;
  1241. X
  1242. Xmpr_static(icon_pr, 64, 64, 1, icon_image) ;
  1243. X
  1244. X/*ARGSUSED*/
  1245. Xvoid
  1246. Xcanvas_proc(canvas, event)
  1247. XCanvas canvas ;
  1248. XEvent *event ;
  1249. X{
  1250. X  if (!started) return ;
  1251. X  cur_event = event ;
  1252. X  handle_event() ;       /* Determine what kind of event it is. */
  1253. X  process_event() ;      /* And process it. */
  1254. X}
  1255. X
  1256. Xcreate_menu(mtype, title, values)    /* Create popup menus for cycle items. */
  1257. Xenum menu_type mtype ;
  1258. Xchar *title, *values[] ;
  1259. X{
  1260. X  int i = 0 ;
  1261. X  int more = 1 ;   /* Cleared when current menu is complete.*/
  1262. X
  1263. X  menus[(int) mtype] = xv_create(XV_NULL,          MENU_COMMAND_MENU,
  1264. X                                 MENU_NOTIFY_PROC, menu_proc,
  1265. X                                 MENU_TITLE_ITEM,  title,
  1266. X                                 0) ;
  1267. X  do
  1268. X    {
  1269. X      if (values[i] != NULL)
  1270. X        XV_SET(menus[(int) mtype], MENU_STRING_ITEM, values[i], i+1, 0) ;
  1271. X      else more = 0 ;
  1272. X      i++ ;
  1273. X    }
  1274. X  while (more) ;
  1275. X}
  1276. X
  1277. XNotify_value
  1278. Xdestroy(client, status)
  1279. XNotify_client client ;
  1280. XDestroy_status status ;
  1281. X{
  1282. X  stop_scan() ;        /* Stop the current scan (if there is one). */
  1283. X  exit(0) ;
  1284. X}
  1285. X
  1286. Xdisplay_menu(menuno)
  1287. Xenum menu_type menuno ;
  1288. X{
  1289. X  cur_menu = menuno ;
  1290. X  menu_show(menus[(int) menuno], canvas, cur_event, 0) ;
  1291. X  return(0) ;
  1292. X}
  1293. X
  1294. Xdraw_area(x, y, width, height, op)
  1295. Xint x, y, width, height ;
  1296. Xenum op_type op ;
  1297. X{
  1298. X  if (op == GNOT)
  1299. X    {
  1300. X      XSetFunction(dpy, gc, GXcopyInverted) ;
  1301. X      XCopyArea(dpy, xid, xid, gc, x, y, width, height, x, y) ;
  1302. X    }
  1303. X  else
  1304. X    {
  1305. X      XSetFunction(dpy, backgc, ops[(int) op]) ;
  1306. X      XFillRectangle(dpy, xid, backgc, x, y, width, height) ;
  1307. X    }
  1308. X}
  1309. X
  1310. Xdraw_image(x, y, width, height, image)
  1311. Xint x, y, width, height ;
  1312. Xenum image_type image ;
  1313. X{
  1314. X  gc_mask = GCStipple | GCTileStipXOrigin | GCTileStipYOrigin ;
  1315. X  gc_val.stipple = images[(int) image] ;
  1316. X  gc_val.ts_x_origin = x ;
  1317. X  gc_val.ts_y_origin = y ;
  1318. X  XChangeGC(dpy, ropgc, gc_mask, &gc_val) ;
  1319. X  XFillRectangle(dpy, xid, ropgc, x, y, width, height) ;
  1320. X}
  1321. X
  1322. Xdraw_line(x1, y1, x2, y2, op)
  1323. Xint x1, y1, x2, y2 ;
  1324. Xenum op_type op ;
  1325. X{
  1326. X  gc_val.foreground = foregnd ;
  1327. X  gc_val.function = ops[(int) op] ;
  1328. X  XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
  1329. X  XDrawLine(dpy, xid, gc, x1, y1, x2, y2) ;
  1330. X}
  1331. X
  1332. X/*ARGSUSED*/
  1333. Xdraw_text(x, y, stencil, ftype, str)
  1334. Xint x, y ;
  1335. Xenum sten_type stencil ;
  1336. Xenum font_type ftype ;
  1337. Xchar *str ;
  1338. X{
  1339. X  gc_val.foreground = foregnd ;
  1340. X  gc_val.font = font[(int) ftype]->fid ;
  1341. X  if (stencil == STEN_INV) gc_val.function = GXcopyInverted ;
  1342. X  else                     gc_val.function = GXcopy ;
  1343. X  XChangeGC(dpy, gc, GCFont | GCForeground | GCFunction, &gc_val) ;
  1344. X  XDrawString(dpy, xid, gc, x, y, str, strlen(str)) ;
  1345. X}
  1346. X
  1347. Xget_event()       /* Get the next XView event. */
  1348. X{
  1349. X  XV_INPUT_READEVENT(wpw, cur_event, 1, 0, NULL) ;
  1350. X  if (event_is_button(cur_event))
  1351. X    if (event_is_down(cur_event))
  1352. X      fs = xv_create(wpw, FULLSCREEN,
  1353. X                     WIN_CONSUME_EVENTS,
  1354. X                       WIN_MOUSE_BUTTONS, LOC_DRAG, 0,
  1355. X                     0) ;
  1356. X    else if (event_is_up(cur_event)) xv_destroy(fs) ;
  1357. X}
  1358. X
  1359. XXFontStruct *
  1360. Xget_font(name)
  1361. Xchar *name ;
  1362. X{
  1363. X  XFontStruct *f ;
  1364. X  if (!(f = XLoadQueryFont(dpy, name)))
  1365. X    if (!(f = XLoadQueryFont(dpy, DEFFONT)))
  1366. X      {
  1367. X        FPRINTF(stderr, "%s: couldn't get the default font.", progname) ;
  1368. X        exit(1) ;
  1369. X      }
  1370. X  return(f) ;
  1371. X}
  1372. X
  1373. Xget_strwidth(ftype, str)    /* Get width in pixels of string value. */
  1374. Xenum font_type ftype ;
  1375. Xchar *str ;
  1376. X{
  1377. X  return(XTextWidth(font[(int) ftype], str, strlen(str))) ;
  1378. X}
  1379. X
  1380. Xgrey_area(x, y, width, height)
  1381. X{
  1382. X  gc_mask = GCStipple | GCTileStipXOrigin | GCTileStipYOrigin ;
  1383. X  gc_val.stipple = grey_pr ;
  1384. X  gc_val.ts_x_origin = x % 16 ;
  1385. X  gc_val.ts_y_origin = y % 16 ;
  1386. X  XChangeGC(dpy, ropgc, gc_mask, &gc_val) ;
  1387. X  XFillRectangle(dpy, xid, ropgc, x, y, width, height) ;
  1388. X}
  1389. X
  1390. Xhandle_event()        /* Work out what kind of event this is. */
  1391. X{
  1392. X  curx = event_x(cur_event) ;
  1393. X  cury = event_y(cur_event) ;
  1394. X  cur_ch = event_id(cur_event) ;
  1395. X
  1396. X       if (cur_ch == LOC_WINENTER)   win_set_kbd_focus(canvas, xid) ;
  1397. X  else if (cur_ch == WIN_REPAINT)    type = REPAINT ;
  1398. X  else if (cur_ch == LOC_MOVE)       type = MOUSE_MOVE ;
  1399. X  else if (cur_ch == LOC_DRAG)       type = MOUSE_DRAG ;
  1400. X  else if (event_is_button(cur_event) && event_is_down(cur_event))
  1401. X    {
  1402. X           if (cur_ch == MS_LEFT)    type = LEFT_DOWN ;
  1403. X      else if (cur_ch == MS_MIDDLE)  type = MIDDLE_DOWN ;
  1404. X      else if (cur_ch == MS_RIGHT)   type = RIGHT_DOWN ;
  1405. X    }
  1406. X  else if (event_is_button(cur_event) && event_is_up(cur_event))
  1407. X    {
  1408. X           if (cur_ch == MS_LEFT)    type = LEFT_UP ;
  1409. X      else if (cur_ch == MS_MIDDLE)  type = MIDDLE_UP ;
  1410. X      else if (cur_ch == MS_RIGHT)   type = RIGHT_UP ;
  1411. X    }
  1412. X  else if (event_is_ascii(cur_event) &&
  1413. X           event_is_down(cur_event)) type = KEYBOARD ;
  1414. X  else                               type = IGNORE ;
  1415. X}
  1416. X
  1417. Xinit_fonts()
  1418. X{
  1419. X  font[(int) NFONT] = get_font(NORMALFONT) ;
  1420. X  font_width = font[(int) NFONT]->max_bounds.rbearing -
  1421. X               font[(int) NFONT]->min_bounds.lbearing ;
  1422. X  font[(int) BFONT] = get_font(BOLDFONT) ;
  1423. X}
  1424. X
  1425. Xinit_ws_type()
  1426. X{
  1427. X  ops[(int) GSET] = GXset ;
  1428. X  ops[(int) GCLR] = GXclear ;
  1429. X  ops[(int) GXOR] = GXxor ;
  1430. X  ops[(int) GSRC] = GXcopy ;
  1431. X  ops[(int) GOR]  = GXor ;
  1432. X  ops[(int) GNOT] = GXcopyInverted ;
  1433. X
  1434. X  started = 0 ;      /* Kludge to correctly handle repaints. */
  1435. X}
  1436. X
  1437. Xmake_frames(argc, argv)
  1438. Xint argc ;
  1439. Xchar *argv[] ;
  1440. X{
  1441. X  xv_init(XV_INIT_ARGS, argc, argv, 0) ;
  1442. X  scantool_icon = xv_create(XV_NULL, ICON,
  1443. X                            ICON_IMAGE, &icon_pr,
  1444. X                            0) ;
  1445. X  base_frame = xv_create(XV_NULL,                     FRAME,
  1446. X                         FRAME_ICON,                  scantool_icon,
  1447. X                         FRAME_LABEL,                 progname,
  1448. X                         FRAME_SHOW_RESIZE_CORNER,    FALSE,
  1449. X                         0) ;
  1450. X
  1451. X  show_frame = xv_create(base_frame, FRAME,
  1452. X                         FRAME_SHOW_LABEL, TRUE,
  1453. X                         XV_WIDTH,         650,
  1454. X                         XV_HEIGHT,        900,
  1455. X                         XV_X,             0,
  1456. X                         XV_Y,             0,
  1457. X                         XV_SHOW,          FALSE,
  1458. X                         0) ;
  1459. X}
  1460. X
  1461. Xmake_subframes()
  1462. X{
  1463. X  canvas = xv_create(base_frame,         CANVAS,
  1464. X                     CANVAS_RETAINED,    FALSE,
  1465. X                     OPENWIN_AUTO_CLEAR, FALSE,
  1466. X                     XV_WIDTH,           SCAN_WIDTH,
  1467. X                     XV_HEIGHT,          SCAN_HEIGHT,
  1468. X                     CANVAS_PAINTWINDOW_ATTRS,
  1469. X                       WIN_CONSUME_EVENTS,
  1470. X                         MS_LEFT, MS_MIDDLE, MS_RIGHT,
  1471. X                         WIN_ASCII_EVENTS, KBD_USE, KBD_DONE,
  1472. X                         LOC_WINENTER, LOC_WINEXIT, LOC_DRAG, LOC_MOVE,
  1473. X                         WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS,
  1474. X                         WIN_REPAINT,
  1475. X                       0,
  1476. X                       WIN_EVENT_PROC,   canvas_proc,
  1477. X                       0,
  1478. X                     0) ;
  1479. X  wpw = canvas_paint_window(canvas) ;
  1480. X  dpy = (Display *) xv_get(base_frame, XV_DISPLAY) ;
  1481. X  xid = (Drawable) xv_get(wpw, XV_XID) ;
  1482. X  screen = DefaultScreen(dpy) ;
  1483. X  root = RootWindow(dpy, screen) ;
  1484. X  foregnd = BlackPixel(dpy, screen) ;
  1485. X  backgnd = WhitePixel(dpy, screen) ;
  1486. X  gc_mask = GCForeground | GCBackground | GCGraphicsExposures ;
  1487. X  gc_val.foreground = foregnd ;
  1488. X  gc_val.background = backgnd ;
  1489. X  gc_val.graphics_exposures = False ;
  1490. X  gc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
  1491. X
  1492. X  backgc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
  1493. X  XSetForeground(dpy, backgc, gc_val.background) ;
  1494. X
  1495. X  ropgc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
  1496. X  gc_val.function = GXcopy ;
  1497. X  gc_val.fill_style = FillOpaqueStippled ;
  1498. X  XChangeGC(dpy, ropgc, GCFunction | GCFillStyle, &gc_val) ;
  1499. X
  1500. X  grey_pr = (Drawable) xv_get(make_server_image(grey_image, 16, 16), XV_XID) ;
  1501. X  frame_cursor_pr = make_server_image(frame_cursor_array, 16, 16) ;
  1502. X  help_cursor_pr  = make_server_image(help_cursor_array,  16, 16) ;
  1503. X  hour_cursor_pr  = make_server_image(hour_cursor_array,  16, 16) ;
  1504. X  main_cursor_pr  = make_server_image(main_cursor_array,  16, 16) ;
  1505. X  images[(int) B_NORMAL] = (Drawable)
  1506. X               xv_get(make_server_image(button_normal_image, 64, 64), XV_XID) ;
  1507. X  images[(int) B_INVERT] = (Drawable)
  1508. X               xv_get(make_server_image(button_invert_image, 64, 64), XV_XID) ;
  1509. X  images[(int) S_NORMAL] = (Drawable)
  1510. X               xv_get(make_server_image(switch_normal_image, 16, 16), XV_XID) ;
  1511. X  images[(int) S_INVERT] = (Drawable)
  1512. X               xv_get(make_server_image(switch_invert_image, 16, 16), XV_XID) ;
  1513. X  images[(int) EXCLAIM_IMAGE] = (Drawable)
  1514. X               xv_get(make_server_image(exclaim_image, 64, 64), XV_XID) ;
  1515. X
  1516. X  cursor[(int) FRAME_CUR] = xv_create(XV_NULL,      CURSOR,
  1517. X                                      CURSOR_IMAGE, frame_cursor_pr,
  1518. X                                      CURSOR_XHOT,  7,
  1519. X                                      CURSOR_YHOT,  7,
  1520. X                                      0) ;
  1521. X  cursor[(int) HELP_CUR] = xv_create(XV_NULL,      CURSOR,
  1522. X                                     CURSOR_IMAGE, help_cursor_pr,
  1523. X                                     0) ;
  1524. X  cursor[(int) HOUR_CUR] = xv_create(XV_NULL,      CURSOR,
  1525. X                                     CURSOR_IMAGE, hour_cursor_pr,
  1526. X                                     0) ;
  1527. X  cursor[(int) MAIN_CUR] = xv_create(XV_NULL,      CURSOR,
  1528. X                                     CURSOR_IMAGE, main_cursor_pr,
  1529. X                                     0) ;
  1530. X
  1531. X  show_canvas = xv_create(show_frame, CANVAS,
  1532. X                          CANVAS_REPAINT_PROC, repaint_show_canvas,
  1533. X                          0) ;
  1534. X  spw = canvas_paint_window(show_canvas) ;
  1535. X  spr = NULL ;
  1536. X
  1537. X  XV_SET(canvas, WIN_CURSOR, cursor[(int) MAIN_CUR]) ;
  1538. X}
  1539. X
  1540. Xmenu_proc(menu, menu_item)
  1541. XMenu menu ;
  1542. XMenu_item menu_item ;
  1543. X{
  1544. X  int choice ;
  1545. X
  1546. X  choice = (int) menu_get(menu_item, MENU_VALUE) ;
  1547. X  if (choice) process_menu(cur_menu, choice) ;
  1548. X}
  1549. X
  1550. XServer_image
  1551. Xmake_server_image(image, width, height)
  1552. Xunsigned short image[] ;
  1553. Xint width, height ;
  1554. X{
  1555. X  return(xv_create(XV_NULL,           SERVER_IMAGE,
  1556. X                   XV_WIDTH,          width,
  1557. X                   XV_HEIGHT,         height,
  1558. X                   SERVER_IMAGE_BITS, image,
  1559. X                   0)) ;
  1560. X}
  1561. X
  1562. X/*ARGSUSED*/
  1563. Xvoid
  1564. Xrepaint_show_canvas(canvas, pw, repaint_area)     /* Show current picture. */
  1565. XCanvas canvas ;
  1566. XPixwin *pw ;
  1567. XRectlist *repaint_area ;
  1568. X{
  1569. X  PW_WRITE(pw, 0, 0, hdr.ras_width, hdr.ras_height, PIX_SRC, spr, 0, 0) ;
  1570. X}
  1571. X
  1572. Xset_cursor(ctype)
  1573. Xenum cur_type ctype ;
  1574. X{
  1575. X  XV_SET(wpw, WIN_CURSOR, cursor[(int) ctype], 0) ;
  1576. X}
  1577. X
  1578. Xshow()      /* Display scanned image. */
  1579. X{
  1580. X  Rect *temprect ;
  1581. X  char errmes[MAXLINE] ;
  1582. X  int fd ;
  1583. X
  1584. X  showing = 1 ;
  1585. X  make_button(SCAN_WIDTH-150, 4*SWITCH_HEIGHT+100, "Show", B_INVERT) ;
  1586. X  if (spr) PR_DESTROY(spr) ;
  1587. X  if ((fd = open(picname, O_RDONLY | O_NDELAY, 0644)) == -1)
  1588. X    {
  1589. X      SPRINTF(errmes, "Cannot open %s.", picname) ;
  1590. X      make_display(errmes) ;
  1591. X    }
  1592. X  else
  1593. X    { 
  1594. X      READ(fd, (char *) &hdr, sizeof(struct rasterfile)) ;
  1595. X      if (hdr.ras_maplength)
  1596. X        {
  1597. X          make_display("Color rasterfiles currently not supported.") ;
  1598. X          return ;
  1599. X        }
  1600. X      spr = mem_create(hdr.ras_width, hdr.ras_height, hdr.ras_depth) ;
  1601. X      READ(fd, (char *) (mpr_d(spr)->md_image),
  1602. X           hdr.ras_width * hdr.ras_height) ;
  1603. X      CLOSE(fd) ;
  1604. X      temprect = (Rect *) xv_get(show_frame, FRAME_OPEN_RECT) ;
  1605. X      temprect->r_left = temprect->r_top = 0 ;
  1606. X      temprect->r_height = hdr.ras_height ;
  1607. X      temprect->r_width = hdr.ras_width ;
  1608. X      XV_SET(show_frame, FRAME_OPEN_RECT, temprect, 0) ;
  1609. X      XV_SET(show_frame, FRAME_LABEL, picname, 0) ;
  1610. X      XV_SET(show_frame, XV_SHOW, TRUE, 0) ;
  1611. X    }
  1612. X  make_button(SCAN_WIDTH-150, 4*SWITCH_HEIGHT+100, "Show", B_NORMAL) ;
  1613. X  showing = 0 ;
  1614. X}
  1615. X
  1616. Xstart_tool()
  1617. X{
  1618. X  window_fit(base_frame) ;
  1619. X  NOTIFY_INTERPOSE_DESTROY_FUNC(base_frame, destroy) ;
  1620. X  started = 1 ;
  1621. X  window_main_loop(base_frame) ;
  1622. X}
  1623. X
  1624. X/*ARGSUSED*/
  1625. XNotify_value
  1626. Xwait_child(frame, pid, status, rusage)
  1627. XWindow frame ;
  1628. Xint pid ;
  1629. Xunion wait *status ;
  1630. Xstruct rusage *rusage ;
  1631. X{
  1632. X  char output[MAXLINE] ;
  1633. X  int high, low ;
  1634. X
  1635. X  if (WIFSTOPPED(*status)) return (NOTIFY_IGNORED) ;
  1636. X       
  1637. X  high = (status->w_status & 0xFF00) >> 8 ;
  1638. X  low = status->w_status & 0xFF ;
  1639. X  if (low) SPRINTF(output, "Scan: terminated with signal %1d", (low & 0x3F)) ;
  1640. X  else 
  1641. X    {
  1642. X      switch (high)
  1643. X        {
  1644. X          case 0  : SPRINTF(output, "Scan: successful. %s saved",
  1645. X                                     picname) ;
  1646. X                    break ;
  1647. X          case 1  : SPRINTF(output, "Scan: cannot open tty port %c",
  1648. X                                     switches[SERIAL_PORT] + 'A') ;
  1649. X                    break ;
  1650. X          case 2  : SPRINTF(output, "Scan: cannot open temporary image file") ;
  1651. X                    break ;
  1652. X          case 3  : SPRINTF(output, "Scan: cannot open raster header file") ;
  1653. X                    break ;
  1654. X          case 4  : SPRINTF(output, "Scan: scanner not responding; aborting") ;
  1655. X                    break ;
  1656. X          case 5  : SPRINTF(output, "Scan: invalid command line argument") ;
  1657. X                    break ;
  1658. X          default : if (high >= 100 && high < 200)
  1659. X                      SPRINTF(output, "Scan: scanner error %1d; aborting",
  1660. X                                       high - 100) ;
  1661. X                    else
  1662. X                      SPRINTF(output, "Scan: terminated with signal %1d",
  1663. X                                       high - 200) ;
  1664. X        }
  1665. X    }    
  1666. X  make_display(output) ;
  1667. X  make_button(SCAN_WIDTH-150, 4*SWITCH_HEIGHT+20, "Scan",   B_NORMAL) ;
  1668. X  make_button(SCAN_WIDTH-150, 4*SWITCH_HEIGHT+60, "Cancel", B_NORMAL) ;
  1669. X  scanning = 0 ;
  1670. X  return (NOTIFY_DONE) ;
  1671. X}
  1672. X
  1673. Xwait_on_child(pid)      /* Wait on child scan process. */
  1674. Xint pid ;
  1675. X{
  1676. X  NOTIFY_SET_WAIT3_FUNC(base_frame, wait_child, pid) ;
  1677. X}
  1678. END_OF_FILE
  1679. if test 16921 -ne `wc -c <'scantool/xview.c'`; then
  1680.     echo shar: \"'scantool/xview.c'\" unpacked with wrong size!
  1681. fi
  1682. # end of 'scantool/xview.c'
  1683. fi
  1684. echo shar: End of archive 1 \(of 3\).
  1685. cp /dev/null ark1isdone
  1686. MISSING=""
  1687. for I in 1 2 3 ; do
  1688.     if test ! -f ark${I}isdone ; then
  1689.     MISSING="${MISSING} ${I}"
  1690.     fi
  1691. done
  1692. if test "${MISSING}" = "" ; then
  1693.     echo You have unpacked all 3 archives.
  1694.     rm -f ark[1-9]isdone
  1695. else
  1696.     echo You still need to unpack the following archives:
  1697.     echo "        " ${MISSING}
  1698. fi
  1699. ##  End of shell archive.
  1700. exit 0
  1701. dan
  1702. -----------------------------------------------------------
  1703.             O'Reilly && Associates
  1704.         argv@sun.com / argv@ora.com
  1705.        632 Petaluma Ave, Sebastopol, CA 95472 
  1706.      800-338-NUTS, in CA: 800-533-NUTS, FAX 707-829-0104
  1707.     Opinions expressed reflect those of the author only.
  1708.