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