Clean up.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2094 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,101 +0,0 @@
|
||||
/*****************************************************************************/
|
||||
// BeUtils.cpp
|
||||
//
|
||||
// Version: 1.0.0d1
|
||||
//
|
||||
// Several utilities for writing applications for the BeOS. It are small
|
||||
// very specific functions, but generally useful (could be here because of a
|
||||
// lack in the APIs, or just sheer lazyness :))
|
||||
//
|
||||
// Authors
|
||||
// Ithamar R. Adema
|
||||
// Michael Pfeiffer
|
||||
//
|
||||
// This application and all source files used in its construction, except
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2001 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef BEUTILS_H
|
||||
#define BEUTILS_H
|
||||
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <SupportDefs.h>
|
||||
#include <Picture.h>
|
||||
#include <PictureButton.h>
|
||||
#include <TranslatorFormats.h>
|
||||
#include <TranslationUtils.h>
|
||||
|
||||
status_t TestForAddonExistence(const char* name, directory_which which,
|
||||
const char* section, BPath& outPath);
|
||||
|
||||
// Reference counted object
|
||||
class Object {
|
||||
private:
|
||||
volatile int32 fRefCount;
|
||||
|
||||
public:
|
||||
// After construction reference count is 1
|
||||
Object() : fRefCount(1) { }
|
||||
// dtor should be private, but ie. ObjectList requires a public dtor!
|
||||
virtual ~Object() { };
|
||||
|
||||
// thread-safe as long as thread that calls Acquire has already
|
||||
// a reference to the object
|
||||
void Acquire() {
|
||||
atomic_add(&fRefCount, 1);
|
||||
}
|
||||
|
||||
bool Release() {
|
||||
if (atomic_add(&fRefCount, -1) == 1) {
|
||||
delete this; return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Automatically send a reply to sender on destruction of object
|
||||
// and delete sender
|
||||
class AutoReply {
|
||||
BMessage* fSender;
|
||||
BMessage fReply;
|
||||
|
||||
public:
|
||||
AutoReply(BMessage* sender, uint32 what);
|
||||
~AutoReply();
|
||||
void SetReply(BMessage* m) { fReply = *m; }
|
||||
};
|
||||
|
||||
// mimetype from sender
|
||||
bool MimeTypeForSender(BMessage* sender, BString& mime);
|
||||
// adds fields to message or replaces existing fields
|
||||
bool AddFields(BMessage* to, const BMessage* from);
|
||||
// load bitmap from application resources
|
||||
BBitmap* LoadBitmap(const char* name, uint32 type_code = B_TRANSLATOR_BITMAP);
|
||||
// convert bitmap to picture; view must be attached to a window!
|
||||
// returns NULL if bitmap is NULL
|
||||
BPicture *BitmapToPicture(BView* view, BBitmap *bitmap);
|
||||
BPicture *BitmapToGrayedPicture(BView* view, BBitmap *bitmap);
|
||||
#endif
|
||||
@@ -30,12 +30,15 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
#include "pr_server.h"
|
||||
#include "Printer.h"
|
||||
#include "PrintServerApp.h"
|
||||
#include "ConfigWindow.h"
|
||||
#include "BeUtils.h"
|
||||
|
||||
// posix
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -44,6 +47,65 @@
|
||||
#include <Autolock.h>
|
||||
#include <Window.h>
|
||||
|
||||
static const float a0_width = 2380.0;
|
||||
static const float a0_height = 3368.0;
|
||||
static const float a1_width = 1684.0;
|
||||
static const float a1_height = 2380.0;
|
||||
static const float a2_width = 1190.0;
|
||||
static const float a2_height = 1684.0;
|
||||
static const float a3_width = 842.0;
|
||||
static const float a3_height = 1190.0;
|
||||
static const float a4_width = 595.0;
|
||||
static const float a4_height = 842.0;
|
||||
static const float a5_width = 421.0;
|
||||
static const float a5_height = 595.0;
|
||||
static const float a6_width = 297.0;
|
||||
static const float a6_height = 421.0;
|
||||
static const float b5_width = 501.0;
|
||||
static const float b5_height = 709.0;
|
||||
static const float letter_width = 612.0;
|
||||
static const float letter_height = 792.0;
|
||||
static const float legal_width = 612.0;
|
||||
static const float legal_height = 1008.0;
|
||||
static const float ledger_width = 1224.0;
|
||||
static const float ledger_height = 792.0;
|
||||
static const float p11x17_width = 792.0;
|
||||
static const float p11x17_height = 1224.0;
|
||||
|
||||
static struct PageFormat
|
||||
{
|
||||
char *label;
|
||||
float width;
|
||||
float height;
|
||||
} pageFormat[] =
|
||||
{
|
||||
{"Letter", letter_width, letter_height },
|
||||
{"Legal", legal_width, legal_height },
|
||||
{"Ledger", ledger_width, ledger_height },
|
||||
{"p11x17", p11x17_width, p11x17_height },
|
||||
{"A0", a0_width, a0_height },
|
||||
{"A1", a1_width, a1_height },
|
||||
{"A2", a2_width, a2_height },
|
||||
{"A3", a3_width, a3_height },
|
||||
{"A4", a4_width, a4_height },
|
||||
{"A5", a5_width, a5_height },
|
||||
{"A6", a6_width, a6_height },
|
||||
{"B5", b5_width, b5_height },
|
||||
};
|
||||
|
||||
static void GetPageFormat(float w, float h, BString& label) {
|
||||
w = floor(w + 0.5); h = floor(h + 0.5);
|
||||
for (int i = 0; i < sizeof(pageFormat) / sizeof(struct PageFormat); i ++) {
|
||||
struct PageFormat& pf = pageFormat[i];
|
||||
if (pf.width == w && pf.height == h || pf.width == h && pf.height == w) {
|
||||
label = pf.label; return;
|
||||
}
|
||||
}
|
||||
|
||||
float unit = 72.0; // currently inc[h]es only
|
||||
label << (w / unit) << "x" << (h / unit) << " in.";
|
||||
}
|
||||
|
||||
ConfigWindow::ConfigWindow(config_setup_kind kind, Printer* defaultPrinter, BMessage* settings, AutoReply* sender)
|
||||
: BWindow(ConfigWindow::GetWindowFrame(), "Page Setup",
|
||||
B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE)
|
||||
@@ -81,8 +143,10 @@ ConfigWindow::ConfigWindow(config_setup_kind kind, Printer* defaultPrinter, BMes
|
||||
r.OffsetTo(left, top);
|
||||
fPageSetup = AddPictureButton(panel, r, "Page Format", "PAGE_SETUP_ON", "PAGE_SETUP_OFF", MSG_PAGE_SETUP);
|
||||
// add description to button
|
||||
r.OffsetTo(left + fPageSetup->Bounds().Width() + 5, top + fPageSetup->Bounds().Height()/2-5);
|
||||
r.OffsetTo(left + fPageSetup->Bounds().Width() + 5, top + 5);
|
||||
AddStringView(panel, r, "Setup page format");
|
||||
r.OffsetBy(0, 10);
|
||||
fPageFormatText = AddStringView(panel, r, "");
|
||||
top += fPageSetup->Bounds().Height() + 5;
|
||||
|
||||
// page selection button
|
||||
@@ -91,8 +155,10 @@ ConfigWindow::ConfigWindow(config_setup_kind kind, Printer* defaultPrinter, BMes
|
||||
r.OffsetTo(left, top);
|
||||
fJobSetup = AddPictureButton(panel, r, "Page Selection", "JOB_SETUP_ON", "JOB_SETUP_OFF", MSG_JOB_SETUP);
|
||||
// add description to button
|
||||
r.OffsetTo(left + fJobSetup->Bounds().Width() + 5, top + fJobSetup->Bounds().Width()/2-5);
|
||||
r.OffsetTo(left + fJobSetup->Bounds().Width() + 5, top + 5);
|
||||
AddStringView(panel, r, "Setup print job");
|
||||
r.OffsetBy(0, 10);
|
||||
fJobSetupText = AddStringView(panel, r, "");
|
||||
top += fJobSetup->Bounds().Height() + 5;
|
||||
}
|
||||
top += 5;
|
||||
@@ -266,11 +332,13 @@ BPictureButton* ConfigWindow::AddPictureButton(BView* panel, BRect frame, const
|
||||
return button;
|
||||
}
|
||||
|
||||
void ConfigWindow::AddStringView(BView* panel, BRect frame, const char* text) {
|
||||
BStringView* ConfigWindow::AddStringView(BView* panel, BRect frame, const char* text) {
|
||||
// frame.bottom = frame.top ;
|
||||
BStringView* string = new BStringView(frame, "", text);
|
||||
string->SetViewColor(panel->ViewColor());
|
||||
string->SetLowColor(panel->ViewColor());
|
||||
panel->AddChild(string);
|
||||
return string;
|
||||
}
|
||||
|
||||
void ConfigWindow::PrinterForMimeType() {
|
||||
@@ -347,8 +415,12 @@ void ConfigWindow::UpdateSettings(bool read) {
|
||||
void ConfigWindow::UpdateUI() {
|
||||
if (fCurrentPrinter == NULL) {
|
||||
fPageSetup->SetEnabled(false);
|
||||
if (fJobSetup) fJobSetup->SetEnabled(false);
|
||||
if (fJobSetup) {
|
||||
fJobSetup->SetEnabled(false);
|
||||
fJobSetupText->SetText("Undefined job settings");
|
||||
}
|
||||
fOk->SetEnabled(false);
|
||||
fPageFormatText->SetText("Undefined paper format");
|
||||
} else {
|
||||
fPageSetup->SetEnabled(true);
|
||||
|
||||
@@ -357,6 +429,43 @@ void ConfigWindow::UpdateUI() {
|
||||
}
|
||||
fOk->SetEnabled(fKind == kJobSetup && !fJobSettings.IsEmpty() ||
|
||||
fKind == kPageSetup && !fPageSettings.IsEmpty());
|
||||
|
||||
// display information about page format
|
||||
BRect paperRect;
|
||||
BString pageFormat;
|
||||
if (fPageSettings.FindRect(PSRV_FIELD_PAPER_RECT, &paperRect) == B_OK) {
|
||||
GetPageFormat(paperRect.Width(), paperRect.Height(), pageFormat);
|
||||
|
||||
int32 orientation = 0;
|
||||
fPageSettings.FindInt32(PSRV_FIELD_ORIENTATION, &orientation);
|
||||
if (orientation == 0) pageFormat << ", Portrait";
|
||||
else pageFormat << ", Landscape";
|
||||
} else {
|
||||
pageFormat << "Undefined paper format";
|
||||
}
|
||||
fPageFormatText->SetText(pageFormat.String());
|
||||
|
||||
// display information about job
|
||||
if (fKind == kJobSetup) {
|
||||
BString job;
|
||||
int32 first, last, copies;
|
||||
if (fJobSettings.FindInt32(PSRV_FIELD_FIRST_PAGE, &first) == B_OK &&
|
||||
fJobSettings.FindInt32(PSRV_FIELD_LAST_PAGE, &last) == B_OK) {
|
||||
if (first >= 1 && first <= last && last != INT_MAX) {
|
||||
job << "From page " << first << " to " << last;
|
||||
} else {
|
||||
job << "All pages";
|
||||
}
|
||||
int32 copies;
|
||||
if (fJobSettings.FindInt32(PSRV_FIELD_COPIES, &copies) == B_OK && copies > 1) {
|
||||
job << ", " << copies << " copies";
|
||||
}
|
||||
} else {
|
||||
job << "Undefined job settings";
|
||||
}
|
||||
|
||||
fJobSetupText->SetText(job.String());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
|
||||
private:
|
||||
BPictureButton* AddPictureButton(BView* panel, BRect frame, const char* name, const char* on, const char* off, uint32 what);
|
||||
void AddStringView(BView* panel, BRect frame, const char* text);
|
||||
BStringView* AddStringView(BView* panel, BRect frame, const char* text);
|
||||
void PrinterForMimeType();
|
||||
void SetupPrintersMenu(BMenu* menu);
|
||||
void UpdateAppSettings(const char* mime, const char* printer);
|
||||
@@ -90,6 +90,8 @@ private:
|
||||
BPictureButton* fPageSetup;
|
||||
BPictureButton* fJobSetup;
|
||||
BButton* fOk;
|
||||
BStringView* fPageFormatText;
|
||||
BStringView* fJobSetupText;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
SubDir OBOS_TOP src servers print ;
|
||||
|
||||
UsePrivateHeaders interface ;
|
||||
UsePrivateHeaders shared ;
|
||||
SubInclude OBOS_TOP src servers print shared ;
|
||||
|
||||
SubDir OBOS_TOP src servers print ;
|
||||
|
||||
UsePrivateHeaders shared interface print ;
|
||||
|
||||
AddResources
|
||||
print_server
|
||||
@@ -18,8 +21,6 @@ Server
|
||||
Printer.Scripting.cpp
|
||||
Printer.cpp
|
||||
ResourceManager.cpp
|
||||
Jobs.cpp
|
||||
BeUtils.cpp
|
||||
Settings.cpp
|
||||
ConfigWindow.cpp
|
||||
;
|
||||
@@ -29,5 +30,6 @@ LinkSharedOSLibs
|
||||
:
|
||||
be
|
||||
root
|
||||
translation
|
||||
translation
|
||||
libprint.a
|
||||
;
|
||||
|
||||
@@ -126,6 +126,38 @@ status_t PrintServerApp::async_thread(void* data)
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// 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 (p->app->CreatePrinter(printerName.String(), driverName.String(),
|
||||
connection.String(),
|
||||
transportName.String(), transportPath.String()) == B_OK) {
|
||||
// If printer was created ok, ask if it needs to be the default
|
||||
char buffer[256];
|
||||
::sprintf(buffer, "Would you like to make %s the default\nprinter?",
|
||||
printerName.String());
|
||||
|
||||
BAlert* alert = new BAlert("", buffer, "No", "Yes");
|
||||
if (alert->Go() == 1) {
|
||||
p->app->SelectPrinter(printerName.String());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +212,7 @@ void PrintServerApp::Handle_BeOSR5_Message(BMessage* msg)
|
||||
}
|
||||
break;
|
||||
|
||||
#if 0
|
||||
// Create a new printer
|
||||
case PSRV_MAKE_PRINTER: {
|
||||
BString driverName, transportName, transportPath;
|
||||
@@ -211,10 +244,12 @@ void PrintServerApp::Handle_BeOSR5_Message(BMessage* msg)
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PSRV_SHOW_PAGE_SETUP:
|
||||
case PSRV_SHOW_PRINT_SETUP:
|
||||
case PSRV_GET_DEFAULT_SETTINGS:
|
||||
case PSRV_MAKE_PRINTER:
|
||||
AsyncHandleMessage(DetachCurrentMessage());
|
||||
break;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2001 OpenBeOS Project
|
||||
// Copyright (c) 2001, 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2001 OpenBeOS Project
|
||||
// Copyright (c) 2001, 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@@ -112,7 +112,8 @@ PrintServerApp::PrintServerApp(status_t* err)
|
||||
fSelectedIconLarge(NULL),
|
||||
fReferences(0),
|
||||
fHasReferences(0),
|
||||
fUseConfigWindow(true)
|
||||
fUseConfigWindow(true),
|
||||
fFolder(NULL)
|
||||
{
|
||||
fSettings = Settings::GetSettings();
|
||||
LoadSettings();
|
||||
@@ -151,6 +152,8 @@ bool PrintServerApp::QuitRequested()
|
||||
|
||||
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) {
|
||||
@@ -162,6 +165,7 @@ bool PrintServerApp::QuitRequested()
|
||||
::watch_node(&nref, B_STOP_WATCHING, be_app_messenger);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Release all printers
|
||||
Printer* printer;
|
||||
@@ -195,18 +199,28 @@ void PrintServerApp::Release() {
|
||||
}
|
||||
|
||||
void PrintServerApp::RegisterPrinter(BDirectory* printer) {
|
||||
BString transport, address, connection;
|
||||
BString transport, address, connection, state;
|
||||
|
||||
printer->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT, &transport);
|
||||
printer->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT_ADDR, &address);
|
||||
printer->ReadAttrString(PSRV_PRINTER_ATTR_CNX, &connection);
|
||||
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()) {
|
||||
Resource* r = fResourceManager.Allocate(transport.String(), address.String(), connection.String());
|
||||
Printer* p = new Printer(printer, r);
|
||||
AddHandler(p);
|
||||
Acquire();
|
||||
BAutolock lock(gLock);
|
||||
if (lock.IsLocked()) {
|
||||
// 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
|
||||
Resource* r = fResourceManager.Allocate(transport.String(), address.String(), connection.String());
|
||||
p = new Printer(printer, r);
|
||||
AddHandler(p);
|
||||
Acquire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,20 +238,29 @@ void PrintServerApp::NotifyPrinterDeletion(Printer* printer) {
|
||||
}
|
||||
}
|
||||
|
||||
void PrintServerApp::HandleRemovedPrinter(BMessage* msg) {
|
||||
int32 opcode;
|
||||
dev_t device;
|
||||
ino_t node;
|
||||
Printer* printer;
|
||||
if (msg->FindInt32("opcode", &opcode) == B_OK && opcode == B_ENTRY_REMOVED &&
|
||||
msg->FindInt32("device", &device) == B_OK &&
|
||||
msg->FindInt64("node", &node) == B_OK &&
|
||||
(printer = Printer::Find(device, node)) != NULL) {
|
||||
|
||||
void PrintServerApp::EntryCreated(node_ref* node, entry_ref* entry) {
|
||||
BEntry printer(entry);
|
||||
if (printer.InitCheck() == B_OK && printer.IsDirectory()) {
|
||||
BDirectory dir(&printer);
|
||||
if (dir.InitCheck() == B_OK) RegisterPrinter(&dir);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintServerApp::EntryRemoved(node_ref* node) {
|
||||
Printer* printer = Printer::Find(node);
|
||||
if (printer) {
|
||||
if (printer == fDefaultPrinter) fDefaultPrinter = NULL;
|
||||
UnregisterPrinter(printer);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintServerApp::AttributeChanged(node_ref* node) {
|
||||
BDirectory printer(node);
|
||||
if (printer.InitCheck() == B_OK) {
|
||||
RegisterPrinter(&printer);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// SetupPrinterList
|
||||
@@ -280,7 +303,11 @@ status_t PrintServerApp::SetupPrinterList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 &&
|
||||
@@ -288,6 +315,7 @@ status_t PrintServerApp::SetupPrinterList()
|
||||
// Get node to watch
|
||||
rc = ::watch_node(&nref, B_WATCH_DIRECTORY, be_app_messenger);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,10 +356,6 @@ PrintServerApp::MessageReceived(BMessage* msg)
|
||||
case B_EXECUTE_PROPERTY:
|
||||
HandleScriptingCommand(msg);
|
||||
break;
|
||||
|
||||
case B_NODE_MONITOR:
|
||||
HandleRemovedPrinter(msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
Inherited::MessageReceived(msg);
|
||||
@@ -378,7 +402,6 @@ PrintServerApp::CreatePrinter(const char* printerName, const char* driverName,
|
||||
// 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_STATE, B_STRING_TYPE, 0, "free", ::strlen("free")+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);
|
||||
@@ -399,7 +422,7 @@ PrintServerApp::CreatePrinter(const char* printerName, const char* driverName,
|
||||
entry.Remove();
|
||||
}
|
||||
} else {
|
||||
RegisterPrinter(&printer);
|
||||
printer.WriteAttr(PSRV_PRINTER_ATTR_STATE, B_STRING_TYPE, 0, "free", ::strlen("free")+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2001 OpenBeOS Project
|
||||
// Copyright (c) 2001, 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
#include "ResourceManager.h"
|
||||
#include "Settings.h"
|
||||
#include "FolderWatcher.h"
|
||||
|
||||
class PrintServerApp;
|
||||
|
||||
@@ -57,7 +58,7 @@ extern BLocker* gLock;
|
||||
// Application class for print_server.
|
||||
/*****************************************************************************/
|
||||
class Printer;
|
||||
class PrintServerApp : public BApplication
|
||||
class PrintServerApp : public BApplication, public FolderListener
|
||||
{
|
||||
typedef BApplication Inherited;
|
||||
public:
|
||||
@@ -93,8 +94,11 @@ private:
|
||||
|
||||
void RegisterPrinter(BDirectory* node);
|
||||
void UnregisterPrinter(Printer* printer);
|
||||
void HandleRemovedPrinter(BMessage* msg);
|
||||
|
||||
// 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();
|
||||
|
||||
@@ -109,6 +113,7 @@ private:
|
||||
sem_id fHasReferences;
|
||||
Settings*fSettings;
|
||||
bool fUseConfigWindow;
|
||||
FolderWatcher* fFolder;
|
||||
|
||||
// "Classic" BeOS R5 support, see PrintServerApp.R5.cpp
|
||||
static status_t async_thread(void* data);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2001 OpenBeOS Project
|
||||
// Copyright (c) 2001, 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
|
||||
@@ -55,6 +55,23 @@
|
||||
#include <StorageKit.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
SpoolFolder::SpoolFolder(BLocker*locker, BLooper* looper, const BDirectory& spoolDir)
|
||||
: Folder(locker, looper, spoolDir)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Notify print_server that there is a job file waiting for printing
|
||||
void SpoolFolder::Notify(Job* job, int kind)
|
||||
{
|
||||
if ((kind == kJobAdded || kind == kJobAttrChanged) &&
|
||||
job->IsValid() && job->IsWaiting()) {
|
||||
be_app_messenger.SendMessage(PSRV_PRINT_SPOOLED_JOB);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
typedef BMessage* (*config_func_t)(BNode*, const BMessage*);
|
||||
typedef BMessage* (*take_job_func_t)(BFile*, BNode*, const BMessage*);
|
||||
@@ -90,14 +107,14 @@ Printer* Printer::Find(const BString& name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Printer* Printer::Find(dev_t dev, ino_t node)
|
||||
Printer* Printer::Find(node_ref* node)
|
||||
{
|
||||
node_ref n;
|
||||
// Look in list to find printer definition
|
||||
for (int32 idx=0; idx < sPrinters.CountItems(); idx++) {
|
||||
Printer* printer = sPrinters.ItemAt(idx);
|
||||
node_ref ref;
|
||||
printer->SpoolDir()->GetNodeRef(&ref);
|
||||
if (ref.device == dev && ref.node == node) return printer;
|
||||
printer->SpoolDir()->GetNodeRef(&n);
|
||||
if (n == *node) return printer;
|
||||
}
|
||||
|
||||
// None found, so return NULL
|
||||
@@ -132,7 +149,7 @@ int32 Printer::CountPrinters()
|
||||
// ---------------------------------------------------------------
|
||||
Printer::Printer(const BDirectory* node, Resource* res)
|
||||
: Inherited(B_EMPTY_STRING),
|
||||
fPrinter(*node),
|
||||
fPrinter(gLock, be_app, *node),
|
||||
fResource(res),
|
||||
fSinglePrintThread(true),
|
||||
fJob(NULL),
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2001 OpenBeOS Project
|
||||
// Copyright (c) 2001, 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@@ -55,6 +55,14 @@ class Printer;
|
||||
// OpenTracker shared sources
|
||||
#include "ObjectList.h"
|
||||
|
||||
class SpoolFolder : public Folder {
|
||||
protected:
|
||||
void Notify(Job* job, int kind);
|
||||
|
||||
public:
|
||||
SpoolFolder(BLocker* locker, BLooper* looper, const BDirectory& spoolDir);
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
// Printer
|
||||
//
|
||||
@@ -71,7 +79,7 @@ public:
|
||||
|
||||
// Static helper functions
|
||||
static Printer* Find(const BString& name);
|
||||
static Printer* Find(dev_t device, ino_t node);
|
||||
static Printer* Find(node_ref* node);
|
||||
static Printer* At(int32 idx);
|
||||
static void Remove(Printer* printer);
|
||||
static int32 CountPrinters();
|
||||
@@ -102,11 +110,11 @@ private:
|
||||
status_t LoadPrinterAddon(image_id& id);
|
||||
void AddCurrentPrinter(BMessage* m);
|
||||
|
||||
Folder fPrinter; // the printer spooling directory
|
||||
Resource* fResource; // the resource required for processing a print job
|
||||
SpoolFolder fPrinter; // the printer spooling directory
|
||||
bool fSinglePrintThread; // is printer add-on allowed to process multiple print job at once
|
||||
Job* fJob; // the next job to process
|
||||
vint32 fProcessing; // the current number of processing threads
|
||||
vint32 fProcessing; // the current nmber of processing threads
|
||||
bool fAbort; // stop processing
|
||||
|
||||
static BObjectList<Printer> sPrinters;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2001 OpenBeOS Project
|
||||
// Copyright (c) 2001, 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@@ -0,0 +1,175 @@
|
||||
/*****************************************************************************/
|
||||
// FolderWatcher
|
||||
//
|
||||
// Author
|
||||
// Michael Pfeiffer
|
||||
//
|
||||
// This application and all source files used in its construction, except
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
#include "FolderWatcher.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// BeOS
|
||||
#include <kernel/fs_attr.h>
|
||||
#include <Node.h>
|
||||
#include <NodeInfo.h>
|
||||
#include <NodeMonitor.h>
|
||||
|
||||
|
||||
// Implementation of FolderWatcher
|
||||
|
||||
FolderWatcher::FolderWatcher(BLooper* looper, const BDirectory& folder, bool watchAttrChanges)
|
||||
: fFolder(folder)
|
||||
, fListener(NULL)
|
||||
, fWatchAttrChanges(watchAttrChanges)
|
||||
{
|
||||
// add this handler to the application for node monitoring
|
||||
if (looper->Lock()) {
|
||||
looper->AddHandler(this);
|
||||
looper->Unlock();
|
||||
}
|
||||
|
||||
// start attribute change watching for existing files
|
||||
if (watchAttrChanges) {
|
||||
BEntry entry;
|
||||
node_ref node;
|
||||
while (fFolder.GetNextEntry(&entry) == B_OK && entry.GetNodeRef(&node) == B_OK) {
|
||||
StartAttrWatching(&node);
|
||||
}
|
||||
}
|
||||
|
||||
// start watching the spooler directory
|
||||
node_ref ref;
|
||||
fFolder.GetNodeRef(&ref);
|
||||
watch_node(&ref, B_WATCH_DIRECTORY, this);
|
||||
}
|
||||
|
||||
FolderWatcher::~FolderWatcher() {
|
||||
// stop node watching for spooler directory
|
||||
node_ref ref;
|
||||
fFolder.GetNodeRef(&ref);
|
||||
watch_node(&ref, B_STOP_WATCHING, this);
|
||||
// stop sending notifications to this handler
|
||||
stop_watching(this);
|
||||
|
||||
if (LockLooper()) {
|
||||
BLooper* looper = Looper();
|
||||
// and remove it
|
||||
looper->RemoveHandler(this);
|
||||
looper->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void FolderWatcher::SetListener(FolderListener* listener) {
|
||||
fListener = listener;
|
||||
}
|
||||
|
||||
bool FolderWatcher::BuildEntryRef(BMessage* msg, const char* dirName, entry_ref* entry) {
|
||||
const char* name;
|
||||
if (msg->FindInt32("device", &entry->device) == B_OK &&
|
||||
msg->FindInt64(dirName, &entry->directory) == B_OK &&
|
||||
msg->FindString("name", &name) == B_OK) {
|
||||
entry->set_name(name);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FolderWatcher::BuildNodeRef(BMessage* msg, node_ref* node) {
|
||||
return (msg->FindInt32("device", &node->device) == B_OK &&
|
||||
msg->FindInt64("node", &node->node) == B_OK);
|
||||
}
|
||||
|
||||
void FolderWatcher::HandleCreatedEntry(BMessage* msg, const char* dirName) {
|
||||
node_ref node;
|
||||
entry_ref entry;
|
||||
if (BuildEntryRef(msg, dirName, &entry) &&
|
||||
BuildNodeRef(msg, &node)) {
|
||||
if (fWatchAttrChanges) StartAttrWatching(&node);
|
||||
fListener->EntryCreated(&node, &entry);
|
||||
}
|
||||
}
|
||||
|
||||
void FolderWatcher::HandleRemovedEntry(BMessage* msg) {
|
||||
node_ref node;
|
||||
if (BuildNodeRef(msg, &node)) {
|
||||
if (fWatchAttrChanges) StopAttrWatching(&node);
|
||||
fListener->EntryRemoved(&node);
|
||||
}
|
||||
}
|
||||
|
||||
void FolderWatcher::HandleChangedAttr(BMessage* msg) {
|
||||
node_ref node;
|
||||
if (BuildNodeRef(msg, &node)) {
|
||||
fListener->AttributeChanged(&node);
|
||||
}
|
||||
}
|
||||
|
||||
void FolderWatcher::MessageReceived(BMessage* msg) {
|
||||
int32 opcode;
|
||||
node_ref folder;
|
||||
ino_t dir;
|
||||
|
||||
if (msg->what == B_NODE_MONITOR) {
|
||||
if (fListener == NULL || msg->FindInt32("opcode", &opcode) != B_OK) return;
|
||||
|
||||
switch (opcode) {
|
||||
case B_ENTRY_CREATED:
|
||||
HandleCreatedEntry(msg, "directory");
|
||||
break;
|
||||
case B_ENTRY_REMOVED:
|
||||
HandleRemovedEntry(msg);
|
||||
break;
|
||||
case B_ENTRY_MOVED:
|
||||
fFolder.GetNodeRef(&folder);
|
||||
if (msg->FindInt64("to directory", &dir) == B_OK && folder.node == dir) {
|
||||
// entry moved into this folder
|
||||
HandleCreatedEntry(msg, "to directory");
|
||||
} else if (msg->FindInt64("from directory", &dir) == B_OK && folder.node == dir) {
|
||||
// entry removed from this folder
|
||||
HandleRemovedEntry(msg);
|
||||
}
|
||||
break;
|
||||
case B_ATTR_CHANGED:
|
||||
HandleChangedAttr(msg);
|
||||
break;
|
||||
default: // nothing to do
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
inherited::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
status_t FolderWatcher::StartAttrWatching(node_ref* node) {
|
||||
return watch_node(node, B_WATCH_ATTR, this);
|
||||
}
|
||||
|
||||
status_t FolderWatcher::StopAttrWatching(node_ref* node) {
|
||||
return watch_node(node, B_STOP_WATCHING, this);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
SubDir OBOS_TOP src servers print shared ;
|
||||
|
||||
UsePrivateHeaders shared interface print ;
|
||||
|
||||
StaticLibrary
|
||||
print
|
||||
:
|
||||
BeUtils.cpp
|
||||
FolderWatcher.cpp
|
||||
Jobs.cpp
|
||||
;
|
||||
@@ -0,0 +1,265 @@
|
||||
/*****************************************************************************/
|
||||
// Jobs
|
||||
//
|
||||
// Author
|
||||
// Michael Pfeiffer
|
||||
//
|
||||
// This application and all source files used in its construction, except
|
||||
// where noted, are licensed under the MIT License, and have been written
|
||||
// and are:
|
||||
//
|
||||
// Copyright (c) 2002 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
#include "pr_server.h"
|
||||
#include "Jobs.h"
|
||||
// #include "PrintServerApp.h"
|
||||
|
||||
// posix
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// BeOS
|
||||
#include <kernel/fs_attr.h>
|
||||
#include <Application.h>
|
||||
#include <Node.h>
|
||||
#include <NodeInfo.h>
|
||||
#include <NodeMonitor.h>
|
||||
|
||||
|
||||
// Implementation of Job
|
||||
|
||||
Job::Job(const BEntry& job, Folder* folder)
|
||||
: fFolder(folder)
|
||||
, fTime(-1)
|
||||
, fStatus(kUnknown)
|
||||
, fValid(false)
|
||||
, fPrinter(NULL)
|
||||
{
|
||||
// store light weight versions of BEntry and BNode
|
||||
job.GetRef(&fEntry);
|
||||
job.GetNodeRef(&fNode);
|
||||
|
||||
fValid = IsValidJobFile();
|
||||
|
||||
BNode node(&job);
|
||||
if (node.InitCheck() != B_OK) return;
|
||||
|
||||
BString status;
|
||||
// read status attribute
|
||||
if (node.ReadAttrString(PSRV_SPOOL_ATTR_STATUS, &status) != B_OK) {
|
||||
status = "";
|
||||
}
|
||||
UpdateStatus(status.String());
|
||||
|
||||
// Now get file name and creation time from file name
|
||||
fTime = 0;
|
||||
BEntry entry(job);
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
if (entry.InitCheck() == B_OK && entry.GetName(name) == B_OK) {
|
||||
fName = name;
|
||||
// search for last '@' in file name
|
||||
char* p = NULL, *c = name;
|
||||
while ((c = strchr(c, '@')) != NULL) {
|
||||
p = c; c ++;
|
||||
}
|
||||
// and get time from file name
|
||||
if (p) fTime = atoi(p+1);
|
||||
}
|
||||
}
|
||||
|
||||
// conversion from string representation of status to JobStatus constant
|
||||
void Job::UpdateStatus(const char* status) {
|
||||
if (strcmp(status, PSRV_JOB_STATUS_WAITING) == 0) fStatus = kWaiting;
|
||||
else if (strcmp(status, PSRV_JOB_STATUS_PROCESSING) == 0) fStatus = kProcessing;
|
||||
else if (strcmp(status, PSRV_JOB_STATUS_FAILED) == 0) fStatus = kFailed;
|
||||
else if (strcmp(status, PSRV_JOB_STATUS_COMPLETED) == 0) fStatus = kCompleted;
|
||||
else fStatus = kUnknown;
|
||||
}
|
||||
|
||||
// Write to status attribute of node
|
||||
void Job::UpdateStatusAttribute(const char* status) {
|
||||
BNode node(&fEntry);
|
||||
if (node.InitCheck() == B_OK) {
|
||||
node.WriteAttr(PSRV_SPOOL_ATTR_STATUS, B_STRING_TYPE, 0, status, strlen(status)+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Job::HasAttribute(BNode* n, const char* name) {
|
||||
attr_info info;
|
||||
return n->GetAttrInfo(name, &info) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool Job::IsValidJobFile() {
|
||||
BNode node(&fEntry);
|
||||
if (node.InitCheck() != B_OK) return false;
|
||||
|
||||
BNodeInfo info(&node);
|
||||
char mimeType[256];
|
||||
|
||||
// Is job a spool file?
|
||||
return (info.InitCheck() == B_OK &&
|
||||
info.GetType(mimeType) == B_OK &&
|
||||
strcmp(mimeType, PSRV_SPOOL_FILETYPE) == 0) &&
|
||||
HasAttribute(&node, PSRV_SPOOL_ATTR_MIMETYPE) &&
|
||||
HasAttribute(&node, PSRV_SPOOL_ATTR_PAGECOUNT) &&
|
||||
HasAttribute(&node, PSRV_SPOOL_ATTR_DESCRIPTION) &&
|
||||
HasAttribute(&node, PSRV_SPOOL_ATTR_PRINTER) &&
|
||||
HasAttribute(&node, PSRV_SPOOL_ATTR_STATUS);
|
||||
}
|
||||
|
||||
|
||||
// Set status of object and optionally write to attribute of node
|
||||
void Job::SetStatus(JobStatus s, bool writeToNode) {
|
||||
fStatus = s;
|
||||
if (!writeToNode) return;
|
||||
switch (s) {
|
||||
case kWaiting: UpdateStatusAttribute(PSRV_JOB_STATUS_WAITING); break;
|
||||
case kProcessing: UpdateStatusAttribute(PSRV_JOB_STATUS_PROCESSING); break;
|
||||
case kFailed: UpdateStatusAttribute(PSRV_JOB_STATUS_FAILED); break;
|
||||
case kCompleted: UpdateStatusAttribute(PSRV_JOB_STATUS_COMPLETED); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Synchronize file attribute with member variable
|
||||
void Job::UpdateAttribute() {
|
||||
fValid = fValid || IsValidJobFile();
|
||||
BNode node(&fEntry);
|
||||
BString status;
|
||||
if (node.InitCheck() == B_OK &&
|
||||
node.ReadAttrString(PSRV_SPOOL_ATTR_STATUS, &status) == B_OK) {
|
||||
UpdateStatus(status.String());
|
||||
}
|
||||
}
|
||||
|
||||
void Job::Remove() {
|
||||
BEntry entry(&fEntry);
|
||||
if (entry.InitCheck() == B_OK) entry.Remove();
|
||||
}
|
||||
|
||||
// Implementation of Folder
|
||||
|
||||
// BObjectList CompareFunction
|
||||
int Folder::AscendingByTime(const Job* a, const Job* b) {
|
||||
return a->Time() - b->Time();
|
||||
}
|
||||
|
||||
bool Folder::AddJob(BEntry& entry, bool notify) {
|
||||
Job* job = new Job(entry, this);
|
||||
if (job->InitCheck() == B_OK) {
|
||||
fJobs.AddItem(job);
|
||||
if (notify) Notify(job, kJobAdded);
|
||||
return true;
|
||||
} else {
|
||||
job->Release();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// simplified assumption that ino_t identifies job file
|
||||
// will probabely not work in all cases with link to a file on another volume???
|
||||
Job* Folder::Find(node_ref* node) {
|
||||
for (int i = 0; i < fJobs.CountItems(); i ++) {
|
||||
Job* job = fJobs.ItemAt(i);
|
||||
if (job->NodeRef() == *node) return job;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Folder::EntryCreated(node_ref* node, entry_ref* entry) {
|
||||
BEntry job(entry);
|
||||
if (job.InitCheck() == B_OK && Lock()) {
|
||||
if (AddJob(job)) {
|
||||
fJobs.SortItems(AscendingByTime);
|
||||
}
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void Folder::EntryRemoved(node_ref* node) {
|
||||
Job* job = Find(node);
|
||||
if (job && Lock()) {
|
||||
fJobs.RemoveItem(job);
|
||||
Notify(job, kJobRemoved);
|
||||
job->Release();
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void Folder::AttributeChanged(node_ref* node) {
|
||||
Job* job = Find(node);
|
||||
if (job && Lock()) {
|
||||
job->UpdateAttribute();
|
||||
Notify(job, kJobAttrChanged);
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// initial setup of job list
|
||||
void Folder::SetupJobList() {
|
||||
if (inherited::Folder()->InitCheck() == B_OK) {
|
||||
inherited::Folder()->Rewind();
|
||||
|
||||
BEntry entry;
|
||||
while (inherited::Folder()->GetNextEntry(&entry) == B_OK) {
|
||||
AddJob(entry, false);
|
||||
}
|
||||
fJobs.SortItems(AscendingByTime);
|
||||
}
|
||||
}
|
||||
|
||||
Folder::Folder(BLocker* locker, BLooper* looper, const BDirectory& spoolDir)
|
||||
: fLocker(locker)
|
||||
, FolderWatcher(looper, spoolDir, true)
|
||||
, fJobs()
|
||||
{
|
||||
SetListener(this);
|
||||
if (Lock()) {
|
||||
SetupJobList();
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Folder::~Folder() {
|
||||
if (!Lock()) return;
|
||||
// release jobs
|
||||
for (int i = 0; i < fJobs.CountItems(); i ++) {
|
||||
Job* job = fJobs.ItemAt(i);
|
||||
job->Release();
|
||||
}
|
||||
Unlock();
|
||||
}
|
||||
|
||||
Job* Folder::GetNextJob() {
|
||||
for (int i = 0; i < fJobs.CountItems(); i ++) {
|
||||
Job* job = fJobs.ItemAt(i);
|
||||
if (job->IsValid() && job->IsWaiting()) {
|
||||
job->Acquire(); return job;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user