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);