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

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