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

1.1       root        1: /*
                      2:   Hatari
                      3: 
                      4:   Printer communication. When bytes are sent to the ST they are sent on to these functions
                      5:   via 'Printer_TransferByteTo()'. This will then open a file or Windows printer and direct
                      6:   the output to this. These bytes are buffered up(to improve speed) and this also allow us
                      7:   to detect when the stream goes into idle - at which point we close the file/printer(Windows
                      8:   printing will only occur when we close).
                      9:   NOTE - Tab's are converted to spaces as the PC 'Tab' setting differs to that of the ST.
                     10:   NOTE - As the ST differs so greatly from modern Windows printing we are limited in the way
                     11:   we can output data - Printer no longer respond to communication over the LPT port(DOS can
                     12:   not use modern printers). As such, we can only print out basic text based documents - the
                     13:   output to file option allows text to be loaded into a Windows word-processor and formatted
                     14:   correctly using that.
                     15: */
                     16: 
                     17: #include "main.h"
                     18: #include "debug.h"
                     19: #include "dialog.h"
                     20: #include "file.h"
                     21: #include "printer.h"
                     22: #include "screen.h"
                     23: #include "statusBar.h"
                     24: #include "view.h"
                     25: 
                     26: #define PRINTER_TAB_SETTING  8          /* A 'Tab' on the ST is 8 spaces */
                     27: #define  PRINTER_IDLE_CLOSE  (4*50)     /* After 4 seconds, close printer */
                     28: 
                     29: #define PRINTER_BUFFER_SIZE  2048       /* 2k buffer which when full will be written to printer/file */
                     30: 
                     31: //static HFILE PrinterFile;
                     32: //static OFSTRUCT PrinterFileInfo;
1.1.1.2 ! root       33: static unsigned char PrinterBuffer[PRINTER_BUFFER_SIZE];   /* Buffer to store character before output */
        !            34: static int nPrinterBufferChars,nPrinterBufferCharsOnLine;  /* # characters in above buffer */
1.1       root       35: static BOOL bConnectedPrinter=FALSE;
                     36: static BOOL bPrinterDiscFile=FALSE,bPrinterWindows=FALSE;
                     37: //static PRINTDLG pd;                                      // Printer Dlg
1.1.1.2 ! root       38: static BOOL bStartedPage;                                  /* Have set up new page? */
        !            39: static BOOL bAlreadyOpenedPrintingFile=FALSE;              /* TRUE if already opened file, so can add to end */
        !            40: static int PrinterX,PrinterY;                              /* X,Y to print to on page */
        !            41: static int nPrinterWidthPels,nPrinterHeightPels;           /* Width/Height of page */
        !            42: static int nIdleCount=0;                                   /* Frames printer has been idle */
1.1       root       43: 
1.1.1.2 ! root       44: 
        !            45: /*-----------------------------------------------------------------------*/
1.1       root       46: /*
                     47:   Initialise Printer
                     48: */
                     49: void Printer_Init(void)
                     50: {
                     51: }
                     52: 
1.1.1.2 ! root       53: 
        !            54: /*-----------------------------------------------------------------------*/
1.1       root       55: /*
                     56:   Uninitialise Printer
                     57: */
                     58: void Printer_UnInit(void)
                     59: {
1.1.1.2 ! root       60:   /* Close any open files */
1.1       root       61:   Printer_CloseAllConnections();
                     62: }
                     63: 
1.1.1.2 ! root       64: 
        !            65: /*-----------------------------------------------------------------------*/
1.1       root       66: /*
                     67:   Close all open files, on disc or Windows printers
                     68: */
                     69: void Printer_CloseAllConnections(void)
                     70: {
1.1.1.2 ! root       71:   /* Empty buffer */
1.1       root       72:   Printer_EmptyInternalBuffer();
                     73: 
1.1.1.2 ! root       74:   /* Close any open files */
1.1       root       75:   Printer_CloseDiscFile();
1.1.1.2 ! root       76:   /* And printers */
1.1       root       77:   Printer_CloseWindowsPrinter();
                     78: 
1.1.1.2 ! root       79:   /* Signal finished with printing */
1.1       root       80:   bConnectedPrinter = FALSE;
                     81: }
                     82: 
1.1.1.2 ! root       83: 
        !            84: /*-----------------------------------------------------------------------*/
