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
11LpstylDriver::LpstylDriver(BMessage* message, PrinterData* printerData,
12	const PrinterCap* printerCap)
13	: GraphicsDriver(message, printerData, printerCap)
14{
15}
16
17
18bool
19LpstylDriver::StartDocument()
20{
21	_EjectAndReset();
22	_IdentifyPrinter();
23	_ColorCartridge();
24	return true;
25}
26
27
28bool
29LpstylDriver::StartPage()
30{
31	if (fPrinterType < kStyleWriter2400)
32		WriteSpoolData("nuA", 3);
33	else
34		WriteSpoolChar('L');
35	return true;
36}
37
38
39bool
40LpstylDriver::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
60bool
61LpstylDriver::EndPage(int page)
62{
63	fprintf(stderr, "end page %d\n", page);
64	return true;
65}
66
67
68bool
69LpstylDriver::EndDocument(bool success)
70{
71	return true;
72}
73
74
75/** Eject the current page (if any) and reset the printer.
76 */
77void
78LpstylDriver::_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
103void
104LpstylDriver::_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
144bool
145LpstylDriver::_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 */
158void
159LpstylDriver::_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 */
173int
174LpstylDriver::_GetStatus(char reg)
175{
176	_WriteFFFx(reg);
177	return ReadSpoolChar();
178}
179