
//
// Modifications History
//
//$ LB (13/06/2002) : added to fit with the new objbitmap structure and GDI management
//
//$LB (20/12/2002) : 16bits to 24bits
//
//$LB (16/12/2003) : add CaptureScreen (copy from LIB2DOS)
//

#include "bitmap.h"
#include "../x/scolplugin.h"


//$LB (16/12/2003)
void CaptureScreen (PtrObjBitmap B, int x, int y, int w, int h)
{
HDC         hScrDC, hMemDC;         // screen DC and memory DC     
int         wScrn, hScrn;           // screen resolution      
HGDIOBJ     hOldBitmap;

	   // create a DC for the screen and create     
	   // a memory DC compatible to screen DC          
       hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);     
       hMemDC = CreateCompatibleDC(hScrDC);      // get points of rectangle to grab  

		//
        // clipping according to the Screen Resolution 
		//
        wScrn = GetDeviceCaps(hScrDC, HORZRES);     
        hScrn = GetDeviceCaps(hScrDC, VERTRES);      
        if (w > wScrn) w = wScrn;
		if (h > hScrn) h = hScrn;
		if (x+w > wScrn) w = wScrn-x;
		if (y+h > hScrn) h = hScrn-y;


	   // make sure the bitmap object is an Device Independant Bitmap
		// we don't need that anymore : the bkg is created as a DIB
       //ObjBitmap_CreateDIBSection (B);
   
       // select new bitmap into memory DC     
       hOldBitmap =   SelectObject (hMemDC, B->DIBhandler);      
   
       // bitblt screen DC to memory DC     
       BitBlt(hMemDC, 0, 0, w, h, hScrDC, x, y, SRCCOPY);     
   
       // select old bitmap back into memory DC and get handle to     
       // bitmap of the screen          
       B->DIBhandler = (HBITMAP)SelectObject(hMemDC, hOldBitmap);      
   
       // clean up      
       DeleteDC(hScrDC);     
       DeleteDC(hMemDC);      
}


 
// create an objbitmap with a dibsection
void ObjBitmap_NewDIBSection (PtrObjBitmap B,PtrPalette P)
{
	DIBSECTION Info;
	BITMAPINFO Bit;
	int tf,i ;
	HDC dc ;
	LPalette Pal ;
	HPALETTE HPal , HPOld ;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "ObjBitmap_NewDIBSection\n");
#endif 
//***********************************

	/**************** construction de la palette initiale  *****************************/
	if (B->BPP == 8)
	{
	  Pal.Version = (unsigned short)GetVersion();
	  Pal.ColorNum = 256;
	  if (P != NULL)
	  for (tf = 0; tf < 256; tf ++)
	  {
	    Pal.Colors[tf].peRed = GET_RED(P, tf); 
	    Pal.Colors[tf].peGreen = GET_GREEN(P, tf);
	    Pal.Colors[tf].peBlue = GET_BLUE(P, tf);
	    Pal.Colors[tf].peFlags = (unsigned char)NULL;
	  }
	  HPal = CreatePalette((LOGPALETTE*)(&Pal));            
	  dc = CreateCompatibleDC(NULL);
	  HPOld = SelectPalette (dc, HPal, FALSE);
	} 
	else
		dc = NULL;
	
	Bit.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	Bit.bmiHeader.biWidth = B->TailleW;
	Bit.bmiHeader.biHeight = - B->TailleH;
	
	Bit.bmiHeader.biPlanes = 1;
	Bit.bmiHeader.biBitCount = B->BPP;
	if ((B->BPP == 8) || (B->BPP == 24))
		Bit.bmiHeader.biCompression = BI_RGB;
	else  
		return;
	Bit.bmiHeader.biSizeImage = 0;
	Bit.bmiHeader.biXPelsPerMeter = 0;
	Bit.bmiHeader.biYPelsPerMeter = 0;
	if (B->BPP == 8)
	{
		Bit.bmiHeader.biClrUsed = 256;
		tf = DIB_PAL_COLORS;
	}
	else 
	{
		Bit.bmiHeader.biClrUsed = 0;
		tf = DIB_RGB_COLORS;
	}
	Bit.bmiHeader.biClrImportant = Bit.bmiHeader.biClrUsed;
	
	B->DIBhandler = CreateDIBSection(dc, (BITMAPINFO *)&Bit, tf, (void **)&B->bits, NULL, 0);
	
	if (B->DIBhandler == NULL)
	{
	  LPVOID lpMsgBuf;
	
		FormatMessage( 
			FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			GetLastError(),
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
			(LPTSTR)&lpMsgBuf,
			0,
			NULL);
	
	
		MMechostr (1, "BITMAP ERROR 2 WIN32 Num %d : %s", GetLastError(), lpMsgBuf);
		LocalFree(lpMsgBuf);
	
		return;
	}
	
	i = GetObject(B->DIBhandler, sizeof(DIBSECTION), &Info);
	if (!i) MMechostr (1, "GETOBJECT ERROR Num %d", GetLastError());
	B->bits = (OBJBITMAP_BUFFER)Info.dsBm.bmBits;
	B->bits[0] = 0;
	B->BPP = Info.dsBm.bmBitsPixel;
	B->BytesPP = B->BPP >>3;
	
	B->BPL = Info.dsBm.bmWidthBytes ;
	if (B->BPL % 4 != 0) B->BPL += 4 - (B->BPL % 4);
	
	if (Info.dsBmih.biHeight > 0)
	B->Flags = 0;     
	
	if (dc) 
	{
	  SelectPalette(dc, HPOld, FALSE);
	  DeleteObject(HPal);
	  DeleteDC(dc);
	}
	
	//$LB (13/06/2002) : we don't create a scol object for this, so we don't have to request a handler to the VM
	B->handler = (int)B->DIBhandler;

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "ObjBitmap_NewDIBSection end\n");
#endif
//***********************************

}







