Write print job to spool file. Not tested under Haiku. Seems to work fine with a simple R5 test application.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19030 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -66,7 +66,7 @@
|
|||||||
#define PSRV_JOB_STATUS_WAITING "Waiting"
|
#define PSRV_JOB_STATUS_WAITING "Waiting"
|
||||||
#define PSRV_JOB_STATUS_PROCESSING "Processing"
|
#define PSRV_JOB_STATUS_PROCESSING "Processing"
|
||||||
#define PSRV_JOB_STATUS_FAILED "Failed"
|
#define PSRV_JOB_STATUS_FAILED "Failed"
|
||||||
#define PSRV_JOB_STATUS_COMPLETED "Completed"
|
#define PSRV_JOB_STATUS_COMPLETED "Completed"
|
||||||
|
|
||||||
// printer attributes
|
// printer attributes
|
||||||
#define PSRV_PRINTER_ATTR_DRV_NAME "Driver Name"
|
#define PSRV_PRINTER_ATTR_DRV_NAME "Driver Name"
|
||||||
@@ -79,19 +79,23 @@
|
|||||||
#define PSRV_PRINTER_ATTR_PNP "_PNP"
|
#define PSRV_PRINTER_ATTR_PNP "_PNP"
|
||||||
#define PSRV_PRINTER_ATTR_MDL "_MDL"
|
#define PSRV_PRINTER_ATTR_MDL "_MDL"
|
||||||
|
|
||||||
// job settings fields
|
// printer name
|
||||||
#define PSRV_FIELD_CURRENT_PRINTER "current_printer"
|
#define PSRV_FIELD_CURRENT_PRINTER "current_printer"
|
||||||
|
|
||||||
|
// page settings fields
|
||||||
#define PSRV_FIELD_XRES "xres"
|
#define PSRV_FIELD_XRES "xres"
|
||||||
#define PSRV_FIELD_YRES "yres"
|
#define PSRV_FIELD_YRES "yres"
|
||||||
#define PSRV_FIELD_PAPER_RECT "paper_rect"
|
#define PSRV_FIELD_PAPER_RECT "paper_rect"
|
||||||
#define PSRV_FIELD_PRINTABLE_RECT "printable_rect"
|
#define PSRV_FIELD_PRINTABLE_RECT "printable_rect"
|
||||||
#define PSRV_FIELD_FIRST_PAGE "first_page"
|
|
||||||
#define PSRV_FIELD_LAST_PAGE "last_page"
|
|
||||||
|
|
||||||
// optional job settings field
|
// optional page settings field
|
||||||
#define PSRV_FIELD_ORIENTATION "orientation"
|
#define PSRV_FIELD_ORIENTATION "orientation"
|
||||||
#define PSRV_FIELD_COPIES "copies"
|
#define PSRV_FIELD_COPIES "copies"
|
||||||
#define PSRV_FIELD_SCALE "scale"
|
#define PSRV_FIELD_SCALE "scale"
|
||||||
#define PSRV_FIELD_QUALITY "quality"
|
#define PSRV_FIELD_QUALITY "quality"
|
||||||
|
|
||||||
|
// job settings fields
|
||||||
|
#define PSRV_FIELD_FIRST_PAGE "first_page"
|
||||||
|
#define PSRV_FIELD_LAST_PAGE "last_page"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+311
-191
@@ -5,8 +5,11 @@
|
|||||||
* Authors:
|
* Authors:
|
||||||
I.R. Adema
|
I.R. Adema
|
||||||
Stefano Ceccherini ([email protected])
|
Stefano Ceccherini ([email protected])
|
||||||
|
Michael Pfeiffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO refactor (avoid code duplications, decrease method sizes)
|
||||||
|
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
@@ -25,68 +28,175 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
// Summery of spool file format:
|
||||||
|
// See articel "How to Write a BeOS R5 Printer Driver" for description
|
||||||
|
// of spool file format: http://haiku-os.org/node/82
|
||||||
|
|
||||||
|
// print_file_header header
|
||||||
|
// BMessage job_settings
|
||||||
|
// _page_header_ page_header
|
||||||
|
// followed by number_of_pictures:
|
||||||
|
// BPoint where
|
||||||
|
// BRect bounds
|
||||||
|
// BPicture picture
|
||||||
|
// remaining pages start at page_header.next_page of previous page_header
|
||||||
|
|
||||||
// TODO: No clue at the moment
|
|
||||||
// We'll need to find out examining a r5 spool file
|
|
||||||
// Maybe the Print kit team found out already ?
|
|
||||||
struct _page_header_ {
|
struct _page_header_ {
|
||||||
char padding[52];
|
int32 number_of_pictures;
|
||||||
|
off_t next_page;
|
||||||
|
int32 reserved[10];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static BMessenger *sPrintServer = NULL;
|
static status_t GetPrinterServerMessenger(BMessenger& messenger)
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
EnsureValidMessenger()
|
|
||||||
{
|
{
|
||||||
if (sPrintServer == NULL)
|
messenger = BMessenger(PSRV_SIGNATURE_TYPE);
|
||||||
sPrintServer = new BMessenger;
|
return messenger.IsValid() ? B_OK : B_ERROR;
|
||||||
|
|
||||||
if (sPrintServer == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
if (!sPrintServer->IsValid())
|
|
||||||
*sPrintServer = BMessenger(PSRV_SIGNATURE_TYPE);
|
|
||||||
|
|
||||||
return sPrintServer->IsValid() ? B_OK : B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BPrintJob::BPrintJob(const char *job_name)
|
BPrintJob::BPrintJob(const char *job_name)
|
||||||
:
|
:
|
||||||
fPrintJobName(NULL),
|
fPrintJobName(NULL),
|
||||||
fPageNumber(0),
|
fPageNumber(0),
|
||||||
fSpoolFile(NULL),
|
fSpoolFile(NULL),
|
||||||
fError(B_OK),
|
fError(B_ERROR),
|
||||||
fSetupMessage(NULL),
|
fSetupMessage(NULL),
|
||||||
fDefaultSetupMessage(NULL),
|
fDefaultSetupMessage(NULL),
|
||||||
fCurrentPageHeader(NULL)
|
fCurrentPageHeader(NULL)
|
||||||
{
|
{
|
||||||
memset(&fCurrentHeader, 0, sizeof(fCurrentHeader));
|
memset(&fCurrentHeader, 0, sizeof(fCurrentHeader));
|
||||||
if (job_name != NULL)
|
|
||||||
|
if (job_name != NULL) {
|
||||||
fPrintJobName = strdup(job_name);
|
fPrintJobName = strdup(job_name);
|
||||||
|
}
|
||||||
|
|
||||||
fCurrentPageHeader = new _page_header_;
|
fCurrentPageHeader = new _page_header_;
|
||||||
|
if (fCurrentPageHeader != NULL) {
|
||||||
|
memset(fCurrentPageHeader, 0, sizeof(*fCurrentPageHeader));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BPrintJob::~BPrintJob()
|
BPrintJob::~BPrintJob()
|
||||||
{
|
{
|
||||||
free(fPrintJobName);
|
CancelJob();
|
||||||
|
|
||||||
|
if (fPrintJobName != NULL) {
|
||||||
|
free(fPrintJobName);
|
||||||
|
fPrintJobName = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete fDefaultSetupMessage;
|
||||||
|
fDefaultSetupMessage = NULL;
|
||||||
|
|
||||||
|
delete fSetupMessage;
|
||||||
|
fSetupMessage = NULL;
|
||||||
|
|
||||||
delete fCurrentPageHeader;
|
delete fCurrentPageHeader;
|
||||||
|
fCurrentPageHeader = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BPrintJob::ConfigPage()
|
||||||
|
{
|
||||||
|
BMessenger printServer;
|
||||||
|
if (GetPrinterServerMessenger(printServer) != B_OK) {
|
||||||
|
BAlert* alert = new BAlert("Error", "Print Server is not responding.", "OK");
|
||||||
|
alert->Go();
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fSetupMessage == NULL) {
|
||||||
|
LoadDefaultSettings();
|
||||||
|
if (fDefaultSetupMessage == NULL) {
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
fSetupMessage = new BMessage(*fDefaultSetupMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage request(*fSetupMessage);
|
||||||
|
request.what = PSRV_SHOW_PAGE_SETUP;
|
||||||
|
|
||||||
|
BMessage* reply = new BMessage();
|
||||||
|
if (printServer.SendMessage(&request, reply) != B_OK) {
|
||||||
|
delete reply;
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply->what != 'okok') {
|
||||||
|
delete reply;
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete fSetupMessage;
|
||||||
|
fSetupMessage = reply;
|
||||||
|
HandlePageSetup(fSetupMessage);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BPrintJob::ConfigJob()
|
||||||
|
{
|
||||||
|
BMessenger printServer;
|
||||||
|
if (GetPrinterServerMessenger(printServer) != B_OK) {
|
||||||
|
BAlert* alert = new BAlert("Error", "Print Server is not responding.", "OK");
|
||||||
|
alert->Go();
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fSetupMessage == NULL) {
|
||||||
|
LoadDefaultSettings();
|
||||||
|
if (fDefaultSetupMessage == NULL) {
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
fSetupMessage = new BMessage(*fDefaultSetupMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage request(*fSetupMessage);
|
||||||
|
request.what = PSRV_SHOW_PRINT_SETUP;
|
||||||
|
|
||||||
|
BMessage* reply = new BMessage();
|
||||||
|
if (printServer.SendMessage(&request, reply) != B_OK) {
|
||||||
|
delete reply;
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply->what != 'okok') {
|
||||||
|
delete reply;
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete fSetupMessage;
|
||||||
|
fSetupMessage = reply;
|
||||||
|
HandlePrintSetup(fSetupMessage);
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BPrintJob::BeginJob()
|
BPrintJob::BeginJob()
|
||||||
{
|
{
|
||||||
// TODO: this should be improved:
|
if (fSpoolFile != NULL) {
|
||||||
// - Take system printers into account
|
// can not start a new job until it has been commited or cancelled
|
||||||
// - handle the case where the path doesn't exist
|
return;
|
||||||
// - more
|
}
|
||||||
|
if (fCurrentPageHeader == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fSetupMessage == NULL) {
|
||||||
|
// TODO show alert, setup message is required
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create spool file
|
||||||
BPath path;
|
BPath path;
|
||||||
status_t status = find_directory(B_USER_PRINTERS_DIRECTORY, &path);
|
status_t status = find_directory(B_USER_PRINTERS_DIRECTORY, &path);
|
||||||
if (status < B_OK)
|
if (status != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char *printer = GetCurrentPrinterName();
|
char *printer = GetCurrentPrinterName();
|
||||||
@@ -101,108 +211,133 @@ BPrintJob::BeginJob()
|
|||||||
|
|
||||||
path.Append(mangledName);
|
path.Append(mangledName);
|
||||||
|
|
||||||
if (path.InitCheck() < B_OK)
|
if (path.InitCheck() != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fAbort = 0;
|
// TODO fSpoolFileName should store the name only (not path which can be 1024 bytes long)
|
||||||
fPageNumber = 0;
|
|
||||||
|
|
||||||
strncpy(fSpoolFileName, path.Path(), sizeof(fSpoolFileName));
|
strncpy(fSpoolFileName, path.Path(), sizeof(fSpoolFileName));
|
||||||
fSpoolFile = new BFile(fSpoolFileName, B_READ_WRITE|B_CREATE_FILE);
|
fSpoolFile = new BFile(fSpoolFileName, B_READ_WRITE | B_CREATE_FILE);
|
||||||
|
|
||||||
|
if (fSpoolFile->InitCheck() != B_OK) {
|
||||||
|
CancelJob();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add print_file_header
|
||||||
|
// page_count is updated in CommitJob()
|
||||||
|
fCurrentHeader.version = 1 << 16;
|
||||||
|
fCurrentHeader.page_count = 0;
|
||||||
|
|
||||||
|
if (fSpoolFile->Write(&fCurrentHeader, sizeof(fCurrentHeader)) != sizeof(fCurrentHeader)) {
|
||||||
|
CancelJob();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add printer settings message
|
||||||
|
fSetupMessage->RemoveName(PSRV_FIELD_CURRENT_PRINTER);
|
||||||
|
fSetupMessage->AddString(PSRV_FIELD_CURRENT_PRINTER, printer);
|
||||||
AddSetupSpec();
|
AddSetupSpec();
|
||||||
|
|
||||||
|
// prepare page header
|
||||||
|
// number_of_pictures is updated in DrawView()
|
||||||
|
// next_page is updated in SpoolPage()
|
||||||
fCurrentPageHeaderOffset = fSpoolFile->Position();
|
fCurrentPageHeaderOffset = fSpoolFile->Position();
|
||||||
fSpoolFile->Write(fCurrentPageHeader, sizeof(_page_header_));
|
fCurrentPageHeader->number_of_pictures = 0;
|
||||||
|
|
||||||
|
// state variables
|
||||||
|
fAbort = 0;
|
||||||
|
fPageNumber = 0;
|
||||||
|
fError = B_OK;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BPrintJob::CommitJob()
|
BPrintJob::CommitJob()
|
||||||
{
|
{
|
||||||
|
if (fSpoolFile == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (fPageNumber <= 0) {
|
if (fPageNumber <= 0) {
|
||||||
BAlert *alert = new BAlert("Alert", "No Pages to print!", "Okay");
|
BAlert *alert = new BAlert("Alert", "No Pages to print!", "Okay");
|
||||||
alert->Go();
|
alert->Go();
|
||||||
CancelJob();
|
CancelJob();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EnsureValidMessenger() != B_OK)
|
if (fCurrentPageHeader->number_of_pictures > 0) {
|
||||||
return;
|
SpoolPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// update spool file
|
||||||
|
EndLastPage();
|
||||||
|
|
||||||
BMessage *message = new BMessage(PSRV_GET_ACTIVE_PRINTER);
|
// set file attributes
|
||||||
BMessage *reply = new BMessage;
|
|
||||||
|
|
||||||
const char *printerName = NULL;
|
|
||||||
if (sPrintServer->SendMessage(message, reply) < B_OK
|
|
||||||
|| reply->FindString("printer_name", &printerName) < B_OK) {
|
|
||||||
// TODO: Show an alert
|
|
||||||
delete message;
|
|
||||||
delete reply;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete message;
|
|
||||||
delete reply;
|
|
||||||
|
|
||||||
app_info appInfo;
|
app_info appInfo;
|
||||||
be_app->GetAppInfo(&appInfo);
|
be_app->GetAppInfo(&appInfo);
|
||||||
|
const char* printerName = "";
|
||||||
|
fSetupMessage->FindString(PSRV_FIELD_CURRENT_PRINTER, &printerName);
|
||||||
|
|
||||||
fSpoolFile->WriteAttr("_spool/Page Count", B_INT32_TYPE, 0, &fPageNumber, sizeof(int32));
|
fSpoolFile->WriteAttr(PSRV_SPOOL_ATTR_PAGECOUNT, B_INT32_TYPE, 0, &fPageNumber, sizeof(int32));
|
||||||
fSpoolFile->WriteAttr("_spool/Description", B_STRING_TYPE, 0, fPrintJobName, strlen(fPrintJobName) + 1);
|
fSpoolFile->WriteAttr(PSRV_SPOOL_ATTR_DESCRIPTION, B_STRING_TYPE, 0, fPrintJobName, strlen(fPrintJobName) + 1);
|
||||||
fSpoolFile->WriteAttr("_spool/Printer", B_STRING_TYPE, 0, printerName, strlen(printerName) + 1);
|
fSpoolFile->WriteAttr(PSRV_SPOOL_ATTR_PRINTER, B_STRING_TYPE, 0, printerName, strlen(printerName) + 1);
|
||||||
fSpoolFile->WriteAttr("_spool/Status", B_STRING_TYPE, 0, "waiting", strlen("waiting") + 1);
|
fSpoolFile->WriteAttr(PSRV_SPOOL_ATTR_STATUS, B_STRING_TYPE, 0, PSRV_JOB_STATUS_WAITING, strlen(PSRV_JOB_STATUS_WAITING) + 1);
|
||||||
fSpoolFile->WriteAttr("_spool/MimeType", B_STRING_TYPE, 0, appInfo.signature, strlen(appInfo.signature) + 1);
|
fSpoolFile->WriteAttr(PSRV_SPOOL_ATTR_MIMETYPE, B_STRING_TYPE, 0, appInfo.signature, strlen(appInfo.signature) + 1);
|
||||||
|
|
||||||
message = new BMessage(PSRV_PRINT_SPOOLED_JOB);
|
delete fSpoolFile;
|
||||||
reply = new BMessage;
|
fSpoolFile = NULL;
|
||||||
|
fError = B_ERROR;
|
||||||
message->AddString("JobName", fPrintJobName);
|
|
||||||
message->AddString("Spool File", fSpoolFileName);
|
// notify print server
|
||||||
sPrintServer->SendMessage(message, reply);
|
BMessenger printServer;
|
||||||
|
if (GetPrinterServerMessenger(printServer) != B_OK) {
|
||||||
delete message;
|
return;
|
||||||
delete reply;
|
}
|
||||||
|
|
||||||
|
BMessage request(PSRV_PRINT_SPOOLED_JOB);
|
||||||
|
BMessage reply;
|
||||||
|
|
||||||
|
request.AddString("JobName", fPrintJobName);
|
||||||
|
request.AddString("Spool File", fSpoolFileName);
|
||||||
|
printServer.SendMessage(&request, &reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BPrintJob::ConfigJob()
|
|
||||||
{
|
|
||||||
// TODO: Implement
|
|
||||||
|
|
||||||
return ConfigPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BPrintJob::CancelJob()
|
BPrintJob::CancelJob()
|
||||||
{
|
{
|
||||||
|
if (fSpoolFile == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fAbort = 1;
|
fAbort = 1;
|
||||||
BEntry(fSpoolFileName).Remove();
|
BEntry(fSpoolFileName).Remove();
|
||||||
delete fSpoolFile;
|
delete fSpoolFile;
|
||||||
}
|
fSpoolFile = NULL;
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BPrintJob::ConfigPage()
|
|
||||||
{
|
|
||||||
// TODO: Launch config window and get settings from it
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BPrintJob::SpoolPage()
|
BPrintJob::SpoolPage()
|
||||||
{
|
{
|
||||||
NewPage();
|
if (fSpoolFile == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update page header
|
||||||
|
fCurrentPageHeader->next_page = fSpoolFile->Position();
|
||||||
|
fSpoolFile->Seek(fCurrentPageHeaderOffset, SEEK_SET);
|
||||||
|
fSpoolFile->Write(fCurrentPageHeader, sizeof(*fCurrentPageHeader));
|
||||||
|
fSpoolFile->Seek(0, SEEK_END);
|
||||||
|
|
||||||
|
fCurrentPageHeader->number_of_pictures = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BPrintJob::CanContinue()
|
BPrintJob::CanContinue()
|
||||||
{
|
{
|
||||||
// Check if our local error storage is still B_OK
|
// Check if our local error storage is still B_OK
|
||||||
return fError == B_OK && !fAbort;
|
return fError == B_OK && !fAbort;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,14 +348,11 @@ BPrintJob::DrawView(BView *view, BRect rect, BPoint where)
|
|||||||
if (view == NULL)
|
if (view == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: Finish me
|
|
||||||
if (view->LockLooper()) {
|
if (view->LockLooper()) {
|
||||||
BPicture *picture = new BPicture;
|
BPicture picture;
|
||||||
RecurseView(view, where, picture, rect);
|
RecurseView(view, where, &picture, rect);
|
||||||
AddPicture(picture, &rect, where);
|
AddPicture(&picture, &rect, where);
|
||||||
|
|
||||||
view->UnlockLooper();
|
view->UnlockLooper();
|
||||||
delete picture;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,12 +360,11 @@ BPrintJob::DrawView(BView *view, BRect rect, BPoint where)
|
|||||||
BMessage *
|
BMessage *
|
||||||
BPrintJob::Settings()
|
BPrintJob::Settings()
|
||||||
{
|
{
|
||||||
BMessage *message = NULL;
|
if (fSetupMessage == NULL) {
|
||||||
|
return NULL;
|
||||||
if (fSetupMessage != NULL)
|
}
|
||||||
message = new BMessage(*fSetupMessage);
|
|
||||||
|
return new BMessage(*fSetupMessage);
|
||||||
return message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -241,42 +372,37 @@ void
|
|||||||
BPrintJob::SetSettings(BMessage *message)
|
BPrintJob::SetSettings(BMessage *message)
|
||||||
{
|
{
|
||||||
if (message != NULL) {
|
if (message != NULL) {
|
||||||
HandlePageSetup(message);
|
HandlePrintSetup(message);
|
||||||
HandlePrintSetup(message);
|
}
|
||||||
|
delete fSetupMessage;
|
||||||
} else if (fSetupMessage != NULL) {
|
fSetupMessage = message;
|
||||||
delete fSetupMessage;
|
|
||||||
fSetupMessage = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BPrintJob::IsSettingsMessageValid(BMessage *message) const
|
BPrintJob::IsSettingsMessageValid(BMessage *message) const
|
||||||
{
|
{
|
||||||
const char *messageName = NULL;
|
|
||||||
char *printerName = GetCurrentPrinterName();
|
char *printerName = GetCurrentPrinterName();
|
||||||
|
if (printerName == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool result = false;
|
const char *name = NULL;
|
||||||
|
|
||||||
// The passed message is valid if it contains the right printer name.
|
// The passed message is valid if it contains the right printer name.
|
||||||
if (message != NULL
|
bool valid = message != NULL
|
||||||
&& message->FindString("printer_name", &messageName) == B_OK
|
&& message->FindString("printer_name", &name) == B_OK
|
||||||
&& strcmp(printerName, messageName) == 0)
|
&& strcmp(printerName, name) == 0;
|
||||||
result = true;
|
|
||||||
|
|
||||||
free(printerName);
|
free(printerName);
|
||||||
|
|
||||||
return result;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Either SetSettings() or ConfigPage() has to be called prior
|
||||||
|
// to any of the getters otherwise they return undefined values.
|
||||||
BRect
|
BRect
|
||||||
BPrintJob::PaperRect()
|
BPrintJob::PaperRect()
|
||||||
{
|
{
|
||||||
if (fDefaultSetupMessage == NULL)
|
|
||||||
LoadDefaultSettings();
|
|
||||||
|
|
||||||
return fPaperSize;
|
return fPaperSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,9 +410,6 @@ BPrintJob::PaperRect()
|
|||||||
BRect
|
BRect
|
||||||
BPrintJob::PrintableRect()
|
BPrintJob::PrintableRect()
|
||||||
{
|
{
|
||||||
if (fDefaultSetupMessage == NULL)
|
|
||||||
LoadDefaultSettings();
|
|
||||||
|
|
||||||
return fUsableSize;
|
return fUsableSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,29 +417,12 @@ BPrintJob::PrintableRect()
|
|||||||
void
|
void
|
||||||
BPrintJob::GetResolution(int32 *xdpi, int32 *ydpi)
|
BPrintJob::GetResolution(int32 *xdpi, int32 *ydpi)
|
||||||
{
|
{
|
||||||
int32 xres = -1, yres = -1;
|
if (xdpi != NULL) {
|
||||||
|
*xdpi = fXResolution;
|
||||||
const BMessage *message = NULL;
|
|
||||||
|
|
||||||
if (fSetupMessage != NULL)
|
|
||||||
message = fSetupMessage;
|
|
||||||
else {
|
|
||||||
if (fDefaultSetupMessage == NULL)
|
|
||||||
LoadDefaultSettings();
|
|
||||||
message = fDefaultSetupMessage;
|
|
||||||
}
|
}
|
||||||
|
if (ydpi != NULL) {
|
||||||
if (message != NULL) {
|
*ydpi = fYResolution;
|
||||||
if (message->HasInt32(PSRV_FIELD_XRES))
|
|
||||||
message->FindInt32(PSRV_FIELD_XRES, &xres);
|
|
||||||
if (message->HasInt32(PSRV_FIELD_YRES))
|
|
||||||
message->FindInt32(PSRV_FIELD_YRES, &yres);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xdpi != NULL)
|
|
||||||
*xdpi = xres;
|
|
||||||
if (ydpi != NULL)
|
|
||||||
*ydpi = yres;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -337,17 +443,20 @@ BPrintJob::LastPage()
|
|||||||
int32
|
int32
|
||||||
BPrintJob::PrinterType(void *) const
|
BPrintJob::PrinterType(void *) const
|
||||||
{
|
{
|
||||||
if (EnsureValidMessenger() != B_OK)
|
BMessenger printServer;
|
||||||
|
if (GetPrinterServerMessenger(printServer) != B_OK) {
|
||||||
return B_COLOR_PRINTER; // default
|
return B_COLOR_PRINTER; // default
|
||||||
|
}
|
||||||
|
|
||||||
BMessage message(PSRV_GET_ACTIVE_PRINTER);
|
BMessage message(PSRV_GET_ACTIVE_PRINTER);
|
||||||
BMessage reply;
|
BMessage reply;
|
||||||
|
|
||||||
sPrintServer->SendMessage(&message, &reply);
|
printServer.SendMessage(&message, &reply);
|
||||||
|
|
||||||
int32 type = B_COLOR_PRINTER;
|
|
||||||
reply.FindInt32("color", &type);
|
|
||||||
|
|
||||||
|
int32 type;
|
||||||
|
if (reply.FindInt32("color", &type) != B_OK) {
|
||||||
|
return B_COLOR_PRINTER; // default
|
||||||
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,62 +501,61 @@ BPrintJob::MangleName(char *filename)
|
|||||||
void
|
void
|
||||||
BPrintJob::HandlePageSetup(BMessage *setup)
|
BPrintJob::HandlePageSetup(BMessage *setup)
|
||||||
{
|
{
|
||||||
if (fSetupMessage != NULL && setup != fSetupMessage && setup != NULL)
|
setup->FindRect(PSRV_FIELD_PRINTABLE_RECT, &fUsableSize);
|
||||||
delete fSetupMessage;
|
setup->FindRect(PSRV_FIELD_PAPER_RECT, &fPaperSize);
|
||||||
|
|
||||||
if (setup->HasRect(PSRV_FIELD_PRINTABLE_RECT))
|
|
||||||
setup->FindRect(PSRV_FIELD_PRINTABLE_RECT, &fUsableSize);
|
|
||||||
if (setup->HasRect(PSRV_FIELD_PAPER_RECT))
|
|
||||||
setup->FindRect(PSRV_FIELD_PAPER_RECT, &fPaperSize);
|
|
||||||
|
|
||||||
fSetupMessage = setup;
|
// TODO verify data type (taken from libprint)
|
||||||
|
int64 valueInt64;
|
||||||
|
if (setup->FindInt64(PSRV_FIELD_XRES, &valueInt64) == B_OK) {
|
||||||
|
fXResolution = (short)valueInt64;
|
||||||
|
}
|
||||||
|
if (setup->FindInt64(PSRV_FIELD_YRES, &valueInt64) == B_OK) {
|
||||||
|
fYResolution = (short)valueInt64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BPrintJob::HandlePrintSetup(BMessage *message)
|
BPrintJob::HandlePrintSetup(BMessage *message)
|
||||||
{
|
{
|
||||||
if (message->HasRect(PSRV_FIELD_PRINTABLE_RECT))
|
HandlePageSetup(message);
|
||||||
message->FindRect(PSRV_FIELD_PRINTABLE_RECT, &fUsableSize);
|
|
||||||
if (message->HasRect(PSRV_FIELD_PAPER_RECT))
|
bool valid = true;
|
||||||
message->FindRect(PSRV_FIELD_PAPER_RECT, &fPaperSize);
|
if (message->FindInt32(PSRV_FIELD_FIRST_PAGE, &fFirstPage) != B_OK) {
|
||||||
if (message->HasInt32(PSRV_FIELD_FIRST_PAGE))
|
valid = false;
|
||||||
message->FindInt32(PSRV_FIELD_FIRST_PAGE, &fFirstPage);
|
}
|
||||||
if (message->HasInt32(PSRV_FIELD_LAST_PAGE))
|
if (message->FindInt32(PSRV_FIELD_LAST_PAGE, &fLastPage) != B_OK) {
|
||||||
message->FindInt32(PSRV_FIELD_LAST_PAGE, &fLastPage);
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BPrintJob::NewPage()
|
BPrintJob::NewPage()
|
||||||
{
|
{
|
||||||
// TODO: this function could be removed, and its functionality moved
|
// write page header
|
||||||
// to SpoolPage()
|
fCurrentPageHeaderOffset = fSpoolFile->Position();
|
||||||
// TODO: Implement for real
|
fSpoolFile->Write(fCurrentPageHeader, sizeof(*fCurrentPageHeader));
|
||||||
fPageNumber++;
|
fPageNumber ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BPrintJob::EndLastPage()
|
BPrintJob::EndLastPage()
|
||||||
{
|
{
|
||||||
if (fSpoolFile == NULL)
|
fSpoolFile->Seek(0, SEEK_SET);
|
||||||
return;
|
fCurrentHeader.page_count = fPageNumber;
|
||||||
|
// TODO set first_page correctly
|
||||||
fCurrentHeader.page_count++;
|
// fCurrentHeader.first_page = 0;
|
||||||
fSpoolFile->Seek(fCurrentPageHeaderOffset, SEEK_SET);
|
fSpoolFile->Write(&fCurrentHeader, sizeof(fCurrentHeader));}
|
||||||
fSpoolFile->Write(fCurrentPageHeader, sizeof(_page_header_));
|
|
||||||
fSpoolFile->Seek(0, SEEK_END);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BPrintJob::AddSetupSpec()
|
BPrintJob::AddSetupSpec()
|
||||||
{
|
{
|
||||||
if (fSetupMessage != NULL && fSpoolFile != NULL)
|
fSetupMessage->Flatten(fSpoolFile);
|
||||||
fSetupMessage->Flatten(fSpoolFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -457,46 +565,58 @@ BPrintJob::AddPicture(BPicture *picture, BRect *rect, BPoint where)
|
|||||||
ASSERT(picture != NULL);
|
ASSERT(picture != NULL);
|
||||||
ASSERT(fSpoolFile != NULL);
|
ASSERT(fSpoolFile != NULL);
|
||||||
ASSERT(rect != NULL);
|
ASSERT(rect != NULL);
|
||||||
|
|
||||||
|
if (fCurrentPageHeader->number_of_pictures == 0) {
|
||||||
|
NewPage();
|
||||||
|
}
|
||||||
|
fCurrentPageHeader->number_of_pictures ++;
|
||||||
|
|
||||||
fSpoolFile->Write(&where, sizeof(where));
|
fSpoolFile->Write(&where, sizeof(where));
|
||||||
fSpoolFile->Write(rect, sizeof(*rect));
|
fSpoolFile->Write(rect, sizeof(*rect));
|
||||||
picture->Flatten(fSpoolFile);
|
picture->Flatten(fSpoolFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns a copy of the current printer name
|
||||||
|
// or NULL if it ccould not be obtained.
|
||||||
|
// Caller is responsible to free the string using free().
|
||||||
char *
|
char *
|
||||||
BPrintJob::GetCurrentPrinterName() const
|
BPrintJob::GetCurrentPrinterName() const
|
||||||
{
|
{
|
||||||
if (EnsureValidMessenger() != B_OK)
|
BMessenger printServer;
|
||||||
|
if (GetPrinterServerMessenger(printServer)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
BMessage message(PSRV_GET_ACTIVE_PRINTER);
|
BMessage message(PSRV_GET_ACTIVE_PRINTER);
|
||||||
BMessage reply;
|
BMessage reply;
|
||||||
|
|
||||||
const char *printerName = NULL;
|
const char *printerName = NULL;
|
||||||
|
|
||||||
if (sPrintServer->SendMessage(&message, &reply) == B_OK)
|
if (printServer.SendMessage(&message, &reply) == B_OK) {
|
||||||
reply.FindString("printer_name", &printerName);
|
reply.FindString("printer_name", &printerName);
|
||||||
|
}
|
||||||
return printerName != NULL ? strdup(printerName) : NULL;
|
if (printerName == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return strdup(printerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BPrintJob::LoadDefaultSettings()
|
BPrintJob::LoadDefaultSettings()
|
||||||
{
|
{
|
||||||
if (EnsureValidMessenger() != B_OK)
|
BMessenger printServer;
|
||||||
|
if (GetPrinterServerMessenger(printServer) != B_OK) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BMessage message(PSRV_GET_DEFAULT_SETTINGS);
|
BMessage message(PSRV_GET_DEFAULT_SETTINGS);
|
||||||
BMessage *reply = new BMessage;
|
BMessage *reply = new BMessage;
|
||||||
|
|
||||||
sPrintServer->SendMessage(&message, reply);
|
printServer.SendMessage(&message, reply);
|
||||||
|
|
||||||
if (reply->HasRect(PSRV_FIELD_PAPER_RECT))
|
HandlePrintSetup(reply);
|
||||||
reply->FindRect(PSRV_FIELD_PAPER_RECT, &fPaperSize);
|
|
||||||
if (reply->HasRect(PSRV_FIELD_PRINTABLE_RECT))
|
|
||||||
reply->FindRect(PSRV_FIELD_PRINTABLE_RECT, &fUsableSize);
|
|
||||||
|
|
||||||
delete fDefaultSetupMessage;
|
delete fDefaultSetupMessage;
|
||||||
fDefaultSetupMessage = reply;
|
fDefaultSetupMessage = reply;
|
||||||
|
|||||||
Reference in New Issue
Block a user