Code:
int grab_screen( int client_fd, char buf[3][2048] )///////////////////////////////////////////////////////////////////////////////
{
// FILE *f = NULL;
HDC hsDC = NULL;
HDC hdDC = NULL;
HBITMAP hBMP = NULL;
BITMAPINFO BI;
png_struct *pstr;
png_info *pinf;
int width, height;
int i, j, k, u, v;
int retval, icon;
icon = atoi( buf[1] + 8 );
WaitForSingleObject( shot.sem, INFINITE );
/* initial data setup */
if( ( hsDC = GetDC( NULL ) ) == NULL )
return( ERR_GDI_FAILED );
width = GetDeviceCaps( hsDC, HORZRES );
height = GetDeviceCaps( hsDC, VERTRES );
if( shot.width != width ||
shot.height != height )
{
if( shot.bytes_tn != NULL ) free( shot.bytes_tn );
if( shot.bytes_fs != NULL ) free( shot.bytes_fs );
if( shot.rows_tn != NULL ) free( shot.rows_tn );
if( shot.rows_fs != NULL ) free( shot.rows_fs );
retval = ERR_MALLOC_FAILED;
if( ( shot.bytes_tn = malloc( (
width * height * 3 ) / 16 ) ) == NULL )
goto png_exit;
if( ( shot.bytes_fs = malloc(
width * height * 3 ) ) == NULL )
goto png_exit;
if( ( shot.rows_tn = malloc( (
height * sizeof( unsigned char* ) ) / 4 ) ) == NULL )
goto png_exit;
if( ( shot.rows_fs = malloc(
height * sizeof( unsigned char* ) ) ) == NULL )
goto png_exit;
shot.width = width;
shot.height = height;
}
/* create the destination DC & bitmap */
retval = ERR_GDI_FAILED;
hBMP = CreateCompatibleBitmap( hsDC, shot.width, shot.height );
if( hBMP == NULL )
goto png_exit;
if( ( hdDC = CreateCompatibleDC( hsDC ) ) == NULL )
goto png_exit;
/* copy desktop pixels into bitmap, get the bits */
memset( &BI, 0, sizeof( BI ) );
BI.bmiHeader.biSize = sizeof( BI.bmiHeader );
BI.bmiHeader.biWidth = shot.width;
BI.bmiHeader.biHeight = shot.height;
BI.bmiHeader.biPlanes = 1;
BI.bmiHeader.biBitCount = 24;
if( SelectObject( hdDC, hBMP ) == NULL )
goto png_exit;
if( BitBlt( hdDC, 0, 0, shot.width, shot.height,
hsDC, 0, 0, SRCCOPY ) == 0 )
goto png_exit;
if( GetDIBits( hdDC, hBMP, 0, shot.height, shot.bytes_fs,
&BI, DIB_RGB_COLORS ) != shot.height )
goto png_exit;
/* setup the png data row pointers */
if( icon )
{
int B, G, R;
width /= 4;
height /= 4;
// shrink the image to 25% of its size
for( j = 0, k = height - 1; j < height; j++, k-- )
{
for( i = 0; i < width * 3; i +=3 )
{
B = G = R = 0;
for( v = j * 4; v < (j + 1) * 4; v++ )
{
for( u = i * 4; u < (i + 3) * 4; u += 3 )
{
B += shot.bytes_fs[ u + v * shot.width * 3];
G += shot.bytes_fs[1 + u + v * shot.width * 3];
R += shot.bytes_fs[2 + u + v * shot.width * 3];
}
}
shot.bytes_tn[ i + j * width * 3] = B / 16;
shot.bytes_tn[1 + i + j * width * 3] = G / 16;
shot.bytes_tn[2 + i + j * width * 3] = R / 16;
}
shot.rows_tn[j] = shot.bytes_tn + k * width * 3;
}
}
else
for( j = 0, k = height - 1; j < height; j++, k-- )
shot.rows_fs[j] = shot.bytes_fs + k * width * 3;
/* finally write the png */
if( send( client_fd, "HTTP/1.0 200 OK\r\nContent-Type: "
"image/png\r\n\r\n", 44, 0 ) != 44 )
return( ERR_SEND_FAILED );
pstr = png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
pinf = png_create_info_struct( pstr );
png_set_IHDR( pstr, pinf, width, height, 8,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE );
png_set_bgr( pstr );
png_set_write_fn( pstr, (void *) client_fd,
user_write_data, user_flush_data );
png_write_info( pstr, pinf );
png_write_image( pstr, ( icon ) ? shot.rows_tn : shot.rows_fs );
png_write_end( pstr, pinf );
png_destroy_write_struct( &pstr, &pinf );
retval = 0;
png_exit:
if( hsDC != NULL );
ReleaseDC( NULL, hsDC );
if( hdDC != NULL );
ReleaseDC( NULL, hdDC );
if( hBMP != NULL )
DeleteObject( hBMP );
ReleaseSemaphore( shot.sem, 1, NULL );
return( retval );
}