Implement Information Contexts
Modified: trunk/reactos/include/win32k/dc.h
Modified: trunk/reactos/subsys/win32k/include/intgdi.h
Modified: trunk/reactos/subsys/win32k/ntuser/metric.c
Modified: trunk/reactos/subsys/win32k/ntuser/windc.c
Modified: trunk/reactos/subsys/win32k/ntuser/winsta.c
Modified: trunk/reactos/subsys/win32k/objects/bitmaps.c
Modified: trunk/reactos/subsys/win32k/objects/brush.c
Modified: trunk/reactos/subsys/win32k/objects/dc.c
Modified: trunk/reactos/subsys/win32k/objects/dib.c
Modified: trunk/reactos/subsys/win32k/objects/fillshap.c
Modified: trunk/reactos/subsys/win32k/objects/line.c
Modified: trunk/reactos/subsys/win32k/objects/print.c
Modified: trunk/reactos/subsys/win32k/objects/text.c

Modified: trunk/reactos/include/win32k/dc.h
--- trunk/reactos/include/win32k/dc.h	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/include/win32k/dc.h	2005-03-07 22:24:33 UTC (rev 13870)
@@ -104,6 +104,7 @@
   XLATEOBJ *XlatePen;
 
   INT  saveLevel;
+  BOOL IsIC;
 
   WIN_DC_INFO  w;
 } DC, *PDC;
@@ -136,6 +137,8 @@
   DEVINFO DevInfo;
   DRIVER_FUNCTIONS DriverFunctions;
   PFILE_OBJECT VideoFileObject;
+  BOOLEAN PreparedDriver;
+  ULONG DisplayNumber;
 
   GDIPOINTER Pointer;
 

Modified: trunk/reactos/subsys/win32k/include/intgdi.h
--- trunk/reactos/subsys/win32k/include/intgdi.h	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/include/intgdi.h	2005-03-07 22:24:33 UTC (rev 13870)
@@ -130,7 +130,8 @@
 IntGdiCreateDC(PUNICODE_STRING Driver,
                PUNICODE_STRING Device,
                PUNICODE_STRING Output,
-               CONST PDEVMODEW InitData);
+               CONST PDEVMODEW InitData,
+               BOOL CreateAsIC);
 
 COLORREF FASTCALL
 IntGetDCColor(HDC hDC, ULONG Object);

Modified: trunk/reactos/subsys/win32k/ntuser/metric.c
--- trunk/reactos/subsys/win32k/ntuser/metric.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/ntuser/metric.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -42,7 +42,6 @@
 {
   NTSTATUS Status;
   PWINSTATION_OBJECT WinStaObject;
-  PWINDOW_OBJECT DesktopWindow;
   ULONG Width, Height, Result;
 
   Result = 0;
@@ -156,19 +155,26 @@
       return(27);
     case SM_CXSCREEN:
     case SM_CYSCREEN:
-      DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
-      if (NULL != DesktopWindow)
-	  {
-	    Width = DesktopWindow->WindowRect.right;
-	    Height = DesktopWindow->WindowRect.bottom;
-	  }
-      else
-	  {
-	    Width = 640;
-	    Height = 480;
-	  }
-      IntReleaseWindowObject(DesktopWindow);
+    {
+      HDC ScreenDCHandle;
+      PDC ScreenDC;
+
+      Width = 640;
+      Height = 480;
+      ScreenDCHandle = IntGdiCreateDC(NULL, NULL, NULL, NULL, TRUE);
+      if (NULL != ScreenDCHandle)
+      {
+	ScreenDC = DC_LockDc(ScreenDCHandle);
+	if (NULL != ScreenDC)
+	{
+	  Width = ScreenDC->DMW.dmPelsWidth;
+	  Height = ScreenDC->DMW.dmPelsHeight;
+	  DC_UnlockDc(ScreenDCHandle);
+	}
+	NtGdiDeleteDC(ScreenDCHandle);
+      }
       return SM_CXSCREEN == Index ? Width : Height;
+    }
     case SM_CXSIZE:
     case SM_CYSIZE:
       return(18);

Modified: trunk/reactos/subsys/win32k/ntuser/windc.c
--- trunk/reactos/subsys/win32k/ntuser/windc.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/ntuser/windc.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -132,7 +132,7 @@
   /* No real locking, just get the pointer */
   DCEOBJ_UnlockDCE(DceHandle);
   Dce->Self = DceHandle;
-  Dce->hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL);
+  Dce->hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
   if (NULL == defaultDCstate)
     {
       defaultDCstate = NtGdiGetDCState(Dce->hDC);

Modified: trunk/reactos/subsys/win32k/ntuser/winsta.c
--- trunk/reactos/subsys/win32k/ntuser/winsta.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/ntuser/winsta.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -189,7 +189,7 @@
       return FALSE;
     }
   RtlInitUnicodeString(&DriverName, L"DISPLAY");
