|
|
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.
1.1.1.5 root 12: */
1.1.1.11 root 13: const char Printer_fileid[] = "Hatari printer.c : " __DATE__ " " __TIME__;
1.1.1.4 root 14:
1.1 root 15: #include "main.h"
1.1.1.9 root 16: #include "configuration.h"
1.1 root 17: #include "file.h"
1.1.1.9 root 18: #include "paths.h"
1.1 root 19: #include "printer.h"
1.1.1.3 root 20:
1.1.1.5 root 21: /* #define PRINTER_DEBUG */
22:
1.1.1.9 root 23: #define PRINTER_FILENAME "hatari.prn"
1.1 root 24:
1.1.1.6 root 25: #define PRINTER_IDLE_CLOSE (4*50) /* After 4 seconds, close printer */
1.1 root 26:
27: #define PRINTER_BUFFER_SIZE 2048 /* 2k buffer which when full will be written to printer/file */
28:
1.1.1.9 root 29: static Uint8 PrinterBuffer[PRINTER_BUFFER_SIZE]; /* Buffer to store character before output */
1.1.1.6 root 30: static size_t nPrinterBufferChars; /* # characters in above buffer */
1.1.1.10 root 31: static bool bConnectedPrinter;
1.1.1.5 root 32: static int nIdleCount;
1.1 root 33:
1.1.1.9 root 34: static FILE *pPrinterHandle;
35:
36:
37: /* internal functions */
38: static void Printer_EmptyFile(void);
39: static void Printer_ResetInternalBuffer(void);
1.1.1.10 root 40: static bool Printer_EmptyInternalBuffer(void);
1.1.1.9 root 41: static void Printer_AddByteToInternalBuffer(Uint8 Byte);
1.1.1.2 root 42:
1.1.1.5 root 43:
1.1.1.6 root 44: /*-----------------------------------------------------------------------*/
1.1.1.9 root 45: /**
46: * Initialise Printer
47: */
1.1 root 48: void Printer_Init(void)
49: {
1.1.1.5 root 50: #ifdef PRINTER_DEBUG
51: fprintf(stderr,"Printer_Init()\n");
52: #endif
53:
54: /* A valid file name for printing is already set up in configuration.c.
55: * But we check it again since the user might have entered an invalid
1.1.1.9 root 56: * file name in the hatari.cfg file... */
1.1.1.6 root 57: if (strlen(ConfigureParams.Printer.szPrintToFileName) <= 1)
1.1.1.5 root 58: {
1.1.1.9 root 59: const char *psHomeDir;
60: psHomeDir = Paths_GetHatariHome();
61:
1.1.1.5 root 62: /* construct filename for printing.... */
1.1.1.9 root 63: if (strlen(psHomeDir)+1+strlen(PRINTER_FILENAME) < sizeof(ConfigureParams.Printer.szPrintToFileName))
64: {
65: sprintf(ConfigureParams.Printer.szPrintToFileName, "%s%c%s",
66: psHomeDir, PATHSEP, PRINTER_FILENAME);
67: }
1.1.1.5 root 68: else
1.1.1.9 root 69: {
70: strcpy(ConfigureParams.Printer.szPrintToFileName, PRINTER_FILENAME);
71: }
1.1.1.5 root 72: }
73:
74: #ifdef PRINTER_DEBUG
75: fprintf(stderr,"Filename for printing: %s \n", ConfigureParams.Printer.szPrintToFileName);
76: #endif
1.1 root 77: }
78:
1.1.1.2 root 79:
80: /*-----------------------------------------------------------------------*/
1.1.1.9 root 81: /**
82: * Uninitialise Printer
83: */
1.1 root 84: void Printer_UnInit(void)
85: {
1.1.1.6 root 86: /* Close any open files */
87: Printer_CloseAllConnections();
88:
1.1.1.5 root 89: #ifdef PRINTER_DEBUG
90: fprintf(stderr,"Printer_UnInit()\n");
91: #endif
1.1 root 92: }
93:
1.1.1.2 root 94:
95: /*-----------------------------------------------------------------------*/
1.1.1.9 root 96: /**
97: * Close all open output file, empty buffers etc.
98: */
1.1 root 99: void Printer_CloseAllConnections(void)
100: {
1.1.1.6 root 101: /* Empty buffer */
102: Printer_EmptyInternalBuffer();
1.1 root 103:
1.1.1.6 root 104: /* Close any open files */
1.1.1.9 root 105: pPrinterHandle = File_Close(pPrinterHandle);
1.1 root 106:
1.1.1.6 root 107: /* Signal finished with printing */
1.1.1.12! root 108: bConnectedPrinter = false;
1.1 root 109: }
110:
1.1.1.2 root 111:
1.1.1.6 root 112: /*-----------------------------------------------------------------------*/
1.1.1.9 root 113: /**
114: * Reset Printer Buffer
115: */
116: static void Printer_ResetInternalBuffer(void)
1.1 root 117: {
1.1.1.9 root 118: nPrinterBufferChars = 0;
1.1 root 119: }
120:
1.1.1.2 root 121:
1.1.1.6 root 122: /*-----------------------------------------------------------------------*/
1.1.1.9 root 123: /**
124: * Empty to file on disk.
125: */
126: static void Printer_EmptyFile(void)
1.1 root 127: {
1.1.1.6 root 128: /* Do have file open? */
1.1.1.9 root 129: if (pPrinterHandle)
1.1.1.6 root 130: {
131: /* Write bytes out */
1.1.1.9 root 132: if (fwrite((Uint8 *)PrinterBuffer,sizeof(Uint8),nPrinterBufferChars,pPrinterHandle) < nPrinterBufferChars)
1.1.1.6 root 133: {
134: /* we wrote less then all chars in the buffer --> ERROR */
1.1.1.7 root 135: fprintf(stderr,"Printer_EmptyFile(): ERROR not all chars were written\n");
1.1.1.6 root 136: }
137: /* Reset */
138: Printer_ResetInternalBuffer();
139: }
1.1 root 140: }
141:
1.1.1.2 root 142:
1.1.1.6 root 143: /*-----------------------------------------------------------------------*/
1.1.1.9 root 144: /**
145: * Empty Printer Buffer
146: */
1.1.1.10 root 147: static bool Printer_EmptyInternalBuffer(void)
1.1 root 148: {
1.1.1.6 root 149: /* Write bytes to file */
1.1.1.9 root 150: if (nPrinterBufferChars > 0)
1.1.1.6 root 151: {
1.1.1.9 root 152: if (pPrinterHandle)
1.1.1.7 root 153: Printer_EmptyFile();
1.1 root 154:
1.1.1.12! root 155: return true;
1.1.1.6 root 156: }
157: /* Nothing to do */
1.1.1.12! root 158: return false;
1.1 root 159: }
160:
1.1.1.2 root 161:
1.1.1.6 root 162: /*-----------------------------------------------------------------------*/
1.1.1.9 root 163: /**
164: * Add byte to our internal buffer, and when full write out - needed to speed
165: */
166: static void Printer_AddByteToInternalBuffer(Uint8 Byte)
1.1 root 167: {
1.1.1.6 root 168: /* Is buffer full? If so empty */
169: if (nPrinterBufferChars == PRINTER_BUFFER_SIZE)
170: Printer_EmptyInternalBuffer();
171: /* Add character */
172: PrinterBuffer[nPrinterBufferChars++] = Byte;
1.1 root 173: }
174:
1.1.1.2 root 175:
1.1.1.6 root 176: /*-----------------------------------------------------------------------*/
1.1.1.9 root 177: /**
178: * Pass byte from emulator to printer. Opens the printer file appending
1.1.1.12! root 179: * if it isn't already open. Returns false if connection to "printer"
1.1.1.9 root 180: * failed
181: */
1.1.1.10 root 182: bool Printer_TransferByteTo(Uint8 Byte)
1.1 root 183: {
1.1.1.6 root 184: /* Do we want to output to a printer/file? */
185: if (!ConfigureParams.Printer.bEnablePrinting)
1.1.1.12! root 186: return false; /* Failed if printing disabled */
1.1.1.6 root 187:
188: /* Have we made a connection to our printer/file? */
189: if (!bConnectedPrinter)
190: {
1.1.1.9 root 191: /* open printer file... */
192: pPrinterHandle = File_Open(ConfigureParams.Printer.szPrintToFileName, "a+");
193: bConnectedPrinter = (pPrinterHandle != NULL);
1.1.1.6 root 194:
195: /* Reset the printer */
196: Printer_ResetInternalBuffer();
197: }
198:
199: /* Is all OK? */
200: if (bConnectedPrinter)
201: {
1.1.1.10 root 202: /* Add byte to our buffer. */
203: Printer_AddByteToInternalBuffer(Byte);
1.1.1.12! root 204: return true; /* OK */
1.1.1.6 root 205: }
206: else
1.1.1.12! root 207: return false; /* Failed */
1.1 root 208: }
209:
1.1.1.2 root 210:
1.1.1.6 root 211: /*-----------------------------------------------------------------------*/
1.1.1.9 root 212: /**
213: * Empty printer buffer, and if remains idle for set time close connection
214: * (ie close file, stop printer)
215: */
1.1 root 216: void Printer_CheckIdleStatus(void)
217: {
1.1.1.6 root 218: /* Is anything waiting for printer? */
219: if (Printer_EmptyInternalBuffer())
220: {
221: nIdleCount = 0;
222: }
223: else
224: {
225: nIdleCount++;
226: /* Has printer been idle? */
227: if (nIdleCount >= PRINTER_IDLE_CLOSE)
228: {
229: /* Close printer output */
230: Printer_CloseAllConnections();
231: nIdleCount = 0;
232: }
233: }
1.1 root 234: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.