/************************************************************************ * * * print * * * *-----------------------------------------------------------------------* * * * Module containing the real printer routines. * * * ************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "settings.h" /*************************************** Definitions ***************************************/ #define SS ( SHORT )Sets[ ActSet ] #define ELITE_ON "\x1b[2w" #define ELITE_OFF "\x1b[1w" #define CONDENSED_ON "\x1b[4w" #define CONDENSED_OFF "\x1b[3w" #define LETTERQ_ON "\x1b[2\"z" #define LETTERQ_OFF "\x1b[1\"z" #define PROPORTIONAL_ON "\x1b[2p" #define PROPORTIONAL_OFF "\x1b[1p" #define LINESP6_ON "\x1b[1z" #define LINESP6_OFF "\x1b[0z" #define PINIT "\x1b[0m\x1b[0w\x1b[1v\x1b[1p\x1b[0q" /*************************************** External References ***************************************/ /*************************************** Functions ***************************************/ /*************************************** Variables ***************************************/ IMPORT struct IODRPReq *GPrtReq; IMPORT struct IOStdReq *PrtReq; IMPORT struct IOPrtCmdReq *CmdReq; IMPORT struct Window *FirstWindow; IMPORT UBYTE LoadString[]; IMPORT struct FileInfoBlock *FIB; IMPORT UBYTE Dir[], File[], Path[]; IMPORT struct FileRequester FReq; IMPORT LONG Memsize; IMPORT UBYTE *ActFile; IMPORT struct Settings Sets[ 10 ]; IMPORT SHORT ActSet; IMPORT UBYTE ScTitle[]; IMPORT UBYTE File[]; /*************************************** Globals ***************************************/ UBYTE title[ 1024 ], PrtBuf[ 1024 ], Req[26] = "Print page no. ?"; struct TRStructure TR = { Req, NULL, NULL, "Skip", "Yes", "Quit", "Tell me ...", 0xffff, 0,0,0,0,0L,0L }; /*************************************** Declarations ***************************************/ VOID PreInit( VOID ); VOID PrintPageWise( VOID ); VOID PrintAll( VOID ); VOID Init( struct Settings ); UBYTE *PrintLine( UBYTE *, SHORT, SHORT ); UBYTE *PrintPage( UBYTE *, SHORT, SHORT, SHORT, SHORT, SHORT ); BOOL AskStatus( VOID ); UBYTE *SkipPage( UBYTE *, SHORT, SHORT, SHORT, SHORT, SHORT ); static UBYTE *SkipLine( UBYTE *, SHORT, SHORT ); /************************************************************************ * * * PreInit * * * *-----------------------------------------------------------------------* * * * Intailizes the printer to the currently chosen settigs. * * * *-----------------------------------------------------------------------* * * * Parameters : * * none * * * * Returns : * * none * * * ************************************************************************/ VOID PreInit( VOID ) { if( AskStatus() ) Init( Sets[ ActSet ] ); } /************************************************************************ * * * PrintPageWise * * * *-----------------------------------------------------------------------* * * * Prints the whole text, asking "Print", "Skip", and "Quit" for * * every page. * * * *-----------------------------------------------------------------------* * * * Parameters : * * none * * * * Returns : * * none * * * ************************************************************************/ VOID PrintPageWise( VOID ) { UBYTE *p, *pn; SHORT i, j, pcnt, res; BOOL go; /***/ if( AskStatus() ) Init( Sets[ ActSet ] ); else return; p = ActFile; i = 1; pcnt = 0; go = TRUE; while(( p != NULL )&&( p < ActFile + Memsize )&&( go == TRUE )) { pn = itoa( i ); while( strlen( pn ) < 5 ) pn--; for( j = 0; j < 5; j++ ) Req[ j + 17 ] = pn[j]; res = TextRequest( &TR ); switch( res ) { case 0 : go = FALSE; break; case 1 : p = PrintPage( p, SS.PageLen, SS.Numb, i, SS.Tabsize, SS.PageWidth ); pcnt++; break; case 2 : p = SkipPage( p, SS.PageLen, SS.Numb, i, SS.Tabsize, SS.PageWidth ); break; } i++; } SimpleRequest( "Sent %s pages", itoa( pcnt )); } /************************************************************************ * * * PrintAll * * * *-----------------------------------------------------------------------* * * * Prints the whole text without asking. * * * *-----------------------------------------------------------------------* * * * Parameters : * * none * * * * Returns : * * none * * * ************************************************************************/ VOID PrintAll( VOID ) { UBYTE *p; SHORT i; /***/ if( AskStatus() ) Init( Sets[ ActSet ] ); else return; p = ActFile; i = 1; while(( p != NULL )&&( p < ActFile + Memsize )) { p = PrintPage( p, SS.PageLen, SS.Numb, i, SS.Tabsize, SS.PageWidth ); i++; } SimpleRequest( "Sent %s pages", itoa( --i )); } /************************************************************************ * * * Init * * * *-----------------------------------------------------------------------* * * * Initializes the printer * * * *-----------------------------------------------------------------------* * * * Parameters : * * set : Settings to init * * * * Returns : * * none * * * ************************************************************************/ VOID Init( struct Settings set ) { static struct Settings Store; SHORT i; UBYTE *p, *q; BOOL ne = FALSE; /***/ /* Compare set and Store, to determine if the set is already set, and to give the use the opportunity, to change settings on his printer. */ p = ( UBYTE * )&Store; q = ( UBYTE * )&set; for( i = 0; i < sizeof( struct Settings ); i++ ) { if( p[i] != q[i] ) { ne = TRUE; break; } } if( ne == FALSE ) return; Printer_WRITE( PrtReq, PINIT, strlen( PINIT )); Printer_PRTCOMMAND( CmdReq, aSLRM, ( UBYTE )set.LMarg, ( UBYTE )set.RMarg, 0, 0 ); if( set.Cond ) Printer_WRITE( PrtReq, CONDENSED_ON, 4L ); else Printer_WRITE( PrtReq, CONDENSED_OFF, 4L ); if( set.LetterQ ) Printer_WRITE( PrtReq, LETTERQ_ON, 5L ); else Printer_WRITE( PrtReq, LETTERQ_OFF, 5L ); if( set.LSpace6 ) Printer_WRITE( PrtReq, LINESP6_ON, 4L ); else Printer_WRITE( PrtReq, LINESP6_OFF, 4L ); switch( set.Style ) { case STYLE_ELITE : Printer_WRITE( PrtReq, ELITE_ON, 4L ); break; case STYLE_PICA : Printer_WRITE( PrtReq, ELITE_OFF, 4L ); break; case STYLE_PROP : Printer_WRITE( PrtReq, PROPORTIONAL_ON, 4L ); break; default : break; } Store = set; } /************************************************************************ * * * PrintLine * * * *-----------------------------------------------------------------------* * * * Print one line. * * * *-----------------------------------------------------------------------* * * * Parameters : * * p : Pointer to the beginning of the line * * TS : Tab - size for this line. * * ll : Line length * * * * Returns : * * Pointer to the beginnig of the next line, or NULL if the end * * of the text was encountered. * * * ************************************************************************/ UBYTE *PrintLine( UBYTE *p, SHORT TS, SHORT ll ) { SHORT i, j, len, nt; UBYTE *q, *re; /***/ if( TS == 0 ) /* Don't wanna run into a division by zero */ TS = 1; /* First, we find our return value. */ for( q = p;( *q != '\n' )&&( q < ( ActFile + Memsize )); q++ ) ; if( q < ( ActFile + Memsize )) { q++; re = q; } else re = NULL; /* Now, we process the line, using the tab replacing algorithm, we developed for "PS". We stop, when we have written the line length. */ i = 0; len = 0; while(( p != q )&&( len < ll )) { if( *p == '\t' ) { nt = TS - ( len % TS ); for( j = 0; j < nt; j++ ) { PrtBuf[i++] = ' '; len++; } p++; continue; } if( *p == '\x1b' ) { while( !isalpha( *p )) PrtBuf[i++] = *p++; PrtBuf[i++] = *p++; continue; } PrtBuf[i++] = *p++; len++; continue; } PrtBuf[ i - 1 ] = '\n'; Printer_WRITE( PrtReq, PrtBuf, ( LONG )i ); if( p < q ) re = p; return re; } /************************************************************************ * * * PrintPage * * * *-----------------------------------------------------------------------* * * * Print one page of text, including the concluding form feed. * * * *-----------------------------------------------------------------------* * * * Parameters : * * p : Pointer to the beginning of the page * * pl : Page length ( in lines ) * * numb : Page numbering flag ( 0 = No, 1 = Top, 2 = Bot, * * 3 = Line ) * * nr : Page number * * TS : Tab size * * ll : Line length * * * * Returns : * * Pointer to the beginning of the next page, of NULL, if we * * reached the end of the text. * * * ************************************************************************/ UBYTE *PrintPage( UBYTE *p, SHORT pl, SHORT numb, SHORT nr, SHORT TS, SHORT ll ) { UBYTE *q, *ns, lf[] = "\n", ff[] = "\xc"; SHORT i, j; /***/ pl--; if( numb != 0 ) { for( i = 0; i < ll; i++ ) title[i] = ' '; pl -= 2; } if( numb == 3 ) { q = stpcpy( title, File ); *q = ' '; } if( numb != 0 ) { q = stpcpy( &title[ ll - 12 ], "Page:" ); *q++ = ' '; ns = itoa( nr ); while( strlen( ns ) < 5 ) ns--; q = stpcpy( q, ns ); *q = '\n'; } if(( numb == 1 )||( numb == 3 )) { Printer_WRITE( PrtReq, title, ( LONG )ll ); Printer_WRITE( PrtReq, lf, 1L ); } for( i = 0; i < pl; i++ ) { p = PrintLine( p, TS, ll ); if( p == NULL ) { for( j = i; j < pl; j++ ) Printer_WRITE( PrtReq, lf, 1L ); break; } } if( numb == 2 ) { Printer_WRITE( PrtReq, lf, 1L ); Printer_WRITE( PrtReq, title, ( LONG )ll ); } Printer_WRITE( PrtReq, ff, 1L ); return p; } /************************************************************************ * * * AskStatus * * * *-----------------------------------------------------------------------* * * * Asks the printer status. * * * *-----------------------------------------------------------------------* * * * Parameters : * * none * * * * Returns : * * TRUE if the printer is ready to print, FALSE if the printer * * is not ready. * * * ************************************************************************/ BOOL AskStatus( VOID ) { UWORD status; /***/ Printer_QUERY( PrtReq, &status ); /* SimpleRequest( "status is %s", itoa( status )); */ switch( status & 0x0700 ) { case 0x0400 : return TRUE; break; case 0x0500 : SimpleRequest( "Please turn your printer online !" ); return FALSE; break; case 0x0700 : SimpleRequest( "Please insert paper and\nturn your printer online !" ); return FALSE; break; default : SimpleRequest( "Something is wrong with your printer !" ); return FALSE; break; } } /************************************************************************ * * * SkipPage * * * *-----------------------------------------------------------------------* * * * Skip one page of text. * * * *-----------------------------------------------------------------------* * * * Parameters : * * p : Pointer to the beginning of the page * * pl : Page length ( in lines ) * * numb : Page numbering flag ( 0 = No, 1 = Top, 2 = Bot, * * 3 = Line ) * * nr : Page number * * TS : Tab size * * ll : Line length * * * * Returns : * * Pointer to the beginning of the next page, of NULL, if we * * reached the end of the text. * * * ************************************************************************/ UBYTE *SkipPage( UBYTE *p, SHORT pl, SHORT numb, SHORT nr, SHORT TS, SHORT ll ) { SHORT i, j; /***/ pl--; if( numb != 0 ) { pl -= 2; } for( i = 0; i < pl; i++ ) { p = SkipLine( p, TS, ll ); if( p == NULL ) { for( j = i; j < pl; j++ ) ; break; } } return p; } /************************************************************************ * * * SkipLine * * * *-----------------------------------------------------------------------* * * * Skip one line. * * * *-----------------------------------------------------------------------* * * * Parameters : * * p : Pointer to the beginning of the line * * TS : Tab - size for this line. * * ll : Line length * * * * Returns : * * Pointer to the beginnig of the next line, or NULL if the end * * of the text was encountered. * * * ************************************************************************/ static UBYTE *SkipLine( UBYTE *p, SHORT TS, SHORT ll ) { SHORT i, j, len, nt; UBYTE *q, *re; /***/ if( TS == 0 ) /* Don't wanna run into a division by zero */ TS = 1; /* First, we find our return value. */ for( q = p;( *q != '\n' )&&( q < ( ActFile + Memsize )); q++ ) ; if( q < ( ActFile + Memsize )) { q++; re = q; } else re = NULL; /* Now, we process the line, using the tab replacing algorithm, we developed for "PS". We stop, when we have written the line length. */ i = 0; len = 0; while(( p != q )&&( len < ll )) { if( *p == '\t' ) { nt = TS - ( len % TS ); for( j = 0; j < nt; j++ ) { PrtBuf[i++] = ' '; len++; } p++; continue; } if( *p == '\x1b' ) { while( !isalpha( *p )) PrtBuf[i++] = *p++; PrtBuf[i++] = *p++; continue; } PrtBuf[i++] = *p++; len++; continue; } PrtBuf[ i - 1 ] = '\n'; if( p < q ) re = p; return re; }