

//
// Modifications History
//
//$ LB (13/06/2002) : changed objbitmap access, according to the new objbitmap structure
//


#include "x/Version.h"
#include "x/scolplugin.h"

#include <stdio.h>
#include <string.h>

#include <stdlib.h>
#include <process.h>

#include "printer.h"

#include "objstr.h"
#include "objects/bitmap.h"



int WM_PRINTER;

int _printbitmap(mmachine m)
{
  DOCINFO di;
  int objbitmap;
  int nError;
  int cWidthPels; 
  int cHeightPels; 
  PtrObjBitmap Bitmap;
  HDC hdcMem;
  HDC hDC;
  BITMAP bmih;
  PtrObjVoid OB;
  int aX,aY;
  int aW,aH;
  int printer;
  char * Printer;
  PRINTER_INFO_1 pInfo[10];
  long dummy;
  long dummy2;
 
  aH=MMpull(m)>>1;
  aW=MMpull(m)>>1;
  aY=MMpull(m)>>1;
  aX=MMpull(m)>>1;
  printer=MMpull(m)>>1;
  objbitmap=MMget(m,0)>>1;

  if ( (aX==NIL) ||(aY==NIL) ||(aW==NIL) ||(aH==NIL)) 
  {
    MMset(m,0,NIL);
    return 0;
  }
  OB = ( PtrObjVoid ) MMstart(m,(MMget(m,0)>>1) ) ;
  Bitmap = (PtrObjBitmap) MMstart(m,(OB->Buffer>>1) ) ;

  //$ LB (13/06/2002) : create DIBSection from bitmap buffer
  if (!Bitmap->DIBhandler) ObjBitmap_CreateDIBSection (Bitmap);


  MMechostr (0,"W: %d  H: %d",Bitmap->TailleW,Bitmap->TailleH);

  if (printer==NIL)
  {
    dummy=0;
    dummy2=0;
    if (!EnumPrinters( 
            PRINTER_ENUM_DEFAULT, // types of printer objects to enumerate 
            NULL, // name of printer object 
            1, // specifies type of printer info structure 
            (unsigned char*)pInfo, // pointer to buffer to receive printer info structures 
            sizeof(PRINTER_INFO_1)*10, // size, in bytes, of array 
            &dummy, // pointer to variable with no. of bytes copied (or required) 
            &dummy2 // pointer to variable with no. of printer info. structures copied 
        ))
    {
      Printer=pInfo[0].pName;
      MMechostr(MSKDEBUG,"\nSortie sur l'imprimante par défaut %s\n n1:%d n2%d",Printer,dummy,dummy2);
      MMset(m,0,NIL);
      return 0;
    }
    Printer=pInfo[0].pName;
    MMechostr(MSKDEBUG,"\nSortie sur l'imprimante par défaut %s\n n1:%d n2%d",Printer,dummy,dummy2);
  }
  else Printer=MMstartstr(m,printer);

  hDC=CreateDC (NULL,Printer,NULL,NULL);
  MMechostr (0,"Apres PrintDLG");
 /*
  * Examine the raster capabilities of the device
  * identified by pd.hDC to verify that it supports
  * the BitBlt function.
  */
 
  if (!(GetDeviceCaps(hDC, RASTERCAPS) & RC_BITBLT)) 
  { 
    DeleteDC(hDC); 
    MMechostr(MSKDEBUG,"Printer cannot display bitmaps.Device Error\n"); 
    return 0;
  } 

 /* 
  * Initialize the members of a DOCINFO 
  * structure. 
  */ 

  di.cbSize = sizeof(DOCINFO); 
  di.lpszDocName = "SCOL Printing"; 
  di.lpszOutput = (LPTSTR) NULL; 
//   di.lpszDataType = (LPTSTR) NULL; 
  di.fwType = 0; 

 /* 
  * Begin a print job by calling the StartDoc 
  * function. 
  */ 
  nError = StartDoc(hDC, &di); 
  if (nError == SP_ERROR) 
  { 
    MMset(m,0,NIL);
    MMechostr(MSKDEBUG,"Start Doc Error\n");
    goto Error; 
  } 

 /* 
  * Inform the driver that the application is 
  * about to begin sending data. 
  */ 
  MMechostr (0,"StartPage...\n");

  nError = StartPage(hDC); 
  if (nError <= 0) 
  { 
    MMset(m,0,NIL);
    MMechostr(MSKDEBUG,"Start Page Error\n");
    goto Error; 
  } 


  hdcMem = CreateCompatibleDC(hDC); 
  if (hdcMem==NULL) 
  {
    MMechostr(MSKDEBUG,"CreateCompatibleDC Error\n");
    MMset(m,0,NIL);
    goto Error;
  }

  if (!SelectObject(hdcMem,Bitmap->DIBhandler)) 
  { 
    MMechostr(MSKDEBUG,"Select1 Error\n");
    MMset(m,0,NIL);
    goto Error;
  }
  
  if (!GetObject(Bitmap->DIBhandler, sizeof(BITMAP), (LPSTR) &bmih))
  { 
    MMechostr(MSKDEBUG,"GetObject Error\n");
    MMset(m,0,NIL);
    goto Error;
  }
      
  cWidthPels = GetDeviceCaps(hDC, HORZRES); 
  cHeightPels = GetDeviceCaps(hDC, VERTRES); 

 /* 
  * Create a memory DC that is compatible with 
  * the printer and select the bitmap (which 
  * the user requested) into this DC. 
  */ 

  MMechostr (0,"SelectObject...\n");
  if (!SelectObject(hdcMem, Bitmap->DIBhandler)) 
  {
    MMechostr(MSKDEBUG,"Select2 Error\n");
    MMset(m,0,NIL);
    goto Error;
  }

  if (!StretchBlt(hDC, 
     (int) ((float) aX*(GetDeviceCaps(hDC, LOGPIXELSX)/2.54) )/100,
     (int) ((float) aY*(GetDeviceCaps(hDC, LOGPIXELSY)/2.54) )/100, 
     (int) ((float) aW*(GetDeviceCaps(hDC, LOGPIXELSX)/2.54) )/100, 
     (int) ((float) aH*(GetDeviceCaps(hDC, LOGPIXELSY)/2.54) )/100, 
     hdcMem, 0, 0, 
     cWidthPels, cHeightPels, 
     SRCCOPY)) 
  {
    MMset(m,0,NIL);
    MMechostr(MSKDEBUG,"Stretch2 Error\n");
    goto Error;
  }

/* Delete the memory DC. */ 
  DeleteDC(hdcMem); 

 /* 
  * Retrieve the width of the string that 
  * specifies the full path and filename for the 
  * file that contains the bitmap. 
  */ 

  MMechostr (0,"EndPage");
  nError = EndPage(hDC); 
  if (nError <= 0)    
  { 
    MMset(m,0,NIL);
    MMechostr(MSKDEBUG,"End Page Error\n");
    goto Error; 
  } 

  /* Inform the driver that document has ended. */ 

  MMechostr (0,"EndDoc");
  nError = EndDoc(hDC);
  if (nError <= 0)
  {
    MMset(m,0,NIL);
    MMechostr(MSKDEBUG,"End Doc Error\n");
    goto Error;
  }

  MMset(m,0,objbitmap*2+1);

Error:
  /* Delete the printer DC. */
  MMechostr (0,"DeleteDC");
  DeleteDC(hDC);
  return 0;
}

