2 * Print spooler and PQ functions
4 * Copyright 1996 John Harvey
16 #include "wine/winuser16.h"
25 DEFAULT_DEBUG_CHANNEL(print)
27 /**********************************************************************
28 * QueryAbort (GDI.155)
30 * Calls the app's AbortProc function if avail.
33 * TRUE if no AbortProc avail or AbortProc wants to continue printing.
34 * FALSE if AbortProc wants to abort printing.
36 BOOL16 WINAPI QueryAbort16(HDC16 hdc, INT16 reserved)
38 DC *dc = DC_GetDCPtr( hdc );
40 if ((!dc) || (!dc->w.lpfnPrint))
42 return Callbacks->CallDrvAbortProc(dc->w.lpfnPrint, hdc, 0);
45 /**********************************************************************
46 * SetAbortProc16 (GDI.381)
49 INT16 WINAPI SetAbortProc16(HDC16 hdc, SEGPTR abrtprc)
51 return Escape16(hdc, SETABORTPROC, 0, abrtprc, (SEGPTR)0);
54 /**********************************************************************
55 * SetAbortProc32 (GDI32.301)
58 INT WINAPI SetAbortProc(HDC hdc, ABORTPROC abrtprc)
60 FIXME(print, "stub\n");
61 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
66 /****************** misc. printer related functions */
69 * The following function should implement a queing system
81 static struct hpq *hpqueue;
83 /**********************************************************************
87 HPQ WINAPI CreatePQ16(int size)
95 if (!(hpq = GlobalAlloc16(GMEM_SHARE|GMEM_MOVEABLE, tmp_size + 8)))
97 pPQ = GlobalLock16(hpq);
106 FIXME(print, "(%d): stub\n",size);
111 /**********************************************************************
115 int WINAPI DeletePQ16(HPQ hPQ)
117 return GlobalFree16((HGLOBAL16)hPQ);
120 /**********************************************************************
121 * ExtractPQ (GDI.232)
124 int WINAPI ExtractPQ16(HPQ hPQ)
126 struct hpq *queue, *prev, *current, *currentPrev;
127 int key = 0, tag = -1;
128 currentPrev = prev = NULL;
129 queue = current = hpqueue;
135 currentPrev = current;
136 current = current->next;
139 if (current->key < key)
151 prev->next = queue->next;
153 hpqueue = queue->next;
157 TRACE(print, "%x got tag %d key %d\n", hPQ, tag, key);
162 /**********************************************************************
166 int WINAPI InsertPQ16(HPQ hPQ, int tag, int key)
168 struct hpq *queueItem = xmalloc(sizeof(struct hpq));
169 queueItem->next = hpqueue;
171 queueItem->key = key;
172 queueItem->tag = tag;
174 FIXME(print, "(%x %d %d): stub???\n", hPQ, tag, key);
178 /**********************************************************************
182 int WINAPI MinPQ16(HPQ hPQ)
184 FIXME(print, "(%x): stub\n", hPQ);
188 /**********************************************************************
192 int WINAPI SizePQ16(HPQ hPQ, int sizechange)
194 FIXME(print, "(%x %d): stub\n", hPQ, sizechange);
201 * The following functions implement part of the spooling process to
202 * print manager. I would like to see wine have a version of print managers
203 * that used LPR/LPD. For simplicity print jobs will be sent to a file for
206 typedef struct PRINTJOB
214 } PRINTJOB, *PPRINTJOB;
216 #define MAX_PRINT_JOBS 1
219 PPRINTJOB gPrintJobsTable[MAX_PRINT_JOBS];
222 static PPRINTJOB FindPrintJobFromHandle(HANDLE16 hHandle)
224 return gPrintJobsTable[0];
227 /* TTD Need to do some DOS->UNIX file conversion here */
228 static int CreateSpoolFile(LPSTR pszOutput)
232 char *psCmdP = psCmd;
234 /* TTD convert the 'output device' into a spool file name */
236 if (pszOutput == NULL || *pszOutput == '\0')
239 PROFILE_GetWineIniString( "spooler", pszOutput, "", psCmd, sizeof(psCmd) );
240 TRACE(print, "Got printerSpoolCommand '%s' for output device '%s'\n",
246 while (*psCmdP && isspace(*psCmdP))
262 TRACE(print, "In child need to exec %s\n",psCmdP);
272 TRACE(print,"Need to execute a cmnd and pipe the output to it\n");
276 TRACE(print, "Just assume its a file\n");
278 if ((fd = open(psCmdP, O_CREAT | O_TRUNC | O_WRONLY , 0600)) < 0)
280 ERR(print, "Failed to create spool file %s, errno = %d\n",
287 static int FreePrintJob(HANDLE16 hJob)
292 pPrintJob = FindPrintJobFromHandle(hJob);
293 if (pPrintJob != NULL)
295 gPrintJobsTable[pPrintJob->nIndex] = NULL;
296 free(pPrintJob->pszOutput);
297 free(pPrintJob->pszTitle);
298 if (pPrintJob->fd >= 0) close(pPrintJob->fd);
305 /**********************************************************************
309 HANDLE16 WINAPI OpenJob16(LPSTR lpOutput, LPSTR lpTitle, HDC16 hDC)
311 HANDLE16 hHandle = (HANDLE16)SP_ERROR;
314 TRACE(print, "'%s' '%s' %04x\n", lpOutput, lpTitle, hDC);
316 pPrintJob = gPrintJobsTable[0];
317 if (pPrintJob == NULL)
321 /* Try an create a spool file */
322 fd = CreateSpoolFile(lpOutput);
327 pPrintJob = xmalloc(sizeof(PRINTJOB));
328 memset(pPrintJob, 0, sizeof(PRINTJOB));
330 pPrintJob->pszOutput = strdup(lpOutput);
332 pPrintJob->pszTitle = strdup(lpTitle);
333 pPrintJob->hDC = hDC;
335 pPrintJob->nIndex = 0;
336 pPrintJob->hHandle = hHandle;
337 gPrintJobsTable[pPrintJob->nIndex] = pPrintJob;
340 TRACE(print, "return %04x\n", hHandle);
344 /**********************************************************************
348 int WINAPI CloseJob16(HANDLE16 hJob)
351 PPRINTJOB pPrintJob = NULL;
353 TRACE(print, "%04x\n", hJob);
355 pPrintJob = FindPrintJobFromHandle(hJob);
356 if (pPrintJob != NULL)
358 /* Close the spool file */
359 close(pPrintJob->fd);
366 /**********************************************************************
367 * WriteSpool (GDI.241)
370 int WINAPI WriteSpool16(HANDLE16 hJob, LPSTR lpData, WORD cch)
373 PPRINTJOB pPrintJob = NULL;
375 TRACE(print, "%04x %08lx %04x\n", hJob, (DWORD)lpData, cch);
377 pPrintJob = FindPrintJobFromHandle(hJob);
378 if (pPrintJob != NULL && pPrintJob->fd >= 0 && cch)
380 if (write(pPrintJob->fd, lpData, cch) != cch)
384 if (pPrintJob->hDC == 0) {
385 TRACE(print, "hDC == 0 so no QueryAbort\n");
387 else if (!(QueryAbort16(pPrintJob->hDC, (nRet == SP_OUTOFDISK) ? nRet : 0 )))
389 CloseJob16(hJob); /* printing aborted */
396 /**********************************************************************
397 * WriteDialog (GDI.242)
400 int WINAPI WriteDialog16(HANDLE16 hJob, LPSTR lpMsg, WORD cchMsg)
404 TRACE(print, "%04x %04x '%s'\n", hJob, cchMsg, lpMsg);
406 nRet = MessageBox16(0, lpMsg, "Printing Error", MB_OKCANCEL);
411 /**********************************************************************
412 * DeleteJob (GDI.244)
415 int WINAPI DeleteJob16(HANDLE16 hJob, WORD wNotUsed)
419 TRACE(print, "%04x\n", hJob);
421 nRet = FreePrintJob(hJob);
426 * The following two function would allow a page to be sent to the printer
427 * when it has been processed. For simplicity they havn't been implemented.
428 * This means a whole job has to be processed before it is sent to the printer.
431 /**********************************************************************
432 * StartSpoolPage (GDI.246)
435 int WINAPI StartSpoolPage16(HANDLE16 hJob)
437 FIXME(print, "StartSpoolPage GDI.246 unimplemented\n");
443 /**********************************************************************
444 * EndSpoolPage (GDI.247)
447 int WINAPI EndSpoolPage16(HANDLE16 hJob)
449 FIXME(print, "EndSpoolPage GDI.247 unimplemented\n");
454 /**********************************************************************
455 * GetSpoolJob (GDI.245)
458 DWORD WINAPI GetSpoolJob16(int nOption, LONG param)
461 TRACE(print, "In GetSpoolJob param 0x%lx noption %d\n",param, nOption);