|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.