xref: /haiku/src/add-ons/print/drivers/preview/PrinterDriver.cpp (revision 9eb55bc1d104b8fda80898f8b25c94d8000c8255)
1 /*
2 
3 Preview printer driver.
4 
5 Copyright (c) 2003 OpenBeOS.
6 
7 Authors:
8 	Philippe Houdoin
9 	Simon Gauvin
10 	Michael Pfeiffer
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy of
13 this software and associated documentation files (the "Software"), to deal in
14 the Software without restriction, including without limitation the rights to
15 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
16 of the Software, and to permit persons to whom the Software is furnished to do
17 so, subject to the following conditions:
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 THE 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 "PrinterSetupWindow.h"
41 #include "PageSetupWindow.h"
42 #include "JobSetupWindow.h"
43 
44 // Private prototypes
45 // ------------------
46 
47 #ifdef CODEWARRIOR
48 	#pragma mark [Constructor & destructor]
49 #endif
50 
51 // Constructor & destructor
52 // ------------------------
53 
54 // --------------------------------------------------
55 PrinterDriver::PrinterDriver(BNode* printerNode)
56 	:	fJobFile(NULL),
57 		fPrinterNode(printerNode),
58 		fJobMsg(NULL)
59 {
60 }
61 
62 
63 // --------------------------------------------------
64 PrinterDriver::~PrinterDriver()
65 {
66 }
67 
68 #ifdef CODEWARRIOR
69 	#pragma mark [Public methods]
70 #endif
71 
72 #ifdef B_BEOS_VERSION_DANO
73 struct print_file_header {
74        int32   version;
75        int32   page_count;
76        off_t   first_page;
77        int32   _reserved_3_;
78        int32   _reserved_4_;
79        int32   _reserved_5_;
80 };
81 #endif
82 
83 
84 // Public methods
85 // --------------
86 
87 status_t
88 PrinterDriver::PrintJob
89 	(
90 	BFile 		*jobFile,		// spool file
91 	BMessage 	*jobMsg			// job message
92 	)
93 {
94 	print_file_header	pfh;
95 	status_t			status;
96 	BMessage 			*msg;
97 	int32 				page;
98 	uint32				copy;
99 	uint32				copies;
100 	const int32         passes = 2;
101 
102 	fJobFile		= jobFile;
103 	fJobMsg			= jobMsg;
104 
105 	if (!fJobFile || !fPrinterNode)
106 		return B_ERROR;
107 
108 	if (fPrintTransport.Open(fPrinterNode) != B_OK) {
109 		return B_ERROR;
110 	}
111 	if (fPrintTransport.IsPrintToFileCanceled()) {
112 		return B_OK;
113 	}
114 
115 	// read print file header
116 	fJobFile->Seek(0, SEEK_SET);
117 	fJobFile->Read(&pfh, sizeof(pfh));
118 
119 	// read job message
120 	fJobMsg = msg = new BMessage();
121 	msg->Unflatten(fJobFile);
122 
123 	if (msg->HasInt32("copies")) {
124 		copies = msg->FindInt32("copies");
125 	} else {
126 		copies = 1;
127 	}
128 
129 	status = BeginJob();
130 
131 	fPrinting = true;
132 	for (fPass = 0; fPass < passes && status == B_OK && fPrinting; fPass++) {
133 		for (copy = 0; copy < copies && status == B_OK && fPrinting; copy++)
134 		{
135 			for (page = 1; page <= pfh.page_count && status == B_OK && fPrinting; page++) {
136 				status = PrintPage(page, pfh.page_count);
137 			}
138 
139 			// re-read job message for next page
140 			fJobFile->Seek(sizeof(pfh), SEEK_SET);
141 			msg->Unflatten(fJobFile);
142 		}
143 	}
144 
145 	status_t s = EndJob();
146 	if (status == B_OK) status = s;
147 
148 	delete fJobMsg;
149 
150 	return status;
151 }
152 
153 /**
154  * This will stop the printing loop
155  *
156  * @param none
157  * @return void
158  */
159 void
160 PrinterDriver::StopPrinting()
161 {
162 	fPrinting = false;
163 }
164 
165 
166 // --------------------------------------------------
167 status_t
168 PrinterDriver::BeginJob()
169 {
170 	return B_OK;
171 }
172 
173 
174 // --------------------------------------------------
175 status_t
176 PrinterDriver::PrintPage(int32 pageNumber, int32 pageCount)
177 {
178 	char text[128];
179 
180 	sprintf(text, "Faking print of page %ld/%ld...", pageNumber, pageCount);
181 	BAlert *alert = new BAlert("PrinterDriver::PrintPage()", text, "Hmm?");
182 	alert->Go();
183 	return B_OK;
184 }
185 
186 
187 // --------------------------------------------------
188 status_t
189 PrinterDriver::EndJob()
190 {
191 	return B_OK;
192 }
193 
194 
195 BlockingWindow* PrinterDriver::NewPrinterSetupWindow(char* printerName) {
196 	return NULL;
197 }
198 
199 BlockingWindow* PrinterDriver::NewPageSetupWindow(BMessage *setupMsg, const char *printerName) {
200 	return new PageSetupWindow(setupMsg, printerName);
201 }
202 
203 BlockingWindow* PrinterDriver::NewJobSetupWindow(BMessage *jobMsg, const char *printerName) {
204 	return new JobSetupWindow(jobMsg, printerName);
205 }
206 
207 status_t PrinterDriver::Go(BlockingWindow* w) {
208 	if (w) {
209 		return w->Go();
210 	} else {
211 		return B_OK;
212 	}
213 }
214 
215 // --------------------------------------------------
216 status_t
217 PrinterDriver::PrinterSetup(char *printerName)
218 	// name of printer, to attach printer settings
219 {
220 	return Go(NewPrinterSetupWindow(printerName));
221 }
222 
223 
224 // --------------------------------------------------
225 status_t
226 PrinterDriver::PageSetup(BMessage *setupMsg, const char *printerName)
227 {
228 	// check to see if the messag is built correctly...
229 	if (setupMsg->HasFloat("scaling") != B_OK) {
230 #if HAS_PRINTER_SETTINGS
231 		PrinterSettings *ps = new PrinterSettings(printerName);
232 
233 		if (ps->InitCheck() == B_OK) {
234 			// first read the settings from the spool dir
235 			if (ps->ReadSettings(setupMsg) != B_OK) {
236 				// if there were none, then create a default set...
237 				ps->GetDefaults(setupMsg);
238 				// ...and save them
239 				ps->WriteSettings(setupMsg);
240 			}
241 		}
242 #endif
243 	}
244 
245 	return Go(NewPageSetupWindow(setupMsg, printerName));
246 }
247 
248 
249 // --------------------------------------------------
250 status_t
251 PrinterDriver::JobSetup(BMessage *jobMsg, const char *printerName)
252 {
253 	// set default value if property not set
254 	if (!jobMsg->HasInt32("copies"))
255 		jobMsg->AddInt32("copies", 1);
256 
257 	if (!jobMsg->HasInt32("first_page"))
258 		jobMsg->AddInt32("first_page", 1);
259 
260 	if (!jobMsg->HasInt32("last_page"))
261 		jobMsg->AddInt32("last_page", MAX_INT32);
262 
263 	return Go(NewJobSetupWindow(jobMsg, printerName));
264 }
265 
266 // --------------------------------------------------
267 BMessage*
268 PrinterDriver::GetDefaultSettings()
269 {
270 	BMessage* msg = new BMessage();
271 	BRect paperRect(0, 0, letter_width, letter_height);
272 	BRect printableRect(paperRect);
273 	printableRect.InsetBy(10, 10);
274 	msg->AddRect("paper_rect", paperRect);
275 	msg->AddRect("printable_rect", printableRect);
276 	msg->AddInt32("orientation", 0);
277 	msg->AddInt32("xres", 300);
278 	msg->AddInt32("yres", 300);
279 	return msg;
280 }
281 
282 #ifdef CODEWARRIOR
283 	#pragma mark [Privates routines]
284 #endif
285 
286 // Private routines
287 // ----------------
288