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

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: 
        !             7:   Printer communication. When bytes are sent from the ST they are sent to these functions
1.1       root        8:   via 'Printer_TransferByteTo()'. This will then open a file or Windows printer and direct
                      9:   the output to this. These bytes are buffered up(to improve speed) and this also allow us
1.1.1.5 ! root       10:   to detect when the stream goes into idle - at which point we close the file/printer.
1.1       root       11:   NOTE - Tab's are converted to spaces as the PC 'Tab' setting differs to that of the ST.
                     12: 
1.1.1.5 ! root       13:   Hack for simple printing by Matthias Arndt <[email protected]>
        !            14: 
        !            15:   ChangeLog:
        !            16: 
        !            17:   9 Aug 2003:   Matthias Arndt <[email protected]>
        !            18:        - initial rewrite
        !            19:        - removed MS Windows specific parts
        !            20:        - made printing to $HOME/hatari.prn possible
1.1.1.4   root       21: 
1.1.1.5 ! root       22:   10 Aug 2003   Matthias Arndt
        !            23:     - corrected stupid string bug that altered the environment var HOME
        !            24: 
        !            25: */
        !            26: char Printer_rcsid[] = "Hatari $Id: printer.c,v 1.14 2004/04/19 08:53:34 thothy Exp $";
1.1.1.4   root       27: 
1.1       root       28: #include "main.h"
                     29: #include "debug.h"
                     30: #include "dialog.h"
                     31: #include "file.h"
                     32: #include "printer.h"
                     33: #include "screen.h"
1.1.1.3   root       34: 
1.1.1.5 ! root       35: /* #define PRINTER_DEBUG */
        !            36: 
        !            37: #define PRINTER_FILENAME "/hatari.prn"
1.1       root       38: 
                     39: #define PRINTER_TAB_SETTING  8          /* A 'Tab' on the ST is 8 spaces */
                     40: #define  PRINTER_IDLE_CLOSE  (4*50)     /* After 4 seconds, close printer */
                     41: 
                     42: #define PRINTER_BUFFER_SIZE  2048       /* 2k buffer which when full will be written to printer/file */
                     43: 
1.1.1.2   root       44: static unsigned char PrinterBuffer[PRINTER_BUFFER_SIZE];   /* Buffer to store character before output */
1.1.1.5 ! root       45: static size_t nPrinterBufferChars;  /* # characters in above buffer */
        !            46: static int nPrinterBufferCharsOnLine;
1.1       root       47: static BOOL bConnectedPrinter=FALSE;
1.1.1.5 ! root       48: static BOOL bPrinterDiscFile=FALSE;
        !            49: static int nIdleCount;
1.1       root       50: 
1.1.1.5 ! root       51: static FILE *PrinterFileHandle;
1.1.1.2   root       52: 
1.1.1.5 ! root       53: 
        !            54: /*-----------------------------------------------------------------------
1.1       root       55:   Initialise Printer
1.1.1.5 ! root       56:  -----------------------------------------------------------------------*/
1.1       root       57: void Printer_Init(void)
                     58: {
1.1.1.5 ! root       59: #ifdef PRINTER_DEBUG
        !            60:        fprintf(stderr,"Printer_Init()\n");
        !            61: #endif
        !            62: 
        !            63:        /* A valid file name for printing is already set up in configuration.c.
        !            64:         * But we check it again since the user might have entered an invalid
        !            65:         * file name in the ~/.hatari.cfg file... */
        !            66:        if(strlen(ConfigureParams.Printer.szPrintToFileName) <= 1)
        !            67:        {
        !            68:                /* construct filename for printing.... */
        !            69:                if (getenv("HOME") != NULL
        !            70:                    && strlen(getenv("HOME"))+strlen(PRINTER_FILENAME) < sizeof(ConfigureParams.Printer.szPrintToFileName))
        !            71:                        sprintf(ConfigureParams.Printer.szPrintToFileName, "%s%s", getenv("HOME"), PRINTER_FILENAME);
        !            72:                else
        !            73:                        sprintf(ConfigureParams.Printer.szPrintToFileName, ".%s",PRINTER_FILENAME);
        !            74:        }
        !            75: 
        !            76: #ifdef PRINTER_DEBUG
        !            77:        fprintf(stderr,"Filename for printing: %s \n", ConfigureParams.Printer.szPrintToFileName);
        !            78: #endif
1.1       root       79: }
                     80: 
1.1.1.2   root       81: 
                     82: /*-----------------------------------------------------------------------*/
1.1       root       83: /*
                     84:   Uninitialise Printer
                     85: */
                     86: void Printer_UnInit(void)
                     87: {
1.1.1.2   root       88:   /* Close any open files */
1.1       root       89:   Printer_CloseAllConnections();
1.1.1.5 ! root       90: #ifdef PRINTER_DEBUG
        !            91:        fprintf(stderr,"Printer_UnInit()\n");
        !            92: #endif
        !            93: 
1.1       root       94: }
                     95: 
1.1.1.2   root       96: 
                     97: /*-----------------------------------------------------------------------*/