-  ScreenDeviceContext = IntGdiCreateDC(&DriverName, NULL, NULL, NULL);
+  ScreenDeviceContext = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
   if (NULL == ScreenDeviceContext)
     {
       IntDestroyPrimarySurface();

Modified: trunk/reactos/subsys/win32k/objects/bitmaps.c
--- trunk/reactos/subsys/win32k/objects/bitmaps.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/objects/bitmaps.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -59,6 +59,12 @@
 		SetLastWin32Error(ERROR_INVALID_HANDLE);
 		return FALSE;
 	}
+	if (DCDest->IsIC)
+	{
+		DC_UnlockDc(hDCDest);
+		/* Yes, Windows really returns TRUE in this case */
+		return TRUE;
+	}
 
 	if (UsesSource)
 	{
@@ -72,6 +78,13 @@
 				SetLastWin32Error(ERROR_INVALID_HANDLE);
 				return FALSE;
 			}
+			if (DCSrc->IsIC)
+			{
+				DC_UnlockDc(hDCSrc);
+				DC_UnlockDc(hDCDest);
+				/* Yes, Windows really returns TRUE in this case */
+				return TRUE;
+			}
 		}
 		else
 		{
@@ -258,6 +271,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (DCDest->IsIC)
+  {
+    DC_UnlockDc(hdcDst);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if((hdcDst != hdcSrc) && !(DCSrc = DC_LockDc(hdcSrc)))
   {
@@ -270,6 +289,16 @@
   {
     DCSrc = DCDest;
   }
+  if (DCSrc->IsIC)
+  {
+    DC_UnlockDc(hdcSrc);
+    if(hdcDst != hdcSrc)
+    {
+      DC_UnlockDc(hdcDst);
+    }
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   /* Offset positions */
   xDst += DCDest->w.DCOrgX;
@@ -575,6 +604,11 @@
 		SetLastWin32Error(ERROR_INVALID_HANDLE);
 		return Result;
 	}
+	if (dc->IsIC)
+	{
+		DC_UnlockDc(hDC);
+		return Result;
+	}
 	XPos += dc->w.DCOrgX;
 	YPos += dc->w.DCOrgY;
 	if ( IN_RECT(dc->CombinedClip->rclBounds,XPos,YPos) )
@@ -1039,6 +1073,12 @@
 		SetLastWin32Error(ERROR_INVALID_HANDLE);
 		return FALSE;
 	}
+	if (DCDest->IsIC)
+	{
+		DC_UnlockDc(hDCDest);
+		/* Yes, Windows really returns TRUE in this case */
+		return TRUE;
+	}
 
 	if (UsesSource)
 	{
@@ -1052,6 +1092,13 @@
 				SetLastWin32Error(ERROR_INVALID_HANDLE);
 				return FALSE;
 			}
+			if (DCSrc->IsIC)
+			{
+				DC_UnlockDc(hDCSrc);
+				DC_UnlockDc(hDCDest);
+				/* Yes, Windows really returns TRUE in this case */
+				return TRUE;
+			}
 		}
 		else
 		{

Modified: trunk/reactos/subsys/win32k/objects/brush.c
--- trunk/reactos/subsys/win32k/objects/brush.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/objects/brush.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -266,6 +266,12 @@
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
    }
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+   }
 	
    for (r = pRects, i = 0; i < cRects; i++)
    {
@@ -466,6 +472,12 @@
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
    }
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+   }
 
    BrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
    if (BrushObj == NULL)

Modified: trunk/reactos/subsys/win32k/objects/dc.c
--- trunk/reactos/subsys/win32k/objects/dc.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/objects/dc.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -136,7 +136,7 @@
   if (hDC == NULL)
     {
       RtlInitUnicodeString(&DriverName, L"DISPLAY");
-      DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL);
+      DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, TRUE);
       if (NULL == DisplayDC)
         {
           return NULL;
@@ -169,6 +169,7 @@
 
   /* Copy information from original DC to new DC  */
   NewDC->hSelf = hNewDC;
+  NewDC->IsIC = FALSE;
 
   NewDC->PDev = OrigDC->PDev;
   NewDC->DMW = OrigDC->DMW;
@@ -454,19 +455,16 @@
   return Valid;
 }
 
