[GDI32]
[reactos.git] / reactos / dll / win32 / gdi32 / objects / dc.c
index 7e2d66a..ddc33e5 100644 (file)
@@ -20,6 +20,15 @@ IntCreateDICW ( LPCWSTR   lpwszDriver,
 
  HANDLE hspool = NULL;
 
+ if ( !ghSpooler && !LoadTheSpoolerDrv())
+ {
+    DPRINT1("WinSpooler.Drv Did not load!\n");
+ }
+ else
+ {
+    DPRINT("WinSpooler.Drv Loaded! hMod -> 0x%x\n", ghSpooler);
+ }
+
  if ((!lpwszDevice) && (!lpwszDriver))
  {
      Default = FALSE;  // Ask Win32k to set Default device.
@@ -27,7 +36,7 @@ IntCreateDICW ( LPCWSTR   lpwszDriver,
  }
  else
  {
-    if (lpwszDevice) // First
+    if ((lpwszDevice) && (wcslen(lpwszDevice) != 0))  // First
     {
       if (!_wcsnicmp(lpwszDevice, L"\\\\.\\DISPLAY",11)) Display = TRUE;
       RtlInitUnicodeString(&Device, lpwszDevice);
@@ -55,6 +64,7 @@ IntCreateDICW ( LPCWSTR   lpwszDriver,
                      (PDEVMODEW) lpInitData,
                      (lpwszOutput ? &Output : NULL),
                       iType,             // DCW 0 and ICW 1.
+                      Display,
                       hspool,
                      (PVOID) NULL,       // NULL for now.
                      (PVOID) &UMdhpdev );
@@ -65,7 +75,7 @@ IntCreateDICW ( LPCWSTR   lpwszDriver,
     PDC_ATTR Dc_Attr;
     PLDC pLDC;
 
-    GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr);
+    GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr);
 
     pLDC = LocalAlloc(LMEM_ZEROINIT, sizeof(LDC));
 
@@ -83,18 +93,30 @@ IntCreateDICW ( LPCWSTR   lpwszDriver,
  * @implemented
  */
 HDC
-STDCALL
+WINAPI
 CreateCompatibleDC ( HDC hdc)
 {
-    /* FIXME need sharememory if it metadc */
-    return NtGdiCreateCompatibleDC(hdc);
+ HDC rhDC;
+// PDC_ATTR Dc_Attr;
+
+ rhDC = NtGdiCreateCompatibleDC(hdc);
+#if 0
+ if ( hdc && rhDC)
+ {
+    if (GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
+    {
+       if ( Dc_Attr->pvLIcm ) IcmCompatibleDC(rhDC, hdc, Dc_Attr);
+    }
+ }
+#endif
+ return rhDC;
 }
 
 /*
  * @implemented
  */
 HDC
-STDCALL
+WINAPI
 CreateDCA (
        LPCSTR          lpszDriver,
        LPCSTR          lpszDevice,
@@ -158,7 +180,7 @@ CreateDCA (
  * @implemented
  */
 HDC
-STDCALL
+WINAPI
 CreateDCW (
        LPCWSTR         lpwszDriver,
        LPCWSTR         lpwszDevice,
@@ -179,7 +201,7 @@ CreateDCW (
  * @implemented
  */
 HDC
-STDCALL
+WINAPI
 CreateICW(
        LPCWSTR         lpszDriver,
        LPCWSTR         lpszDevice,
@@ -199,7 +221,7 @@ CreateICW(
  * @implemented
  */
 HDC
-STDCALL
+WINAPI
 CreateICA(
        LPCSTR          lpszDriver,
        LPCSTR          lpszDevice,
@@ -250,29 +272,41 @@ CreateICA(
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 DeleteDC(HDC hDC)
 {
   BOOL Ret = TRUE;
-#if 0
-  PDC_ATTR Dc_Attr;
-  PLDC pLDC;
+  PLDC pLDC = NULL;
+  HANDLE hPrinter = NULL;
+  ULONG hType = GDI_HANDLE_GET_TYPE(hDC);
 
-  if (!GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr)) return FALSE;
+  pLDC = GdiGetLDC(hDC);
 
-  if ( Dc_Attr )
-    {
-      pLDC = Dc_Attr->pvLDC;
+  if (hType != GDILoObjType_LO_DC_TYPE)
+  {
+
+     if ( !pLDC || hType == GDILoObjType_LO_METADC16_TYPE)
+     {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+     }
+     if (pLDC->Flags & LDC_INIT_DOCUMENT) AbortDoc(hDC);
+     if (pLDC->hPrinter)
+     {
+        DocumentEventEx(NULL, pLDC->hPrinter, hDC, DOCUMENTEVENT_DELETEDC, 0, NULL, 0, NULL);
+        hPrinter = pLDC->hPrinter;
+        pLDC->hPrinter = NULL;
+     }
+  }
 
-      if ( pLDC )
-        {
-          DPRINT1("Delete the Local DC structure\n");
-          LocalFree( pLDC );
-        }
-    }
-#endif
   Ret = NtGdiDeleteObjectApp(hDC);
 
+  if (Ret && pLDC )
+  {
+     DPRINT1("Delete the Local DC structure\n");
+     LocalFree( pLDC );
+  }
+  if (hPrinter) fpClosePrinter(hPrinter);
   return Ret;
 }
 
@@ -280,7 +314,7 @@ DeleteDC(HDC hDC)
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 DeleteObject(HGDIOBJ hObject)
 {
   UINT Type = 0;
@@ -330,7 +364,7 @@ DeleteObject(HGDIOBJ hObject)
           PBRUSH_ATTR Brh_Attr;
           PTEB pTeb;
 
-          if ((!GdiGetHandleUserData(hObject, (PVOID) &Brh_Attr)) ||
+          if ((!GdiGetHandleUserData(hObject, (DWORD)Type, (PVOID) &Brh_Attr)) ||
               (Brh_Attr == NULL) ) break;
 
           pTeb = NtCurrentTeb();
@@ -360,7 +394,7 @@ DeleteObject(HGDIOBJ hObject)
 }
 
 INT
-STDCALL
+WINAPI
 GetArcDirection( HDC hdc )
 {
   return GetDCDWord( hdc, GdiGetArcDirection, 0);
@@ -368,7 +402,7 @@ GetArcDirection( HDC hdc )
 
 
 INT
-STDCALL
+WINAPI
 SetArcDirection( HDC hdc, INT nDirection )
 {
   return GetAndSetDCDWord( hdc, GdiGetSetArcDirection, nDirection, 0, 0, 0 );
@@ -376,7 +410,7 @@ SetArcDirection( HDC hdc, INT nDirection )
 
 
 HGDIOBJ
-STDCALL
+WINAPI
 GetDCObject( HDC hDC, INT iType)
 {
  if((iType == GDI_OBJECT_TYPE_BRUSH) ||
@@ -387,7 +421,9 @@ GetDCObject( HDC hDC, INT iType)
    HGDIOBJ hGO = NULL;
    PDC_ATTR Dc_Attr;
 
-   if (!GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr)) return NULL;
+   if (!hDC) return hGO;
+
+   if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return NULL;
 
    switch (iType)
    {
@@ -415,7 +451,7 @@ GetDCObject( HDC hDC, INT iType)
  *
  */
 HGDIOBJ
-STDCALL
+WINAPI
 GetCurrentObject(HDC hdc,
                  UINT uObjectType)
 {
@@ -451,12 +487,180 @@ GetCurrentObject(HDC hdc,
     return  GetDCObject(hdc, uObjectType);
 }
 
+/*
+ * @implemented
+ *
+ */
+int
+WINAPI
+GetDeviceCaps(HDC hDC,
+              int i)
+{
+  PDC_ATTR Dc_Attr;
+  PLDC pLDC;
+  PDEVCAPS pDevCaps = GdiDevCaps; // Primary display device capabilities.
+  DPRINT("Device CAPS1\n");
+
+  if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
+  {
+     if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
+     {
+        if ( i == TECHNOLOGY) return DT_METAFILE;
+        return 0;
+     }
+     else
+     {
+        pLDC = GdiGetLDC(hDC);
+        if ( !pLDC )
+        {
+           SetLastError(ERROR_INVALID_HANDLE);
+           return 0;
+        }
+        if (!(pLDC->Flags & LDC_DEVCAPS))
+        {
+           if (!NtGdiGetDeviceCapsAll(hDC, &pLDC->DevCaps))
+              SetLastError(ERROR_INVALID_PARAMETER);
+           pLDC->Flags |= LDC_DEVCAPS;
+        }
+        pDevCaps = &pLDC->DevCaps;
+     }
+  }
+  else
+  {
+     if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
+        return 0;
+     if (!(Dc_Attr->ulDirty_ & DC_PRIMARY_DISPLAY) )
+        return NtGdiGetDeviceCaps(hDC,i);
+  }
+  DPRINT("Device CAPS2\n");
+  
+  switch (i)
+  {
+    case DRIVERVERSION:
+      return pDevCaps->ulVersion;
+
+    case TECHNOLOGY:
+      return pDevCaps->ulTechnology;
+
+    case HORZSIZE:
+      return pDevCaps->ulHorzSize;
+
+    case VERTSIZE:
+      return pDevCaps->ulVertSize;
+
+    case HORZRES:
+      return pDevCaps->ulHorzRes;
+
+    case VERTRES:
+      return pDevCaps->ulVertRes;
+
+    case LOGPIXELSX:
+      return pDevCaps->ulLogPixelsX;
+
+    case LOGPIXELSY:
+      return pDevCaps->ulLogPixelsY;
+
+    case BITSPIXEL:
+      return pDevCaps->ulBitsPixel;
+
+    case PLANES:
+      return pDevCaps->ulPlanes;
+
+    case NUMBRUSHES:
+      return -1;
+
+    case NUMPENS:
+      return pDevCaps->ulNumPens;
+
+    case NUMFONTS:
+      return pDevCaps->ulNumFonts;
+
+    case NUMCOLORS:
+      return pDevCaps->ulNumColors;
+
+    case ASPECTX:
+      return pDevCaps->ulAspectX;
+
+    case ASPECTY:
+      return pDevCaps->ulAspectY;
+
+    case ASPECTXY:
+      return pDevCaps->ulAspectXY;
+
+    case CLIPCAPS:
+      return CP_RECTANGLE;
+
+    case SIZEPALETTE:
+      return pDevCaps->ulSizePalette;
+
+    case NUMRESERVED:
+      return 20;
+
+    case COLORRES:
+      return pDevCaps->ulColorRes;
+
+    case DESKTOPVERTRES:
+      return pDevCaps->ulVertRes;
+
+    case DESKTOPHORZRES:
+      return pDevCaps->ulHorzRes;
+
+    case BLTALIGNMENT:
+      return pDevCaps->ulBltAlignment;
+
+    case SHADEBLENDCAPS:
+      return pDevCaps->ulShadeBlend;
+
+    case COLORMGMTCAPS:
+      return pDevCaps->ulColorMgmtCaps;
+
+    case PHYSICALWIDTH:
+      return pDevCaps->ulPhysicalWidth;
+
+    case PHYSICALHEIGHT:
+      return pDevCaps->ulPhysicalHeight;
+
+    case PHYSICALOFFSETX:
+      return pDevCaps->ulPhysicalOffsetX;
+
+    case PHYSICALOFFSETY:
+      return pDevCaps->ulPhysicalOffsetY;
+
+    case VREFRESH:
+      return pDevCaps->ulVRefresh;
+
+    case RASTERCAPS:
+      return pDevCaps->ulRasterCaps;
+
+    case CURVECAPS:
+      return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
+             CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
+
+    case LINECAPS:
+      return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+             LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
+
+    case POLYGONALCAPS:
+      return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
+             PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
+
+    case TEXTCAPS:
+      return pDevCaps->ulTextCaps;
+
+    case PDEVICESIZE:
+    case SCALINGFACTORX:
+    case SCALINGFACTORY:
+    default:
+      return 0;
+  }
+  return 0;
+}
 
 /*
  * @implemented
  */
 DWORD
-STDCALL
+WINAPI
 GetRelAbs(
          HDC  hdc,
          DWORD dwIgnore
@@ -469,8 +673,8 @@ GetRelAbs(
 /*
  * @implemented
  */
-DWORD
-STDCALL
+INT
+WINAPI
 SetRelAbs(
        HDC hdc,
        INT Mode
@@ -484,7 +688,7 @@ SetRelAbs(
  * @implemented
  */
 DWORD
-STDCALL
+WINAPI
 GetAndSetDCDWord( HDC hDC, INT u, DWORD dwIn, DWORD Unk1, DWORD Unk2, DWORD Unk3 )
 {
   BOOL Ret = TRUE;
@@ -523,7 +727,7 @@ GetAndSetDCDWord( HDC hDC, INT u, DWORD dwIn, DWORD Unk1, DWORD Unk2, DWORD Unk3
  * @implemented
  */
 DWORD
-STDCALL
+WINAPI
 GetDCDWord( HDC hDC, INT u, DWORD Result )
 {
   BOOL Ret = NtGdiGetDCDword( hDC, u, (DWORD*) &u );
@@ -536,7 +740,7 @@ GetDCDWord( HDC hDC, INT u, DWORD Result )
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 GetAspectRatioFilterEx(
                 HDC hdc,
                 LPSIZE lpAspectRatio
@@ -550,7 +754,7 @@ GetAspectRatioFilterEx(
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 GetDCOrgEx(
     HDC hdc,
     LPPOINT lpPoint
@@ -564,7 +768,7 @@ GetDCOrgEx(
  * @implemented
  */
 LONG
-STDCALL
+WINAPI
 GetDCOrg(
     HDC hdc
     )
@@ -626,14 +830,14 @@ GetNonFontObject(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
  * @implemented
  */
 int
-STDCALL
+WINAPI
 GetObjectA(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
 {
   ENUMLOGFONTEXDVW LogFont;
   DWORD dwType;
   INT Result = 0;
 
-  dwType = GDI_HANDLE_GET_TYPE(hGdiObj);;
+  dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
 
   if(dwType == GDI_OBJECT_TYPE_COLORSPACE) //Stays here, processes struct A
   {
@@ -692,7 +896,7 @@ GetObjectA(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
  * @implemented
  */
 int
-STDCALL
+WINAPI
 GetObjectW(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
 {
   DWORD dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
@@ -724,7 +928,7 @@ GetObjectW(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
     }
     // Poorly written apps are not ReactOS problem!
     // We fix it here if the size is larger than the default size.
-    if( cbSize > sizeof(ENUMLOGFONTEXDVW) ) cbSize = sizeof(ENUMLOGFONTEXDVW);
+    if( cbSize > (int)sizeof(ENUMLOGFONTEXDVW) ) cbSize = sizeof(ENUMLOGFONTEXDVW);
 
     Result = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer); // Should handle the copy.
 
@@ -743,29 +947,29 @@ GetObjectW(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
  * @implemented
  */
 COLORREF
-STDCALL
+WINAPI
 GetDCBrushColor(
        HDC hdc
 )
 {
   PDC_ATTR Dc_Attr;
 
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return CLR_INVALID;
-  return (COLORREF) Dc_Attr->ulPenClr;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return CLR_INVALID;
+  return (COLORREF) Dc_Attr->ulBrushClr;
 }
 
 /*
  * @implemented
  */
 COLORREF
-STDCALL
+WINAPI
 GetDCPenColor(
        HDC hdc
 )
 {
   PDC_ATTR Dc_Attr;
 
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return CLR_INVALID;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return CLR_INVALID;
   return (COLORREF) Dc_Attr->ulPenClr;
 }
 
@@ -773,7 +977,7 @@ GetDCPenColor(
  * @implemented
  */
 COLORREF
-STDCALL
+WINAPI
 SetDCBrushColor(
        HDC hdc,
        COLORREF crColor
@@ -782,7 +986,7 @@ SetDCBrushColor(
   PDC_ATTR Dc_Attr;
   COLORREF OldColor = CLR_INVALID;
 
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return OldColor;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
   else
   {
     OldColor = (COLORREF) Dc_Attr->ulBrushClr;
@@ -801,7 +1005,7 @@ SetDCBrushColor(
  * @implemented
  */
 COLORREF
-STDCALL
+WINAPI
 SetDCPenColor(
        HDC hdc,
        COLORREF crColor
@@ -810,7 +1014,7 @@ SetDCPenColor(
   PDC_ATTR Dc_Attr;
   COLORREF OldColor = CLR_INVALID;
 
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return OldColor;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
   else
   {
      OldColor = (COLORREF) Dc_Attr->ulPenClr;
@@ -830,11 +1034,11 @@ SetDCPenColor(
  *
  */
 COLORREF
-STDCALL
+WINAPI
 GetBkColor(HDC hdc)
 {
   PDC_ATTR Dc_Attr;
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
   return Dc_Attr->ulBackgroundClr;
 }
 
@@ -842,7 +1046,7 @@ GetBkColor(HDC hdc)
  * @implemented
  */
 COLORREF
-STDCALL
+WINAPI
 SetBkColor(
        HDC hdc,
        COLORREF crColor
@@ -851,7 +1055,7 @@ SetBkColor(
   PDC_ATTR Dc_Attr;
   COLORREF OldColor = CLR_INVALID;
 
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return OldColor;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
 #if 0
   if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
   {
@@ -867,7 +1071,7 @@ SetBkColor(
       }
       if (pLDC->iType == LDC_EMFLDC)
       {
-        if return EMFDRV_SetBkColor( hDC, crColor );
+        return EMFDRV_SetBkColor( hDC, crColor );
       }
     }
   }
@@ -877,7 +1081,7 @@ SetBkColor(
 
   if ( Dc_Attr->crBackgroundClr != crColor )
   {
-     Dc_Attr->ulDirty_ |= DIRTY_LINE;
+     Dc_Attr->ulDirty_ |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL);
      Dc_Attr->crBackgroundClr = crColor;
   }
   return OldColor;
@@ -888,11 +1092,11 @@ SetBkColor(
  *
  */
 int
-STDCALL
+WINAPI
 GetBkMode(HDC hdc)
 {
   PDC_ATTR Dc_Attr;
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
   return Dc_Attr->lBkMode;
 }
 
@@ -901,14 +1105,14 @@ GetBkMode(HDC hdc)
  *
  */
 int
-STDCALL
+WINAPI
 SetBkMode(HDC hdc,
               int iBkMode)
 {
   PDC_ATTR Dc_Attr;
   INT OldMode = 0;
 
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return OldMode;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldMode;
 #if 0
   if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
   {
@@ -924,7 +1128,7 @@ SetBkMode(HDC hdc,
       }
       if (pLDC->iType == LDC_EMFLDC)
       {
-        if return EMFDRV_SetBkMode( hdc, iBkMode )
+        return EMFDRV_SetBkMode( hdc, iBkMode )
       }
     }
   }
@@ -940,11 +1144,11 @@ SetBkMode(HDC hdc,
  *
  */
 int
-STDCALL
+WINAPI
 GetPolyFillMode(HDC hdc)
 {
   PDC_ATTR Dc_Attr;
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
   return Dc_Attr->lFillMode;
 }
 
@@ -952,7 +1156,7 @@ GetPolyFillMode(HDC hdc)
  * @unimplemented
  */
 int
-STDCALL
+WINAPI
 SetPolyFillMode(HDC hdc,
                 int iPolyFillMode)
 {
@@ -973,14 +1177,14 @@ SetPolyFillMode(HDC hdc,
       }
       if (pLDC->iType == LDC_EMFLDC)
       {
-        if return EMFDRV_SetPolyFillMode( hdc, iPolyFillMode )
+        return EMFDRV_SetPolyFillMode( hdc, iPolyFillMode )
       }
     }
   }
 #endif
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
 
-  if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
+  if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
   {
      if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
      {
@@ -1000,11 +1204,11 @@ SetPolyFillMode(HDC hdc,
  *
  */
 int
-STDCALL
+WINAPI
 GetGraphicsMode(HDC hdc)
 {
   PDC_ATTR Dc_Attr;
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
   return Dc_Attr->iGraphicsMode;
 }
 
@@ -1012,7 +1216,7 @@ GetGraphicsMode(HDC hdc)
  * @unimplemented
  */
 int
-STDCALL
+WINAPI
 SetGraphicsMode(HDC hdc,
                 int iMode)
 {
@@ -1023,11 +1227,11 @@ SetGraphicsMode(HDC hdc,
      SetLastError(ERROR_INVALID_PARAMETER);
      return 0;
   }
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
 
   if (iMode == Dc_Attr->iGraphicsMode) return iMode;
 
-  if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc)
+  if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
   {
      if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
      {
@@ -1035,6 +1239,11 @@ SetGraphicsMode(HDC hdc,
        Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
      }
   }
+/* One would think that setting the graphics mode to GM_COMPATIBLE
+ * would also reset the world transformation matrix to the unity
+ * matrix. However, in Windows, this is not the case. This doesn't
+ * make a lot of sense to me, but that's the way it is.
+ */
   oMode = Dc_Attr->iGraphicsMode;
   Dc_Attr->iGraphicsMode = iMode;
 
@@ -1045,7 +1254,7 @@ SetGraphicsMode(HDC hdc,
  * @implemented
  */
 HDC
-STDCALL
+WINAPI
 ResetDCW(
        HDC             hdc,
        CONST DEVMODEW  *lpInitData
@@ -1060,7 +1269,7 @@ ResetDCW(
  * @implemented
  */
 HDC
-STDCALL
+WINAPI
 ResetDCA(
        HDC             hdc,
        CONST DEVMODEA  *lpInitData
@@ -1076,25 +1285,11 @@ ResetDCA(
 }
 
 
-/*
- * @implemented
- */
-int
-STDCALL
-StartDocW(
-       HDC             hdc,
-       CONST DOCINFOW  *a1
-       )
-{
-       return NtGdiStartDoc ( hdc, (DOCINFOW *)a1, NULL, 0);
-}
-
-
 /*
  * @implemented
  */
 DWORD
-STDCALL
+WINAPI
 GetObjectType(
        HGDIOBJ h
        )
@@ -1185,86 +1380,13 @@ GetStockObject(
   return Ret;
 }
 
-
-BOOL
-STDCALL
-GetViewportExtEx(
-             HDC hdc,
-             LPSIZE lpSize
-                )
-{
-  PDC_ATTR Dc_Attr;
-
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
-
-  if ( Dc_Attr->flXform & PAGE_EXTENTS_CHANGED ) // Something was updated, go to kernel.
-     return NtGdiGetDCPoint( hdc, GdiGetViewPortExt, (LPPOINT) lpSize );
-  else
-  {
-     lpSize->cx = Dc_Attr->szlViewportExt.cx;
-     lpSize->cy = Dc_Attr->szlViewportExt.cy;
-  }
-  return TRUE;
-}
-
-
-BOOL
-STDCALL
-GetViewportOrgEx(
-             HDC hdc,
-             LPPOINT lpPoint
-                )
-{
-  PDC_ATTR Dc_Attr;
-
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
-  lpPoint->x = Dc_Attr->ptlViewportOrg.x;
-  lpPoint->x = Dc_Attr->ptlViewportOrg.x;
-  return TRUE;
-  // return NtGdiGetDCPoint( hdc, GdiGetViewPortOrg, lpPoint );
-}
-
-
-BOOL
-STDCALL
-GetWindowExtEx(
-           HDC hdc,
-           LPSIZE lpSize
-              )
-{
-  PDC_ATTR Dc_Attr;
-
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
-  lpSize->cx = Dc_Attr->szlWindowExt.cx;
-  lpSize->cy = Dc_Attr->szlWindowExt.cy;
-  return TRUE;
-  // return NtGdiGetDCPoint( hdc, GdiGetWindowExt, (LPPOINT) lpSize );
-}
-
-
-BOOL
-STDCALL
-GetWindowOrgEx(
-           HDC hdc,
-           LPPOINT lpPoint
-              )
-{
-  PDC_ATTR Dc_Attr;
-
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return FALSE;
-  lpPoint->x = Dc_Attr->ptlWindowOrg.x;
-  lpPoint->x = Dc_Attr->ptlWindowOrg.x;
-  return TRUE;
-  //return NtGdiGetDCPoint( hdc, GdiGetWindowOrg, lpPoint );
-}
-
 /* FIXME: include correct header */
-HPALETTE STDCALL NtUserSelectPalette(HDC  hDC,
+HPALETTE WINAPI NtUserSelectPalette(HDC  hDC,
                             HPALETTE  hpal,
                             BOOL  ForceBackground);
 
 HPALETTE
-STDCALL
+WINAPI
 SelectPalette(
     HDC hDC,
     HPALETTE hPal,
@@ -1281,7 +1403,7 @@ SelectPalette(
       if ( !pLDC )
       {
          SetLastError(ERROR_INVALID_HANDLE);
-         return FALSE;
+         return NULL;
       }
       if (pLDC->iType == LDC_EMFLDC)
       {
@@ -1298,11 +1420,11 @@ SelectPalette(
  *
  */
 int
-STDCALL
+WINAPI
 GetMapMode(HDC hdc)
 {
   PDC_ATTR Dc_Attr;
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
   return Dc_Attr->iMapMode;
 }
 
@@ -1310,14 +1432,14 @@ GetMapMode(HDC hdc)
  * @implemented
  */
 INT
-STDCALL
+WINAPI
 SetMapMode(
        HDC hdc,
        INT Mode
        )
 {
   PDC_ATTR Dc_Attr;
-  if (!GdiGetHandleUserData((HGDIOBJ) hdc, (PVOID) &Dc_Attr)) return 0;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
 #if 0
   if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
   {
@@ -1326,11 +1448,176 @@ SetMapMode(
     else
     {
       SetLastError(ERROR_INVALID_HANDLE);
-      return FALSE;
+      return 0;
     }
 #endif
-  if ((Mode == Dc_Attr->iMapMode) && (Mode != MM_ISOTROPIC)) return Mode;
-  return GetAndSetDCDWord( hdc, GdiGetSetMapMode, Mode, 0, 0, 0 );
+  // Force change if Isotropic is set for recompute.
+  if ((Mode != Dc_Attr->iMapMode) || (Mode == MM_ISOTROPIC))
+  {
+      Dc_Attr->ulDirty_ &= ~SLOW_WIDTHS;
+      return GetAndSetDCDWord( hdc, GdiGetSetMapMode, Mode, 0, 0, 0 );
+  }
+  return Dc_Attr->iMapMode;
 }
 
+/*
+ * @implemented
+ *
+ */
+int
+WINAPI
+GetStretchBltMode(HDC hdc)
+{
+  PDC_ATTR Dc_Attr;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
+  return Dc_Attr->lStretchBltMode;
+}
 
+/*
+ * @implemented
+ */
+int
+WINAPI
+SetStretchBltMode(HDC hdc, int iStretchMode)
+{
+  INT oSMode;
+  PDC_ATTR Dc_Attr;
+#if 0
+  if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
+  {
+    if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
+      return MFDRV_SetStretchBltMode( hdc, iStretchMode);
+    else
+    {
+      PLDC pLDC = GdiGetLDC(hdc);
+      if ( !pLDC )
+      {
+         SetLastError(ERROR_INVALID_HANDLE);
+         return 0;
+      }
+      if (pLDC->iType == LDC_EMFLDC)
+      {
+        return EMFDRV_SetStretchBltMode( hdc, iStretchMode);
+      }
+    }
+  }
+#endif
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
+
+  oSMode = Dc_Attr->lStretchBltMode;
+  Dc_Attr->lStretchBltMode = iStretchMode;
+
+  // Wine returns an error here. We set the default.
+  if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK;
+
+  Dc_Attr->jStretchBltMode = iStretchMode;
+
+  return oSMode;
+}
+
+/*
+ * @implemented
+ */
+HFONT
+WINAPI
+GetHFONT(HDC hdc)
+{
+  PDC_ATTR Dc_Attr;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return NULL;
+  return Dc_Attr->hlfntNew;
+}
+
+
+/*
+ * @implemented
+ *
+ */
+HGDIOBJ
+WINAPI
+SelectObject(HDC hDC,
+             HGDIOBJ hGdiObj)
+{
+    PDC_ATTR pDc_Attr;
+    HGDIOBJ hOldObj = NULL;
+    UINT uType;
+
+    if(!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
+    {
+       SetLastError(ERROR_INVALID_HANDLE);
+        return NULL;
+    }
+
+    hGdiObj = GdiFixUpHandle(hGdiObj);
+    if (!GdiIsHandleValid(hGdiObj))
+    {
+        return NULL;
+    }
+
+    uType = GDI_HANDLE_GET_TYPE(hGdiObj);
+
+    switch (uType)
+    {
+        case GDI_OBJECT_TYPE_REGION:
+            return (HGDIOBJ)ExtSelectClipRgn(hDC, hGdiObj, RGN_COPY);
+
+        case GDI_OBJECT_TYPE_BITMAP:
+            return NtGdiSelectBitmap(hDC, hGdiObj);
+
+        case GDI_OBJECT_TYPE_BRUSH:
+            hOldObj = pDc_Attr->hbrush;
+            pDc_Attr->ulDirty_ |= DC_BRUSH_DIRTY;
+            pDc_Attr->hbrush = hGdiObj;
+            return hOldObj;
+//            return NtGdiSelectBrush(hDC, hGdiObj);
+
+        case GDI_OBJECT_TYPE_PEN:
+        case GDI_OBJECT_TYPE_EXTPEN:
+            hOldObj = pDc_Attr->hpen;
+            pDc_Attr->ulDirty_ |= DC_PEN_DIRTY;
+            pDc_Attr->hpen = hGdiObj;
+            return hOldObj;
+//            return NtGdiSelectPen(hDC, hGdiObj);
+
+        case GDI_OBJECT_TYPE_FONT:
+            hOldObj = pDc_Attr->hlfntNew;
+            if (hOldObj == hGdiObj) return hOldObj;
+
+            pDc_Attr->ulDirty_ &= ~SLOW_WIDTHS;
+            pDc_Attr->ulDirty_ |= DIRTY_CHARSET;
+            pDc_Attr->hlfntNew = hGdiObj;
+
+            if (!(pDc_Attr->ulDirty_ & DC_DIBSECTION))
+            {
+                PGDIBSOBJECT pgO;
+
+                pgO = GdiAllocBatchCommand(hDC, GdiBCSelObj);
+                if (pgO)
+                {
+                    pgO->hgdiobj = hGdiObj;
+                    return hOldObj;
+                }
+            }
+
+            // default for select object font
+            return NtGdiSelectFont(hDC, hGdiObj);
+
+#if 0
+        case GDI_OBJECT_TYPE_METADC:
+            return MFDRV_SelectObject( hDC, hGdiObj); 
+        case GDI_OBJECT_TYPE_EMF:
+            PLDC pLDC = GdiGetLDC(hDC);
+            if ( !pLDC ) return NULL;
+            return EMFDRV_SelectObject( hDC, hGdiObj);
+#endif
+        case GDI_OBJECT_TYPE_COLORSPACE:
+            SetColorSpace(hDC, (HCOLORSPACE) hGdiObj);
+            return NULL;
+
+        case GDI_OBJECT_TYPE_PALETTE:
+        default:
+            SetLastError(ERROR_INVALID_FUNCTION);
+            return NULL;
+    }
+
+    return NULL;
+}