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

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

unix.superglobalmegacorp.com

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