xref: /haiku/src/add-ons/print/drivers/preview/PrinterDriver.cpp (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
1 /*
2  * Copyright 2003-2007, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Philippe Houdoin
7  *		Simon Gauvin
8  *		Michael Pfeiffer
9  *		Dr. Hartmut Reh
10  */
11 
12 #include <stdio.h>
13 #include <string.h>			// for memset()
14 
15 #include <StorageKit.h>
16 
17 #include "PrinterDriver.h"
18 
19 #include "PrinterSetupWindow.h"
20 #include "PageSetupWindow.h"
21 #include "JobSetupWindow.h"
22 
23 // Private prototypes
24 // ------------------
25 
26 #ifdef CODEWARRIOR
27 	#pragma mark [Constructor & destructor]
28 #endif
29 
30 // Constructor & destructor
31 // ------------------------
32 
33 // --------------------------------------------------
34 PrinterDriver::PrinterDriver(BNode* printerNode)
35 	:	fJobFile(NULL),
36 		fPrinterNode(printerNode),
37 		fJobMsg(NULL)
38 {
39 }
40 
41 
42 // --------------------------------------------------
43 PrinterDriver::~PrinterDriver()
44 {
45 }
46 
47 #ifdef CODEWARRIOR
48 	#pragma mark [Public methods]
49 #endif
50 
51 #ifdef B_BEOS_VERSION_DANO
52 struct print_file_header {
53        int32   version;
54        int32   page_count;
55        off_t   first_page;
56        int32   _reserved_3_;
57        int32   _reserved_4_;
58        int32   _reserved_5_;
59 };
60 #endif
61 
62 
63 // Public methods
64 // --------------
65 
66 status_t
67 PrinterDriver::PrintJob
68 	(
69 	BFile 		*jobFile,		// spool file
70 	BMessage 	*jobMsg			// job message
71 	)
72 {
73 	print_file_header	pfh;
74 	status_t			status;
75 	BMessage 			*msg;
76 	int32 				page;
77 	uint32				copy;
78 	uint32				copies;
79 	const int32         passes = 2;
80 
81 	fJobFile		= jobFile;
82 	fJobMsg			= jobMsg;
83 
84 	if (!fJobFile || !fPrinterNode)
85 		return B_ERROR;
86 
87 	// read print file header
88 	fJobFile->Seek(0, SEEK_SET);
89 	fJobFile->Read(&pfh, sizeof(pfh));
90 
91 	// read job message
92 	fJobMsg = msg = new BMessage();
93 	msg->Unflatten(fJobFile);
94 
95 	if (msg->HasInt32("copies")) {
96 		copies = msg->FindInt32("copies");
97 	} else {
98 		copies = 1;
99 	}
100 
101 	status = BeginJob();
102 
103 	fPrinting = true;
104 	for (fPass = 0; fPass < passes && status == B_OK && fPrinting; fPass++) {
105 		for (copy = 0; copy < copies && status == B_OK && fPrinting; copy++)
106 		{
107 			for (page = 1; page <= pfh.page_count && status == B_OK && fPrinting; page++) {
108 				status = PrintPage(page, pfh.page_count);
109 			}
110 
111 			// re-read job message for next page
112 			fJobFile->Seek(sizeof(pfh), SEEK_SET);
113 			msg->Unflatten(fJobFile);
114 		}
115 	}
116 
117 	status_t s = EndJob();
118 	if (status == B_OK) status = s;
119 
120 	delete fJobMsg;
121 
122 	return status;
123 }
124 
125 /**
126  * This will stop the printing loop
127  *
128  * @param none
129  * @return void
130  */
131 void
132 PrinterDriver::StopPrinting()
133 {
134 	fPrinting = false;
135 }
136 
137 
138 // --------------------------------------------------
139 status_t
140 PrinterDriver::BeginJob()
141 {
142 	return B_OK;
143 }
144 
145 
146 // --------------------------------------------------
147 status_t
148 PrinterDriver::PrintPage(int32 pageNumber, int32 pageCount)
149 {
150 	char text[128];
151 
152 	sprintf(text, "Faking print of page %ld/%ld...", pageNumber, pageCount);
153 	BAlert *alert = new BAlert("PrinterDriver::PrintPage()", text, "Hmm?");
154 	alert->Go();
155 	return B_OK;
156 }
157 
158 
159 // --------------------------------------------------
160 status_t
161 PrinterDriver::EndJob()
162 {
163 	return B_OK;
164 }
165 
166 
167 BlockingWindow* PrinterDriver::NewPrinterSetupWindow(char* printerName) {
168 	return NULL;
169 }
170 
171 BlockingWindow* PrinterDriver::NewPageSetupWindow(BMessage *setupMsg, const char *printerName) {
172 	return new PageSetupWindow(setupMsg, printerName);
173 }
174 
175 BlockingWindow* PrinterDriver::NewJobSetupWindow(BMessage *jobMsg, const char *printerName) {
176 	return new JobSetupWindow(jobMsg, printerName);
177 }
178 
179 status_t PrinterDriver::Go(BlockingWindow* w) {
180 	if (w) {
181 		return w->Go();
182 	} else {
183 		return B_OK;
184 	}
185 }
186 
187 // --------------------------------------------------
188 status_t
189 PrinterDriver::PrinterSetup(char *printerName)
190 	// name of printer, to attach printer settings
191 {
192 	return Go(NewPrinterSetupWindow(printerName));
193 }
194 
195 
196 // --------------------------------------------------
197 status_t
198 PrinterDriver::PageSetup(BMessage *setupMsg, const char *printerName)
199 {
200 	// check to see if the messag is built correctly...
201 	if (setupMsg->HasFloat("scaling") != B_OK) {
202 #if HAS_PRINTER_SETTINGS
203 		PrinterSettings *ps = new PrinterSettings(printerName);
204 
205 		if (ps->InitCheck() == B_OK) {
206 			// first read the settings from the spool dir
207 			if (ps->ReadSettings(setupMsg) != B_OK) {
208 				// if there were none, then create a default set...
209 				ps->GetDefaults(setupMsg);
210 				// ...and save them
211 				ps->WriteSettings(setupMsg);
212 			}
213 		}
214 #endif
215 	}
216 
217 	return Go(NewPageSetupWindow(setupMsg, printerName));
218 }
219 
220 
221 // --------------------------------------------------
222 status_t
223 PrinterDriver::JobSetup(BMessage *jobMsg, const char *printerName)
224 {
225 	// set default value if property not set
226 	if (!jobMsg->HasInt32("copies"))
227 		jobMsg->AddInt32("copies", 1);
228 
229 	if (!jobMsg->HasInt32("first_page"))
230 		jobMsg->AddInt32("first_page", 1);
231 
232 	if (!jobMsg->HasInt32("last_page"))
233 		jobMsg->AddInt32("last_page", MAX_INT32);
234 
235 	return Go(NewJobSetupWindow(jobMsg, printerName));
236 }
237 
238 // --------------------------------------------------
239 BMessage*
240 PrinterDriver::GetDefaultSettings()
241 {
242 	BMessage* msg = new BMessage();
243 	BRect paperRect(0, 0, letter_width, letter_height);
244 	BRect printableRect(paperRect);
245 	printableRect.InsetBy(10, 10);
246 	msg->AddRect("paper_rect", paperRect);
247 	msg->AddRect("printable_rect", printableRect);
248 	msg->AddInt32("orientation", 0);
249 	msg->AddInt32("xres", 300);
250 	msg->AddInt32("yres", 300);
251 	return msg;
252 }
253 
254 #ifdef CODEWARRIOR
255 	#pragma mark [Privates routines]
256 #endif
257 
258 // Private routines
259 // ----------------
260