1.1       root       85: /*
                     86:   Open file on disc, to which all printer output will be sent
                     87: */
                     88: BOOL Printer_OpenDiscFile(void)
                     89: {
                     90: /* FIXME */
                     91: /*
                     92:   // Close existing
                     93:   Printer_CloseAllConnections();
                     94: 
                     95:   // Open file
                     96:   bPrinterDiscFile = TRUE;
                     97:   // Do we have a filename for output?
                     98:   if (strlen(ConfigureParams.Printer.szPrintToFileName)<=0) {
                     99:     // First, Return back into a Window
                    100:     Screen_ReturnFromFullScreen();
                    101:     View_ToggleWindowsMouse(MOUSE_WINDOWS);
                    102:     // Ask for filename
                    103:     if (!File_OpenSelectDlg(hWnd,ConfigureParams.Printer.szPrintToFileName,FILEFILTER_ALLFILES,FALSE,TRUE))
                    104:       bPrinterDiscFile = FALSE;
                    105:     // Revert back to ST mouse mode
                    106:     View_ToggleWindowsMouse(MOUSE_ST);
                    107:   }
                    108: 
                    109:   // OK to print?
                    110:   if (bPrinterDiscFile) {
                    111:     // Open file to print to - if previously opened, just re-open to add to end
                    112:     if (!bAlreadyOpenedPrintingFile)
                    113:       PrinterFile = OpenFile(ConfigureParams.Printer.szPrintToFileName,&PrinterFileInfo,OF_CREATE | OF_WRITE);
                    114:     else {
                    115:       // Re-open and position at end of file
                    116:       PrinterFile = OpenFile(ConfigureParams.Printer.szPrintToFileName,&PrinterFileInfo,OF_WRITE);
                    117:       _llseek(PrinterFile,0,FILE_END);
                    118:     }
                    119: 
                    120:     if (PrinterFile==HFILE_ERROR)
                    121:       bPrinterDiscFile = FALSE;
                    122:     else
                    123:       bAlreadyOpenedPrintingFile = TRUE;
                    124:   }
                    125: */
                    126:   return(bPrinterDiscFile);
                    127: }
                    128: 
1.1.1.2 ! root      129: 
        !           130: /*-----------------------------------------------------------------------*/
1.1       root      131: /*
                    132:   Close file on disc, if we have one open
                    133: */
                    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       root      139: //FIXME    _lclose(PrinterFile);
                    140: 
                    141:     bPrinterDiscFile = FALSE;
                    142:   }
                    143: }
                    144: 
1.1.1.2 ! root      145: 
        !           146: /*-----------------------------------------------------------------------*/
1.1       root      147: /*
                    148:   Empty to disc file
                    149: */
                    150: void Printer_EmptyDiscFile(void)
                    151: {
1.1.1.2 ! root      152:   /* Do have file open? */
1.1       root      153:   if (bPrinterDiscFile) {
1.1.1.2 ! root      154:     /* Write bytes out */
1.1       root      155: //FIXME    _hwrite(PrinterFile,(char *)PrinterBuffer,nPrinterBufferChars);
1.1.1.2 ! root      156:     /* Reset */
1.1       root      157:     Printer_ResetInternalBuffer();
                    158:   }
                    159: }
                    160: 
1.1.1.2 ! root      161: 
        !           162: /*-----------------------------------------------------------------------*/
1.1       root      163: /*
                    164:   Start new printer page
                    165: */
                    166: void Printer_StartNewPage(void)
                    167: {
1.1.1.2 ! root      168:   /* Reset coords on printer(start printing 'top-left') */
1.1       root      169:   PrinterX = PrinterY = 0;
1.1.1.2 ! root      170:   /* Set new page */
1.1       root      171: //FIXME  StartPage(pd.hDC); 
1.1.1.2 ! root      172:   /* Set flag */
1.1       root      173:   bStartedPage = TRUE;
                    174: }
                    175: 
1.1.1.2 ! root      176: 
        !           177: /*-----------------------------------------------------------------------*/
