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