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

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

unix.superglobalmegacorp.com

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