2 * Print spooler and PQ functions
4 * Copyright 1996 John Harvey
23 /**********************************************************************
24 * QueryAbort (GDI.155)
26 * Calls the app's AbortProc function if avail.
29 * TRUE if no AbortProc avail or AbortProc wants to continue printing.
30 * FALSE if AbortProc wants to abort printing.
32 BOOL16 WINAPI
QueryAbort(HDC16 hdc
, INT16 reserved
)
34 DC
*dc
= DC_GetDCPtr( hdc
);
36 if ((!dc
) || (!dc
->w
.lpfnPrint
))
38 return Callbacks
->CallDrvAbortProc(dc
->w
.lpfnPrint
, hdc
, 0);
41 /**********************************************************************
42 * SetAbortProc (GDI.381)
45 INT16 WINAPI
SetAbortProc(HDC16 hdc
, FARPROC16 abrtprc
)
47 DC
*dc
= DC_GetDCPtr( hdc
);
50 dc
->w
.lpfnPrint
= abrtprc
;
56 /****************** misc. printer related functions */
59 * The following function should implement a queing system
71 static struct hpq
*hpqueue
;
73 /**********************************************************************
77 HPQ WINAPI
CreatePQ(int size
)
85 if (!(hpq
= GlobalAlloc16(GMEM_SHARE
|GMEM_MOVEABLE
, tmp_size
+ 8)))
87 pPQ
= GlobalLock16(hpq
);
96 FIXME(print
, "(%d): stub\n",size
);
101 /**********************************************************************
105 int WINAPI
DeletePQ(HPQ hPQ
)
107 return GlobalFree16((HGLOBAL16
)hPQ
);
110 /**********************************************************************
111 * ExtractPQ (GDI.232)
114 int WINAPI
ExtractPQ(HPQ hPQ
)
116 struct hpq
*queue
, *prev
, *current
, *currentPrev
;
117 int key
= 0, tag
= -1;
118 currentPrev
= prev
= NULL
;
119 queue
= current
= hpqueue
;
125 currentPrev
= current
;
126 current
= current
->next
;
129 if (current
->key
< key
)
141 prev
->next
= queue
->next
;
143 hpqueue
= queue
->next
;
147 TRACE(print
, "%x got tag %d key %d\n", hPQ
, tag
, key
);
152 /**********************************************************************
156 int WINAPI
InsertPQ(HPQ hPQ
, int tag
, int key
)
158 struct hpq
*queueItem
= xmalloc(sizeof(struct hpq
));
159 queueItem
->next
= hpqueue
;
161 queueItem
->key
= key
;
162 queueItem
->tag
= tag
;
164 FIXME(print
, "(%x %d %d): stub???\n", hPQ
, tag
, key
);
168 /**********************************************************************
172 int WINAPI
MinPQ(HPQ hPQ
)
174 FIXME(print
, "(%x): stub\n", hPQ
);
178 /**********************************************************************
182 int WINAPI
SizePQ(HPQ hPQ
, int sizechange
)
184 FIXME(print
, "(%x %d): stub\n", hPQ
, sizechange
);
191 * The following functions implement part of the spooling process to
192 * print manager. I would like to see wine have a version of print managers
193 * that used LPR/LPD. For simplicity print jobs will be sent to a file for
196 typedef struct PRINTJOB
204 } PRINTJOB
, *PPRINTJOB
;
206 #define MAX_PRINT_JOBS 1
209 PPRINTJOB gPrintJobsTable
[MAX_PRINT_JOBS
];
212 static PPRINTJOB
FindPrintJobFromHandle(HANDLE16 hHandle
)
214 return gPrintJobsTable
[0];
217 /* TTD Need to do some DOS->UNIX file conversion here */
218 static int CreateSpoolFile(LPSTR pszOutput
)
222 char *psCmdP
= psCmd
;
224 /* TTD convert the 'output device' into a spool file name */
226 if (pszOutput
== NULL
|| *pszOutput
== '\0')
229 PROFILE_GetWineIniString( "spooler", pszOutput
, "", psCmd
, sizeof(psCmd
) );
230 TRACE(print
, "Got printerSpoolCommand '%s' for output device '%s'\n",
236 while (*psCmdP
&& isspace(*psCmdP
))
252 TRACE(print
, "In child need to exec %s\n",psCmdP
);
262 TRACE(print
,"Need to execute a cmnd and pipe the output to it\n");
266 TRACE(print
, "Just assume its a file\n");
268 if ((fd
= open(psCmdP
, O_CREAT
| O_TRUNC
| O_WRONLY
, 0600)) < 0)
270 ERR(print
, "Failed to create spool file %s, errno = %d\n",
277 static int FreePrintJob(HANDLE16 hJob
)
282 pPrintJob
= FindPrintJobFromHandle(hJob
);
283 if (pPrintJob
!= NULL
)
285 gPrintJobsTable
[pPrintJob
->nIndex
] = NULL
;
286 free(pPrintJob
->pszOutput
);
287 free(pPrintJob
->pszTitle
);
288 if (pPrintJob
->fd
>= 0) close(pPrintJob
->fd
);
295 /**********************************************************************
299 HANDLE16 WINAPI
OpenJob(LPSTR lpOutput
, LPSTR lpTitle
, HDC16 hDC
)
301 HANDLE16 hHandle
= (HANDLE16
)SP_ERROR
;
304 TRACE(print
, "'%s' '%s' %04x\n", lpOutput
, lpTitle
, hDC
);
306 pPrintJob
= gPrintJobsTable
[0];
307 if (pPrintJob
== NULL
)
311 /* Try an create a spool file */
312 fd
= CreateSpoolFile(lpOutput
);
317 pPrintJob
= xmalloc(sizeof(PRINTJOB
));
318 memset(pPrintJob
, 0, sizeof(PRINTJOB
));
320 pPrintJob
->pszOutput
= strdup(lpOutput
);
322 pPrintJob
->pszTitle
= strdup(lpTitle
);
323 pPrintJob
->hDC
= hDC
;
325 pPrintJob
->nIndex
= 0;
326 pPrintJob
->hHandle
= hHandle
;
327 gPrintJobsTable
[pPrintJob
->nIndex
] = pPrintJob
;
330 TRACE(print
, "return %04x\n", hHandle
);
334 /**********************************************************************
338 int WINAPI
CloseJob(HANDLE16 hJob
)
341 PPRINTJOB pPrintJob
= NULL
;
343 TRACE(print
, "%04x\n", hJob
);
345 pPrintJob
= FindPrintJobFromHandle(hJob
);
346 if (pPrintJob
!= NULL
)
348 /* Close the spool file */
349 close(pPrintJob
->fd
);
356 /**********************************************************************
357 * WriteSpool (GDI.241)
360 int WINAPI
WriteSpool(HANDLE16 hJob
, LPSTR lpData
, WORD cch
)
363 PPRINTJOB pPrintJob
= NULL
;
365 TRACE(print
, "%04x %08lx %04x\n", hJob
, (DWORD
)lpData
, cch
);
367 pPrintJob
= FindPrintJobFromHandle(hJob
);
368 if (pPrintJob
!= NULL
&& pPrintJob
->fd
>= 0 && cch
)
370 if (write(pPrintJob
->fd
, lpData
, cch
) != cch
)
374 if (pPrintJob
->hDC
== 0) {
375 TRACE(print
, "hDC == 0 so no QueryAbort\n");
377 else if (!(QueryAbort(pPrintJob
->hDC
, (nRet
== SP_OUTOFDISK
) ? nRet
: 0 )))
379 CloseJob(hJob
); /* printing aborted */
386 /**********************************************************************
387 * WriteDialog (GDI.242)
390 int WINAPI
WriteDialog(HANDLE16 hJob
, LPSTR lpMsg
, WORD cchMsg
)
394 TRACE(print
, "%04x %04x '%s'\n", hJob
, cchMsg
, lpMsg
);
396 nRet
= MessageBox16(0, lpMsg
, "Printing Error", MB_OKCANCEL
);
401 /**********************************************************************
402 * DeleteJob (GDI.244)
405 int WINAPI
DeleteJob(HANDLE16 hJob
, WORD wNotUsed
)
409 TRACE(print
, "%04x\n", hJob
);
411 nRet
= FreePrintJob(hJob
);
416 * The following two function would allow a page to be sent to the printer
417 * when it has been processed. For simplicity they havn't been implemented.
418 * This means a whole job has to be processed before it is sent to the printer.
421 /**********************************************************************
422 * StartSpoolPage (GDI.246)
425 int WINAPI
StartSpoolPage(HANDLE16 hJob
)
427 FIXME(print
, "StartSpoolPage GDI.246 unimplemented\n");
433 /**********************************************************************
434 * EndSpoolPage (GDI.247)
437 int WINAPI
EndSpoolPage(HANDLE16 hJob
)
439 FIXME(print
, "EndSpoolPage GDI.247 unimplemented\n");
444 /**********************************************************************
445 * GetSpoolJob (GDI.245)
448 DWORD WINAPI
GetSpoolJob(int nOption
, LONG param
)
451 TRACE(print
, "In GetSpoolJob param 0x%lx noption %d\n",param
, nOption
);