* do some simple checking if the printer exists and is usable at

all, otherwise complain or offer to make it the default printer


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24554 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Karsten Heimrich
2008-03-24 13:23:03 +00:00
parent 04a969c8cf
commit c8ee6ba8fb
+94 -57
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2006, Haiku. All rights reserved. * Copyright 2001-2008, Haiku. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -31,7 +31,7 @@
// ANSI C // ANSI C
#include <stdio.h> #include <stdio.h>
// for printf // for printf
#include <unistd.h> #include <unistd.h>
// for unlink // for unlink
BLocker *gLock = NULL; BLocker *gLock = NULL;
@@ -52,7 +52,7 @@ typedef char* (*add_printer_func_t)(const char* printer_name);
* application failed to start. * application failed to start.
*/ */
int int
main() main()
{ {
status_t rc = B_OK; status_t rc = B_OK;
gLock = new BLocker(); gLock = new BLocker();
@@ -85,12 +85,12 @@ PrintServerApp::PrintServerApp(status_t* err)
{ {
fSettings = Settings::GetSettings(); fSettings = Settings::GetSettings();
LoadSettings(); LoadSettings();
if (*err != B_OK) if (*err != B_OK)
return; return;
fHasReferences = create_sem(1, "has_references"); fHasReferences = create_sem(1, "has_references");
// Build list of transport addons // Build list of transport addons
Transport::Scan(B_USER_ADDONS_DIRECTORY); Transport::Scan(B_USER_ADDONS_DIRECTORY);
Transport::Scan(B_COMMON_ADDONS_DIRECTORY); Transport::Scan(B_COMMON_ADDONS_DIRECTORY);
@@ -98,14 +98,14 @@ PrintServerApp::PrintServerApp(status_t* err)
SetupPrinterList(); SetupPrinterList();
RetrieveDefaultPrinter(); RetrieveDefaultPrinter();
// Cache icons for selected printer // Cache icons for selected printer
fSelectedIconMini = new BBitmap(BRect(0,0,B_MINI_ICON-1,B_MINI_ICON-1), B_CMAP8); fSelectedIconMini = new BBitmap(BRect(0,0,B_MINI_ICON-1,B_MINI_ICON-1), B_CMAP8);
fSelectedIconLarge = new BBitmap(BRect(0,0,B_LARGE_ICON-1,B_LARGE_ICON-1), B_CMAP8); fSelectedIconLarge = new BBitmap(BRect(0,0,B_LARGE_ICON-1,B_LARGE_ICON-1), B_CMAP8);
BMimeType type(PRNT_SIGNATURE_TYPE); BMimeType type(PRNT_SIGNATURE_TYPE);
type.GetIcon(fSelectedIconMini, B_MINI_ICON); type.GetIcon(fSelectedIconMini, B_MINI_ICON);
type.GetIcon(fSelectedIconLarge, B_LARGE_ICON); type.GetIcon(fSelectedIconLarge, B_LARGE_ICON);
PostMessage(PSRV_PRINT_SPOOLED_JOB); PostMessage(PSRV_PRINT_SPOOLED_JOB);
// Start handling of spooled files // Start handling of spooled files
} }
@@ -118,15 +118,15 @@ PrintServerApp::~PrintServerApp()
} }
bool bool
PrintServerApp::QuitRequested() PrintServerApp::QuitRequested()
{ {
// don't quit when user types Command+Q! // don't quit when user types Command+Q!
BMessage* m = CurrentMessage(); BMessage* m = CurrentMessage();
bool shortcut; bool shortcut;
if (m != NULL && m->FindBool("shortcut", &shortcut) == B_OK && shortcut) if (m != NULL && m->FindBool("shortcut", &shortcut) == B_OK && shortcut)
return false; return false;
if (!Inherited::QuitRequested()) if (!Inherited::QuitRequested())
return false; return false;
@@ -174,23 +174,23 @@ void
PrintServerApp::RegisterPrinter(BDirectory* printer) PrintServerApp::RegisterPrinter(BDirectory* printer)
{ {
BString transport, address, connection, state; BString transport, address, connection, state;
if (printer->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT, &transport) == B_OK if (printer->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT, &transport) == B_OK
&& printer->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT_ADDR, &address) == B_OK && printer->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT_ADDR, &address) == B_OK
&& printer->ReadAttrString(PSRV_PRINTER_ATTR_CNX, &connection) == B_OK && printer->ReadAttrString(PSRV_PRINTER_ATTR_CNX, &connection) == B_OK
&& printer->ReadAttrString(PSRV_PRINTER_ATTR_STATE, &state) == B_OK && printer->ReadAttrString(PSRV_PRINTER_ATTR_STATE, &state) == B_OK
&& state == "free") { && state == "free") {
BAutolock lock(gLock); BAutolock lock(gLock);
if (lock.IsLocked()) { if (lock.IsLocked()) {
// check if printer is already registered // check if printer is already registered
node_ref node; node_ref node;
if (printer->GetNodeRef(&node) != B_OK) if (printer->GetNodeRef(&node) != B_OK)
return; return;
if (Printer::Find(&node) != NULL) if (Printer::Find(&node) != NULL)
return; return;
// register new printer // register new printer
Resource* r = fResourceManager.Allocate(transport.String(), address.String(), connection.String()); Resource* r = fResourceManager.Allocate(transport.String(), address.String(), connection.String());
AddHandler(new Printer(printer, r)); AddHandler(new Printer(printer, r));
@@ -204,7 +204,7 @@ void
PrintServerApp::UnregisterPrinter(Printer* printer) PrintServerApp::UnregisterPrinter(Printer* printer)
{ {
RemoveHandler(printer); RemoveHandler(printer);
Printer::Remove(printer); Printer::Remove(printer);
printer->Release(); printer->Release();
} }
@@ -256,7 +256,7 @@ PrintServerApp::AttributeChanged(node_ref* node)
// SetupPrinterList // SetupPrinterList
// //
// This method builds the internal list of printers from disk. It // This method builds the internal list of printers from disk. It
// also installs a node monitor to be sure that the list keeps // also installs a node monitor to be sure that the list keeps
// updated with the definitions on disk. // updated with the definitions on disk.
// //
// Parameters: // Parameters:
@@ -275,12 +275,12 @@ PrintServerApp::SetupPrinterList()
rc = ::find_directory(B_USER_PRINTERS_DIRECTORY, &path); rc = ::find_directory(B_USER_PRINTERS_DIRECTORY, &path);
if (rc != B_OK) if (rc != B_OK)
return rc; return rc;
// Directory has to exist in order to watch it // Directory has to exist in order to watch it
mode_t mode = 0777; mode_t mode = 0777;
create_directory(path.Path(), mode); create_directory(path.Path(), mode);
BDirectory dir(path.Path()); BDirectory dir(path.Path());
rc = dir.InitCheck(); rc = dir.InitCheck();
if (rc != B_OK) if (rc != B_OK)
return rc; return rc;
@@ -288,21 +288,21 @@ PrintServerApp::SetupPrinterList()
// Register printer definition nodes // Register printer definition nodes
BEntry entry; BEntry entry;
while(dir.GetNextEntry(&entry) == B_OK) { while(dir.GetNextEntry(&entry) == B_OK) {
if (!entry.IsDirectory()) if (!entry.IsDirectory())
continue; continue;
BDirectory node(&entry); BDirectory node(&entry);
BNodeInfo info(&node); BNodeInfo info(&node);
char buffer[256]; char buffer[256];
if (info.GetType(buffer) == B_OK && strcmp(buffer, PSRV_PRINTER_FILETYPE) == 0) { if (info.GetType(buffer) == B_OK && strcmp(buffer, PSRV_PRINTER_FILETYPE) == 0) {
RegisterPrinter(&node); RegisterPrinter(&node);
} }
} }
// Now we are ready to start node watching // Now we are ready to start node watching
fFolder = new FolderWatcher(this, dir, true); fFolder = new FolderWatcher(this, dir, true);
fFolder->SetListener(this); fFolder->SetListener(this);
return B_OK; return B_OK;
} }
@@ -340,10 +340,10 @@ PrintServerApp::MessageReceived(BMessage* msg)
case B_EXECUTE_PROPERTY: case B_EXECUTE_PROPERTY:
HandleScriptingCommand(msg); HandleScriptingCommand(msg);
break; break;
default: default:
Inherited::MessageReceived(msg); Inherited::MessageReceived(msg);
} }
} }
// --------------------------------------------------------------- // ---------------------------------------------------------------
@@ -370,7 +370,7 @@ PrintServerApp::CreatePrinter(const char* printerName, const char* driverName,
const char* connection, const char* transportName, const char* transportPath) const char* connection, const char* transportName, const char* transportPath)
{ {
status_t rc; status_t rc;
// Find directory containing printer definitions // Find directory containing printer definitions
BPath path; BPath path;
rc = ::find_directory(B_USER_PRINTERS_DIRECTORY,&path,true,NULL); rc = ::find_directory(B_USER_PRINTERS_DIRECTORY,&path,true,NULL);
@@ -382,20 +382,57 @@ PrintServerApp::CreatePrinter(const char* printerName, const char* driverName,
BDirectory printer; BDirectory printer;
rc = printersDir.CreateDirectory(printerName, &printer); rc = printersDir.CreateDirectory(printerName, &printer);
if (rc != B_OK) if (rc == B_FILE_EXISTS) {
printer.SetTo(&printersDir, printerName);
BString info;
char type[B_MIME_TYPE_LENGTH];
BNodeInfo(&printer).GetType(type);
if (strcmp(PSRV_PRINTER_FILETYPE, type) == 0) {
BPath tmp;
if (FindPrinterDriver(printerName, tmp) == B_OK) {
if (fDefaultPrinter) {
// the printer exists, but is not the default printer
if(strcmp(fDefaultPrinter->Name(), printerName) != 0)
rc = B_OK;
return rc;
}
// the printer exists, but no default at all
return B_OK;
} else {
info.SetTo("There already exists an printer you are going to"
" create, but it's driver could not be found! Replace?");
}
} else {
info.SetTo("There already exists an printer you are going to"
" create, but it's not usable at all! Replace?");
}
if (info.Length() != 0) {
BAlert *alert = new BAlert("Info", info.String(), "Cancel", "OK");
alert->SetShortcut(0, B_ESCAPE);
if (alert->Go() == 0)
return rc;
}
} else if (rc != B_OK) {
return rc; return rc;
}
// Set its type to a printer // Set its type to a printer
BNodeInfo info(&printer); BNodeInfo info(&printer);
info.SetType(PSRV_PRINTER_FILETYPE); info.SetType(PSRV_PRINTER_FILETYPE);
// Store the settings in its attributes // Store the settings in its attributes
printer.WriteAttr(PSRV_PRINTER_ATTR_PRT_NAME, B_STRING_TYPE, 0, printerName, ::strlen(printerName)+1); printer.WriteAttr(PSRV_PRINTER_ATTR_PRT_NAME, B_STRING_TYPE, 0, printerName,
printer.WriteAttr(PSRV_PRINTER_ATTR_DRV_NAME, B_STRING_TYPE, 0, driverName, ::strlen(driverName)+1); ::strlen(printerName) + 1);
printer.WriteAttr(PSRV_PRINTER_ATTR_TRANSPORT, B_STRING_TYPE, 0, transportName,::strlen(transportName)+1); printer.WriteAttr(PSRV_PRINTER_ATTR_DRV_NAME, B_STRING_TYPE, 0, driverName,
printer.WriteAttr(PSRV_PRINTER_ATTR_TRANSPORT_ADDR, B_STRING_TYPE, 0, transportPath,::strlen(transportPath)+1); ::strlen(driverName) + 1);
printer.WriteAttr(PSRV_PRINTER_ATTR_CNX, B_STRING_TYPE, 0, connection, ::strlen(connection)+1); printer.WriteAttr(PSRV_PRINTER_ATTR_TRANSPORT, B_STRING_TYPE, 0, transportName,
::strlen(transportName) + 1);
printer.WriteAttr(PSRV_PRINTER_ATTR_TRANSPORT_ADDR, B_STRING_TYPE, 0,
transportPath, ::strlen(transportPath) + 1);
printer.WriteAttr(PSRV_PRINTER_ATTR_CNX, B_STRING_TYPE, 0, connection,
::strlen(connection) + 1);
// Notify printer driver that a new printer definition node // Notify printer driver that a new printer definition node
// has been created. // has been created.
@@ -405,30 +442,30 @@ PrintServerApp::CreatePrinter(const char* printerName, const char* driverName,
rc = FindPrinterDriver(driverName, path); rc = FindPrinterDriver(driverName, path);
if (rc != B_OK) if (rc != B_OK)
goto error; goto error;
id = ::load_add_on(path.Path()); id = ::load_add_on(path.Path());
if (id <= 0) { if (id <= 0) {
rc = B_ERROR; rc = B_ERROR;
goto error; goto error;
} }
rc = get_image_symbol(id, "add_printer", B_SYMBOL_TYPE_TEXT, (void**)&func); rc = get_image_symbol(id, "add_printer", B_SYMBOL_TYPE_TEXT, (void**)&func);
if (rc != B_OK) if (rc != B_OK)
goto error; goto error;
// call the function and check its result // call the function and check its result
if ((*func)(printerName) == NULL) if ((*func)(printerName) == NULL)
rc = B_ERROR; rc = B_ERROR;
else else
printer.WriteAttr(PSRV_PRINTER_ATTR_STATE, B_STRING_TYPE, 0, "free", ::strlen("free")+1); printer.WriteAttr(PSRV_PRINTER_ATTR_STATE, B_STRING_TYPE, 0, "free", ::strlen("free")+1);
error: error:
if (rc != B_OK) { if (rc != B_OK) {
BEntry entry; BEntry entry;
if (printer.GetEntry(&entry) == B_OK) if (printer.GetEntry(&entry) == B_OK)
entry.Remove(); entry.Remove();
} }
if (id > 0) if (id > 0)
::unload_add_on(id); ::unload_add_on(id);
@@ -455,9 +492,9 @@ PrintServerApp::SelectPrinter(const char* printerName)
{ {
status_t rc; status_t rc;
BNode node; BNode node;
// Find the node of the "old" default printer // Find the node of the "old" default printer
if (fDefaultPrinter != NULL if (fDefaultPrinter != NULL
&& FindPrinterNode(fDefaultPrinter->Name(), node) == B_OK) { && FindPrinterNode(fDefaultPrinter->Name(), node) == B_OK) {
// and remove the custom icon // and remove the custom icon
BNodeInfo info(&node); BNodeInfo info(&node);
@@ -473,12 +510,12 @@ PrintServerApp::SelectPrinter(const char* printerName)
info.SetIcon(fSelectedIconMini, B_MINI_ICON); info.SetIcon(fSelectedIconMini, B_MINI_ICON);
info.SetIcon(fSelectedIconLarge, B_LARGE_ICON); info.SetIcon(fSelectedIconLarge, B_LARGE_ICON);
} }
fDefaultPrinter = Printer::Find(printerName); fDefaultPrinter = Printer::Find(printerName);
StoreDefaultPrinter(); StoreDefaultPrinter();
// update our pref file // update our pref file
be_roster->Broadcast(new BMessage(B_PRINTER_CHANGED)); be_roster->Broadcast(new BMessage(B_PRINTER_CHANGED));
return rc; return rc;
} }
@@ -554,7 +591,7 @@ PrintServerApp::StoreDefaultPrinter()
// --------------------------------------------------------------- // ---------------------------------------------------------------
status_t status_t
PrintServerApp::FindPrinterNode(const char* name, BNode& node) PrintServerApp::FindPrinterNode(const char* name, BNode& node)
{ {
// Find directory containing printer definitions // Find directory containing printer definitions
BPath path; BPath path;
status_t rc = ::find_directory(B_USER_PRINTERS_DIRECTORY, &path, true, NULL); status_t rc = ::find_directory(B_USER_PRINTERS_DIRECTORY, &path, true, NULL);
@@ -594,8 +631,8 @@ PrintServerApp::FindPrinterDriver(const char* name, BPath& outPath)
bool PrintServerApp::OpenSettings(BFile& file, const char* name, bool forReading) { bool PrintServerApp::OpenSettings(BFile& file, const char* name, bool forReading) {
BPath path; BPath path;
uint32 openMode = forReading ? B_READ_ONLY : B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY; uint32 openMode = forReading ? B_READ_ONLY : B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY;
return find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK return find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK
&& path.Append(name) == B_OK && path.Append(name) == B_OK
&& file.SetTo(path.Path(), openMode) == B_OK; && file.SetTo(path.Path(), openMode) == B_OK;
} }