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 11 LpstylDriver::LpstylDriver(BMessage* message, PrinterData* printerData, 12 const PrinterCap* printerCap) 13 : GraphicsDriver(message, printerData, printerCap) 14 { 15 } 16 17 18 bool 19 LpstylDriver::StartDocument() 20 { 21 _EjectAndReset(); 22 _IdentifyPrinter(); 23 _ColorCartridge(); 24 return true; 25 } 26 27 28 bool 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 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 61 LpstylDriver::EndPage(int page) 62 { 63 fprintf(stderr, "end page %d\n", page); 64 return true; 65 } 66 67 68 bool 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 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 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 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 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 174 LpstylDriver::_GetStatus(char reg) 175 { 176 _WriteFFFx(reg); 177 return ReadSpoolChar(); 178 } 179