xref: /haiku/src/add-ons/print/drivers/lpstyl/Lpstyl.cpp (revision d9949ac911df2fb1023ee4b14fa34a41633e370a)
1 /*
2 * Copyright 2017, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Adrien Destugues <pulkomandy@pulkomandy.tk>
7 */
8 #include "Lpstyl.h"
9 
10 
LpstylDriver(BMessage * message,PrinterData * printerData,const PrinterCap * printerCap)11 LpstylDriver::LpstylDriver(BMessage* message, PrinterData* printerData,
12 	const PrinterCap* printerCap)
13 	: GraphicsDriver(message, printerData, printerCap)
14 {
15 }
16 
17 
18 bool
StartDocument()19 LpstylDriver::StartDocument()
20 {
21 	_EjectAndReset();
22 	_IdentifyPrinter();
23 	_ColorCartridge();
24 	return true;
25 }
26 
27 
28 bool
StartPage()29 LpstylDriver::StartPage()
30 {
31 	if (fPrinterType < kStyleWriter2400)
32 		WriteSpoolData("nuA", 3);
33 	else
34 		WriteSpoolChar('L');
35 	return true;
36 }
37 
38 
39 bool
NextBand(BBitmap * bitmap,BPoint * offset)40 LpstylDriver::NextBand(BBitmap* bitmap, BPoint* offset)
41 {
42 	fprintf(stderr, "Next band at %f %f\n", offset->x, offset->y);
43 
44 	int page_height = GetPageHeight();
45 
46 	// Advance the cursor
47 	offset->y += bitmap->Bounds().Height();
48 
49 	// Have we reached the end of the page yet?
50 	if (offset->y >= page_height)
51 	{
52 		offset->y = -1;
53 		offset->x = -1;
54 	}
55 
56 	return true;
57 }
58 
59 
60 bool
EndPage(int page)61 LpstylDriver::EndPage(int page)
62 {
63 	fprintf(stderr, "end page %d\n", page);
64 	return true;
65 }
66 
67 
68 bool
EndDocument(bool success)69 LpstylDriver::EndDocument(bool success)
70 {
71 	return true;
72 }
73 
74 
75 /** Eject the current page (if any) and reset the printer.
76  */
77 void
_EjectAndReset(void)78 LpstylDriver::_EjectAndReset(void)
79 {
80 	_WriteFFFx('I');
81 
82 	int s1;
83 
84 	do {
85 		for (;;) {
86 			try {
87 				s1 = _GetStatus('1');
88 				break;
89 			} catch(const TransportException&) {
90 				continue;
91 			}
92 		}
93 
94 		if (s1 == 1) {
95 			// Check for stylewriter1, where status 1 doesn't g to 0 on init.
96 			if (_GetStatus('2') == 0 && _GetStatus('B') == 0xa0)
97 				break;
98 		}
99 	} while (s1 == 1);
100 }
101 
102 
103 void
_IdentifyPrinter(void)104 LpstylDriver::_IdentifyPrinter(void)
105 {
106 	WriteSpoolChar('?');
107 
108 	char smallBuf[32];
109 	int i = 0;
110 	for (i = 0; i < 31; i++) {
111 		smallBuf[i] = ReadSpoolChar();
112 		if (smallBuf[i] == 0x0D)
113 			break;
114 	}
115 	smallBuf[i] = 0;
116 
117 	if (strcmp(smallBuf, "IJ10\x0D") == 0)
118 		fPrinterType = kStyleWriter;
119 	else if (strcmp(smallBuf, "SW\x0D") == 0)
120 		fPrinterType = kStyleWriter2;
121 	else if (strcmp(smallBuf, "SW3\x0D") == 0)
122 		fPrinterType = kStyleWriter3;
123 	else if (strcmp(smallBuf, "CS\x0D") == 0) {
124 		switch (_GetStatus('p'))
125 		{
126 			default:
127 			case 1:
128 				fPrinterType = kStyleWriter2400;
129 				break;
130 			case 2:
131 				fPrinterType = kStyleWriter2200;
132 				break;
133 			case 4:
134 				fPrinterType = kStyleWriter1500;
135 				break;
136 			case 5:
137 				fPrinterType = kStyleWriter2500;
138 				break;
139 		}
140 	}
141 }
142 
143 
144 bool
_ColorCartridge()145 LpstylDriver::_ColorCartridge()
146 {
147 	WriteSpoolChar('D');
148 	unsigned char i = _GetStatus('H');
149 	return i & 0x80;
150 }
151 
152 
153 /** Send a 4-byte command to the printer.
154  *
155  * These commands can be sent at any time, because their prefix is FFFFFF, a
156  * sequence which can't be generated by the data compression algorithm
157  */
158 void
_WriteFFFx(char x)159 LpstylDriver::_WriteFFFx(char x)
160 {
161 	unsigned char str[4];
162 	str[0] = str[1] = str[2] = 0xFF;
163 	str[3] = x;
164 	WriteSpoolData(str, 4);
165 }
166 
167 
168 /** Get one of the printer status bytes.
169  *
170  * There are 3 status registers, 1, 2, and B. Each returns some different
171  * information about the printer state.
172  */
173 int
_GetStatus(char reg)174 LpstylDriver::_GetStatus(char reg)
175 {
176 	_WriteFFFx(reg);
177 	return ReadSpoolChar();
178 }
179