/***********************************/
/* win_trans.h                     */
/*                                 */
/* source for windows transparency */
/*                                 */
/* loïc berthelot    janv 2004     */
/***********************************/


//
// Modifications History
//
//$LB (16/12/2003) : TODO TO DO : process a repaint after a _SIMULATEwindowTransparency (there's a bug about that...)
//




#include "objects/win_trans.h"
#include "objects/bitmap.h"
#include "osversion.h"
#include "macros.h"
#include "colors.h"




//$LB (16/12/2003)
PtrObjBitmap LIB2DOStransBkg             =NULL; // background bitmap for simulated window transparency 

PSLWA        pSetLayeredWindowAttributes =NULL; // point to window layer attributes function
HMODULE      user32DLL                   =NULL; // handle of user32 dll




//$LB (16/12/2003)
int InitWindowTransparency(PtrObjWindow W)
{
RECT screen;


	if (user32DLL == NULL)
	{
		if ((user32DLL = LoadLibrary ("user32")) == NULL)
		{
			MMechostr (MSKDEBUG, "\nWindows Transparency Initialization failed!... user32.dll not found...\n");
			return 0;
		}

		pSetLayeredWindowAttributes =   (PSLWA) GetProcAddress(user32DLL,"SetLayeredWindowAttributes");

		if (pSetLayeredWindowAttributes == NULL) 
		{
			MMechostr (MSKDEBUG, "\nWindows Transparency Initialization failed!... SetLayeredWindowAttributes function not found!\n");
			return 0;
		}
	}


	// LIB2D transparency bitmap background
	if (LIB2DOStransBkg == NULL)
	{
	  GetWindowRect ( GetDesktopWindow () , &screen) ;

	  LIB2DOStransBkg = (PtrObjBitmap) malloc (sizeof(struct ObjBitmap));
	  LIB2DOStransBkg->TailleW = screen.right - screen.left;
	  LIB2DOStransBkg->TailleH = screen.bottom - screen.top;
	  LIB2DOStransBkg->BPP = 24;
	  LIB2DOStransBkg->BytesPP = 3;

	  ObjBitmap_New (LIB2DOStransBkg, NULL);
	}
	
	// update the screen capture
    CaptureScreen (LIB2DOStransBkg, 0, 0, LIB2DOStransBkg->TailleW, LIB2DOStransBkg->TailleH);


	// window transparency buffer
	if (W != NULL)
	if (W->tBuf == NULL)
	{
		W->tBuf = (PtrObjBitmap) malloc (sizeof(struct ObjBitmap));
		W->tBuf->TailleW = W->TailleW;
		W->tBuf->TailleH = W->TailleH;
		W->tBuf->BPP = 24;
		W->tBuf->BytesPP = 3;
		W->tX = W->PosX;
		W->tY = W->PosY;

		ObjBitmap_New (W->tBuf, NULL);
		ObjBitmap_CreateDIBSection (W->tBuf);
	}

	return 1;
}