1.1       root       98: /*
                     99:   Close all open files, on disc or Windows printers
                    100: */
                    101: void Printer_CloseAllConnections(void)
                    102: {
1.1.1.2   root      103:   /* Empty buffer */
1.1       root      104:   Printer_EmptyInternalBuffer();
                    105: 
1.1.1.2   root      106:   /* Close any open files */
1.1       root      107:   Printer_CloseDiscFile();
                    108: 
1.1.1.2   root      109:   /* Signal finished with printing */
1.1       root      110:   bConnectedPrinter = FALSE;
                    111: }
                    112: 
1.1.1.2   root      113: 
1.1.1.5 ! root      114: /*-----------------------------------------------------------------------
1.1       root      115:   Open file on disc, to which all printer output will be sent
1.1.1.5 ! root      116:  -----------------------------------------------------------------------*/
1.1       root      117: BOOL Printer_OpenDiscFile(void)
                    118: {
                    119: 
                    120:   bPrinterDiscFile = TRUE;
                    121: 
1.1.1.5 ! root      122:   /* open printer file... */
        !           123:   PrinterFileHandle = fopen(ConfigureParams.Printer.szPrintToFileName, "a+");
        !           124:   if(!PrinterFileHandle)
        !           125:        bPrinterDiscFile=FALSE;
1.1       root      126: 
                    127:   return(bPrinterDiscFile);
                    128: }
                    129: 
1.1.1.2   root      130: 
1.1.1.5 ! root      131: /*-----------------------------------------------------------------------
1.1       root      132:   Close file on disc, if we have one open
1.1.1.5 ! root      133:  -----------------------------------------------------------------------*/
1.1       root      134: void Printer_CloseDiscFile(void)
                    135: {
1.1.1.2   root      136:   /* Do have file open? */
1.1       root      137:   if (bPrinterDiscFile) {
1.1.1.2   root      138:     /* Close */
1.1.1.5 ! root      139:        fclose(PrinterFileHandle);
1.1       root      140:     bPrinterDiscFile = FALSE;
                    141:   }
                    142: }
                    143: 
1.1.1.2   root      144: 
1.1.1.5 ! root      145: /*-----------------------------------------------------------------------
1.1       root      146:   Empty to disc file
1.1.1.5 ! root      147:  -----------------------------------------------------------------------*/
1.1       root      148: void Printer_EmptyDiscFile(void)
                    149: {
1.1.1.2   root      150:   /* Do have file open? */
1.1       root      151:   if (bPrinterDiscFile) {
1.1.1.2   root      152:     /* Write bytes out */
1.1.1.5 ! root      153:     if(fwrite((unsigned char *)PrinterBuffer,sizeof(unsigned char),nPrinterBufferChars,PrinterFileHandle) < nPrinterBufferChars)
        !           154:         {
        !           155:                /* we wrote less then all chars in the buffer --> ERROR */
        !           156:                fprintf(stderr,"Printer_EmptyDiscFile(): ERROR not all chars were written\n");
        !           157:         }
1.1.1.2   root      158:     /* Reset */
1.1       root      159:     Printer_ResetInternalBuffer();
                    160:   }
                    161: }
                    162: 
1.1.1.2   root      163: 
1.1.1.5 ! root      164: /*-----------------------------------------------------------------------
1.1       root      165:   Reset Printer Buffer
1.1.1.5 ! root      166:  -----------------------------------------------------------------------*/
1.1       root      167: void Printer_ResetInternalBuffer(void)
                    168: {
                    169:   nPrinterBufferChars = 0;
                    170: }
                    171: 
1.1.1.5 ! root      172: /*-----------------------------------------------------------------------
1.1       root      173:   Reset character line
1.1.1.5 ! root      174:  *----------------------------------------------------------------------*/
1.1       root      175: void Printer_ResetCharsOnLine(void)
                    176: {
                    177:   nPrinterBufferCharsOnLine = 0;
                    178: }
                    179: 
1.1.1.2   root      180: 
1.1.1.5 ! root      181: /*-----------------------------------------------------------------------
1.1       root      182:   Empty Printer Buffer
1.1.1.5 ! root      183:  -----------------------------------------------------------------------*/
1.1       root      184: BOOL Printer_EmptyInternalBuffer(void)
                    185: {
1.1.1.2   root      186:   /* Write bytes to file */
1.1       root      187:   if (nPrinterBufferChars>0) {
                    188:     if (bPrinterDiscFile)
                    189:       Printer_EmptyDiscFile();
                    190: 
                    191:     return(TRUE);
                    192:   }
                    193: 
1.1.1.2   root      194:   /* Nothing to do */
1.1       root      195:   return(FALSE);
                    196: }
                    197: 
