xref: /haiku/src/servers/print/PrintServerApp.R5.cpp (revision 2807c36668a1730dd59bc39de65e0b8f88cd5d0d)
1 /*****************************************************************************/
2 // print_server Background Application.
3 //
4 // Version: 1.0.0d1
5 //
6 // The print_server manages the communication between applications and the
7 // printer and transport drivers.
8 //
9 // Authors
10 //   Ithamar R. Adema
11 //   Michael Pfeiffer
12 //
13 // This application and all source files used in its construction, except
14 // where noted, are licensed under the MIT License, and have been written
15 // and are:
16 //
17 // Copyright (c) 2001, 2002 OpenBeOS Project
18 //
19 // Permission is hereby granted, free of charge, to any person obtaining a
20 // copy of this software and associated documentation files (the "Software"),
21 // to deal in the Software without restriction, including without limitation
22 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
23 // and/or sell copies of the Software, and to permit persons to whom the
24 // Software is furnished to do so, subject to the following conditions:
25 //
26 // The above copyright notice and this permission notice shall be included
27 // in all copies or substantial portions of the Software.
28 //
29 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
30 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
32 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
34 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35 // DEALINGS IN THE SOFTWARE.
36 /*****************************************************************************/
37 
38 #include "PrintServerApp.h"
39 
40 #include "pr_server.h"
41 #include "Printer.h"
42 #include "ConfigWindow.h"
43 
44 	// BeOS API
45 #include <Alert.h>
46 #include <Autolock.h>
47 #include <PrintJob.h>
48 
49 struct AsyncThreadParams {
50 	PrintServerApp* app;
51 	Printer* printer;
52 	BMessage* message;
53 
54 	AsyncThreadParams(PrintServerApp* app, Printer* p, BMessage* m)
55 		: app(app)
56 		, printer(p)
57 		, message(m)
58 	{
59 		app->Acquire();
60 		if (printer) printer->Acquire();
61 	}
62 
63 	~AsyncThreadParams() {
64 		if (printer) printer->Release();
65 		delete message;
66 		app->Release();
67 	}
68 
69 	BMessage* AcquireMessage() {
70 		BMessage* m = message; message = NULL; return m;
71 	}
72 };
73 
74 status_t PrintServerApp::async_thread(void* data)
75 {
76 	AsyncThreadParams* p = (AsyncThreadParams*)data;
77 
78 	Printer* printer = p->printer;
79 	BMessage* msg = p->AcquireMessage();
80 
81 	{
82 		AutoReply sender(msg, 'stop');
83 		switch (msg->what) {
84 				// Handle showing the page config dialog
85 			case PSRV_SHOW_PAGE_SETUP: {
86 					BMessage reply(*msg);
87 					if (printer != NULL) {
88 						if (p->app->fUseConfigWindow) {
89 							ConfigWindow* w = new ConfigWindow(kPageSetup, printer, msg, &sender);
90 							w->Go();
91 						} else if (printer->ConfigurePage(reply) == B_OK) {
92 							sender.SetReply(&reply);
93 						}
94 					} else {
95 							// If no default printer, give user choice of aborting or setting up a printer
96 						BAlert* alert = new BAlert("Info", "Hang on there! You don't have any printers set up!\nYou'll need to do that before trying to print\n\nWould you like to set up a printer now?", "No thanks", "Sure!");
97 						if (alert->Go() == 1) {
98 							run_add_printer_panel();
99 						}
100 					}
101 				}
102 				break;
103 
104 				// Handle showing the print config dialog
105 			case PSRV_SHOW_PRINT_SETUP: {
106 					if (printer == NULL) break;
107 					if (p->app->fUseConfigWindow) {
108 						ConfigWindow* w = new ConfigWindow(kJobSetup, printer, msg, &sender);
109 						w->Go();
110 					} else {
111 						BMessage reply(*msg);
112 						if (printer->ConfigureJob(reply) == B_OK) {
113 							sender.SetReply(&reply);
114 						}
115 					}
116 				}
117 				break;
118 
119 				// Retrieve default configuration message from printer add-on
120 			case PSRV_GET_DEFAULT_SETTINGS:
121 				if (printer != NULL) {
122 					BMessage reply;
123 					if (printer->GetDefaultSettings(reply) == B_OK) {
124 						sender.SetReply(&reply);
125 						break;
126 					}
127 				}
128 				break;
129 
130 				// Create a new printer
131 			case PSRV_MAKE_PRINTER: {
132 					BString driverName, transportName, transportPath;
133 					BString printerName, connection;
134 
135 					if (msg->FindString("driver", &driverName) == B_OK &&
136 						msg->FindString("transport", &transportName) == B_OK &&
137 						msg->FindString("transport path", &transportPath) == B_OK &&
138 						msg->FindString("printer name", &printerName) == B_OK
139 						) {
140 
141 						if (msg->FindString("connection", &connection) != B_OK)
142 							connection = "Local";
143 
144 							// then create the actual printer
145 						if (p->app->CreatePrinter(printerName.String(), driverName.String(),
146 							connection.String(),
147 							transportName.String(), transportPath.String()) == B_OK) {
148 								// If printer was created ok, ask if it needs to be the default
149 							char buffer[256];
150 							::sprintf(buffer, "Would you like to make %s the default\nprinter?",
151 								printerName.String());
152 
153 							BAlert* alert = new BAlert("", buffer, "No", "Yes");
154 							if (alert->Go() == 1) {
155 								p->app->SelectPrinter(printerName.String());
156 							}
157 						}
158 					}
159 				}
160 				break;
161 		}
162 	}
163 
164 	delete p;
165 }
166 
167 
168 // Async. processing of received message
169 void PrintServerApp::AsyncHandleMessage(BMessage* msg)
170 {
171 	AsyncThreadParams* data = new AsyncThreadParams(this, fDefaultPrinter, msg);
172 
173 	thread_id tid = spawn_thread(async_thread, "async", B_NORMAL_PRIORITY, (void*)data);
174 
175 	if (tid > 0) {
176 		resume_thread(tid);
177 	} else {
178 		delete data;
179 	}
180 }
181 
182 void PrintServerApp::Handle_BeOSR5_Message(BMessage* msg)
183 {
184 	switch(msg->what) {
185 			// Get currently selected printer
186 		case PSRV_GET_ACTIVE_PRINTER: {
187 				BMessage reply('okok');
188 				BString printerName = fDefaultPrinter ? fDefaultPrinter->Name() : "";
189 				BString mime;
190 				if (fUseConfigWindow && MimeTypeForSender(msg, mime)) {
191 					BAutolock lock(gLock);
192 					if (lock.IsLocked()) {
193 							// override with printer for application
194 						PrinterSettings* p = fSettings->FindPrinterSettings(mime.String());
195 						if (p) printerName = p->GetPrinter();
196 					}
197 				}
198 				reply.AddString("printer_name", printerName);
199 				reply.AddInt32("color", BPrintJob::B_COLOR_PRINTER);	// BeOS knows not if color or not, so always color
200 				msg->SendReply(&reply);
201 			}
202 			break;
203 
204 			//make printer active (currently always quietly :))
205 		case PSRV_MAKE_PRINTER_ACTIVE_QUIETLY:
206 			//make printer active quietly
207 		case PSRV_MAKE_PRINTER_ACTIVE: {
208 				BString newActivePrinter;
209 				if (msg->FindString("printer",&newActivePrinter) == B_OK) {
210 					SelectPrinter(newActivePrinter.String());
211 				}
212 			}
213 			break;
214 
215 #if 0
216 			// Create a new printer
217 		case PSRV_MAKE_PRINTER: {
218 				BString driverName, transportName, transportPath;
219 				BString printerName, connection;
220 
221 				if (msg->FindString("driver", &driverName) == B_OK &&
222 					msg->FindString("transport", &transportName) == B_OK &&
223 					msg->FindString("transport path", &transportPath) == B_OK &&
224 					msg->FindString("printer name", &printerName) == B_OK
225 					) {
226 
227 					if (msg->FindString("connection", &connection) != B_OK)
228 						connection = "Local";
229 
230 						// then create the actual printer
231 					if (CreatePrinter(printerName.String(), driverName.String(),
232 						connection.String(),
233 						transportName.String(), transportPath.String()) == B_OK) {
234 							// If printer was created ok, ask if it needs to be the default
235 						char buffer[256];
236 						::sprintf(buffer, "Would you like to make %s the default\nprinter?",
237 							printerName.String());
238 
239 						BAlert* alert = new BAlert("", buffer, "No", "Yes");
240 						if (alert->Go() == 1) {
241 							SelectPrinter(printerName.String());
242 						}
243 					}
244 				}
245 			}
246 			break;
247 #endif
248 
249 		case PSRV_SHOW_PAGE_SETUP:
250 		case PSRV_SHOW_PRINT_SETUP:
251 		case PSRV_GET_DEFAULT_SETTINGS:
252 		case PSRV_MAKE_PRINTER:
253 			AsyncHandleMessage(DetachCurrentMessage());
254 			break;
255 
256 			// Tell printer addon to print a spooled job
257 		case PSRV_PRINT_SPOOLED_JOB:
258 			HandleSpooledJobs();
259 			break;
260 	}
261 }
262