home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume29 / gs45 / part01 < prev    next >
Encoding:
Text File  |  1992-04-25  |  17.1 KB  |  578 lines

  1. Newsgroups: comp.sources.misc
  2. From: lh@aega84.UUCP (Lothar Hirschbiegel)
  3. Subject:  v29i078:  gs45 - driver for Genius GS4500 hand scanner under SysV/386, Part01/01
  4. Message-ID: <1992Apr17.020205.15971@sparky.imd.sterling.com>
  5. X-Md4-Signature: 7a386ac88a5c2905a78313e126ec4704
  6. Date: Fri, 17 Apr 1992 02:02:05 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: lh@aega84.UUCP (Lothar Hirschbiegel)
  10. Posting-number: Volume 29, Issue 78
  11. Archive-name: gs45/part01
  12. Environment: Genius-GS4500, ISC-SVR4, MS-DOS
  13.  
  14. Driver for GS4500 Hand Scanner.
  15.  
  16. This is my first public release of a driver for the Genius hand scanner,
  17. model GS4500. I have noticed this scanner is sold as an OEM product under
  18. different names, so chances are high the driver will work with other brands
  19. of hand scanners too (though *not* real greyscale hand scanners with 64 or 256
  20. grey scales like the Logitech ScanMan256 and others).
  21. The driver supports all available resolutions from 100 up to 400 dpi.
  22. I have included a little test program to generate PBM output which can be
  23. processed by various viewers (xv, xloadimage) and filters.
  24.  
  25. It works under ISC-SVR4 (and probably most other Intel based SVR4 versions,
  26. though not tested), and also under ISC-SVR3.
  27. I have included a README in the shar file.
  28.  
  29. Regards
  30. L. Hirschbiegel / lh@aega84.uucp
  31.  
  32. ==========================shar file follows=============================
  33. #! /bin/sh
  34. # This is a shell archive.  Remove anything before this line, then unpack
  35. # it by saving it into a file and typing "sh file".  To overwrite existing
  36. # files, type "sh file -c".  You can also feed this as standard input via
  37. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  38. # will see the following message at the end:
  39. #        "End of shell archive."
  40. # Contents:  COPYING INSTALLATION Master Node README System gs45.c
  41. #   gs45.h gs45test.c
  42. # Wrapped by root@tmcsys on Tue Apr 14 23:02:20 1992
  43. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  44. if test -f COPYING -a "${1}" != "-c" ; then 
  45.   echo shar: Will not over-write existing file \"COPYING\"
  46. else
  47. echo shar: Extracting \"COPYING\" \(733 characters\)
  48. sed "s/^X//" >COPYING <<'END_OF_COPYING'
  49. XGenius GS4500 Scanner Driver V1.0
  50. XCopyright (c) 1992, Lothar F. Hirschbiegel
  51. XAll rights reserved.
  52. X
  53. XPermission is granted to distribute this program in exact, complete
  54. Xsource form, which includes this copyright notice, as long as no fee
  55. Xother than media and distribution cost is charged.
  56. X
  57. XThis program may not be used in whole, or in part, in any other manner
  58. Xwithout prior written permission from the author.
  59. X
  60. XThis program may not be distributed in modified form without prior
  61. Xwritten permission from the author.  In other words, patches may be
  62. Xdistributed, but modified source may not be distributed.
  63. X
  64. XIf there are any questions, comments or suggestions, the author may be
  65. Xcontacted at:
  66. X
  67. X    lh@aega84.uucp   or 
  68. X    unido!aega84!lh
  69. X    
  70. END_OF_COPYING
  71. if test 733 -ne `wc -c <COPYING`; then
  72.     echo shar: \"COPYING\" unpacked with wrong size!
  73. fi
  74. # end of overwriting check
  75. fi
  76. if test -f INSTALLATION -a "${1}" != "-c" ; then 
  77.   echo shar: Will not over-write existing file \"INSTALLATION\"
  78. else
  79. echo shar: Extracting \"INSTALLATION\" \(2365 characters\)
  80. sed "s/^X//" >INSTALLATION <<'END_OF_INSTALLATION'
  81. XInstallation
  82. X============
  83. X
  84. XI have not provided a Makefile, since compiling is trivial and wouldn't
  85. Xrequire a Makefile at all...
  86. X
  87. XPlease note that I have written and tested this driver for Interactive
  88. XSVR4.0.3 and Interactive SVR3 Release 2.0.2. I do *not* claim it will run
  89. Xon other Intel based Unix versions too, but given the similarities between
  90. Xdifferent versions of SVR4 (and sometimes SVR3) chances are quite high...
  91. X
  92. X1. If you are on a SVR4 system just go ahead compiling with the command
  93. X   cc -c gs45.c
  94. X   If you are on a SVR3 system you might have to change the line
  95. X   gs45_paddr = kvtophys(gs45tsd);    /* Line 124 in gs45.c */
  96. X   to
  97. X   gs45_paddr = svirtophys(gs45tsd);
  98. X   if you run into problems after compiling and linking your new kernel.
  99. X   I've used this driver with svirtophys under ISC SVR3r2.0.2 a while ago,
  100. X   but I have absolutely no idea whether kvtophys is available also under
  101. X   SVR3 (I don't have access to ISC SVR3 anymore).
  102. X
  103. X   After compilation rename the resulting file gs45.o to Driver.o .
  104. X
  105. X2. Integrate the driver into the system by using 
  106. X   idinstall -a -k            for SVR4 (WARNING: if you don't use the -k option
  107. X                            idinstall will clear your configuration files
  108. X                            after installation!) 
  109. X   or
  110. X   insdriver                for SVR3 
  111. X   I have prepared Master, Node and System files.
  112. X   You will be asked about the drivers name; enter "gs45" then.
  113. X
  114. X3. That's almost all to do now. Now build a new kernel with
  115. X   /etc/conf/bin/idbuild on SVR4 or use kconfig on SVR3.
  116. X
  117. X[ Disclaimer: you should *never* change your kernel and/or integrate
  118. X  drivers into the kernel without making backups *before* doing so :-) ]
  119. X
  120. XAfter rebooting your system there will be a device called /dev/gscan.
  121. X
  122. XI have included a little test program "gs45test.c" which you may
  123. Xuse to test the successful installation of the driver. It generates
  124. XPBM output which can be viewed with xv or xloadimage.
  125. XCompile with cc -o gs45test gs45test.c , use it with "gs45test > outfile".
  126. XIt is also an example of how to use the driver. If in doubt, read the
  127. Xincluded manpage gs45.man.
  128. X
  129. XIf you have any questions, suggestions and/or complaints (hopefully not:-)
  130. Xyou can contact me under the email address "lh@aega84.uucp".
  131. X
  132. X[ By the way: anybody willing to write an online viewer
  133. Xfor X11 for the driver?? Would be nice to see your scanning progress
  134. Xdirectly in an X11 window... :-) ]
  135. END_OF_INSTALLATION
  136. if test 2365 -ne `wc -c <INSTALLATION`; then
  137.     echo shar: \"INSTALLATION\" unpacked with wrong size!
  138. fi
  139. # end of overwriting check
  140. fi
  141. if test -f Master -a "${1}" != "-c" ; then 
  142.   echo shar: Will not over-write existing file \"Master\"
  143. else
  144. echo shar: Extracting \"Master\" \(30 characters\)
  145. sed "s/^X//" >Master <<'END_OF_Master'
  146. Xgs45    ocri    ioHc    gs45    0    0    1    2    3
  147. END_OF_Master
  148. if test 30 -ne `wc -c <Master`; then
  149.     echo shar: \"Master\" unpacked with wrong size!
  150. fi
  151. # end of overwriting check
  152. fi
  153. if test -f Node -a "${1}" != "-c" ; then 
  154.   echo shar: Will not over-write existing file \"Node\"
  155. else
  156. echo shar: Extracting \"Node\" \(15 characters\)
  157. sed "s/^X//" >Node <<'END_OF_Node'
  158. Xgs45 gscan    c    0
  159. END_OF_Node
  160. if test 15 -ne `wc -c <Node`; then
  161.     echo shar: \"Node\" unpacked with wrong size!
  162. fi
  163. # end of overwriting check
  164. fi
  165. if test -f README -a "${1}" != "-c" ; then 
  166.   echo shar: Will not over-write existing file \"README\"
  167. else
  168. echo shar: Extracting \"README\" \(1207 characters\)
  169. sed "s/^X//" >README <<'END_OF_README'
  170. X
  171. X
  172. XDriver for GS4500 Hand Scanner, written by Lothar Hirschbiegel (lh@aega84.uucp)
  173. X
  174. XThis is my first public release of a driver for the Genius hand scanner,
  175. Xmodel GS4500. I have noticed this scanner is sold as an OEM product under
  176. Xdifferent names, so chances are high the driver will work with other brands
  177. Xof hand scanners too (though *not* real greyscale hand scanners with 64 or 256
  178. Xgrey scales like the Logitech ScanMan256 and others).
  179. XThe driver supports all available resolutions from 100 up to 400 dpi.
  180. XI have included a little test program to generate PBM output which can be
  181. Xprocessed by various viewers (xv, xloadimage) and filters.
  182. X
  183. XOne word of warning: since the Genius interface controller is not interrupt
  184. Xdriven in default HW mode, the driver is a real cpu hog... This is no problem
  185. Xunder MS-DOS, but under UNIX the slowdown is remarkably high.  In fact the
  186. Xmachine locks up almost completely during scanning. This could be avoided,
  187. Xbut chances to lose lines of scanned pixels will increase dramatically.
  188. XI would not recommend using the scanner for large scanning sessions while 10
  189. Xother users are logged into your machine :-) .
  190. X
  191. XL. Hirschbiegel
  192. Xlh@aega84.uucp , Tue Apr 14 22:48:54 GMT 1992
  193. X
  194. END_OF_README
  195. if test 1207 -ne `wc -c <README`; then
  196.     echo shar: \"README\" unpacked with wrong size!
  197. fi
  198. # end of overwriting check
  199. fi
  200. if test -f System -a "${1}" != "-c" ; then 
  201.   echo shar: Will not over-write existing file \"System\"
  202. else
  203. echo shar: Extracting \"System\" \(27 characters\)
  204. sed "s/^X//" >System <<'END_OF_System'
  205. Xgs45    Y    1    0    0    0    272    27b    0    0
  206. END_OF_System
  207. if test 27 -ne `wc -c <System`; then
  208.     echo shar: \"System\" unpacked with wrong size!
  209. fi
  210. # end of overwriting check
  211. fi
  212. if test -f gs45.c -a "${1}" != "-c" ; then 
  213.   echo shar: Will not over-write existing file \"gs45.c\"
  214. else
  215. echo shar: Extracting \"gs45.c\" \(4838 characters\)
  216. sed "s/^X//" >gs45.c <<'END_OF_gs45.c'
  217. X
  218. X/*************************************************************
  219. X * Driver for GS4500 Scanner Controller                      *
  220. X * Copyright L. Hirschbiegel 1991                            *
  221. X *************************************************************/
  222. X
  223. X/* This software was written by Lothar Hirschbiegel (lh@aega84.uucp) */
  224. X/* For a complete license see file COPYING */
  225. X
  226. X/********************************************/
  227. X/* Port address GROUP 1: 272, 273, 27A, 27B */
  228. X/* Settings for DMA channel 3 (default)     */
  229. X/********************************************/
  230. X
  231. X#include <sys/signal.h>
  232. X#include <sys/types.h>
  233. X#include <sys/tss.h>
  234. X#include <sys/fs/s5dir.h>
  235. X#include <sys/sysmacros.h>
  236. X#include <sys/user.h>
  237. X#include <sys/errno.h>
  238. X#include <sys/buf.h> 
  239. X#include <sys/ddi.h> 
  240. X#define KERNEL
  241. X#include "gs45.h" 
  242. X
  243. X/* Will only read from DMA port (no writing) */
  244. X#define DMALOAD 0x47
  245. X
  246. X/* private kernel buffer for temporary storage of data */
  247. Xunchar gs45tsd[256];
  248. X
  249. X#define DMA_mode 0x0b
  250. X#define DMA_fflop 0x0c
  251. X#define DMA_mask 0x0a
  252. X#define DMA_page 0x82
  253. X#define DMA_count 0x07
  254. X#define DMA_start 0x06
  255. X#define DMA_drqtc 0x08
  256. X#define DMA_req 0x09
  257. X
  258. X#define DMA3TC    0x08
  259. X
  260. X#define TRUE 1
  261. X#define FALSE 0
  262. X
  263. X#define START_SCAN    0x01
  264. X#define END_SCAN    0xfe
  265. X
  266. Xstruct _gs45state {
  267. X    int    is_open;
  268. X    int is_on;
  269. X    int ioval[4];
  270. X    int iores[4];
  271. X    int offs[4];
  272. X} gs45state = {0,                                 /* is_open */
  273. X               0,                                /* is_on */
  274. X               {0xf0,0xa0,0x80,0xe0},            /* ioval */
  275. X               {0x35,0x69,0x9e,0xce},            /* iores */
  276. X                 {0xffe4,0xfff0,0xff84,0xffe4}       /* DMA count full page */
  277. X              };
  278. X
  279. Xunsigned long gs45_paddr;
  280. Xint gs45res_switch = -1;
  281. X
  282. X#define SCAN_ON        (gs45state.ioval[gs45res_switch]|START_SCAN)
  283. X#define SCAN_OFF    (gs45state.ioval[gs45res_switch]&END_SCAN)
  284. X#define SCAN_LEN    (gs45state.iores[gs45res_switch]) 
  285. X
  286. Xgs45_start(xferlen)
  287. Xint xferlen;
  288. X{
  289. X    short recv, rcl, rch;
  290. X    uint page, base_l, base_h, len_l, len_h, base, plen;
  291. X
  292. X    base = gs45_paddr;
  293. X    plen = xferlen - 1;
  294. X
  295. X    base_l = base & 0xff;
  296. X    base = base >> 8;
  297. X    base_h = base & 0xff;
  298. X    base = base >> 8;
  299. X    page = base & 0xff;
  300. X    len_l = plen & 0xff;
  301. X    plen = plen >> 8;
  302. X    len_h = plen & 0xff;
  303. X
  304. X    outb(DMA_page, page);
  305. X    outb(DMA_mask, 0x07);    /* mask channel 3 */
  306. X
  307. X    outb(DMA_mode,DMALOAD);    
  308. X    outb(DMA_fflop, 0x0);    
  309. X
  310. X    outb(DMA_start, base_l);    /* set dma base addr */
  311. X    outb(DMA_start, base_h);    /* set dma base addr */
  312. X
  313. X    outb(DMA_fflop, 0x0);    
  314. X
  315. X    outb(DMA_count, len_l);    /* set dma len counter */
  316. X    outb(DMA_count, len_h);    /* set dma len counter */
  317. X
  318. X    outb(GS_CCP, 0);        /* clear card receive counter */
  319. X    recv = inb(GS_VDP, 0);    /* reset card dma request */
  320. X
  321. X    outb(DMA_req, 0x3);        /* reset dma channel 3 */
  322. X    outb(DMA_mask,0x3);        /* clear masked channel */
  323. X
  324. X    /* check for end of transfer */
  325. X
  326. X    do {                    
  327. X        recv = inb(DMA_drqtc);
  328. X    } while (!(recv & DMA3TC));    /* check for channel_bit dma channel 3 */
  329. X}
  330. X
  331. Xgs45open(dev)
  332. Xint dev;
  333. X{
  334. X    if(gs45state.is_open)
  335. X    {
  336. X        u.u_error=EBUSY;
  337. X        return;
  338. X    } 
  339. X    gs45state.is_open = TRUE;
  340. X    gs45_paddr = kvtophys(gs45tsd);    
  341. X
  342. X    /* could be :
  343. X     *        gs45_paddr = svirtophys(gs45tsd);
  344. X     * for SVR3.2. Test at your own risk... */
  345. X
  346. X    gs45res_switch = -1;                    /* dpi switch is undefined */
  347. X}
  348. X
  349. Xgs45close(dev)
  350. Xint dev;
  351. X{
  352. X    gs45state.is_open = FALSE;
  353. X    if(gs45state.is_on == TRUE)
  354. X        outb(GS_CP, SCAN_OFF);
  355. X    gs45res_switch = -1;                    /* dpi switch is undefined */
  356. X}
  357. X
  358. Xcheck_gs45dpi()
  359. X{
  360. X    int inval;
  361. X
  362. X    do {
  363. X        inval=inb(GS_SP);
  364. X    } while (!(inval & 0x80));        /* wait until AR = 1 */
  365. X                                    /* scanner turned on */
  366. X    do {
  367. X        inval=inb(GS_SP);
  368. X    } while (inval & 0x80);            /* wait until AR = 0 */
  369. X                                    /* status port is valid */
  370. X    inval &= 0xa4;                    /* mask dpi bits */
  371. X    
  372. X    switch(inval)
  373. X    {
  374. X        case 0x24:    gs45res_switch = 0;
  375. X                    break;
  376. X        case 0x20:    gs45res_switch = 1;
  377. X                    break;
  378. X        case 0x04:    gs45res_switch = 2;
  379. X                    break;
  380. X        case 0x00:    gs45res_switch = 3;
  381. X                    break;
  382. X        default:    gs45res_switch = -1;
  383. X                    break;
  384. X    }
  385. X}
  386. X
  387. Xgs45ioctl(dev,cmnd,arg)
  388. Xint dev;
  389. Xint cmnd;
  390. Xint *arg;
  391. X{
  392. X    int i, cmstate;
  393. X
  394. X    switch (cmnd)
  395. X    {
  396. X         case GET_DPI:
  397. X                    copyout(&gs45res_switch, arg, sizeof(int));
  398. X                    break;
  399. X        case SCANNER_ON:
  400. X                    outb(GS_CP, TRUE);            /* turn on scanner */
  401. X                      outb(GS_CCP, TRUE);           /* clear dma count */
  402. X                    check_gs45dpi();
  403. X                    if(gs45res_switch == -1)
  404. X                    {
  405. X                        outb(GS_CP, FALSE);
  406. X                        gs45state.is_on = FALSE;
  407. X                        u.u_error = EIO;
  408. X                        return;
  409. X                    }
  410. X                    outb(GS_CP, SCAN_ON);            /* reset scanner */
  411. X                      outb(GS_CCP, SCAN_ON);           /* clear dma count */
  412. X                    gs45state.is_on = TRUE;
  413. X                    break;
  414. X        case SCANNER_OFF:
  415. X                    outb(GS_CP, SCAN_OFF);
  416. X                    gs45state.is_on = FALSE;
  417. X                    break;
  418. X        default:     break;
  419. X    }
  420. X    return;
  421. X}
  422. X
  423. Xgs45read()
  424. X{
  425. X    if(gs45state.is_on == FALSE)
  426. X    {
  427. X        u.u_error = EIO;
  428. X        return;
  429. X    }
  430. X
  431. X    while (u.u_count >= SCAN_LEN)
  432. X    {
  433. X        gs45_start(SCAN_LEN);
  434. X
  435. X        if (!copyout(gs45tsd,u.u_base,SCAN_LEN))
  436. X        {
  437. X            u.u_base += SCAN_LEN;
  438. X               u.u_count -= SCAN_LEN;
  439. X        }
  440. X        else
  441. X        {
  442. X            u.u_error = EIO;
  443. X            return;
  444. X        }
  445. X    }
  446. X}
  447. END_OF_gs45.c
  448. if test 4838 -ne `wc -c <gs45.c`; then
  449.     echo shar: \"gs45.c\" unpacked with wrong size!
  450. fi
  451. # end of overwriting check
  452. fi
  453. if test -f gs45.h -a "${1}" != "-c" ; then 
  454.   echo shar: Will not over-write existing file \"gs45.h\"
  455. else
  456. echo shar: Extracting \"gs45.h\" \(1137 characters\)
  457. sed "s/^X//" >gs45.h <<'END_OF_gs45.h'
  458. X/*************************************************************
  459. X * Includes for GS4500 Scanner Controller                    *
  460. X * Copyright L. Hirschbiegel 1991                            *
  461. X *************************************************************/
  462. X
  463. X/* This software was written by Lothar Hirschbiegel (lh@aega84.uucp) */
  464. X/* For a complete license see file COPYING */
  465. X
  466. X/* common commands via ioctl  */
  467. X/* special file is /dev/gscan */
  468. X
  469. X#define SCANNER_ON      0x10    /* no arg */
  470. X#define SCANNER_OFF     0x11    /* no arg */
  471. X#define GET_DPI          0x14    /* returns dpi_switch in (int *)arg */
  472. X                                /* 0 = 100 dpi ..... 3 = 400 dpi    */
  473. X
  474. X#define LLEN_100        0x35    /* number of bytes per line res 100 dpi */
  475. X#define LLEN_200        0x69    /* number of bytes per line res 200 dpi */
  476. X#define LLEN_300        0x9e    /* number of bytes per line res 300 dpi */
  477. X#define LLEN_400        0xce    /* number of bytes per line res 400 dpi */
  478. X
  479. X
  480. X#ifdef KERNEL
  481. X
  482. X#define GS_VDP  0x272  /* video data port */
  483. X#define GS_SP   0x273  /* status port */
  484. X#define GS_CP   0x27a  /* control port */
  485. X#define GS_CCP  0x27b  /* counter clear port */
  486. X
  487. X#endif /* KERNEL */
  488. END_OF_gs45.h
  489. if test 1137 -ne `wc -c <gs45.h`; then
  490.     echo shar: \"gs45.h\" unpacked with wrong size!
  491. fi
  492. # end of overwriting check
  493. fi
  494. if test -f gs45test.c -a "${1}" != "-c" ; then 
  495.   echo shar: Will not over-write existing file \"gs45test.c\"
  496. else
  497. echo shar: Extracting \"gs45test.c\" \(1618 characters\)
  498. sed "s/^X//" >gs45test.c <<'END_OF_gs45test.c'
  499. X
  500. X/*************************************************************
  501. X * Test program for GS4500 Scanner Driver                    *
  502. X * Copyright L. Hirschbiegel 1991                            *
  503. X *************************************************************/
  504. X
  505. X/* This software was written by Lothar Hirschbiegel (lh@aega84.uucp) */
  506. X/* For a complete license see file COPYING */
  507. X
  508. X/* USAGE: gs45test [ scanlines ] > outfile */
  509. X/* This test program generates PBM output files from GS4500 scanner input */
  510. X
  511. X#include <stdio.h>
  512. X#include "gs45.h"
  513. X
  514. Xmain(argc, argv)
  515. Xint argc;
  516. Xchar *argv[];
  517. X{
  518. X    int fd, z, numbytes;
  519. X    unsigned char c, *buf;
  520. X    int sv, i, num, scanlines;
  521. X    char res[8];
  522. X    char lines[8], ibuf[8];
  523. X    
  524. X    if(argc == 2)
  525. X        scanlines = atoi(*(++argv));
  526. X    else
  527. X        scanlines = 800;    /* default */
  528. X
  529. X    if ((fd = open("/dev/gscan",0)) < 0)
  530. X        perror("");
  531. X    
  532. X    if((ioctl(fd,SCANNER_ON))==-1)
  533. X        perror("");
  534. X
  535. X    ioctl(fd, GET_DPI, &sv);
  536. X    num = (sv + 1) * 100;
  537. X    fprintf(stderr,"DPI = %d\n",num);
  538. X
  539. X    switch(sv)
  540. X    {
  541. X        case 0:    strcpy(res,"424");
  542. X                numbytes = scanlines*LLEN_100;
  543. X                break;
  544. X        case 1:    strcpy(res,"840");
  545. X                numbytes = scanlines*LLEN_200;
  546. X                break;
  547. X        case 2:    strcpy(res,"1264");
  548. X                numbytes = scanlines*LLEN_300;
  549. X                break;
  550. X        case 3:    strcpy(res,"1648");
  551. X                numbytes = scanlines*LLEN_400;
  552. X                break;
  553. X    }
  554. X
  555. X    fprintf(stderr,"SCANLINES = %d\n",scanlines);
  556. X    sprintf(ibuf,"%d",scanlines);
  557. X    strcpy(lines,ibuf);
  558. X    buf = (unsigned char *)malloc(numbytes);
  559. X    if (buf == NULL) {
  560. X        perror("");
  561. X        exit(1);
  562. X    }
  563. X    printf("P4\n%s %s\n",res, lines);
  564. X    num = read(fd, buf, numbytes);
  565. X    for (i=0;i<num;i++) printf("%c",(buf[i]^0xff));
  566. X    ioctl(fd,SCANNER_OFF);
  567. X}
  568. END_OF_gs45test.c
  569. if test 1618 -ne `wc -c <gs45test.c`; then
  570.     echo shar: \"gs45test.c\" unpacked with wrong size!
  571. fi
  572. # end of overwriting check
  573. fi
  574. echo shar: End of shell archive.
  575. exit 0
  576.  
  577. exit 0 # Just in case...
  578.