2 * Print spooler and PQ functions
4 * Copyright 1996 John Harvey
20 #include "wine/winuser16.h"
24 /**********************************************************************
25 * QueryAbort (GDI.155)
27 * Calls the app's AbortProc function if avail.
30 * TRUE if no AbortProc avail or AbortProc wants to continue printing.
31 * FALSE if AbortProc wants to abort printing.
33 BOOL16 WINAPI QueryAbort(HDC16 hdc, INT16 reserved)
35 DC *dc = DC_GetDCPtr( hdc );
37 if ((!dc) || (!dc->w.lpfnPrint))
39 return Callbacks->CallDrvAbortProc(dc->w.lpfnPrint, hdc, 0);
42 /**********************************************************************
43 * SetAbortProc16 (GDI.381)
46 INT16 WINAPI SetAbortProc16(HDC16 hdc, SEGPTR abrtprc)
48 return Escape16(hdc, SETABORTPROC, 0, abrtprc, (SEGPTR)0);
51 /**********************************************************************
52 * SetAbortProc32 (GDI32.301)
55 INT32 WINAPI SetAbortProc32(HDC32 hdc, ABORTPROC32 abrtprc)
57 FIXME(print, "stub\n");
58 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
63 /****************** misc. printer related functions */
66 * The following function should implement a queing system
78 static struct hpq *hpqueue;
80 /**********************************************************************
84 HPQ WINAPI CreatePQ(int size)
92 if (!(hpq = GlobalAlloc16(GMEM_SHARE|GMEM_MOVEABLE, tmp_size + 8)))
94 pPQ = GlobalLock16(hpq);
103 FIXME(print, "(%d): stub\n",size);
108 /**********************************************************************
112 int WINAPI DeletePQ(HPQ hPQ)
114 return GlobalFree16((HGLOBAL16)hPQ);
117 /**********************************************************************
118 * ExtractPQ (GDI.232)
121 int WINAPI ExtractPQ(HPQ hPQ)
123 struct hpq *queue, *prev, *current, *currentPrev;
124 int key = 0, tag = -1;
125 currentPrev = prev = NULL;
126 queue = current = hpqueue;
132 currentPrev = current;
133 current = current->next;
136 if (current->key < key)
148 prev->next = queue->next;
150 hpqueue = queue->next;
154 TRACE(print, "%x got tag %d key %d\n", hPQ, tag, key);
159 /**********************************************************************
163 int WINAPI InsertPQ(HPQ hPQ, int tag, int key)
165 struct hpq *queueItem = xmalloc(sizeof(struct hpq));
166 queueItem->next = hpqueue;
168 queueItem->key = key;
169 queueItem->tag = tag;
171 FIXME(print, "(%x %d %d): stub???\n", hPQ, tag, key);
175 /**********************************************************************
179 int WINAPI MinPQ(HPQ hPQ)
181 FIXME(print, "(%x): stub\n", hPQ);
185 /**********************************************************************
189 int WINAPI SizePQ(HPQ hPQ, int sizechange)
191 FIXME(print, "(%x %d): stub\n", hPQ, sizechange);
198 * The following functions implement part of the spooling process to
199 * print manager. I would like to see wine have a version of print managers
200 * that used LPR/LPD. For simplicity print jobs will be sent to a file for
203 typedef struct PRINTJOB
211 } PRINTJOB, *PPRINTJOB;
213 #define MAX_PRINT_JOBS 1
216 PPRINTJOB gPrintJobsTable[MAX_PRINT_JOBS];
219 static PPRINTJOB FindPrintJobFromHandle(HANDLE16 hHandle)
221 return gPrintJobsTable[0];
224 /* TTD Need to do some DOS->UNIX file conversion here */
225 static int CreateSpoolFile(LPSTR pszOutput)
229 char *psCmdP = psCmd;
231 /* TTD convert the 'output device' into a spool file name */
233 if (pszOutput == NULL || *pszOutput == '\0')
236 PROFILE_GetWineIniString( "spooler", pszOutput, "", psCmd, sizeof(psCmd) );
237 TRACE(print, "Got printerSpoolCommand '%s' for output device '%s'\n",
243 while (*psCmdP && isspace(*psCmdP))
259 TRACE(print, "In child need to exec %s\n",psCmdP);
269 TRACE(print,"Need to execute a cmnd and pipe the output to it\n");
273 TRACE(print, "Just assume its a file\n");
275 if ((fd = open(psCmdP, O_CREAT | O_TRUNC | O_WRONLY , 0600)) < 0)
277 ERR(print, "Failed to create spool file %s, errno = %d\n",
284 static int FreePrintJob(HANDLE16 hJob)
289 pPrintJob = FindPrintJobFromHandle(hJob);
290 if (pPrintJob != NULL)
292 gPrintJobsTable[pPrintJob->nIndex] = NULL;
293 free(pPrintJob->pszOutput);
294 free(pPrintJob->pszTitle);
295 if (pPrintJob->fd >= 0) close(pPrintJob->fd);
302 /**********************************************************************
306 HANDLE16 WINAPI OpenJob(LPSTR lpOutput, LPSTR lpTitle, HDC16 hDC)
308 HANDLE16 hHandle = (HANDLE16)SP_ERROR;
311 TRACE(print, "'%s' '%s' %04x\n", lpOutput, lpTitle, hDC);
313 pPrintJob = gPrintJobsTable[0];
314 if (pPrintJob == NULL)
318 /* Try an create a spool file */
319 fd = CreateSpoolFile(lpOutput);
324 pPrintJob = xmalloc(sizeof(PRINTJOB));
325 memset(pPrintJob, 0, sizeof(PRINTJOB));
327 pPrintJob->pszOutput = strdup(lpOutput);
329 pPrintJob->pszTitle = strdup(lpTitle);
330 pPrintJob->hDC = hDC;
332 pPrintJob->nIndex = 0;
333 pPrintJob->hHandle = hHandle;
334 gPrintJobsTable[pPrintJob->nIndex] = pPrintJob;
337 TRACE(print, "return %04x\n", hHandle);
341 /**********************************************************************
345 int WINAPI CloseJob(HANDLE16 hJob)
348 PPRINTJOB pPrintJob = NULL;
350 TRACE(print, "%04x\n", hJob);
352 pPrintJob = FindPrintJobFromHandle(hJob);
353 if (pPrintJob != NULL)
355 /* Close the spool file */
356 close(pPrintJob->fd);
363 /**********************************************************************
364 * WriteSpool (GDI.241)
367 int WINAPI WriteSpool(HANDLE16 hJob, LPSTR lpData, WORD cch)
370 PPRINTJOB pPrintJob = NULL;
372 TRACE(print, "%04x %08lx %04x\n", hJob, (DWORD)lpData, cch);
374 pPrintJob = FindPrintJobFromHandle(hJob);
375 if (pPrintJob != NULL && pPrintJob->fd >= 0 && cch)
377 if (write(pPrintJob->fd, lpData, cch) != cch)
381 if (pPrintJob->hDC == 0) {
382 TRACE(print, "hDC == 0 so no QueryAbort\n");
384 else if (!(QueryAbort(pPrintJob->hDC, (nRet == SP_OUTOFDISK) ? nRet : 0 )))
386 CloseJob(hJob); /* printing aborted */
393 /**********************************************************************
394 * WriteDialog (GDI.242)
397 int WINAPI WriteDialog(HANDLE16 hJob, LPSTR lpMsg, WORD cchMsg)
401 TRACE(print, "%04x %04x '%s'\n", hJob, cchMsg, lpMsg);
403 nRet = MessageBox16(0, lpMsg, "Printing Error", MB_OKCANCEL);
408 /**********************************************************************
409 * DeleteJob (GDI.244)
412 int WINAPI DeleteJob(HANDLE16 hJob, WORD wNotUsed)
416 TRACE(print, "%04x\n", hJob);
418 nRet = FreePrintJob(hJob);
423 * The following two function would allow a page to be sent to the printer
424 * when it has been processed. For simplicity they havn't been implemented.
425 * This means a whole job has to be processed before it is sent to the printer.
428 /**********************************************************************
429 * StartSpoolPage (GDI.246)
432 int WINAPI StartSpoolPage(HANDLE16 hJob)
434 FIXME(print, "StartSpoolPage GDI.246 unimplemented\n");
440 /**********************************************************************
441 * EndSpoolPage (GDI.247)
444 int WINAPI EndSpoolPage(HANDLE16 hJob)
446 FIXME(print, "EndSpoolPage GDI.247 unimplemented\n");
451 /**********************************************************************
452 * GetSpoolJob (GDI.245)
455 DWORD WINAPI GetSpoolJob(int nOption, LONG param)
458 TRACE(print, "In GetSpoolJob param 0x%lx noption %d\n",param, nOption);