typedef struct PRINT
{
  PRINTDLG pd;
  PtrObjBitmap bm;
  PtrObjWindow wn;
  int x,y,w,h;
} PRINT;

void PrintDialogThread (PVOID pvoid)
{
  PRINT *p;
  PtrObjWindow w;

  p=(PRINT*)pvoid;
  w=p->wn;
  
  p->pd.lStructSize=sizeof(PRINTDLG); 
  if (w)
    p->pd.hwndOwner=w->WHandler; 
  else
    p->pd.hwndOwner=NULL; 

  p->pd.hDevMode=NULL; 
  p->pd.hDevNames=NULL; 
  p->pd.hDC=NULL; 
  p->pd.Flags=PD_RETURNDC; 
  p->pd.nFromPage=1; 
  p->pd.nToPage=1; 
  p->pd.nMinPage=1; 
  p->pd.nMaxPage=1; 
  p->pd.nCopies=1;
  p->pd.hInstance=NULL; 
  p->pd.lCustData=0; 
  p->pd.lpfnPrintHook=NULL; 
  p->pd.lpfnSetupHook=NULL; 
  p->pd.lpPrintTemplateName=NULL; 
  p->pd.lpSetupTemplateName=NULL; 
  p->pd.hPrintTemplate=NULL; 
  p->pd.hSetupTemplate=NULL; 

  if (!PrintDlg(&(p->pd)))
  {
    MMechostr (0,"ERR PrintDLG\n");
    PostMessage ((HWND)SCgetExtra("hscol"),WM_PRINTER,-1,(LPARAM)pvoid);
  } 

  PostMessage ((HWND)SCgetExtra("hscol"),WM_PRINTER,0,(LPARAM)pvoid);

  _endthread();
}

