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