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

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

unix.superglobalmegacorp.com

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