-BOOL FASTCALL
-IntCreatePrimarySurface()
+static BOOL FASTCALL
+IntPrepareDriver()
 {
    PGD_ENABLEDRIVER GDEnableDriver;
    DRVENABLEDATA DED;
-   SURFOBJ *SurfObj;
-   SIZEL SurfSize;
    UNICODE_STRING DriverFileNames;
    PWSTR CurrentName;
    BOOL GotDriver;
    BOOL DoDefault;
    ULONG DisplayNumber;
-   RECTL SurfaceRect;
 
    for (DisplayNumber = 0; ; DisplayNumber++)
    {
@@ -488,7 +486,6 @@
       if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
       {
          DPRINT1("FindDriverFileNames failed\n");
-         /* return FALSE; */
          continue;
       }
 
@@ -543,7 +540,6 @@
       {
          ObDereferenceObject(PrimarySurface.VideoFileObject);
          DPRINT1("No suitable DDI driver found\n");
-         /* return FALSE; */
          continue;
       }
 
@@ -608,7 +604,6 @@
             ObDereferenceObject(PrimarySurface.VideoFileObject);
             DPRINT1("DrvEnablePDEV with default parameters failed\n");
             DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
-            /* return FALSE; */
             continue;
          }
       }
@@ -623,7 +618,7 @@
          DPRINT("Adjusting GDIInfo.ulLogPixelsY\n");
          PrimarySurface.GDIInfo.ulLogPixelsY = 96;
       }
-      
+
       PrimarySurface.Pointer.Exclude.right = -1;
 
       DPRINT("calling completePDev\n");
@@ -637,43 +632,66 @@
 
       DRIVER_ReferenceDriver(L"DISPLAY");
 
-      DPRINT("calling EnableSurface\n");
+      PrimarySurface.PreparedDriver = TRUE;
+      PrimarySurface.DisplayNumber = DisplayNumber;
 
-      /* Enable the drawing surface */
-      PrimarySurface.Handle =
-         PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.PDev);
-      if (NULL == PrimarySurface.Handle)
-      {
-/*         PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);*/
-         PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
-         ObDereferenceObject(PrimarySurface.VideoFileObject);
-         DPRINT1("DrvEnableSurface failed\n");
-         /* return FALSE; */
-         continue;
-      }
+      return TRUE;
+   }
 
-      /* attach monitor */
-      IntAttachMonitor(&PrimarySurface, DisplayNumber);
+   return FALSE;
+}
 
-      SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
-      SurfObj->dhpdev = PrimarySurface.PDev;
-      SurfSize = SurfObj->sizlBitmap;
-      SurfSize = SurfObj->sizlBitmap;
-      SurfaceRect.left = SurfaceRect.top = 0;
-      SurfaceRect.right = SurfObj->sizlBitmap.cx;
-      SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
-      /* FIXME - why does EngEraseSurface() sometimes crash?
-        EngEraseSurface(SurfObj, &SurfaceRect, 0); */
+static BOOL FASTCALL
+IntPrepareDriverIfNeeded()
+{
+   return (PrimarySurface.PreparedDriver ? TRUE : IntPrepareDriver());
+}
 