1.1       root      178: /*
                    179:   Send character to Windows printer, add to XY position
                    180: */
                    181: void Printer_PrintCharacter(char Char)
                    182: {
                    183: /*FIXME*/
1.1.1.2 ! root      184: #if 0
1.1       root      185:   SIZE CharSize;
                    186: 
1.1.1.2 ! root      187:   /* Have started page? If not, begin new one */
1.1       root      188:   if (!bStartedPage)
                    189:     Printer_StartNewPage();
                    190: 
1.1.1.2 ! root      191:   /* Find width/height of character */
1.1       root      192:   GetTextExtentPoint32(pd.hDC, &Char,1, &CharSize);
                    193: 
1.1.1.2 ! root      194:   /* Handle returns to new lines... */
1.1       root      195:   if (Char==0xa) {
                    196:     PrinterY += CharSize.cy;
                    197:     return;
                    198:   }
                    199:   if (Char==0xd) {
                    200:     PrinterX = 0;
                    201:     return;
                    202:   }
                    203:  
1.1.1.2 ! root      204:   /* Will fit on page? */
1.1       root      205:   if ((PrinterX+CharSize.cx)>=nPrinterWidthPels) {
1.1.1.2 ! root      206:     PrinterY += CharSize.cy;            /* Off right of page, start new line */
1.1       root      207:     PrinterX = 0;
                    208:   }
                    209:   if ((PrinterY+CharSize.cy)>=nPrinterHeightPels) {
                    210:     if (bStartedPage)
1.1.1.2 ! root      211:       EndPage(pd.hDC);                  /* Off bottom of page, start new one */
1.1       root      212:     Printer_StartNewPage();
                    213:   }
                    214: 
1.1.1.2 ! root      215:   /* Print character */
1.1       root      216:   TextOut(pd.hDC, PrinterX,PrinterY, &Char, 1);
                    217:   PrinterX += CharSize.cx;
1.1.1.2 ! root      218: #endif
1.1       root      219: }
                    220: 
1.1.1.2 ! root      221: 
        !           222: /*-----------------------------------------------------------------------*/
1.1       root      223: /*
                    224:   Open Windows printer - Always return TRUE as sucess so we can 'print' without constantly
                    225:   bringing up the Printer dialog if they happened to press 'Cancel'.
                    226: */
                    227: BOOL Printer_OpenWindowsPrinter(void)
                    228: {
                    229: /* FIXME */
                    230: /*
                    231:   DOCINFO di;
                    232:   int nError;
                    233: 
                    234:   // Close existing
                    235:   Printer_CloseAllConnections();
                    236: 
                    237:   // First, Return back into a Window
                    238:   Screen_ReturnFromFullScreen();
                    239:   View_ToggleWindowsMouse(MOUSE_WINDOWS);
                    240: 
                    241:   // Initialize the PRINTDLG members. 
                    242:   pd.lStructSize = sizeof(PRINTDLG); 
                    243:   pd.hDevMode = (HANDLE) NULL; 
                    244:   pd.hDevNames = (HANDLE) NULL; 
                    245:   pd.Flags = PD_RETURNDC | PD_ALLPAGES | PD_NOSELECTION | PD_DISABLEPRINTTOFILE | PD_HIDEPRINTTOFILE; 
                    246:   pd.hwndOwner = hWnd; 
                    247:   pd.hDC = (HDC) NULL; 
                    248:   pd.nFromPage = 1; 
                    249:   pd.nToPage = 1; 
                    250:   pd.nMinPage = 0; 
                    251:   pd.nMaxPage = 0; 
                    252:   pd.nCopies = 1; 
                    253:   pd.hInstance = (HINSTANCE)NULL; 
                    254:   pd.lCustData = 0L; 
                    255:   pd.lpfnPrintHook = (LPPRINTHOOKPROC) NULL; 
                    256:   pd.lpfnSetupHook = (LPSETUPHOOKPROC) NULL; 
                    257:   pd.lpPrintTemplateName = (LPSTR) NULL; 
                    258:   pd.lpSetupTemplateName = (LPSTR)  NULL; 
                    259:   pd.hPrintTemplate = (HANDLE) NULL; 
                    260:   pd.hSetupTemplate = (HANDLE) NULL; 
                    261:  
                    262:   // Display the PRINT dialog box. 
                    263:   if (PrintDlg(&pd)!=0) { 
                    264:     // Initialize the members of a DOCINFO structure. 
                    265:     di.cbSize = sizeof(DOCINFO); 
                    266:     di.lpszDocName = "Hatari Print Output"; 
                    267:     di.lpszOutput = (LPTSTR) NULL; 
                    268:     di.lpszDatatype = (LPTSTR) NULL; 
                    269:     di.fwType = 0; 
                    270:  
                    271:     // Begin a print job by calling the StartDoc function. 
                    272:     nError = StartDoc(pd.hDC, &di); 
                    273:     if (nError == SP_ERROR) {
                    274:       // Report error
                    275:       Main_SysError("Unable to start Printing operation.",PROG_NAME);
                    276:       // Delete the printer DC.
                    277:       DeleteDC(pd.hDC);
                    278:       // Fail printing
                    279:       bPrinterWindows = FALSE;
                    280: 
                    281:       return(TRUE);
                    282:     }
                    283:     
                    284:     // Get Printer Information
                    285:     nPrinterWidthPels = GetDeviceCaps(pd.hDC, HORZRES);
                    286:     nPrinterHeightPels = GetDeviceCaps(pd.hDC, VERTRES);
                    287:     // Ready for first page
                    288:     bStartedPage = FALSE;
                    289: 
                    290:     // All OK
                    291:     bPrinterWindows = TRUE;
                    292:   }
                    293:   else
                    294:     bPrinterWindows = FALSE;
                    295: 
                    296:   // Revert back to ST mouse mode
                    297:   View_ToggleWindowsMouse(MOUSE_ST);
                    298: */
                    299:   return(TRUE);
                    300: }
                    301: 
