1504 lines
46 KiB
C
1504 lines
46 KiB
C
#ifdef FLJ
|
|
#undef MOD_BACKGROUNDIMAGE
|
|
#endif
|
|
|
|
#include <setjmp.h>
|
|
#include "jpeg/jpeglib.h"
|
|
#include <stdio.h>
|
|
|
|
#include <windows.h>
|
|
|
|
#ifdef MOD_BACKGROUNDIMAGE
|
|
|
|
#include <math.h>
|
|
#include "putty.h"
|
|
#include "terminal.h"
|
|
|
|
#include "kitty_image.h"
|
|
|
|
extern Conf *conf ;// extern Config cfg;
|
|
//extern int offset_width, offset_height ;
|
|
//extern int font_width, font_height ;
|
|
|
|
#ifndef NCFGCOLOURS
|
|
#define NCFGCOLOURS 24
|
|
#endif
|
|
#ifndef NEXTCOLOURS
|
|
#define NEXTCOLOURS 240
|
|
#endif
|
|
#ifndef NALLCOLOURS
|
|
#define NALLCOLOURS (NCFGCOLOURS + NEXTCOLOURS)
|
|
#endif
|
|
|
|
//extern COLORREF colours[NALLCOLOURS] ;
|
|
extern HWND MainHwnd ;
|
|
|
|
int stricmp(const char *s1, const char *s2) ;
|
|
int GetSessionField( const char * session_in, const char * folder_in, const char * field, char * result ) ;
|
|
int get_param( const char * val ) ;
|
|
|
|
int return_offset_height(void) ;
|
|
int return_offset_width(void) ;
|
|
int return_font_height(void) ;
|
|
int return_font_width(void) ;
|
|
COLORREF return_colours258(void) ;
|
|
|
|
|
|
static BOOL (WINAPI * pAlphaBlend)( HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION ) = 0 ;
|
|
|
|
//static HWND hwnd;
|
|
|
|
HDC textdc = NULL ;
|
|
HBITMAP textbm = NULL ;
|
|
COLORREF colorinpixel;
|
|
HDC colorinpixeldc = NULL ;
|
|
HBITMAP colorinpixelbm = NULL;
|
|
HDC backgrounddc = NULL ;
|
|
HBITMAP backgroundbm = NULL ;
|
|
HDC backgroundblenddc = NULL ;
|
|
HBITMAP backgroundblendbm = NULL;
|
|
BOOL bBgRelToTerm;
|
|
bool resizing;
|
|
RECT size_before;
|
|
|
|
|
|
#ifdef DLL
|
|
#define TARGET extern __declspec(dllexport)
|
|
#else
|
|
#define TARGET
|
|
#endif
|
|
|
|
static int ShrinkBitmapEnable = 1 ;
|
|
void SetShrinkBitmapEnable( int v ) {
|
|
if( v ) ShrinkBitmapEnable = 1 ;
|
|
else ShrinkBitmapEnable = 0 ;
|
|
}
|
|
|
|
|
|
//
|
|
// Fonctions de shrink de bitmap
|
|
//
|
|
#define Alloc(p,t) (t *)malloc((p)*sizeof(t))
|
|
#define For(i,n) for ((i)=0;(i)<(n);(i)++)
|
|
#define iFor(n) For (i,n)
|
|
#define jFor(n) For (j,n)
|
|
|
|
typedef struct {
|
|
WORD x, y ; // dimensions
|
|
WORD l ; // bytes per scan-line (32-bit allignment)
|
|
BYTE *b ; // bits of bitmap,3 bytes/pixel, BGR
|
|
} tWorkBMP ; // 24-bit working bitmap
|
|
|
|
void CreateWorkingBitmap( WORD dx, WORD dy, tWorkBMP *w ) {
|
|
w->x=dx ;
|
|
w->y=dy ;
|
|
w->l=(dx+1)*3&0xfffc ;
|
|
w->b=Alloc( w->l*dy, BYTE ) ;
|
|
}
|
|
|
|
HBITMAP CreateEmptyBitmap( WORD dx, WORD dy ) {
|
|
HDC h = GetDC( NULL ) ;
|
|
HBITMAP b = CreateCompatibleBitmap( h, dx, dy ) ;
|
|
ReleaseDC( NULL, h ) ;
|
|
return(b) ;
|
|
}
|
|
|
|
void SetBMIHeader( BITMAPINFO *b, short dx, short dy ) {
|
|
b->bmiHeader.biSize = sizeof(BITMAPINFOHEADER) ;
|
|
b->bmiHeader.biWidth = dx ;
|
|
b->bmiHeader.biHeight = -dy ;
|
|
b->bmiHeader.biPlanes = 1 ;
|
|
b->bmiHeader.biBitCount = 24 ;
|
|
b->bmiHeader.biCompression = BI_RGB ;
|
|
b->bmiHeader.biSizeImage = 0 ;
|
|
b->bmiHeader.biXPelsPerMeter = 1 ;
|
|
b->bmiHeader.biYPelsPerMeter = 1 ;
|
|
b->bmiHeader.biClrUsed = 0 ;
|
|
b->bmiHeader.biClrImportant = 0 ;
|
|
}
|
|
|
|
POINT GetBitmapSize( HBITMAP h ) {
|
|
POINT p ;
|
|
BITMAP o ;
|
|
GetObject( h, sizeof(o), &o ) ;
|
|
p.x = o.bmWidth ;
|
|
p.y = o.bmHeight ;
|
|
return(p) ;
|
|
}
|
|
|
|
void OpenBitmapForWork( HBITMAP b, tWorkBMP *w ) {
|
|
BITMAPINFO s ;
|
|
HDC h = GetDC( NULL ) ;
|
|
POINT v = GetBitmapSize( b ) ;
|
|
CreateWorkingBitmap( v.x, v.y, w ) ;
|
|
SetBMIHeader( &s,w->x, w->y ) ;
|
|
GetDIBits( h, b, 0, w->y, w->b, &s, DIB_RGB_COLORS ) ;
|
|
ReleaseDC( NULL, h ) ;
|
|
}
|
|
|
|
void SaveWorkingBitmap( tWorkBMP *w, HBITMAP b ) {
|
|
BITMAPINFO s ;
|
|
HDC h = GetDC( NULL ) ;
|
|
SetBMIHeader( &s, w->x, w->y ) ;
|
|
SetDIBits( h, b, 0, w->y, w->b, &s, DIB_RGB_COLORS ) ;
|
|
ReleaseDC( NULL, h ) ;
|
|
}
|
|
|
|
void ShrinkWorkingBitmap( tWorkBMP *a, tWorkBMP *b, WORD bx, WORD by ) {
|
|
BYTE *uy = a->b, *ux, i ;
|
|
WORD x, y, nx, ny = 0 ;
|
|
DWORD df = 3*bx, nf = df*by, j ;
|
|
float k, qx[2], qy[2], q[4], *f = Alloc( nf, float ) ;
|
|
|
|
CreateWorkingBitmap( bx, by, b) ;
|
|
|
|
jFor (nf) f[j]=0;
|
|
j=0;
|
|
|
|
For( y, a->y ) {
|
|
ux=uy;
|
|
uy+=a->l;
|
|
nx=0;
|
|
ny+=by;
|
|
if (ny>a->y) {
|
|
qy[0]=1-(qy[1]=(ny-a->y)/(float)by);
|
|
For (x,a->x) {
|
|
nx+=bx;
|
|
if (nx>a->x) {
|
|
qx[0]=1-(qx[1]=(nx-a->x)/(float)bx);
|
|
iFor (4) q[i]=qx[i&1]*qy[i>>1];
|
|
iFor (3) {
|
|
f[j]+=(*ux)*q[0];
|
|
f[j+3]+=(*ux)*q[1];
|
|
f[j+df]+=(*ux)*q[2];
|
|
f[(j++)+df+3]+=(*(ux++))*q[3];
|
|
}
|
|
} else iFor (3) {
|
|
f[j+i]+=(*ux)*qy[0];
|
|
f[j+df+i]+=(*(ux++))*qy[1];
|
|
}
|
|
if (nx>=a->x) nx-=a->x;
|
|
if (!nx) j+=3;
|
|
}
|
|
} else {
|
|
For (x,a->x) {
|
|
nx+=bx;
|
|
if (nx>a->x) {
|
|
qx[0]=1-(qx[1]=(nx-a->x)/(float)bx);
|
|
iFor (3) {
|
|
f[j]+=(*ux)*qx[0];
|
|
f[(j++)+3]+=(*(ux++))*qx[1];
|
|
}
|
|
}
|
|
else iFor (3) f[j+i]+=*(ux++);
|
|
if (nx>=a->x) nx-=a->x;
|
|
if (!nx) j+=3;
|
|
}
|
|
if (ny<a->y) j-=df;
|
|
}
|
|
if (ny>=a->y) ny-=a->y;
|
|
}
|
|
|
|
nf=0;
|
|
k=bx*by/(float)(a->x*a->y);
|
|
uy=b->b;
|
|
|
|
For (y,by) {
|
|
jFor (df) uy[j]=(unsigned char)(f[nf++]*k+.5);
|
|
uy+=b->l;
|
|
}
|
|
|
|
free (f);
|
|
}
|
|
|
|
TARGET HBITMAP ShrinkBitmap( HBITMAP a, WORD bx, WORD by )
|
|
// creates and returns new bitmap with dimensions of
|
|
// [bx,by] by shrinking bitmap a both [bx,by] must be less or equal
|
|
// than the dims of a, unless the result is nonsense
|
|
{
|
|
tWorkBMP in, out ;
|
|
HBITMAP b=CreateEmptyBitmap( bx, by ) ;
|
|
OpenBitmapForWork( a, &in ) ;
|
|
ShrinkWorkingBitmap( &in, &out, bx, by ) ;
|
|
free( in.b ) ;
|
|
SaveWorkingBitmap( &out, b ) ;
|
|
free( out.b ) ;
|
|
return( b ) ;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HBITMAP ResizeBmp( HBITMAP hBmpSrc, WORD bx, WORD by ) {
|
|
SIZE newSize ;
|
|
newSize.cx = bx;
|
|
newSize.cy = by;
|
|
// taille actuelle
|
|
BITMAP bmpInfo;
|
|
GetObject(hBmpSrc, sizeof(BITMAP), &bmpInfo);
|
|
SIZE oldSize;
|
|
oldSize.cx = bmpInfo.bmWidth;
|
|
oldSize.cy = bmpInfo.bmHeight;
|
|
|
|
// selection source ds un DC
|
|
HDC hdc = GetDC(NULL);
|
|
HDC hDCSrc = CreateCompatibleDC(hdc);
|
|
HBITMAP hOldBmpSrc = (HBITMAP)SelectObject(hDCSrc, hBmpSrc);
|
|
|
|
// création bitmap dest et sélection ds un DC
|
|
HDC hDCDst = CreateCompatibleDC(hdc);
|
|
HBITMAP hBmpDst = CreateCompatibleBitmap(hdc, newSize.cx, newSize.cy);
|
|
HBITMAP hOldBmpDst = (HBITMAP)SelectObject(hDCDst, hBmpDst);
|
|
|
|
// resize
|
|
StretchBlt(hDCDst, 0, 0, newSize.cx, newSize.cy, hDCSrc, 0, 0, oldSize.cx, oldSize.cy, SRCCOPY);
|
|
|
|
// libération ressources
|
|
SelectObject(hDCSrc, hOldBmpSrc);
|
|
SelectObject(hDCDst, hOldBmpDst);
|
|
DeleteDC(hDCSrc);
|
|
DeleteDC(hDCDst);
|
|
ReleaseDC(NULL, hdc);
|
|
return hBmpDst;
|
|
}
|
|
|
|
static void fill_dc(HDC dc, int width, int height, COLORREF color)
|
|
{
|
|
HBRUSH clrBrush = CreateSolidBrush(color);
|
|
HPEN clrPen = CreatePen(PS_SOLID, 0, color);
|
|
|
|
HBRUSH oldBrush;
|
|
HPEN oldPen;
|
|
|
|
oldBrush = SelectObject(dc, clrBrush);
|
|
oldPen = SelectObject(dc, clrPen);
|
|
|
|
Rectangle(dc, 0, 0, width, height);
|
|
|
|
SelectObject(dc, oldBrush);
|
|
SelectObject(dc, oldPen);
|
|
}
|
|
|
|
static BOOL load_wallpaper_bmp(HBITMAP* rawImage, int* style, int* x, int* y)
|
|
{
|
|
LONG lRes;
|
|
HKEY kDesktop;
|
|
DWORD pathLen = MAX_PATH;
|
|
DWORD numBufLen = 10;
|
|
char wpPath[MAX_PATH];
|
|
char wpStyleBuf[10];
|
|
char wpTileBuf[10];
|
|
|
|
int wpStyle = -1;
|
|
int wpTile = -1;
|
|
|
|
// NOTE: In the non-wallpaper case (i.e., load_file_bmp), we load parameters
|
|
// like x, y and style from cfg, but in the wallpaper case we ignore our
|
|
// stored configuration and get that information from the system.
|
|
|
|
// ENHANCE: It's possible to set WallpaperOriginX and WallpaperOriginY to
|
|
// specify an exact position for the start of the wallpaper, but this
|
|
// function doesn't support that yet. I don't think it's possible to set
|
|
// it through the normal UI anyway, you have to hack the registry to do it.
|
|
// For now, we'll never return an (x,y) positioning request to the caller.
|
|
*x = *y = 0;
|
|
|
|
lRes = RegOpenKeyEx(
|
|
HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, KEY_READ, &kDesktop
|
|
);
|
|
if(lRes != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(kDesktop);
|
|
return FALSE; // TODO: Should the error be reported to the user here?
|
|
}
|
|
|
|
lRes = RegQueryValueEx(kDesktop, "Wallpaper", NULL, NULL, (LPBYTE)wpPath, &pathLen);
|
|
if(lRes != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(kDesktop);
|
|
return FALSE; // TODO: Should the error be reported to the user here?
|
|
}
|
|
|
|
lRes = RegQueryValueEx( kDesktop, "WallpaperStyle", NULL, NULL, (LPBYTE)wpStyleBuf, &numBufLen );
|
|
if(lRes == ERROR_SUCCESS)
|
|
wpStyle = atoi(wpStyleBuf);
|
|
|
|
lRes = RegQueryValueEx( kDesktop, "TileWallpaper", NULL, NULL, (LPBYTE)wpTileBuf, &numBufLen );
|
|
if(lRes == ERROR_SUCCESS)
|
|
wpTile = atoi(wpTileBuf);
|
|
|
|
if(wpStyle < 0 && wpStyle > 3)
|
|
wpStyle = 0; // Default to tile.
|
|
else if(wpTile > 0)
|
|
wpStyle = 0; // Force tile.
|
|
else if(wpStyle == 0 && wpTile == 0)
|
|
wpStyle = 1; // For Explorer, wpStyle == wpTile == 0 means center, and
|
|
// it doesn't ever set wpStyle to 1. We call wpStyle == 1
|
|
// center and don't use wpTile, to simplify things after
|
|
// this point.
|
|
|
|
RegCloseKey(kDesktop);
|
|
|
|
if( *rawImage!=NULL ) { DeleteObject( *rawImage ) ; *rawImage=NULL ; }
|
|
*rawImage = LoadImage(
|
|
NULL, wpPath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
|
|
);
|
|
if(*rawImage == 0)
|
|
return FALSE; // TODO: Should the error be reported to the user here?
|
|
|
|
*style = wpStyle;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static BOOL load_file_bmp(HBITMAP* rawImage, int* style, int* x, int* y)
|
|
{
|
|
*x = conf_get_int( conf,CONF_bg_image_abs_x);
|
|
*y = conf_get_int( conf,CONF_bg_image_abs_y );
|
|
*style = conf_get_int( conf,CONF_bg_image_style);
|
|
|
|
if( *rawImage!=NULL ) { DeleteObject( *rawImage ) ; *rawImage=NULL ; }
|
|
*rawImage = LoadImage(
|
|
NULL, conf_get_filename( conf, CONF_bg_image_filename )->path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
|
|
);
|
|
if(*rawImage == 0)
|
|
return FALSE; // TODO: Should the error be reported to the user here?
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
jmp_buf JPEG_bailout;
|
|
int usePalette = 0;
|
|
char *loadError = NULL;
|
|
COLORREF skycolour = RGB(0, 0, 255);
|
|
|
|
HBITMAP CreateHBitmap(int w, int h, LPVOID *lpBits)
|
|
{
|
|
HBITMAP bitmap;
|
|
BITMAPINFOHEADER BIH ;
|
|
int iSize = sizeof(BITMAPINFOHEADER) ;
|
|
memset(&BIH, 0, iSize);
|
|
|
|
// Fill in the header info.
|
|
BIH.biSize = iSize;
|
|
BIH.biWidth = w;
|
|
BIH.biHeight = h;
|
|
BIH.biPlanes = 1;
|
|
BIH.biBitCount = 24;
|
|
BIH.biCompression = BI_RGB;
|
|
HDC hDC = CreateCompatibleDC(NULL);
|
|
bitmap = CreateDIBSection(hDC,
|
|
(BITMAPINFO*)&BIH,
|
|
DIB_RGB_COLORS,
|
|
lpBits,
|
|
NULL,
|
|
0);
|
|
DeleteDC(hDC);
|
|
return bitmap;
|
|
}
|
|
|
|
// LOADJPEGIMAGE -- Load JPEG image into memory
|
|
HBITMAP loadJPEGimage(FILE *input_file, HGLOBAL *LimageBitmap, int *LsizeX, int *LsizeY)
|
|
{
|
|
int i;
|
|
LPBITMAPINFOHEADER bh;
|
|
DWORD bmpsize;
|
|
struct jpeg_decompress_struct cinfo;
|
|
struct jpeg_error_mgr jerr;
|
|
JSAMPARRAY colormap;
|
|
LPBYTE pix;
|
|
int linewid;
|
|
int pixbytes;
|
|
static LPBYTE sl = NULL;
|
|
static HGLOBAL imageBitmap = NULL; // In-memory bitmap
|
|
|
|
sl = NULL;
|
|
imageBitmap = NULL;
|
|
if (setjmp(JPEG_bailout) != 0) {
|
|
/* Since we arrive here via longjmp() from
|
|
parts unknown, we may have allocated
|
|
the line buffer or bitmap prior to bailing
|
|
out. If they've been allocated, release them. */
|
|
|
|
if (sl != NULL) {
|
|
GlobalFree(sl);
|
|
sl = NULL;
|
|
}
|
|
if (imageBitmap != NULL) {
|
|
GlobalFree(imageBitmap);
|
|
imageBitmap = NULL;
|
|
}
|
|
return NULL;
|
|
}
|
|
cinfo.err = jpeg_std_error(&jerr);
|
|
jpeg_create_decompress(&cinfo);
|
|
jpeg_stdio_src(&cinfo, input_file);
|
|
jpeg_read_header(&cinfo, TRUE);
|
|
cinfo.desired_number_of_colors = 254;
|
|
cinfo.quantize_colors = usePalette;
|
|
jpeg_start_decompress(&cinfo);
|
|
|
|
pixbytes = (usePalette ? 1 : 3);
|
|
sl = GlobalAlloc(GMEM_FIXED, cinfo.output_width * pixbytes);
|
|
if (sl == NULL) {
|
|
loadError = "Cannot allocate JPEG decoder row buffer";
|
|
return NULL;
|
|
}
|
|
|
|
linewid = ((((cinfo.output_width * pixbytes) + (sizeof(LONG) - 1)) / sizeof(LONG)) * sizeof(LONG));
|
|
bmpsize = sizeof(BITMAPINFOHEADER) +
|
|
(usePalette ? (256 * sizeof(RGBQUAD)) : 0) +
|
|
(linewid * cinfo.output_height);
|
|
|
|
imageBitmap = GlobalAlloc(GMEM_FIXED, bmpsize);
|
|
if (imageBitmap == NULL) {
|
|
loadError = "Cannot allocate bitmap for decoded JPEG image";
|
|
GlobalFree(sl);
|
|
return NULL;
|
|
}
|
|
|
|
// Plug in header fields with information from cinfo
|
|
|
|
bh = (LPBITMAPINFOHEADER) imageBitmap;
|
|
pix = ((LPBYTE) imageBitmap) + sizeof(BITMAPINFOHEADER) +
|
|
(usePalette ? (256 * sizeof(RGBQUAD)) : 0);
|
|
pix = pix + 0 ; // Pour eviter un warning de compilation
|
|
bh->biSize = sizeof(BITMAPINFOHEADER);
|
|
bh->biWidth = cinfo.output_width;
|
|
bh->biHeight = cinfo.output_height;
|
|
bh->biPlanes = 1;
|
|
bh->biBitCount = usePalette ? 8 : 24;
|
|
bh->biCompression = BI_RGB;
|
|
bh->biSizeImage = 0;
|
|
bh->biXPelsPerMeter = bh->biYPelsPerMeter = 2835;
|
|
bh->biClrUsed = 0;
|
|
bh->biClrImportant = 0;
|
|
|
|
/* Construct the palette from the colour map optimised
|
|
for the JPEG file. */
|
|
|
|
if (usePalette) {
|
|
colormap = cinfo.colormap;
|
|
for (i = 0; i < cinfo.actual_number_of_colors; i++) {
|
|
if (cinfo.num_components == 1) {
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[i])->rgbRed =
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[i])->rgbGreen =
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[i])->rgbBlue = GETJSAMPLE(colormap[0][i]);
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[i])->rgbReserved = 0;
|
|
} else {
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[i])->rgbRed = GETJSAMPLE(colormap[0][i]);
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[i])->rgbGreen = GETJSAMPLE(colormap[1][i]);
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[i])->rgbBlue = GETJSAMPLE(colormap[2][i]);
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[i])->rgbReserved = 0;
|
|
}
|
|
}
|
|
|
|
/* Plug black and our text colour in the last two slots
|
|
of the palette so we canbe sure they're available. */
|
|
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[254])->rgbRed =
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[254])->rgbGreen =
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[254])->rgbBlue =
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[254])->rgbReserved = 0;
|
|
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[255])->rgbRed = GetRValue(skycolour);
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[255])->rgbGreen = GetGValue(skycolour);
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[255])->rgbBlue = GetBValue(skycolour);
|
|
((LPRGBQUAD) &((LPBITMAPINFO) bh)->bmiColors[255])->rgbReserved = 0;
|
|
}
|
|
|
|
// Return scan lines and transfer to the pixel array
|
|
|
|
BYTE *pDst = NULL;
|
|
HBITMAP hBitmap = CreateHBitmap(bh->biWidth, bh->biHeight, (void**)&pDst);
|
|
int nStorageWidth = ((bh->biWidth * 24 + 31) & ~31) >> 3; //dword alignment
|
|
JSAMPARRAY ppDst = &pDst;
|
|
/*
|
|
LPBYTE px = pix + (linewid * (bh->biHeight - 1));
|
|
for (i = 0; i < (int) cinfo.output_height; i++) {
|
|
unsigned char *slp[1] = { sl };
|
|
jpeg_read_scanlines(&cinfo, slp, 1);
|
|
if (usePalette) {
|
|
memcpy(px, sl, cinfo.output_width);
|
|
} else {
|
|
int j, k;
|
|
|
|
if (cinfo.num_components == 3) {
|
|
for (j = k = 0; j < (int) cinfo.output_width; j++, k += 3) {
|
|
px[k] = sl[k + 2];
|
|
px[k + 1] = sl[k + 1];
|
|
px[k + 2] = sl[k];
|
|
}
|
|
} else {
|
|
for (j = k = 0; j < (int) cinfo.output_width; j++, k += 3) {
|
|
px[k] = sl[j];
|
|
px[k + 1] = sl[j];
|
|
px[k + 2] = sl[j];
|
|
}
|
|
}
|
|
}
|
|
px -= linewid;
|
|
}
|
|
*/
|
|
pDst = pDst + (cinfo.output_height-1)*nStorageWidth ;
|
|
while (cinfo.output_scanline < cinfo.output_height) {
|
|
jpeg_read_scanlines (&cinfo, ppDst, 1);
|
|
|
|
if(cinfo.out_color_components==3) {
|
|
//swap R & B
|
|
BYTE* p = pDst;
|
|
int i ;
|
|
for( i=0;i<bh->biWidth;i++) {
|
|
BYTE r = p[0];
|
|
p[0] = p[2];
|
|
p[2] = r;
|
|
p += 3;
|
|
}
|
|
}
|
|
|
|
//pDst += nStorageWidth;
|
|
pDst -= nStorageWidth;
|
|
}
|
|
|
|
GlobalFree(sl);
|
|
jpeg_finish_decompress(&cinfo);
|
|
jpeg_destroy_decompress(&cinfo);
|
|
|
|
*LsizeX = (int) bh->biWidth;
|
|
*LsizeY = (int) bh->biHeight;
|
|
*LimageBitmap = imageBitmap;
|
|
return hBitmap;
|
|
}
|
|
|
|
|
|
static BOOL load_file_jpeg(HBITMAP* rawImage, int* style, int* x, int* y) {
|
|
*x = conf_get_int( conf, CONF_bg_image_abs_x );
|
|
*y = conf_get_int( conf, CONF_bg_image_abs_y );
|
|
*style = conf_get_int( conf, CONF_bg_image_style );
|
|
int res=TRUE, LsizeX, LsizeY ;
|
|
FILE *fp ;
|
|
HGLOBAL LimageBitmap = NULL ;
|
|
|
|
|
|
if( ( fp=fopen( conf_get_filename( conf,CONF_bg_image_filename)->path, "rb" ) ) == NULL ) return FALSE ;
|
|
|
|
if( *rawImage!=NULL ) { DeleteObject( *rawImage ) ; *rawImage=NULL ; }
|
|
*rawImage = loadJPEGimage(fp, &LimageBitmap,&LsizeX, &LsizeY) ;
|
|
if( rawImage == NULL ) res =FALSE ;
|
|
fclose( fp ) ;
|
|
|
|
GlobalFree(LimageBitmap);
|
|
|
|
return res;
|
|
}
|
|
|
|
static HBITMAP CreateDIBSectionWithFileMapping(HDC dc, int width, int height, HANDLE fmap)
|
|
{
|
|
BITMAPINFOHEADER BMI;
|
|
|
|
BMI.biSize = sizeof(BITMAPINFOHEADER);
|
|
BMI.biWidth = width;
|
|
BMI.biHeight = height;
|
|
BMI.biPlanes = 1;
|
|
BMI.biBitCount = 32;
|
|
BMI.biCompression = BI_RGB;
|
|
BMI.biSizeImage = 0;
|
|
BMI.biXPelsPerMeter = 0;
|
|
BMI.biYPelsPerMeter = 0;
|
|
BMI.biClrUsed = 0;
|
|
BMI.biClrImportant = 0;
|
|
|
|
return(CreateDIBSection(dc, (BITMAPINFO *)&BMI, DIB_RGB_COLORS, 0, fmap, 0));
|
|
}
|
|
|
|
|
|
/***********SCREEN CAPTURE*******************/
|
|
|
|
/******************************/
|
|
|
|
void init_dc_blend(void) {
|
|
//HMODULE * msimg32_dll = LoadLibrary("msimg32.dll");
|
|
HMODULE msimg32_dll = LoadLibrary("msimg32.dll");
|
|
|
|
if(msimg32_dll)
|
|
pAlphaBlend = GetProcAddress(msimg32_dll, "AlphaBlend");
|
|
|
|
if(pAlphaBlend) {
|
|
HDC hdc = GetDC(MainHwnd);
|
|
|
|
// Create one pixel size bitmap for use in color_blend.
|
|
if( colorinpixeldc !=NULL ) { DeleteDC(colorinpixeldc ) ; } colorinpixeldc = CreateCompatibleDC(hdc);
|
|
if( colorinpixelbm!=NULL ) { DeleteObject(colorinpixelbm) ; } colorinpixelbm = CreateCompatibleBitmap(hdc, 1, 1);
|
|
SelectObject(colorinpixeldc, colorinpixelbm);
|
|
colorinpixel = 0;
|
|
SetPixelV(colorinpixeldc, 0, 0, colorinpixel);
|
|
|
|
ReleaseDC(MainHwnd, hdc);
|
|
}
|
|
}
|
|
|
|
void color_blend(
|
|
HDC destDc, int x, int y, int width, int height,
|
|
COLORREF alphacolor, int opacity)
|
|
{
|
|
if(pAlphaBlend) {
|
|
// Fast alpha blending for Win98&2000 and newer...
|
|
BLENDFUNCTION blender;
|
|
|
|
// Create one pixel size bitmap for use in color_blend.
|
|
if(colorinpixel != alphacolor)
|
|
{
|
|
colorinpixel = alphacolor;
|
|
SetPixelV(colorinpixeldc, 0, 0, alphacolor);
|
|
}
|
|
|
|
blender.BlendOp = AC_SRC_OVER;
|
|
blender.BlendFlags = 0;
|
|
blender.SourceConstantAlpha = (0xff * opacity) / 100;
|
|
blender.AlphaFormat = 0;
|
|
|
|
(*pAlphaBlend)(destDc, x, y, width, height, colorinpixeldc, 0, 0, 1, 1, blender);
|
|
}
|
|
else
|
|
{
|
|
// Slow alpha blending for Win95&NT...
|
|
// Note: Only tested with WinXP, should work on 95/NT.. probably.
|
|
int i, alphacolorR, alphacolorG, alphacolorB, bk_opacity;
|
|
HBITMAP tmpbm;
|
|
HDC tmpdc;
|
|
static HANDLE fmap;
|
|
static int fmap_size;
|
|
static unsigned char * pRGB;
|
|
|
|
if(fmap_size < width * height * 4)
|
|
{
|
|
if(fmap) {
|
|
UnmapViewOfFile(pRGB);
|
|
CloseHandle(fmap);
|
|
}
|
|
fmap_size = width * height * 4;
|
|
fmap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, fmap_size, NULL);
|
|
pRGB = MapViewOfFile(fmap, FILE_MAP_ALL_ACCESS, 0, 0, fmap_size);
|
|
}
|
|
|
|
// Create DIBSection so we get pixels easily.
|
|
tmpdc = CreateCompatibleDC(destDc);
|
|
tmpbm = CreateDIBSectionWithFileMapping(destDc, width, height, fmap);
|
|
SelectObject(tmpdc, tmpbm);
|
|
|
|
// Copy bitmap to temporary bitmap for easy pixel access.
|
|
BitBlt(tmpdc, 0, 0, width, height, destDc, x, y, SRCCOPY);
|
|
|
|
// Moved stuff out from the loop
|
|
alphacolorR = GetRValue(alphacolor) * opacity;
|
|
alphacolorG = GetGValue(alphacolor) * opacity;
|
|
alphacolorB = GetBValue(alphacolor) * opacity;
|
|
bk_opacity = 100 - opacity;
|
|
|
|
for(i=0; i<width*height*4; i+=4)
|
|
{
|
|
pRGB[i + 0] = (pRGB[i + 0] * bk_opacity + alphacolorB) / 100;
|
|
pRGB[i + 1] = (pRGB[i + 1] * bk_opacity + alphacolorG) / 100;
|
|
pRGB[i + 2] = (pRGB[i + 2] * bk_opacity + alphacolorR) / 100;
|
|
}
|
|
|
|
// Copy temporary bitmap back to original
|
|
BitBlt(destDc, x, y, width, height, tmpdc, 0, 0, SRCCOPY);
|
|
|
|
DeleteObject(tmpbm);
|
|
DeleteDC(tmpdc);
|
|
}
|
|
}
|
|
|
|
static void color_opacity_gradient( HDC destDc, int x, int y, int width, int height, COLORREF alphacolor, int style ) {
|
|
int i, alphacolorR, alphacolorG, alphacolorB, bk_opacity, opacity, h, w ;
|
|
double l ;
|
|
HBITMAP tmpbm;
|
|
HDC tmpdc;
|
|
static HANDLE fmap;
|
|
static int fmap_size;
|
|
static unsigned char * pRGB;
|
|
int OpacityMin = 0, OpacityMax = 100 ;
|
|
|
|
char buf[256] = "" ;
|
|
if( GetSessionField( conf_get_str(conf,CONF_sessionname), conf_get_str(conf,CONF_folder), "BgOpacityRange", buf ) ) {
|
|
sscanf( buf, "%d-%d", &OpacityMin, &OpacityMax ) ;
|
|
if( OpacityMin == OpacityMax ) { OpacityMin = 0 ; OpacityMax = 100 ; }
|
|
}
|
|
|
|
if(fmap_size < width * height * 4) {
|
|
if(fmap) { UnmapViewOfFile(pRGB) ; CloseHandle(fmap) ; }
|
|
fmap_size = width * height * 4;
|
|
fmap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, fmap_size, NULL);
|
|
pRGB = MapViewOfFile(fmap, FILE_MAP_ALL_ACCESS, 0, 0, fmap_size);
|
|
}
|
|
|
|
// Create DIBSection so we get pixels easily.
|
|
tmpdc = CreateCompatibleDC(destDc);
|
|
tmpbm = CreateDIBSectionWithFileMapping(destDc, width, height, fmap);
|
|
SelectObject(tmpdc, tmpbm);
|
|
|
|
// Copy bitmap to temporary bitmap for easy pixel access.
|
|
BitBlt(tmpdc, 0, 0, width, height, destDc, x, y, SRCCOPY);
|
|
|
|
opacity = 0 ; bk_opacity = 100 ; alphacolorR = 0 ; alphacolorG = 0 ; alphacolorB = 0 ;
|
|
w = 0 ; h = 0 ;
|
|
|
|
for(i=0; i<width*height*4; i+=4) {
|
|
|
|
switch( style ) {
|
|
case 2: // De bas en haut
|
|
if( (i%(4*width)) == 0 ) {
|
|
h++ ;
|
|
opacity = OpacityMin + 1.0*( OpacityMax-OpacityMin ) * (1.0*h)/(1.0*height) ;
|
|
opacity = 100 - opacity ;
|
|
}
|
|
break ;
|
|
case 3: // De gauche a droite
|
|
w++ ; if( w >= width ) { w = 0 ; }
|
|
opacity = OpacityMin + 1.0*( OpacityMax-OpacityMin ) * (1.0*w)/(1.0*width) ;
|
|
break ;
|
|
case 4: // De droite a gauche
|
|
w++ ; if( w >= width ) { w = 0 ; }
|
|
opacity = OpacityMin + 1.0*( OpacityMax-OpacityMin ) * (1.0*w)/(1.0*width) ;
|
|
opacity = 100 - opacity ;
|
|
break ;
|
|
case 5: // Du centre vers l'exterieur
|
|
if( (i%(4*width)) == 0 ) { h++ ; }
|
|
w++ ; if( w >= width ) { w = 0 ; }
|
|
l = sqrt( pow(1.0*width/2.0-w,2.0)+pow(1.0*height/2.0-h,2.0) ) /
|
|
sqrt( pow(1.0*width/2.0,2.0)+pow(1.0*height/2.0,2.0) );
|
|
opacity = OpacityMin + 1.0*( OpacityMax-OpacityMin ) * l ;
|
|
break ;
|
|
case 6: // De l'exterieur vers le centre
|
|
if( (i%(4*width)) == 0 ) { h++ ; }
|
|
w++ ; if( w >= width ) { w = 0 ; }
|
|
l = sqrt( pow(1.0*width/2.0-w,2.0)+pow(1.0*height/2.0-h,2.0) ) /
|
|
sqrt( pow(1.0*width/2.0,2.0)+pow(1.0*height/2.0,2.0) );
|
|
opacity = OpacityMin + 1.0*( OpacityMax-OpacityMin ) * l ;
|
|
opacity = 100 - opacity ;
|
|
break ;
|
|
case 7:
|
|
if( (i%(4*width)) == 0 ) { h++ ; }
|
|
w++ ; if( w >= width ) { w = 0 ; }
|
|
l = sqrt( pow(1.0*w,2.0)+pow(1.0*h,2.0) )/sqrt( pow(1.0*width,2.0)+pow(1.0*height,2.0) ) ;
|
|
opacity = OpacityMin + 1.0*( OpacityMax-OpacityMin ) * l ;
|
|
break ;
|
|
case 8:
|
|
if( (i%(4*width)) == 0 ) { h++ ; }
|
|
w++ ; if( w >= width ) { w = 0 ; }
|
|
l = sqrt( pow(1.0*w,2.0)+pow(1.0*h,2.0) )/sqrt( pow(1.0*width,2.0)+pow(1.0*height,2.0) ) ;
|
|
opacity = OpacityMin + 1.0*( OpacityMax-OpacityMin ) * l ;
|
|
opacity = 100 - opacity ;
|
|
break ;
|
|
case 9:
|
|
if( (i%(4*width)) == 0 ) { h++ ; }
|
|
w++ ; if( w >= width ) { w = 0 ; }
|
|
l = sqrt( pow(1.0*(width-w),2.0)+pow(1.0*h,2.0) )/sqrt( pow(1.0*width,2.0)+pow(1.0*height,2.0) ) ;
|
|
opacity = OpacityMin + 1.0*( OpacityMax-OpacityMin ) * l ;
|
|
break ;
|
|
case 10:
|
|
if( (i%(4*width)) == 0 ) { h++ ; }
|
|
w++ ; if( w >= width ) { w = 0 ; }
|
|
l = sqrt( pow(1.0*(width-w),2.0)+pow(1.0*h,2.0) )/sqrt( pow(1.0*width,2.0)+pow(1.0*height,2.0) ) ;
|
|
opacity = OpacityMin + 1.0*( OpacityMax-OpacityMin ) * l ;
|
|
opacity = 100 - opacity ;
|
|
break ;
|
|
default: // De haut en bas
|
|
if( (i%(4*width)) == 0 ) {
|
|
h++ ;
|
|
opacity = OpacityMin + 1.0*( OpacityMax-OpacityMin ) * (1.0*h)/(1.0*height) ;
|
|
}
|
|
break ;
|
|
}
|
|
if( opacity < 0 ) opacity = 0 ;
|
|
if( opacity > 100 ) opacity = 100 ;
|
|
|
|
alphacolorR = GetRValue(alphacolor) * opacity;
|
|
alphacolorG = GetGValue(alphacolor) * opacity;
|
|
alphacolorB = GetBValue(alphacolor) * opacity;
|
|
bk_opacity = 100 - opacity ;
|
|
|
|
pRGB[i + 0] = (pRGB[i + 0] * bk_opacity + alphacolorB) / 100;
|
|
pRGB[i + 1] = (pRGB[i + 1] * bk_opacity + alphacolorG) / 100;
|
|
pRGB[i + 2] = (pRGB[i + 2] * bk_opacity + alphacolorR) / 100;
|
|
}
|
|
|
|
// Copy temporary bitmap back to original
|
|
BitBlt(destDc, x, y, width, height, tmpdc, 0, 0, SRCCOPY);
|
|
|
|
DeleteObject(tmpbm);
|
|
DeleteDC(tmpdc);
|
|
}
|
|
|
|
void CreateBlankBitmap( HBITMAP * rawImage, const int width, const int height ) {
|
|
HDC dc= CreateCompatibleDC(NULL);
|
|
BITMAPINFO bi;
|
|
ZeroMemory( &bi.bmiHeader, sizeof(BITMAPINFOHEADER) );
|
|
bi.bmiHeader.biWidth=width; // Set size you need
|
|
bi.bmiHeader.biHeight=height; // Set size you need
|
|
bi.bmiHeader.biPlanes=1;
|
|
bi.bmiHeader.biBitCount=24; // Can be 8, 16, 32 bpp or
|
|
bi.bmiHeader.biSizeImage=0;
|
|
bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
|
|
bi.bmiHeader.biClrUsed= 0;
|
|
bi.bmiHeader.biClrImportant= 0;
|
|
VOID *pvBits;
|
|
|
|
if( *rawImage!=NULL ) { DeleteObject( *rawImage ) ; *rawImage=NULL ; }
|
|
*rawImage = CreateDIBSection( dc,&bi,DIB_RGB_COLORS,&pvBits,NULL,0 );
|
|
ReleaseDC(NULL, dc) ;
|
|
|
|
HDC hDC = GetDC(MainHwnd);
|
|
HDC hDCDst = CreateCompatibleDC(hDC); // memory device context for dest bitmap
|
|
ReleaseDC(NULL, hDC);
|
|
|
|
// hdcMem contains your rendered particle
|
|
|
|
HBRUSH hBrush = CreateSolidBrush(RGB(255,0,0));
|
|
// Paints the rectangular band with the brush
|
|
RECT Rect = {0, 0, width-1, height-1};
|
|
FillRect(hDCDst, &Rect, hBrush);
|
|
// Deletes the brush
|
|
DeleteObject(hBrush);
|
|
|
|
HGDIOBJ holdDIBDst = SelectObject(hDCDst, *rawImage);
|
|
|
|
// transfer the image to your DIB bitmap
|
|
BitBlt(hDCDst, 0, 0 ,width, height, hDC, 0, 0, SRCCOPY);
|
|
|
|
// clean up
|
|
SelectObject(hDCDst, holdDIBDst);
|
|
DeleteDC(hDCDst);
|
|
}
|
|
|
|
BOOL load_bg_bmp()
|
|
{
|
|
HBITMAP rawImage = NULL;
|
|
BITMAP rawImageInfo;
|
|
HDC hdcPrimary;
|
|
HDC bmpdc;
|
|
int deskWidth, deskHeight, clientWidth, clientHeight;
|
|
int x, y;
|
|
int style;
|
|
|
|
//COLORREF backgroundcolor = colours[258]; // Default Background
|
|
COLORREF backgroundcolor = return_colours258() ;
|
|
COLORREF alphacolor = backgroundcolor;
|
|
|
|
// Start off assuming this is true.
|
|
bBgRelToTerm = conf_get_int( conf,CONF_bg_image_abs_fixed);
|
|
|
|
RECT clientRect;
|
|
GetWindowRect( MainHwnd, &clientRect ) ;
|
|
clientWidth = clientRect.right-clientRect.left+1 ;
|
|
clientHeight = clientRect.bottom-clientRect.top+1 ;
|
|
|
|
switch( conf_get_int( conf,CONF_bg_type) )
|
|
{
|
|
// Solid
|
|
case 0:
|
|
// No bitmap file to load. We'll handle this case below.
|
|
break;
|
|
|
|
// Wallpaper
|
|
case 1:
|
|
backgroundcolor = GetSysColor(COLOR_BACKGROUND);
|
|
bBgRelToTerm = FALSE; // Wallpaper is never positioned relative to term.
|
|
if(!load_wallpaper_bmp(&rawImage, &style, &x, &y))
|
|
rawImage = NULL; // Make sure rawImage is still NULL.
|
|
break;
|
|
|
|
// Image
|
|
case 2:
|
|
{
|
|
backgroundcolor = GetSysColor(COLOR_BACKGROUND) ;
|
|
if( conf_get_filename(conf,CONF_bg_image_filename)->path[0] == '#' ) {
|
|
int r=0,g=0,b=0;
|
|
sscanf( conf_get_filename(conf,CONF_bg_image_filename)->path, "#%02X%02X%02X", &r, &g, &b ) ;
|
|
backgroundcolor = RGB( r, g, b ) ;
|
|
BYTE *pDst = NULL;
|
|
rawImage = CreateHBitmap(10, 10, (void**)&pDst);
|
|
style = 4 ;
|
|
}
|
|
else if( !stricmp( conf_get_filename(conf,CONF_bg_image_filename)->path+strlen(conf_get_filename(conf,CONF_bg_image_filename)->path)-4, ".jpg" ) ) {
|
|
if(!load_file_jpeg(&rawImage, &style, &x, &y))
|
|
rawImage = NULL; // Make sure rawImage is still NULL.
|
|
}
|
|
else if( !stricmp( conf_get_filename(conf,CONF_bg_image_filename)->path+strlen(conf_get_filename(conf,CONF_bg_image_filename)->path)-5, ".jpeg" ) ) {
|
|
if(!load_file_jpeg(&rawImage, &style, &x, &y))
|
|
rawImage = NULL; // Make sure rawImage is still NULL.
|
|
}
|
|
else
|
|
if(!load_file_bmp(&rawImage, &style, &x, &y))
|
|
rawImage = NULL; // Make sure rawImage is still NULL.
|
|
break;
|
|
}
|
|
}
|
|
|
|
hdcPrimary = GetDC(MainHwnd);
|
|
deskWidth = GetDeviceCaps(hdcPrimary, HORZRES);
|
|
deskHeight = GetDeviceCaps(hdcPrimary, VERTRES);
|
|
|
|
|
|
// Securite pour ne pas depacer les limites de l'ecran principal
|
|
if( (bBgRelToTerm == 0)
|
|
&&((clientRect.right>deskWidth)||(clientRect.bottom>deskHeight)) ) {
|
|
//DeleteObject(rawImage); rawImage = NULL ;
|
|
bBgRelToTerm = 1 ;
|
|
}
|
|
|
|
if(rawImage == NULL)
|
|
{
|
|
// Create a solid bitmap. We'll get here in two cases: either the user
|
|
// selected the Solid background option, or the attempt to do something
|
|
// fancier (use the system wallpaper or an image file) failed.
|
|
/*
|
|
if( backgrounddc!=NULL ) DeleteDC(backgrounddc) ; backgrounddc = CreateCompatibleDC(hdcPrimary);
|
|
if( backgroundbm!=NULL ) DeleteObject(backgroundbm); backgroundbm
|
|
= CreateCompatibleBitmap(hdcPrimary, deskWidth, deskHeight);
|
|
SelectObject(backgrounddc, backgroundbm);
|
|
*/
|
|
// Do not create anything, use default 'no background'-code instead.
|
|
}
|
|
else
|
|
{
|
|
// We've managed to load a good image. Now, we need to manipulate it to
|
|
// the right size, location, etc.
|
|
|
|
// Find the width and height of the image we just loaded.
|
|
GetObject(rawImage, sizeof(rawImageInfo), &rawImageInfo);
|
|
|
|
// Create a temporary DC to wrap the raw image.
|
|
bmpdc = CreateCompatibleDC(hdcPrimary);
|
|
SelectObject(bmpdc, rawImage);
|
|
|
|
// Create a memory DC that has a new bitmap of the appropriate final
|
|
// image size.
|
|
if( textdc!=NULL ) { DeleteDC(textdc) ; } textdc = CreateCompatibleDC(hdcPrimary);
|
|
if( textbm!= NULL ) { DeleteObject(textbm) ; } textbm = CreateCompatibleBitmap(hdcPrimary, deskWidth, deskHeight);
|
|
SelectObject(textdc, textbm);
|
|
|
|
if( backgrounddc!=NULL ) { DeleteDC(backgrounddc) ; } backgrounddc = CreateCompatibleDC(hdcPrimary);
|
|
if( backgroundbm!=NULL ) { DeleteObject(backgroundbm) ; } backgroundbm = CreateCompatibleBitmap(hdcPrimary, deskWidth, deskHeight) ;
|
|
SelectObject(backgrounddc, backgroundbm);
|
|
|
|
switch(style)
|
|
{
|
|
case 0: { // Tile
|
|
for(y = 0; y < deskHeight; y += rawImageInfo.bmHeight)
|
|
{
|
|
for(x = 0; x < deskWidth; x += rawImageInfo.bmWidth)
|
|
{
|
|
BitBlt(
|
|
backgrounddc,
|
|
x, y, rawImageInfo.bmWidth, rawImageInfo.bmHeight,
|
|
bmpdc, 0, 0, SRCCOPY
|
|
);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 1: // Center
|
|
|
|
// Calculate x & y, ignoring values they may already have, then drop
|
|
// down to the (X,Y) placement case below.
|
|
|
|
x = (deskWidth - rawImageInfo.bmWidth) / 2;
|
|
y = (deskHeight - rawImageInfo.bmHeight) / 2;
|
|
|
|
case 3: { // Absolute Place at given (X,Y)
|
|
// Start out with a background color fill.
|
|
fill_dc(backgrounddc, deskWidth, deskHeight, backgroundcolor);
|
|
|
|
BitBlt(
|
|
backgrounddc,
|
|
x, y, rawImageInfo.bmWidth, rawImageInfo.bmHeight,
|
|
bmpdc, 0, 0, SRCCOPY
|
|
);
|
|
break;
|
|
}
|
|
|
|
case 2: // Stretch
|
|
StretchBlt(
|
|
backgrounddc, 0, 0, deskWidth, deskHeight,
|
|
bmpdc, 0, 0, rawImageInfo.bmWidth, rawImageInfo.bmHeight,
|
|
SRCCOPY
|
|
);
|
|
|
|
break;
|
|
|
|
case 4: // blank background
|
|
fill_dc(backgrounddc, deskWidth, deskHeight, backgroundcolor) ;
|
|
break ;
|
|
|
|
case 5: // Stretch a la taille de la fenetre
|
|
{
|
|
if( (ShrinkBitmapEnable)&&(clientWidth<rawImageInfo.bmWidth)&&(clientHeight<rawImageInfo.bmHeight) ) {
|
|
HBITMAP newhbmpBMP ;
|
|
if( (newhbmpBMP = ShrinkBitmap( rawImage,clientWidth,clientHeight)) != NULL ) {
|
|
//if( (newhbmpBMP = ResizeBmp( rawImage,clientWidth,clientHeight)) != NULL ) {
|
|
DeleteDC(bmpdc) ;
|
|
bmpdc = CreateCompatibleDC(0) ;
|
|
DeleteDC(backgrounddc); backgrounddc = GetDC(MainHwnd);
|
|
SelectObject(bmpdc, newhbmpBMP ) ;
|
|
BitBlt(backgrounddc, 0, 0,clientWidth,clientHeight, bmpdc, 0, 0, SRCCOPY ) ;
|
|
DeleteObject(newhbmpBMP);
|
|
}
|
|
else
|
|
StretchBlt( backgrounddc,0,0,clientWidth,clientHeight,bmpdc,0,0,rawImageInfo.bmWidth,rawImageInfo.bmHeight,SRCCOPY);
|
|
}
|
|
else
|
|
StretchBlt( backgrounddc,0,0,clientWidth,clientHeight,bmpdc,0,0,rawImageInfo.bmWidth,rawImageInfo.bmHeight,SRCCOPY);
|
|
}
|
|
break ;
|
|
}
|
|
|
|
// Create a version of the background DC with opacity already applied
|
|
// for fast screen fill in areas with no text.
|
|
|
|
if( backgroundblenddc!=NULL ) { DeleteDC(backgroundblenddc) ; } backgroundblenddc = CreateCompatibleDC(hdcPrimary);
|
|
if( backgroundblendbm!=NULL ) { DeleteObject(backgroundblendbm) ; } backgroundblendbm = CreateCompatibleBitmap( hdcPrimary, deskWidth, deskHeight );
|
|
|
|
DeleteObject(rawImage);
|
|
DeleteDC(bmpdc);
|
|
|
|
SelectObject(backgroundblenddc, backgroundblendbm);
|
|
BitBlt(
|
|
backgroundblenddc, 0, 0, deskWidth, deskHeight,
|
|
backgrounddc, 0, 0, SRCCOPY
|
|
);
|
|
|
|
if( conf_get_int(conf,CONF_bg_opacity) >= 0 )
|
|
{ color_blend( backgroundblenddc, 0, 0, deskWidth, deskHeight, alphacolor, conf_get_int(conf,CONF_bg_opacity)); }
|
|
else
|
|
{
|
|
if( bBgRelToTerm == 1 ) {
|
|
deskWidth = clientWidth ;
|
|
deskHeight = clientHeight ;
|
|
}
|
|
|
|
color_opacity_gradient( backgroundblenddc, 0, 0, deskWidth, deskHeight, alphacolor, -conf_get_int(conf,CONF_bg_opacity) );
|
|
}
|
|
}
|
|
|
|
ReleaseDC(MainHwnd, hdcPrimary);
|
|
|
|
//DeleteDC(hdcPrimary);
|
|
return TRUE;
|
|
}
|
|
|
|
void paint_term_edges(Terminal*term, HDC hdc, LONG paint_left, LONG paint_top, LONG paint_right, LONG paint_bottom)
|
|
{
|
|
if(backgrounddc == 0)
|
|
load_bg_bmp();
|
|
|
|
if(backgrounddc)
|
|
{
|
|
LONG topLeftX = paint_left;
|
|
LONG topLeftY = paint_top;
|
|
LONG width = (paint_right - paint_left);
|
|
LONG height = (paint_bottom - paint_top);
|
|
HDC srcdc = backgroundblenddc;
|
|
POINT srcTopLeft;
|
|
RECT size_now;
|
|
srcTopLeft.x = topLeftX;
|
|
srcTopLeft.y = topLeftY;
|
|
|
|
if(!bBgRelToTerm)
|
|
ClientToScreen(MainHwnd, &srcTopLeft);
|
|
|
|
if(!srcdc)
|
|
srcdc = backgrounddc;
|
|
|
|
if(resizing)
|
|
{
|
|
GetClientRect(MainHwnd, &size_now);
|
|
if(size_now.bottom > size_before.bottom || size_now.right > size_before.right)
|
|
{
|
|
// Draw on full area on resize.
|
|
BitBlt(hdc, topLeftX, topLeftY, width, height, srcdc, srcTopLeft.x, srcTopLeft.y, SRCCOPY);
|
|
|
|
return;
|
|
}
|
|
}
|
|
//debug_log("1: %d %d %d %d\n",size_before.top,size_before.bottom,size_before.left,size_before.right) ;
|
|
//debug_log("2: %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %d\n",topLeftX,topLeftY,width,height,srcTopLeft.x,srcTopLeft.y,size_now.top,size_now.bottom,size_now.left,size_now.right,resizing) ;
|
|
|
|
// Draw top edge
|
|
BitBlt(
|
|
hdc, topLeftX, topLeftY, width, return_offset_height(),
|
|
srcdc, srcTopLeft.x, srcTopLeft.y, SRCCOPY
|
|
);
|
|
// Draw left edge
|
|
BitBlt(
|
|
hdc, topLeftX, topLeftY+1, return_offset_width(), height-2,
|
|
srcdc, srcTopLeft.x, srcTopLeft.y+1, SRCCOPY
|
|
);
|
|
// Draw right edge (extra width for clean resizing)
|
|
BitBlt(
|
|
hdc, topLeftX+width-1, topLeftY+1, return_offset_width(), height-2,
|
|
srcdc, srcTopLeft.x+width-1, srcTopLeft.y+1, SRCCOPY
|
|
);
|
|
// Draw bottom edge (extra height for clean resizing)
|
|
BitBlt(
|
|
hdc, topLeftX, topLeftY+height-1, width, return_offset_height(),
|
|
srcdc, srcTopLeft.x, srcTopLeft.y+height-1, SRCCOPY
|
|
);
|
|
}
|
|
else
|
|
{
|
|
HBRUSH bgbrush, oldbrush;
|
|
HPEN edge, oldpen;
|
|
//COLORREF backgroundcolor = colours[258];
|
|
COLORREF backgroundcolor = return_colours258() ;
|
|
|
|
bgbrush = CreateSolidBrush(backgroundcolor);
|
|
edge = CreatePen(PS_SOLID, 0, backgroundcolor);
|
|
|
|
oldbrush = SelectObject(hdc, bgbrush);
|
|
oldpen = SelectObject(hdc, edge);
|
|
|
|
/*
|
|
* Jordan Russell reports that this apparently
|
|
* ineffectual IntersectClipRect() call masks a
|
|
* Windows NT/2K bug causing strange display
|
|
* problems when the PuTTY window is taller than
|
|
* the primary monitor. It seems harmless enough...
|
|
*/
|
|
IntersectClipRect(hdc,
|
|
paint_left, paint_top,
|
|
paint_right, paint_bottom);
|
|
|
|
ExcludeClipRect(hdc,
|
|
return_offset_width(), return_offset_height(),
|
|
return_offset_width()+return_font_width()*(term->cols),
|
|
return_offset_height()+return_font_height()*(term->rows));
|
|
|
|
//debug_log("3: %d %d %d %d %d %d %d\n",resizing,paint_left, paint_top, paint_right, paint_bottom,offset_width,offset_height ) ;
|
|
//debug_log("4: %d %d %d %d\n",size_before.top,size_before.bottom,size_before.left,size_before.right) ;
|
|
//debug_log("5: %d %d %d %d %d %d\n",paint_top,paint_bottom,paint_left,paint_right,term->cols,term->rows);
|
|
|
|
Rectangle(hdc, paint_left, paint_top,
|
|
paint_right, paint_bottom);
|
|
|
|
SelectObject(hdc, oldpen);
|
|
DeleteObject(edge);
|
|
SelectObject(hdc, oldbrush);
|
|
DeleteObject(bgbrush);
|
|
}
|
|
}
|
|
|
|
/*
|
|
void original_paint_term_edges(HDC hdc, LONG paint_left, LONG paint_top, LONG paint_right, LONG paint_bottom)
|
|
{
|
|
if(backgrounddc == 0)
|
|
load_bg_bmp();
|
|
|
|
if(backgrounddc)
|
|
{
|
|
LONG topLeftX = paint_left;
|
|
LONG topLeftY = paint_top;
|
|
LONG width = (paint_right - paint_left);
|
|
LONG height = (paint_bottom - paint_top);
|
|
HDC srcdc = backgroundblenddc;
|
|
POINT srcTopLeft;
|
|
RECT size_now;
|
|
srcTopLeft.x = topLeftX;
|
|
srcTopLeft.y = topLeftY;
|
|
|
|
if(!bBgRelToTerm)
|
|
ClientToScreen(hwnd, &srcTopLeft);
|
|
|
|
if(!srcdc)
|
|
srcdc = backgrounddc;
|
|
|
|
if(resizing)
|
|
{
|
|
GetClientRect(hwnd, &size_now);
|
|
if(size_now.bottom > size_before.bottom || size_now.right > size_before.right)
|
|
{
|
|
// Draw on full area on resize.
|
|
BitBlt(hdc, topLeftX, topLeftY, width, height, srcdc, srcTopLeft.x, srcTopLeft.y, SRCCOPY);
|
|
|
|
return;
|
|
}
|
|
}
|
|
//debug_log("1: %d %d %d %d\n",size_before.top,size_before.bottom,size_before.left,size_before.right) ;
|
|
//debug_log("2: %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %d\n",topLeftX,topLeftY,width,height,srcTopLeft.x,srcTopLeft.y,size_now.top,size_now.bottom,size_now.left,size_now.right,resizing) ;
|
|
|
|
// Draw top edge
|
|
BitBlt(
|
|
hdc, topLeftX, topLeftY, width, offset_height,
|
|
srcdc, srcTopLeft.x, srcTopLeft.y, SRCCOPY
|
|
);
|
|
// Draw left edge
|
|
BitBlt(
|
|
hdc, topLeftX, topLeftY+1, offset_width, height-2,
|
|
srcdc, srcTopLeft.x, srcTopLeft.y+1, SRCCOPY
|
|
);
|
|
// Draw right edge (extra width for clean resizing)
|
|
BitBlt(
|
|
hdc, topLeftX+width-1, topLeftY+1, offset_width, height-2,
|
|
srcdc, srcTopLeft.x+width-1, srcTopLeft.y+1, SRCCOPY
|
|
);
|
|
// Draw bottom edge (extra height for clean resizing)
|
|
BitBlt(
|
|
hdc, topLeftX, topLeftY+height-1, width, offset_height,
|
|
srcdc, srcTopLeft.x, srcTopLeft.y+height-1, SRCCOPY
|
|
);
|
|
}
|
|
else
|
|
{
|
|
HBRUSH bgbrush, oldbrush;
|
|
HPEN edge, oldpen;
|
|
COLORREF backgroundcolor = colours[258];
|
|
|
|
bgbrush = CreateSolidBrush(backgroundcolor);
|
|
edge = CreatePen(PS_SOLID, 0, backgroundcolor);
|
|
|
|
oldbrush = SelectObject(hdc, bgbrush);
|
|
oldpen = SelectObject(hdc, edge);
|
|
|
|
//
|
|
// * Jordan Russell reports that this apparently
|
|
// * ineffectual IntersectClipRect() call masks a
|
|
// * Windows NT/2K bug causing strange display
|
|
// * problems when the PuTTY window is taller than
|
|
// * the primary monitor. It seems harmless enough...
|
|
|
|
IntersectClipRect(hdc,
|
|
paint_left, paint_top,
|
|
paint_right, paint_bottom);
|
|
|
|
ExcludeClipRect(hdc,
|
|
offset_width, offset_height,
|
|
offset_width+font_width*(term->cols),
|
|
offset_height+font_height*(term->rows));
|
|
|
|
//debug_log("3: %d %d %d %d %d %d %d\n",resizing,paint_left, paint_top, paint_right, paint_bottom,offset_width,offset_height ) ;
|
|
//debug_log("4: %d %d %d %d\n",size_before.top,size_before.bottom,size_before.left,size_before.right) ;
|
|
//debug_log("5: %d %d %d %d %d %d\n",paint_top,paint_bottom,paint_left,paint_right,term->cols,term->rows);
|
|
|
|
Rectangle(hdc, paint_left, paint_top,
|
|
paint_right, paint_bottom);
|
|
|
|
SelectObject(hdc, oldpen);
|
|
DeleteObject(edge);
|
|
SelectObject(hdc, oldbrush);
|
|
DeleteObject(bgbrush);
|
|
}
|
|
}
|
|
*/
|
|
|
|
void clean_bg(void) {
|
|
DeleteDC(textdc);textdc=NULL;
|
|
DeleteObject(textbm);textbm=NULL;
|
|
//DeleteObject(colorinpixel);
|
|
//DeleteDC(colorinpixeldc);
|
|
//DeleteObject(colorinpixelbm);
|
|
DeleteDC(backgrounddc);backgrounddc=NULL;
|
|
DeleteObject(backgroundbm);backgroundbm=NULL;
|
|
DeleteDC(backgroundblenddc);backgroundblenddc=NULL;
|
|
DeleteObject(backgroundblendbm);backgroundblendbm=NULL;
|
|
}
|
|
|
|
void RedrawBackground( HWND hwnd ) {
|
|
if(
|
|
1 && // On inhibe cette fonction a cause du probleme de fuite memoire due a l'image de fond !!! , mais probleme de rafraichissement ?
|
|
(get_param("BACKGROUNDIMAGE"))&&(!get_param("PUTTY"))&&(conf_get_int(conf,CONF_bg_type) != 0) )
|
|
{
|
|
clean_bg() ;
|
|
load_bg_bmp(); // Apparement c'est ça qui faisait la fuite memoire !!!
|
|
}
|
|
/*
|
|
InvalidateRect(hwnd, NULL, true) ;
|
|
RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
|
|
*/
|
|
RedrawWindow( hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_UPDATENOW ) ;
|
|
|
|
}
|
|
|
|
|
|
#ifdef MOD_STARTBUTTON
|
|
/*
|
|
* Patch permettant de gerer le probleme de chargement de l'image de fond arrive avec putty 0.61
|
|
*/
|
|
void BackgroundImagePatch( int num ) {
|
|
int key=0x47 ;
|
|
|
|
if( num == 1 ) { // Double-clic sur une session, on fait ALT-G + Down + ALT-O
|
|
key = 0x47 ; /* VK_G 71 */
|
|
keybd_event(VK_LMENU , 0, 0, 0) ;
|
|
keybd_event( key, 0, 0, 0);
|
|
keybd_event( key, 0, KEYEVENTF_KEYUP, 0) ;
|
|
keybd_event(VK_LMENU, 0, KEYEVENTF_KEYUP, 0) ;
|
|
|
|
keybd_event(VK_DOWN, 0, 0, 0) ;
|
|
keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0) ;
|
|
|
|
key=0x4F ; /* VK_O */
|
|
keybd_event(VK_LMENU , 0, 0, 0) ;
|
|
keybd_event( key, 0, 0, 0);
|
|
keybd_event( key, 0, KEYEVENTF_KEYUP, 0) ;
|
|
keybd_event(VK_LMENU, 0, KEYEVENTF_KEYUP, 0) ;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
HBITMAP HWND_to_HBITMAP(HWND hWnd)
|
|
{
|
|
RECT r;
|
|
HDC hdcMem, hdcScr;
|
|
HBITMAP hbmMem, hbmOld;
|
|
|
|
GetWindowRect(hWnd, &r);
|
|
hdcScr = GetWindowDC(hWnd);
|
|
hdcMem = CreateCompatibleDC(hdcScr);
|
|
hbmMem = CreateCompatibleBitmap(hdcScr, r.right -= r.left, r.bottom -= r.top) ;
|
|
hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem);
|
|
BitBlt(hdcMem, 0, 0, r.right, r.bottom, hdcScr, 0, 0, SRCCOPY);
|
|
SelectObject(hdcMem, hbmOld);
|
|
ReleaseDC(hWnd, hdcScr);
|
|
DeleteDC(hdcMem);
|
|
return hbmMem;
|
|
}
|
|
|
|
BOOL HBITMAP_to_JPG(HBITMAP hbm, LPCTSTR jpgfile, int quality)
|
|
{
|
|
BITMAP bm;
|
|
BITMAPINFO bi;
|
|
BYTE *pPixels;
|
|
JSAMPROW jrows[1], jrow;
|
|
HDC hdcScr, hdcMem1, hdcMem2;
|
|
HBITMAP hbmMem, hbmOld1, hbmOld2;
|
|
FILE *fp = fopen(jpgfile, "wb");
|
|
struct jpeg_compress_struct jpeg;
|
|
struct jpeg_error_mgr jerr;
|
|
|
|
if(!hbm)
|
|
return 0;
|
|
if(!GetObject(hbm, sizeof(bm), &bm))
|
|
return 0;
|
|
if(!fp)
|
|
return 0;
|
|
|
|
ZeroMemory(&bi, sizeof(bi));
|
|
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
bi.bmiHeader.biWidth = bm.bmWidth;
|
|
bi.bmiHeader.biHeight = bm.bmHeight;
|
|
bi.bmiHeader.biPlanes = 1;
|
|
bi.bmiHeader.biBitCount = 24;
|
|
bi.bmiHeader.biCompression = BI_RGB;
|
|
|
|
hdcScr = GetDC(0);
|
|
hdcMem1 = CreateCompatibleDC(hdcScr);
|
|
hbmOld1 = (HBITMAP)SelectObject(hdcMem1,hbm);
|
|
hdcMem2 = CreateCompatibleDC(hdcScr);
|
|
hbmMem = CreateDIBSection(hdcScr, &bi, DIB_RGB_COLORS, (VOID **)&pPixels, 0, 0);
|
|
hbmOld2 = (HBITMAP)SelectObject(hdcMem2, hbmMem);
|
|
|
|
BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem1, 0, 0, SRCCOPY);
|
|
|
|
SelectObject(hdcMem1, hbmOld1);
|
|
SelectObject(hdcMem2, hbmOld2);
|
|
ReleaseDC(0, hdcScr);
|
|
DeleteDC(hdcMem1);
|
|
DeleteDC(hdcMem2);
|
|
|
|
jpeg.err = jpeg_std_error(&jerr);
|
|
jpeg_create_compress(&jpeg);
|
|
jpeg_stdio_dest(&jpeg, fp);
|
|
jpeg.image_width = bm.bmWidth;
|
|
jpeg.image_height = bm.bmHeight;
|
|
jpeg.input_components = 3;
|
|
jpeg.in_color_space = JCS_RGB;
|
|
jpeg.dct_method = JDCT_FLOAT;
|
|
jpeg_set_defaults(&jpeg);
|
|
jpeg_set_quality(&jpeg, (quality < 0 || quality > 100) ? 100 : quality, TRUE);
|
|
jpeg_start_compress(&jpeg, TRUE);
|
|
|
|
char *comment=NULL ;
|
|
if( comment ) {
|
|
jpeg_write_marker(&jpeg, JPEG_COM, (const JOCTET*)comment, strlen(comment));
|
|
}
|
|
|
|
while(jpeg.next_scanline < jpeg.image_height)
|
|
{
|
|
unsigned int i, j, tmp;
|
|
|
|
jrow = &pPixels[(jpeg.image_height - jpeg.next_scanline - 1) * ((((bm.bmWidth * 24) + 31) / 32) * 4)];
|
|
|
|
for(i = 0; i < jpeg.image_width; i++)
|
|
{
|
|
j = i * 3;
|
|
tmp = jrow[j];
|
|
jrow[j] = jrow[j + 2];
|
|
jrow[j + 2] = tmp;
|
|
}
|
|
jrows[0] = jrow;
|
|
jpeg_write_scanlines(&jpeg, jrows, 1);
|
|
}
|
|
|
|
jpeg_finish_compress(&jpeg);
|
|
jpeg_destroy_compress(&jpeg);
|
|
DeleteObject(hbmMem);
|
|
fclose(fp);
|
|
return 1;
|
|
}
|
|
|
|
void MakeScreenShot() {
|
|
HBITMAP hbm = HWND_to_HBITMAP(GetDesktopWindow());
|
|
if(hbm) {
|
|
HBITMAP_to_JPG(hbm, "screenshot.jpg", 85) ;
|
|
DeleteObject(hbm);
|
|
}
|
|
}
|
|
|
|
int screenCapturePart(int x, int y, int w, int h, LPCSTR fname,int quality) {
|
|
int return_code = 0 ;
|
|
HDC hdcSource = GetDC(NULL);
|
|
HDC hdcMemory = CreateCompatibleDC(hdcSource);
|
|
|
|
//int capX = GetDeviceCaps(hdcSource, HORZRES);
|
|
//int capY = GetDeviceCaps(hdcSource, VERTRES);
|
|
|
|
HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, w, h);
|
|
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap);
|
|
|
|
BitBlt(hdcMemory, 0, 0, w, h, hdcSource, x, y, SRCCOPY);
|
|
hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld);
|
|
|
|
DeleteDC(hdcSource);
|
|
DeleteDC(hdcMemory);
|
|
|
|
//HPALETTE hpal = NULL;
|
|
if( HBITMAP_to_JPG( hBitmap,fname, quality) ) { return_code = 1 ; }
|
|
DeleteObject(hBitmap);
|
|
|
|
return return_code ;
|
|
}
|
|
|
|
int screenCaptureClientRect( HWND hwnd, LPCSTR fname, int quality ) {
|
|
RECT rc;
|
|
POINT p;
|
|
GetClientRect(hwnd, &rc);
|
|
p.x=rc.left; p.y=rc.top,
|
|
ClientToScreen(hwnd,&p);
|
|
rc.left=p.x;rc.top=p.y;
|
|
return screenCapturePart(rc.left,rc.top,rc.right,rc.bottom,fname,quality) ;
|
|
}
|
|
int screenCaptureWinRect( HWND hwnd, LPCSTR fname, int quality ) {
|
|
RECT r;
|
|
GetWindowRect(hwnd, &r);
|
|
return screenCapturePart(r.left,r.top,r.right-r.left,r.bottom-r.top,fname,quality) ;
|
|
}
|
|
int screenCaptureAll( LPCSTR fname, int quality ) {
|
|
return screenCapturePart(0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics (SM_CYSCREEN),fname,quality) ;
|
|
}
|