* Added Gutenprint printer driver add-on to image.
* This is still work in progress: Printing should work with the following restrictions: - Color printing is untested. - Some configuration options provided by Gutenprint are missing. - Error reporting is missing. - The page margins should at least to increased to 1 cm or 0.4 Inch. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39216 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c0710fb94e
commit
9295cd647f
@ -142,6 +142,7 @@ SYSTEM_ADD_ONS_MEDIA_PLUGINS = $(X86_ONLY)ffmpeg raw_decoder ;
|
||||
SYSTEM_ADD_ONS_PRINT =
|
||||
Canon\ LIPS3\ Compatible
|
||||
Canon\ LIPS4\ Compatible
|
||||
Gutenprint
|
||||
PCL5\ Compatible
|
||||
PCL6\ Compatible
|
||||
PDF\ Writer
|
||||
|
@ -1,6 +1,7 @@
|
||||
SubDir HAIKU_TOP src add-ons print drivers ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons print drivers canon_lips ;
|
||||
SubInclude HAIKU_TOP src add-ons print drivers gutenprint ;
|
||||
SubInclude HAIKU_TOP src add-ons print drivers pcl5 ;
|
||||
SubInclude HAIKU_TOP src add-ons print drivers pcl6 ;
|
||||
SubInclude HAIKU_TOP src add-ons print drivers pdf ;
|
||||
|
84
src/add-ons/print/drivers/gutenprint/GPArray.cpp
Normal file
84
src/add-ons/print/drivers/gutenprint/GPArray.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#include<Debug.h>
|
||||
|
||||
template<typename TYPE>
|
||||
GPArray<TYPE>::GPArray()
|
||||
:
|
||||
fArray(NULL),
|
||||
fSize(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template<typename TYPE>
|
||||
GPArray<TYPE>::~GPArray()
|
||||
{
|
||||
if (fArray != NULL) {
|
||||
for (int i = 0; i < fSize; i ++)
|
||||
delete fArray[i];
|
||||
delete[] fArray;
|
||||
fArray = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename TYPE>
|
||||
void
|
||||
GPArray<TYPE>::SetSize(int size)
|
||||
{
|
||||
ASSERT(fSize == NULL);
|
||||
fArray = new PointerType[size];
|
||||
if (fArray == NULL)
|
||||
return;
|
||||
|
||||
fSize = size;
|
||||
for (int i = 0; i < size; i ++) {
|
||||
fArray[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename TYPE>
|
||||
int
|
||||
GPArray<TYPE>::Size() const
|
||||
{
|
||||
return fSize;
|
||||
}
|
||||
|
||||
|
||||
template<typename TYPE>
|
||||
void
|
||||
GPArray<TYPE>::DecreaseSize()
|
||||
{
|
||||
ASSERT(fArray != NULL);
|
||||
ASSERT(fArray[fSize-1] == NULL);
|
||||
fSize --;
|
||||
}
|
||||
|
||||
template<typename TYPE>
|
||||
TYPE**
|
||||
GPArray<TYPE>::Array()
|
||||
{
|
||||
return fArray;
|
||||
}
|
||||
|
||||
|
||||
template<typename TYPE>
|
||||
TYPE ** const
|
||||
GPArray<TYPE>::Array() const
|
||||
{
|
||||
return fArray;
|
||||
}
|
||||
|
||||
template<typename TYPE>
|
||||
bool
|
||||
GPArray<TYPE>::IsEmpty() const
|
||||
{
|
||||
return fSize == 0;
|
||||
}
|
34
src/add-ons/print/drivers/gutenprint/GPArray.h
Normal file
34
src/add-ons/print/drivers/gutenprint/GPArray.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#ifndef GP_ARRAY_H
|
||||
#define GP_ARRAY_H
|
||||
|
||||
template<typename TYPE>
|
||||
class GPArray
|
||||
{
|
||||
public:
|
||||
typedef TYPE* PointerType;
|
||||
|
||||
GPArray();
|
||||
virtual ~GPArray();
|
||||
|
||||
void SetSize(int size);
|
||||
int Size() const;
|
||||
void DecreaseSize();
|
||||
TYPE** Array();
|
||||
TYPE** const Array() const;
|
||||
bool IsEmpty() const;
|
||||
|
||||
private:
|
||||
TYPE** fArray;
|
||||
int fSize;
|
||||
};
|
||||
|
||||
#include "GPArray.cpp"
|
||||
|
||||
#endif
|
34
src/add-ons/print/drivers/gutenprint/GPBand.cpp
Normal file
34
src/add-ons/print/drivers/gutenprint/GPBand.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#include "GPBand.h"
|
||||
|
||||
GPBand::GPBand(BBitmap* bitmap, BRect validRect, BPoint where)
|
||||
:
|
||||
fBitmap(*bitmap),
|
||||
fValidRect(validRect),
|
||||
fWhere(where)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
GPBand::GetBoundingRectangle() const
|
||||
{
|
||||
BRect rect = fValidRect;
|
||||
rect.OffsetTo(fWhere);
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GPBand::ContainsLine(int line) const
|
||||
{
|
||||
int y = line - (int)fWhere.y;
|
||||
return 0 <= y && y <= fValidRect.IntegerHeight();
|
||||
}
|
28
src/add-ons/print/drivers/gutenprint/GPBand.h
Normal file
28
src/add-ons/print/drivers/gutenprint/GPBand.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#ifndef GP_BAND_H
|
||||
#define GP_BAND_H
|
||||
|
||||
|
||||
#include <Bitmap.h>
|
||||
|
||||
|
||||
class GPBand
|
||||
{
|
||||
public:
|
||||
GPBand(BBitmap* bitmap, BRect validRect, BPoint where);
|
||||
|
||||
BRect GetBoundingRectangle() const;
|
||||
bool ContainsLine(int line) const;
|
||||
|
||||
BBitmap fBitmap;
|
||||
BRect fValidRect;
|
||||
BPoint fWhere;
|
||||
};
|
||||
|
||||
#endif
|
229
src/add-ons/print/drivers/gutenprint/GPBinding.cpp
Normal file
229
src/add-ons/print/drivers/gutenprint/GPBinding.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#include "GPBinding.h"
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include <gutenprint/gutenprint.h>
|
||||
|
||||
|
||||
#include "GPCapabilityExtractor.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
// printer manufacturer
|
||||
static const char* kManufacturerId = "id";
|
||||
static const char* kManufacturerDisplayName = "name";
|
||||
|
||||
// printer model
|
||||
static const char* kModelDisplayName = "model";
|
||||
static const char* kModelDriver = "driver";
|
||||
|
||||
|
||||
GPBinding::GPBinding()
|
||||
:
|
||||
fInitialized(false),
|
||||
fOutputStream(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
GPBinding::~GPBinding()
|
||||
{
|
||||
DeleteBands();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GPBinding::GetPrinterManufacturers(BMessage& manufacturers)
|
||||
{
|
||||
InitGutenprint();
|
||||
|
||||
list<string> ids;
|
||||
set<string> manufacturerSet;
|
||||
|
||||
for (int i = 0; i < stp_printer_model_count(); i ++) {
|
||||
const stp_printer_t* printer = stp_get_printer_by_index(i);
|
||||
string manufacturer = stp_printer_get_manufacturer(printer);
|
||||
|
||||
// ignore unnamed manufacturers
|
||||
if (manufacturer == "")
|
||||
continue;
|
||||
|
||||
// add manufacturer only once
|
||||
if (manufacturerSet.find(manufacturer) != manufacturerSet.end())
|
||||
continue;
|
||||
|
||||
manufacturerSet.insert(manufacturer);
|
||||
|
||||
ids.push_back(manufacturer);
|
||||
}
|
||||
|
||||
ids.sort();
|
||||
|
||||
list<string>::iterator it = ids.begin();
|
||||
for (; it != ids.end(); it ++) {
|
||||
string manufacturer = *it;
|
||||
const char* id = manufacturer.c_str();
|
||||
const char* name = manufacturer.c_str();
|
||||
AddManufacturer(manufacturers, id, name);
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GPBinding::ExtractManufacturer(const BMessage& manufacturers, int32 index,
|
||||
BString& id, BString& displayName)
|
||||
{
|
||||
if (manufacturers.FindString(kManufacturerId, index, &id) != B_OK)
|
||||
return false;
|
||||
if (manufacturers.FindString(kManufacturerDisplayName, index, &displayName)
|
||||
!= B_OK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPBinding::AddManufacturer(BMessage& manufacturers, const char* id,
|
||||
const char* displayName)
|
||||
{
|
||||
manufacturers.AddString(kManufacturerId, id);
|
||||
manufacturers.AddString(kManufacturerDisplayName, displayName);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GPBinding::GetPrinterModels(const char* manufacturer, BMessage& models)
|
||||
{
|
||||
for (int i = 0; i < stp_printer_model_count(); i ++) {
|
||||
const stp_printer_t* printer = stp_get_printer_by_index(i);
|
||||
if (strcmp(manufacturer, stp_printer_get_manufacturer(printer)) != 0)
|
||||
continue;
|
||||
|
||||
const char* displayName = stp_printer_get_long_name(printer);
|
||||
const char* driver = stp_printer_get_driver(printer);
|
||||
AddModel(models, displayName, driver);
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GPBinding::ExtractModel(const BMessage& models, int32 index, BString& displayName,
|
||||
BString& driver)
|
||||
{
|
||||
if (models.FindString(kModelDisplayName, index, &displayName) != B_OK)
|
||||
return false;
|
||||
if (models.FindString(kModelDriver, index, &driver) != B_OK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPBinding::AddModel(BMessage& models, const char* displayName, const char* driver)
|
||||
{
|
||||
models.AddString(kModelDisplayName, displayName);
|
||||
models.AddString(kModelDriver, driver);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GPBinding::GetCapabilities(const char* driver, GPCapabilities* capabilities)
|
||||
{
|
||||
InitGutenprint();
|
||||
const stp_printer_t* printer = stp_get_printer_by_driver(driver);
|
||||
if (printer == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
GPCapabilityExtractor extractor(capabilities);
|
||||
extractor.Visit(printer);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GPBinding::BeginJob(GPJobConfiguration* configuration,
|
||||
OutputStream* outputStream)
|
||||
throw(TransportException)
|
||||
{
|
||||
fOutputStream = outputStream;
|
||||
fJob.SetApplicationName("Gutenprint");
|
||||
fJob.SetConfiguration(configuration);
|
||||
fJob.SetOutputStream(outputStream);
|
||||
|
||||
return fJob.Begin();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPBinding::EndJob() throw(TransportException)
|
||||
{
|
||||
fJob.End();
|
||||
fOutputStream = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPBinding::BeginPage() throw(TransportException)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPBinding::EndPage() throw(TransportException)
|
||||
{
|
||||
status_t status = fJob.PrintPage(fBands);
|
||||
DeleteBands();
|
||||
if (status != B_OK)
|
||||
throw TransportException("I/O Error");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPBinding::AddBitmapToPage(BBitmap* bitmap, BRect validRect, BPoint where)
|
||||
{
|
||||
GPBand* band = new(nothrow) GPBand(bitmap, validRect, where);
|
||||
if (band == NULL) {
|
||||
// TODO report error
|
||||
return;
|
||||
}
|
||||
|
||||
fBands.push_back(band);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPBinding::InitGutenprint()
|
||||
{
|
||||
if (fInitialized)
|
||||
return;
|
||||
fInitialized = true;
|
||||
// TODO make sure this creates no memory leaks,
|
||||
// as there is no "destroy" counter part
|
||||
stp_init();
|
||||
stp_set_output_codeset("UTF-8");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPBinding::DeleteBands()
|
||||
{
|
||||
list<GPBand*>::iterator it = fBands.begin();
|
||||
for (; it != fBands.end(); it ++) {
|
||||
GPBand* band = *it;
|
||||
delete band;
|
||||
}
|
||||
fBands.clear();
|
||||
}
|
63
src/add-ons/print/drivers/gutenprint/GPBinding.h
Normal file
63
src/add-ons/print/drivers/gutenprint/GPBinding.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#ifndef GP_BINDING_H
|
||||
#define GP_BINDING_H
|
||||
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Message.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "GPBand.h"
|
||||
#include "GPJob.h"
|
||||
#include "GPJobConfiguration.h"
|
||||
#include "OutputStream.h"
|
||||
#include "ValidRect.h"
|
||||
|
||||
class GPCapabilities;
|
||||
|
||||
class GPBinding
|
||||
{
|
||||
public:
|
||||
GPBinding();
|
||||
~GPBinding();
|
||||
|
||||
status_t GetPrinterManufacturers(BMessage& manufacturers);
|
||||
bool ExtractManufacturer(const BMessage& manufacturers, int32 index,
|
||||
BString& id, BString& displayName);
|
||||
void AddManufacturer(BMessage& manufacturers, const char* id,
|
||||
const char* name);
|
||||
|
||||
status_t GetPrinterModels(const char* manufacturer, BMessage& models);
|
||||
bool ExtractModel(const BMessage& models, int32 index,
|
||||
BString& displayName, BString& driver);
|
||||
void AddModel(BMessage& models, const char* displayName,
|
||||
const char* driver);
|
||||
|
||||
status_t GetCapabilities(const char* driver,
|
||||
GPCapabilities* capabilities);
|
||||
|
||||
status_t BeginJob(GPJobConfiguration* configuration,
|
||||
OutputStream* outputStream) throw(TransportException);
|
||||
void EndJob() throw(TransportException);
|
||||
void BeginPage() throw(TransportException);
|
||||
void EndPage() throw(TransportException);
|
||||
void AddBitmapToPage(BBitmap* bitmap, BRect validRect, BPoint where);
|
||||
|
||||
private:
|
||||
void InitGutenprint();
|
||||
void DeleteBands();
|
||||
|
||||
bool fInitialized;
|
||||
OutputStream* fOutputStream;
|
||||
list<GPBand*> fBands;
|
||||
GPJob fJob;
|
||||
};
|
||||
|
||||
#endif
|
124
src/add-ons/print/drivers/gutenprint/GPCapabilities.cpp
Normal file
124
src/add-ons/print/drivers/gutenprint/GPCapabilities.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
|
||||
*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
|
||||
|
||||
#include "GPCapabilities.h"
|
||||
|
||||
#include "GPBinding.h"
|
||||
#include "GPData.h"
|
||||
#include "PrinterData.h"
|
||||
|
||||
|
||||
GPCapabilities::GPCapabilities(const PrinterData* printer_data)
|
||||
:
|
||||
PrinterCap(printer_data)
|
||||
{
|
||||
InitCapabilitiesFromGutenprint();
|
||||
}
|
||||
|
||||
|
||||
GPCapabilities::~GPCapabilities()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
GPCapabilities::countCap(CapID category) const
|
||||
{
|
||||
const GPArray<struct BaseCap>* capabilities;
|
||||
|
||||
switch (category) {
|
||||
case kPaper:
|
||||
return fPageSizes.Size();
|
||||
case kPaperSource:
|
||||
return fInputSlots.Size();
|
||||
case kResolution:
|
||||
return fResolutions.Size();
|
||||
case kColor:
|
||||
return fPrintingModes.Size();
|
||||
case kDriverSpecificCapabilities:
|
||||
return fDriverSpecificCategories.Size();
|
||||
|
||||
default:
|
||||
capabilities = DriverSpecificCapabilities(category);
|
||||
if (capabilities == NULL)
|
||||
return 0;
|
||||
return capabilities->Size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const BaseCap**
|
||||
GPCapabilities::enumCap(CapID category) const
|
||||
{
|
||||
typedef const BaseCap** ArrayType;
|
||||
const GPArray<struct BaseCap>* capabilities;
|
||||
|
||||
switch (category) {
|
||||
case kPaper:
|
||||
return (ArrayType)fPageSizes.Array();
|
||||
case kPaperSource:
|
||||
return (ArrayType)fInputSlots.Array();
|
||||
case kResolution:
|
||||
return (ArrayType)fResolutions.Array();
|
||||
case kColor:
|
||||
return (ArrayType)fPrintingModes.Array();
|
||||
case kDriverSpecificCapabilities:
|
||||
return (ArrayType)fDriverSpecificCategories.Array();
|
||||
|
||||
default:
|
||||
capabilities = DriverSpecificCapabilities(category);
|
||||
if (capabilities == NULL)
|
||||
return NULL;
|
||||
return (ArrayType)capabilities->Array();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GPCapabilities::isSupport(CapID category) const
|
||||
{
|
||||
switch (category) {
|
||||
case kPaper:
|
||||
case kPaperSource:
|
||||
case kResolution:
|
||||
case kColor:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return countCap(category) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GPCapabilities::InitCapabilitiesFromGutenprint()
|
||||
{
|
||||
const GPData* data = dynamic_cast<const GPData*>(getPrinterData());
|
||||
ASSERT(data != NULL);
|
||||
// capabilities are available only after printer model
|
||||
// has been selected
|
||||
if (data->fGutenprintDriverName == "")
|
||||
return;
|
||||
|
||||
|
||||
GPBinding binding;
|
||||
binding.GetCapabilities(data->fGutenprintDriverName.String(), this);
|
||||
}
|
||||
|
||||
|
||||
const GPArray<struct BaseCap>*
|
||||
GPCapabilities::DriverSpecificCapabilities(int32 category) const
|
||||
{
|
||||
DriverSpecificCapabilitiesType::const_iterator it =
|
||||
fDriverSpecificCapabilities.find(category);
|
||||
if (it == fDriverSpecificCapabilities.end())
|
||||
return NULL;
|
||||
return &it->second;
|
||||
}
|
||||
|
51
src/add-ons/print/drivers/gutenprint/GPCapabilities.h
Normal file
51
src/add-ons/print/drivers/gutenprint/GPCapabilities.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
|
||||
*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*
|
||||
*/
|
||||
#ifndef GP_CAPABILITIES_H
|
||||
#define GP_CAPABILITIES_H
|
||||
|
||||
|
||||
#include "PrinterCap.h"
|
||||
|
||||
#include "GPArray.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
class GPCapabilityExtractor;
|
||||
|
||||
class GPCapabilities : public PrinterCap {
|
||||
public:
|
||||
GPCapabilities(const PrinterData* printer_data);
|
||||
~GPCapabilities();
|
||||
|
||||
virtual int countCap(CapID) const;
|
||||
virtual bool isSupport(CapID) const;
|
||||
virtual const BaseCap **enumCap(CapID) const;
|
||||
|
||||
private:
|
||||
void InitCapabilitiesFromGutenprint();
|
||||
const GPArray<struct BaseCap>*
|
||||
DriverSpecificCapabilities(int32 category) const;
|
||||
|
||||
GPArray<struct BaseCap> fPageSizes;
|
||||
GPArray<struct BaseCap> fResolutions;
|
||||
GPArray<struct BaseCap> fInputSlots;
|
||||
GPArray<struct BaseCap> fPrintingModes;
|
||||
|
||||
GPArray<struct BaseCap> fDriverSpecificCategories;
|
||||
|
||||
typedef map<int32, GPArray<struct BaseCap> > DriverSpecificCapabilitiesType;
|
||||
DriverSpecificCapabilitiesType fDriverSpecificCapabilities;
|
||||
|
||||
friend class GPCapabilityExtractor;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
255
src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.cpp
Normal file
255
src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.cpp
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#include "GPCapabilityExtractor.h"
|
||||
|
||||
#include "PrinterCap.h"
|
||||
|
||||
|
||||
const char* kInputSlot = "InputSlot";
|
||||
|
||||
|
||||
#if 1
|
||||
#define GP_PRINT(...) \
|
||||
fprintf(stderr, __VA_ARGS__)
|
||||
#else
|
||||
#define GP_PRINT(...) \
|
||||
{}
|
||||
#endif
|
||||
|
||||
GPCapabilityExtractor::GPCapabilityExtractor(GPCapabilities* capabilities)
|
||||
:
|
||||
fState(kIgnoreParameter),
|
||||
fCapabilities(capabilities),
|
||||
fIndex(0),
|
||||
fNextDriverSpecificCategoryID(PrinterCap::kDriverSpecificCapabilitiesBegin)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GPCapabilityExtractor::BeginParameter(const char* name, const char* displayName,
|
||||
stp_parameter_class_t parameterClass)
|
||||
{
|
||||
fState = kIgnoreParameter;
|
||||
if (strcmp(kPageSize, name) == 0) {
|
||||
GP_PRINT("Supported parameter: %s\n", name);
|
||||
fState = kExtractPageSizeParameter;
|
||||
} else if (strcmp(kResolution, name) == 0) {
|
||||
GP_PRINT("Supported parameter: %s\n", name);
|
||||
fState = kExtractResolutionParameter;
|
||||
} else if (strcmp(kInputSlot, name) == 0) {
|
||||
GP_PRINT("Supported parameter: %s\n", name);
|
||||
fState = kExtractInputSlotParameter;
|
||||
} else if (strcmp(kPrintingMode, name) == 0) {
|
||||
GP_PRINT("Supported parameter: %s\n", name);
|
||||
fState = kExtractPrintingModeParameter;
|
||||
} else {
|
||||
GP_PRINT("Parameter: %s - %s\n", name, displayName);
|
||||
bool recordParameter = parameterClass == STP_PARAMETER_CLASS_FEATURE ||
|
||||
parameterClass == STP_PARAMETER_CLASS_OUTPUT;
|
||||
if (!recordParameter)
|
||||
return false;
|
||||
|
||||
fState = kExtractParameter;
|
||||
DriverSpecificCap* capability = new DriverSpecificCap(displayName,
|
||||
fNextDriverSpecificCategoryID, DriverSpecificCap::kList);
|
||||
capability->fKey = name;
|
||||
|
||||
fDriverSpecificCategories.push_back(capability);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPCapabilityExtractor::DefaultStringParameter(const char* name,
|
||||
const char* key)
|
||||
{
|
||||
if (key == NULL)
|
||||
fDefaultKey = "";
|
||||
else
|
||||
fDefaultKey = key;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPCapabilityExtractor::StringParameterSize(const char* name, int size)
|
||||
{
|
||||
fIndex = 0;
|
||||
|
||||
switch (fState) {
|
||||
case kExtractPageSizeParameter:
|
||||
fCapabilities->fPageSizes.SetSize(size);
|
||||
break;
|
||||
|
||||
case kExtractResolutionParameter:
|
||||
fCapabilities->fResolutions.SetSize(size);
|
||||
break;
|
||||
|
||||
case kExtractInputSlotParameter:
|
||||
fCapabilities->fInputSlots.SetSize(size);
|
||||
break;
|
||||
|
||||
case kExtractPrintingModeParameter:
|
||||
fCapabilities->fPrintingModes.SetSize(size);
|
||||
break;
|
||||
|
||||
case kExtractParameter:
|
||||
fState = kExtractListParameter;
|
||||
fCapabilities->fDriverSpecificCapabilities[
|
||||
fNextDriverSpecificCategoryID].SetSize(size);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPCapabilityExtractor::StringParameter(const char* name, const char* key,
|
||||
const char* displayName)
|
||||
{
|
||||
bool isDefault = fDefaultKey == key;
|
||||
BaseCap* capability;
|
||||
|
||||
switch (fState) {
|
||||
case kExtractResolutionParameter:
|
||||
GP_PRINT("GPCapabilityExtractor: ResolutionParameter expected\n");
|
||||
break;
|
||||
|
||||
case kExtractInputSlotParameter:
|
||||
capability = new PaperSourceCap(displayName, isDefault,
|
||||
static_cast<JobData::PaperSource>(fIndex));
|
||||
AddCapability(fCapabilities->fInputSlots, capability, key);
|
||||
break;
|
||||
|
||||
case kExtractPrintingModeParameter:
|
||||
capability = new ColorCap(displayName, isDefault,
|
||||
static_cast<JobData::Color>(fIndex));
|
||||
AddCapability(fCapabilities->fPrintingModes, capability, key);
|
||||
break;
|
||||
|
||||
case kExtractListParameter:
|
||||
capability = new ListItemCap(displayName, isDefault, fIndex);
|
||||
AddCapability(fCapabilities->fDriverSpecificCapabilities[
|
||||
fNextDriverSpecificCategoryID], capability, key);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPCapabilityExtractor::ResolutionParameter(const char* name, const char* key,
|
||||
const char* displayName, int x, int y)
|
||||
{
|
||||
bool isDefault = fDefaultKey == key;
|
||||
BaseCap* capability;
|
||||
|
||||
switch (fState) {
|
||||
case kExtractResolutionParameter:
|
||||
if (x <= 0 || y <= 0) {
|
||||
// usually this is the entry for the "Default" resolution
|
||||
// if we want to show this in the UI, we need a way to
|
||||
// determine the resolution (x and y) for it, because
|
||||
// libprint needs it for rasterization
|
||||
fCapabilities->fResolutions.DecreaseSize();
|
||||
break;
|
||||
}
|
||||
|
||||
capability = new ResolutionCap(displayName, isDefault, fIndex,
|
||||
x, y);
|
||||
AddCapability(fCapabilities->fResolutions, capability, key);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPCapabilityExtractor::PageSizeParameter(const char* name, const char* key,
|
||||
const char* displayName, BSize pageSize, BRect imageableArea)
|
||||
{
|
||||
bool isDefault = fDefaultKey == key;
|
||||
BaseCap* capability;
|
||||
|
||||
switch (fState) {
|
||||
case kExtractPageSizeParameter:
|
||||
capability = new PaperCap(displayName, isDefault,
|
||||
static_cast<JobData::Paper>(fIndex),
|
||||
BRect(0, 0, pageSize.width, pageSize.height),
|
||||
imageableArea);
|
||||
AddCapability(fCapabilities->fPageSizes, capability, key);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPCapabilityExtractor::EndParameter(const char* name)
|
||||
{
|
||||
if (fState == kExtractListParameter) {
|
||||
fNextDriverSpecificCategoryID ++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPCapabilityExtractor::EndVisit()
|
||||
{
|
||||
if (fCapabilities->fInputSlots.Size() == 0)
|
||||
AddDefaultInputSlot();
|
||||
SetDriverSpecificCategories();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPCapabilityExtractor::AddDefaultInputSlot()
|
||||
{
|
||||
BeginParameter(kInputSlot, "Input Slot", STP_PARAMETER_CLASS_FEATURE);
|
||||
DefaultStringParameter(kInputSlot, "");
|
||||
StringParameterSize(kInputSlot, 1);
|
||||
StringParameter(kInputSlot, "", "Default");
|
||||
EndParameter(kInputSlot);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPCapabilityExtractor::SetDriverSpecificCategories()
|
||||
{
|
||||
int size = fDriverSpecificCategories.size();
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
fCapabilities->fDriverSpecificCategories.SetSize(size);
|
||||
struct BaseCap** array = fCapabilities->fDriverSpecificCategories.Array();
|
||||
list<DriverSpecificCap*>::iterator it = fDriverSpecificCategories.begin();
|
||||
for (int index = 0; it != fDriverSpecificCategories.end(); it ++,
|
||||
index ++) {
|
||||
array[index] = *it;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GPCapabilityExtractor::AddCapability(GPArray<struct BaseCap>& array,
|
||||
BaseCap* capability, const char* key)
|
||||
{
|
||||
capability->fKey = key;
|
||||
array.Array()[fIndex] = capability;
|
||||
fIndex ++;
|
||||
}
|
63
src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.h
Normal file
63
src/add-ons/print/drivers/gutenprint/GPCapabilityExtractor.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#ifndef GP_CAPABILITY_EXTRACTOR_H
|
||||
#define GP_CAPABILITY_EXTRACTOR_H
|
||||
|
||||
#include "GPParameterVisitor.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "GPCapabilities.h"
|
||||
|
||||
enum GPCapabilityExtractorState {
|
||||
kIgnoreParameter,
|
||||
kExtractPageSizeParameter,
|
||||
kExtractResolutionParameter,
|
||||
kExtractInputSlotParameter,
|
||||
kExtractPrintingModeParameter,
|
||||
kExtractParameter,
|
||||
kExtractListParameter,
|
||||
|
||||
};
|
||||
|
||||
class GPCapabilityExtractor : public GPParameterVisitor
|
||||
{
|
||||
public:
|
||||
GPCapabilityExtractor(GPCapabilities* cap);
|
||||
|
||||
bool BeginParameter(const char* name, const char* displayName,
|
||||
stp_parameter_class_t parameterClass);
|
||||
void DefaultStringParameter(const char* name,
|
||||
const char* key);
|
||||
void StringParameterSize(const char* name, int size);
|
||||
void StringParameter(const char* name, const char* key,
|
||||
const char* displayName);
|
||||
void ResolutionParameter(const char* name, const char* key,
|
||||
const char* displayName, int x, int y);
|
||||
void PageSizeParameter(const char* name, const char* key,
|
||||
const char* displayName, BSize pageSize, BRect imageableArea);
|
||||
void EndParameter(const char* name);
|
||||
void EndVisit();
|
||||
|
||||
protected:
|
||||
void AddDefaultInputSlot();
|
||||
void SetDriverSpecificCategories();
|
||||
void AddCapability(GPArray<struct BaseCap>& array, BaseCap* capability,
|
||||
const char* key);
|
||||
|
||||
private:
|
||||
GPCapabilityExtractorState fState;
|
||||
GPCapabilities* fCapabilities;
|
||||
int fIndex;
|
||||
BString fDefaultKey;
|
||||
|
||||
list<DriverSpecificCap*> fDriverSpecificCategories;
|
||||
int32 fNextDriverSpecificCategoryID;
|
||||
};
|
||||
|
||||
#endif
|
32
src/add-ons/print/drivers/gutenprint/GPData.cpp
Normal file
32
src/add-ons/print/drivers/gutenprint/GPData.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ithamar R. Adema <ithamar.adema@team-embedded.nl>
|
||||
*/
|
||||
|
||||
|
||||
#include "GPData.h"
|
||||
|
||||
#include <Node.h>
|
||||
|
||||
#define PD_PRINTER_DRIVER_ATTRIBUTE "gutenprint:driver-name"
|
||||
|
||||
|
||||
void
|
||||
GPData::load()
|
||||
{
|
||||
PrinterData::load();
|
||||
fNode->ReadAttrString(PD_PRINTER_DRIVER_ATTRIBUTE,
|
||||
&fGutenprintDriverName);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPData::save()
|
||||
{
|
||||
PrinterData::save();
|
||||
fNode->WriteAttrString(PD_PRINTER_DRIVER_ATTRIBUTE,
|
||||
&fGutenprintDriverName);
|
||||
}
|
36
src/add-ons/print/drivers/gutenprint/GPData.h
Normal file
36
src/add-ons/print/drivers/gutenprint/GPData.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ithamar R. Adema <ithamar.adema@team-embedded.nl>
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#ifndef GP_DATA_H
|
||||
#define GP_DATA_H
|
||||
|
||||
|
||||
#include "PrinterData.h"
|
||||
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BNode;
|
||||
|
||||
|
||||
class GPData : public PrinterData {
|
||||
public:
|
||||
GPData(BNode* node)
|
||||
:
|
||||
PrinterData(node)
|
||||
{
|
||||
}
|
||||
|
||||
// PrinterData overrides
|
||||
virtual void load();
|
||||
virtual void save();
|
||||
|
||||
BString fGutenprintDriverName;
|
||||
};
|
||||
|
||||
#endif // PSDATA_H
|
239
src/add-ons/print/drivers/gutenprint/GPDriver.cpp
Normal file
239
src/add-ons/print/drivers/gutenprint/GPDriver.cpp
Normal file
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* GP.cpp
|
||||
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
|
||||
* Copyright 2010 Michael Pfeiffer.
|
||||
*/
|
||||
|
||||
|
||||
#include "GPDriver.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Debug.h>
|
||||
#include <File.h>
|
||||
|
||||
#include "DbgMsg.h"
|
||||
#include "Halftone.h"
|
||||
#include "JobData.h"
|
||||
#include "PackBits.h"
|
||||
#include "GPCapabilities.h"
|
||||
#include "GPData.h"
|
||||
#include "PrinterData.h"
|
||||
#include "UIDriver.h"
|
||||
#include "ValidRect.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
GPDriver::GPDriver(BMessage* msg, PrinterData* printer_data,
|
||||
const PrinterCap* printer_cap)
|
||||
:
|
||||
GraphicsDriver(msg, printer_data, printer_cap)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
GPDriver::Write(const void *buffer, size_t size)
|
||||
throw(TransportException)
|
||||
{
|
||||
writeSpoolData(buffer, size);
|
||||
}
|
||||
|
||||
bool
|
||||
GPDriver::startDoc()
|
||||
{
|
||||
try {
|
||||
const GPData* data = dynamic_cast<const GPData*>(getPrinterData());
|
||||
ASSERT(data != NULL);
|
||||
fConfiguration.fDriver = data->fGutenprintDriverName;
|
||||
|
||||
SetParameter(fConfiguration.fPageSize, PrinterCap::kPaper,
|
||||
getJobData()->getPaper());
|
||||
|
||||
SetParameter(fConfiguration.fResolution, PrinterCap::kResolution,
|
||||
getJobData()->getResolutionID());
|
||||
|
||||
fConfiguration.fXDPI = getJobData()->getXres();
|
||||
fConfiguration.fYDPI = getJobData()->getYres();
|
||||
|
||||
SetParameter(fConfiguration.fInputSlot, PrinterCap::kPaperSource,
|
||||
getJobData()->getPaperSource());
|
||||
|
||||
SetParameter(fConfiguration.fPrintingMode, PrinterCap::kColor,
|
||||
getJobData()->getColor());
|
||||
|
||||
if (getPrinterCap()->isSupport(PrinterCap::kDriverSpecificCapabilities))
|
||||
SetDriverSpecificSettings();
|
||||
|
||||
fprintf(stderr, "Driver: %s\n", fConfiguration.fDriver.String());
|
||||
fprintf(stderr, "PageSize %s\n", fConfiguration.fPageSize.String());
|
||||
fprintf(stderr, "Resolution %s\n", fConfiguration.fResolution.String());
|
||||
fprintf(stderr, "InputSlot %s\n", fConfiguration.fInputSlot.String());
|
||||
fprintf(stderr, "PrintingMode %s\n", fConfiguration.fPrintingMode.String());
|
||||
|
||||
return fBinding.BeginJob(&fConfiguration, this) == B_OK;
|
||||
}
|
||||
catch (TransportException& err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPDriver::SetParameter(BString& parameter, PrinterCap::CapID category,
|
||||
int value)
|
||||
{
|
||||
const BaseCap* capability;
|
||||
capability = getPrinterCap()->findCap(category, value);
|
||||
if (capability != NULL && capability->fKey != "")
|
||||
parameter = capability->Key();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPDriver::SetDriverSpecificSettings()
|
||||
{
|
||||
PrinterCap::CapID category = PrinterCap::kDriverSpecificCapabilities;
|
||||
int count = getPrinterCap()->countCap(category);
|
||||
const BaseCap** capabilities = getPrinterCap()->enumCap(category);
|
||||
for (int i = 0; i < count; i++) {
|
||||
const BaseCap* capability = capabilities[i];
|
||||
PrinterCap::CapID id = static_cast<PrinterCap::CapID>(capability->ID());
|
||||
AddDriverSpecificSetting(id, capability->fKey.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPDriver::AddDriverSpecificSetting(PrinterCap::CapID category, const char* key) {
|
||||
const BaseCap* capability = NULL;
|
||||
if (getJobData()->HasDriverSpecificSetting(key))
|
||||
{
|
||||
const string& value = getJobData()->DriverSpecificSetting(key);
|
||||
capability = getPrinterCap()->findCapWithKey(category, value.c_str());
|
||||
}
|
||||
|
||||
if (capability == NULL) {
|
||||
// job data should contain a value;
|
||||
// try to use the default value anyway
|
||||
capability = getPrinterCap()->getDefaultCap(category);
|
||||
}
|
||||
|
||||
if (capability == NULL) {
|
||||
// should not reach here!
|
||||
return;
|
||||
}
|
||||
|
||||
fConfiguration.fDriverSpecificSettings[key] = capability->fKey;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GPDriver::startPage(int)
|
||||
{
|
||||
fBinding.BeginPage();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GPDriver::endPage(int)
|
||||
{
|
||||
try {
|
||||
fBinding.EndPage();
|
||||
return true;
|
||||
}
|
||||
catch (TransportException& err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GPDriver::endDoc(bool)
|
||||
{
|
||||
try {
|
||||
fBinding.EndJob();
|
||||
return true;
|
||||
}
|
||||
catch (TransportException& err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GPDriver::nextBand(BBitmap* bitmap, BPoint* offset)
|
||||
{
|
||||
DBGMSG(("> nextBand\n"));
|
||||
try {
|
||||
BRect bounds = bitmap->Bounds();
|
||||
|
||||
RECT rc;
|
||||
rc.left = (int)bounds.left;
|
||||
rc.top = (int)bounds.top;
|
||||
rc.right = (int)bounds.right;
|
||||
rc.bottom = (int)bounds.bottom;
|
||||
|
||||
int height = rc.bottom - rc.top + 1;
|
||||
|
||||
int x = (int)offset->x;
|
||||
int y = (int)offset->y;
|
||||
|
||||
int page_height = getPageHeight();
|
||||
|
||||
if (y + height > page_height)
|
||||
height = page_height - y;
|
||||
|
||||
rc.bottom = height - 1;
|
||||
|
||||
DBGMSG(("height = %d\n", height));
|
||||
DBGMSG(("x = %d\n", x));
|
||||
DBGMSG(("y = %d\n", y));
|
||||
|
||||
if (get_valid_rect(bitmap, &rc)) {
|
||||
|
||||
DBGMSG(("validate rect = %d, %d, %d, %d\n",
|
||||
rc.left, rc.top, rc.right, rc.bottom));
|
||||
|
||||
x = rc.left;
|
||||
y += rc.top;
|
||||
/*
|
||||
int width = rc.right - rc.left + 1;
|
||||
int height = rc.bottom - rc.top + 1;
|
||||
int delta = bitmap->BytesPerRow();
|
||||
|
||||
DBGMSG(("width = %d\n", width));
|
||||
DBGMSG(("height = %d\n", height));
|
||||
DBGMSG(("delta = %d\n", delta));
|
||||
DBGMSG(("renderobj->get_pixel_depth() = %d\n", fHalftone->getPixelDepth()));
|
||||
*/
|
||||
int width = rc.right - rc.left + 1;
|
||||
int height = rc.bottom - rc.top + 1;
|
||||
fprintf(stderr, "GPDriver nextBand x %d, y %d, width %d,"
|
||||
" height %d\n",
|
||||
x, y, width, height);
|
||||
BRect imageRect(rc.left, rc.top, rc.right, rc.bottom);
|
||||
fBinding.AddBitmapToPage(bitmap, imageRect, BPoint(x, y));
|
||||
} else {
|
||||
DBGMSG(("band bitmap is clean.\n"));
|
||||
}
|
||||
|
||||
if (y >= page_height) {
|
||||
offset->x = -1.0;
|
||||
offset->y = -1.0;
|
||||
} else
|
||||
offset->y += height;
|
||||
|
||||
DBGMSG(("< nextBand\n"));
|
||||
return true;
|
||||
}
|
||||
catch (TransportException& err) {
|
||||
BAlert* alert = new BAlert("", err.what(), "OK");
|
||||
alert->Go();
|
||||
return false;
|
||||
}
|
||||
}
|
43
src/add-ons/print/drivers/gutenprint/GPDriver.h
Normal file
43
src/add-ons/print/drivers/gutenprint/GPDriver.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* GP.h
|
||||
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
|
||||
*/
|
||||
#ifndef __GP_H
|
||||
#define __GP_H
|
||||
|
||||
|
||||
#include "GPBinding.h"
|
||||
#include "GPCapabilities.h"
|
||||
#include "GraphicsDriver.h"
|
||||
#include "OutputStream.h"
|
||||
|
||||
class Halftone;
|
||||
|
||||
|
||||
class GPDriver : public GraphicsDriver, public OutputStream
|
||||
{
|
||||
public:
|
||||
GPDriver(BMessage* msg, PrinterData* printer_data,
|
||||
const PrinterCap* printer_cap);
|
||||
|
||||
void Write(const void *buffer, size_t size)
|
||||
throw(TransportException);
|
||||
|
||||
protected:
|
||||
bool startDoc();
|
||||
void SetParameter(BString& parameter, PrinterCap::CapID category,
|
||||
int value);
|
||||
void SetDriverSpecificSettings();
|
||||
void AddDriverSpecificSetting(PrinterCap::CapID category,
|
||||
const char* key);
|
||||
bool startPage(int page);
|
||||
bool nextBand(BBitmap* bitmap, BPoint* offset);
|
||||
bool endPage(int page);
|
||||
bool endDoc(bool success);
|
||||
|
||||
private:
|
||||
GPBinding fBinding;
|
||||
GPJobConfiguration fConfiguration;
|
||||
};
|
||||
|
||||
#endif // __GP_H
|
503
src/add-ons/print/drivers/gutenprint/GPJob.cpp
Normal file
503
src/add-ons/print/drivers/gutenprint/GPJob.cpp
Normal file
@ -0,0 +1,503 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#include "GPJob.h"
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
|
||||
GPJob::GPJob()
|
||||
:
|
||||
fApplicationName(),
|
||||
fOutputStream(NULL),
|
||||
fConfiguration(NULL),
|
||||
fFirstPage(true),
|
||||
fVariables(NULL),
|
||||
fBands(NULL),
|
||||
fCachedBand(NULL),
|
||||
fWriteError(B_OK)
|
||||
{
|
||||
fImage.init = ImageInit;
|
||||
fImage.reset = ImageReset;
|
||||
fImage.width = ImageWidth;
|
||||
fImage.height = ImageHeight;
|
||||
fImage.get_row = ImageGetRow;
|
||||
fImage.get_appname = ImageGetAppname;
|
||||
fImage.conclude = ImageConclude;
|
||||
fImage.rep = this;
|
||||
}
|
||||
|
||||
|
||||
GPJob::~GPJob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::SetApplicationName(const BString& applicationName)
|
||||
{
|
||||
fApplicationName = applicationName;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::SetConfiguration(GPJobConfiguration* configuration)
|
||||
{
|
||||
fConfiguration = configuration;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::SetOutputStream(OutputStream* outputStream)
|
||||
{
|
||||
fOutputStream = outputStream;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GPJob::Begin()
|
||||
{
|
||||
fWriteError = B_OK;
|
||||
|
||||
stp_init();
|
||||
|
||||
fPrinter = stp_get_printer_by_driver(fConfiguration->fDriver);
|
||||
if (fPrinter == NULL) {
|
||||
fprintf(stderr, "GPJob Begin: driver %s not found!\n",
|
||||
fConfiguration->fDriver.String());
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fVariables = stp_vars_create();
|
||||
if (fVariables == NULL) {
|
||||
fprintf(stderr, "GPJob Begin: out of memory\n");
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
stp_set_printer_defaults(fVariables, fPrinter);
|
||||
|
||||
stp_set_outfunc(fVariables, OutputFunction);
|
||||
stp_set_errfunc(fVariables, ErrorFunction);
|
||||
stp_set_outdata(fVariables, this);
|
||||
stp_set_errdata(fVariables, this);
|
||||
|
||||
stp_set_string_parameter(fVariables, "PageSize",
|
||||
fConfiguration->fPageSize);
|
||||
|
||||
if (fConfiguration->fResolution != "")
|
||||
stp_set_string_parameter(fVariables, "Resolution",
|
||||
fConfiguration->fResolution);
|
||||
|
||||
stp_set_string_parameter(fVariables, "InputSlot",
|
||||
fConfiguration->fInputSlot);
|
||||
|
||||
stp_set_string_parameter(fVariables, "PrintingMode",
|
||||
fConfiguration->fPrintingMode);
|
||||
|
||||
map<string, string>::iterator it = fConfiguration->fDriverSpecificSettings.
|
||||
begin();
|
||||
for (; it != fConfiguration->fDriverSpecificSettings.end(); it ++) {
|
||||
stp_set_string_parameter(fVariables, it->first.c_str(),
|
||||
it->second.c_str());
|
||||
}
|
||||
|
||||
stp_set_string_parameter(fVariables, "InputImageType",
|
||||
"RGB");
|
||||
stp_set_string_parameter(fVariables, "ChannelBitDepth",
|
||||
"8");
|
||||
stp_set_float_parameter(fVariables, "Density",
|
||||
1.0f);
|
||||
stp_set_string_parameter(fVariables, "JobMode", "Job");
|
||||
|
||||
stp_set_printer_defaults_soft(fVariables, fPrinter);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::End()
|
||||
{
|
||||
if (fVariables == NULL)
|
||||
return;
|
||||
|
||||
if (!fFirstPage)
|
||||
stp_end_job(fVariables, &fImage);
|
||||
|
||||
stp_vars_destroy(fVariables);
|
||||
fVariables = NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gcd(int a, int b)
|
||||
{
|
||||
// Euclidean algorithm for greatest common divisor
|
||||
while (b != 0) {
|
||||
int t = b;
|
||||
b = a % b;
|
||||
a = t;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
to72dpiFloor(int value, int fromUnit) {
|
||||
// proper rounding is important in this formula
|
||||
// do not "optimize"
|
||||
const int toUnit = 72;
|
||||
int g = gcd(toUnit, fromUnit);
|
||||
int n = toUnit / g;
|
||||
int m = fromUnit / g;
|
||||
return (value / m) * n;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
to72dpiCeiling(int value, int fromUnit) {
|
||||
// proper rounding is important in this formula
|
||||
// do not "optimize"
|
||||
const int toUnit = 72;
|
||||
int g = gcd(toUnit, fromUnit);
|
||||
int n = toUnit / g;
|
||||
int m = fromUnit / g;
|
||||
return ((value + m - 1) / m) * n;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
from72dpi(int value, int toUnit)
|
||||
{
|
||||
const int fromUnit = 72;
|
||||
return value * toUnit / fromUnit;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GPJob::PrintPage(list<GPBand*>& bands) {
|
||||
if (fWriteError != B_OK)
|
||||
return fWriteError;
|
||||
|
||||
fPrintRect = GetPrintRectangle(bands);
|
||||
fBands = &bands;
|
||||
fCachedBand = NULL;
|
||||
|
||||
{
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
stp_get_imageable_area(fVariables, &left, &right, &bottom, &top);
|
||||
fprintf(stderr, "GPJob imageable area left %d, top %d, right %d, "
|
||||
"bottom %d\n",
|
||||
left, top, right, bottom);
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
int left = (int)fPrintRect.left;
|
||||
int top = (int)fPrintRect.top;
|
||||
int width = fPrintRect.IntegerWidth() + 1;
|
||||
int height = fPrintRect.IntegerHeight() + 1;
|
||||
|
||||
fprintf(stderr, "GPJob raw image dimensions left %d, top %d, width %d, height %d\n",
|
||||
left, top, width, height);
|
||||
}
|
||||
|
||||
int xDPI = fConfiguration->fXDPI;
|
||||
int yDPI = fConfiguration->fYDPI;
|
||||
|
||||
// left, top of the image on the page in 1/72 Inches
|
||||
int left = static_cast<int>(fPrintRect.left);
|
||||
left = to72dpiFloor(left, xDPI);
|
||||
int top = static_cast<int>(fPrintRect.top);
|
||||
top = to72dpiFloor(top, yDPI);
|
||||
|
||||
// because of rounding in the previous step,
|
||||
// now the image left, top has to be synchronized
|
||||
fPrintRect.left = from72dpi(left, xDPI);
|
||||
fPrintRect.top = from72dpi(top, yDPI);
|
||||
|
||||
// width and height of the image on the page in 1/72 Inches
|
||||
int width = fPrintRect.IntegerWidth() + 1;
|
||||
width = to72dpiCeiling(width, xDPI);
|
||||
int height = fPrintRect.IntegerHeight() + 1;
|
||||
height = to72dpiCeiling(height, yDPI);
|
||||
|
||||
// synchronize image right and bottom too
|
||||
fPrintRect.right = fPrintRect.left + from72dpi(width, xDPI);
|
||||
fPrintRect.bottom = fPrintRect.top + from72dpi(height, yDPI);
|
||||
|
||||
{
|
||||
int left = (int)fPrintRect.left;
|
||||
int top = (int)fPrintRect.top;
|
||||
int width = fPrintRect.IntegerWidth() + 1;
|
||||
int height = fPrintRect.IntegerHeight() + 1;
|
||||
|
||||
fprintf(stderr, "GPJob image dimensions left %d, top %d, width %d, height %d\n",
|
||||
left, top, width, height);
|
||||
}
|
||||
|
||||
fprintf(stderr, "GPJob image dimensions in 1/72 Inches:\n"
|
||||
"left %d, top %d, width %d, height %d\n",
|
||||
left, top, width, height);
|
||||
|
||||
stp_set_width(fVariables, width);
|
||||
stp_set_height(fVariables, height);
|
||||
stp_set_left(fVariables, left);
|
||||
stp_set_top(fVariables, top);
|
||||
|
||||
stp_merge_printvars(fVariables, stp_printer_get_defaults(fPrinter));
|
||||
|
||||
if (!stp_verify(fVariables)) {
|
||||
// TODO report error
|
||||
fprintf(stderr, "GPJob PrintPage: invalid variables\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (fFirstPage) {
|
||||
fFirstPage = false;
|
||||
stp_start_job(fVariables, &fImage);
|
||||
}
|
||||
|
||||
stp_print(fVariables, &fImage);
|
||||
|
||||
return fWriteError;
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
GPJob::GetPrintRectangle(list<GPBand*>& bands)
|
||||
{
|
||||
list<GPBand*>::iterator it = bands.begin();
|
||||
if (it == bands.end())
|
||||
return BRect(0, 0, 0, 0);
|
||||
|
||||
GPBand* first = *it;
|
||||
BRect rect = first->GetBoundingRectangle();
|
||||
for (it ++; it != bands.end(); it ++) {
|
||||
GPBand* band = *it;
|
||||
rect = rect | band->GetBoundingRectangle();
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::Init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::Reset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
GPJob::Width()
|
||||
{
|
||||
return static_cast<int>(fPrintRect.IntegerWidth() + 1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
GPJob::Height()
|
||||
{
|
||||
return static_cast<int>(fPrintRect.IntegerHeight() + 1);
|
||||
}
|
||||
|
||||
|
||||
stp_image_status_t
|
||||
GPJob::GetRow(unsigned char* data, size_t size, int row)
|
||||
{
|
||||
if (fWriteError != B_OK)
|
||||
return STP_IMAGE_STATUS_ABORT;
|
||||
|
||||
// row is relative to left, top of image
|
||||
// convert it to absolute value
|
||||
int line = static_cast<int>(fPrintRect.top) + row;
|
||||
|
||||
FillWhite(data, size);
|
||||
|
||||
GPBand* band = FindBand(line);
|
||||
if (band != NULL)
|
||||
FillRow(band, data, size, line);
|
||||
|
||||
return STP_IMAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
GPBand*
|
||||
GPJob::FindBand(int line)
|
||||
{
|
||||
if (fCachedBand != NULL && fCachedBand->ContainsLine(line))
|
||||
return fCachedBand;
|
||||
|
||||
list<GPBand*>::iterator it = fBands->begin();
|
||||
for (; it != fBands->end(); it ++) {
|
||||
GPBand* band = *it;
|
||||
if (band->ContainsLine(line)) {
|
||||
fCachedBand = band;
|
||||
return band;
|
||||
}
|
||||
}
|
||||
|
||||
fCachedBand = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::FillRow(GPBand* band, unsigned char* data, size_t size, int line)
|
||||
{
|
||||
int imageTop = line - static_cast<int>(band->fWhere.y -
|
||||
band->fValidRect.top);
|
||||
int imageLeft = static_cast<int>(band->fValidRect.left);
|
||||
|
||||
const int sourceDelta = band->fBitmap.BytesPerRow();
|
||||
const int kSourceBytesPerPixel = 4; // BGRA
|
||||
const unsigned char* source =
|
||||
static_cast<unsigned char*>(band->fBitmap.Bits())
|
||||
+ imageTop * sourceDelta
|
||||
+ imageLeft * kSourceBytesPerPixel;
|
||||
|
||||
int dataLeft = static_cast<int>(band->fWhere.x - fPrintRect.left);
|
||||
|
||||
const int kTargetBytesPerPixel = 3; // RGB
|
||||
unsigned char* target = &data[dataLeft * kTargetBytesPerPixel];
|
||||
|
||||
const int width = band->fValidRect.IntegerWidth() + 1;
|
||||
ASSERT(0 <= imageTop && imageTop <= band->fValidRect.IntegerHeight());
|
||||
ASSERT((dataLeft + width) * kTargetBytesPerPixel <= size);
|
||||
|
||||
for (int i = 0; i < width; i ++) {
|
||||
target[0] = source[2];
|
||||
target[1] = source[1];
|
||||
target[2] = source[0];
|
||||
target += kTargetBytesPerPixel;
|
||||
source += kSourceBytesPerPixel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::FillWhite(unsigned char* data, size_t size)
|
||||
{
|
||||
for (size_t i = 0; i < size; i ++)
|
||||
data[i] = 0xff;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
GPJob::GetAppname()
|
||||
{
|
||||
return fApplicationName.String();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::Conclude()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::Write(const char* data, size_t size)
|
||||
{
|
||||
try {
|
||||
fOutputStream->Write(data, size);
|
||||
} catch (TransportException e) {
|
||||
fWriteError = B_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::ReportError(const char* data, size_t size)
|
||||
{
|
||||
// TODO report error in printer add-on
|
||||
fprintf(stderr, "GPJob Gutenprint Error: %*s\n", (int)size, data);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::ImageInit(stp_image_t* image)
|
||||
{
|
||||
GPJob* job = static_cast<GPJob*>(image->rep);
|
||||
job->Init();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::ImageReset(stp_image_t* image)
|
||||
{
|
||||
GPJob* job = static_cast<GPJob*>(image->rep);
|
||||
job->Reset();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
GPJob::ImageWidth(stp_image_t* image)
|
||||
{
|
||||
GPJob* job = static_cast<GPJob*>(image->rep);
|
||||
return job->Width();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
GPJob::ImageHeight(stp_image_t *image)
|
||||
{
|
||||
GPJob* job = static_cast<GPJob*>(image->rep);
|
||||
return job->Height();
|
||||
}
|
||||
|
||||
|
||||
stp_image_status_t
|
||||
GPJob::ImageGetRow(stp_image_t* image, unsigned char* data, size_t size,
|
||||
int row)
|
||||
{
|
||||
GPJob* job = static_cast<GPJob*>(image->rep);
|
||||
return job->GetRow(data, size, row);
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
GPJob::ImageGetAppname(stp_image_t* image)
|
||||
{
|
||||
GPJob* job = static_cast<GPJob*>(image->rep);
|
||||
return job->GetAppname();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::ImageConclude(stp_image_t *image)
|
||||
{
|
||||
GPJob* job = static_cast<GPJob*>(image->rep);
|
||||
job->Conclude();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::OutputFunction(void *cookie, const char *data, size_t size)
|
||||
{
|
||||
GPJob* job = static_cast<GPJob*>(cookie);
|
||||
job->Write(data, size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPJob::ErrorFunction(void *cookie, const char *data, size_t size)
|
||||
{
|
||||
GPJob* job = static_cast<GPJob*>(cookie);
|
||||
job->ReportError(data, size);
|
||||
}
|
||||
|
80
src/add-ons/print/drivers/gutenprint/GPJob.h
Normal file
80
src/add-ons/print/drivers/gutenprint/GPJob.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#ifndef GP_JOB_H
|
||||
#define GP_JOB_H
|
||||
|
||||
#include<gutenprint/gutenprint.h>
|
||||
|
||||
#include<list>
|
||||
|
||||
#include<String.h>
|
||||
|
||||
#include "GPBand.h"
|
||||
#include "GPJobConfiguration.h"
|
||||
#include "OutputStream.h"
|
||||
|
||||
|
||||
class GPJob
|
||||
{
|
||||
public:
|
||||
GPJob();
|
||||
~GPJob();
|
||||
|
||||
void SetApplicationName(const BString& applicationName);
|
||||
void SetConfiguration(GPJobConfiguration* configuration);
|
||||
void SetOutputStream(OutputStream* outputStream);
|
||||
|
||||
status_t Begin();
|
||||
void End();
|
||||
|
||||
status_t PrintPage(list<GPBand*>& bands);
|
||||
|
||||
private:
|
||||
BRect GetPrintRectangle(list<GPBand*>& bands);
|
||||
GPBand* FindBand(int line);
|
||||
void FillRow(GPBand* band, unsigned char* data, size_t size,
|
||||
int line);
|
||||
void FillWhite(unsigned char* data, size_t size);
|
||||
|
||||
void Init();
|
||||
void Reset();
|
||||
int Width();
|
||||
int Height();
|
||||
stp_image_status_t GetRow(unsigned char* data, size_t size, int row);
|
||||
const char* GetAppname();
|
||||
void Conclude();
|
||||
void Write(const char* data, size_t size);
|
||||
void ReportError(const char* data, size_t size);
|
||||
|
||||
static void ImageInit(stp_image_t* image);
|
||||
static void ImageReset(stp_image_t* image);
|
||||
static int ImageWidth(stp_image_t* image);
|
||||
static int ImageHeight(stp_image_t *image);
|
||||
static stp_image_status_t ImageGetRow(stp_image_t* image,
|
||||
unsigned char* data, size_t size, int row);
|
||||
static const char* ImageGetAppname(stp_image_t* image);
|
||||
static void ImageConclude(stp_image_t *image);
|
||||
static void OutputFunction(void *cookie, const char *data,
|
||||
size_t size);
|
||||
static void ErrorFunction(void *cookie, const char *data,
|
||||
size_t size);
|
||||
|
||||
BString fApplicationName;
|
||||
OutputStream* fOutputStream;
|
||||
GPJobConfiguration* fConfiguration;
|
||||
|
||||
bool fFirstPage;
|
||||
stp_image_t fImage;
|
||||
stp_vars_t* fVariables;
|
||||
const stp_printer_t* fPrinter;
|
||||
BRect fPrintRect;
|
||||
list<GPBand*>* fBands;
|
||||
GPBand* fCachedBand;
|
||||
status_t fWriteError;
|
||||
};
|
||||
#endif
|
21
src/add-ons/print/drivers/gutenprint/GPJobConfiguration.cpp
Normal file
21
src/add-ons/print/drivers/gutenprint/GPJobConfiguration.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#include "GPJobConfiguration.h"
|
||||
|
||||
GPJobConfiguration::GPJobConfiguration()
|
||||
:
|
||||
fDriver(),
|
||||
fPageSize(),
|
||||
fResolution(),
|
||||
fInputSlot(),
|
||||
fPrintingMode(),
|
||||
fXDPI(600),
|
||||
fYDPI(600)
|
||||
{
|
||||
}
|
||||
|
35
src/add-ons/print/drivers/gutenprint/GPJobConfiguration.h
Normal file
35
src/add-ons/print/drivers/gutenprint/GPJobConfiguration.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#ifndef GP_JOB_CONFIGURATION_H
|
||||
#define GP_JOB_CONFIGURATION_H
|
||||
|
||||
#include<String.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class GPJobConfiguration
|
||||
{
|
||||
public:
|
||||
GPJobConfiguration();
|
||||
|
||||
BString fDriver;
|
||||
BString fPageSize;
|
||||
BString fResolution;
|
||||
BString fInputSlot;
|
||||
BString fPrintingMode;
|
||||
|
||||
int fXDPI;
|
||||
int fYDPI;
|
||||
|
||||
map<string, string> fDriverSpecificSettings;
|
||||
};
|
||||
|
||||
#endif
|
215
src/add-ons/print/drivers/gutenprint/GPParameterVisitor.cpp
Normal file
215
src/add-ons/print/drivers/gutenprint/GPParameterVisitor.cpp
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#include "GPParameterVisitor.h"
|
||||
|
||||
#include <String.h>
|
||||
|
||||
|
||||
const char* kJobMode = "JobMode";
|
||||
const char* kJob = "Job";
|
||||
|
||||
const char* kPrintingMode = "PrintingMode";
|
||||
const char* kColor = "Color";
|
||||
const char* kBlackAndWhite = "BW";
|
||||
|
||||
const char* kResolution = "Resolution";
|
||||
const char* kFakeResolutionKey = "";
|
||||
|
||||
const char* kPageSize = "PageSize";
|
||||
|
||||
const char* kChannelBitDepth = "ChannelBitDepth";
|
||||
|
||||
|
||||
GPParameterVisitor::GPParameterVisitor()
|
||||
:
|
||||
fVariables(NULL),
|
||||
fHasResolutionParameter(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
GPParameterVisitor::~GPParameterVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPParameterVisitor::Visit(const stp_printer_t* printer)
|
||||
{
|
||||
// this code is based on Gutenprint printer_options.c
|
||||
const stp_vars_t* defaultVariables = stp_printer_get_defaults(printer);
|
||||
stp_vars_t* variables = stp_vars_create_copy(defaultVariables);
|
||||
fVariables = variables;
|
||||
|
||||
stp_set_string_parameter(variables, kJobMode, kJob);
|
||||
|
||||
stp_parameter_t printingMode;
|
||||
stp_describe_parameter(variables, kPrintingMode, &printingMode);
|
||||
bool isColorPrinter = stp_string_list_is_present(printingMode.bounds.str,
|
||||
kColor) != 0;
|
||||
stp_parameter_description_destroy(&printingMode);
|
||||
|
||||
if (isColorPrinter)
|
||||
stp_set_string_parameter(variables, kPrintingMode, kColor);
|
||||
else
|
||||
stp_set_string_parameter(variables, kPrintingMode, kBlackAndWhite);
|
||||
|
||||
stp_set_string_parameter(variables, kChannelBitDepth, "8");
|
||||
|
||||
stp_parameter_list_t list = stp_get_parameter_list(variables);
|
||||
int size = stp_parameter_list_count(list);
|
||||
|
||||
for (int i = 0; i < size; i ++) {
|
||||
const stp_parameter_t* parameter = stp_parameter_list_param(list, i);
|
||||
stp_parameter_t description;
|
||||
stp_describe_parameter(fVariables, parameter->name, &description);
|
||||
VisitParameter(list, parameter, &description);
|
||||
stp_parameter_description_destroy(&description);
|
||||
}
|
||||
|
||||
// TODO check if this can really happen
|
||||
if (!fHasResolutionParameter) {
|
||||
AddMissingResolution();
|
||||
}
|
||||
|
||||
EndVisit();
|
||||
|
||||
stp_parameter_list_destroy(list);
|
||||
stp_vars_destroy(variables);
|
||||
fVariables = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPParameterVisitor::AddMissingResolution()
|
||||
{
|
||||
// some printer definitions don't have resolution parameter
|
||||
// however "libprint" needs to know it for rasterization
|
||||
|
||||
// TODO find out if other parameters influence the resolution
|
||||
// e.g. color vs black and white
|
||||
int x, y;
|
||||
stp_describe_resolution(fVariables, &x, &y);
|
||||
|
||||
BeginParameter(kResolution, "Resolution", STP_PARAMETER_CLASS_FEATURE);
|
||||
DefaultStringParameter(kResolution, kFakeResolutionKey);
|
||||
StringParameterSize(kResolution, 1);
|
||||
|
||||
if (x <= 0 || y <= 0) {
|
||||
// TODO decide if more resolutions (150, 600) should be possible
|
||||
x = 300;
|
||||
y = 300;
|
||||
}
|
||||
|
||||
BString displayName;
|
||||
if (x != y)
|
||||
displayName << x << " x " << y << " DPI";
|
||||
else
|
||||
displayName << x << " DPI";
|
||||
|
||||
ResolutionParameter(kResolution, kFakeResolutionKey, displayName.String(),
|
||||
x, y);
|
||||
|
||||
EndParameter(kResolution);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPParameterVisitor::VisitParameter(stp_parameter_list_t list,
|
||||
const stp_parameter_t* parameter, stp_parameter_t* description)
|
||||
{
|
||||
// TODO decide which parameters should be revealed to user
|
||||
// e.g. up to STP_PARAMETER_LEVEL_ADVANCED4;
|
||||
const stp_parameter_level_t kMaxLevel = STP_PARAMETER_LEVEL_BASIC;
|
||||
stp_parameter_class_t parameterClass = parameter->p_class;
|
||||
if (parameter->read_only ||
|
||||
(parameter->p_level > kMaxLevel
|
||||
&& strcmp(parameter->name, kResolution) != 0)
|
||||
|| parameterClass != STP_PARAMETER_CLASS_OUTPUT
|
||||
&& parameterClass != STP_PARAMETER_CLASS_CORE
|
||||
&& parameterClass != STP_PARAMETER_CLASS_FEATURE)
|
||||
return;
|
||||
|
||||
if (!description->is_active)
|
||||
return;
|
||||
|
||||
switch (description->p_type) {
|
||||
case STP_PARAMETER_TYPE_STRING_LIST:
|
||||
if (!BeginParameter(description->name, description->text,
|
||||
parameterClass))
|
||||
return;
|
||||
VisitStringList(description);
|
||||
EndParameter(description->name);
|
||||
break;
|
||||
|
||||
case STP_PARAMETER_TYPE_BOOLEAN:
|
||||
break;
|
||||
|
||||
case STP_PARAMETER_TYPE_DOUBLE:
|
||||
break;
|
||||
|
||||
case STP_PARAMETER_TYPE_INT:
|
||||
break;
|
||||
|
||||
case STP_PARAMETER_TYPE_DIMENSION:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GPParameterVisitor::VisitStringList(stp_parameter_t* parameter)
|
||||
{
|
||||
stp_string_list_t* list = parameter->bounds.str;
|
||||
int count = stp_string_list_count(list);
|
||||
if (count <= 0)
|
||||
return;
|
||||
|
||||
const char* name = parameter->name;
|
||||
if (parameter->is_mandatory)
|
||||
DefaultStringParameter(name, parameter->deflt.str);
|
||||
else
|
||||
DefaultStringParameter(name, NULL);
|
||||
|
||||
StringParameterSize(name, count);
|
||||
|
||||
for (int i = 0; i < count; i ++) {
|
||||
const stp_param_string_t* entry = stp_string_list_param(list, i);
|
||||
const char* key = entry->name;
|
||||
const char* displayName = entry->text;
|
||||
if (strcmp(name, kResolution) == 0) {
|
||||
stp_set_string_parameter(fVariables, kResolution, key);
|
||||
|
||||
int x, y;
|
||||
stp_describe_resolution(fVariables, &x, &y);
|
||||
|
||||
ResolutionParameter(name, key, displayName, x, y);
|
||||
|
||||
fHasResolutionParameter = true;
|
||||
} else if (strcmp(name, kPageSize) == 0) {
|
||||
stp_set_string_parameter(fVariables, kPageSize, key);
|
||||
|
||||
int width;
|
||||
int height;
|
||||
stp_get_media_size(fVariables, &width, &height);
|
||||
BSize pageSize(width, height);
|
||||
|
||||
int left, right, top, bottom;
|
||||
stp_get_imageable_area(fVariables, &left, &right, &bottom, &top);
|
||||
BRect imageableArea(left, top, right, bottom);
|
||||
|
||||
PageSizeParameter(name, key, displayName, pageSize, imageableArea);
|
||||
} else {
|
||||
StringParameter(name, key, displayName);
|
||||
}
|
||||
}
|
||||
}
|
67
src/add-ons/print/drivers/gutenprint/GPParameterVisitor.h
Normal file
67
src/add-ons/print/drivers/gutenprint/GPParameterVisitor.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#ifndef GP_PARAMETER_VISITOR_H
|
||||
#define GP_PARAMETER_VISITOR_H
|
||||
|
||||
#include <gutenprint/gutenprint.h>
|
||||
|
||||
#include <Size.h>
|
||||
#include <Rect.h>
|
||||
|
||||
|
||||
extern const char* kJobMode;
|
||||
extern const char* kJob;
|
||||
|
||||
extern const char* kPrintingMode;
|
||||
extern const char* kColor;
|
||||
extern const char* kBlackAndWhite;
|
||||
|
||||
extern const char* kResolution;
|
||||
extern const char* kFakeResolutionKey;
|
||||
|
||||
extern const char* kPageSize;
|
||||
|
||||
extern const char* kChannelBitDepth;
|
||||
|
||||
|
||||
class GPParameterVisitor
|
||||
{
|
||||
public:
|
||||
GPParameterVisitor();
|
||||
virtual ~GPParameterVisitor();
|
||||
|
||||
void Visit(const stp_printer_t* printer);
|
||||
void VisitParameter(stp_parameter_list_t list,
|
||||
const stp_parameter_t* parameter, stp_parameter_t* description);
|
||||
void VisitStringList(stp_parameter_t* parameter);
|
||||
|
||||
virtual bool BeginParameter(const char* name, const char* displayName,
|
||||
stp_parameter_class_t parameterClass) = 0;
|
||||
// key is null if there is no default value
|
||||
virtual void DefaultStringParameter(const char* name,
|
||||
const char* key) = 0;
|
||||
virtual void StringParameterSize(const char* name, int size) = 0;
|
||||
virtual void StringParameter(const char* name, const char* key,
|
||||
const char* displayName) = 0;
|
||||
virtual void ResolutionParameter(const char* name, const char* key,
|
||||
const char* displayName, int x, int y) = 0;
|
||||
virtual void PageSizeParameter(const char* name, const char* key,
|
||||
const char* displayName, BSize pageSize,
|
||||
BRect imageableArea) = 0;
|
||||
virtual void EndParameter(const char* name) = 0;
|
||||
virtual void EndVisit() = 0;
|
||||
|
||||
private:
|
||||
void AddMissingResolution();
|
||||
|
||||
stp_vars_t* fVariables;
|
||||
bool fHasResolutionParameter;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
82
src/add-ons/print/drivers/gutenprint/GPPrinterDriver.cpp
Normal file
82
src/add-ons/print/drivers/gutenprint/GPPrinterDriver.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* GPEntry.cpp
|
||||
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
|
||||
* Copyright 2010 Michael Pfeiffer.
|
||||
*/
|
||||
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
#include "GPDriver.h"
|
||||
#include "GPCapabilities.h"
|
||||
#include "GPData.h"
|
||||
#include "PrinterDriver.h"
|
||||
#include "SelectPrinterDialog.h"
|
||||
|
||||
|
||||
class GPPrinterDriver : public PrinterDriver
|
||||
{
|
||||
public:
|
||||
GPPrinterDriver(BNode* printerFolder)
|
||||
:
|
||||
PrinterDriver(printerFolder)
|
||||
{
|
||||
}
|
||||
|
||||
const char* GetSignature() const
|
||||
{
|
||||
return "application/x-vnd.gutenprint";
|
||||
}
|
||||
|
||||
const char* GetDriverName() const
|
||||
{
|
||||
return "Gutenprint";
|
||||
}
|
||||
|
||||
const char* GetVersion() const
|
||||
{
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
const char* GetCopyright() const
|
||||
{
|
||||
return "Gutenprint driver "
|
||||
"Copyright © 2010 Michael Pfeiffer.\n";
|
||||
}
|
||||
|
||||
char* AddPrinter(char *printerName)
|
||||
{
|
||||
GPData* data = dynamic_cast<GPData*>(GetPrinterData());
|
||||
ASSERT(data != NULL);
|
||||
|
||||
SelectPrinterDialog* dialog =
|
||||
new SelectPrinterDialog(data);
|
||||
|
||||
if (dialog->Go() != B_OK)
|
||||
return NULL;
|
||||
|
||||
return printerName;
|
||||
}
|
||||
|
||||
PrinterData* InstantiatePrinterData(BNode* node)
|
||||
{
|
||||
return new GPData(node);
|
||||
}
|
||||
|
||||
PrinterCap* InstantiatePrinterCap(PrinterData* printerData)
|
||||
{
|
||||
return new GPCapabilities(printerData);
|
||||
}
|
||||
|
||||
GraphicsDriver* InstantiateGraphicsDriver(BMessage* settings,
|
||||
PrinterData* printerData, PrinterCap* printerCap)
|
||||
{
|
||||
return new GPDriver(settings, printerData, printerCap);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
PrinterDriver* instantiate_printer_driver(BNode* printerFolder)
|
||||
{
|
||||
return new GPPrinterDriver(printerFolder);
|
||||
}
|
38
src/add-ons/print/drivers/gutenprint/Gutenprint.rdef
Normal file
38
src/add-ons/print/drivers/gutenprint/Gutenprint.rdef
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
resource app_signature "application/x-vnd.gutenprint";
|
||||
|
||||
resource app_flags B_SINGLE_LAUNCH;
|
||||
|
||||
resource app_version {
|
||||
major = 0,
|
||||
middle = 0,
|
||||
minor = 1,
|
||||
|
||||
variety = B_APPV_DEVELOPMENT,
|
||||
internal = 0,
|
||||
|
||||
short_info = "Gutenprint add-on",
|
||||
long_info = "Gutenprint add-on for Haiku\nCopyright 1999 Y.Takagi\nCopyright 2010 Michael Pfeiffer\nAll Rights Reserved."
|
||||
};
|
||||
|
||||
resource vector_icon {
|
||||
$"6E6369660B050002001602B76E71BBF8593D1210B8A7674742A04ABEFB00AEFF"
|
||||
$"E1053802001603373333B9333339333337333348E54F4B555400FFBFE5FF9B02"
|
||||
$"00160336C6F3B9284239E397376BB94A71BE484A25005346B5FFFF02001602B5"
|
||||
$"00003A6000BA6000B500004A2E244AB9D001C0FF9A020116023AA41339C70ABC"
|
||||
$"27003D026E4ACAB74AC8AB0183FFAD020106023600000000000000003700004A"
|
||||
$"10004AB0000035FF06FB1E9303020106023600000000000000003700004A1000"
|
||||
$"4AB00000FFE3E3FFDD05050101000073020116023E1E41BC9E393B21B93C88A6"
|
||||
$"4824E3485D850090FF3C0B0606BE023A5F485C46584C5E5656525A5656604C58"
|
||||
$"483A0608EFB6302E302E25372248223A2248465A4A59485B4A59584B41573E58"
|
||||
$"3F563D543C0608AAFF503A4E3C3231342F302E302E25372248223A2248465A46"
|
||||
$"5A464C543C4A46543C0606FF06573E583F563D543C543C4A46465A464C465A4A"
|
||||
$"59485B4A59584B410604DB4A594A4F4A59584B41563F563F4E470A0426484256"
|
||||
$"4252264406057A0322513A5E42543C58425452B77BC262B77BC262254A080228"
|
||||
$"5038580A06542A3C22353135324C3B4C3A0202404A3E4C4248434D454B414F02"
|
||||
$"0332332B3332334B3E4B3E453E3547444E26400F0A090100000A000301060810"
|
||||
$"01178400040A010102000A0001051001178200040A020105000A030106000A04"
|
||||
$"0108000A050103000A060104000A08010920251C0A0701092022210A00010730"
|
||||
$"241C01178100040A00010730221E01178100040A0001071815FF01178100040A"
|
||||
$"0A010A00"
|
||||
};
|
25
src/add-ons/print/drivers/gutenprint/Jamfile
Normal file
25
src/add-ons/print/drivers/gutenprint/Jamfile
Normal file
@ -0,0 +1,25 @@
|
||||
SubDir HAIKU_TOP src add-ons print drivers gutenprint ;
|
||||
|
||||
SubDirSysHdrs [ FDirName $(HAIKU_TOP) src libs print libgutenprint include ] ;
|
||||
SubDirHdrs [ FDirName $(HAIKU_TOP) headers libs print libprint ] ;
|
||||
|
||||
AddResources Gutenprint : Gutenprint.rdef ;
|
||||
|
||||
Addon Gutenprint :
|
||||
GPBand.cpp
|
||||
GPBinding.cpp
|
||||
GPCapabilities.cpp
|
||||
GPCapabilityExtractor.cpp
|
||||
GPData.cpp
|
||||
GPDriver.cpp
|
||||
GPJob.cpp
|
||||
GPJobConfiguration.cpp
|
||||
GPParameterVisitor.cpp
|
||||
GPPrinterDriver.cpp
|
||||
SelectPrinterDialog.cpp
|
||||
:
|
||||
be
|
||||
libgutenprint.a
|
||||
libprint.a
|
||||
$(TARGET_LIBSTDC++)
|
||||
;
|
22
src/add-ons/print/drivers/gutenprint/OutputStream.h
Normal file
22
src/add-ons/print/drivers/gutenprint/OutputStream.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
#ifndef OUTPUT_STREAM_H
|
||||
#define OUTPUT_STREAM_H
|
||||
|
||||
#include "Transport.h"
|
||||
|
||||
|
||||
class OutputStream
|
||||
{
|
||||
public:
|
||||
virtual void Write(const void *buffer, size_t size)
|
||||
throw(TransportException) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
196
src/add-ons/print/drivers/gutenprint/SelectPrinterDialog.cpp
Normal file
196
src/add-ons/print/drivers/gutenprint/SelectPrinterDialog.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2010, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ithamar R. Adema <ithamar.adema@team-embedded.nl>
|
||||
* Michael Pfeiffer
|
||||
*/
|
||||
|
||||
|
||||
#include "SelectPrinterDialog.h"
|
||||
|
||||
#include <GroupLayout.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
|
||||
#include <Button.h>
|
||||
#include <Debug.h>
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <ListView.h>
|
||||
#include <Message.h>
|
||||
#include <Path.h>
|
||||
#include <ScrollBar.h>
|
||||
#include <ScrollView.h>
|
||||
#include <String.h>
|
||||
#include <StringItem.h>
|
||||
|
||||
#include "GPBinding.h"
|
||||
|
||||
|
||||
enum {
|
||||
kMsgCancel = 'stop',
|
||||
kMsgOK = 'okok',
|
||||
|
||||
kMsgManufacturerSelected = 'msel',
|
||||
kMsgPrinterSelected = 'psel',
|
||||
};
|
||||
|
||||
|
||||
class StringValueItem : public BStringItem {
|
||||
public:
|
||||
StringValueItem(const BString& text, const BString& value)
|
||||
:
|
||||
BStringItem(text.String()),
|
||||
fValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
BString fValue;
|
||||
};
|
||||
|
||||
|
||||
SelectPrinterDialog::SelectPrinterDialog(GPData* data)
|
||||
:
|
||||
DialogWindow(BRect(10, 10, 400, 400),
|
||||
"Select Printer", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
|
||||
B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS),
|
||||
fData(data)
|
||||
{
|
||||
SetResult(B_ERROR);
|
||||
|
||||
BButton* ok;
|
||||
BButton* cancel;
|
||||
|
||||
ok = new BButton("btn:ok", "OK", new BMessage(kMsgOK));
|
||||
ok->MakeDefault(true);
|
||||
ok->SetEnabled(false);
|
||||
fOKButton = ok;
|
||||
|
||||
cancel = new BButton("btn:cancel", "Cancel", new BMessage(kMsgCancel));
|
||||
|
||||
BScrollView* manuScroller, *printerScroller;
|
||||
fManufacturersListView = new BListView("olv:manufacturers");
|
||||
manuScroller = new BScrollView("scr:manufacturers", fManufacturersListView,
|
||||
0, false, true);
|
||||
fPrintersListView = new BListView("olv:printers");
|
||||
printerScroller = new BScrollView("scr:printers", fPrintersListView, 0,
|
||||
false, true);
|
||||
|
||||
fPrintersListView->SetSelectionMessage(new BMessage(kMsgPrinterSelected));
|
||||
fManufacturersListView->SetSelectionMessage(
|
||||
new BMessage(kMsgManufacturerSelected));
|
||||
PopulateManufacturers();
|
||||
|
||||
// Build the layout
|
||||
SetLayout(new BGroupLayout(B_VERTICAL));
|
||||
|
||||
AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
|
||||
.AddGroup(B_HORIZONTAL, 5, 1.0f)
|
||||
.Add(manuScroller)
|
||||
.Add(printerScroller)
|
||||
.End()
|
||||
.AddGroup(B_HORIZONTAL, 5, 2.0f)
|
||||
.AddGlue()
|
||||
.Add(cancel)
|
||||
.Add(ok)
|
||||
.End()
|
||||
.SetInsets(10, 10, 10, 10)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SelectPrinterDialog::PopulateManufacturers()
|
||||
{
|
||||
BMessage manufacturers;
|
||||
GPBinding binding;
|
||||
binding.GetPrinterManufacturers(manufacturers);
|
||||
|
||||
BString id;
|
||||
BString displayName;
|
||||
for (int32 index = 0; binding.ExtractManufacturer(manufacturers, index, id,
|
||||
displayName); index ++) {
|
||||
fManufacturersListView->AddItem(new StringValueItem(id, displayName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SelectPrinterDialog::PopulatePrinters()
|
||||
{
|
||||
BString manufacturer = GetSelectedItemValue(fManufacturersListView).String();
|
||||
if (manufacturer.Length() == 0)
|
||||
return;
|
||||
|
||||
BMessage models;
|
||||
GPBinding binding;
|
||||
binding.GetPrinterModels(manufacturer, models);
|
||||
|
||||
BString displayName;
|
||||
BString driver;
|
||||
for (int32 index = 0; binding.ExtractModel(models, index, displayName, driver);
|
||||
index ++) {
|
||||
StringValueItem* item = new StringValueItem(displayName, driver);
|
||||
fPrintersListView->AddItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
SelectPrinterDialog::GetSelectedItemValue(BListView* listView)
|
||||
{
|
||||
int32 index = listView->CurrentSelection();
|
||||
|
||||
// Bail out if no manufacturer is selected
|
||||
if (index < 0)
|
||||
return "";
|
||||
BListItem* item = listView->ItemAt(index);
|
||||
StringValueItem* valueItem = dynamic_cast<StringValueItem*>(item);
|
||||
ASSERT(valueItem != NULL);
|
||||
|
||||
return valueItem->fValue;
|
||||
}
|
||||
|
||||
void
|
||||
SelectPrinterDialog::PrinterSelected()
|
||||
{
|
||||
int32 index = fPrintersListView->CurrentSelection();
|
||||
fOKButton->SetEnabled(index >= 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SelectPrinterDialog::Save()
|
||||
{
|
||||
BString driverName = GetSelectedItemValue(fPrintersListView);
|
||||
fData->fGutenprintDriverName = driverName;
|
||||
fData->save();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SelectPrinterDialog::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case kMsgManufacturerSelected:
|
||||
fPrintersListView->MakeEmpty();
|
||||
PopulatePrinters();
|
||||
PrinterSelected();
|
||||
break;
|
||||
case kMsgPrinterSelected:
|
||||
PrinterSelected();
|
||||
break;
|
||||
case kMsgOK:
|
||||
Save();
|
||||
SetResult(B_NO_ERROR);
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
case kMsgCancel:
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
default:
|
||||
DialogWindow::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
35
src/add-ons/print/drivers/gutenprint/SelectPrinterDialog.h
Normal file
35
src/add-ons/print/drivers/gutenprint/SelectPrinterDialog.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef SELECT_PRINTER_DIALOG_H
|
||||
#define SELECT_PRINTER_DIALOG_H
|
||||
|
||||
|
||||
#include <storage/FindDirectory.h>
|
||||
|
||||
#include "DialogWindow.h"
|
||||
#include "GPData.h"
|
||||
|
||||
|
||||
class BListView;
|
||||
class BButton;
|
||||
class PSData;
|
||||
|
||||
|
||||
class SelectPrinterDialog : public DialogWindow {
|
||||
public:
|
||||
SelectPrinterDialog(GPData* data);
|
||||
|
||||
void MessageReceived(BMessage* msg);
|
||||
private:
|
||||
void PopulateManufacturers();
|
||||
void PopulatePrinters();
|
||||
BString GetSelectedItemValue(BListView* listView);
|
||||
void PrinterSelected();
|
||||
void Save();
|
||||
|
||||
BListView* fManufacturersListView;
|
||||
BListView* fPrintersListView;
|
||||
BButton* fOKButton;
|
||||
|
||||
GPData* fData;
|
||||
};
|
||||
|
||||
#endif // SELECTPPDDLG_H
|
Loading…
Reference in New Issue
Block a user