-      /* Put the pointer in the center of the screen */
-      GDIDEV(SurfObj)->Pointer.Pos.x = (SurfaceRect.right - SurfaceRect.left) / 2;
-      GDIDEV(SurfObj)->Pointer.Pos.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
+BOOL FASTCALL
+IntCreatePrimarySurface()
+{
+   SIZEL SurfSize;
+   RECTL SurfaceRect;
+   SURFOBJ *SurfObj;
 
-      EngUnlockSurface(SurfObj);
-      IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
-      break;
+   if (! IntPrepareDriverIfNeeded())
+   {
+      return FALSE;
    }
 
+   DPRINT("calling EnableSurface\n");
+   /* Enable the drawing surface */
+   PrimarySurface.Handle =
+      PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.PDev);
+   if (NULL == PrimarySurface.Handle)
+   {
+/*      PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);*/
+      PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
+      ObDereferenceObject(PrimarySurface.VideoFileObject);
+      DPRINT1("DrvEnableSurface failed\n");
+      return FALSE;
+   }
+
+   /* attach monitor */
+   IntAttachMonitor(&PrimarySurface, PrimarySurface.DisplayNumber);
+
+   SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
+   SurfObj->dhpdev = PrimarySurface.PDev;
+   SurfSize = SurfObj->sizlBitmap;
+   SurfSize = SurfObj->sizlBitmap;
+   SurfaceRect.left = SurfaceRect.top = 0;
+   SurfaceRect.right = SurfObj->sizlBitmap.cx;
+   SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
+   /* FIXME - why does EngEraseSurface() sometimes crash?
+     EngEraseSurface(SurfObj, &SurfaceRect, 0); */
+
+   /* Put the pointer in the center of the screen */
+   GDIDEV(SurfObj)->Pointer.Pos.x = (SurfaceRect.right - SurfaceRect.left) / 2;
+   GDIDEV(SurfObj)->Pointer.Pos.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
+
+   EngUnlockSurface(SurfObj);
+   IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
+
    return TRUE;
 }
 
@@ -694,6 +712,7 @@
     PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);
     PrimarySurface.DriverFunctions.DisableSurface(PrimarySurface.PDev);
     PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
+    PrimarySurface.PreparedDriver = FALSE;
 
     DceEmptyCache();
 
@@ -704,7 +723,8 @@
 IntGdiCreateDC(PUNICODE_STRING Driver,
                PUNICODE_STRING Device,
                PUNICODE_STRING Output,
-               CONST PDEVMODEW InitData)
+               CONST PDEVMODEW InitData,
+               BOOL CreateAsIC)
 {
   HDC      hNewDC;
   PDC      NewDC;
@@ -714,11 +734,19 @@
   UNICODE_STRING StdDriver;
   
   RtlInitUnicodeString(&StdDriver, L"DISPLAY");
-  
+
   if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE))
     {
-      if (! IntGraphicsCheck(TRUE))
+      if (CreateAsIC)
         {
+          if (! IntPrepareDriverIfNeeded())
+            {
+              DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
+              return NULL;
+            }
+        }
+      else if (! IntGraphicsCheck(TRUE))
+        {
           DPRINT1("Unable to initialize graphics, returning NULL dc\n");
           return NULL;
         }
@@ -750,6 +778,7 @@
     return NULL;
   }
 
+  NewDC->IsIC = CreateAsIC;
   NewDC->DMW = PrimarySurface.DMW;
   NewDC->DevInfo = &PrimarySurface.DevInfo;
   NewDC->GDIInfo = &PrimarySurface.GDIInfo;
@@ -763,43 +792,46 @@
   NewDC->DMW.dmSize = sizeof(NewDC->DMW);
   NewDC->DMW.dmFields = 0x000fc000;
 
-  /* FIXME: get mode selection information from somewhere  */
+  NewDC->DMW.dmLogPixels = 96;
+  NewDC->w.bitsPerPixel = NewDC->DMW.dmBitsPerPel; // FIXME: set this here??
+  DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel);
 
-  NewDC->DMW.dmLogPixels = 96;
-  SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
-  if ( !SurfObj )
+  if (! CreateAsIC)
   {
-	  DC_UnlockDc ( hNewDC );
-	  DC_FreeDC ( hNewDC) ;
-	  return NULL;
-  }
-  NewDC->DMW.dmBitsPerPel = BitsPerFormat(SurfObj->iBitmapFormat);
-  NewDC->DMW.dmPelsWidth = SurfObj->sizlBitmap.cx;
-  NewDC->DMW.dmPelsHeight = SurfObj->sizlBitmap.cy;
-  NewDC->DMW.dmDisplayFlags = 0;
-  NewDC->DMW.dmDisplayFrequency = 0;
+    SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
+    if ( !SurfObj )
+    {
+      DC_UnlockDc ( hNewDC );
+      DC_FreeDC ( hNewDC) ;
+      return NULL;
+    }
+    ASSERT(NewDC->DMW.dmBitsPerPel == BitsPerFormat(SurfObj->iBitmapFormat));
+    ASSERT(NewDC->DMW.dmPelsWidth == SurfObj->sizlBitmap.cx);
+    ASSERT(NewDC->DMW.dmPelsHeight == SurfObj->sizlBitmap.cy);
 