//$LB (16/12/2003)
/********************************************************/
/*                                                      */
/* int _SIMULATEwindowTransparency                      */
/*                                                      */
/* allows to switch the transparency mode.              */
/*                                                      */
/* usefull to take a look at the graphic behaviour the  */
/* window should have if the transparency is simulated  */
/* (<=> when scol is running under Win95,98,ME)         */
/*                                                      */
/* parameters :                                         */
/*   - ObjWin window                                    */
/*   - I flag (1 : simulation ON; 0 : simulation OFF)   */
/*                                                      */
/********************************************************/
int _SIMULATEwindowTransparency (mmachine m)
{
osinfo theOSinfo = GetOsInfo();
PtrObjVoid O;
PtrObjWindow W;
HWND H;
int s, flag;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SIMULATEwindowTransparency");
#endif
//***********************************


    flag  = MTOI (MMpull(m));
	s      = MMpull(m) ;

    if ( s == NIL ) 
	{
		MMechostr(MSKDEBUG, "\n_SIMULATEwindowTransparency : window is NIL!...\n");
		return MMpush ( m , NIL ) ;
	}

    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;
    W = ( PtrObjWindow) MMstart(m, (O->Buffer>>1) ) ;
	H = W->WHandler;


	//
	// WinXP, Win2000
	//
	if ( ((theOSinfo &0XF0) | OS_WINDOWS) &&  (((theOSinfo &0x0F) | kOsInfoWinXp) || ((theOSinfo &0x0F) | kOsInfoWin2000)) )
	{

		if (flag == 0)
		{
			if (!InitWindowTransparency(NULL))
				return MMpush (m, NIL);

			pSetLayeredWindowAttributes (H,	_COLOR_BGR_TO_I (W->tColorB, W->tColorG, W->tColorR), W->tfactor, W->tflags);
			W->tSimulated = 0;
		}
		else
		{
			if (!InitWindowTransparency(W))
				return MMpush (m, NIL);

			pSetLayeredWindowAttributes (H,	0xCCCCCC, 255, LWA_ALPHA);
			W->tSimulated = 1;
		} 

	}
		
	//
	// OTHER VERSIONS : this function is just for Win2000, XP, 
	//



//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SIMULATEwindowTransparency ok");
#endif
//***********************************

	return MMpush (m, s);
    
}



//$LB (16/12/2003)
/********************************************************/
/* internal body                                        */
/*                                                      */
/* int SetWindowTransparency                            */
/*                                                      */
/* allows to set the window transparency, which can be  */
/* done with a transparency color, or with an alpha     */
/* blending factor.                                     */
/*                                                      */
/* it's fully functional with WinXP and Win2000.        */
/* With other Windows versions, we have to simulate the */
/* process with a screen capture, within the window     */
/* painting procedure.                                  */
/*                                                      */
/********************************************************/
int SetWindowTransparency (PtrObjWindow Wnd, int color, int factor, int flags)
{
HWND H = (HWND)Wnd->WHandler;

		if (Wnd->tSimulated ==0)

		//
		// WIN XP and WIN 2K
		//
		{
			SetWindowLong (H, GWL_EXSTYLE, GetWindowLong (H, GWL_EXSTYLE ) | WS_EX_LAYERED ) ;

			if (!InitWindowTransparency(Wnd))
				return 0;

			pSetLayeredWindowAttributes (H,	color, factor, flags);
		}
		
		//
		// OTHER VERSIONS
		//
		else
		{
			return 1;
		}

		return 1;
}






//$LB (16/12/2003)
/********************************************************/
/*                                                      */
/* int _SETwindowTransparency                           */
/*                                                      */
/* allows to set the window transparency.               */
/*                                                      */
/* use the internal SetWindowTransprency function.      */
/*                                                      */
/* parameters :                                         */
/*   - ObjWin window                                    */
/*   - I transparencyColor   [0x000000 --> 0xFFFFFF]    */
/*   - I alphaBlendingFactor [0x00 --> 0xFF]            */
/*   - I flags (WNT_COLORKEY|WNT_ALPHA)                 */
/*                                                      */
/********************************************************/
int _SETwindowTransparency (mmachine m)
{
int s, color, factor, flags;
PtrObjVoid O;
PtrObjWindow H;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SETwindowTransparency");
#endif
//***********************************


    flags  = MTOI (MMpull(m));
	factor = MTOI (MMpull(m));
	color  = MTOI (MMpull(m));
	s      = MMpull(m) ;

    if ( s == NIL ) 
	{
		MMechostr(MSKDEBUG, "\n_SETwindowTransparency : window is NIL!...\n");
		return MMpush ( m , NIL ) ;
	}

    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;
    H = ( PtrObjWindow) MMstart(m, (O->Buffer>>1) ) ;

	if (!SetWindowTransparency (H, color, factor, flags))
		return MMpush (m, NIL);
	else 
	{
		_COLOR_I_TO_BGR (color, &(H->tColorB), &(H->tColorG), &(H->tColorR));
		
		H->tfactor = factor;
		H->tflags = flags;


//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\n_SETwindowTransparency ok");
#endif
//***********************************

		return MMpush (m, s);
	}
    
}