1.1.1.2 ! root      302: 
        !           303: /*-----------------------------------------------------------------------*/
1.1       root      304: /*
                    305:   Close Windows printer
                    306: */
                    307: void Printer_CloseWindowsPrinter(void)
                    308: {
                    309: /* FIXME */
                    310: /*
                    311:   // Do have file open?
                    312:   if (bPrinterWindows) {
                    313:     // End page
                    314:     if (bStartedPage)
                    315:       EndPage(pd.hDC);
                    316:     // Inform the driver that document has ended.
                    317:     EndDoc(pd.hDC);
                    318:     // Delete the printer DC.
                    319:     DeleteDC(pd.hDC);
                    320: 
                    321:     bPrinterWindows = FALSE;
                    322:   }
                    323: */
                    324: }
                    325: 
1.1.1.2 ! root      326: 
        !           327: /*-----------------------------------------------------------------------*/
1.1       root      328: /*
                    329:   Empty Windows printer
                    330: */
                    331: void Printer_EmptyWindowsPrinter(void)
                    332: {
                    333:   int i;
                    334: 
1.1.1.2 ! root      335:   /* Do have file open? */
1.1       root      336:   if (bPrinterWindows) {
1.1.1.2 ! root      337:     /* Write bytes out */
1.1       root      338:     for(i=0; i<nPrinterBufferChars; i++)
                    339:       Printer_PrintCharacter(PrinterBuffer[i]);
1.1.1.2 ! root      340:     /* Reset */
1.1       root      341:     Printer_ResetInternalBuffer();
                    342:   }
                    343: }
                    344: 
1.1.1.2 ! root      345: 
        !           346: /*-----------------------------------------------------------------------*/
1.1       root      347: /*
                    348:   Reset Printer Buffer
                    349: */
                    350: void Printer_ResetInternalBuffer(void)
                    351: {
                    352:   nPrinterBufferChars = 0;
                    353: }
                    354: 
1.1.1.2 ! root      355: 
        !           356: /*-----------------------------------------------------------------------*/
1.1       root      357: /*
                    358:   Reset character line
                    359: */
                    360: void Printer_ResetCharsOnLine(void)
                    361: {
                    362:   nPrinterBufferCharsOnLine = 0;
                    363: }
                    364: 
1.1.1.2 ! root      365: 
        !           366: /*-----------------------------------------------------------------------*/
1.1       root      367: /*
                    368:   Empty Printer Buffer
                    369: */
                    370: BOOL Printer_EmptyInternalBuffer(void)
                    371: {
1.1.1.2 ! root      372:   /* Write bytes to file */
1.1       root      373:   if (nPrinterBufferChars>0) {
                    374:     if (bPrinterDiscFile)
                    375:       Printer_EmptyDiscFile();
                    376:     else if (bPrinterWindows)
                    377:       Printer_EmptyWindowsPrinter();
                    378: 
                    379:     return(TRUE);
                    380:   }
                    381: 
1.1.1.2 ! root      382:   /* Nothing to do */
1.1       root      383:   return(FALSE);
                    384: }
                    385: 
1.1.1.2 ! root      386: 
        !           387: /*-----------------------------------------------------------------------*/
1.1       root      388: /*
                    389:   Return TRUE if byte is standard ASCII character which is OK to output
                    390: */
                    391: BOOL Printer_ValidByte(unsigned char Byte)
                    392: {
1.1.1.2 ! root      393:   /* Return/New line? */
1.1       root      394:   if ( (Byte==0x0d) || (Byte==0x0a) )
                    395:     return(TRUE);
1.1.1.2 ! root      396:   /* Normal character? */
1.1       root      397:   if ( (Byte>=32) && (Byte<127) )
                    398:     return(TRUE);
1.1.1.2 ! root      399:   /* Tab */
1.1       root      400:   if (Byte=='\t')
                    401:     return(TRUE);
                    402:   return(FALSE);
                    403: }
                    404: 
1.1.1.2 ! root      405: 
        !           406: /*-----------------------------------------------------------------------*/