1.1.1.2   root      198: 
1.1.1.5 ! root      199: /*-----------------------------------------------------------------------
1.1       root      200:   Return TRUE if byte is standard ASCII character which is OK to output
1.1.1.5 ! root      201:  -----------------------------------------------------------------------*/
1.1       root      202: BOOL Printer_ValidByte(unsigned char Byte)
                    203: {
1.1.1.2   root      204:   /* Return/New line? */
1.1       root      205:   if ( (Byte==0x0d) || (Byte==0x0a) )
                    206:     return(TRUE);
1.1.1.2   root      207:   /* Normal character? */
1.1       root      208:   if ( (Byte>=32) && (Byte<127) )
                    209:     return(TRUE);
1.1.1.2   root      210:   /* Tab */
1.1       root      211:   if (Byte=='\t')
                    212:     return(TRUE);
                    213:   return(FALSE);
                    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.2   root      223:   /* Is buffer full? If so empty */
1.1       root      224:   if (nPrinterBufferChars==PRINTER_BUFFER_SIZE)
                    225:     Printer_EmptyInternalBuffer();
1.1.1.2   root      226:   /* Add character */
1.1       root      227:   PrinterBuffer[nPrinterBufferChars++] = Byte;
1.1.1.2   root      228:   /* Add count of character on line */
1.1       root      229:   if ( !((Byte==0xd) || (Byte==0xa)) )
                    230:     nPrinterBufferCharsOnLine++;
                    231: }
                    232: 
1.1.1.2   root      233: 
1.1.1.5 ! root      234: /*-----------------------------------------------------------------------
1.1       root      235:   Add 'Tab' to internal buffer
1.1.1.5 ! root      236:  -----------------------------------------------------------------------*/
1.1       root      237: void Printer_AddTabToInternalBuffer(void)
                    238: {
                    239:   int i,NumSpaces;
                    240: 
1.1.1.2   root      241:   /* Is buffer full? If so empty */
1.1       root      242:   if (nPrinterBufferChars>=(PRINTER_BUFFER_SIZE-PRINTER_TAB_SETTING))
                    243:     Printer_EmptyInternalBuffer();
1.1.1.2   root      244:   /* Add tab - convert to 'PRINTER_TAB_SETTING' space */
1.1       root      245:   NumSpaces = PRINTER_TAB_SETTING-(nPrinterBufferCharsOnLine%PRINTER_TAB_SETTING);
                    246:   for(i=0; i<NumSpaces; i++) {
                    247:     PrinterBuffer[nPrinterBufferChars++] = ' ';
                    248:     nPrinterBufferCharsOnLine++;
                    249:   }
                    250: }
                    251: 
1.1.1.2   root      252: 
1.1.1.5 ! root      253: /*-----------------------------------------------------------------------
1.1       root      254:   Pass byte from emulator to printer
1.1.1.5 ! root      255:  -----------------------------------------------------------------------*/
1.1       root      256: BOOL Printer_TransferByteTo(unsigned char Byte)
                    257: {
1.1.1.5 ! root      258:   /* Do we want to output to a printer/file? */
1.1       root      259:   if (!ConfigureParams.Printer.bEnablePrinting)
1.1.1.5 ! root      260:     return(FALSE);  /* Failed if printing disabled */
1.1       root      261: 
1.1.1.5 ! root      262:   /* Have we made a connection to our printer/file? */
1.1       root      263:   if (!bConnectedPrinter) {
1.1.1.5 ! root      264:     bConnectedPrinter = Printer_OpenDiscFile();
        !           265: 
        !           266:     /* Reset the printer */
1.1       root      267:     Printer_ResetInternalBuffer();
                    268:     Printer_ResetCharsOnLine();
                    269:   }
                    270: 
1.1.1.5 ! root      271:   /* Is all OK? */
1.1       root      272:   if (bConnectedPrinter) {
1.1.1.5 ! root      273:     /* Add byte to our buffer, if is useable character */
1.1       root      274:     if (Printer_ValidByte(Byte)) {
                    275:       if (Byte=='\t')
                    276:         Printer_AddTabToInternalBuffer();
                    277:       else
                    278:         Printer_AddByteToInternalBuffer(Byte);
                    279:       if (Byte==0xd)
                    280:         nPrinterBufferCharsOnLine = 0;
                    281:     }
                    282: 
1.1.1.5 ! root      283:     return(TRUE);  /* OK */
1.1       root      284:   }
                    285:   else
1.1.1.5 ! root      286: 
1.1.1.4   root      287:     return(FALSE);  /* Failed */
1.1       root      288: }
                    289: 
1.1.1.2   root      290: 
1.1.1.5 ! root      291: /*-----------------------------------------------------------------------
        !           292:   Empty printer buffer, and if remains idle for set time close connection
        !           293:   (ie close file, stop printer)
        !           294:  -----------------------------------------------------------------------*/
1.1       root      295: void Printer_CheckIdleStatus(void)
                    296: {
1.1.1.2   root      297:   /* Is anything waiting for printer? */
1.1       root      298:   if (Printer_EmptyInternalBuffer()) {
                    299:     nIdleCount = 0;
                    300:   }
                    301:   else {
                    302:     nIdleCount++;
1.1.1.2   root      303:     /* Has printer been idle? */
1.1       root      304:     if (nIdleCount>=PRINTER_IDLE_CLOSE) {
1.1.1.2   root      305:       /* Close printer output */
1.1       root      306:       Printer_CloseAllConnections();
                    307:       nIdleCount = 0;
                    308:     }
                    309:   }
                    310: }

unix.superglobalmegacorp.com

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