-  NewDC->w.bitsPerPixel = NewDC->DMW.dmBitsPerPel; // FIXME: set this here??
-  NewDC->w.hPalette = NewDC->DevInfo->hpalDefault;
-  NewDC->w.ROPmode = R2_COPYPEN;
-
-  DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel);
+    NewDC->w.hPalette = NewDC->DevInfo->hpalDefault;
+    NewDC->w.ROPmode = R2_COPYPEN;
   
-  DC_UnlockDc( hNewDC );
+    DC_UnlockDc( hNewDC );
 
-  hVisRgn = NtGdiCreateRectRgn(0, 0, SurfObj->sizlBitmap.cx,
-                              SurfObj->sizlBitmap.cy);
-  NtGdiSelectVisRgn(hNewDC, hVisRgn);
-  NtGdiDeleteObject(hVisRgn);
+    hVisRgn = NtGdiCreateRectRgn(0, 0, SurfObj->sizlBitmap.cx,
+                                 SurfObj->sizlBitmap.cy);
+    NtGdiSelectVisRgn(hNewDC, hVisRgn);
+    NtGdiDeleteObject(hVisRgn);
 
-  /*  Initialize the DC state  */
-  DC_InitDC(hNewDC);
-  NtGdiSetTextColor(hNewDC, RGB(0, 0, 0));
-  NtGdiSetTextAlign(hNewDC, TA_TOP);
-  NtGdiSetBkColor(hNewDC, RGB(255, 255, 255));
-  NtGdiSetBkMode(hNewDC, OPAQUE);
+    /*  Initialize the DC state  */
+    DC_InitDC(hNewDC);
+    NtGdiSetTextColor(hNewDC, RGB(0, 0, 0));
+    NtGdiSetTextAlign(hNewDC, TA_TOP);
+    NtGdiSetBkColor(hNewDC, RGB(255, 255, 255));
+    NtGdiSetBkMode(hNewDC, OPAQUE);
 
-  EngUnlockSurface(SurfObj);
+    EngUnlockSurface(SurfObj);
+  }
+  else
+  {
+    DC_UnlockDc( hNewDC );
+  }
   
   return hNewDC;
 }
@@ -847,7 +879,7 @@
     }
   }
   
-  Ret = IntGdiCreateDC(&SafeDriver, &SafeDevice, NULL, &SafeInitData);
+  Ret = IntGdiCreateDC(&SafeDriver, &SafeDevice, NULL, &SafeInitData, FALSE);
   
   return Ret;
 }
@@ -856,10 +888,50 @@
 NtGdiCreateIC(PUNICODE_STRING Driver,
               PUNICODE_STRING Device,
               PUNICODE_STRING Output,
-              CONST PDEVMODEW DevMode)
+              CONST PDEVMODEW InitData)
 {
-  /* FIXME: this should probably do something else...  */
-  return  NtGdiCreateDC(Driver, Device, Output, DevMode);
+  UNICODE_STRING SafeDriver, SafeDevice;
+  DEVMODEW SafeInitData;
+  HDC Ret;
+  NTSTATUS Status;
+  
+  if(InitData)
+  {
+    Status = MmCopyFromCaller(&SafeInitData, InitData, sizeof(DEVMODEW));
+    if(!NT_SUCCESS(Status))
+    {
+      SetLastNtError(Status);
+      return NULL;
+    }
+    /* FIXME - InitData can have some more bytes! */
+  }
+  
+  if(Driver)
+  {
+    Status = IntSafeCopyUnicodeString(&SafeDriver, Driver);
+    if(!NT_SUCCESS(Status))
+    {
+      SetLastNtError(Status);
+      return NULL;
+    }
+  }
+  
+  if(Device)
+  {
+    Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
+    if(!NT_SUCCESS(Status))
+    {
+      RtlFreeUnicodeString(&SafeDriver);
+      SetLastNtError(Status);
+      return NULL;
+    }
+  }
+  
+  Ret = IntGdiCreateDC(NULL == Driver ? NULL : &SafeDriver,
+                       NULL == Device ? NULL : &SafeDevice, NULL,
+                       NULL == InitData ? NULL : &SafeInitData, TRUE);
+  
+  return Ret;
 }
 
 BOOL STDCALL
@@ -1144,6 +1216,7 @@
 
   newdc->hSelf = hnewdc;
   newdc->saveLevel = 0;
