
//
// 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, "\nObjBitmap_NewDIBSection");
#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 )
	{
		MMechostr ( 1 , "BITMAP ERROR WIN32 Num %d" , GetLastError ());
		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, "\nObjBitmap_NewDIBSection end");
#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, "\nObjBitmap_New");
#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, "\nObjBitmap_New end %d", newHandler);
#endif
//***********************************
      
     return newHandler; // return the new handler
}    