|
|
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.9 ! root 15: const char Printer_rcsid[] = "Hatari $Id: printer.c,v 1.23 2008/02/23 16:51:27 thothy Exp $";
1.1.1.4 root 16:
1.1 root 17: #include "main.h"
1.1.1.9 ! root 18: #include "configuration.h"
1.1 root 19: #include "file.h"
1.1.1.9 ! root 20: #include "paths.h"
1.1 root 21: #include "printer.h"
1.1.1.3 root 22:
1.1.1.5 root 23: /* #define PRINTER_DEBUG */
24:
1.1.1.9 ! root 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.9 ! root 32: static Uint8 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.1.9 ! root 35: static BOOL bConnectedPrinter;
1.1.1.5 root 36: static int nIdleCount;
1.1 root 37:
1.1.1.9 ! root 38: static FILE *pPrinterHandle;
! 39:
! 40:
! 41: /* internal functions */
! 42: static void Printer_EmptyFile(void);
! 43: static void Printer_ResetInternalBuffer(void);
! 44: static void Printer_ResetCharsOnLine(void);
! 45: static BOOL Printer_EmptyInternalBuffer(void);
! 46: static BOOL Printer_ValidByte(Uint8 Byte);
! 47: static void Printer_AddByteToInternalBuffer(Uint8 Byte);
! 48: static void Printer_AddTabToInternalBuffer(void);
1.1.1.2 root 49:
1.1.1.5 root 50:
1.1.1.6 root 51: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 52: /**
! 53: * Initialise Printer
! 54: */
1.1 root 55: void Printer_Init(void)
56: {
1.1.1.5 root 57: #ifdef PRINTER_DEBUG
58: fprintf(stderr,"Printer_Init()\n");
59: #endif
60:
61: /* A valid file name for printing is already set up in configuration.c.
62: * But we check it again since the user might have entered an invalid
1.1.1.9 ! root 63: * file name in the hatari.cfg file... */
1.1.1.6 root 64: if (strlen(ConfigureParams.Printer.szPrintToFileName) <= 1)
1.1.1.5 root 65: {
1.1.1.9 ! root 66: const char *psHomeDir;
! 67: psHomeDir = Paths_GetHatariHome();
! 68:
1.1.1.5 root 69: /* construct filename for printing.... */
1.1.1.9 ! root 70: if (strlen(psHomeDir)+1+strlen(PRINTER_FILENAME) < sizeof(ConfigureParams.Printer.szPrintToFileName))
! 71: {
! 72: sprintf(ConfigureParams.Printer.szPrintToFileName, "%s%c%s",
! 73: psHomeDir, PATHSEP, PRINTER_FILENAME);
! 74: }
1.1.1.5 root 75: else
1.1.1.9 ! root 76: {
! 77: strcpy(ConfigureParams.Printer.szPrintToFileName, PRINTER_FILENAME);
! 78: }
1.1.1.5 root 79: }
80:
81: #ifdef PRINTER_DEBUG
82: fprintf(stderr,"Filename for printing: %s \n", ConfigureParams.Printer.szPrintToFileName);
83: #endif
1.1 root 84: }
85:
1.1.1.2 root 86:
87: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 88: /**
! 89: * Uninitialise Printer
! 90: */
1.1 root 91: void Printer_UnInit(void)
92: {
1.1.1.6 root 93: /* Close any open files */
94: Printer_CloseAllConnections();
95:
1.1.1.5 root 96: #ifdef PRINTER_DEBUG
97: fprintf(stderr,"Printer_UnInit()\n");
98: #endif
1.1 root 99: }
100:
1.1.1.2 root 101:
102: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 103: /**
! 104: * Close all open output file, empty buffers etc.
! 105: */
1.1 root 106: void Printer_CloseAllConnections(void)
107: {
1.1.1.6 root 108: /* Empty buffer */
109: Printer_EmptyInternalBuffer();
1.1 root 110:
1.1.1.6 root 111: /* Close any open files */
1.1.1.9 ! root 112: pPrinterHandle = File_Close(pPrinterHandle);
1.1 root 113:
1.1.1.6 root 114: /* Signal finished with printing */
115: bConnectedPrinter = FALSE;
1.1 root 116: }
117:
1.1.1.2 root 118:
1.1.1.6 root 119: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 120: /**
! 121: * Reset Printer Buffer
! 122: */
! 123: static void Printer_ResetInternalBuffer(void)
1.1 root 124: {
1.1.1.9 ! root 125: nPrinterBufferChars = 0;
1.1 root 126: }
127:
1.1.1.2 root 128:
1.1.1.6 root 129: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 130: /**
! 131: * Reset character line
! 132: */
! 133: static void Printer_ResetCharsOnLine(void)
1.1 root 134: {
1.1.1.9 ! root 135: nPrinterBufferCharsOnLine = 0;
1.1 root 136: }
137:
1.1.1.2 root 138:
1.1.1.6 root 139: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 140: /**
! 141: * Empty to file on disk.
! 142: */
! 143: static void Printer_EmptyFile(void)
1.1 root 144: {
1.1.1.6 root 145: /* Do have file open? */
1.1.1.9 ! root 146: if (pPrinterHandle)
1.1.1.6 root 147: {
148: /* Write bytes out */
1.1.1.9 ! root 149: if (fwrite((Uint8 *)PrinterBuffer,sizeof(Uint8),nPrinterBufferChars,pPrinterHandle) < nPrinterBufferChars)
1.1.1.6 root 150: {
151: /* we wrote less then all chars in the buffer --> ERROR */
1.1.1.7 root 152: fprintf(stderr,"Printer_EmptyFile(): ERROR not all chars were written\n");
1.1.1.6 root 153: }
154: /* Reset */
155: Printer_ResetInternalBuffer();
156: }
1.1 root 157: }
158:
1.1.1.2 root 159:
1.1.1.6 root 160: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 161: /**
! 162: * Empty Printer Buffer
! 163: */
! 164: static BOOL Printer_EmptyInternalBuffer(void)
1.1 root 165: {
1.1.1.6 root 166: /* Write bytes to file */
1.1.1.9 ! root 167: if (nPrinterBufferChars > 0)
1.1.1.6 root 168: {
1.1.1.9 ! root 169: if (pPrinterHandle)
1.1.1.7 root 170: Printer_EmptyFile();
1.1 root 171:
1.1.1.6 root 172: return TRUE;
173: }
174: /* Nothing to do */
175: return FALSE;
1.1 root 176: }
177:
1.1.1.2 root 178:
1.1.1.6 root 179: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 180: /**
! 181: * Return TRUE if byte is standard ASCII character which is OK to output
! 182: */
! 183: static BOOL Printer_ValidByte(Uint8 Byte)
1.1 root 184: {
1.1.1.6 root 185: /* Return/New line? */
186: if ((Byte == 0x0d) || (Byte == 0x0a))
187: return TRUE;
188: /* Normal character? */
189: if ((Byte >= 32) && (Byte < 127))
190: return TRUE;
191: /* Tab */
192: if (Byte == '\t')
193: return TRUE;
194: return FALSE;
1.1 root 195: }
196:
1.1.1.2 root 197:
198: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 199: /**
! 200: * Add byte to our internal buffer, and when full write out - needed to speed
! 201: */
! 202: static void Printer_AddByteToInternalBuffer(Uint8 Byte)
1.1 root 203: {
1.1.1.6 root 204: /* Is buffer full? If so empty */
205: if (nPrinterBufferChars == PRINTER_BUFFER_SIZE)
206: Printer_EmptyInternalBuffer();
207: /* Add character */
208: PrinterBuffer[nPrinterBufferChars++] = Byte;
209: /* Add count of character on line */
210: if (!((Byte == 0xd) || (Byte == 0xa)))
211: nPrinterBufferCharsOnLine++;
1.1 root 212: }
213:
1.1.1.2 root 214:
1.1.1.6 root 215: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 216: /**
! 217: * Add 'Tab' to internal buffer
! 218: */
! 219: static void Printer_AddTabToInternalBuffer(void)
1.1 root 220: {
1.1.1.6 root 221: int i,NumSpaces;
1.1 root 222:
1.1.1.6 root 223: /* Is buffer full? If so empty */
224: if (nPrinterBufferChars >= (PRINTER_BUFFER_SIZE-PRINTER_TAB_SETTING))
225: Printer_EmptyInternalBuffer();
226: /* Add tab - convert to 'PRINTER_TAB_SETTING' space */
227: NumSpaces = PRINTER_TAB_SETTING-(nPrinterBufferCharsOnLine%PRINTER_TAB_SETTING);
228: for(i = 0; i < NumSpaces; i++)
229: {
230: PrinterBuffer[nPrinterBufferChars++] = ' ';
231: nPrinterBufferCharsOnLine++;
232: }
1.1 root 233: }
234:
1.1.1.2 root 235:
1.1.1.6 root 236: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 237: /**
! 238: * Pass byte from emulator to printer. Opens the printer file appending
! 239: * if it isn't already open. Returns FALSE if connection to "printer"
! 240: * failed
! 241: */
! 242: BOOL Printer_TransferByteTo(Uint8 Byte)
1.1 root 243: {
1.1.1.6 root 244: /* Do we want to output to a printer/file? */
245: if (!ConfigureParams.Printer.bEnablePrinting)
246: return FALSE; /* Failed if printing disabled */
247:
248: /* Have we made a connection to our printer/file? */
249: if (!bConnectedPrinter)
250: {
1.1.1.9 ! root 251: /* open printer file... */
! 252: pPrinterHandle = File_Open(ConfigureParams.Printer.szPrintToFileName, "a+");
! 253: bConnectedPrinter = (pPrinterHandle != NULL);
1.1.1.6 root 254:
255: /* Reset the printer */
256: Printer_ResetInternalBuffer();
257: Printer_ResetCharsOnLine();
258: }
259:
260: /* Is all OK? */
261: if (bConnectedPrinter)
262: {
263: /* Add byte to our buffer, if is useable character */
264: if (Printer_ValidByte(Byte))
265: {
266: if (Byte == '\t')
267: Printer_AddTabToInternalBuffer();
268: else
269: Printer_AddByteToInternalBuffer(Byte);
270: if (Byte == 0xd)
271: nPrinterBufferCharsOnLine = 0;
272: }
1.1.1.5 root 273:
1.1.1.6 root 274: return TRUE; /* OK */
275: }
276: else
277: return FALSE; /* Failed */
1.1 root 278: }
279:
1.1.1.2 root 280:
1.1.1.6 root 281: /*-----------------------------------------------------------------------*/
1.1.1.9 ! root 282: /**
! 283: * Empty printer buffer, and if remains idle for set time close connection
! 284: * (ie close file, stop printer)
! 285: */
1.1 root 286: void Printer_CheckIdleStatus(void)
287: {
1.1.1.6 root 288: /* Is anything waiting for printer? */
289: if (Printer_EmptyInternalBuffer())
290: {
291: nIdleCount = 0;
292: }
293: else
294: {
295: nIdleCount++;
296: /* Has printer been idle? */
297: if (nIdleCount >= PRINTER_IDLE_CLOSE)
298: {
299: /* Close printer output */
300: Printer_CloseAllConnections();
301: nIdleCount = 0;
302: }
303: }
1.1 root 304: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.