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
This commit is contained in:
Michael Pfeiffer
2007-02-01 20:39:20 +00:00
parent f6c0820638
commit 24a0bfcb01
5 changed files with 495 additions and 479 deletions
+150 -107
View File
@@ -44,41 +44,43 @@
// Implementation of PrinterListView // Implementation of PrinterListView
PrinterListView::PrinterListView(BRect frame) PrinterListView::PrinterListView(BRect frame)
: Inherited(frame, "printers_list", B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL) : Inherited(frame, "printers_list", B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL),
, fFolder(NULL) fFolder(NULL)
{ {
} }
void PrinterListView::BuildPrinterList() {
// clear list void
PrinterListView::BuildPrinterList()
{
// clear list
const BListItem** items = Items(); const BListItem** items = Items();
for (int32 i = CountItems()-1; i >= 0; i --) { for (int32 i = CountItems()-1; i >= 0; i --)
delete items[i]; delete items[i];
}
MakeEmpty(); MakeEmpty();
// TODO: Fixup situation in which PrintServer is not running // Find directory containing printer definition nodes
BEntry entry;
status_t rc;
BPath path; BPath path;
status_t rc = ::find_directory(B_USER_PRINTERS_DIRECTORY, &path);
if (rc != B_OK)
return;
// Find directory containing printer definition nodes BDirectory dir(path.Path());
if ((rc=::find_directory(B_USER_PRINTERS_DIRECTORY, &path)) == B_OK) { rc = dir.InitCheck();
BDirectory dir(path.Path()); if (rc != B_OK)
return;
// Can we reach the directory? fNode = dir;
if ((rc = dir.InitCheck()) == B_OK) { BEntry entry;
fNode = dir; while(dir.GetNextEntry(&entry) == B_OK) {
// Yes, so loop over it's entries BDirectory printer(&entry);
while((rc = dir.GetNextEntry(&entry)) == B_OK) { AddPrinter(printer);
BDirectory printer(&entry);
AddPrinter(printer);
}
}
} }
} }
void PrinterListView::AttachedToWindow()
void
PrinterListView::AttachedToWindow()
{ {
Inherited::AttachedToWindow(); Inherited::AttachedToWindow();
@@ -86,18 +88,25 @@ void PrinterListView::AttachedToWindow()
SetInvocationMessage(new BMessage(MSG_MKDEF_PRINTER)); SetInvocationMessage(new BMessage(MSG_MKDEF_PRINTER));
SetTarget(Window()); 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(); BuildPrinterList();
// Select active printer // Select active printer
for (int32 i = 0; i < CountItems(); i ++) { for (int32 i = 0; i < CountItems(); i ++) {
PrinterItem* item = dynamic_cast<PrinterItem*>(ItemAt(i)); PrinterItem* item = dynamic_cast<PrinterItem*>(ItemAt(i));
if (item->IsActivePrinter()) { if (item != NULL && item->IsActivePrinter()) {
Select(i); break; Select(i); break;
} }
} }
BPath path; if (hasPrintersDirectory) {
if (find_directory(B_USER_PRINTERS_DIRECTORY, &path) == B_OK) {
BDirectory dir(path.Path()); BDirectory dir(path.Path());
if (dir.InitCheck() == B_OK) { if (dir.InitCheck() == B_OK) {
fFolder = new FolderWatcher(this->Window(), dir, true); fFolder = new FolderWatcher(this->Window(), dir, true);
@@ -106,12 +115,18 @@ void PrinterListView::AttachedToWindow()
} }
} }
bool PrinterListView::QuitRequested() {
bool
PrinterListView::QuitRequested()
{
delete fFolder; fFolder = NULL; delete fFolder; fFolder = NULL;
return true; return true;
} }
void PrinterListView::AddPrinter(BDirectory& printer) {
void
PrinterListView::AddPrinter(BDirectory& printer)
{
BString state; BString state;
node_ref node; node_ref node;
// If the entry is a directory // 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 --) { for (int32 i = CountItems()-1; i >= 0; i --) {
PrinterItem* item = dynamic_cast<PrinterItem*>(ItemAt(i)); PrinterItem* item = dynamic_cast<PrinterItem*>(ItemAt(i));
node_ref ref; node_ref ref;
@@ -143,12 +160,17 @@ PrinterItem* PrinterListView::FindItem(node_ref* node) {
return NULL; return NULL;
} }
void PrinterListView::EntryCreated(node_ref* node, entry_ref* entry) {
void
PrinterListView::EntryCreated(node_ref* node, entry_ref* entry)
{
BDirectory printer(node); BDirectory printer(node);
AddPrinter(printer); AddPrinter(printer);
} }
void PrinterListView::EntryRemoved(node_ref* node) {
void PrinterListView::EntryRemoved(node_ref* node)
{
PrinterItem* item = FindItem(node); PrinterItem* item = FindItem(node);
if (item) { if (item) {
RemoveItem(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); BDirectory printer(node);
AddPrinter(printer); AddPrinter(printer);
} }
void PrinterListView::UpdateItem(PrinterItem* item) { void
PrinterListView::UpdateItem(PrinterItem* item)
{
item->UpdatePendingJobs(); item->UpdatePendingJobs();
InvalidateItem(IndexOf(item)); InvalidateItem(IndexOf(item));
} }
PrinterItem* PrinterListView::SelectedItem() { PrinterItem* PrinterListView::SelectedItem()
{
BListItem* item = ItemAt(CurrentSelection()); BListItem* item = ItemAt(CurrentSelection());
return dynamic_cast<PrinterItem*>(item); return dynamic_cast<PrinterItem*>(item);
} }
BBitmap* PrinterItem::sIcon = NULL; BBitmap* PrinterItem::sIcon = NULL;
BBitmap* PrinterItem::sSelectedIcon = NULL; BBitmap* PrinterItem::sSelectedIcon = NULL;
PrinterItem::PrinterItem(PrintersWindow* window, const BDirectory& node) PrinterItem::PrinterItem(PrintersWindow* window, const BDirectory& node)
: BListItem(0, false) : BListItem(0, false),
, fFolder(NULL) fFolder(NULL),
, fNode(node) fNode(node)
{ {
if (sIcon == NULL) if (sIcon == NULL) {
{
sIcon = new BBitmap(BRect(0,0,B_LARGE_ICON-1,B_LARGE_ICON-1), B_CMAP8); sIcon = new BBitmap(BRect(0,0,B_LARGE_ICON-1,B_LARGE_ICON-1), B_CMAP8);
BMimeType type(PSRV_PRINTER_FILETYPE); BMimeType type(PSRV_PRINTER_FILETYPE);
type.GetIcon(sIcon, B_LARGE_ICON); 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); sSelectedIcon = 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(sSelectedIcon, B_LARGE_ICON); 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_PRT_NAME, fName);
GetStringProperty(PSRV_PRINTER_ATTR_COMMENTS, fComments); GetStringProperty(PSRV_PRINTER_ATTR_COMMENTS, fComments);
GetStringProperty(PSRV_PRINTER_ATTR_TRANSPORT, fTransport); GetStringProperty(PSRV_PRINTER_ATTR_TRANSPORT, fTransport);
GetStringProperty(PSRV_PRINTER_ATTR_DRV_NAME, fDriverName); GetStringProperty(PSRV_PRINTER_ATTR_DRV_NAME, fDriverName);
BPath path; BPath path;
// Setup spool folder // Setup spool folder
if (find_directory(B_USER_PRINTERS_DIRECTORY, &path) == B_OK) { if (find_directory(B_USER_PRINTERS_DIRECTORY, &path) == B_OK) {
path.Append(fName.String()); path.Append(fName.String());
BDirectory dir(path.Path()); BDirectory dir(path.Path());
@@ -210,16 +237,22 @@ PrinterItem::PrinterItem(PrintersWindow* window, const BDirectory& node)
UpdatePendingJobs(); UpdatePendingJobs();
} }
PrinterItem::~PrinterItem() {
PrinterItem::~PrinterItem()
{
delete fFolder; fFolder = NULL; delete fFolder; fFolder = NULL;
} }
void PrinterItem::GetStringProperty(const char* propName, BString& outString)
void
PrinterItem::GetStringProperty(const char* propName, BString& outString)
{ {
fNode.ReadAttrString(propName, &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); 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 ); SetHeight( (height.ascent+height.descent+height.leading) * 3.0 +4 );
} }
bool PrinterItem::Remove(BListView* view) bool PrinterItem::Remove(BListView* view)
{ {
BMessenger msgr; BMessenger msgr;
@@ -247,104 +281,113 @@ bool PrinterItem::Remove(BListView* view)
return false; return false;
} }
void PrinterItem::DrawItem(BView *owner, BRect /*bounds*/, bool complete) void PrinterItem::DrawItem(BView *owner, BRect /*bounds*/, bool complete)
{ {
BListView* list = dynamic_cast<BListView*>(owner); BListView* list = dynamic_cast<BListView*>(owner);
if (list) if (list == NULL)
{ return;
font_height height;
BFont font;
owner->GetFont(&font);
font.GetHeight(&height);
float fntheight = height.ascent+height.descent+height.leading;
BRect bounds = list->ItemFrame(list->IndexOf(this)); font_height height;
BFont font;
owner->GetFont(&font);
font.GetHeight(&height);
float fntheight = height.ascent+height.descent+height.leading;
rgb_color color = owner->ViewColor(); BRect bounds = list->ItemFrame(list->IndexOf(this));
if ( IsSelected() )
color = tint_color(color, B_HIGHLIGHT_BACKGROUND_TINT);
rgb_color oldviewcolor = owner->ViewColor(); rgb_color color = owner->ViewColor();
rgb_color oldlowcolor = owner->LowColor(); if ( IsSelected() )
rgb_color oldcolor = owner->HighColor(); color = tint_color(color, B_HIGHLIGHT_BACKGROUND_TINT);
owner->SetViewColor( color );
owner->SetHighColor( color );
owner->SetLowColor( color );
owner->FillRect(bounds);
owner->SetLowColor( oldlowcolor );
owner->SetHighColor( oldcolor );
BPoint iconPt = bounds.LeftTop() + BPoint(2,2); rgb_color oldviewcolor = owner->ViewColor();
BPoint namePt = iconPt + BPoint(B_LARGE_ICON+8, fntheight); rgb_color oldlowcolor = owner->LowColor();
BPoint driverPt = iconPt + BPoint(B_LARGE_ICON+8, fntheight*2); rgb_color oldcolor = owner->HighColor();
BPoint commentPt = iconPt + BPoint(B_LARGE_ICON+8, fntheight*3); owner->SetViewColor( color );
owner->SetHighColor( color );
owner->SetLowColor( color );
owner->FillRect(bounds);
owner->SetLowColor( oldlowcolor );
owner->SetHighColor( oldcolor );
float width = owner->StringWidth("No pending jobs."); BPoint iconPt = bounds.LeftTop() + BPoint(2,2);
BPoint pendingPt(bounds.right - width -8, namePt.y); BPoint namePt = iconPt + BPoint(B_LARGE_ICON+8, fntheight);
BPoint transportPt(bounds.right - width -8, driverPt.y); BPoint driverPt = iconPt + BPoint(B_LARGE_ICON+8, fntheight*2);
BPoint commentPt = iconPt + BPoint(B_LARGE_ICON+8, fntheight*3);
drawing_mode mode = owner->DrawingMode(); float width = owner->StringWidth("No pending jobs.");
owner->SetDrawingMode(B_OP_OVER); BPoint pendingPt(bounds.right - width -8, namePt.y);
owner->DrawBitmap(IsActivePrinter() ? sSelectedIcon : sIcon, iconPt); BPoint transportPt(bounds.right - width -8, driverPt.y);
// left of item drawing_mode mode = owner->DrawingMode();
owner->DrawString(fName.String(), fName.Length(), namePt); owner->SetDrawingMode(B_OP_OVER);
owner->DrawString(fDriverName.String(), fDriverName.Length(), driverPt); owner->DrawBitmap(IsActivePrinter() ? sSelectedIcon : sIcon, iconPt);
owner->DrawString(fComments.String(), fComments.Length(), commentPt);
// right of item // left of item
owner->DrawString(fPendingJobs.String(), 16, pendingPt); owner->DrawString(fName.String(), fName.Length(), namePt);
owner->DrawString(fTransport.String(), fTransport.Length(), transportPt); owner->DrawString(fDriverName.String(), fDriverName.Length(), driverPt);
owner->DrawString(fComments.String(), fComments.Length(), commentPt);
owner->SetDrawingMode(mode); // right of item
owner->DrawString(fPendingJobs.String(), 16, pendingPt);
owner->DrawString(fTransport.String(), fTransport.Length(), transportPt);
owner->SetViewColor(oldviewcolor); owner->SetDrawingMode(mode);
}
owner->SetViewColor(oldviewcolor);
} }
bool PrinterItem::IsActivePrinter()
bool
PrinterItem::IsActivePrinter()
{ {
bool rc = false;
BMessenger msgr; BMessenger msgr;
if (::GetPrinterServerMessenger(msgr) != B_OK)
return false;
if (::GetPrinterServerMessenger(msgr) == B_OK) BMessage getNameOfActivePrinter(B_GET_PROPERTY);
{ getNameOfActivePrinter.AddSpecifier("ActivePrinter");
BMessage reply, getNameOfActivePrinter(B_GET_PROPERTY);
getNameOfActivePrinter.AddSpecifier("ActivePrinter");
BString activePrinterName; BString activePrinterName;
if (msgr.SendMessage(&getNameOfActivePrinter, &reply) == B_OK && BMessage reply;
reply.FindString("result", &activePrinterName) == B_OK) { return msgr.SendMessage(&getNameOfActivePrinter, &reply) == B_OK
// Compare name of active printer with name of 'this' printer item && reply.FindString("result", &activePrinterName) == B_OK
rc = (fName == activePrinterName); && fName == activePrinterName;
}
}
return rc;
} }
bool PrinterItem::HasPendingJobs() {
bool
PrinterItem::HasPendingJobs()
{
return fFolder && fFolder->CountJobs() > 0; return fFolder && fFolder->CountJobs() > 0;
} }
SpoolFolder* PrinterItem::Folder() {
SpoolFolder* PrinterItem::Folder()
{
return fFolder; return fFolder;
} }
BDirectory* PrinterItem::Node() {
BDirectory*
PrinterItem::Node()
{
return &fNode; return &fNode;
} }
void PrinterItem::UpdatePendingJobs() {
void
PrinterItem::UpdatePendingJobs()
{
if (fFolder) { if (fFolder) {
uint32 pendingJobs = fFolder->CountJobs(); uint32 pendingJobs = fFolder->CountJobs();
fPendingJobs = "";
if (pendingJobs == 1) { if (pendingJobs == 1) {
fPendingJobs = "1 pending job."; fPendingJobs = "1 pending job.";
return;
} else if (pendingJobs > 1) { } else if (pendingJobs > 1) {
fPendingJobs << pendingJobs << " pending jobs.h"; fPendingJobs << pendingJobs << " pending jobs.h";
return;
} }
if (pendingJobs >= 1) return;
} }
fPendingJobs = "No pending jobs."; fPendingJobs = "No pending jobs.";
} }
+45 -43
View File
@@ -43,65 +43,67 @@ class SpoolFolder;
class PrinterItem; class PrinterItem;
class PrinterListView; class PrinterListView;
class PrinterListView : public BListView, public FolderListener class PrinterListView : public BListView, public FolderListener {
{ private:
typedef BListView Inherited; typedef BListView Inherited;
BDirectory fNode; void AddPrinter(BDirectory &printer);
FolderWatcher* fFolder; PrinterItem *FindItem(node_ref *node);
void AddPrinter(BDirectory& printer); void EntryCreated(node_ref *node, entry_ref *entry);
PrinterItem* FindItem(node_ref* node); void EntryRemoved(node_ref *node);
void AttributeChanged(node_ref *node);
void EntryCreated(node_ref* node, entry_ref* entry); public:
void EntryRemoved(node_ref* node); PrinterListView(BRect frame);
void AttributeChanged(node_ref* node); void AttachedToWindow();
bool QuitRequested();
public: void BuildPrinterList();
PrinterListView(BRect frame); PrinterItem *SelectedItem();
void AttachedToWindow();
bool QuitRequested();
void BuildPrinterList(); void UpdateItem(PrinterItem *item);
PrinterItem* SelectedItem();
void UpdateItem(PrinterItem* item); private:
BDirectory fNode;
FolderWatcher *fFolder;
}; };
class BBitmap; class BBitmap;
class PrintersWindow; class PrintersWindow;
class PrinterItem : public BListItem class PrinterItem : public BListItem {
{ public:
public: PrinterItem(PrintersWindow *window, const BDirectory &node);
PrinterItem(PrintersWindow* window, const BDirectory& node/*const BMessenger& thePrinter*/); ~PrinterItem();
~PrinterItem();
void DrawItem(BView *owner, BRect bounds, bool complete); void DrawItem(BView *owner, BRect bounds, bool complete);
void Update(BView *owner, const BFont *font); void Update(BView *owner, const BFont *font);
bool Remove(BListView* view); bool Remove(BListView *view);
bool IsActivePrinter(); bool IsActivePrinter();
bool HasPendingJobs(); bool HasPendingJobs();
const char* Name() const const char *Name() const {
{ return fName.String(); } return fName.String();
}
SpoolFolder* Folder(); SpoolFolder *Folder();
BDirectory* Node(); BDirectory *Node();
void UpdatePendingJobs(); void UpdatePendingJobs();
private: private:
void GetStringProperty(const char* propName, BString& outString); void GetStringProperty(const char *propName, BString &outString);
SpoolFolder *fFolder; SpoolFolder *fFolder;
BDirectory fNode; BDirectory fNode;
BString fComments; BString fComments;
BString fTransport; BString fTransport;
BString fDriverName; BString fDriverName;
BString fName; BString fName;
BString fPendingJobs; BString fPendingJobs;
static BBitmap* sIcon;
static BBitmap* sSelectedIcon; static BBitmap *sIcon;
static BBitmap *sSelectedIcon;
}; };
#endif #endif
-34
View File
@@ -185,40 +185,6 @@ void PrintServerApp::Handle_BeOSR5_Message(BMessage* msg)
} }
break; 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_PAGE_SETUP:
case PSRV_SHOW_PRINT_SETUP: case PSRV_SHOW_PRINT_SETUP:
case PSRV_GET_DEFAULT_SETTINGS: case PSRV_GET_DEFAULT_SETTINGS:
+194 -186
View File
@@ -12,7 +12,7 @@
#include "Printer.h" #include "Printer.h"
#include "pr_server.h" #include "pr_server.h"
// BeOS API // BeOS API
#include <Alert.h> #include <Alert.h>
#include <Autolock.h> #include <Autolock.h>
#include <Directory.h> #include <Directory.h>
@@ -27,9 +27,11 @@
#include <PrintJob.h> #include <PrintJob.h>
#include <String.h> #include <String.h>
// ANSI C // ANSI C
#include <stdio.h> //for printf #include <stdio.h>
#include <unistd.h> //for unlink // for printf
#include <unistd.h>
// for unlink
BLocker *gLock = NULL; 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 * @returns B_OK if application was started, or an errorcode if
* application failed to start. * application failed to start.
*
* @see your favorite C/C++ textbook :P
*/ */
int int
main() main()
{ {
status_t rc = B_OK; status_t rc = B_OK;
gLock = new BLocker(); gLock = new BLocker();
// Create our application object
PrintServerApp print_server(&rc); PrintServerApp print_server(&rc);
// If all went fine, let's start it
if (rc == B_OK) { if (rc == B_OK) {
print_server.Run(); print_server.Run();
} }
@@ -76,7 +73,6 @@ main()
* *
* @see BApplication * @see BApplication
*/ */
PrintServerApp::PrintServerApp(status_t* err) PrintServerApp::PrintServerApp(status_t* err)
: Inherited(PSRV_SIGNATURE_TYPE, err), : Inherited(PSRV_SIGNATURE_TYPE, err),
fSelectedIconMini(NULL), fSelectedIconMini(NULL),
@@ -88,120 +84,128 @@ PrintServerApp::PrintServerApp(status_t* err)
{ {
fSettings = Settings::GetSettings(); fSettings = Settings::GetSettings();
LoadSettings(); LoadSettings();
// If our superclass initialized ok
if (*err == B_OK) {
fHasReferences = create_sem(1, "has_references");
// let us try as well if (*err != B_OK)
SetupPrinterList(); return;
RetrieveDefaultPrinter();
fSelectedIconMini = new BBitmap(BRect(0,0,B_MINI_ICON-1,B_MINI_ICON-1), B_CMAP8); fHasReferences = create_sem(1, "has_references");
fSelectedIconLarge = new BBitmap(BRect(0,0,B_LARGE_ICON-1,B_LARGE_ICON-1), B_CMAP8);
// Cache icons for selected printer SetupPrinterList();
BMimeType type(PRNT_SIGNATURE_TYPE); RetrieveDefaultPrinter();
type.GetIcon(fSelectedIconMini, B_MINI_ICON);
type.GetIcon(fSelectedIconLarge, B_LARGE_ICON);
// Start handling of spooled files // Cache icons for selected printer
PostMessage(PSRV_PRINT_SPOOLED_JOB); 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(); SaveSettings();
delete fSettings; delete fSettings;
} }
bool PrintServerApp::QuitRequested()
bool
PrintServerApp::QuitRequested()
{ {
// don't quit when user types Command+Q!
BMessage* m = CurrentMessage(); BMessage* m = CurrentMessage();
bool shortcut; bool shortcut;
// don't quit when user types Command+Q! if (m != NULL && m->FindBool("shortcut", &shortcut) == B_OK && shortcut)
if (m && m->FindBool("shortcut", &shortcut) == B_OK && shortcut) return false; return false;
bool rc = Inherited::QuitRequested(); if (!Inherited::QuitRequested())
if (rc) { return false;
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
// Release all printers // Stop watching the folder
Printer* printer; delete fFolder; fFolder = NULL;
while ((printer = Printer::At(0)) != NULL) {
printer->AbortPrintThread();
UnregisterPrinter(printer);
}
// Wait for printers // Release all printers
if (fHasReferences > 0) { Printer* printer;
acquire_sem(fHasReferences); while ((printer = Printer::At(0)) != NULL) {
delete_sem(fHasReferences); printer->AbortPrintThread();
fHasReferences = 0; UnregisterPrinter(printer);
}
ASSERT(fSelectedIconMini != NULL);
delete fSelectedIconMini; fSelectedIconMini = NULL;
delete fSelectedIconLarge; fSelectedIconLarge = NULL;
} }
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; 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;
Printer* p; if (printer->GetNodeRef(&node) != B_OK)
if (printer->GetNodeRef(&node) != B_OK) return; return;
p = Printer::Find(&node);
if (p != NULL) return; if (Printer::Find(&node) != NULL)
// register new printer return;
// register new printer
Resource* r = fResourceManager.Allocate(transport.String(), address.String(), connection.String()); Resource* r = fResourceManager.Allocate(transport.String(), address.String(), connection.String());
p = new Printer(printer, r); AddHandler(new Printer(printer, r));
AddHandler(p);
Acquire(); Acquire();
} }
} }
} }
void PrintServerApp::UnregisterPrinter(Printer* printer) {
void
PrintServerApp::UnregisterPrinter(Printer* printer)
{
RemoveHandler(printer); RemoveHandler(printer);
Printer::Remove(printer); Printer::Remove(printer);
printer->Release(); printer->Release();
} }
void PrintServerApp::NotifyPrinterDeletion(Printer* printer) {
void
PrintServerApp::NotifyPrinterDeletion(Printer* printer)
{
BAutolock lock(gLock); BAutolock lock(gLock);
if (lock.IsLocked()) { if (lock.IsLocked()) {
fResourceManager.Free(printer->GetResource()); 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); BEntry printer(entry);
if (printer.InitCheck() == B_OK && printer.IsDirectory()) { if (printer.InitCheck() == B_OK && printer.IsDirectory()) {
BDirectory dir(&printer); 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); Printer* printer = Printer::Find(node);
if (printer) { if (printer) {
if (printer == fDefaultPrinter) fDefaultPrinter = NULL; 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); BDirectory printer(node);
if (printer.InitCheck() == B_OK) { if (printer.InitCheck() == B_OK) {
RegisterPrinter(&printer); RegisterPrinter(&printer);
} }
} }
// --------------------------------------------------------------- // ---------------------------------------------------------------
// SetupPrinterList // SetupPrinterList
// //
@@ -246,51 +259,45 @@ void PrintServerApp::AttributeChanged(node_ref* node) {
// Returns: // Returns:
// B_OK if successful, or an errorcode if failed. // B_OK if successful, or an errorcode if failed.
// --------------------------------------------------------------- // ---------------------------------------------------------------
status_t PrintServerApp::SetupPrinterList() status_t
PrintServerApp::SetupPrinterList()
{ {
BEntry entry;
status_t rc; status_t rc;
// Find directory containing printer definition nodes
BPath path; BPath path;
rc = ::find_directory(B_USER_PRINTERS_DIRECTORY, &path);
if (rc != B_OK)
return rc;
// Find directory containing printer definition nodes // Directory has to exist in order to watch it
if ((rc=::find_directory(B_USER_PRINTERS_DIRECTORY, &path)) == B_OK) { mode_t mode = 0777;
BDirectory dir(path.Path()); create_directory(path.Path(), mode);
// Can we reach the directory? BDirectory dir(path.Path());
if ((rc=dir.InitCheck()) == B_OK) { rc = dir.InitCheck();
// Yes, so loop over it's entries if (rc != B_OK)
while((rc=dir.GetNextEntry(&entry)) == B_OK) { return rc;
// 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 && // Register printer definition nodes
strcmp(buffer, PSRV_PRINTER_FILETYPE) == 0) { BEntry entry;
// Yes, it is a printer definition node while(dir.GetNextEntry(&entry) == B_OK) {
RegisterPrinter(&node); if (!entry.IsDirectory())
} continue;
}
}
BDirectory node(&entry);
fFolder = new FolderWatcher(this, dir, true); BNodeInfo info(&node);
fFolder->SetListener(this); char buffer[256];
#if 0 if (info.GetType(buffer) == B_OK && strcmp(buffer, PSRV_PRINTER_FILETYPE) == 0) {
// If we scanned all entries successfully RegisterPrinter(&node);
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
} }
} }
return rc; // Now we are ready to start node watching
fFolder = new FolderWatcher(this, dir, true);
fFolder->SetListener(this);
return B_OK;
} }
// --------------------------------------------------------------- // ---------------------------------------------------------------
@@ -358,52 +365,57 @@ PrintServerApp::CreatePrinter(const char* printerName, const char* driverName,
{ {
status_t rc; status_t rc;
// Find directory containing printer definitions // Find directory containing printer definitions
BPath path; 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 // Create our printer definition/spool directory
BDirectory printersDir(path.Path()); BDirectory printersDir(path.Path());
BDirectory printer; BDirectory printer;
if ((rc=printersDir.CreateDirectory(printerName,&printer)) == B_OK) {
// Set its type to a printer
BNodeInfo info(&printer);
info.SetType(PSRV_PRINTER_FILETYPE);
// Store the settings in its attributes rc = printersDir.CreateDirectory(printerName, &printer);
printer.WriteAttr(PSRV_PRINTER_ATTR_PRT_NAME, B_STRING_TYPE, 0, printerName, ::strlen(printerName)+1); if (rc != B_OK)
printer.WriteAttr(PSRV_PRINTER_ATTR_DRV_NAME, B_STRING_TYPE, 0, driverName, ::strlen(driverName)+1); return rc;
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 // Set its type to a printer
if (FindPrinterDriver(driverName, path) == B_OK) { BNodeInfo info(&printer);
// Try and load the addon info.SetType(PSRV_PRINTER_FILETYPE);
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); // 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();
} 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; 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);
info.SetIcon(NULL, B_MINI_ICON); info.SetIcon(NULL, B_MINI_ICON);
info.SetIcon(NULL, B_LARGE_ICON); info.SetIcon(NULL, B_LARGE_ICON);
} }
// Find the node for the new default printer // Find the node for the new default printer
if ((rc=FindPrinterNode(printerName, node)) == B_OK) { rc=FindPrinterNode(printerName, node);
// and add the custom icon if (rc == B_OK) {
// and add the custom icon
BNodeInfo info(&node); BNodeInfo info(&node);
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(); // update our pref file StoreDefaultPrinter();
// update our pref file
be_roster->Broadcast(new BMessage(B_PRINTER_CHANGED)); be_roster->Broadcast(new BMessage(B_PRINTER_CHANGED));
return rc; return rc;
@@ -467,8 +481,6 @@ PrintServerApp::HandleSpooledJobs()
} }
} }
// static const char* kPrinterData = "printer_data";
// --------------------------------------------------------------- // ---------------------------------------------------------------
// RetrieveDefaultPrinter() // RetrieveDefaultPrinter()
// //
@@ -526,17 +538,14 @@ PrintServerApp::StoreDefaultPrinter()
status_t status_t
PrintServerApp::FindPrinterNode(const char* name, BNode& node) PrintServerApp::FindPrinterNode(const char* name, BNode& node)
{ {
status_t rc; // Find directory containing printer definitions
// Find directory containing printer definitions
BPath path; BPath path;
if ((rc=::find_directory(B_USER_PRINTERS_DIRECTORY,&path,true,NULL)) == B_OK) status_t rc = ::find_directory(B_USER_PRINTERS_DIRECTORY, &path, true, NULL);
{ if (rc != B_OK)
path.Append(name); return rc;
rc = node.SetTo(path.Path());
}
return rc; path.Append(name);
return node.SetTo(path.Path());
} }
// --------------------------------------------------------------- // ---------------------------------------------------------------
@@ -557,10 +566,9 @@ PrintServerApp::FindPrinterNode(const char* name, BNode& node)
status_t status_t
PrintServerApp::FindPrinterDriver(const char* name, BPath& outPath) 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_USER_ADDONS_DIRECTORY, "Print", outPath) != B_OK) && TestForAddonExistence(name, B_COMMON_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);
return ::TestForAddonExistence(name, B_BEOS_ADDONS_DIRECTORY, "Print", outPath);
return B_OK; return B_OK;
} }
@@ -569,9 +577,9 @@ 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;
} }
static const char* kSettingsName = "print_server_settings"; static const char* kSettingsName = "print_server_settings";
+61 -64
View File
@@ -1,95 +1,92 @@
/* /*
* Copyright 2001-2006, Haiku. All rights reserved. * Copyright 2001-2007, Haiku. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Ithamar R. Adema * Ithamar R. Adema
* Michael Pfeiffer * Michael Pfeiffer
*/ */
#ifndef PRINTSERVERAPP_H #ifndef _PRINT_SERVER_APP_H
#define PRINTSERVERAPP_H #define _PRINT_SERVER_APP_H
#include "ResourceManager.h"
#include "Settings.h"
#include "FolderWatcher.h"
class PrintServerApp;
#include <Application.h> #include <Application.h>
#include <Bitmap.h> #include <Bitmap.h>
#include <OS.h> #include <OS.h>
#include <String.h> #include <String.h>
// global BLocker for synchronisation #include "FolderWatcher.h"
extern BLocker* gLock; #include "ResourceManager.h"
#include "Settings.h"
/*****************************************************************************/
// PrintServerApp
//
// Application class for print_server.
/*****************************************************************************/
class Printer; class Printer;
class PrintServerApp : public BApplication, public FolderListener
{
typedef BApplication Inherited;
public:
PrintServerApp(status_t* err);
~PrintServerApp();
void Acquire(); // The global BLocker for synchronisation.
void Release(); extern BLocker *gLock;
bool QuitRequested(); // The print_server application.
void MessageReceived(BMessage* msg); class PrintServerApp : public BApplication, public FolderListener {
void NotifyPrinterDeletion(Printer* printer); private:
typedef BApplication Inherited;
public:
PrintServerApp(status_t *err);
~PrintServerApp();
void Acquire();
void Release();
bool QuitRequested();
void MessageReceived(BMessage *msg);
void NotifyPrinterDeletion(Printer *printer);
// Scripting support, see PrintServerApp.Scripting.cpp // Scripting support, see PrintServerApp.Scripting.cpp
status_t GetSupportedSuites(BMessage* msg); status_t GetSupportedSuites(BMessage *msg);
void HandleScriptingCommand(BMessage* msg); void HandleScriptingCommand(BMessage *msg);
Printer* GetPrinterFromSpecifier(BMessage* msg); Printer *GetPrinterFromSpecifier(BMessage *msg);
BHandler* ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec, BHandler *ResolveSpecifier(BMessage *msg, int32 index, BMessage *spec,
int32 form, const char* prop); int32 form, const char *prop);
private: private:
bool OpenSettings(BFile& file, const char* name, bool forReading); bool OpenSettings(BFile &file, const char *name, bool forReading);
void LoadSettings(); void LoadSettings();
void SaveSettings(); void SaveSettings();
status_t SetupPrinterList(); status_t SetupPrinterList();
void HandleSpooledJobs(); void HandleSpooledJobs();
status_t SelectPrinter(const char* printerName); status_t SelectPrinter(const char *printerName);
status_t CreatePrinter( const char* printerName, const char* driverName, status_t CreatePrinter(const char *printerName, const char *driverName,
const char* connection, const char* transportName, const char *connection, const char *transportName,
const char* transportPath); const char *transportPath);
void RegisterPrinter(BDirectory* node); void RegisterPrinter(BDirectory *node);
void UnregisterPrinter(Printer* printer); 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(); // FolderListener
status_t RetrieveDefaultPrinter(); void EntryCreated(node_ref *node, entry_ref *entry);
void EntryRemoved(node_ref *node);
void AttributeChanged(node_ref *node);
status_t FindPrinterNode(const char* name, BNode& node); status_t StoreDefaultPrinter();
status_t FindPrinterDriver(const char* name, BPath& outPath); status_t RetrieveDefaultPrinter();
ResourceManager fResourceManager; status_t FindPrinterNode(const char *name, BNode &node);
Printer* fDefaultPrinter; status_t FindPrinterDriver(const char *name, BPath &outPath);
BBitmap* fSelectedIconMini;
BBitmap* fSelectedIconLarge;
vint32 fReferences;
sem_id fHasReferences;
Settings*fSettings;
bool fUseConfigWindow;
FolderWatcher* fFolder;
// "Classic" BeOS R5 support, see PrintServerApp.R5.cpp // "Classic" BeOS R5 support, see PrintServerApp.R5.cpp
static status_t async_thread(void* data); static status_t async_thread(void *data);
void AsyncHandleMessage(BMessage* msg); void AsyncHandleMessage(BMessage *msg);
void Handle_BeOSR5_Message(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;
}; };