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