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