1.1       root      407: /*
                    408:   Add byte to our internal buffer, and when full write out - needed to speed
                    409: */
                    410: void Printer_AddByteToInternalBuffer(unsigned char Byte)
                    411: {
1.1.1.2 ! root      412:   /* Is buffer full? If so empty */
1.1       root      413:   if (nPrinterBufferChars==PRINTER_BUFFER_SIZE)
                    414:     Printer_EmptyInternalBuffer();
1.1.1.2 ! root      415:   /* Add character */
1.1       root      416:   PrinterBuffer[nPrinterBufferChars++] = Byte;
1.1.1.2 ! root      417:   /* Add count of character on line */
1.1       root      418:   if ( !((Byte==0xd) || (Byte==0xa)) )
                    419:     nPrinterBufferCharsOnLine++;
                    420: }
                    421: 
1.1.1.2 ! root      422: 
        !           423: /*-----------------------------------------------------------------------*/
1.1       root      424: /*
                    425:   Add 'Tab' to internal buffer
                    426: */
                    427: void Printer_AddTabToInternalBuffer(void)
                    428: {
                    429:   int i,NumSpaces;
                    430: 
1.1.1.2 ! root      431:   /* Is buffer full? If so empty */
1.1       root      432:   if (nPrinterBufferChars>=(PRINTER_BUFFER_SIZE-PRINTER_TAB_SETTING))
                    433:     Printer_EmptyInternalBuffer();
1.1.1.2 ! root      434:   /* Add tab - convert to 'PRINTER_TAB_SETTING' space */
1.1       root      435:   NumSpaces = PRINTER_TAB_SETTING-(nPrinterBufferCharsOnLine%PRINTER_TAB_SETTING);
                    436:   for(i=0; i<NumSpaces; i++) {
                    437:     PrinterBuffer[nPrinterBufferChars++] = ' ';
                    438:     nPrinterBufferCharsOnLine++;
                    439:   }
                    440: }
                    441: 
1.1.1.2 ! root      442: 
        !           443: /*-----------------------------------------------------------------------*/
1.1       root      444: /*
                    445:   Pass byte from emulator to printer
                    446: */
                    447: BOOL Printer_TransferByteTo(unsigned char Byte)
                    448: {
                    449: /* FIXME */
                    450: /*
                    451:   // Do we want to output to a printer/file?
                    452:   if (!ConfigureParams.Printer.bEnablePrinting)
                    453:     return(FALSE);  //Failed
                    454: 
                    455:   // Have we made a connection to our printer/file?
                    456:   if (!bConnectedPrinter) {
                    457:     // Open file, to Windows printer
                    458:     if (ConfigureParams.Printer.bPrintToFile)
                    459:       bConnectedPrinter = Printer_OpenDiscFile();
                    460:     else
                    461:       bConnectedPrinter = Printer_OpenWindowsPrinter();
                    462:     // Reset
                    463:     Printer_ResetInternalBuffer();
                    464:     Printer_ResetCharsOnLine();
                    465:   }
                    466: 
                    467:   // Is all OK?
                    468:   if (bConnectedPrinter) {
                    469:     // Add byte to our buffer, if is useable character
                    470:     if (Printer_ValidByte(Byte)) {
                    471:       if (Byte=='\t')
                    472:         Printer_AddTabToInternalBuffer();
                    473:       else
                    474:         Printer_AddByteToInternalBuffer(Byte);
                    475:       if (Byte==0xd)
                    476:         nPrinterBufferCharsOnLine = 0;
                    477:     }
                    478:     // Show icon on status bar
                    479:     StatusBar_SetIcon(STATUS_ICON_PRINTER,ICONSTATE_UPDATE);
                    480: 
                    481:     return(TRUE);  //OK
                    482:   }
                    483:   else
                    484:     return(FALSE);  //Failed
                    485: */
                    486: }
                    487: 
1.1.1.2 ! root      488: 
        !           489: /*-----------------------------------------------------------------------*/
1.1       root      490: /*
                    491:   Empty printer buffer, and if remains idle for set time close connection(ie close file, stop printer)
                    492: */
                    493: void Printer_CheckIdleStatus(void)
                    494: {
1.1.1.2 ! root      495:   /* Is anything waiting for printer? */
1.1       root      496:   if (Printer_EmptyInternalBuffer()) {
                    497:     nIdleCount = 0;
                    498:   }
                    499:   else {
                    500:     nIdleCount++;
1.1.1.2 ! root      501:     /* Has printer been idle? */
1.1       root      502:     if (nIdleCount>=PRINTER_IDLE_CLOSE) {
1.1.1.2 ! root      503:       /* Close printer output */
1.1       root      504:       Printer_CloseAllConnections();
                    505:       nIdleCount = 0;
                    506:     }
                    507:   }
                    508: }

unix.superglobalmegacorp.com

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