+  newdc->IsIC = dc->IsIC;
 
 #if 0
   PATH_InitGdiPath( &newdc->w.path );

Modified: trunk/reactos/subsys/win32k/objects/dib.c
--- trunk/reactos/subsys/win32k/objects/dib.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/objects/dib.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -27,6 +27,11 @@
    PBITMAPOBJ BitmapObj;
 
    if (!(dc = DC_LockDc(hDC))) return 0;
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      return 0;
+   }
 
    BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
    if (BitmapObj == NULL)
@@ -73,6 +78,11 @@
    PBITMAPOBJ BitmapObj;
 
    if (!(dc = DC_LockDc(hDC))) return 0;
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      return 0;
+   }
 
    BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
    if (BitmapObj == NULL)
@@ -264,6 +274,11 @@
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return 0;
     }
+  if (Dc->IsIC)
+    {
+      DC_UnlockDc(hDC);
+      return 0;
+    }
 
   Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
 
@@ -325,6 +340,11 @@
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return 0;
    }
+   if (Dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      return 0;
+   }
    hSourcePalette = Dc->w.hPalette;
    /* FIXME: This is incorrect. hDestPalette should be something other. */
    hDestPalette = Dc->DevInfo->hpalDefault;

Modified: trunk/reactos/subsys/win32k/objects/fillshap.c
--- trunk/reactos/subsys/win32k/objects/fillshap.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/objects/fillshap.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -237,6 +237,12 @@
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
    }
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+   }
 
    FillBrush = BRUSHOBJ_LockBrush(dc->w.hBrush);
    if (NULL == FillBrush)
@@ -664,6 +670,12 @@
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
     }
+  if (dc->IsIC)
+    {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+    }
 
   FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
   if (NULL == FillBrushObj)
@@ -844,6 +856,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
   else
   {
+    if (dc->IsIC)
+    {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+    }
     Safept = ExAllocatePoolWithTag(PagedPool, sizeof(POINT) * Count, TAG_SHAPE);
     if(!Safept)
       SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
@@ -883,6 +901,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count > 0)
   {
@@ -1061,6 +1085,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   ret = IntRectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
   DC_UnlockDc ( hDC );
@@ -1358,6 +1388,12 @@
     DPRINT1("NtGdiRoundRect() - hDC is invalid\n");
     SetLastWin32Error(ERROR_INVALID_HANDLE);
   }
+  else if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    ret = TRUE;
+  }
   else
   {
     ret = IntRoundRect ( dc, LeftRect, TopRect, RightRect, BottomRect, Width, Height );
@@ -1490,6 +1526,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hdc);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   if(!pVertex || !uVertex || !pMesh || !uMesh)
   {
     DC_UnlockDc(hdc);

Modified: trunk/reactos/subsys/win32k/objects/line.c
--- trunk/reactos/subsys/win32k/objects/line.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/objects/line.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -368,6 +368,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   Ret = IntGdiArc(dc,
                   LeftRect,
@@ -404,6 +410,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
 
   // Line from current position to starting point of arc
   if ( !IntGdiLineTo(dc, XRadial1, YRadial1) )
@@ -466,6 +478,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   Ret = IntGdiLineTo(dc, XEnd, YEnd);
   
@@ -491,6 +509,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Point)
   {
@@ -526,6 +550,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count > 0)
   {
@@ -577,6 +607,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count > 0)
   {
@@ -639,6 +675,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count >= 2)
   {
@@ -690,6 +732,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count > 0)
   {
@@ -743,6 +791,12 @@
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count > 0)
   {

Modified: trunk/reactos/subsys/win32k/objects/print.c
--- trunk/reactos/subsys/win32k/objects/print.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/objects/print.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -158,6 +158,11 @@
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return -1;
    }
+   if ( pDC->IsIC )
+   {
+      DC_UnlockDc(hDC);
+      return 0;
+   }
 
    if ( InSize && UnsafeInData )
    {

Modified: trunk/reactos/subsys/win32k/objects/text.c
--- trunk/reactos/subsys/win32k/objects/text.c	2005-03-07 18:31:10 UTC (rev 13869)
+++ trunk/reactos/subsys/win32k/objects/text.c	2005-03-07 22:24:33 UTC (rev 13870)
@@ -1534,6 +1534,12 @@
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
    }
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+   }
 
    if (NULL != UnsafeDx && Count > 0)
    {