xref: /haiku/src/servers/print/PrintServerApp.R5.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
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_TRANSLATION_CONTEXT
24 #define B_TRANSLATION_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 					alert->SetShortcut(0, B_ESCAPE);
101 					if (alert->Go() == 1) {
102 						if (count == 0)
103 							run_add_printer_panel();
104 						else
105 							run_select_printer_panel();
106 					}
107 				}
108 			}	break;
109 
110 			// Retrieve default configuration message from printer add-on
111 			case PSRV_GET_DEFAULT_SETTINGS: {
112 				if (printer) {
113 					BMessage reply;
114 					if (printer->GetDefaultSettings(reply) == B_OK) {
115 						sender.SetReply(&reply);
116 						break;
117 					}
118 				}
119 			}	break;
120 
121 			// Create a new printer
122 			case PSRV_MAKE_PRINTER: {
123 				BString driverName;
124 				BString printerName;
125 				BString transportName;
126 				BString transportPath;
127 				if (msg->FindString("driver", &driverName) == B_OK
128 					&& msg->FindString("transport", &transportName) == B_OK
129 					&& msg->FindString("transport path", &transportPath) == B_OK
130 					&& msg->FindString("printer name", &printerName) == B_OK) {
131 					BString connection;
132 					if (msg->FindString("connection", &connection) != B_OK)
133 						connection = "Local";
134 
135 					// then create the actual printer
136 					if (p->app->CreatePrinter(printerName.String(),
137 						driverName.String(), connection.String(),
138 						transportName.String(),
139 						transportPath.String()) == B_OK) {
140 						// If printer was created ok,
141 						// ask if it needs to be the default
142 						BString text(B_TRANSLATE("Would you like to make @ "
143 							"the default printer?"));
144 						text.ReplaceFirst("@", printerName.String());
145 						BAlert* alert = new BAlert("", text.String(),
146 							B_TRANSLATE("No"), B_TRANSLATE("Yes"));
147 						alert->SetShortcut(0, B_ESCAPE);
148 						if (alert->Go() == 1)
149 							p->app->SelectPrinter(printerName.String());
150 					}
151 				}
152 			}	break;
153 		}
154 	}
155 	delete p;
156 	return B_OK;
157 }
158 
159 
160 // Async. processing of received message
161 void
162 PrintServerApp::AsyncHandleMessage(BMessage* msg)
163 {
164 	AsyncThreadParams* data = new AsyncThreadParams(this, fDefaultPrinter, msg);
165 
166 	thread_id tid = spawn_thread(async_thread, "async", B_NORMAL_PRIORITY,
167 		(void*)data);
168 
169 	if (tid > 0) {
170 		resume_thread(tid);
171 	} else {
172 		delete data;
173 	}
174 }
175 
176 
177 void
178 PrintServerApp::Handle_BeOSR5_Message(BMessage* msg)
179 {
180 	switch(msg->what) {
181 			// Get currently selected printer
182 		case PSRV_GET_ACTIVE_PRINTER: {
183 				BMessage reply('okok');
184 				BString printerName;
185 				if (fDefaultPrinter)
186 					printerName = fDefaultPrinter->Name();
187 				BString mime;
188 				if (fUseConfigWindow && MimeTypeForSender(msg, mime)) {
189 					BAutolock lock(gLock);
190 					if (lock.IsLocked()) {
191 							// override with printer for application
192 						PrinterSettings* p = fSettings->FindPrinterSettings(
193 							mime.String());
194 						if (p)
195 							printerName = p->GetPrinter();
196 					}
197 				}
198 				reply.AddString("printer_name", printerName);
199 				// BeOS knows not if color or not, so always color
200 				reply.AddInt32("color", BPrintJob::B_COLOR_PRINTER);
201 				msg->SendReply(&reply);
202 			}
203 			break;
204 
205 			//make printer active (currently always quietly :))
206 		case PSRV_MAKE_PRINTER_ACTIVE_QUIETLY:
207 			//make printer active quietly
208 		case PSRV_MAKE_PRINTER_ACTIVE: {
209 				BString newActivePrinter;
210 				if (msg->FindString("printer",&newActivePrinter) == B_OK) {
211 					SelectPrinter(newActivePrinter.String());
212 				}
213 			}
214 			break;
215 
216 		case PSRV_SHOW_PAGE_SETUP:
217 		case PSRV_SHOW_PRINT_SETUP:
218 		case PSRV_GET_DEFAULT_SETTINGS:
219 		case PSRV_MAKE_PRINTER:
220 			AsyncHandleMessage(DetachCurrentMessage());
221 			break;
222 
223 			// Tell printer addon to print a spooled job
224 		case PSRV_PRINT_SPOOLED_JOB:
225 			HandleSpooledJobs();
226 			break;
227 	}
228 }
229 
230