📄 gvpprn.c
字号:
/* Copyright (C) 1993-2000, Ghostgum Software Pty Ltd. All rights reserved.
This file is part of GSview.
This program is distributed with NO WARRANTY OF ANY KIND. No author
or distributor accepts any responsibility for the consequences of using it,
or for whether it serves any particular purpose or works at all, unless he
or she says so in writing. Refer to the GSview Free Public Licence
(the "Licence") for full details.
Every copy of GSview must include a copy of the Licence, normally in a
plain ASCII text file named LICENCE. The Licence grants you the right
to copy, modify and redistribute GSview, but only under certain conditions
described in the Licence. Among other things, the Licence requires that
the copyright notice and this notice be preserved on all copies.
*/
/* gvpprn.c */
/* Printer routines for PM GSview */
#include "gvpm.h"
char not_defined[] = "[Not defined]";
#define PRINT_BUF_SIZE 16384u
// Nasty globals
int print_gdi_width;
int print_gdi_height;
int print_gdi_xdpi;
int print_gdi_ydpi;
ULONG print_gdi_read_handle;
ULONG print_gdi_write_handle;
MRESULT EXPENTRY
SpoolDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
int notify_message;
int i, j;
char *entry;
switch(msg) {
case WM_INITDLG:
entry = (char *)mp2;
j = 0;
i = 0;
while (*entry) {
if ( strcmp(entry, option.printer_queue) == 0 )
j = i;
entry += strlen(entry)+1; /* skip to queue comment */
if (*entry) {
WinSendMsg( WinWindowFromID(hwnd, SPOOL_PORT),
LM_INSERTITEM, MPFROMLONG(LIT_END), MPFROMP(entry));
entry += strlen(entry)+1;
}
i++;
}
WinSendMsg( WinWindowFromID(hwnd, SPOOL_PORT),
LM_SELECTITEM, MPFROMLONG(j), MPFROMLONG(TRUE) );
break;
case WM_CONTROL:
notify_message = SHORT2FROMMP(mp1);
switch (notify_message) {
case LN_ENTER:
if (SHORT1FROMMP(mp1) == SPOOL_PORT)
WinPostMsg(hwnd, WM_COMMAND, (MPARAM)DID_OK, MPFROM2SHORT(CMDSRC_OTHER, TRUE));
break;
}
break;
case WM_COMMAND:
switch(LOUSHORT(mp1)) {
case ID_HELP:
get_help();
return (MRESULT)TRUE;
case DID_OK:
WinDismissDlg(hwnd, 1+(int)WinSendMsg(WinWindowFromID(hwnd, SPOOL_PORT),
LM_QUERYSELECTION, MPFROMSHORT(LIT_FIRST), (MPARAM)0));
return (MRESULT)TRUE;
case DID_CANCEL:
WinDismissDlg(hwnd, 0);
return (MRESULT)TRUE;
}
break;
}
return WinDefDlgProc(hwnd, msg, mp1, mp2);
}
char *
get_ports(char *buf, int len)
{
/* get port list from SplEnumQueue */
/* port list consists of entries formatted as follows */
/* queue_name,'\0',queue_comment,'\0' */
/* terminated by double null */
/* We need to use queue_name, user needs to see queue_comment */
SPLERR splerr;
ULONG cbBuf ;
ULONG cTotal;
ULONG cReturned ;
ULONG cbNeeded ;
ULONG ulLevel ;
ULONG i ;
PSZ pszComputerName ;
PBYTE pBuf ;
PPRQINFO3 prq ;
PBYTE pdrivbuf;
int used;
char *p;
used = 0;
p = buf;
ulLevel = 3L;
pszComputerName = (PSZ)NULL ;
splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, 0L, /* cbBuf */
&cReturned, &cTotal,
&cbNeeded, NULL);
if ( splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall ) {
if (!DosAllocMem( (PPVOID)&pBuf, cbNeeded,
PAG_READ|PAG_WRITE|PAG_COMMIT) ) {
cbBuf = cbNeeded ;
splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, cbBuf,
&cReturned, &cTotal,
&cbNeeded, NULL);
if ( (splerr == NO_ERROR) &&
!DosAllocMem((PPVOID)&pdrivbuf, 1024, PAG_READ|PAG_WRITE|PAG_COMMIT))
{
/* Set pointer to point to the beginning of the buffer. */
prq = (PPRQINFO3)pBuf;
/* cReturned has the count of the number of PRQINFO3 structures. */
for (i=0;i < cReturned ; i++) {
/* Don't list if connected to FILE */
splerr = SplQueryDevice(pszComputerName, prq->pszPrinters, 3,
pdrivbuf, 1024L, &cbNeeded);
if ((splerr != NO_ERROR) ||
(strcmp("FILE", (char *)(((PPRDINFO3)pdrivbuf)->pszLogAddr)) != 0))
{
used += strlen((char *)(prq->pszName)) + 1;
used += strlen((char *)(prq->pszComment)) + 1;
if (used < len) {
strcpy(p, (char *)(prq->pszName));
p += strlen(p)+1;
strcpy(p, (char *)(prq->pszComment));
p += strlen(p)+1;
}
}
prq++;
}/*endfor cReturned */
DosFreeMem((PVOID)pdrivbuf) ;
}
DosFreeMem((PVOID)pBuf) ;
}
} /* end if Q level given */
else {
*p++ = '\0';
*p = '\0';
return NULL;
}
*p = '\0';
return buf;
}
/* return TRUE if portname available */
/* return FALSE if cancelled or error */
/* if port non-NULL, use as suggested port */
BOOL
get_portname(char *portname, char *port)
{
char *buffer;
char *p;
int i, iport;
if ((buffer = (char *)malloc(PRINT_BUF_SIZE)) == (char *)NULL)
return FALSE;
/* get list of ports */
get_ports(buffer, PRINT_BUF_SIZE);
if (port != (char *)NULL) {
/* use specified port */
p = buffer;
while (strlen(p) != 0) {
if (strcmp(p, port)==0)
break;
p += strlen(p)+1; /* skip queue name */
if (*p)
p += strlen(p)+1; /* skip queue comment */
}
if (*p) {
strcpy(portname, "\\\\spool\\");
strcat(portname, p);
strcpy(option.printer_queue, p);
}
else
port = NULL; /* couldn't find it, so prompt for valid port */
}
if (port == (char *)NULL) {
/* select a port */
nHelpTopic = IDS_TOPICSPOOL;
iport = WinDlgBox(HWND_DESKTOP, hwnd_frame, SpoolDlgProc, hlanguage, IDD_SPOOL, buffer);
if (!iport || iport == 65536) {
free(buffer);
return FALSE;
}
p = buffer;
for (i=2; i<iport+iport && strlen(p)!=0; i++)
p += strlen(p)+1;
strcpy(portname, "\\\\spool\\");
strcat(portname, p);
strcpy(option.printer_queue, p);
}
if (strlen(portname) == 0)
return FALSE;
free(buffer);
return TRUE;
}
/* If strlen(queue_name)==0, return default queue and driver name */
/* If queue_name supplied, return driver_name */
/* returns 0 if OK, non-zero for error */
int
spl_find_queue(char *queue_name, char *driver_name)
{
SPLERR splerr;
ULONG cbBuf;
ULONG cTotal;
ULONG cReturned;
ULONG cbNeeded;
ULONG ulLevel;
ULONG i;
PSZ pszComputerName;
PBYTE pBuf;
PPRQINFO3 prq;
ulLevel = 3L;
pszComputerName = (PSZ)NULL ;
splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, 0L, /* cbBuf */
&cReturned, &cTotal,
&cbNeeded, NULL);
if ( splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall ) {
if (!DosAllocMem( (PPVOID)&pBuf, cbNeeded,
PAG_READ|PAG_WRITE|PAG_COMMIT) ) {
cbBuf = cbNeeded ;
splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, cbBuf,
&cReturned, &cTotal,
&cbNeeded, NULL);
if (splerr == NO_ERROR) {
/* Set pointer to point to the beginning of the buffer. */
prq = (PPRQINFO3)pBuf ;
/* cReturned has the count of the number of PRQINFO3 structures. */
for (i=0;i < cReturned ; i++) {
/* find queue name and return driver name */
if (strlen(queue_name)==0) { /* use default queue */
if ( prq->fsType & PRQ3_TYPE_APPDEFAULT )
strcpy(queue_name, (char *)(prq->pszName));
}
if (strcmp((char *)(prq->pszName), queue_name) == 0) {
char *p;
for (p=(char *)(prq->pszDriverName); *p && (*p!='.'); p++)
/* do nothing */ ;
*p = '\0'; /* truncate at '.' */
if (driver_name != NULL)
strcpy(driver_name, (char *)(prq->pszDriverName));
DosFreeMem((PVOID)pBuf) ;
return 0;
}
prq++;
}/*endfor cReturned */
}
DosFreeMem((PVOID)pBuf) ;
}
} /* end if Q level given */
else {
/* If we are here we had a bad error code. Print it and some other info.*/
gserror(0, "SplEnumQueue failed", MB_ICONEXCLAMATION, SOUND_ERROR);
}
if (splerr)
return splerr;
return -1;
}
/* Spool file to queue */
/* queue==NULL means prompt for port with dialog box */
/* return TRUE if successful, FALSE if error */
int
gp_printfile(char *filename, char *queue)
{
HSPL hspl;
PDEVOPENSTRUC pdata;
PSZ pszToken = (PBYTE)"*";
BOOL rc;
char queue_name[256];
char driver_name[256];
char port_name[256];
char *buffer;
FILE *f;
int count;
if (!get_portname(port_name, queue))
return FALSE;
strcpy(queue_name, port_name+8); /* ignore \\spool\ prefix */
spl_find_queue(queue_name, driver_name);
if ((buffer = (char *)malloc(PRINT_BUF_SIZE)) == (char *)NULL) {
gserror(0, "Out of memory in gp_printfile", MB_ICONEXCLAMATION, SOUND_ERROR);
return FALSE;
}
if ((f = fopen(filename, "rb")) == (FILE *)NULL) {
gserror(IDS_NOTEMP, NULL, MB_ICONEXCLAMATION, SOUND_ERROR);
free(buffer);
return FALSE;
}
/* Allocate memory for pdata */
if ( !DosAllocMem( (PPVOID)&pdata,sizeof( DEVOPENSTRUC ),
(PAG_READ|PAG_WRITE|PAG_COMMIT ) ) ) {
/* Initialize elements of pdata */
pdata->pszLogAddress = (PSZ)queue_name;
pdata->pszDriverName = (PSZ)driver_name;
pdata->pdriv = NULL;
pdata->pszDataType = (PSZ)"PM_Q_RAW";
pdata->pszComment = (PSZ)"GSview";
pdata->pszQueueProcName = NULL;
pdata->pszQueueProcParams = NULL;
pdata->pszSpoolerParams = NULL;
pdata->pszNetworkParams = NULL;
hspl = SplQmOpen( pszToken,5L,( PQMOPENDATA )pdata );
if ( hspl == SPL_ERROR ) {
gserror(0, "SplQMOpen failed", MB_ICONEXCLAMATION, SOUND_ERROR);
DosFreeMem((PVOID)pdata);
free(buffer);
fclose(f);
return FALSE; /* failed */
}
rc = SplQmStartDoc(hspl, (PBYTE)filename);
if (!rc) {
gserror(0, "SplQMStartDoc failed", MB_ICONEXCLAMATION, SOUND_ERROR);
DosFreeMem((PVOID)pdata);
free(buffer);
fclose(f);
return FALSE;
}
/* loop, copying file to queue */
while (rc && (count = fread(buffer, 1, PRINT_BUF_SIZE, f)) != 0 ) {
rc = SplQmWrite(hspl, count, buffer);
if (!rc)
gserror(0, "SplQMWrite failed", MB_ICONEXCLAMATION, SOUND_ERROR);
}
free(buffer);
fclose(f);
if (!rc) {
gserror(0, "Aborting Spooling", MB_ICONEXCLAMATION, SOUND_ERROR);
SplQmAbort(hspl);
}
else {
SplQmEndDoc(hspl);
rc = SplQmClose(hspl);
if (!rc)
gserror(0, "SplQMClose failed", MB_ICONEXCLAMATION, SOUND_ERROR);
}
}
else
rc = FALSE; /* no memory */
return rc;
}
void
strip_spaces(char *s)
{
char *d = s;
while (*s) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -