#define STRICT
#ifndef _INC_WINDOWS
#include <windows.h>
#endif
#include <string.h>
#include <stdio.h>
#pragma hdrstop

#include "spool.h"

HDC 	 	HDCPrinter;		/* Handle Device Context della Stampante */
int 		PrintOpen;		/* TRUE Stampa in esecuzione, altrimente FALSE */
DOCINFO 	DocInfo;		/* Struttura per apertura lavoro con la stampante */
char 		SpoolName[32];	/* Nome dello Spool */
HINSTANCE	hInst;

int FAR PASCAL 	PRCLOSE(void);				/* Chiusura della Stampa */
int FAR PASCAL 	PROPEN(char far *NameSpool);/* Apertura della Stampa */
int FAR PASCAL 	PROUT(char far *Buffer);	/* Stampa una Stringa */
int FAR PASCAL 	PRENDPAGE(void);			/* Chiusura pagina */
int FAR PASCAL 	PRSTARTPAGE(void);			/* Apertura pagina */
HDC FAR GetHDCPrintDefault(void);			/* Ritorna HDC della stampante di default */

/*-----------------------------------------------------------------
 	Funzione 	LibMain

	Descrizione
	-----------
	Entrata DLL 					

	Parametri
    ----------
	HINSTANCE	hInstance
	WORD 		wDataSegment	
	WORD 		wHeapSize
    LPSTR		lpszCmdLine

    Tipo dato ritorno
    -----------------
    int

	Note
	----
------------------------------------------------------------------*/
int FAR PASCAL LibMain( HINSTANCE hInstance, WORD wDataSegment,
												WORD wHeapSize, LPSTR lpszCmdLine )
{
	if ( wHeapSize != 0 ) UnlockData( 0 );

	hInst = hInstance;
	HDCPrinter	= NULL;
	PrintOpen	= TRUE;

	return 1;
}

/*-----------------------------------------------------------------
 	Funzione 	WEP

	Descrizione
	-----------
	Uscita DLL 					

	Parametri
    ----------
	int			bSystemExit

    Tipo dato ritorno
    -----------------
    int

	Note
	----
------------------------------------------------------------------*/
int FAR PASCAL _export WEP ( int bSystemExit )
{
	PRCLOSE();
	return 1;
}

/*-----------------------------------------------------------------
 	Funzione 	WEP

	Descrizione
	-----------
	Uscita DLL 					

	Parametri
    ----------
	int			bSystemExit

    Tipo dato ritorno
    -----------------
    int

	Note
	----
------------------------------------------------------------------*/
int FAR PASCAL _export PRCLOSE()
{
	if (PrintOpen == TRUE) EndDoc(HDCPrinter);

	PrintOpen		= FALSE;

	if (HDCPrinter != NULL) {
		HDCPrinter	= 0;
		return 0;
	}
	return 1;
}

/*-----------------------------------------------------------------
* 	Funzione 	PROPEN
*
*	Descrizione
*	-----------
*	Apre un lavoro con la stampante di default di Windows 					
*
*	Parametri
*   ----------
*	char _FAR		*NameSpool		Descrizione file di Spool 	
*
*   Tipo dato ritorno
*   -----------------
*   int			0	OK
*				1	Errore : HDC del device non valido     	
*				2	Errore : apertura lavoro non valido    
*
*	Note
*	----
------------------------------------------------------------------*/
int FAR PASCAL _export PROPEN (char far * NameSpool)
{
	PRCLOSE();								/* Chiude eventuale lavoro aperto */

	/* Preleva HDC della stampante di default*/ 
	HDCPrinter	= GetHDCPrintDefault();

	if (HDCPrinter != NULL) {

    	/* Prepara struttura DOCINFO */
		DocInfo.cbSize		= sizeof(DocInfo);
		DocInfo.lpszDocName	= (char far *) SpoolName;
		DocInfo.lpszOutput	= NULL;

        /* Controllo che il nome dello Spool sia inferiore a 32 Byte */
		if (strlen(NameSpool) > 31) {
			strncpy(SpoolName, NameSpool, 31);
			SpoolName[31] = NULL;
		} else strcpy(SpoolName, NameSpool);

        /* Apre il Job */
		if (StartDoc(HDCPrinter, (DOCINFO far *) &DocInfo) >= 0) {
			PrintOpen	= TRUE;
			return 0;	/* OK */
		}
		else {
			PRCLOSE();
			return 2;	/* Si e' verificato un errore nell' aprire il Job */
		}
	}
	return 1;	/* HDC di Default non valido */
}

/*-----------------------------------------------------------------
 	Funzione 	PROUT

	Descrizione
	-----------
	Stampa il contenuto puntato da Buffer 					

	Parametri
    ----------
	char _FAR 	*Buffer		Ptr al Buffer contenente l' output per la stampante

    Tipo dato ritorno
    -----------------
    int			0	OK
    			1	Nessun lavoro aperto
                2	Errore : Escape non andato a buon fine

	Note
	----
	Il contenuto del Buffer deve terminare con NULL. 
------------------------------------------------------------------*/
int FAR PASCAL _export PROUT(char far *Buffer)
{
	int 		RetVal;			/* valore di ritorno */
	char NEAR  *AllocBuffer;	/* Ptr al Buffer */
	HLOCAL 		HMemLocal;		/* Handle al blocco di memoria allocata localmente */ 
	size_t		TotLenBuffer;	/* Lunghezza totale del Buffer di Input */

    /* Controlla ovviamente che ci sia un lavoro aperto */ 
	if (PrintOpen == TRUE) {

		TotLenBuffer	= _fstrlen(Buffer);

		HMemLocal = LocalAlloc(LPTR, TotLenBuffer + 2);	/* Alloca memoria */
		AllocBuffer	= LocalLock(HMemLocal);				/* Lock dell' Handle */

        /* Copia Buffer in AllocBuffer in offset 2 e riempe i primi due byte con lunghezza DOCINFO */
		_fmemcpy((void far *) (AllocBuffer + 2), Buffer, TotLenBuffer);
		*(size_t *) AllocBuffer = TotLenBuffer;	

        /* Spedisce direttamente il buffer alla stampante */
		RetVal	= Escape(HDCPrinter, PASSTHROUGH, NULL, (LPCSTR) AllocBuffer, NULL);

		LocalUnlock(HMemLocal);	/* UNLock dell' Handle */
		LocalFree(HMemLocal);	/* Libera memoria */ 

		return  RetVal > 0 ? 0 : 2;		/* Ritorna 0 se Escape e' andato a buon fine, altrimenti 1 */  
	}
	return 1;	/* Ritorna 1, in quanto non e' aperto nessun lavoro */  
}

/*-----------------------------------------------------------------
 	Funzione 	PRENDPAGE

	Descrizione
	-----------
	Chiude una pagina 					

	Parametri
    ----------

    Tipo dato ritorno
    -----------------
    int			0	OK
    			1	Nessun lavoro aperto

	Note
	----
------------------------------------------------------------------*/
int FAR PASCAL _export PRENDPAGE()
{
	/* Esegue EndPage se un lavoro e' attualmente in esecuzione */
	if (PrintOpen == TRUE) return EndPage(HDCPrinter) > 0 ? 0 : 1;

	return 1;	/* Nessun lavoro aperto */
}

/*-----------------------------------------------------------------
 	Funzione 	PRSTARTPAGE

	Descrizione
	-----------
	Apre una pagina 					

	Parametri
    ----------

    Tipo dato ritorno
    -----------------
    int			0	OK
    			1	Nessun lavoro aperto

	Note
	----
------------------------------------------------------------------*/
int FAR PASCAL _export PRSTARTPAGE()
{
	/* Esegue EndPage se un lavoro e' attualmente in esecuzione */
	if (PrintOpen == TRUE) return (StartPage(HDCPrinter) > 0 ? 0 : 1);

	return 1;	/* Nessun lavoro aperto */
}

/*-----------------------------------------------------------------
 	Funzione 	GetHDCPrintDefault

	Descrizione
	-----------
	Preleva da Win.Ini nella Sezione [windows] entry [device] la
    stampante di Default, crea un Device Context ad essa e ritorna
	il suo Handle.

	Parametri
    ----------

    Tipo dato ritorno
    -----------------
    HDC			Handle alla stampante (se NULL : errore creazione DC)

	Note
	----
------------------------------------------------------------------*/
HDC far GetHDCPrintDefault()
{

	char ProfileDevice[100];
	char far *Device, far *Driver, far *PortOut;

    /* Preleva in Win.Ini la Sezione [windows] entry [device] per	*/
	/* stampante di default											*/  
	GetProfileString("windows", "device", "", ProfileDevice, 100);

    /* Compone le stringhe per identificare il device e creare il DC */ 
	if ((Device = strtok(ProfileDevice, ",")) != NULL &&
			(Driver = strtok(NULL, ", ")) != NULL &&
			(PortOut = strtok(NULL, ", ")) != NULL) {

#if 0
		return CreateDC(Driver, Device, PortOut, NULL);
#else
		return CreateDC("RAW", NULL, PortOut, NULL);
#endif
    }

    /* DC non creato, ritorna NULL */ 
	return NULL;
}

/* EOF */