Initial work on Apple Stylewriter printer driver.

This commit is contained in:
Adrien Destugues 2018-06-03 18:33:51 +02:00
parent c85dd27c9e
commit d9949ac911
9 changed files with 512 additions and 0 deletions

View File

@ -2,6 +2,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 lpstyl ;
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 postscript ;

View File

@ -0,0 +1,14 @@
SubDir HAIKU_TOP src add-ons print drivers lpstyl ;
SubDirHdrs [ FDirName $(HAIKU_TOP) headers libs print libprint ] ;
AddResources Lpstyl : Lpstyl.rdef ;
Addon Lpstyl :
Lpstyl.cpp
LpstylCap.cpp
LpstylData.cpp
LpstylEntry.cpp
: be libprint.a [ TargetLibstdc++ ]
;

View File

@ -0,0 +1,178 @@
/*
* Copyright 2017, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrien Destugues <pulkomandy@pulkomandy.tk>
*/
#include "Lpstyl.h"
LpstylDriver::LpstylDriver(BMessage* message, PrinterData* printerData,
const PrinterCap* printerCap)
: GraphicsDriver(message, printerData, printerCap)
{
}
bool
LpstylDriver::StartDocument()
{
_EjectAndReset();
_IdentifyPrinter();
_ColorCartridge();
return true;
}
bool
LpstylDriver::StartPage()
{
if (fPrinterType < kStyleWriter2400)
WriteSpoolData("nuA", 3);
else
WriteSpoolChar('L');
return true;
}
bool
LpstylDriver::NextBand(BBitmap* bitmap, BPoint* offset)
{
fprintf(stderr, "Next band at %f %f\n", offset->x, offset->y);
int page_height = GetPageHeight();
// Advance the cursor
offset->y += bitmap->Bounds().Height();
// Have we reached the end of the page yet?
if (offset->y >= page_height)
{
offset->y = -1;
offset->x = -1;
}
return true;
}
bool
LpstylDriver::EndPage(int page)
{
fprintf(stderr, "end page %d\n", page);
return true;
}
bool
LpstylDriver::EndDocument(bool success)
{
return true;
}
/** Eject the current page (if any) and reset the printer.
*/
void
LpstylDriver::_EjectAndReset(void)
{
_WriteFFFx('I');
int s1;
do {
for (;;) {
try {
s1 = _GetStatus('1');
break;
} catch(const TransportException&) {
continue;
}
}
if (s1 == 1) {
// Check for stylewriter1, where status 1 doesn't g to 0 on init.
if (_GetStatus('2') == 0 && _GetStatus('B') == 0xa0)
break;
}
} while (s1 == 1);
}
void
LpstylDriver::_IdentifyPrinter(void)
{
WriteSpoolChar('?');
char smallBuf[32];
int i = 0;
for (i = 0; i < 31; i++) {
smallBuf[i] = ReadSpoolChar();
if (smallBuf[i] == 0x0D)
break;
}
smallBuf[i] = 0;
if (strcmp(smallBuf, "IJ10\x0D") == 0)
fPrinterType = kStyleWriter;
else if (strcmp(smallBuf, "SW\x0D") == 0)
fPrinterType = kStyleWriter2;
else if (strcmp(smallBuf, "SW3\x0D") == 0)
fPrinterType = kStyleWriter3;
else if (strcmp(smallBuf, "CS\x0D") == 0) {
switch (_GetStatus('p'))
{
default:
case 1:
fPrinterType = kStyleWriter2400;
break;
case 2:
fPrinterType = kStyleWriter2200;
break;
case 4:
fPrinterType = kStyleWriter1500;
break;
case 5:
fPrinterType = kStyleWriter2500;
break;
}
}
}
bool
LpstylDriver::_ColorCartridge()
{
WriteSpoolChar('D');
unsigned char i = _GetStatus('H');
return i & 0x80;
}
/** Send a 4-byte command to the printer.
*
* These commands can be sent at any time, because their prefix is FFFFFF, a
* sequence which can't be generated by the data compression algorithm
*/
void
LpstylDriver::_WriteFFFx(char x)
{
unsigned char str[4];
str[0] = str[1] = str[2] = 0xFF;
str[3] = x;
WriteSpoolData(str, 4);
}
/** Get one of the printer status bytes.
*
* There are 3 status registers, 1, 2, and B. Each returns some different
* information about the printer state.
*/
int
LpstylDriver::_GetStatus(char reg)
{
_WriteFFFx(reg);
return ReadSpoolChar();
}

View File

@ -0,0 +1,51 @@
/*
* Copyright 2017, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrien Destugues <pulkomandy@pulkomandy.tk>
*/
#ifndef LPSTYL_H
#define LPSTYL_H
#include "GraphicsDriver.h"
enum PrinterType {
kStyleWriter,
kStyleWriter2,
kStyleWriter3,
kStyleWriter2400,
kStyleWriter2200,
kStyleWriter1500,
kStyleWriter2500
};
class LpstylDriver: public GraphicsDriver {
public:
LpstylDriver(BMessage* message, PrinterData* printerData,
const PrinterCap* printerCap);
protected:
bool StartDocument();
bool StartPage();
bool NextBand(BBitmap* bitmap, BPoint* offset);
bool EndPage(int page);
bool EndDocument(bool success);
private:
void _EjectAndReset(void);
void _IdentifyPrinter(void);
bool _ColorCartridge(void);
void _WriteFFFx(char x);
int _GetStatus(char reg);
private:
PrinterType fPrinterType;
};
#endif

View File