int _printbitmapdlg(mmachine m)
{
  PtrObjBitmap Bitmap;
  PtrObjWindow Window;
  PtrObjVoid OB;
  int aX,aY;
  int aW,aH;
  PRINT * p;

  aH=MMpull(m)>>1;
  aW=MMpull(m)>>1;
  aY=MMpull(m)>>1;
  aX=MMpull(m)>>1;

  if ( (aX==NIL) ||(aY==NIL) ||(aW==NIL) ||(aH==NIL)) 
  {
	MMpull(m);
    MMset(m,0,NIL);
    return 0;
  }

  p=malloc (sizeof (PRINT));
  if (!p) 
  {
	MMpull(m);
    MMset(m,0,NIL);
    return 0;
  }
  
  if (MMget(m,0)!=NIL) 
  {
    OB = ( PtrObjVoid ) MMstart(m,(MMpull(m)>>1) ) ;
    Window = ( PtrObjWindow ) MMstart(m,(OB->Buffer>>1) ) ;
    p->wn=Window;
  }
  else
  {
    MMpull(m);
    p->wn=NULL;
  }

  OB = ( PtrObjVoid ) MMstart(m,(MMget(m,0)>>1) ) ;
  Bitmap = ( PtrObjBitmap ) MMstart(m,(OB->Buffer>>1) ) ;

  p->x=aX;
  p->y=aY;
  p->w=aW;
  p->h=aH;
  p->bm=Bitmap;
  p->wn=Window;

  MMechostr (0,"W: %d  H: %d",Bitmap->TailleW,Bitmap->TailleH);

  if (_beginthread (PrintDialogThread,0,p)==-1)
  {
	  MMset(m,0,NIL);
      return 0;
  }

/*  hDC=CreateDC (NULL,"HP DeskJet 600",NULL,NULL);*/
  return 0;
}


