home *** CD-ROM | disk | FTP | other *** search
/ swCHIP 1991 January / swCHIP_95-1.bin / utility / gsview13 / src / gvwpipe.c < prev    next >
C/C++ Source or Header  |  1995-12-09  |  8KB  |  268 lines

  1. /* Copyright (C) 1993, 1994, Russell Lang.  All rights reserved.
  2.   
  3.   This file is part of GSview.
  4.   
  5.   This program is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the GSview Free Public Licence 
  9.   (the "Licence") for full details.
  10.   
  11.   Every copy of GSview must include a copy of the Licence, normally in a 
  12.   plain ASCII text file named LICENCE.  The Licence grants you the right 
  13.   to copy, modify and redistribute GSview, but only under certain conditions 
  14.   described in the Licence.  Among other things, the Licence requires that 
  15.   the copyright notice and this notice be preserved on all copies.
  16. */
  17.  
  18. /* gvwpipe.c */
  19. /* pipe support for Windows GSview */
  20. #include "gvwin.h"
  21.  
  22. /* routines to be visible outside this module */
  23. extern void pipeinit();
  24. extern FILE *pipeopen(void);    /* open pipe for first time */
  25. extern void pipeclose(void);    /* finished with pipe, close & delete temp files */
  26. extern void pipereset(void);    /* pipe is empty, do cleanup */
  27. extern void piperequest(void);    /* request from gswin for pipe data */
  28. extern void pipeflush(void);    /* start sending data through pipe */
  29. extern BOOL is_pipe_done(void);    /* true if pipe has just been reset */
  30.  
  31. /* internal to this module */
  32.  
  33. /* imitation pipes using SHAREABLE GLOBAL MEMORY */
  34. #define PIPE_DATASIZE 16380    /* maximum block size */
  35. /* Data is passed to gswin in a global shareable memory block.
  36.  * The global handle is passed in lParam and the byte count
  37.  * is stored in the first word of the global memory block.
  38.  * The maximum number of bytes passed is PIPE_DATASIZE.
  39.  * EOF is signified by count = 0 (hglobal must still be valid)
  40.  */
  41. /* In gsview 1.0, Ghostscript 2.6.1 and earlier, 
  42.  * The global handle was passed in the LOWORD of lParam 
  43.  * and the HIWORD contained the byte count.
  44.  * This was changed in gsview 1.1, Ghostscript 3.0 so that a
  45.  * 32 bit handle could be used for Win32  */
  46. /* In gsview 1.2, Windows NT or 95 uses a memory mapped file */
  47.  
  48. char pipe_name[MAXSTR];        /* pipe filename */
  49. FILE *pipe_file;        /* pipe file */
  50. fpos_t pipe_wpos;
  51. fpos_t pipe_rpos;
  52. BOOL pipe_empty;
  53. int piperead(char *buf, int size);
  54. char *pipebuf;
  55. HANDLE pipe_hmapfile;
  56. LPBYTE pipe_mapptr;
  57.  
  58. /* this is called before gswin is started */
  59. /* so we can tell when we get the first piperequest */
  60. void
  61. pipeinit(void)
  62. {
  63.     pipe_empty = FALSE;    /* so we wait for first request */
  64. }
  65.  
  66. FILE *
  67. pipeopen(void)
  68. {
  69.     if (pipe_file != (FILE *)NULL) {
  70.         fclose(pipe_file);
  71.         pipe_file = (FILE *)NULL;
  72.         unlink(pipe_name);
  73.         pipe_name[0] = '\0';
  74.     }
  75. #ifdef __WIN32__
  76.     if (is_winnt || is_win95) {
  77.         char buf[64];
  78.         if (pipe_hmapfile != 0) {
  79.         if (pipe_mapptr != NULL)
  80.             UnmapViewOfFile(pipe_mapptr);
  81.         pipe_mapptr = NULL;
  82.         CloseHandle(pipe_hmapfile);
  83.         pipe_hmapfile = 0;
  84.         }
  85.         sprintf(buf,"gsview_%d", hwndimg);
  86.         pipe_hmapfile = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 
  87.                 PIPE_DATASIZE+sizeof(WORD), buf);
  88.         pipe_mapptr = MapViewOfFile(pipe_hmapfile, FILE_MAP_WRITE, 0, 0, 0);
  89.         if (pipe_mapptr == NULL) {
  90.         message_box("Can't memory map file",0);
  91.         return NULL;
  92.         }
  93.     }
  94. #endif
  95.     if ((pipe_file = gp_open_scratch_file(szScratch, pipe_name, "w+b")) == (FILE *)NULL) {
  96.         gserror(IDS_PIPE_EOPEN, NULL, NULL, SOUND_ERROR);
  97.         unlink(pipe_name);
  98.         pipe_name[0] = '\0';
  99.         return (FILE *)NULL;
  100.     }
  101.     pipebuf = malloc(PIPE_DATASIZE);
  102.     pipereset();
  103.     return pipe_file;
  104. }
  105.  
  106. void
  107. pipeclose(void)
  108. {
  109. HGLOBAL hglobal;
  110. LPBYTE lpb;
  111.     if (pipebuf != (char *)NULL) {
  112.         free(pipebuf);
  113.         pipebuf = (char *)NULL;
  114.     }
  115.     if (pipe_file != (FILE *)NULL) {
  116.         fclose(pipe_file);
  117.         pipe_file = (FILE *)NULL;
  118.         unlink(pipe_name);
  119.         pipe_name[0] = '\0';
  120.     }
  121.     if (hwndtext != (HWND)NULL) {
  122. #if !defined(__WIN32__) && defined(GS261)
  123.       if (option.gsversion == IDM_GS261) {
  124.         /* send an EOF (zero length block) */
  125.         hglobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, 1);
  126.         if (hglobal == (HGLOBAL)NULL) {
  127.             gserror(IDS_PIPE_EMEM, NULL, NULL, SOUND_ERROR);
  128.             return;
  129.         }
  130.         PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, MAKELPARAM(hglobal,0));
  131.       }
  132.       else {
  133. #endif
  134. #ifdef __WIN32__
  135.         if (is_winnt || is_win95) {
  136.         /* send an EOF (zero length block) */
  137.         *((WORD *)pipe_mapptr) = 0;
  138.         PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, (LPARAM)hwndimg);
  139.         }
  140.         else
  141. #endif
  142.         {
  143.         /* send an EOF (zero length block) */
  144.         hglobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof(WORD));
  145.         if (hglobal == (HGLOBAL)NULL) {
  146.             gserror(IDS_PIPE_EMEM, NULL, NULL, SOUND_ERROR);
  147.             return;
  148.         }
  149.         lpb = GlobalLock(hglobal);
  150.         *((WORD FAR *)lpb) = 0;
  151.         GlobalUnlock(hglobal);
  152.         PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, (LPARAM)hglobal);
  153.         }
  154. #if !defined(__WIN32__) && defined(GS261)
  155.       }
  156. #endif
  157.     }
  158.     pipe_empty = TRUE;
  159. }
  160.  
  161. /* rpos and wpos are now empty so reset the file */
  162. void
  163. pipereset(void)
  164. {
  165.     if ( (pipe_file == (FILE *)NULL) || (pipe_name[0] == '\0') )
  166.         return;
  167.     if ((pipe_file = freopen(pipe_name, "w+b", pipe_file)) == (FILE *)NULL) {
  168.         gserror(IDS_PIPE_EOPEN, NULL, NULL, SOUND_ERROR);
  169.         unlink(pipe_name);
  170.         pipe_name[0] = '\0';
  171.         return;
  172.     }
  173.     fgetpos(pipe_file, &pipe_rpos);
  174.     fgetpos(pipe_file, &pipe_wpos);
  175.     pipe_empty = TRUE;
  176.     info_wait(FALSE);
  177. }
  178.  
  179. /* give another block of data to gswin */
  180. /* called from WndImgProc */
  181. void
  182. piperequest(void)
  183. {
  184. HGLOBAL hglobal;
  185. LPBYTE lpb;
  186. UINT count;
  187.     if (pipe_file == (FILE *)NULL) {
  188.         pipe_empty = TRUE;
  189.         return;
  190.     }
  191.  
  192.     count = piperead(pipebuf, PIPE_DATASIZE);
  193.     if (count==0)
  194.         return; 
  195.  
  196. #ifdef __WIN32__
  197.     if (is_winnt || is_win95) {
  198.         memcpy(pipe_mapptr+sizeof(WORD), pipebuf, count);
  199.         *((WORD *)pipe_mapptr) = (WORD)count;
  200.         PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, (LPARAM)hwndimg);
  201.     }
  202.     else
  203. #endif
  204.      {
  205.         hglobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, PIPE_DATASIZE + sizeof(WORD));
  206.         if (hglobal == (HGLOBAL)NULL) {
  207.         gserror(IDS_PIPE_EMEM, NULL, NULL, SOUND_ERROR);
  208.         return;
  209.         }
  210. #if !defined(__WIN32__) && defined(GS261)
  211.       if (option.gsversion == IDM_GS261) {
  212.         lpb = GlobalLock(hglobal);
  213.         _fmemcpy(lpb, pipebuf, count);
  214.         GlobalUnlock(hglobal);
  215.         /* we may be processing SendMessage so use PostMessage to avoid lockups */
  216.         PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, MAKELPARAM(hglobal,count));
  217.       }
  218.       else {
  219. #endif
  220.         lpb = GlobalLock(hglobal);
  221.         *((WORD FAR *)lpb) = (WORD)count;
  222.         _fmemcpy(lpb+sizeof(WORD), pipebuf, count);
  223.         GlobalUnlock(hglobal);
  224.         /* we may be processing SendMessage so use PostMessage to avoid lockups */
  225.         PostMessage(hwndtext, WM_GSVIEW, PIPE_DATA, (LPARAM)hglobal);
  226. #if !defined(__WIN32__) && defined(GS261)
  227.       }
  228. #endif
  229.     }
  230. }
  231.  
  232. /* write pipe_file to pipe */
  233. void
  234. pipeflush(void)
  235. {
  236.     if (pipe_empty) {
  237.         pipe_empty = FALSE;
  238.         piperequest();    /* repeat the request */
  239.     }
  240.     info_wait(TRUE);
  241. }
  242.  
  243. /* true  if pipereset was last called */
  244. /* false if pipeflush was last called */
  245. int
  246. is_pipe_done(void)
  247. {
  248.     return pipe_empty;
  249. }
  250.  
  251. /* read a block from pipe */
  252. /* return count of characters read */
  253. /* reset pipe if empty */
  254. int
  255. piperead(char *buf, int size)
  256. {
  257. int rcount;
  258.     fflush(pipe_file);
  259.     fgetpos(pipe_file,&pipe_wpos);
  260.     fsetpos(pipe_file,&pipe_rpos);
  261.     rcount = fread(buf, 1, size, pipe_file);
  262.     fgetpos(pipe_file,&pipe_rpos);
  263.     fsetpos(pipe_file,&pipe_wpos);
  264.     if (rcount == 0)
  265.        pipereset();
  266.     return rcount;
  267. }
  268.