xref: /haiku/src/servers/print/PrintServerApp.R5.cpp (revision f2b4344867e97c3f4e742a1b4a15e6879644601a)
1 /*
2  * Copyright 2001-2008, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ithamar R. Adema
7  *		Michael Pfeiffer
8  */
9 #include "PrintServerApp.h"
10 
11 #include "pr_server.h"
12 #include "Printer.h"
13 #include "ConfigWindow.h"
14 
15 	// BeOS API
16 #include <Alert.h>
17 #include <Autolock.h>
18 #include <Catalog.h>
19 #include <Locale.h>
20 #include <PrintJob.h>
21 
22 
23 #undef B_TRANSLATE_CONTEXT
24 #define B_TRANSLATE_CONTEXT "PrintServerApp"
25 
26 
27 struct AsyncThreadParams {
28 	PrintServerApp* app;
29 	Printer* printer;
30 	BMessage* message;
31 
32 	AsyncThreadParams(PrintServerApp* app, Printer* p, BMessage* m)
33 		: app(app)
34 		, printer(p)
35 		, message(m)
36 	{
37 		app->Acquire();
38 		if (printer) printer->Acquire();
39 	}
40 
41 	~AsyncThreadParams() {
42 		if (printer) printer->Release();
43 		delete message;
44 		app->Release();
45 	}
46 
47 	BMessage* AcquireMessage() {
48 		BMessage* m = message; message = NULL; return m;
49 	}
50 };
51 
52 
53 status_t
54 PrintServerApp::async_thread(void* data)
55 {
56 	AsyncThreadParams* p = (AsyncThreadParams*)data;
57 
58 	Printer* printer = p->printer;
59 	BMessage* msg = p->AcquireMessage();
60 	{
61 		AutoReply sender(msg, 'stop');
62 		switch (msg->what) {
63 			// Handle showing the config dialog
64 			case PSRV_SHOW_PAGE_SETUP: {
65 			case PSRV_SHOW_PRINT_SETUP:
66 				if (printer) {
67 					if (p->app->fUseConfigWindow) {
68 						config_setup_kind kind = kJobSetup;
69 						if (msg->what == PSRV_SHOW_PAGE_SETUP)
70 							kind = kPageSetup;
71 						ConfigWindow* w = new ConfigWindow(kind, printer, msg,
72 							&sender);
73 						w->Go();
74 					} else {
75 						BMessage reply(*msg);
76 						status_t status = B_ERROR;
77 						if (msg->what == PSRV_SHOW_PAGE_SETUP)
78 							status = printer->ConfigurePage(reply);
79 						else
80 							status = printer->ConfigureJob(reply);
81 
82 						if (status == B_OK)
83 							sender.SetReply(&reply);
84 					}
85 				} else {
86 					// If no default printer is set, give user
87 					// choice of aborting or setting up a printer
88 					int32 count = Printer::CountPrinters();
89 					BString alertText(
90 						B_TRANSLATE("There are no printers set up."));
91 					if (count > 0)
92 						alertText.SetTo(B_TRANSLATE(
93 							"There is no default printer set up."));
94 
95 					alertText.Append(" ");
96 					alertText.Append(
97 						B_TRANSLATE("Would you like to set one up now?"));
98 					BAlert* alert = new BAlert("Info", alertText.String(),
99 						B_TRANSLATE("No"), B_TRANSLATE("Yes"));
100 					if (alert->Go() == 1) {
101 						if (count == 0)
102 							run_add_printer_panel();
103 						else
104 							run_select_printer_panel();
105 					}
106 				}
107 			}	break;
108 
109 			// Retrieve default configuration message from printer add-on
110 			case PSRV_GET_DEFAULT_SETTINGS: {
111 				if (printer) {
112 					BMessage reply;
113 					if (printer->GetDefaultSettings(reply) == B_OK) {
114 						sender.SetReply(&reply);
115 						break;
116 					}
117 				}
118 			}	break;
119 
120 			// Create a new printer
121 			case PSRV_MAKE_PRINTER: {
122 				BString driverName;
123 				BString printerName;
124 				BString transportName;
125 				BString transportPath;
126 				if (msg->FindString("driver", &driverName) == B_OK
127 					&& msg->FindString("transport", &transportName) == B_OK
128 					&& msg->FindString("transport path", &transportPath) == B_OK
129 					&& msg->FindString("printer name", &printerName) == B_OK) {
130 					BString connection;
131 					if (msg->FindString("connection", &connection) != B_OK)
132 						connection = "Local";
133 
134 					// then create the actual printer
135 					if (p->app->CreatePrinter(printerName.String(),
136 						driverName.String(), connection.String(),
137 						transportName.String(),
138 						transportPath.String()) == B_OK) {
139 						// If printer was created ok,
140 						// ask if it needs to be the default
141 						BString text(B_TRANSLATE("Would you like to make @ "
142 							"the default printer?"));
143 						text.ReplaceFirst("@", printerName.String());
144 						BAlert* alert = new BAlert("", text.String(),
145 							B_TRANSLATE("No"), B_TRANSLATE("Yes"));
146 						if (alert->Go() == 1)
147 							p->app->SelectPrinter(printerName.String());
148 					}
149 				}
150 			}	break;
151 		}
152 	}
153 	delete p;
154 	return B_OK;
155 }
156 
157 
158 // Async. processing of received message
159 void
160 PrintServerApp::AsyncHandleMessage(BMessage* msg)
161 {
162 	AsyncThreadParams* data = new AsyncThreadParams(this, fDefaultPrinter, msg);
163 
164 	thread_id tid = spawn_thread(async_thread, "async", B_NORMAL_PRIORITY,
165 		(void*)data);
166 
167 	if (tid > 0) {
168 		resume_thread(tid);
169 	} else {
170 		delete data;
171 	}
172 }
173 
174 
175 void
176 PrintServerApp::Handle_BeOSR5_Message(BMessage* msg)
177 {
178 	switch(msg->what) {
179 			// Get currently selected printer
180 		case PSRV_GET_ACTIVE_PRINTER: {
181 				BMessage reply('okok');
182 				BString printerName;
183 				if (fDefaultPrinter)
184 					printerName = fDefaultPrinter->Name();
185 				BString mime;
186 				if (fUseConfigWindow && MimeTypeForSender(msg, mime)) {
187 					BAutolock lock(gLock);
188 					if (lock.IsLocked()) {
189 							// override with printer for application
190 						PrinterSettings* p = fSettings->FindPrinterSettings(
191 							mime.String());
192 						if (p)
193 							printerName = p->GetPrinter();
194 					}
195 				}
196 				reply.AddString("printer_name", printerName);
197 				// BeOS knows not if color or not, so always color
198 				reply.AddInt32("color", BPrintJob::B_COLOR_PRINTER);
199 				msg->SendReply(&reply);
200 			}
201 			break;
202 
203 			//make printer active (currently always quietly :))
204 		case PSRV_MAKE_PRINTER_ACTIVE_QUIETLY:
205 			//make printer active quietly
206 		case PSRV_MAKE_PRINTER_ACTIVE: {
207 				BString newActivePrinter;
208 				if (msg->FindString("printer",&newActivePrinter) == B_OK) {
209 					SelectPrinter(newActivePrinter.String());
210 				}
211 			}
212 			break;
213 
214 		case PSRV_SHOW_PAGE_SETUP:
215 		case PSRV_SHOW_PRINT_SETUP:
216 		case PSRV_GET_DEFAULT_SETTINGS:
217 		case PSRV_MAKE_PRINTER:
218 			AsyncHandleMessage(DetachCurrentMessage());
219 			break;
220 
221 			// Tell printer addon to print a spooled job
222 		case PSRV_PRINT_SPOOLED_JOB:
223 			HandleSpooledJobs();
224 			break;
225 	}
226 }
227 
228