|
|
1.1 root 1: /*
1.1.1.5 root 2: Hatari - printer.c
1.1 root 3:
1.1.1.5 root 4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
1.1.1.6 root 7: Printer communication. When bytes are sent from the ST they are sent to these
8: functions via 'Printer_TransferByteTo()'. This will then open a file and
9: direct the output to this. These bytes are buffered up (to improve speed) and
10: this also allow us to detect when the stream goes into idle - at which point
11: we close the file/printer.
12: NOTE - Tab's are converted to spaces as the PC 'Tab' setting differs to that
13: of the ST.
1.1.1.5 root 14: */
1.1.1.8 ! root 15: const char Printer_rcsid[] = "Hatari $Id: printer.c,v 1.18 2006/02/08 22:49:27 eerot Exp $";
1.1.1.4 root 16:
1.1 root 17: #include "main.h"
18: #include "dialog.h"
19: #include "file.h"
20: #include "printer.h"
21: #include "screen.h"
1.1.1.3 root 22:
1.1.1.5 root 23: /* #define PRINTER_DEBUG */
24:
25: #define PRINTER_FILENAME "/hatari.prn"
1.1 root 26:
27: #define PRINTER_TAB_SETTING 8 /* A 'Tab' on the ST is 8 spaces */
1.1.1.6 root 28: #define PRINTER_IDLE_CLOSE (4*50) /* After 4 seconds, close printer */
1.1 root 29:
30: #define PRINTER_BUFFER_SIZE 2048 /* 2k buffer which when full will be written to printer/file */
31:
1.1.1.2 root 32: static unsigned char PrinterBuffer[PRINTER_BUFFER_SIZE]; /* Buffer to store character before output */
1.1.1.6 root 33: static size_t nPrinterBufferChars; /* # characters in above buffer */
1.1.1.5 root 34: static int nPrinterBufferCharsOnLine;
1.1 root 35: static BOOL bConnectedPrinter=FALSE;
1.1.1.7 root 36: static BOOL bPrinterFile = FALSE;
1.1.1.5 root 37: static int nIdleCount;
1.1 root 38:
1.1.1.5 root 39: static FILE *PrinterFileHandle;
1.1.1.2 root 40:
1.1.1.5 root 41:
1.1.1.6 root 42: /*-----------------------------------------------------------------------*/
43: /*
1.1 root 44: Initialise Printer
1.1.1.6 root 45: */
1.1 root 46: void Printer_Init(void)
47: {
1.1.1.5 root 48: #ifdef PRINTER_DEBUG
49: fprintf(stderr,"Printer_Init()\n");
50: #endif
51:
52: /* A valid file name for printing is already set up in configuration.c.
53: * But we check it again since the user might have entered an invalid
54: * file name in the ~/.hatari.cfg file... */
1.1.1.6 root 55: if (strlen(ConfigureParams.Printer.szPrintToFileName) <= 1)
1.1.1.5 root 56: {
57: /* construct filename for printing.... */
58: if (getenv("HOME") != NULL
1.1.1.6 root 59: && strlen(getenv("HOME"))+strlen(PRINTER_FILENAME) < sizeof(ConfigureParams.Printer.szPrintToFileName))
1.1.1.5 root 60: sprintf(ConfigureParams.Printer.szPrintToFileName, "%s%s", getenv("HOME"), PRINTER_FILENAME);
61: else
62: sprintf(ConfigureParams.Printer.szPrintToFileName, ".%s",PRINTER_FILENAME);
63: }
64:
65: #ifdef PRINTER_DEBUG
66: fprintf(stderr,"Filename for printing: %s \n", ConfigureParams.Printer.szPrintToFileName);
67: #endif
1.1 root 68: }
69:
1.1.1.2 root 70:
71: /*-----------------------------------------------------------------------*/
1.1 root 72: /*
73: Uninitialise Printer
74: */
75: void Printer_UnInit(void)
76: {
1.1.1.6 root 77: /* Close any open files */
78: Printer_CloseAllConnections();
79:
1.1.1.5 root 80: #ifdef PRINTER_DEBUG
81: fprintf(stderr,"Printer_UnInit()\n");
82: #endif
1.1 root 83: }
84:
1.1.1.2 root 85:
86: /*-----------------------------------------------------------------------*/
1.1 root 87: /*
1.1.1.6 root 88: Close all open files etc.
1.1 root 89: */
90: void Printer_CloseAllConnections(void)
91: {
1.1.1.6 root 92: /* Empty buffer */
93: Printer_EmptyInternalBuffer();
1.1 root 94:
1.1.1.6 root 95: /* Close any open files */
1.1.1.7 root 96: Printer_CloseFile();
1.1 root 97:
1.1.1.6 root 98: /* Signal finished with printing */
99: bConnectedPrinter = FALSE;
1.1 root 100: }
101:
1.1.1.2 root 102:
1.1.1.6 root 103: /*-----------------------------------------------------------------------*/
104: /*
1.1.1.7 root 105: Open file on disk, to which all printer output will be sent.
1.1.1.6 root 106: */
1.1.1.7 root 107: BOOL Printer_OpenFile(void)
1.1 root 108: {
109:
1.1.1.7 root 110: bPrinterFile = TRUE;
1.1 root 111:
1.1.1.6 root 112: /* open printer file... */
113: PrinterFileHandle = fopen(ConfigureParams.Printer.szPrintToFileName, "a+");
114: if (!PrinterFileHandle)
1.1.1.7 root 115: bPrinterFile = FALSE;
1.1 root 116:
1.1.1.7 root 117: return bPrinterFile;
1.1 root 118: }
119:
1.1.1.2 root 120:
1.1.1.6 root 121: /*-----------------------------------------------------------------------*/
122: /*
1.1.1.7 root 123: Close file on disk, if we have one open.
1.1.1.6 root 124: */
1.1.1.7 root 125: void Printer_CloseFile(void)
1.1 root 126: {
1.1.1.6 root 127: /* Do have file open? */
1.1.1.7 root 128: if (bPrinterFile)
1.1.1.6 root 129: {
130: /* Close */
131: fclose(PrinterFileHandle);
1.1.1.7 root 132: bPrinterFile = FALSE;
1.1.1.6 root 133: }
1.1 root 134: }
135:
1.1.1.2 root 136:
1.1.1.6 root 137: /*-----------------------------------------------------------------------*/
138: /*
1.1.1.7 root 139: Empty to file on disk.
1.1.1.6 root 140: */
1.1.1.7 root 141: void Printer_EmptyFile(void)
1.1 root 142: {
1.1.1.6 root 143: /* Do have file open? */
1.1.1.7 root 144: if (bPrinterFile)
1.1.1.6 root 145: {
146: /* Write bytes out */
147: if (fwrite((unsigned char *)PrinterBuffer,sizeof(unsigned char),nPrinterBufferChars,PrinterFileHandle) < nPrinterBufferChars)
148: {
149: /* we wrote less then all chars in the buffer --> ERROR */
1.1.1.7 root 150: fprintf(stderr,"Printer_EmptyFile(): ERROR not all chars were written\n");
1.1.1.6 root 151: }
152: /* Reset */
153: Printer_ResetInternalBuffer();
154: }
1.1 root 155: }
156:
1.1.1.2 root 157:
1.1.1.6 root 158: /*-----------------------------------------------------------------------*/
159: /*
1.1 root 160: Reset Printer Buffer
1.1.1.6 root 161: */
1.1 root 162: void Printer_ResetInternalBuffer(void)
163: {
1.1.1.6 root 164: nPrinterBufferChars = 0;
1.1 root 165: }
166:
1.1.1.6 root 167:
168: /*-----------------------------------------------------------------------*/
169: /*
1.1 root 170: Reset character line
1.1.1.6 root 171: */
1.1 root 172: void Printer_ResetCharsOnLine(void)
173: {
1.1.1.6 root 174: nPrinterBufferCharsOnLine = 0;
1.1 root 175: }
176:
1.1.1.2 root 177:
1.1.1.6 root 178: /*-----------------------------------------------------------------------*/
179: /*
1.1 root 180: Empty Printer Buffer
1.1.1.6 root 181: */
1.1 root 182: BOOL Printer_EmptyInternalBuffer(void)
183: {
1.1.1.6 root 184: /* Write bytes to file */
185: if (nPrinterBufferChars>0)
186: {
1.1.1.7 root 187: if (bPrinterFile)
188: Printer_EmptyFile();
1.1 root 189:
1.1.1.6 root 190: return TRUE;
191: }
1.1 root 192:
1.1.1.6 root 193: /* Nothing to do */
194: return FALSE;
1.1 root 195: }
196:
1.1.1.2 root 197:
1.1.1.6 root 198: /*-----------------------------------------------------------------------*/
199: /*
1.1 root 200: Return TRUE if byte is standard ASCII character which is OK to output
1.1.1.6 root 201: */
1.1 root 202: BOOL Printer_ValidByte(unsigned char Byte)
203: {
1.1.1.6 root 204: /* Return/New line? */
205: if ((Byte == 0x0d) || (Byte == 0x0a))
206: return TRUE;
207: /* Normal character? */
208: if ((Byte >= 32) && (Byte < 127))
209: return TRUE;
210: /* Tab */
211: if (Byte == '\t')
212: return TRUE;
213: return FALSE;
1.1 root 214: }
215:
1.1.1.2 root 216:
217: /*-----------------------------------------------------------------------*/
1.1 root 218: /*
219: Add byte to our internal buffer, and when full write out - needed to speed
220: */
221: void Printer_AddByteToInternalBuffer(unsigned char Byte)
222: {
1.1.1.6 root 223: /* Is buffer full? If so empty */
224: if (nPrinterBufferChars == PRINTER_BUFFER_SIZE)
225: Printer_EmptyInternalBuffer();
226: /* Add character */
227: PrinterBuffer[nPrinterBufferChars++] = Byte;
228: /* Add count of character on line */
229: if (!((Byte == 0xd) || (Byte == 0xa)))
230: nPrinterBufferCharsOnLine++;
1.1 root 231: }
232:
1.1.1.2 root 233:
1.1.1.6 root 234: /*-----------------------------------------------------------------------*/
235: /*
1.1 root 236: Add 'Tab' to internal buffer
1.1.1.6 root 237: */
1.1 root 238: void Printer_AddTabToInternalBuffer(void)
239: {
1.1.1.6 root 240: int i,NumSpaces;
1.1 root 241:
1.1.1.6 root 242: /* Is buffer full? If so empty */
243: if (nPrinterBufferChars >= (PRINTER_BUFFER_SIZE-PRINTER_TAB_SETTING))
244: Printer_EmptyInternalBuffer();
245: /* Add tab - convert to 'PRINTER_TAB_SETTING' space */
246: NumSpaces = PRINTER_TAB_SETTING-(nPrinterBufferCharsOnLine%PRINTER_TAB_SETTING);
247: for(i = 0; i < NumSpaces; i++)
248: {
249: PrinterBuffer[nPrinterBufferChars++] = ' ';
250: nPrinterBufferCharsOnLine++;
251: }
1.1 root 252: }
253:
1.1.1.2 root 254:
1.1.1.6 root 255: /*-----------------------------------------------------------------------*/
256: /*
1.1 root 257: Pass byte from emulator to printer
1.1.1.6 root 258: */
1.1 root 259: BOOL Printer_TransferByteTo(unsigned char Byte)
260: {
1.1.1.6 root 261: /* Do we want to output to a printer/file? */
262: if (!ConfigureParams.Printer.bEnablePrinting)
263: return FALSE; /* Failed if printing disabled */
264:
265: /* Have we made a connection to our printer/file? */
266: if (!bConnectedPrinter)
267: {
1.1.1.7 root 268: bConnectedPrinter = Printer_OpenFile();
1.1.1.6 root 269:
270: /* Reset the printer */
271: Printer_ResetInternalBuffer();
272: Printer_ResetCharsOnLine();
273: }
274:
275: /* Is all OK? */
276: if (bConnectedPrinter)
277: {
278: /* Add byte to our buffer, if is useable character */
279: if (Printer_ValidByte(Byte))
280: {
281: if (Byte == '\t')
282: Printer_AddTabToInternalBuffer();
283: else
284: Printer_AddByteToInternalBuffer(Byte);
285: if (Byte == 0xd)
286: nPrinterBufferCharsOnLine = 0;
287: }
1.1.1.5 root 288:
1.1.1.6 root 289: return TRUE; /* OK */
290: }
291: else
292: return FALSE; /* Failed */
1.1 root 293: }
294:
1.1.1.2 root 295:
1.1.1.6 root 296: /*-----------------------------------------------------------------------*/
297: /*
1.1.1.5 root 298: Empty printer buffer, and if remains idle for set time close connection
299: (ie close file, stop printer)
1.1.1.6 root 300: */
1.1 root 301: void Printer_CheckIdleStatus(void)
302: {
1.1.1.6 root 303: /* Is anything waiting for printer? */
304: if (Printer_EmptyInternalBuffer())
305: {
306: nIdleCount = 0;
307: }
308: else
309: {
310: nIdleCount++;
311: /* Has printer been idle? */
312: if (nIdleCount >= PRINTER_IDLE_CLOSE)
313: {
314: /* Close printer output */
315: Printer_CloseAllConnections();
316: nIdleCount = 0;
317: }
318: }
1.1 root 319: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.