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