@ -0,0 +1,126 @@
/*
* Copyright 2017, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrien Destugues <pulkomandy@pulkomandy.tk>
*/
#include "LpstylCap.h"
#define TO72DPI(a) (a * 72.0f / 360.0f)
static const PaperCap a4(
"A4",
true,
JobData::kA4,
BRect(0.0f, 0.0f, TO72DPI(2975.0f), TO72DPI(4210.0f)),
BRect(TO72DPI(72.0f), TO72DPI(72.0f), TO72DPI(2903.0f), TO72DPI(4138.0f)));
static const PaperCap letter(
"Letter",
true,
JobData::kLetter,
BRect(0.0f, 0.0f, TO72DPI(3060.0f), TO72DPI(3960.0f)),
BRect(TO72DPI(72.0f), TO72DPI(72.0f), TO72DPI(2988.0f), TO72DPI(3888.0f)));
static const ResolutionCap dpi360("360dpi", true, 1, 360, 360);
static const PaperCap* papers[] = {
&a4,
&letter,
};
static const ResolutionCap* resolutions[] = {
&dpi360,
};
static const ColorCap color("Color", false, JobData::kColor);
static const ColorCap monochrome("Shades of Gray", true, JobData::kMonochrome);
static const ColorCap* colors[] = {
&color,
&monochrome
};
// This is required so libprint saves PrinterData in the printer spool dir.
static const ProtocolClassCap proto("Serial", true, 1, "Serial port");
static const ProtocolClassCap* protocols[] = {
&proto
};
int
LpstylCap::CountCap(CapID capid) const
{
switch (capid) {
case kPaper:
return sizeof(papers) / sizeof(papers[0]);
case kResolution:
return sizeof(resolutions) / sizeof(resolutions[0]);
#if 0
case kPaperSource:
return sizeof(papersources) / sizeof(papersources[0]);
case kPrintStyle:
return sizeof(printstyles) / sizeof(printstyles[0]);
case kBindingLocation:
return sizeof(bindinglocations) / sizeof(bindinglocations[0]);
#endif
case kColor:
return sizeof(colors) / sizeof(colors[0]);
case kProtocolClass:
return sizeof(protocols) / sizeof(protocols[0]);
default:
return 0;
}
}
const BaseCap**
LpstylCap::GetCaps(CapID capid) const
{
switch (capid) {
case kPaper:
return (const BaseCap **)papers;
case kResolution:
return (const BaseCap **)resolutions;
#if 0
case kPaperSource:
return (const BaseCap **)papersources;
case kPrintStyle:
return (const BaseCap **)printstyles;
case kBindingLocation:
return (const BaseCap **)bindinglocations;
#endif
case kProtocolClass:
return (const BaseCap **)protocols;
case kColor:
return (const BaseCap **)colors;
default:
return NULL;
}
}
bool
LpstylCap::Supports(CapID capid) const
{
switch (capid) {
case kPaper:
case kResolution:
case kColor:
case kProtocolClass:
return true;
case kPaperSource:
case kPrintStyle:
case kBindingLocation:
case kCopyCommand:
case kHalftone:
default:
return false;
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright 2017, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrien Destugues <pulkomandy@pulkomandy.tk>
*/
#ifndef LPSTYLCAP_H
#define LPSTYLCAP_H
#include "PrinterCap.h"
class LpstylCap : public PrinterCap {
public:
LpstylCap(const PrinterData* printer_data)
: PrinterCap(printer_data) {}
virtual int CountCap(CapID) const;
virtual bool Supports(CapID) const;
virtual const BaseCap** GetCaps(CapID) const;
};
#endif // __LIPS4CAP_H

View File

@ -0,0 +1,25 @@
/*
* Copyright 2017, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrien Destugues <pulkomandy@pulkomandy.tk>
*/
#include "LpstylData.h"
#include <termios.h>
#include <Node.h>
#include <SupportKit.h>
void
LpstylData::Save()
{
PrinterData::Save();
// force baudrate for the serial transport
int32 rate = B57600;
fNode->WriteAttr("transport_baudrate", B_INT32_TYPE, 0, &rate, sizeof(int32));
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2017, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrien Destugues <pulkomandy@pulkomandy.tk>
*/
#ifndef LPSTYLDATA_H
#define LPSTYLDATA_H
#include "PrinterData.h"
class BNode;
class LpstylData : public PrinterData {
public:
LpstylData(BNode* node)
:
PrinterData(node)
{
}
// PrinterData overrides
virtual void Save();
};
#endif // LPSTYLDATA_H

View File

@ -0,0 +1,62 @@
/*
* Copyright 2017, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrien Destugues <pulkomandy@pulkomandy.tk>
*/
#include "Lpstyl.h"
#include "LpstylCap.h"
#include "LpstylData.h"
#include "PrinterDriver.h"
class LpstylPrinterDriver : public PrinterDriver
{
public:
LpstylPrinterDriver(BNode* printerFolder)
: PrinterDriver(printerFolder)
{}
const char* GetSignature() const
{
return "application/x-vnd.lpstyl";
}
const char* GetDriverName() const
{
return "Apple StyleWriter";
}
const char* GetVersion() const
{
return "1.0.0";
}
const char* GetCopyright() const
{
return "Copyright 1996-2000 Monroe Williams, 2017 Adrien Destugues.\n";
}
PrinterData* InstantiatePrinterData(BNode* node)
{
return new LpstylData(node);
}
PrinterCap* InstantiatePrinterCap(PrinterData* printerData)
{
return new LpstylCap(printerData);
}
GraphicsDriver* InstantiateGraphicsDriver(BMessage* settings,
PrinterData* printerData, PrinterCap* printerCap)
{
return new LpstylDriver(settings, printerData, printerCap);
}
};
PrinterDriver*
instantiate_printer_driver(BNode* printerFolder)
{
return new LpstylPrinterDriver(printerFolder);
}