home *** CD-ROM | disk | FTP | other *** search
/ swCHIP 1991 January / swCHIP_95-1.bin / utility / gsview13 / src / gvwprn.c < prev    next >
C/C++ Source or Header  |  1995-12-09  |  21KB  |  696 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. /* gvwprn.c */
  19. /* Printer routines for Windows GSview */
  20. #include "gvwin.h"
  21.  
  22. /* documented in Device Driver Adaptation Guide */
  23. /* Prototypes taken from print.h */
  24. DECLARE_HANDLE(HPJOB);
  25.  
  26. HPJOB   WINAPI OpenJob(LPSTR, LPSTR, HPJOB);
  27. int     WINAPI StartSpoolPage(HPJOB);
  28. int     WINAPI EndSpoolPage(HPJOB);
  29. int     WINAPI WriteSpool(HPJOB, LPSTR, int);
  30. int     WINAPI CloseJob(HPJOB);
  31. int     WINAPI DeleteJob(HPJOB, int);
  32. int     WINAPI WriteDialog(HPJOB, LPSTR, int);
  33. int     WINAPI DeleteSpoolPage(HPJOB);
  34.  
  35. static char pcfname[MAXSTR];    /* name of temporary command file for printing */
  36. static char pfname[MAXSTR];    /* name of temporary file for printing options */
  37. char not_defined[] = "[Not defined]";
  38.  
  39. /* dialog box for selecting printer properties */
  40. BOOL CALLBACK _export
  41. PropDlgProc(HWND hDlg, UINT wmsg, WPARAM wParam, LPARAM lParam)
  42. {
  43.     char buf[128];
  44.     int iprop;
  45.     int ivalue;
  46.     WORD notify_message;
  47.     char *p;
  48.     char *value;
  49.     static char device[MAXSTR];    /* contains printer device name */
  50.     static struct prop_item_s* propitem;
  51.     char section[MAXSTR];
  52.  
  53.     switch (wmsg) {
  54.         case WM_INITDIALOG:
  55.         lstrcpy(device, (LPSTR)lParam);    /* initialise device name */
  56.         propitem = get_properties(device);
  57.         if (propitem == (struct prop_item_s *)NULL) {
  58.             EndDialog(hDlg, FALSE);
  59.             return TRUE;
  60.         }
  61.         for (iprop=0; propitem[iprop].name[0]; iprop++) {
  62.             SendDlgItemMessage(hDlg, PROP_NAME, CB_ADDSTRING, 0, 
  63.             (LPARAM)((LPSTR)propitem[iprop].name+1));
  64.         }
  65.         SendDlgItemMessage(hDlg, PROP_NAME, CB_SETCURSEL, 0, 0L);
  66.         /* force update of PROP_VALUE */
  67.         SendDlgNotification(hDlg, PROP_NAME, CBN_SELCHANGE);
  68.         return TRUE;
  69.         case WM_COMMAND:
  70.         notify_message = GetNotification(wParam,lParam);
  71.         switch (LOWORD(wParam)) {
  72.             case ID_HELP:
  73.                 SendMessage(hwndimg, help_message, 0, 0L);
  74.                 return(FALSE);
  75.             case PROP_NAME:
  76.             if (notify_message != CBN_SELCHANGE) {
  77.                 return FALSE;
  78.             }
  79.             iprop = (int)SendDlgItemMessage(hDlg, PROP_NAME, CB_GETCURSEL, 0, 0L);
  80.             if (iprop == CB_ERR) {
  81.                 return FALSE;
  82.             }
  83.             /* now look up entry in gsview.ini */
  84.             /* and update PROP_VALUE list box */
  85.             strcpy(section, device);
  86.             strcat(section, " values");
  87.             GetPrivateProfileString(section, propitem[iprop].name, "", buf, sizeof(buf)-2, INIFILE);
  88.             buf[strlen(buf)+1] = '\0';    /* put double NULL at end */
  89.                 SendDlgItemMessage(hDlg, PROP_VALUE, CB_RESETCONTENT, 0, 0L);
  90.                 SendDlgItemMessage(hDlg, PROP_VALUE, CB_ADDSTRING, 0, 
  91.                 (LPARAM)((LPSTR)not_defined));
  92.             p = buf;
  93.             if (*p != '\0') {
  94.               EnableWindow(GetDlgItem(hDlg, PROP_VALUE), TRUE);
  95.               while (*p!='\0') {
  96.                 value = p;
  97.                 while ((*p!='\0') && (*p!=','))
  98.                 p++;
  99.                 *p++ = '\0';
  100.                     SendDlgItemMessage(hDlg, PROP_VALUE, CB_ADDSTRING, 0, 
  101.                     (LPARAM)((LPSTR)value));
  102.               }
  103.             }
  104.             SendDlgItemMessage(hDlg, PROP_VALUE, CB_SELECTSTRING, -1, (LPARAM)(LPSTR)propitem[iprop].value);
  105.                 SetDlgItemText(hDlg, PROP_VALUE, propitem[iprop].value);
  106.             return FALSE;
  107.             case PROP_VALUE:
  108.             if (notify_message == CBN_SELCHANGE) {
  109.                 iprop = (int)SendDlgItemMessage(hDlg, PROP_NAME, CB_GETCURSEL, 0, 0L);
  110.                 if (iprop == CB_ERR)
  111.                     return FALSE;
  112.                 ivalue = (int)SendDlgItemMessage(hDlg, PROP_VALUE, CB_GETCURSEL, 0, 0L);
  113.                 if (ivalue == CB_ERR)
  114.                     return FALSE;
  115.                 SendDlgItemMessage(hDlg, PROP_VALUE, CB_GETLBTEXT, ivalue, (LPARAM)(LPSTR)propitem[iprop].value);
  116.             }
  117.             if (notify_message == CBN_EDITCHANGE) {
  118.                 iprop = (int)SendDlgItemMessage(hDlg, PROP_NAME, CB_GETCURSEL, 0, 0L);
  119.                 if (iprop == CB_ERR)
  120.                     return FALSE;
  121.                     GetDlgItemText(hDlg, PROP_VALUE, (LPSTR)propitem[iprop].value, sizeof(propitem->value));
  122.             }
  123.             return FALSE;
  124.             case IDOK:
  125.             for (iprop=0; propitem[iprop].name[0]; iprop++) {
  126.                 WritePrivateProfileString(device, propitem[iprop].name, propitem[iprop].value, INIFILE);
  127.             }
  128.             free((char *)propitem);
  129.             EndDialog(hDlg, TRUE);
  130.             return TRUE;
  131.             case IDCANCEL:
  132.             free((char *)propitem);
  133.             EndDialog(hDlg, FALSE);
  134.             return TRUE;
  135.         }
  136.         break;
  137.     }
  138.     return FALSE;
  139. }
  140.  
  141.  
  142. /* dialog box for selecting printer device and resolution */
  143. BOOL CALLBACK _export
  144. DeviceDlgProc(HWND hDlg, UINT wmsg, WPARAM wParam, LPARAM lParam)
  145. {
  146.     char buf[128];
  147.     int idevice;
  148.     WORD notify_message;
  149.     char *p;
  150.     char *res;
  151.     int numentry;
  152.     char entry[MAXSTR];
  153.     struct prop_item_s *proplist;
  154.  
  155.     switch (wmsg) {
  156.         case WM_INITDIALOG:
  157.         p = get_devices();
  158.         res = p;    /* save for free() */
  159.         for (numentry=0; p!=(char *)NULL && strlen(p)!=0; numentry++) {
  160.             SendDlgItemMessage(hDlg, DEVICE_NAME, CB_ADDSTRING, 0, 
  161.             (LPARAM)((LPSTR)p));
  162.             p += strlen(p) + 1;
  163.         }
  164.         free(res);
  165.         if (SendDlgItemMessage(hDlg, DEVICE_NAME, CB_SELECTSTRING, 0, (LPARAM)(LPSTR)option.device_name)
  166.             == CB_ERR)
  167.             SendDlgItemMessage(hDlg, DEVICE_NAME, CB_SETCURSEL, 0, 0L);
  168.         /* force update of DEVICE_RES */
  169.         SendDlgNotification(hDlg, DEVICE_NAME, CBN_SELCHANGE);
  170.         if (SendDlgItemMessage(hDlg, DEVICE_RES, CB_SELECTSTRING, 0, (LPARAM)(LPSTR)option.device_resolution)
  171.             == CB_ERR)
  172.             SendDlgItemMessage(hDlg, DEVICE_RES, CB_SETCURSEL, 0, 0L);
  173.         return TRUE;
  174.         case WM_COMMAND:
  175.         notify_message = GetNotification(wParam,lParam);
  176.         switch (LOWORD(wParam)) {
  177.             case ID_HELP:
  178.                 SendMessage(hwndimg, help_message, 0, 0L);
  179.                 return(FALSE);
  180.             case DEVICE_NAME:
  181.             if (notify_message != CBN_SELCHANGE) {
  182.                 return FALSE;
  183.             }
  184.             idevice = (int)SendDlgItemMessage(hDlg, DEVICE_NAME, CB_GETCURSEL, 0, 0L);
  185.             if (idevice == CB_ERR) {
  186.                 return FALSE;
  187.             }
  188.             SendDlgItemMessage(hDlg, DEVICE_NAME, CB_GETLBTEXT, idevice, (LPARAM)(LPSTR)entry);
  189.             if ( (proplist = get_properties(entry)) != (struct prop_item_s *)NULL ) {
  190.                     free((char *)proplist);
  191.                 EnableWindow(GetDlgItem(hDlg, DEVICE_PROP), TRUE);
  192.             }
  193.             else
  194.                 EnableWindow(GetDlgItem(hDlg, DEVICE_PROP), FALSE);
  195.             /* now look up entry in gsview.ini */
  196.             /* and update DEVICE_RES list box */
  197.             GetPrivateProfileString(DEVSECTION, entry, "", buf, sizeof(buf)-2, INIFILE);
  198.             buf[strlen(buf)+1] = '\0';    /* double NULL at end */
  199.                 SendDlgItemMessage(hDlg, DEVICE_RES, CB_RESETCONTENT, 0, 0L);
  200.             p = buf;
  201.             if (*p == '\0') {
  202.                 /* no resolutions can be set */
  203.                 EnableWindow(GetDlgItem(hDlg, DEVICE_RES), FALSE);
  204.                 EnableWindow(GetDlgItem(hDlg, DEVICE_RESTEXT), FALSE);
  205.             }
  206.             else {
  207.               EnableWindow(GetDlgItem(hDlg, DEVICE_RES), TRUE);
  208.               EnableWindow(GetDlgItem(hDlg, DEVICE_RESTEXT), TRUE);
  209.               while (*p!='\0') {
  210.                 res = p;
  211.                 while ((*p!='\0') && (*p!=','))
  212.                 p++;
  213.                 *p++ = '\0';
  214.                     SendDlgItemMessage(hDlg, DEVICE_RES, CB_ADDSTRING, 0, 
  215.                     (LPARAM)((LPSTR)res));
  216.               }
  217.             }
  218.             SendDlgItemMessage(hDlg, DEVICE_RES, CB_SETCURSEL, 0, 0L);
  219.             if (SendDlgItemMessage(hDlg, DEVICE_RES, CB_GETLBTEXT, 0, (LPARAM)(LPSTR)buf)
  220.                 != CB_ERR)
  221.                     SetDlgItemText(hDlg, DEVICE_RES, buf);
  222.             return FALSE;
  223.             case DEVICE_RES:
  224.             /* don't have anything to do */
  225.             return FALSE;
  226.             case DEVICE_PROP:
  227.             idevice = (int)SendDlgItemMessage(hDlg, DEVICE_NAME, CB_GETCURSEL, 0, 0L);
  228.             if (idevice == CB_ERR) {
  229.                 return FALSE;
  230.             }
  231.             SendDlgItemMessage(hDlg, DEVICE_NAME, CB_GETLBTEXT, idevice, (LPARAM)(LPSTR)entry);
  232.             if ( (proplist = get_properties(entry)) != (struct prop_item_s *)NULL ) {
  233. #ifndef __WIN32__
  234.                     DLGPROC lpProcProp;
  235. #endif
  236.                     free((char *)proplist);
  237.                 LoadString(phInstance, IDS_TOPICPRINT, szHelpTopic, sizeof(szHelpTopic));
  238. #ifdef __WIN32__
  239.                 DialogBoxParam( phInstance, "PropDlgBox", hDlg, PropDlgProc, (LPARAM)entry);
  240. #else
  241.                 lpProcProp = (DLGPROC)MakeProcInstance((FARPROC)PropDlgProc, phInstance);
  242.                 DialogBoxParam( phInstance, "PropDlgBox", hDlg, lpProcProp, (LPARAM)entry);
  243.                 FreeProcInstance((FARPROC)lpProcProp);
  244. #endif
  245.             }
  246.             else
  247.                 play_sound(SOUND_ERROR);
  248.             return FALSE;
  249.             case IDOK:
  250.             /* save device name and resolution */
  251.                 GetDlgItemText(hDlg, DEVICE_NAME, option.device_name, sizeof(option.device_name));
  252.                 GetDlgItemText(hDlg, DEVICE_RES, option.device_resolution, sizeof(option.device_resolution));
  253.             EndDialog(hDlg, TRUE);
  254.             return TRUE;
  255.             case IDCANCEL:
  256.             EndDialog(hDlg, FALSE);
  257.             return TRUE;
  258.         }
  259.         break;
  260.     }
  261.     return FALSE;
  262. }
  263.  
  264.  
  265.  
  266. /* Modeless dialog box - Cancel printing */
  267. BOOL CALLBACK _export
  268. CancelDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  269. {
  270.     switch(message) {
  271.     case WM_INITDIALOG:
  272.         SetWindowText(hDlg, szAppName);
  273.         return TRUE;
  274.     case WM_COMMAND:
  275.         switch(LOWORD(wParam)) {
  276.         case IDCANCEL:
  277.             DestroyWindow(hDlg);
  278.             hDlgModeless = 0;
  279.             EndDialog(hDlg, 0);
  280.             return TRUE;
  281.         }
  282.     }
  283.     return FALSE;
  284. }
  285.  
  286. /* Dialog box to select printer port */
  287. BOOL CALLBACK _export
  288. SpoolDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  289. {
  290. LPSTR entry;
  291.     switch(message) {
  292.     case WM_INITDIALOG:
  293.         entry = (LPSTR)lParam;
  294.         while (*entry) {
  295.         SendDlgItemMessage(hDlg, SPOOL_PORT, LB_ADDSTRING, 0, (LPARAM)entry);
  296.         entry += lstrlen(entry)+1;
  297.         }
  298.         if ( (*option.printer_port=='\0') ||
  299.         (SendDlgItemMessage(hDlg, SPOOL_PORT, LB_SELECTSTRING, 0, (LPARAM)(LPSTR)option.printer_port)
  300.             == LB_ERR) )
  301.             SendDlgItemMessage(hDlg, SPOOL_PORT, LB_SETCURSEL, 0, (LPARAM)0);
  302.         return TRUE;
  303.     case WM_COMMAND:
  304.         switch(LOWORD(wParam)) {
  305.         case SPOOL_PORT:
  306. #ifdef __WIN32__
  307.             if (HIWORD(wParam)
  308. #else
  309.             if (HIWORD(lParam)
  310. #endif
  311.                            == LBN_DBLCLK)
  312.             PostMessage(hDlg, WM_COMMAND, IDOK, 0L);
  313.             return FALSE;
  314.         case IDOK:
  315.             SendDlgItemMessage(hDlg, SPOOL_PORT, LB_GETTEXT, 
  316.             (int)SendDlgItemMessage(hDlg, SPOOL_PORT, LB_GETCURSEL, 0, 0L),
  317.             (LPARAM)(LPSTR)option.printer_port);
  318.             EndDialog(hDlg, 1+(int)SendDlgItemMessage(hDlg, SPOOL_PORT, LB_GETCURSEL, 0, 0L));
  319.             return TRUE;
  320.         case IDCANCEL:
  321.             EndDialog(hDlg, 0);
  322.             return TRUE;
  323.         }
  324.     }
  325.     return FALSE;
  326. }
  327.  
  328. #ifdef __WIN32__
  329. /* Win32s can't get access to OpenJob etc., so we try to sneak the */
  330. /* data through the Windows printer driver unchanged */
  331. BOOL CALLBACK _export
  332. PrintAbortProc(HDC hdcPrn, int code)
  333. {
  334.     MSG msg;
  335.     while (hDlgModeless && PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
  336.     if (hDlgModeless || !IsDialogMessage(hDlgModeless,&msg)) {
  337.             TranslateMessage(&msg);
  338.             DispatchMessage(&msg);
  339.     }
  340.     }
  341.     return(hDlgModeless!=0);
  342. }
  343.  
  344. /* Print File to port */
  345. /* port==NULL means prompt for port with dialog box */
  346. /* Win32s ignores the port parameter */
  347. int
  348. gp_printfile_win32s(char *filename, char *port)
  349. {
  350. HDC printer;
  351. PRINTDLG pd;
  352. DOCINFO di;
  353. char *buf;
  354. int *bufcount, count;
  355. FILE *f;
  356. long lsize;
  357. long ldone;
  358. char fmt[MAXSTR];
  359. char pcdone[10];
  360. int error = TRUE;
  361.     memset(&pd, 0, sizeof(PRINTDLG));
  362.     pd.lStructSize = sizeof(PRINTDLG);
  363.     pd.hwndOwner = hwndimg;
  364.     pd.Flags = PD_PRINTSETUP | PD_RETURNDC;
  365.  
  366.     if ((f = fopen(filename, "rb")) == (FILE *)NULL)
  367.         return FALSE;
  368.     fseek(f, 0L, SEEK_END);
  369.     lsize = ftell(f);
  370.     if (lsize <= 0)
  371.         lsize = 1;
  372.     fseek(f, 0L, SEEK_SET);
  373.     ldone = 0;
  374.     LoadString(phInstance, IDS_CANCELDONE, fmt, sizeof(fmt));
  375.  
  376.     if (PrintDlg(&pd)) {
  377.     printer = pd.hDC;
  378.     if (printer != (HDC)NULL) {
  379.         if ( (buf = malloc(4096+2)) != (char *)NULL ) {
  380.             bufcount = (int *)buf;
  381.         EnableWindow(hwndimg,FALSE);
  382.         hDlgModeless = CreateDialogParam(phInstance,"CancelDlgBox",hwndimg,CancelDlgProc,(LPARAM)szAppName);
  383.         SetAbortProc(printer, PrintAbortProc);
  384.         di.cbSize = sizeof(DOCINFO);
  385.         di.lpszDocName = szAppName;
  386.         di.lpszOutput = NULL;
  387.         if (StartDoc(printer, &di) > 0) {
  388.             while ( hDlgModeless &&  ((count = fread(buf+2, 1, 4096, f)) != 0) ) {
  389.             *bufcount = count;
  390.             Escape(printer, PASSTHROUGH, count+2, (LPSTR)buf, NULL);
  391.                 ldone += count;
  392.                 sprintf(pcdone, fmt, (int)(ldone * 100 / lsize));
  393.                 SetWindowText(GetDlgItem(hDlgModeless, CANCEL_PCDONE), pcdone);
  394.             }
  395.             if (hDlgModeless)
  396.             EndDoc(printer);
  397.             else
  398.             AbortDoc(printer);
  399.         }
  400.         if (hDlgModeless) {
  401.             DestroyWindow(hDlgModeless);
  402.             error = FALSE;
  403.             hDlgModeless = (HWND)0;
  404.         }
  405.             EnableWindow(hwndimg,TRUE);
  406.             free(buf);
  407.         }
  408.       }
  409.       DeleteDC(printer);
  410.     }
  411.     fclose(f);
  412.     return !error;
  413. }
  414.  
  415. /* Print File */
  416. int
  417. gp_printfile_win95(char *filename, char *pmport)
  418. {
  419. /* Get printer port from win.ini, then copy to \\.\port */
  420. #define PRINT_BUF_SIZE 1048
  421. char *buffer;
  422. char *portname;
  423. int i, port;
  424. FILE *f;
  425. WORD count;
  426. int error = FALSE;
  427. long lsize;
  428. long ldone;
  429. char pcdone[20];
  430. MSG msg;
  431. FILE *outfile;
  432.  
  433.     /* get list of ports */
  434.     if ((buffer = malloc(PRINT_BUF_SIZE)) == (char *)NULL)
  435.         return FALSE;
  436.  
  437.     if ( (pmport == (char *)NULL) || (strlen(pmport)==0) || (strcmp(pmport, "PRN")==0) ) {
  438.         GetProfileString("ports", NULL, "", buffer, PRINT_BUF_SIZE);
  439.         /* select a port */
  440.         port = DialogBoxParam(phInstance, "SpoolDlgBox", hwndtext, SpoolDlgProc, (LPARAM)buffer);
  441.         if (!port) {
  442.             free(buffer);
  443.             return FALSE;
  444.         }
  445.         portname = buffer;
  446.         for (i=1; i<port && strlen(portname)!=0; i++)
  447.             portname += lstrlen(portname)+1;
  448.     }
  449.     else
  450.         portname = (char *)pmport;    /* Print Manager port name already supplied */
  451.  
  452.     if ((f = fopen(filename, "rb")) == (FILE *)NULL) {
  453.         free(buffer);
  454.         return FALSE;
  455.     }
  456.     fseek(f, 0L, SEEK_END);
  457.     lsize = ftell(f);
  458.     if (lsize <= 0)
  459.         lsize = 1;
  460.     fseek(f, 0L, SEEK_SET);
  461.  
  462.     
  463.     outfile = fopen(portname, "wb");
  464.     if (outfile == (FILE *)NULL) {
  465.         fclose(f);
  466.         free(buffer);
  467.         return FALSE;
  468.     }
  469.  
  470.     hDlgModeless = CreateDialog(phInstance, "CancelDlgBox", hwndtext, CancelDlgProc);
  471.     ldone = 0;
  472.  
  473.     while (!error && hDlgModeless 
  474.       && (count = fread(buffer, 1, PRINT_BUF_SIZE, f)) != 0 ) {
  475.         if (fwrite(buffer, 1, count, outfile) < count)
  476.         error = TRUE;
  477.         ldone += count;
  478.         sprintf(pcdone, "%d %%done", (int)(ldone * 100 / lsize));
  479.         SetWindowText(GetDlgItem(hDlgModeless, CANCEL_PCDONE), pcdone);
  480.         while (PeekMessage(&msg, hDlgModeless, 0, 0, PM_REMOVE)) {
  481.         if ((hDlgModeless == 0) || !IsDialogMessage(hDlgModeless, &msg)) {
  482.             TranslateMessage(&msg);
  483.             DispatchMessage(&msg);
  484.           }
  485.           }
  486.       }
  487.     free(buffer);
  488.     fclose(f);
  489.  
  490.     if (!hDlgModeless)
  491.         error=TRUE;
  492.     DestroyWindow(hDlgModeless);
  493.     hDlgModeless = 0;
  494.     fclose(outfile);
  495.     return !error;
  496. }
  497.  
  498. /* Print File */
  499. int
  500. gp_printfile(char *filename, char *pmport)
  501. {
  502.     if (is_win95)  /* perhaps WinNT should also use this version */
  503.         gp_printfile_win95(filename, pmport);
  504.     else
  505.         gp_printfile_win32s(filename, pmport);
  506. }
  507.  
  508. #else /* !__WIN32__ */
  509. /* Print File to port */
  510. /* port==NULL means prompt for port with dialog box */
  511. int
  512. gp_printfile(char *filename, char *port)
  513. {
  514. #define PRINT_BUF_SIZE 16384u
  515. char *buffer;
  516. char *portname;
  517. int i, iport;
  518. DLGPROC lpfnSpoolProc;
  519. HPJOB hJob;
  520. UINT count;
  521. FILE *f;
  522. int error = FALSE;
  523. DLGPROC lpfnCancelProc;
  524. long lsize;
  525. long ldone;
  526. char fmt[MAXSTR];
  527. char pcdone[10];
  528. MSG msg;
  529.  
  530.     if ((buffer = malloc(PRINT_BUF_SIZE)) == (char *)NULL)
  531.         return FALSE;
  532.     if (port == (char *)NULL) {
  533.         /* get list of ports */
  534.         GetProfileString("ports", NULL, "", buffer, PRINT_BUF_SIZE);
  535.         /* select a port */
  536.         lpfnSpoolProc = (DLGPROC)MakeProcInstance((FARPROC)SpoolDlgProc, phInstance);
  537.         iport = DialogBoxParam(phInstance, "SpoolDlgBox", hwndtext, lpfnSpoolProc, (LPARAM)buffer);
  538.         FreeProcInstance((FARPROC)lpfnSpoolProc);
  539.         if (!iport) {
  540.         free(buffer);
  541.         return FALSE;
  542.         }
  543.         portname = buffer;
  544.         for (i=1; i<iport && strlen(portname)!=0; i++)
  545.         portname += lstrlen(portname)+1;
  546.     }
  547.     else
  548.         portname = port;
  549.     
  550.     if ((f = fopen(filename, "rb")) == (FILE *)NULL) {
  551.         free(buffer);
  552.         return FALSE;
  553.     }
  554.     fseek(f, 0L, SEEK_END);
  555.     lsize = ftell(f);
  556.     if (lsize <= 0)
  557.         lsize = 1;
  558.     fseek(f, 0L, SEEK_SET);
  559.  
  560.     hJob = OpenJob(portname, filename, (HDC)NULL);
  561.     switch ((int)hJob) {
  562.         case SP_APPABORT:
  563.         case SP_ERROR:
  564.         case SP_OUTOFDISK:
  565.         case SP_OUTOFMEMORY:
  566.         case SP_USERABORT:
  567.             fclose(f);
  568.         free(buffer);
  569.             return FALSE;
  570.     }
  571.     if (StartSpoolPage(hJob) < 0)
  572.         error = TRUE;
  573.  
  574.     lpfnCancelProc = (DLGPROC)MakeProcInstance((FARPROC)CancelDlgProc, phInstance);
  575.     hDlgModeless = CreateDialog(phInstance, "CancelDlgBox", hwndimg, lpfnCancelProc);
  576.     ldone = 0;
  577.     LoadString(phInstance, IDS_CANCELDONE, fmt, sizeof(fmt));
  578.  
  579.     while (!error && hDlgModeless 
  580.       && (count = fread(buffer, 1, PRINT_BUF_SIZE, f)) != 0 ) {
  581.         if (WriteSpool(hJob, buffer, count) < 0)
  582.         error = TRUE;
  583.         ldone += count;
  584.         sprintf(pcdone, fmt, (int)(ldone * 100 / lsize));
  585.         SetWindowText(GetDlgItem(hDlgModeless, CANCEL_PCDONE), pcdone);
  586.         while (PeekMessage(&msg, hDlgModeless, 0, 0, PM_REMOVE)) {
  587.             if ((hDlgModeless == 0) || !IsDialogMessage(hDlgModeless, &msg)) {
  588.             TranslateMessage(&msg);
  589.             DispatchMessage(&msg);
  590.         }
  591.         }
  592.     }
  593.     free(buffer);
  594.     fclose(f);
  595.  
  596.     if (!hDlgModeless)
  597.         error=TRUE;
  598.     DestroyWindow(hDlgModeless);
  599.     hDlgModeless = 0;
  600.     FreeProcInstance((FARPROC)lpfnCancelProc);
  601.     EndSpoolPage(hJob);
  602.     if (error)
  603.         DeleteJob(hJob, 0);
  604.     else
  605.         CloseJob(hJob);
  606.     return !error;
  607. }
  608. #endif /* !__WIN32__ */
  609.  
  610.  
  611. /* cleanup print temporary files */
  612. void
  613. print_cleanup(void)
  614. {
  615.     if ((pcfname[0] != '\0') && !debug)
  616.         unlink(pcfname);
  617.     pcfname[0] = '\0';
  618.     if ((pfname[0] != '\0') && !debug)
  619.         unlink(pfname);
  620.     pfname[0] = '\0';
  621. }
  622.  
  623.  
  624. /* print a range of pages using a Ghostscript device */
  625. void
  626. gsview_print(BOOL to_file)
  627. {
  628.     BOOL flag;
  629. #ifndef __WIN32__
  630.     DLGPROC lpProcDevice;
  631. #endif
  632.     char command[256];
  633.  
  634.     if (psfile.name[0] == '\0') {
  635.         gserror(IDS_NOTOPEN, NULL, MB_ICONEXCLAMATION, SOUND_NOTOPEN);
  636.         return;
  637.     }
  638.     
  639.     LoadString(phInstance, IDS_TOPICPRINT, szHelpTopic, sizeof(szHelpTopic));
  640. #ifdef __WIN32__
  641.     flag = DialogBoxParam( phInstance, "DeviceDlgBox", hwndimg, DeviceDlgProc, (LPARAM)NULL);
  642. #else
  643.     lpProcDevice = (DLGPROC)MakeProcInstance((FARPROC)DeviceDlgProc, phInstance);
  644.     flag = DialogBoxParam( phInstance, "DeviceDlgBox", hwndimg, lpProcDevice, (LPARAM)NULL);
  645.     FreeProcInstance((FARPROC)lpProcDevice);
  646. #endif
  647.     if (!flag)
  648.         return;
  649.  
  650.     load_string(IDS_WAITGSCLOSE, szWait, sizeof(szWait));
  651.     info_wait(TRUE);
  652.     gs_close();    /* we need a new Ghostscript */
  653.     info_wait(FALSE);
  654.  
  655.     if (!gsview_cprint(to_file, pcfname, pfname))
  656.         return;
  657.  
  658.     sprintf(command,"%s -sGSVIEW=%u @%s", option.gscommand,
  659.         (unsigned int)hwndimg, pfname);
  660.  
  661.     if (strlen(command) > 126) {
  662.         /* command line too long */
  663.         gserror(IDS_TOOLONG, command, MB_ICONSTOP, SOUND_ERROR);
  664.         unlink(pfname);
  665.         pfname[0] = '\0';
  666.         gsprog.hinst = (HINSTANCE)NULL;
  667.         return;
  668.     }
  669.     load_string(IDS_WAITGSOPEN, szWait, sizeof(szWait));
  670.     info_wait(TRUE);
  671.     gsprog.hinst = (HINSTANCE)WinExec(command, SW_SHOWMINNOACTIVE);
  672.  
  673. #ifdef __WIN32__
  674.     if (gsprog.hinst == NULL)
  675. #else
  676.     if (gsprog.hinst < HINSTANCE_ERROR)
  677. #endif
  678.     {
  679.         gserror(IDS_CANNOTRUN, command, MB_ICONSTOP, SOUND_ERROR);
  680.         unlink(pfname);
  681.         pfname[0] = '\0';
  682.         info_wait(FALSE);
  683.         gsprog.hinst = (HINSTANCE)NULL;
  684.         return;
  685.     }
  686.  
  687. /*
  688.     set_timer(timeout*pages);
  689. */
  690.     load_string(IDS_WAITPRINT, szWait, sizeof(szWait));
  691.     info_wait(TRUE);
  692.     return;
  693. }
  694.  
  695.  
  696.