/*
* Copyright 2001-2008, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ithamar R. Adema
* Michael Pfeiffer
*/
#include "PrintServerApp.h"
#include "pr_server.h"
#include "Printer.h"
#include "ConfigWindow.h"
// BeOS API
#include <Alert.h>
#include <Autolock.h>
#include <Catalog.h>
#include <Locale.h>
#include <PrintJob.h>
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "PrintServerApp"
struct AsyncThreadParams {
PrintServerApp* app;
Printer* printer;
BMessage* message;
AsyncThreadParams(PrintServerApp* app, Printer* p, BMessage* m)
: app(app)
, printer(p)
, message(m)
{
app->Acquire();
if (printer) printer->Acquire();
}
~AsyncThreadParams() {
if (printer) printer->Release();
delete message;
app->Release();
}
BMessage* AcquireMessage() {
BMessage* m = message; message = NULL; return m;
}
};
status_t
PrintServerApp::async_thread(void* data)
{
AsyncThreadParams* p = (AsyncThreadParams*)data;
Printer* printer = p->printer;
BMessage* msg = p->AcquireMessage();
{
AutoReply sender(msg, 'stop');
switch (msg->what) {
// Handle showing the config dialog
case PSRV_SHOW_PAGE_SETUP: {
case PSRV_SHOW_PRINT_SETUP:
if (printer) {
if (p->app->fUseConfigWindow) {
config_setup_kind kind = kJobSetup;
if (msg->what == PSRV_SHOW_PAGE_SETUP)
kind = kPageSetup;
ConfigWindow* w = new ConfigWindow(kind, printer, msg,
&sender);
w->Go();
} else {
BMessage reply(*msg);
status_t status = B_ERROR;
if (msg->what == PSRV_SHOW_PAGE_SETUP)
status = printer->ConfigurePage(reply);
else
status = printer->ConfigureJob(reply);
if (status == B_OK)
sender.SetReply(&reply);
}
} else {
// If no default printer is set, give user
// choice of aborting or setting up a printer
int32 count = Printer::CountPrinters();
BString alertText(
B_TRANSLATE("There are no printers set up."));
if (count > 0)
alertText.SetTo(B_TRANSLATE(
"There is no default printer set up."));
alertText.Append(" ");
alertText.Append(
B_TRANSLATE("Would you like to set one up now?"));
BAlert* alert = new BAlert("Info", alertText.String(),
B_TRANSLATE("No"), B_TRANSLATE("Yes"));
alert->SetShortcut(0, B_ESCAPE);
if (alert->Go() == 1) {
if (count == 0)
run_add_printer_panel();
else
run_select_printer_panel();
}
}
} break;
// Retrieve default configuration message from printer add-on
case PSRV_GET_DEFAULT_SETTINGS: {
if (printer) {
BMessage reply;
if (printer->GetDefaultSettings(reply) == B_OK) {
sender.SetReply(&reply);
break;
}
}
} break;
// Create a new printer
case PSRV_MAKE_PRINTER: {
BString driverName;
BString printerName;
BString transportName;
BString transportPath;
if (msg->FindString("driver", &driverName) == B_OK
&& msg->FindString("transport", &transportName) == B_OK
&& msg->FindString("transport path", &transportPath) == B_OK
&& msg->FindString("printer name", &printerName) == B_OK) {
BString connection;
if (msg->FindString("connection", &connection) != B_OK)
connection = "Local";
// then create the actual printer
if (p->app->CreatePrinter(printerName.String(),
driverName.String(), connection.String(),
transportName.String(),
transportPath.String()) == B_OK) {
// If printer was created ok,
// ask if it needs to be the default
BString text(B_TRANSLATE("Would you like to make @ "
"the default printer?"));
text.ReplaceFirst("@", printerName.String());
BAlert* alert = new BAlert("", text.String(),
B_TRANSLATE("No"), B_TRANSLATE("Yes"));
alert->SetShortcut(0, B_ESCAPE);
if (alert->Go() == 1)
p->app->SelectPrinter(printerName.String());
}
}
} break;
}
}
delete p;
return B_OK;
}
// Async. processing of received message
void
PrintServerApp::AsyncHandleMessage(BMessage* msg)
{
AsyncThreadParams* data = new AsyncThreadParams(this, fDefaultPrinter, msg);
thread_id tid = spawn_thread(async_thread, "async", B_NORMAL_PRIORITY,
(void*)data);
if (tid > 0) {
resume_thread(tid);
} else {
delete data;
}
}
void
PrintServerApp::Handle_BeOSR5_Message(BMessage* msg)
{
switch(msg->what) {
// Get currently selected printer
case PSRV_GET_ACTIVE_PRINTER: {
BMessage reply('okok');
BString printerName;
if (fDefaultPrinter)
printerName = fDefaultPrinter->Name();
BString mime;
if (fUseConfigWindow && MimeTypeForSender(msg, mime)) {
BAutolock lock(gLock);
if (lock.IsLocked()) {
// override with printer for application
PrinterSettings* p = fSettings->FindPrinterSettings(
mime.String());
if (p)
printerName = p->GetPrinter();
}
}
reply.AddString("printer_name", printerName);
// BeOS knows not if color or not, so always color
reply.AddInt32("color", BPrintJob::B_COLOR_PRINTER);
msg->SendReply(&reply);
}
break;
//make printer active (currently always quietly :))
case PSRV_MAKE_PRINTER_ACTIVE_QUIETLY:
//make printer active quietly
case PSRV_MAKE_PRINTER_ACTIVE: {
BString newActivePrinter;
if (msg->FindString("printer",&newActivePrinter) == B_OK) {
SelectPrinter(newActivePrinter.String());
}
}
break;
case PSRV_SHOW_PAGE_SETUP:
case PSRV_SHOW_PRINT_SETUP:
case PSRV_GET_DEFAULT_SETTINGS:
case PSRV_MAKE_PRINTER:
AsyncHandleMessage(DetachCurrentMessage());
break;
// Tell printer addon to print a spooled job
case PSRV_PRINT_SPOOLED_JOB:
HandleSpooledJobs();
break;
}
}
↑ V773 Visibility scope of the 'alert' pointer was exited without releasing the memory. A memory leak is possible.
↑ V773 Visibility scope of the 'alert' pointer was exited without releasing the memory. A memory leak is possible.