|
|
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.6 ! root 15: char Printer_rcsid[] = "Hatari $Id: printer.c,v 1.16 2005/04/07 10:15:02 thothy 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.5 root 36: static BOOL bPrinterDiscFile=FALSE;
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 */
! 96: Printer_CloseDiscFile();
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 root 105: Open file on disc, to which all printer output will be sent
1.1.1.6 ! root 106: */
1.1 root 107: BOOL Printer_OpenDiscFile(void)
108: {
109:
1.1.1.6 ! root 110: bPrinterDiscFile = TRUE;
1.1 root 111:
1.1.1.6 ! root 112: /* open printer file... */
! 113: PrinterFileHandle = fopen(ConfigureParams.Printer.szPrintToFileName, "a+");
! 114: if (!PrinterFileHandle)
! 115: bPrinterDiscFile=FALSE;
1.1 root 116:
1.1.1.6 ! root 117: return bPrinterDiscFile;
1.1 root 118: }
119:
1.1.1.2 root 120:
1.1.1.6 ! root 121: /*-----------------------------------------------------------------------*/
! 122: /*
1.1 root 123: Close file on disc, if we have one open
1.1.1.6 ! root 124: */
1.1 root 125: void Printer_CloseDiscFile(void)
126: {
1.1.1.6 ! root 127: /* Do have file open? */
! 128: if (bPrinterDiscFile)
! 129: {
! 130: /* Close */
! 131: fclose(PrinterFileHandle);
! 132: bPrinterDiscFile = FALSE;
! 133: }
1.1 root 134: }
135:
1.1.1.2 root 136:
1.1.1.6 ! root 137: /*-----------------------------------------------------------------------*/
! 138: /*
1.1 root 139: Empty to disc file
1.1.1.6 ! root 140: */
1.1 root 141: void Printer_EmptyDiscFile(void)
142: {
1.1.1.6 ! root 143: /* Do have file open? */
! 144: if (bPrinterDiscFile)
! 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 */
! 150: fprintf(stderr,"Printer_EmptyDiscFile(): ERROR not all chars were written\n");
! 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: {
! 187: if (bPrinterDiscFile)
! 188: Printer_EmptyDiscFile();
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: {
! 268: bConnectedPrinter = Printer_OpenDiscFile();
! 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.