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