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