From 24a0bfcb01213f135e54941f144acc997eb8c72b Mon Sep 17 00:00:00 2001 From: Michael Pfeiffer Date: Thu, 1 Feb 2007 20:39:20 +0000 Subject: [PATCH] Fix bug #1004. The directory B_USER_PRINTERS_DIRECTORY does not exist in haiku.image. It is now created when print_server or the Printers preflet is started. Applied coding style. "Flattened" some nested if statements. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20030 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/preferences/print/PrinterListView.cpp | 289 ++++++++------- src/preferences/print/PrinterListView.h | 106 +++--- src/servers/print/PrintServerApp.R5.cpp | 34 -- src/servers/print/PrintServerApp.cpp | 406 +++++++++++----------- src/servers/print/PrintServerApp.h | 139 ++++---- 5 files changed, 495 insertions(+), 479 deletions(-) diff --git a/src/preferences/print/PrinterListView.cpp b/src/preferences/print/PrinterListView.cpp index 3b4d9c9886..f5ee52588a 100644 --- a/src/preferences/print/PrinterListView.cpp +++ b/src/preferences/print/PrinterListView.cpp @@ -44,41 +44,43 @@ // Implementation of PrinterListView PrinterListView::PrinterListView(BRect frame) - : Inherited(frame, "printers_list", B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL) - , fFolder(NULL) + : Inherited(frame, "printers_list", B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL), + fFolder(NULL) { } -void PrinterListView::BuildPrinterList() { - // clear list - const BListItem** items = Items(); - for (int32 i = CountItems()-1; i >= 0; i --) { - delete items[i]; - } - MakeEmpty(); - // TODO: Fixup situation in which PrintServer is not running - BEntry entry; - status_t rc; - BPath path; +void +PrinterListView::BuildPrinterList() +{ + // clear list + const BListItem** items = Items(); + for (int32 i = CountItems()-1; i >= 0; i --) + delete items[i]; + MakeEmpty(); - // Find directory containing printer definition nodes - if ((rc=::find_directory(B_USER_PRINTERS_DIRECTORY, &path)) == B_OK) { - BDirectory dir(path.Path()); + // Find directory containing printer definition nodes + BPath path; + status_t rc = ::find_directory(B_USER_PRINTERS_DIRECTORY, &path); + if (rc != B_OK) + return; + + BDirectory dir(path.Path()); + rc = dir.InitCheck(); + if (rc != B_OK) + return; - // Can we reach the directory? - if ((rc = dir.InitCheck()) == B_OK) { - fNode = dir; - // Yes, so loop over it's entries - while((rc = dir.GetNextEntry(&entry)) == B_OK) { - BDirectory printer(&entry); - AddPrinter(printer); - } - } + fNode = dir; + BEntry entry; + while(dir.GetNextEntry(&entry) == B_OK) { + BDirectory printer(&entry); + AddPrinter(printer); } } -void PrinterListView::AttachedToWindow() + +void +PrinterListView::AttachedToWindow() { Inherited::AttachedToWindow(); @@ -86,18 +88,25 @@ void PrinterListView::AttachedToWindow() SetInvocationMessage(new BMessage(MSG_MKDEF_PRINTER)); SetTarget(Window()); + BPath path; + bool hasPrintersDirectory = find_directory(B_USER_PRINTERS_DIRECTORY, &path) == B_OK; + + if (hasPrintersDirectory) { + create_directory(path.Path(), 0777); + // directory has to exist in order to start watching it + } + BuildPrinterList(); - // Select active printer + // Select active printer for (int32 i = 0; i < CountItems(); i ++) { PrinterItem* item = dynamic_cast(ItemAt(i)); - if (item->IsActivePrinter()) { + if (item != NULL && item->IsActivePrinter()) { Select(i); break; } } - BPath path; - if (find_directory(B_USER_PRINTERS_DIRECTORY, &path) == B_OK) { + if (hasPrintersDirectory) { BDirectory dir(path.Path()); if (dir.InitCheck() == B_OK) { fFolder = new FolderWatcher(this->Window(), dir, true); @@ -106,12 +115,18 @@ void PrinterListView::AttachedToWindow() } } -bool PrinterListView::QuitRequested() { + +bool +PrinterListView::QuitRequested() +{ delete fFolder; fFolder = NULL; return true; } -void PrinterListView::AddPrinter(BDirectory& printer) { + +void +PrinterListView::AddPrinter(BDirectory& printer) +{ BString state; node_ref node; // If the entry is a directory @@ -132,7 +147,9 @@ void PrinterListView::AddPrinter(BDirectory& printer) { } } -PrinterItem* PrinterListView::FindItem(node_ref* node) { + +PrinterItem* PrinterListView::FindItem(node_ref* node) +{ for (int32 i = CountItems()-1; i >= 0; i --) { PrinterItem* item = dynamic_cast(ItemAt(i)); node_ref ref; @@ -143,12 +160,17 @@ PrinterItem* PrinterListView::FindItem(node_ref* node) { return NULL; } -void PrinterListView::EntryCreated(node_ref* node, entry_ref* entry) { + +void +PrinterListView::EntryCreated(node_ref* node, entry_ref* entry) +{ BDirectory printer(node); AddPrinter(printer); } -void PrinterListView::EntryRemoved(node_ref* node) { + +void PrinterListView::EntryRemoved(node_ref* node) +{ PrinterItem* item = FindItem(node); if (item) { RemoveItem(item); @@ -156,51 +178,56 @@ void PrinterListView::EntryRemoved(node_ref* node) { } } -void PrinterListView::AttributeChanged(node_ref* node) { +void +PrinterListView::AttributeChanged(node_ref* node) +{ BDirectory printer(node); AddPrinter(printer); } -void PrinterListView::UpdateItem(PrinterItem* item) { +void +PrinterListView::UpdateItem(PrinterItem* item) +{ item->UpdatePendingJobs(); InvalidateItem(IndexOf(item)); } -PrinterItem* PrinterListView::SelectedItem() { +PrinterItem* PrinterListView::SelectedItem() +{ BListItem* item = ItemAt(CurrentSelection()); return dynamic_cast(item); } + BBitmap* PrinterItem::sIcon = NULL; BBitmap* PrinterItem::sSelectedIcon = NULL; + PrinterItem::PrinterItem(PrintersWindow* window, const BDirectory& node) - : BListItem(0, false) - , fFolder(NULL) - , fNode(node) + : BListItem(0, false), + fFolder(NULL), + fNode(node) { - if (sIcon == NULL) - { + if (sIcon == NULL) { sIcon = new BBitmap(BRect(0,0,B_LARGE_ICON-1,B_LARGE_ICON-1), B_CMAP8); BMimeType type(PSRV_PRINTER_FILETYPE); type.GetIcon(sIcon, B_LARGE_ICON); } - if (sSelectedIcon == NULL) - { + if (sSelectedIcon == NULL) { sSelectedIcon = new BBitmap(BRect(0,0,B_LARGE_ICON-1,B_LARGE_ICON-1), B_CMAP8); BMimeType type(PRNT_SIGNATURE_TYPE); type.GetIcon(sSelectedIcon, B_LARGE_ICON); } - // Get Name of printer + // Get Name of printer GetStringProperty(PSRV_PRINTER_ATTR_PRT_NAME, fName); GetStringProperty(PSRV_PRINTER_ATTR_COMMENTS, fComments); GetStringProperty(PSRV_PRINTER_ATTR_TRANSPORT, fTransport); GetStringProperty(PSRV_PRINTER_ATTR_DRV_NAME, fDriverName); BPath path; - // Setup spool folder + // Setup spool folder if (find_directory(B_USER_PRINTERS_DIRECTORY, &path) == B_OK) { path.Append(fName.String()); BDirectory dir(path.Path()); @@ -210,16 +237,22 @@ PrinterItem::PrinterItem(PrintersWindow* window, const BDirectory& node) UpdatePendingJobs(); } -PrinterItem::~PrinterItem() { + +PrinterItem::~PrinterItem() +{ delete fFolder; fFolder = NULL; } -void PrinterItem::GetStringProperty(const char* propName, BString& outString) + +void +PrinterItem::GetStringProperty(const char* propName, BString& outString) { fNode.ReadAttrString(propName, &outString); } -void PrinterItem::Update(BView *owner, const BFont *font) + +void +PrinterItem::Update(BView *owner, const BFont *font) { BListItem::Update(owner,font); @@ -229,6 +262,7 @@ void PrinterItem::Update(BView *owner, const BFont *font) SetHeight( (height.ascent+height.descent+height.leading) * 3.0 +4 ); } + bool PrinterItem::Remove(BListView* view) { BMessenger msgr; @@ -247,104 +281,113 @@ bool PrinterItem::Remove(BListView* view) return false; } + void PrinterItem::DrawItem(BView *owner, BRect /*bounds*/, bool complete) { BListView* list = dynamic_cast(owner); - if (list) - { - font_height height; - BFont font; - owner->GetFont(&font); - font.GetHeight(&height); - float fntheight = height.ascent+height.descent+height.leading; + if (list == NULL) + return; - BRect bounds = list->ItemFrame(list->IndexOf(this)); - - rgb_color color = owner->ViewColor(); - if ( IsSelected() ) - color = tint_color(color, B_HIGHLIGHT_BACKGROUND_TINT); - - rgb_color oldviewcolor = owner->ViewColor(); - rgb_color oldlowcolor = owner->LowColor(); - rgb_color oldcolor = owner->HighColor(); - owner->SetViewColor( color ); - owner->SetHighColor( color ); - owner->SetLowColor( color ); - owner->FillRect(bounds); - owner->SetLowColor( oldlowcolor ); - owner->SetHighColor( oldcolor ); + font_height height; + BFont font; + owner->GetFont(&font); + font.GetHeight(&height); + float fntheight = height.ascent+height.descent+height.leading; - BPoint iconPt = bounds.LeftTop() + BPoint(2,2); - BPoint namePt = iconPt + BPoint(B_LARGE_ICON+8, fntheight); - BPoint driverPt = iconPt + BPoint(B_LARGE_ICON+8, fntheight*2); - BPoint commentPt = iconPt + BPoint(B_LARGE_ICON+8, fntheight*3); - - float width = owner->StringWidth("No pending jobs."); - BPoint pendingPt(bounds.right - width -8, namePt.y); - BPoint transportPt(bounds.right - width -8, driverPt.y); - - drawing_mode mode = owner->DrawingMode(); - owner->SetDrawingMode(B_OP_OVER); - owner->DrawBitmap(IsActivePrinter() ? sSelectedIcon : sIcon, iconPt); - - // left of item - owner->DrawString(fName.String(), fName.Length(), namePt); - owner->DrawString(fDriverName.String(), fDriverName.Length(), driverPt); - owner->DrawString(fComments.String(), fComments.Length(), commentPt); - - // right of item - owner->DrawString(fPendingJobs.String(), 16, pendingPt); - owner->DrawString(fTransport.String(), fTransport.Length(), transportPt); - - owner->SetDrawingMode(mode); - - owner->SetViewColor(oldviewcolor); - } -} - -bool PrinterItem::IsActivePrinter() -{ - bool rc = false; - BMessenger msgr; - - if (::GetPrinterServerMessenger(msgr) == B_OK) - { - BMessage reply, getNameOfActivePrinter(B_GET_PROPERTY); - getNameOfActivePrinter.AddSpecifier("ActivePrinter"); + BRect bounds = list->ItemFrame(list->IndexOf(this)); - BString activePrinterName; - if (msgr.SendMessage(&getNameOfActivePrinter, &reply) == B_OK && - reply.FindString("result", &activePrinterName) == B_OK) { - // Compare name of active printer with name of 'this' printer item - rc = (fName == activePrinterName); - } - } + rgb_color color = owner->ViewColor(); + if ( IsSelected() ) + color = tint_color(color, B_HIGHLIGHT_BACKGROUND_TINT); + + rgb_color oldviewcolor = owner->ViewColor(); + rgb_color oldlowcolor = owner->LowColor(); + rgb_color oldcolor = owner->HighColor(); + owner->SetViewColor( color ); + owner->SetHighColor( color ); + owner->SetLowColor( color ); + owner->FillRect(bounds); + owner->SetLowColor( oldlowcolor ); + owner->SetHighColor( oldcolor ); - return rc; + BPoint iconPt = bounds.LeftTop() + BPoint(2,2); + BPoint namePt = iconPt + BPoint(B_LARGE_ICON+8, fntheight); + BPoint driverPt = iconPt + BPoint(B_LARGE_ICON+8, fntheight*2); + BPoint commentPt = iconPt + BPoint(B_LARGE_ICON+8, fntheight*3); + + float width = owner->StringWidth("No pending jobs."); + BPoint pendingPt(bounds.right - width -8, namePt.y); + BPoint transportPt(bounds.right - width -8, driverPt.y); + + drawing_mode mode = owner->DrawingMode(); + owner->SetDrawingMode(B_OP_OVER); + owner->DrawBitmap(IsActivePrinter() ? sSelectedIcon : sIcon, iconPt); + + // left of item + owner->DrawString(fName.String(), fName.Length(), namePt); + owner->DrawString(fDriverName.String(), fDriverName.Length(), driverPt); + owner->DrawString(fComments.String(), fComments.Length(), commentPt); + + // right of item + owner->DrawString(fPendingJobs.String(), 16, pendingPt); + owner->DrawString(fTransport.String(), fTransport.Length(), transportPt); + + owner->SetDrawingMode(mode); + + owner->SetViewColor(oldviewcolor); } -bool PrinterItem::HasPendingJobs() { + +bool +PrinterItem::IsActivePrinter() +{ + BMessenger msgr; + if (::GetPrinterServerMessenger(msgr) != B_OK) + return false; + + BMessage getNameOfActivePrinter(B_GET_PROPERTY); + getNameOfActivePrinter.AddSpecifier("ActivePrinter"); + + BString activePrinterName; + BMessage reply; + return msgr.SendMessage(&getNameOfActivePrinter, &reply) == B_OK + && reply.FindString("result", &activePrinterName) == B_OK + && fName == activePrinterName; +} + + +bool +PrinterItem::HasPendingJobs() +{ return fFolder && fFolder->CountJobs() > 0; } -SpoolFolder* PrinterItem::Folder() { + +SpoolFolder* PrinterItem::Folder() +{ return fFolder; } -BDirectory* PrinterItem::Node() { + +BDirectory* +PrinterItem::Node() +{ return &fNode; } -void PrinterItem::UpdatePendingJobs() { + +void +PrinterItem::UpdatePendingJobs() +{ if (fFolder) { uint32 pendingJobs = fFolder->CountJobs(); - fPendingJobs = ""; if (pendingJobs == 1) { fPendingJobs = "1 pending job."; + return; } else if (pendingJobs > 1) { fPendingJobs << pendingJobs << " pending jobs.h"; + return; } - if (pendingJobs >= 1) return; } fPendingJobs = "No pending jobs."; } diff --git a/src/preferences/print/PrinterListView.h b/src/preferences/print/PrinterListView.h index 36d9d4a2a2..b5ddbaa434 100644 --- a/src/preferences/print/PrinterListView.h +++ b/src/preferences/print/PrinterListView.h @@ -43,65 +43,67 @@ class SpoolFolder; class PrinterItem; class PrinterListView; -class PrinterListView : public BListView, public FolderListener -{ - typedef BListView Inherited; - - BDirectory fNode; - FolderWatcher* fFolder; - - void AddPrinter(BDirectory& printer); - PrinterItem* FindItem(node_ref* node); - - void EntryCreated(node_ref* node, entry_ref* entry); - void EntryRemoved(node_ref* node); - void AttributeChanged(node_ref* node); - -public: - PrinterListView(BRect frame); - void AttachedToWindow(); - bool QuitRequested(); - - void BuildPrinterList(); - PrinterItem* SelectedItem(); +class PrinterListView : public BListView, public FolderListener { + private: + typedef BListView Inherited; - void UpdateItem(PrinterItem* item); + void AddPrinter(BDirectory &printer); + PrinterItem *FindItem(node_ref *node); + + void EntryCreated(node_ref *node, entry_ref *entry); + void EntryRemoved(node_ref *node); + void AttributeChanged(node_ref *node); + + public: + PrinterListView(BRect frame); + void AttachedToWindow(); + bool QuitRequested(); + + void BuildPrinterList(); + PrinterItem *SelectedItem(); + + void UpdateItem(PrinterItem *item); + + private: + BDirectory fNode; + FolderWatcher *fFolder; }; class BBitmap; class PrintersWindow; -class PrinterItem : public BListItem -{ -public: - PrinterItem(PrintersWindow* window, const BDirectory& node/*const BMessenger& thePrinter*/); - ~PrinterItem(); - - void DrawItem(BView *owner, BRect bounds, bool complete); - void Update(BView *owner, const BFont *font); - - bool Remove(BListView* view); - bool IsActivePrinter(); - bool HasPendingJobs(); - - const char* Name() const - { return fName.String(); } +class PrinterItem : public BListItem { + public: + PrinterItem(PrintersWindow *window, const BDirectory &node); + ~PrinterItem(); - SpoolFolder* Folder(); - BDirectory* Node(); - void UpdatePendingJobs(); + void DrawItem(BView *owner, BRect bounds, bool complete); + void Update(BView *owner, const BFont *font); + + bool Remove(BListView *view); + bool IsActivePrinter(); + bool HasPendingJobs(); + + const char *Name() const { + return fName.String(); + } + + SpoolFolder *Folder(); + BDirectory *Node(); + void UpdatePendingJobs(); + + private: + void GetStringProperty(const char *propName, BString &outString); -private: - void GetStringProperty(const char* propName, BString& outString); - - SpoolFolder *fFolder; - BDirectory fNode; - BString fComments; - BString fTransport; - BString fDriverName; - BString fName; - BString fPendingJobs; - static BBitmap* sIcon; - static BBitmap* sSelectedIcon; + SpoolFolder *fFolder; + BDirectory fNode; + BString fComments; + BString fTransport; + BString fDriverName; + BString fName; + BString fPendingJobs; + + static BBitmap *sIcon; + static BBitmap *sSelectedIcon; }; #endif diff --git a/src/servers/print/PrintServerApp.R5.cpp b/src/servers/print/PrintServerApp.R5.cpp index d00b86f5d8..e99aa22fc3 100644 --- a/src/servers/print/PrintServerApp.R5.cpp +++ b/src/servers/print/PrintServerApp.R5.cpp @@ -185,40 +185,6 @@ void PrintServerApp::Handle_BeOSR5_Message(BMessage* msg) } break; -#if 0 - // Create a new printer - case PSRV_MAKE_PRINTER: { - BString driverName, transportName, transportPath; - BString printerName, connection; - - 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 - ) { - - if (msg->FindString("connection", &connection) != B_OK) - connection = "Local"; - - // then create the actual printer - if (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 - char buffer[256]; - ::sprintf(buffer, "Would you like to make %s the default printer?", - printerName.String()); - - BAlert* alert = new BAlert("", buffer, "No", "Yes"); - if (alert->Go() == 1) { - SelectPrinter(printerName.String()); - } - } - } - } - break; -#endif - case PSRV_SHOW_PAGE_SETUP: case PSRV_SHOW_PRINT_SETUP: case PSRV_GET_DEFAULT_SETTINGS: diff --git a/src/servers/print/PrintServerApp.cpp b/src/servers/print/PrintServerApp.cpp index 996d864501..eae036c28d 100644 --- a/src/servers/print/PrintServerApp.cpp +++ b/src/servers/print/PrintServerApp.cpp @@ -12,7 +12,7 @@ #include "Printer.h" #include "pr_server.h" - // BeOS API +// BeOS API #include #include #include @@ -27,9 +27,11 @@ #include #include - // ANSI C -#include //for printf -#include //for unlink +// ANSI C +#include + // for printf +#include + // for unlink BLocker *gLock = NULL; @@ -47,18 +49,13 @@ typedef char* (*add_printer_func_t)(const char* printer_name); * * @returns B_OK if application was started, or an errorcode if * application failed to start. - * - * @see your favorite C/C++ textbook :P */ - int -main() +main() { status_t rc = B_OK; gLock = new BLocker(); - // Create our application object PrintServerApp print_server(&rc); - // If all went fine, let's start it if (rc == B_OK) { print_server.Run(); } @@ -76,7 +73,6 @@ main() * * @see BApplication */ - PrintServerApp::PrintServerApp(status_t* err) : Inherited(PSRV_SIGNATURE_TYPE, err), fSelectedIconMini(NULL), @@ -88,120 +84,128 @@ PrintServerApp::PrintServerApp(status_t* err) { fSettings = Settings::GetSettings(); LoadSettings(); - // If our superclass initialized ok - if (*err == B_OK) { - fHasReferences = create_sem(1, "has_references"); + + if (*err != B_OK) + return; - // let us try as well - SetupPrinterList(); - RetrieveDefaultPrinter(); - - 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); - - // Cache icons for selected printer - BMimeType type(PRNT_SIGNATURE_TYPE); - type.GetIcon(fSelectedIconMini, B_MINI_ICON); - type.GetIcon(fSelectedIconLarge, B_LARGE_ICON); - - // Start handling of spooled files - PostMessage(PSRV_PRINT_SPOOLED_JOB); - } + fHasReferences = create_sem(1, "has_references"); + + SetupPrinterList(); + RetrieveDefaultPrinter(); + + // Cache icons for selected printer + 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); + BMimeType type(PRNT_SIGNATURE_TYPE); + type.GetIcon(fSelectedIconMini, B_MINI_ICON); + type.GetIcon(fSelectedIconLarge, B_LARGE_ICON); + + PostMessage(PSRV_PRINT_SPOOLED_JOB); + // Start handling of spooled files } -PrintServerApp::~PrintServerApp() { + +PrintServerApp::~PrintServerApp() +{ SaveSettings(); delete fSettings; } -bool PrintServerApp::QuitRequested() + +bool +PrintServerApp::QuitRequested() { + // don't quit when user types Command+Q! BMessage* m = CurrentMessage(); - bool shortcut; - // don't quit when user types Command+Q! - if (m && m->FindBool("shortcut", &shortcut) == B_OK && shortcut) return false; + bool shortcut; + if (m != NULL && m->FindBool("shortcut", &shortcut) == B_OK && shortcut) + return false; - bool rc = Inherited::QuitRequested(); - if (rc) { - delete fFolder; fFolder = NULL; -#if 0 - // Find directory containing printer definition nodes - BPath path; - if (::find_directory(B_USER_PRINTERS_DIRECTORY, &path) == B_OK) { - BEntry entry(path.Path()); - node_ref nref; - if (entry.InitCheck() == B_OK && - entry.GetNodeRef(&nref) == B_OK) { - // Stop watching the printer directory - ::watch_node(&nref, B_STOP_WATCHING, be_app_messenger); - } - } -#endif + if (!Inherited::QuitRequested()) + return false; - // Release all printers - Printer* printer; - while ((printer = Printer::At(0)) != NULL) { - printer->AbortPrintThread(); - UnregisterPrinter(printer); - } + // Stop watching the folder + delete fFolder; fFolder = NULL; - // Wait for printers - if (fHasReferences > 0) { - acquire_sem(fHasReferences); - delete_sem(fHasReferences); - fHasReferences = 0; - } - - ASSERT(fSelectedIconMini != NULL); - - delete fSelectedIconMini; fSelectedIconMini = NULL; - delete fSelectedIconLarge; fSelectedIconLarge = NULL; + // Release all printers + Printer* printer; + while ((printer = Printer::At(0)) != NULL) { + printer->AbortPrintThread(); + UnregisterPrinter(printer); } - - return rc; + + // Wait for printers + if (fHasReferences > 0) { + acquire_sem(fHasReferences); + delete_sem(fHasReferences); + fHasReferences = 0; + } + + delete fSelectedIconMini; fSelectedIconMini = NULL; + delete fSelectedIconLarge; fSelectedIconLarge = NULL; + + return true; } -void PrintServerApp::Acquire() { - if (atomic_add(&fReferences, 1) == 0) acquire_sem(fHasReferences); + +void +PrintServerApp::Acquire() +{ + if (atomic_add(&fReferences, 1) == 0) + acquire_sem(fHasReferences); } -void PrintServerApp::Release() { - if (atomic_add(&fReferences, -1) == 1) release_sem(fHasReferences); + +void +PrintServerApp::Release() +{ + if (atomic_add(&fReferences, -1) == 1) + release_sem(fHasReferences); } -void PrintServerApp::RegisterPrinter(BDirectory* printer) { + +void +PrintServerApp::RegisterPrinter(BDirectory* printer) +{ BString transport, address, connection, state; - 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_CNX, &connection) == B_OK && - printer->ReadAttrString(PSRV_PRINTER_ATTR_STATE, &state) == B_OK && - state == "free") { + 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_CNX, &connection) == B_OK + && printer->ReadAttrString(PSRV_PRINTER_ATTR_STATE, &state) == B_OK + && state == "free") { BAutolock lock(gLock); if (lock.IsLocked()) { - // check if printer is already registered + // check if printer is already registered node_ref node; - Printer* p; - if (printer->GetNodeRef(&node) != B_OK) return; - p = Printer::Find(&node); - if (p != NULL) return; - // register new printer + if (printer->GetNodeRef(&node) != B_OK) + return; + + if (Printer::Find(&node) != NULL) + return; + + // register new printer Resource* r = fResourceManager.Allocate(transport.String(), address.String(), connection.String()); - p = new Printer(printer, r); - AddHandler(p); + AddHandler(new Printer(printer, r)); Acquire(); } } } -void PrintServerApp::UnregisterPrinter(Printer* printer) { + +void +PrintServerApp::UnregisterPrinter(Printer* printer) +{ RemoveHandler(printer); Printer::Remove(printer); printer->Release(); } -void PrintServerApp::NotifyPrinterDeletion(Printer* printer) { + +void +PrintServerApp::NotifyPrinterDeletion(Printer* printer) +{ BAutolock lock(gLock); if (lock.IsLocked()) { fResourceManager.Free(printer->GetResource()); @@ -210,7 +214,9 @@ void PrintServerApp::NotifyPrinterDeletion(Printer* printer) { } -void PrintServerApp::EntryCreated(node_ref* node, entry_ref* entry) { +void +PrintServerApp::EntryCreated(node_ref* node, entry_ref* entry) +{ BEntry printer(entry); if (printer.InitCheck() == B_OK && printer.IsDirectory()) { BDirectory dir(&printer); @@ -218,7 +224,10 @@ void PrintServerApp::EntryCreated(node_ref* node, entry_ref* entry) { } } -void PrintServerApp::EntryRemoved(node_ref* node) { + +void +PrintServerApp::EntryRemoved(node_ref* node) +{ Printer* printer = Printer::Find(node); if (printer) { if (printer == fDefaultPrinter) fDefaultPrinter = NULL; @@ -226,13 +235,17 @@ void PrintServerApp::EntryRemoved(node_ref* node) { } } -void PrintServerApp::AttributeChanged(node_ref* node) { + +void +PrintServerApp::AttributeChanged(node_ref* node) +{ BDirectory printer(node); if (printer.InitCheck() == B_OK) { RegisterPrinter(&printer); } } + // --------------------------------------------------------------- // SetupPrinterList // @@ -246,51 +259,45 @@ void PrintServerApp::AttributeChanged(node_ref* node) { // Returns: // B_OK if successful, or an errorcode if failed. // --------------------------------------------------------------- -status_t PrintServerApp::SetupPrinterList() +status_t +PrintServerApp::SetupPrinterList() { - BEntry entry; status_t rc; + + // Find directory containing printer definition nodes BPath path; + rc = ::find_directory(B_USER_PRINTERS_DIRECTORY, &path); + if (rc != B_OK) + return rc; - // Find directory containing printer definition nodes - if ((rc=::find_directory(B_USER_PRINTERS_DIRECTORY, &path)) == B_OK) { - BDirectory dir(path.Path()); - - // Can we reach the directory? - if ((rc=dir.InitCheck()) == B_OK) { - // Yes, so loop over it's entries - while((rc=dir.GetNextEntry(&entry)) == B_OK) { - // If the entry is a directory - if (entry.IsDirectory()) { - // Check it's Mime type for a spool director - BDirectory node(&entry); - BNodeInfo info(&node); - char buffer[256]; - - if (info.GetType(buffer) == B_OK && - strcmp(buffer, PSRV_PRINTER_FILETYPE) == 0) { - // Yes, it is a printer definition node - RegisterPrinter(&node); - } - } - } - - - fFolder = new FolderWatcher(this, dir, true); - fFolder->SetListener(this); -#if 0 - // If we scanned all entries successfully - node_ref nref; - if (rc == B_ENTRY_NOT_FOUND && - (rc=dir.GetNodeRef(&nref)) == B_OK) { - // Get node to watch - rc = ::watch_node(&nref, B_WATCH_DIRECTORY, be_app_messenger); - } -#endif + // Directory has to exist in order to watch it + mode_t mode = 0777; + create_directory(path.Path(), mode); + + BDirectory dir(path.Path()); + rc = dir.InitCheck(); + if (rc != B_OK) + return rc; + + // Register printer definition nodes + BEntry entry; + while(dir.GetNextEntry(&entry) == B_OK) { + if (!entry.IsDirectory()) + continue; + + BDirectory node(&entry); + BNodeInfo info(&node); + char buffer[256]; + if (info.GetType(buffer) == B_OK && strcmp(buffer, PSRV_PRINTER_FILETYPE) == 0) { + RegisterPrinter(&node); } } + + // Now we are ready to start node watching + fFolder = new FolderWatcher(this, dir, true); + fFolder->SetListener(this); - return rc; + return B_OK; } // --------------------------------------------------------------- @@ -358,52 +365,57 @@ PrintServerApp::CreatePrinter(const char* printerName, const char* driverName, { status_t rc; - // Find directory containing printer definitions + // Find directory containing printer definitions BPath path; - if ((rc=::find_directory(B_USER_PRINTERS_DIRECTORY,&path,true,NULL)) == B_OK) { + rc = ::find_directory(B_USER_PRINTERS_DIRECTORY,&path,true,NULL); + if (rc != B_OK) + return rc; - // Create our printer definition/spool directory - BDirectory printersDir(path.Path()); - BDirectory printer; - if ((rc=printersDir.CreateDirectory(printerName,&printer)) == B_OK) { - // Set its type to a printer - BNodeInfo info(&printer); - info.SetType(PSRV_PRINTER_FILETYPE); + // Create our printer definition/spool directory + BDirectory printersDir(path.Path()); + BDirectory printer; + + rc = printersDir.CreateDirectory(printerName, &printer); + if (rc != B_OK) + return rc; + + // Set its type to a printer + BNodeInfo info(&printer); + info.SetType(PSRV_PRINTER_FILETYPE); + + // 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_DRV_NAME, B_STRING_TYPE, 0, driverName, ::strlen(driverName)+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 + // has been created. + // TODO check why we keep the printer definition node + // although printer driver cannot be found or loaded + if (FindPrinterDriver(driverName, path) != B_OK) + return B_OK; + + image_id id = ::load_add_on(path.Path()); + if (id <= 0) + return B_OK; + + add_printer_func_t func; + if (get_image_symbol(id, "add_printer", B_SYMBOL_TYPE_TEXT, (void**)&func) == B_OK) { + // call the function and check its result + if ((*func)(printerName) == NULL) { + BEntry entry; + if (printer.GetEntry(&entry) == B_OK) + entry.Remove(); - // 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_DRV_NAME, B_STRING_TYPE, 0, driverName, ::strlen(driverName)+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); - - // Find printer driver - if (FindPrinterDriver(driverName, path) == B_OK) { - // Try and load the addon - image_id id = ::load_add_on(path.Path()); - if (id > 0) { - // Addon was loaded, so try and get the add_printer symbol - add_printer_func_t func; - if (get_image_symbol(id, "add_printer", B_SYMBOL_TYPE_TEXT, (void**)&func) == B_OK) { - // call the function and check its result - if ((*func)(printerName) == NULL) { - BEntry entry; - if (printer.GetEntry(&entry) == B_OK) { - // Delete the printer if function failed - entry.Remove(); - } - } else { - printer.WriteAttr(PSRV_PRINTER_ATTR_STATE, B_STRING_TYPE, 0, "free", ::strlen("free")+1); - } - } - - ::unload_add_on(id); - } - } - } + } else + printer.WriteAttr(PSRV_PRINTER_ATTR_STATE, B_STRING_TYPE, 0, "free", ::strlen("free")+1); } - return rc; + ::unload_add_on(id); + return B_OK; } // --------------------------------------------------------------- @@ -427,25 +439,27 @@ PrintServerApp::SelectPrinter(const char* printerName) status_t rc; BNode node; - // Find the node of the "old" default printer - if (fDefaultPrinter != NULL && - FindPrinterNode(fDefaultPrinter->Name(), node) == B_OK) { - // and remove the custom icon + // Find the node of the "old" default printer + if (fDefaultPrinter != NULL + && FindPrinterNode(fDefaultPrinter->Name(), node) == B_OK) { + // and remove the custom icon BNodeInfo info(&node); info.SetIcon(NULL, B_MINI_ICON); info.SetIcon(NULL, B_LARGE_ICON); } - // Find the node for the new default printer - if ((rc=FindPrinterNode(printerName, node)) == B_OK) { - // and add the custom icon + // Find the node for the new default printer + rc=FindPrinterNode(printerName, node); + if (rc == B_OK) { + // and add the custom icon BNodeInfo info(&node); info.SetIcon(fSelectedIconMini, B_MINI_ICON); info.SetIcon(fSelectedIconLarge, B_LARGE_ICON); } fDefaultPrinter = Printer::Find(printerName); - StoreDefaultPrinter(); // update our pref file + StoreDefaultPrinter(); + // update our pref file be_roster->Broadcast(new BMessage(B_PRINTER_CHANGED)); return rc; @@ -467,8 +481,6 @@ PrintServerApp::HandleSpooledJobs() } } -// static const char* kPrinterData = "printer_data"; - // --------------------------------------------------------------- // RetrieveDefaultPrinter() // @@ -525,18 +537,15 @@ PrintServerApp::StoreDefaultPrinter() // --------------------------------------------------------------- status_t PrintServerApp::FindPrinterNode(const char* name, BNode& node) -{ - status_t rc; - - // Find directory containing printer definitions +{ + // Find directory containing printer definitions BPath path; - if ((rc=::find_directory(B_USER_PRINTERS_DIRECTORY,&path,true,NULL)) == B_OK) - { - path.Append(name); - rc = node.SetTo(path.Path()); - } - - return rc; + status_t rc = ::find_directory(B_USER_PRINTERS_DIRECTORY, &path, true, NULL); + if (rc != B_OK) + return rc; + + path.Append(name); + return node.SetTo(path.Path()); } // --------------------------------------------------------------- @@ -557,10 +566,9 @@ PrintServerApp::FindPrinterNode(const char* name, BNode& node) status_t PrintServerApp::FindPrinterDriver(const char* name, BPath& outPath) { - // try to locate the driver - if (::TestForAddonExistence(name, B_USER_ADDONS_DIRECTORY, "Print", outPath) != B_OK) - if (::TestForAddonExistence(name, B_COMMON_ADDONS_DIRECTORY, "Print", outPath) != B_OK) - return ::TestForAddonExistence(name, B_BEOS_ADDONS_DIRECTORY, "Print", outPath); + if (::TestForAddonExistence(name, B_USER_ADDONS_DIRECTORY, "Print", outPath) != B_OK + && TestForAddonExistence(name, B_COMMON_ADDONS_DIRECTORY, "Print", outPath) != B_OK) + return ::TestForAddonExistence(name, B_BEOS_ADDONS_DIRECTORY, "Print", outPath); return B_OK; } @@ -569,9 +577,9 @@ PrintServerApp::FindPrinterDriver(const char* name, BPath& outPath) bool PrintServerApp::OpenSettings(BFile& file, const char* name, bool forReading) { BPath path; 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 && - path.Append(name) == B_OK && - file.SetTo(path.Path(), openMode) == B_OK; + return find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK + && path.Append(name) == B_OK + && file.SetTo(path.Path(), openMode) == B_OK; } static const char* kSettingsName = "print_server_settings"; diff --git a/src/servers/print/PrintServerApp.h b/src/servers/print/PrintServerApp.h index 7d594bfc2b..cc177d5231 100644 --- a/src/servers/print/PrintServerApp.h +++ b/src/servers/print/PrintServerApp.h @@ -1,96 +1,93 @@ /* - * Copyright 2001-2006, Haiku. All rights reserved. + * Copyright 2001-2007, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Ithamar R. Adema * Michael Pfeiffer */ -#ifndef PRINTSERVERAPP_H -#define PRINTSERVERAPP_H - -#include "ResourceManager.h" -#include "Settings.h" -#include "FolderWatcher.h" - -class PrintServerApp; +#ifndef _PRINT_SERVER_APP_H +#define _PRINT_SERVER_APP_H #include #include #include #include -// global BLocker for synchronisation -extern BLocker* gLock; +#include "FolderWatcher.h" +#include "ResourceManager.h" +#include "Settings.h" -/*****************************************************************************/ -// PrintServerApp -// -// Application class for print_server. -/*****************************************************************************/ class Printer; -class PrintServerApp : public BApplication, public FolderListener -{ - typedef BApplication Inherited; -public: - PrintServerApp(status_t* err); - ~PrintServerApp(); + +// The global BLocker for synchronisation. +extern BLocker *gLock; + +// The print_server application. +class PrintServerApp : public BApplication, public FolderListener { + private: + typedef BApplication Inherited; + + public: + PrintServerApp(status_t *err); + ~PrintServerApp(); + + void Acquire(); + void Release(); + + bool QuitRequested(); + void MessageReceived(BMessage *msg); + void NotifyPrinterDeletion(Printer *printer); - void Acquire(); - void Release(); - - bool QuitRequested(); - void MessageReceived(BMessage* msg); - void NotifyPrinterDeletion(Printer* printer); - // Scripting support, see PrintServerApp.Scripting.cpp - status_t GetSupportedSuites(BMessage* msg); - void HandleScriptingCommand(BMessage* msg); - Printer* GetPrinterFromSpecifier(BMessage* msg); - BHandler* ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec, - int32 form, const char* prop); -private: - bool OpenSettings(BFile& file, const char* name, bool forReading); - void LoadSettings(); - void SaveSettings(); - - status_t SetupPrinterList(); - - void HandleSpooledJobs(); + status_t GetSupportedSuites(BMessage *msg); + void HandleScriptingCommand(BMessage *msg); + Printer *GetPrinterFromSpecifier(BMessage *msg); + BHandler *ResolveSpecifier(BMessage *msg, int32 index, BMessage *spec, + int32 form, const char *prop); + private: + bool OpenSettings(BFile &file, const char *name, bool forReading); + void LoadSettings(); + void SaveSettings(); - status_t SelectPrinter(const char* printerName); - status_t CreatePrinter( const char* printerName, const char* driverName, - const char* connection, const char* transportName, - const char* transportPath); - - void RegisterPrinter(BDirectory* node); - void UnregisterPrinter(Printer* printer); - // FolderListener - void EntryCreated(node_ref* node, entry_ref* entry); - void EntryRemoved(node_ref* node); - void AttributeChanged(node_ref* node); + status_t SetupPrinterList(); + + void HandleSpooledJobs(); - status_t StoreDefaultPrinter(); - status_t RetrieveDefaultPrinter(); - - status_t FindPrinterNode(const char* name, BNode& node); - status_t FindPrinterDriver(const char* name, BPath& outPath); - - ResourceManager fResourceManager; - Printer* fDefaultPrinter; - BBitmap* fSelectedIconMini; - BBitmap* fSelectedIconLarge; - vint32 fReferences; - sem_id fHasReferences; - Settings*fSettings; - bool fUseConfigWindow; - FolderWatcher* fFolder; + status_t SelectPrinter(const char *printerName); + status_t CreatePrinter(const char *printerName, const char *driverName, + const char *connection, const char *transportName, + const char *transportPath); + void RegisterPrinter(BDirectory *node); + void UnregisterPrinter(Printer *printer); + + // FolderListener + void EntryCreated(node_ref *node, entry_ref *entry); + void EntryRemoved(node_ref *node); + void AttributeChanged(node_ref *node); + + status_t StoreDefaultPrinter(); + status_t RetrieveDefaultPrinter(); + + status_t FindPrinterNode(const char *name, BNode &node); + status_t FindPrinterDriver(const char *name, BPath &outPath); + // "Classic" BeOS R5 support, see PrintServerApp.R5.cpp - static status_t async_thread(void* data); - void AsyncHandleMessage(BMessage* msg); - void Handle_BeOSR5_Message(BMessage* msg); + static status_t async_thread(void *data); + void AsyncHandleMessage(BMessage *msg); + void Handle_BeOSR5_Message(BMessage *msg); + ResourceManager fResourceManager; + Printer *fDefaultPrinter; + BBitmap *fSelectedIconMini; + BBitmap *fSelectedIconLarge; + vint32 fReferences; + sem_id fHasReferences; + Settings *fSettings; + bool fUseConfigWindow; + FolderWatcher *fFolder; + }; #endif