//$ LB (13/06/2002) : don't create a DIBSection anymore, when creating an ObjBitmap.
//                    alloc memory for buffer and palette. The DIBSection will be create later if needed.

/********************************************************/
/*                                                      */
/* int ObjBitmap_New (old NewObjBitmap)                 */
/*                                                      */
/* create a new bitmap buffer and return a handler      */
/*                                                      */
/********************************************************/
int ObjBitmap_New ( PtrObjBitmap B , PtrPalette P )
{
int tf;
int sizeImage;
int newHandler;


//***********************************
#if DEBUG_LIB2D
MMechostr (0, "ObjBitmap_New\n");
#endif
//***********************************


 	 //
	 // Init Data
	 //
 
	 B->BPL = B->TailleW * (B->BPP >>3);                 // nb bytes per line
	 if (B->BPL % 4 != 0 ) B->BPL += 4 - (B->BPL % 4);   // align 32 bits (Windows constraint)

	 //$ LB (13/06/2002) : use BPL instead of (BPP * 8 * Width), because Windows Bitmaps are 32 bits aligned...
	 sizeImage = B->BPL * abs(B->TailleH);


	 //
   // alloc Palette
	 //
   if (B->BPP == 8)
	 {

			B->table = (PALETTEENTRY*) malloc (256 * sizeof (PALETTEENTRY));

			if (!B->table) return 0;

			if (P)
				for ( tf = 0 ; tf < 256 ; tf ++ )
				{
					B->table[tf].peRed = GET_RED(P,tf) ; 
					B->table[tf].peGreen = GET_GREEN(P,tf) ;
					B->table[tf].peBlue = GET_BLUE(P,tf) ;
					B->table[tf].peFlags = ( unsigned char ) NULL ;
				}
				
			else 
				for ( tf = 0 ; tf < 256 ; tf ++ )
				{
					B->table[tf].peRed = tf; 
					B->table[tf].peGreen = tf;
					B->table[tf].peBlue = tf;
					B->table[tf].peFlags = ( unsigned char ) NULL ;
				}

     } else B->table = NULL;


 	 //
     // alloc Bitmap Buffer
	 //
	 B->bits = (OBJBITMAP_BUFFER) malloc (sizeImage);  
	 if (!B->bits) return 0;


	 //
	 // Init Data
	 //
 	 //memset ((void*) B->bits, 0, sizeImage);  // bitmap buffer
	 B->bits[0] = 0;

   B->DIBhandler = NULL;                    // DIBSection handler
	 #ifdef USE_DRAWDIB
     B->Flags = BUFFER_FLAG_DOWN;         // Flags
   #else
		 B->Flags = 0 ;     
	 #endif


   newHandler = OBJgetNewHandler ();
 

	 //MMechostr(MSKDEBUG, "creating bitmap %d %d %d\n", newHandler, B->TailleW, B->TailleH);

//***********************************
#if DEBUG_LIB2D
MMechostr (0, "ObjBitmap_New end %d\n", newHandler);
#endif
//***********************************
      
     return newHandler; // return the new handler
}    