[ros-dev] Screen Shot for Real Hardware Was: [ros-kernel] David Recent Video Card Support Changes

James Tabor jimtabor at adsl-64-217-116-74.dsl.hstntx.swbell.net
Sat Jan 14 09:16:59 CET 2006


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;



More information about the Ros-dev mailing list