[ros-kernel] David Recent Video Card Support Changes

Filip Navara xnavara at volny.cz
Mon Mar 8 21:44:35 CET 2004


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
-------------- next part --------------
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-kernel mailing list