Hi All!
It is time to Implement Screen Shot for real hardware!
Who is up to it?
8^D
James
Oldies but Gold'ies
Filip Navara wrote: 03/08/04 20:44
James Tabor wrote:
Filip Navara wrote:
I cheated, because I used virtual machine with
emulated S3 card, but
it looks same on real HW. If you need a screenshot feature, I'll try
find on of my old patches that saves screenshots to files and adapt
it for the current CVS.
Regards,
Filip
Ya! A good work around hack is good! If you can do so.
Thank,
James
Here it is. Few notes:
1) Beware, it's hack!
2) It's a not little hack, it's a big hack!
3) Saves the screenshot to c:\reactos\screenshot.bmp.
4) Press ALT-PRINTSCREEN in any usual window (not console) to take the
screenshot.
- Filip
------------------------------------------------------------------------
Index: drivers/video/videoprt/videoprt.c
Index: lib/user32/windows/defwnd.c
===================================================================
RCS file: /CVS/ReactOS/reactos/lib/user32/windows/defwnd.c,v
retrieving revision 1.124
diff -u -r1.124 defwnd.c
--- lib/user32/windows/defwnd.c 22 Feb 2004 23:40:58 -0000 1.124
+++ lib/user32/windows/defwnd.c 8 Mar 2004 20:26:40 -0000
@@ -949,10 +949,205 @@
return GetSysColorBrush(COLOR_WINDOW);
}
+/*
+ * CreateBitmapInfoStructure
+ *
+ * Creates a bitmap info structure for saving a bitmap into a file.
+ */
+
+PBITMAPINFO FASTCALL
+CreateBitmapInfoStructure(HDC hDC, HBITMAP hBmp)
+{
+ BITMAP bmp;
+ PBITMAPINFO pbmi;
+ WORD cClrBits;
+
+ /* Get the width, height and the colordepth of the image. */
+ if (!GetObjectW(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
+ {
+ return NULL;
+ }
+
+ /* Convert the color format to a count of bits. */
+ cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
+
+ /*
+ * Allocate memory for the BITMAPINFO-structure. This structure
+ * contains a BITMAPINFOHEADER-structure and an array of RGBQUAD
+ * datastructures.
+ */
+ if (cClrBits <= 8)
+ pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) *
(1 << cClrBits));
+ else
+ pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));
+
+
+ /* Initialize the fields in the BITMAPINFO-structure. */
+ pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmi->bmiHeader.biWidth = bmp.bmWidth;
+ pbmi->bmiHeader.biHeight = bmp.bmHeight;
+ pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
+ pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
+
+ if (cClrBits <= 8)
+ pbmi->bmiHeader.biClrUsed = 1 << cClrBits;
+
+ pbmi->bmiHeader.biCompression = BI_RGB;
+
+ /*
+ * Compute the number of bytes in the array of color indices
+ * and store the result in biSizeImage.
+ */
+
+ pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 7) / 8 *
pbmi->bmiHeader.biHeight * cClrBits;
+
+ /*
+ * Set biClrImportant to 0 to indicate that all of the device
+ * colors are important.
+ */
+
+ pbmi->bmiHeader.biClrImportant = 0;
+
+ /* And finally return the info-structure. */
+ return pbmi;
+}
+
+/*
+ * SaveBitmap
+ *
+ * Saves a bitmap to a specified file.
+ */
+
+HRESULT FASTCALL
+SaveBitmap(PWCHAR strFileName, HDC hDC, HBITMAP hBMP)
+{
+ HANDLE hf;
+ BITMAPFILEHEADER hdr;
+ PBITMAPINFOHEADER pbih;
+ LPBYTE lpBits;
+ DWORD dwTotal;
+ DWORD cb;
+ BYTE *hp;
+ DWORD dwTmp;
+ PBITMAPINFO pbi;
+
+ pbi = CreateBitmapInfoStructure(hDC, hBMP);
+ if (pbi == NULL)
+ {
+ return E_FAIL;
+ }
+
+ pbih = (PBITMAPINFOHEADER)pbi;
+ lpBits = (LPBYTE)GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
+
+ if (!lpBits)
+ {
+ return E_FAIL;
+ }
+
+ /*
+ * Retrieve the colortable (RGBQUAD-array) and the bits
+ * (array of palette indices) from the DIB.
+ */
+
+ if (!GetDIBits(hDC, hBMP, 0, (WORD)pbih->biHeight, lpBits, pbi, DIB_RGB_COLORS))
+ {
+ return E_FAIL;
+ }
+
+
+ /* Create the .BMP file. */
+
+ hf = CreateFileW(
+ strFileName,
+ GENERIC_READ | GENERIC_WRITE,
+ (DWORD)0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ (HANDLE)NULL);
+
+ if (hf == INVALID_HANDLE_VALUE)
+ {
+ return E_FAIL;
+ }
+
+ hdr.bfType = 0x4D42; /* 0x42 = "B", 0x4D = "M" */
+
+ /* Compute the size of the entire file. */
+ hdr.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed
* sizeof(RGBQUAD) + pbih->biSizeImage);
+ hdr.bfReserved1 = 0;
+ hdr.bfReserved2 = 0;
+
+ /* Compute the offset to the array of color indices. */
+ hdr.bfOffBits = ( DWORD ) sizeof( BITMAPFILEHEADER ) + pbih->biSize +
pbih->biClrUsed * sizeof( RGBQUAD );
+
+ /* Copy the BITMAPFILEHEADER into the .BMP file. */
+ if (!WriteFile(hf, (LPVOID)&hdr, sizeof(BITMAPFILEHEADER), (LPDWORD)&dwTmp,
NULL))
+ {
+ return E_FAIL;
+ }
+
+
+ /* Copy the BITMAPINFOHEADER and RGBQUAD array into the file. */
+ if (!WriteFile(hf,
+ (LPVOID)pbih,
+ sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof(RGBQUAD),
+ (LPDWORD)&dwTmp, NULL))
+ {
+ return E_FAIL;
+ }
+
+
+ /* Copy the array of color indices into the .BMP file. */
+ dwTotal = cb = pbih->biSizeImage;
+ hp = lpBits;
+
+ if (!WriteFile(hf, (LPSTR)hp, (int)cb, (LPDWORD)&dwTmp, NULL))
+ {
+ return E_FAIL;
+ }
+
+
+ /* Now close the .BMP file. */
+ if (!CloseHandle(hf))
+ {
+ return E_FAIL;
+ }
+
+ /* Free the memory reserved. */
+ GlobalFree((HGLOBAL)lpBits);
+
+ return S_OK;
+}
+
VOID FASTCALL
DefWndScreenshot(HWND hWnd)
{
-
+ HDC hScreenDC = GetDC(0), hDC;
+ HBITMAP hBmp, hSaveBmp;
+
+ DbgPrint("Screenshot\n");
+ hBmp = CreateCompatibleBitmap(
+ hScreenDC,
+ GetSystemMetrics(SM_CXSCREEN),
+ GetSystemMetrics(SM_CYSCREEN));
+ hDC = CreateCompatibleDC(hScreenDC);
+ hSaveBmp = SelectObject(hDC, hBmp);
+ BitBlt(
+ hDC,
+ 0,
+ 0,
+ GetSystemMetrics(SM_CXSCREEN),
+ GetSystemMetrics(SM_CYSCREEN),
+ hScreenDC,
+ 0,
+ 0,
+ SRCCOPY);
+ SaveBitmap(L"c:\\reactos\\screenshot.bmp", hDC, hBmp);
+ SelectObject(hDC, hSaveBmp);
+ DeleteObject(hBmp);
+ DeleteDC(hDC);
}
LRESULT STDCALL
Index: subsys/win32k/objects/dib.c
===================================================================
RCS file: /CVS/ReactOS/reactos/subsys/win32k/objects/dib.c,v
retrieving revision 1.42
diff -u -r1.42 dib.c
--- subsys/win32k/objects/dib.c 19 Feb 2004 21:12:10 -0000 1.42
+++ subsys/win32k/objects/dib.c 8 Mar 2004 20:27:00 -0000
@@ -23,6 +23,7 @@
#include <windows.h>
#include <stdlib.h>
#include <win32k/bitmaps.h>
+#include <win32k/color.h>
#include <win32k/debug.h>
#include "../eng/handle.h"
#include <ntos/minmax.h>
@@ -259,7 +260,7 @@
}
// Converts a device-dependent bitmap to a DIB
-#if 0
+#if 1
INT STDCALL NtGdiGetDIBits(HDC hDC,
HBITMAP hBitmap,
UINT StartScan,
@@ -278,7 +279,7 @@
UINT coloruse) /* [in] RGB or palette index */
#endif
{
-#if 0
+#if 1
BITMAPINFO Info;
BITMAPCOREHEADER *Core;
PBITMAPOBJ BitmapObj;
@@ -377,8 +378,7 @@
Info.bmiHeader.biWidth == BitmapObj->bitmap.bmWidth &&
Info.bmiHeader.biHeight == BitmapObj->bitmap.bmHeight &&
Info.bmiHeader.biPlanes == BitmapObj->bitmap.bmPlanes &&
- Info.bmiHeader.biBitCount == BitmapObj->bitmap.bmBitsPixel &&
- 8 < Info.bmiHeader.biBitCount)
+ Info.bmiHeader.biBitCount == BitmapObj->bitmap.bmBitsPixel)
{
Info.bmiHeader.biSizeImage = BitmapObj->bitmap.bmHeight *
BitmapObj->bitmap.bmWidthBytes;
Status = MmCopyToCaller(Bits, BitmapObj->bitmap.bmBits,
Info.bmiHeader.biSizeImage);
@@ -390,7 +390,7 @@
}
RtlZeroMemory(&InfoWithBitFields, sizeof(InfoWithBitFields));
RtlCopyMemory(&(InfoWithBitFields.Info), &Info, sizeof(BITMAPINFO));
- if (BI_BITFIELDS == Info.bmiHeader.biCompression)
+ if (Info.bmiHeader.biCompression == BI_BITFIELDS)
{
DCObj = DC_LockDc(hDC);
if (NULL == DCObj)
@@ -419,6 +419,22 @@
BITMAPOBJ_UnlockBitmap(hBitmap);
return 0;
}
+ if (Info.bmiHeader.biBitCount <= 8)
+ {
+ DCObj = DC_LockDc(hDC);
+ if (NULL == DCObj)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ BITMAPOBJ_UnlockBitmap(hBitmap);
+ return 0;
+ }
+ NtGdiGetPaletteEntries(
+ DCObj->w.hPalette,
+ 0,
+ 1 << Info.bmiHeader.biBitCount,
+ (LPPALETTEENTRY)&UnsafeInfo->bmiColors);
+ DC_UnlockDc(hDC);
+ }
}
else
{
@@ -516,7 +532,7 @@
if (bits && lines)
{
/* If the bitmap object already have a dib section that contains image data, get
the bits from it */
- if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 &&
info->bmiHeader.biBitCount >= 15)
+ if(bmp->dib)
{
/*FIXME: Only RGB dibs supported for now */
unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb =
bmp->dib->dsBm.bmWidthBytes;
@@ -702,6 +718,44 @@
}
break;
+ case 8: /* 8 bpp dstDIB */
+ {
+ switch(bmp->dib->dsBm.bmBitsPixel) {
+ case 8: /* 8 bpp srcDIB -> 8 bpp dstDIB */
+ {
+ /* FIXME: BI_BITFIELDS not supported yet */
+ for (y = 0; y < lines; y++, dbits+=dstwidthb,
sbits+=srcwidthb)
+ memcpy(dbits, sbits, srcwidthb);
+ }
+ break;
+
+ default: /* ? bit bmp -> 8 bit DIB */
+ DPRINT1("FIXME: 8 bit DIB %d bit bitmap\n",
+ bmp->bitmap.bmBitsPixel);
+ break;
+ }
+ }
+ break;
+
+ case 4: /* 4 bpp dstDIB */
+ {
+ switch(bmp->dib->dsBm.bmBitsPixel) {
+ case 4: /* 4 bpp srcDIB -> 4 bpp dstDIB */
+ {
+ /* FIXME: BI_BITFIELDS not supported yet */
+ for (y = 0; y < lines; y++, dbits+=dstwidthb,
sbits+=srcwidthb)
+ memcpy(dbits, sbits, srcwidthb);
+ }
+ break;
+
+ default: /* ? bit bmp -> 4 bit DIB */
+ DPRINT1("FIXME: 4 bit DIB %d bit bitmap\n",
+ bmp->bitmap.bmBitsPixel);
+ break;
+ }
+ }
+ break;
+
default: /* ? bit DIB */
DPRINT1("FIXME: Unsupported DIB depth %d\n",
info->bmiHeader.biBitCount);
break;