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 "Printer.h"
|
||||||
#include "PrintServerApp.h"
|
#include "PrintServerApp.h"
|
||||||
#include "ConfigWindow.h"
|
#include "ConfigWindow.h"
|
||||||
#include "BeUtils.h"
|
#include "BeUtils.h"
|
||||||
|
|
||||||
// posix
|
// posix
|
||||||
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -44,6 +47,65 @@
|
|||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
#include <Window.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)
|
ConfigWindow::ConfigWindow(config_setup_kind kind, Printer* defaultPrinter, BMessage* settings, AutoReply* sender)
|
||||||
: BWindow(ConfigWindow::GetWindowFrame(), "Page Setup",
|
: BWindow(ConfigWindow::GetWindowFrame(), "Page Setup",
|
||||||
B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE)
|
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);
|
r.OffsetTo(left, top);
|
||||||
fPageSetup = AddPictureButton(panel, r, "Page Format", "PAGE_SETUP_ON", "PAGE_SETUP_OFF", MSG_PAGE_SETUP);
|
fPageSetup = AddPictureButton(panel, r, "Page Format", "PAGE_SETUP_ON", "PAGE_SETUP_OFF", MSG_PAGE_SETUP);
|
||||||
// add description to button
|
// 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");
|
AddStringView(panel, r, "Setup page format");
|
||||||
|
r.OffsetBy(0, 10);
|
||||||
|
fPageFormatText = AddStringView(panel, r, "");
|
||||||
top += fPageSetup->Bounds().Height() + 5;
|
top += fPageSetup->Bounds().Height() + 5;
|
||||||
|
|
||||||
// page selection button
|
// page selection button
|
||||||
@@ -91,8 +155,10 @@ ConfigWindow::ConfigWindow(config_setup_kind kind, Printer* defaultPrinter, BMes
|
|||||||
r.OffsetTo(left, top);
|
r.OffsetTo(left, top);
|
||||||
fJobSetup = AddPictureButton(panel, r, "Page Selection", "JOB_SETUP_ON", "JOB_SETUP_OFF", MSG_JOB_SETUP);
|
fJobSetup = AddPictureButton(panel, r, "Page Selection", "JOB_SETUP_ON", "JOB_SETUP_OFF", MSG_JOB_SETUP);
|
||||||
// add description to button
|
// 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");
|
AddStringView(panel, r, "Setup print job");
|
||||||
|
r.OffsetBy(0, 10);
|
||||||
|
fJobSetupText = AddStringView(panel, r, "");
|
||||||
top += fJobSetup->Bounds().Height() + 5;
|
top += fJobSetup->Bounds().Height() + 5;
|
||||||
}
|
}
|
||||||
top += 5;
|
top += 5;
|
||||||
@@ -266,11 +332,13 @@ BPictureButton* ConfigWindow::AddPictureButton(BView* panel, BRect frame, const
|
|||||||
return button;
|
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);
|
BStringView* string = new BStringView(frame, "", text);
|
||||||
string->SetViewColor(panel->ViewColor());
|
string->SetViewColor(panel->ViewColor());
|
||||||
string->SetLowColor(panel->ViewColor());
|
string->SetLowColor(panel->ViewColor());
|
||||||
panel->AddChild(string);
|
panel->AddChild(string);
|
||||||
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWindow::PrinterForMimeType() {
|
void ConfigWindow::PrinterForMimeType() {
|
||||||
@@ -347,8 +415,12 @@ void ConfigWindow::UpdateSettings(bool read) {
|
|||||||
void ConfigWindow::UpdateUI() {
|
void ConfigWindow::UpdateUI() {
|
||||||
if (fCurrentPrinter == NULL) {
|
if (fCurrentPrinter == NULL) {
|
||||||
fPageSetup->SetEnabled(false);
|
fPageSetup->SetEnabled(false);
|
||||||
if (fJobSetup) fJobSetup->SetEnabled(false);
|
if (fJobSetup) {
|
||||||
|
fJobSetup->SetEnabled(false);
|
||||||
|
fJobSetupText->SetText("Undefined job settings");
|
||||||
|
}
|
||||||
fOk->SetEnabled(false);
|
fOk->SetEnabled(false);
|
||||||
|
fPageFormatText->SetText("Undefined paper format");
|
||||||
} else {
|
} else {
|
||||||
fPageSetup->SetEnabled(true);
|
fPageSetup->SetEnabled(true);
|
||||||
|
|
||||||
@@ -357,6 +429,43 @@ void ConfigWindow::UpdateUI() {
|
|||||||
}
|
}
|
||||||
fOk->SetEnabled(fKind == kJobSetup && !fJobSettings.IsEmpty() ||
|
fOk->SetEnabled(fKind == kJobSetup && !fJobSettings.IsEmpty() ||
|
||||||
fKind == kPageSetup && !fPageSettings.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:
|
private:
|
||||||
BPictureButton* AddPictureButton(BView* panel, BRect frame, const char* name, const char* on, const char* off, uint32 what);
|
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 PrinterForMimeType();
|
||||||
void SetupPrintersMenu(BMenu* menu);
|
void SetupPrintersMenu(BMenu* menu);
|
||||||
void UpdateAppSettings(const char* mime, const char* printer);
|
void UpdateAppSettings(const char* mime, const char* printer);
|
||||||
@@ -90,6 +90,8 @@ private:
|
|||||||
BPictureButton* fPageSetup;
|
BPictureButton* fPageSetup;
|
||||||
BPictureButton* fJobSetup;
|
BPictureButton* fJobSetup;
|
||||||
BButton* fOk;
|
BButton* fOk;
|
||||||
|
BStringView* fPageFormatText;
|
||||||
|
BStringView* fJobSetupText;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
SubDir OBOS_TOP src servers print ;
|
SubDir OBOS_TOP src servers print ;
|
||||||
|
|
||||||
UsePrivateHeaders interface ;
|
SubInclude OBOS_TOP src servers print shared ;
|
||||||
UsePrivateHeaders shared ;
|
|
||||||
|
SubDir OBOS_TOP src servers print ;
|
||||||
|
|
||||||
|
UsePrivateHeaders shared interface print ;
|
||||||
|
|
||||||
AddResources
|
AddResources
|
||||||
print_server
|
print_server
|
||||||
@@ -18,8 +21,6 @@ Server
|
|||||||
Printer.Scripting.cpp
|
Printer.Scripting.cpp
|
||||||
Printer.cpp
|
Printer.cpp
|
||||||
ResourceManager.cpp
|
ResourceManager.cpp
|
||||||
Jobs.cpp
|
|
||||||
BeUtils.cpp
|
|
||||||
Settings.cpp
|
Settings.cpp
|
||||||
ConfigWindow.cpp
|
ConfigWindow.cpp
|
||||||
;
|
;
|
||||||
@@ -29,5 +30,6 @@ LinkSharedOSLibs
|
|||||||
:
|
:
|
||||||
be
|
be
|
||||||
root
|
root
|
||||||
translation
|
translation
|
||||||
|
libprint.a
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -126,6 +126,38 @@ status_t PrintServerApp::async_thread(void* data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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;
|
break;
|
||||||
|
|
||||||
|
#if 0
|
||||||
// Create a new printer
|
// Create a new printer
|
||||||
case PSRV_MAKE_PRINTER: {
|
case PSRV_MAKE_PRINTER: {
|
||||||
BString driverName, transportName, transportPath;
|
BString driverName, transportName, transportPath;
|
||||||
@@ -211,10 +244,12 @@ void PrintServerApp::Handle_BeOSR5_Message(BMessage* msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
||||||
|
case PSRV_MAKE_PRINTER:
|
||||||
AsyncHandleMessage(DetachCurrentMessage());
|
AsyncHandleMessage(DetachCurrentMessage());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// where noted, are licensed under the MIT License, and have been written
|
// where noted, are licensed under the MIT License, and have been written
|
||||||
// and are:
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// 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
|
// where noted, are licensed under the MIT License, and have been written
|
||||||
// and are:
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -112,7 +112,8 @@ PrintServerApp::PrintServerApp(status_t* err)
|
|||||||
fSelectedIconLarge(NULL),
|
fSelectedIconLarge(NULL),
|
||||||
fReferences(0),
|
fReferences(0),
|
||||||
fHasReferences(0),
|
fHasReferences(0),
|
||||||
fUseConfigWindow(true)
|
fUseConfigWindow(true),
|
||||||
|
fFolder(NULL)
|
||||||
{
|
{
|
||||||
fSettings = Settings::GetSettings();
|
fSettings = Settings::GetSettings();
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
@@ -151,6 +152,8 @@ bool PrintServerApp::QuitRequested()
|
|||||||
|
|
||||||
bool rc = Inherited::QuitRequested();
|
bool rc = Inherited::QuitRequested();
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
delete fFolder; fFolder = NULL;
|
||||||
|
#if 0
|
||||||
// Find directory containing printer definition nodes
|
// Find directory containing printer definition nodes
|
||||||
BPath path;
|
BPath path;
|
||||||
if (::find_directory(B_USER_PRINTERS_DIRECTORY, &path) == B_OK) {
|
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);
|
::watch_node(&nref, B_STOP_WATCHING, be_app_messenger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Release all printers
|
// Release all printers
|
||||||
Printer* printer;
|
Printer* printer;
|
||||||
@@ -195,18 +199,28 @@ void PrintServerApp::Release() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrintServerApp::RegisterPrinter(BDirectory* printer) {
|
void PrintServerApp::RegisterPrinter(BDirectory* printer) {
|
||||||
BString transport, address, connection;
|
BString transport, address, connection, state;
|
||||||
|
|
||||||
printer->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT, &transport);
|
if (printer->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT, &transport) == B_OK &&
|
||||||
printer->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT_ADDR, &address);
|
printer->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT_ADDR, &address) == B_OK &&
|
||||||
printer->ReadAttrString(PSRV_PRINTER_ATTR_CNX, &connection);
|
printer->ReadAttrString(PSRV_PRINTER_ATTR_CNX, &connection) == B_OK &&
|
||||||
|
printer->ReadAttrString(PSRV_PRINTER_ATTR_STATE, &state) == B_OK &&
|
||||||
|
state == "free") {
|
||||||
|
|
||||||
BAutolock lock(gLock);
|
BAutolock lock(gLock);
|
||||||
if (lock.IsLocked()) {
|
if (lock.IsLocked()) {
|
||||||
Resource* r = fResourceManager.Allocate(transport.String(), address.String(), connection.String());
|
// check if printer is already registered
|
||||||
Printer* p = new Printer(printer, r);
|
node_ref node;
|
||||||
AddHandler(p);
|
Printer* p;
|
||||||
Acquire();
|
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;
|
void PrintServerApp::EntryCreated(node_ref* node, entry_ref* entry) {
|
||||||
dev_t device;
|
BEntry printer(entry);
|
||||||
ino_t node;
|
if (printer.InitCheck() == B_OK && printer.IsDirectory()) {
|
||||||
Printer* printer;
|
BDirectory dir(&printer);
|
||||||
if (msg->FindInt32("opcode", &opcode) == B_OK && opcode == B_ENTRY_REMOVED &&
|
if (dir.InitCheck() == B_OK) RegisterPrinter(&dir);
|
||||||
msg->FindInt32("device", &device) == B_OK &&
|
}
|
||||||
msg->FindInt64("node", &node) == B_OK &&
|
}
|
||||||
(printer = Printer::Find(device, node)) != NULL) {
|
|
||||||
|
void PrintServerApp::EntryRemoved(node_ref* node) {
|
||||||
|
Printer* printer = Printer::Find(node);
|
||||||
|
if (printer) {
|
||||||
if (printer == fDefaultPrinter) fDefaultPrinter = NULL;
|
if (printer == fDefaultPrinter) fDefaultPrinter = NULL;
|
||||||
UnregisterPrinter(printer);
|
UnregisterPrinter(printer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintServerApp::AttributeChanged(node_ref* node) {
|
||||||
|
BDirectory printer(node);
|
||||||
|
if (printer.InitCheck() == B_OK) {
|
||||||
|
RegisterPrinter(&printer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// SetupPrinterList
|
// 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
|
// If we scanned all entries successfully
|
||||||
node_ref nref;
|
node_ref nref;
|
||||||
if (rc == B_ENTRY_NOT_FOUND &&
|
if (rc == B_ENTRY_NOT_FOUND &&
|
||||||
@@ -288,6 +315,7 @@ status_t PrintServerApp::SetupPrinterList()
|
|||||||
// Get node to watch
|
// Get node to watch
|
||||||
rc = ::watch_node(&nref, B_WATCH_DIRECTORY, be_app_messenger);
|
rc = ::watch_node(&nref, B_WATCH_DIRECTORY, be_app_messenger);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,10 +356,6 @@ PrintServerApp::MessageReceived(BMessage* msg)
|
|||||||
case B_EXECUTE_PROPERTY:
|
case B_EXECUTE_PROPERTY:
|
||||||
HandleScriptingCommand(msg);
|
HandleScriptingCommand(msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_NODE_MONITOR:
|
|
||||||
HandleRemovedPrinter(msg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Inherited::MessageReceived(msg);
|
Inherited::MessageReceived(msg);
|
||||||
@@ -378,7 +402,6 @@ PrintServerApp::CreatePrinter(const char* printerName, const char* driverName,
|
|||||||
// Store the settings in its attributes
|
// Store the settings in its attributes
|
||||||
printer.WriteAttr(PSRV_PRINTER_ATTR_PRT_NAME, B_STRING_TYPE, 0, printerName, ::strlen(printerName)+1);
|
printer.WriteAttr(PSRV_PRINTER_ATTR_PRT_NAME, B_STRING_TYPE, 0, printerName, ::strlen(printerName)+1);
|
||||||
printer.WriteAttr(PSRV_PRINTER_ATTR_DRV_NAME, B_STRING_TYPE, 0, driverName, ::strlen(driverName)+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, 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_TRANSPORT_ADDR, B_STRING_TYPE, 0, transportPath,::strlen(transportPath)+1);
|
||||||
printer.WriteAttr(PSRV_PRINTER_ATTR_CNX, B_STRING_TYPE, 0, connection, ::strlen(connection)+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();
|
entry.Remove();
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// where noted, are licensed under the MIT License, and have been written
|
||||||
// and are:
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
#include "FolderWatcher.h"
|
||||||
|
|
||||||
class PrintServerApp;
|
class PrintServerApp;
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ extern BLocker* gLock;
|
|||||||
// Application class for print_server.
|
// Application class for print_server.
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
class Printer;
|
class Printer;
|
||||||
class PrintServerApp : public BApplication
|
class PrintServerApp : public BApplication, public FolderListener
|
||||||
{
|
{
|
||||||
typedef BApplication Inherited;
|
typedef BApplication Inherited;
|
||||||
public:
|
public:
|
||||||
@@ -93,8 +94,11 @@ private:
|
|||||||
|
|
||||||
void RegisterPrinter(BDirectory* node);
|
void RegisterPrinter(BDirectory* node);
|
||||||
void UnregisterPrinter(Printer* printer);
|
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 StoreDefaultPrinter();
|
||||||
status_t RetrieveDefaultPrinter();
|
status_t RetrieveDefaultPrinter();
|
||||||
|
|
||||||
@@ -109,6 +113,7 @@ private:
|
|||||||
sem_id fHasReferences;
|
sem_id fHasReferences;
|
||||||
Settings*fSettings;
|
Settings*fSettings;
|
||||||
bool fUseConfigWindow;
|
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);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// where noted, are licensed under the MIT License, and have been written
|
// where noted, are licensed under the MIT License, and have been written
|
||||||
// and are:
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
|||||||
@@ -55,6 +55,23 @@
|
|||||||
#include <StorageKit.h>
|
#include <StorageKit.h>
|
||||||
#include <SupportDefs.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* (*config_func_t)(BNode*, const BMessage*);
|
||||||
typedef BMessage* (*take_job_func_t)(BFile*, 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;
|
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
|
// Look in list to find printer definition
|
||||||
for (int32 idx=0; idx < sPrinters.CountItems(); idx++) {
|
for (int32 idx=0; idx < sPrinters.CountItems(); idx++) {
|
||||||
Printer* printer = sPrinters.ItemAt(idx);
|
Printer* printer = sPrinters.ItemAt(idx);
|
||||||
node_ref ref;
|
printer->SpoolDir()->GetNodeRef(&n);
|
||||||
printer->SpoolDir()->GetNodeRef(&ref);
|
if (n == *node) return printer;
|
||||||
if (ref.device == dev && ref.node == node) return printer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// None found, so return NULL
|
// None found, so return NULL
|
||||||
@@ -132,7 +149,7 @@ int32 Printer::CountPrinters()
|
|||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
Printer::Printer(const BDirectory* node, Resource* res)
|
Printer::Printer(const BDirectory* node, Resource* res)
|
||||||
: Inherited(B_EMPTY_STRING),
|
: Inherited(B_EMPTY_STRING),
|
||||||
fPrinter(*node),
|
fPrinter(gLock, be_app, *node),
|
||||||
fResource(res),
|
fResource(res),
|
||||||
fSinglePrintThread(true),
|
fSinglePrintThread(true),
|
||||||
fJob(NULL),
|
fJob(NULL),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// where noted, are licensed under the MIT License, and have been written
|
// where noted, are licensed under the MIT License, and have been written
|
||||||
// and are:
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -55,6 +55,14 @@ class Printer;
|
|||||||
// OpenTracker shared sources
|
// OpenTracker shared sources
|
||||||
#include "ObjectList.h"
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
class SpoolFolder : public Folder {
|
||||||
|
protected:
|
||||||
|
void Notify(Job* job, int kind);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SpoolFolder(BLocker* locker, BLooper* looper, const BDirectory& spoolDir);
|
||||||
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
// Printer
|
// Printer
|
||||||
//
|
//
|
||||||
@@ -71,7 +79,7 @@ public:
|
|||||||
|
|
||||||
// Static helper functions
|
// Static helper functions
|
||||||
static Printer* Find(const BString& name);
|
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 Printer* At(int32 idx);
|
||||||
static void Remove(Printer* printer);
|
static void Remove(Printer* printer);
|
||||||
static int32 CountPrinters();
|
static int32 CountPrinters();
|
||||||
@@ -102,11 +110,11 @@ private:
|
|||||||
status_t LoadPrinterAddon(image_id& id);
|
status_t LoadPrinterAddon(image_id& id);
|
||||||
void AddCurrentPrinter(BMessage* m);
|
void AddCurrentPrinter(BMessage* m);
|
||||||
|
|
||||||
Folder fPrinter; // the printer spooling directory
|
|
||||||
Resource* fResource; // the resource required for processing a print job
|
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
|
bool fSinglePrintThread; // is printer add-on allowed to process multiple print job at once
|
||||||
Job* fJob; // the next job to process
|
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
|
bool fAbort; // stop processing
|
||||||
|
|
||||||
static BObjectList<Printer> sPrinters;
|
static BObjectList<Printer> sPrinters;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// where noted, are licensed under the MIT License, and have been written
|
// where noted, are licensed under the MIT License, and have been written
|
||||||
// and are:
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// 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