int RealPrintDlg (PRINT * p)
{
  DOCINFO di;
  int nError;
  int cWidthPels;
  int cHeightPels;
  PtrObjBitmap Bitmap;
  HDC hdcMem;
/*  HDC hDC;*/
  BITMAP bmih;
  int aX,aY;
  int aW,aH;
/*  PAGESETUPDLG psd;*/  
  PRINTDLG * pd;
/*  MMechostr (0,"Apres PrintDLG pd.hDC=%X\n",pd->hDC);*/
  pd=&(p->pd);
  Bitmap=p->bm;

  //$ LB (13/06/2002) : create DIBSection from bitmap buffer
  if (!Bitmap->DIBhandler) ObjBitmap_CreateDIBSection (Bitmap);



  aX=p->x;
  aY=p->y;
  aW=p->w;
  aH=p->h;

  MMechostr (0,"W: %d  H: %d",Bitmap->TailleW,Bitmap->TailleH);

 /* 
  * Examine the raster capabilities of the device 
  * identified by pd.hDC to verify that it supports 
  * the BitBlt function. 
  */ 
 
  if (!(GetDeviceCaps(pd->hDC, RASTERCAPS) & RC_BITBLT)) 
  { 
    MMechostr(MSKDEBUG,"Printer cannot display bitmaps.Device Error\n"); 
    DeleteDC(pd->hDC); 
    return 0;
  } 

 /* 
  * Initialize the members of a DOCINFO 
  * structure. 
  */ 

  di.cbSize = sizeof(DOCINFO); 
  di.lpszDocName = "SCOL Printing"; 
  di.lpszOutput = (LPTSTR) NULL; 
//   di.lpszDataType = (LPTSTR) NULL; 
  di.fwType = 0; 

 /* 
  * Begin a print job by calling the StartDoc 
  * function. 
  */ 
  nError = StartDoc(pd->hDC, &di); 
  if (nError == SP_ERROR) 
  { 
    MMechostr(MSKDEBUG,"Start Doc Error\n");
    goto Error; 
  } 

 /* 
  * Inform the driver that the application is 
  * about to begin sending data. 
  */ 
  MMechostr (0,"StartPage...\n");

  nError = StartPage(pd->hDC); 
  if (nError <= 0) 
  { 
    MMechostr(MSKDEBUG,"Start Page Error\n");
    goto Error; 
  } 


  hdcMem = CreateCompatibleDC(pd->hDC); 
  if (hdcMem==NULL) 
  {
    MMechostr(MSKDEBUG,"CreateCompatibleDC Error\n");
    goto Error;
  }

  if (!SelectObject(hdcMem,Bitmap->DIBhandler)) 
  { 
    MMechostr(MSKDEBUG,"Select1 Error\n");
    goto Error;
  }
  
  if (!GetObject(Bitmap->DIBhandler, sizeof(BITMAP), (LPSTR) &bmih))
  { 
    MMechostr(MSKDEBUG,"GetObject Error\n");
    goto Error;
  }
      
  cWidthPels = GetDeviceCaps(pd->hDC, HORZRES); 
  cHeightPels = GetDeviceCaps(pd->hDC, VERTRES); 
  MMechostr (0,"W: %d  H: %d\n",cWidthPels,cHeightPels);
  MMechostr (0,"W: %d  H: %d\n",GetDeviceCaps(hdcMem, HORZRES),GetDeviceCaps(hdcMem, VERTRES));

 /* 
  * Create a memory DC that is compatible with 
  * the printer and select the bitmap (which 
  * the user requested) into this DC. 
  */ 

  MMechostr (0,"SelectObject...\n");
  if (!SelectObject(hdcMem, Bitmap->DIBhandler)) 
  {
    MMechostr(MSKDEBUG,"Select2 Error\n");
    goto Error;
  }

  if (!StretchBlt(pd->hDC, 
     (int) ((float) aX*(GetDeviceCaps(pd->hDC, LOGPIXELSX)/2.54) )/100,
     (int) ((float) aY*(GetDeviceCaps(pd->hDC, LOGPIXELSY)/2.54) )/100, 
     (int) ((float) aW*(GetDeviceCaps(pd->hDC, LOGPIXELSX)/2.54) )/100, 
     (int) ((float) aH*(GetDeviceCaps(pd->hDC, LOGPIXELSY)/2.54) )/100, 
     hdcMem, 0, 0, 
     cWidthPels, cHeightPels, 
     SRCCOPY)) 
  {
    MMechostr(MSKDEBUG,"Stretch2 Error\n");
    goto Error;
  }

/* Delete the memory DC. */ 
  DeleteDC(hdcMem); 

 /* 
  * Retrieve the width of the string that 
  * specifies the full path and filename for the 
  * file that contains the bitmap. 
  */ 

  MMechostr (0,"EndPage");
  nError = EndPage(pd->hDC); 
  if (nError <= 0)    
  { 
    MMechostr(MSKDEBUG,"End Page Error\n");
    goto Error; 
  } 

  /* Inform the driver that document has ended. */ 

  MMechostr (0,"EndDoc");
  nError = EndDoc(pd->hDC); 
  if (nError <= 0) 
  { 
    MMechostr(MSKDEBUG,"End Doc Error\n");
    goto Error; 
  } 

Error: 
  /* Delete the printer DC. */ 
  MMechostr (0,"DeleteDC");
  DeleteDC(pd->hDC); 
  return 0;
} 

int _lineprint(mmachine m)
{
  FILE * prn;
  int s;
  char * S;

  s=MMget (m,0)>>1;
  if (s==NIL) return 0;
  S=MMstartstr(m,s);
  if (S==NULL) { MMset (m,0,NIL); return 0;};

  prn=fopen("LPT1:","w");
  if (!prn) MMechostr (0,"impossible d'ouvrir l'imprimante LPT1\n");
  else
  {
    fprintf (prn,"%s",S);
    fflush (prn);
    fclose (prn);
  }
  return 0;
}

int _lineprintff(mmachine m)
{
  FILE * prn;
  int s;
  char * S;

  s=MMget (m,0)>>1;
  if (s==NIL) return 0;
  S=MMstartstr(m,s);
  if (S==NULL) { MMset (m,0,NIL); return 0;};

  prn=fopen("LPT1:","w");
  if (!prn) MMechostr (0,"impossible d'ouvrir l'imprimante LPT1\n");
  else
  {
    fprintf (prn,"%s\f",S);
    fflush (prn);
    fclose (prn);
  }
  return 0;
}

int ScolPrinter(mmachine m,HWND hwnd,unsigned msg,UINT wParam, LONG lParam,int *ret)
{
	RealPrintDlg((PRINT*)lParam);
	return 0;
}

int IniPrinter(mmachine m)
{
	WM_PRINTER=OBJgetUserEvent();
	OBJdefEvent(WM_PRINTER,ScolPrinter);
	return 0;
}
