1/*
2
3PDF Writer printer driver.
4
5Copyright (c) 2001-2003 OpenBeOS.
6
7Authors:
8	Philippe Houdoin
9	Simon Gauvin
10	Michael Pfeiffer
11
12Permission is hereby granted, free of charge, to any person obtaining a copy of
13this software and associated documentation files (the "Software"), to deal in
14the Software without restriction, including without limitation the rights to
15use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
16of the Software, and to permit persons to whom the Software is furnished to do
17so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28THE SOFTWARE.
29
30*/
31
32
33#include <stdio.h>
34#include <string.h>			// for memset()
35
36#include <StorageKit.h>
37
38#include "PrinterDriver.h"
39
40#include "PageSetupWindow.h"
41#include "JobSetupWindow.h"
42#include "StatusWindow.h"
43#include "PrinterSettings.h"
44#include "Report.h"
45
46// Private prototypes
47// ------------------
48
49#ifdef CODEWARRIOR
50	#pragma mark [Constructor & destructor]
51#endif
52
53// Constructor & destructor
54// ------------------------
55
56// --------------------------------------------------
57PrinterDriver::PrinterDriver()
58	:	fJobFile(NULL),
59		fPrinterNode(NULL),
60		fJobMsg(NULL)
61{
62}
63
64
65// --------------------------------------------------
66PrinterDriver::~PrinterDriver()
67{
68}
69
70#ifdef CODEWARRIOR
71	#pragma mark [Public methods]
72#endif
73
74#ifdef B_BEOS_VERSION_DANO
75struct print_file_header {
76       int32   version;
77       int32   page_count;
78       off_t   first_page;
79       int32   _reserved_3_;
80       int32   _reserved_4_;
81       int32   _reserved_5_;
82};
83#endif
84
85// Public methods
86// --------------
87
88status_t
89PrinterDriver::PrintJob
90	(
91	BFile 		*jobFile,		// spool file
92	BNode 		*printerNode,	// printer node, used by OpenTransport() to find & load transport add-on
93	BMessage 	*jobMsg			// job message
94	)
95{
96	print_file_header	pfh;
97	status_t			status;
98	BMessage 			*msg;
99	int32 				page;
100	uint32				copy;
101	uint32				copies;
102	const int32         passes = 2;
103
104	fJobFile		= jobFile;
105	fPrinterNode	= printerNode;
106	fJobMsg			= jobMsg;
107
108	if (!fJobFile || !fPrinterNode)
109		return B_ERROR;
110
111	if (fPrintTransport.Open(fPrinterNode) != B_OK) {
112		return B_ERROR;
113	}
114	if (fPrintTransport.IsPrintToFileCanceled()) {
115		return B_OK;
116	}
117
118	// read print file header
119	fJobFile->Seek(0, SEEK_SET);
120	fJobFile->Read(&pfh, sizeof(pfh));
121
122	// read job message
123	fJobMsg = msg = new BMessage();
124	msg->Unflatten(fJobFile);
125	// We have to load the settings here for Dano/Zeta because they don't store
126	// all fields from the message returned by config_job in the job file!
127	PrinterSettings::Read(printerNode, msg, PrinterSettings::kJobSettings);
128
129	if (msg->HasInt32("copies")) {
130		copies = msg->FindInt32("copies");
131	} else {
132		copies = 1;
133	}
134
135	// force creation of Report object
136	Report::Instance();
137
138	// show status window
139	StatusWindow* statusWindow = new StatusWindow(passes, pfh.page_count, this);
140
141	status = BeginJob();
142
143	fPrinting = true;
144	for (fPass = 0; fPass < passes && status == B_OK && fPrinting; fPass++) {
145		for (copy = 0; copy < copies && status == B_OK && fPrinting; copy++)
146		{
147			for (page = 1; page <= pfh.page_count && status == B_OK && fPrinting; page++) {
148				statusWindow->NextPage();
149				status = PrintPage(page, pfh.page_count);
150			}
151
152			// re-read job message for next page
153			fJobFile->Seek(sizeof(pfh), SEEK_SET);
154			msg->Unflatten(fJobFile);
155		}
156	}
157
158	status_t s = EndJob();
159	if (status == B_OK) status = s;
160
161	delete fJobMsg;
162
163	// close status window
164	if (Report::Instance()->CountItems() != 0) {
165		statusWindow->WaitForClose();
166	}
167	if (statusWindow->Lock()) {
168		statusWindow->Quit();
169	}
170
171	// delete Report object
172	Report::Instance()->Free();
173
174	return status;
175}
176
177/**
178 * This will stop the printing loop
179 *
180 * @param none
181 * @return void
182 */
183void
184PrinterDriver::StopPrinting()
185{
186	fPrinting = false;
187}
188
189
190// --------------------------------------------------
191status_t
192PrinterDriver::BeginJob()
193{
194	return B_OK;
195}
196
197
198// --------------------------------------------------
199status_t
200PrinterDriver::PrintPage(int32 pageNumber, int32 pageCount)
201{
202	char text[128];
203
204	sprintf(text, "Faking print of page %" B_PRId32 "/%" B_PRId32 "...", pageNumber, pageCount);
205	BAlert *alert = new BAlert("PrinterDriver::PrintPage()", text, "Hmm?");
206	alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
207	alert->Go();
208	return B_OK;
209}
210
211
212// --------------------------------------------------
213status_t
214PrinterDriver::EndJob()
215{
216	return B_OK;
217}
218
219
220// --------------------------------------------------
221status_t
222PrinterDriver::PrinterSetup(char *printerName)
223	// name of printer, to attach printer settings
224{
225	return B_OK;
226}
227
228
229// --------------------------------------------------
230status_t
231PrinterDriver::PageSetup(BMessage *setupMsg, const char *printerName)
232{
233	PageSetupWindow *psw;
234
235	psw = new PageSetupWindow(setupMsg, printerName);
236	return psw->Go();
237}
238
239
240// --------------------------------------------------
241status_t
242PrinterDriver::JobSetup(BMessage *jobMsg, const char *printerName)
243{
244	// set default value if property not set
245	if (!jobMsg->HasInt32("copies"))
246		jobMsg->AddInt32("copies", 1);
247
248	if (!jobMsg->HasInt32("first_page"))
249		jobMsg->AddInt32("first_page", 1);
250
251	if (!jobMsg->HasInt32("last_page"))
252		jobMsg->AddInt32("last_page", MAX_INT32);
253
254	JobSetupWindow * jsw;
255
256	jsw = new JobSetupWindow(jobMsg, printerName);
257	return jsw->Go();
258}
259
260#ifdef CODEWARRIOR
261	#pragma mark [Privates routines]
262#endif
263
264// Private routines
265// ----------------
266