Annotation of hatari/src/printer.c, revision 1.1.1.9

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.