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