/* * @implemented */ BOOL WINAPI CancelDC(HDC hDC) { PDC_ATTR pDc_Attr; if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC && GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_METADC ) { PLDC pLDC = GdiGetLDC(hDC); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } /* If a document has started set it to die. */ if (pLDC->Flags & LDC_INIT_DOCUMENT) pLDC->Flags |= LDC_KILL_DOCUMENT; return NtGdiCancelDC(hDC); } if (GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &pDc_Attr)) { pDc_Attr->ulDirty_ &= ~DC_PLAYMETAFILE; return TRUE; } return FALSE; }
/* * @implemented * */ BOOL WINAPI GetCurrentPositionEx(HDC hdc, LPPOINT lpPoint) { PDC_ATTR Dc_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; if ( lpPoint ) { if ( Dc_Attr->ulDirty_ & DIRTY_PTLCURRENT ) // have a hit! { lpPoint->x = Dc_Attr->ptfxCurrent.x; lpPoint->y = Dc_Attr->ptfxCurrent.y; DPtoLP ( hdc, lpPoint, 1); // reconvert back. Dc_Attr->ptlCurrent.x = lpPoint->x; // save it Dc_Attr->ptlCurrent.y = lpPoint->y; Dc_Attr->ulDirty_ &= ~DIRTY_PTLCURRENT; // clear bit } else { lpPoint->x = Dc_Attr->ptlCurrent.x; lpPoint->y = Dc_Attr->ptlCurrent.y; } } else { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } return TRUE; }
/* * @implemented */ BOOL WINAPI SetBrushOrgEx(HDC hdc, int nXOrg, int nYOrg, LPPOINT lppt) { PDC_ATTR Dc_Attr; #if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) { PLDC pLDC = GdiGetLDC(hdc); if ( (pLDC == NULL) || (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_SetBrushOrg(hdc, nXOrg, nYOrg); // ReactOS only. } return FALSE; } #endif if (GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID)&Dc_Attr)) { PGDIBSSETBRHORG pgSBO; /* Does the caller want the current brush origin to be returned? */ if (lppt) { lppt->x = Dc_Attr->ptlBrushOrigin.x; lppt->y = Dc_Attr->ptlBrushOrigin.y; } /* Check if we have nothing to do */ if ((nXOrg == Dc_Attr->ptlBrushOrigin.x) && (nYOrg == Dc_Attr->ptlBrushOrigin.y)) return TRUE; /* Allocate a batch command buffer */ pgSBO = GdiAllocBatchCommand(hdc, GdiBCSetBrushOrg); if (pgSBO != NULL) { /* Set current brush origin in the DC attribute */ Dc_Attr->ptlBrushOrigin.x = nXOrg; Dc_Attr->ptlBrushOrigin.y = nYOrg; /* Setup the GDI batch command */ pgSBO->ptlBrushOrigin = Dc_Attr->ptlBrushOrigin; return TRUE; } } /* Fall back to the slower kernel path */ return NtGdiSetBrushOrg(hdc, nXOrg, nYOrg, lppt); }
/* * @unimplemented */ BOOL WINAPI SetViewportExtEx(HDC hdc, int nXExtent, int nYExtent, LPSIZE lpSize) { 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_SetViewportExtEx(); else { PLDC pLDC = GdiGetLDC(hdc); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_SetViewportExtEx(); } } } #endif if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) { return FALSE; } if (lpSize) { lpSize->cx = Dc_Attr->szlViewportExt.cx; lpSize->cy = Dc_Attr->szlViewportExt.cy; } if ((Dc_Attr->szlViewportExt.cx == nXExtent) && (Dc_Attr->szlViewportExt.cy == nYExtent)) return TRUE; if ((Dc_Attr->iMapMode == MM_ISOTROPIC) || (Dc_Attr->iMapMode == MM_ANISOTROPIC)) { if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) { if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY) { NtGdiFlush(); // Sync up Dc_Attr from Kernel space. Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY); } } Dc_Attr->szlViewportExt.cx = nXExtent; Dc_Attr->szlViewportExt.cy = nYExtent; if (Dc_Attr->dwLayout & LAYOUT_RTL) NtGdiMirrorWindowOrg(hdc); Dc_Attr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID); } return TRUE; }
/* * @implemented * */ int WINAPI GetROP2(HDC hdc) { PDC_ATTR Dc_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0; return Dc_Attr->jROP2; }
/* * @unimplemented */ BOOL WINAPI SetWindowOrgEx(HDC hdc, int X, int Y, LPPOINT lpPoint) { #if 0 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_SetWindowOrgEx(); else { PLDC pLDC = GdiGetLDC(hdc); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_SetWindowOrgEx(); } } } #endif if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; if (lpPoint) { lpPoint->x = Dc_Attr->ptlWindowOrg.x; lpPoint->y = Dc_Attr->ptlWindowOrg.y; } if ((Dc_Attr->ptlWindowOrg.x == X) && (Dc_Attr->ptlWindowOrg.y == Y)) return TRUE; if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc) { if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY) { NtGdiFlush(); // Sync up Dc_Attr from Kernel space. Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY); } } Dc_Attr->ptlWindowOrg.x = X; Dc_Attr->lWindowOrgx = X; Dc_Attr->ptlWindowOrg.y = Y; if (Dc_Attr->dwLayout & LAYOUT_RTL) NtGdiMirrorWindowOrg(hdc); Dc_Attr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID); return TRUE; #endif return NtGdiSetWindowOrgEx(hdc,X,Y,lpPoint); }
/* * @implemented */ DWORD WINAPI GetLayout(HDC hdc ) { PDC_ATTR Dc_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return GDI_ERROR; return Dc_Attr->dwLayout; }
/* * @implemented */ DWORD WINAPI GdiGetCodePage(HDC hdc) { PDC_ATTR Dc_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0; if (Dc_Attr->ulDirty_ & DIRTY_CHARSET) return LOWORD(NtGdiGetCharSet(hdc)); return LOWORD(Dc_Attr->iCS_CP); }
/* * @implemented * */ BOOL WINAPI OffsetWindowOrgEx(HDC hdc, int nXOffset, int nYOffset, LPPOINT lpPoint) { #if 0 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_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint); else { PLDC pLDC = GdiGetLDC(hdc); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint); } } } #endif if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; if ( lpPoint ) { *lpPoint = (POINT)Dc_Attr->ptlWindowOrg; lpPoint->x = Dc_Attr->lWindowOrgx; } if ( nXOffset || nYOffset != nXOffset ) { if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc) { if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY) { NtGdiFlush(); Dc_Attr->ulDirty_ &= ~DC_MODE_DIRTY; } } Dc_Attr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID); Dc_Attr->ptlWindowOrg.x += nXOffset; Dc_Attr->ptlWindowOrg.y += nYOffset; Dc_Attr->lWindowOrgx += nXOffset; } return TRUE; #endif return NtGdiOffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint); }
/* * @implemented */ HCOLORSPACE WINAPI GetColorSpace(HDC hDC) { PDC_ATTR pDc_Attr; if (!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr)) { SetLastError(ERROR_INVALID_HANDLE); return NULL; } return pDc_Attr->hColorSpace; }
/* * @implemented * */ BOOL WINAPI GetBrushOrgEx(HDC hdc,LPPOINT pt) { PDC_ATTR Dc_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; if (pt) { pt->x = Dc_Attr->ptlBrushOrigin.x; pt->y = Dc_Attr->ptlBrushOrigin.y; } return TRUE; }
BOOL WINAPI GetWindowOrgEx( HDC hdc, LPPOINT lpPoint ) { PDC_ATTR Dc_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; lpPoint->x = Dc_Attr->ptlWindowOrg.x; lpPoint->y = Dc_Attr->ptlWindowOrg.y; return TRUE; //return NtGdiGetDCPoint( hdc, GdiGetWindowOrg, lpPoint ); }
BOOL WINAPI GetViewportOrgEx( HDC hdc, LPPOINT lpPoint ) { PDC_ATTR Dc_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; lpPoint->x = Dc_Attr->ptlViewportOrg.x; lpPoint->y = Dc_Attr->ptlViewportOrg.y; if (Dc_Attr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x; return TRUE; // return NtGdiGetDCPoint( hdc, GdiGetViewPortOrg, lpPoint ); }
BOOL WINAPI GetWindowExtEx( HDC hdc, LPSIZE lpSize ) { PDC_ATTR Dc_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; lpSize->cx = Dc_Attr->szlWindowExt.cx; lpSize->cy = Dc_Attr->szlWindowExt.cy; if (Dc_Attr->dwLayout & LAYOUT_RTL) lpSize->cx = -lpSize->cx; return TRUE; // return NtGdiGetDCPoint( hdc, GdiGetWindowExt, (LPPOINT) lpSize ); }
/* * @implemented */ int WINAPI SetROP2(HDC hdc, int fnDrawMode) { PDC_ATTR Dc_Attr; INT Old_ROP2; #if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) { if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC) return MFDRV_SetROP2( hdc, fnDrawMode); else { PLDC pLDC = GdiGetLDC(hdc); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_SetROP2(( hdc, fnDrawMode); } return FALSE; } } #endif if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) { if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY) { NtGdiFlush(); Dc_Attr->ulDirty_ &= ~DC_MODE_DIRTY; } } Old_ROP2 = Dc_Attr->jROP2; Dc_Attr->jROP2 = fnDrawMode; return Old_ROP2; }
HBITMAP WINAPI CreateCompatibleBitmap( HDC hDC, INT Width, INT Height) { PDC_ATTR pDc_Attr; if (!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr)) return NULL; if (!Width || !Height) return GetStockObject(DEFAULT_BITMAP); if (!(pDc_Attr->ulDirty_ & DC_DIBSECTION)) { return NtGdiCreateCompatibleBitmap(hDC, Width, Height); } else { HBITMAP hBmp = NULL; struct { BITMAP bitmap; BITMAPINFOHEADER bmih; RGBQUAD rgbquad[256]; } buffer; DIBSECTION* pDIBs = (DIBSECTION*) &buffer; BITMAPINFO* pbmi = (BITMAPINFO*) &buffer.bmih; hBmp = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_BITMAP); if (GetObjectA(hBmp, sizeof(DIBSECTION), pDIBs) != sizeof(DIBSECTION)) return NULL; if (pDIBs->dsBm.bmBitsPixel <= 8) GetDIBColorTable(hDC, 0, 256, buffer.rgbquad); pDIBs->dsBmih.biWidth = Width; pDIBs->dsBmih.biHeight = Height; return CreateDIBSection(hDC, pbmi, DIB_RGB_COLORS, NULL, NULL, 0); } return NULL; }
/* * @unimplemented */ BOOL WINAPI SetViewportOrgEx(HDC hdc, int X, int Y, LPPOINT lpPoint) { #if 0 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_SetViewportOrgEx(); else { PLDC pLDC = GdiGetLDC(hdc); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_SetViewportOrgEx(); } } } #endif if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; if (lpPoint) { lpPoint->x = Dc_Attr->ptlViewportOrg.x; lpPoint->y = Dc_Attr->ptlViewportOrg.y; if (Dc_Attr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x; } Dc_Attr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID); if (Dc_Attr->dwLayout & LAYOUT_RTL) X = -X; Dc_Attr->ptlViewportOrg.x = X; Dc_Attr->ptlViewportOrg.y = Y; return TRUE; #endif return NtGdiSetViewportOrgEx(hdc,X,Y,lpPoint); }
BOOL WINAPI ModifyWorldTransform( HDC hDC, CONST XFORM *Xform, DWORD iMode ) { #if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC) { if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC) return FALSE; else { PLDC pLDC = GdiGetLDC(hDC); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (pLDC->iType == LDC_EMFLDC) { if (iMode == MWT_MAX+1) if (!EMFDRV_SetWorldTransform( hDC, Xform) ) return FALSE; return EMFDRV_ModifyWorldTransform( hDC, Xform, iMode); // Ported from wine. } return FALSE; } } #endif PDC_ATTR Dc_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; /* Check that graphics mode is GM_ADVANCED */ if ( Dc_Attr->iGraphicsMode != GM_ADVANCED ) return FALSE; return NtGdiModifyWorldTransform(hDC, (CONST LPXFORM) Xform, iMode); }
BOOL WINAPI GetViewportExtEx( HDC hdc, LPSIZE lpSize ) { PDC_ATTR Dc_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; if ((Dc_Attr->flXform & PAGE_EXTENTS_CHANGED) && (Dc_Attr->iMapMode == MM_ISOTROPIC)) // Something was updated, go to kernel. return NtGdiGetDCPoint( hdc, GdiGetViewPortExt, (PPOINTL) lpSize ); else { lpSize->cx = Dc_Attr->szlViewportExt.cx; lpSize->cy = Dc_Attr->szlViewportExt.cy; } return TRUE; }
/* * @implemented */ HDC WINAPI CreateCompatibleDC( _In_ HDC hdc) { HDC hdcNew; // PDC_ATTR pdcattr; hdcNew = NtGdiCreateCompatibleDC(hdc); #if 0 if ( hdc && hdcNew) { if (GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID*)&pdcattr)) { if (pdcattr->pvLIcm) IcmCompatibleDC(hdcNew, hdc, pdcattr); } } #endif return hdcNew; }
/* * I thought it was okay to have this in DeleteObject but~ Speed. (jt) */ BOOL FASTCALL DeleteRegion( _In_ HRGN hrgn) { #if 0 PRGN_ATTR Rgn_Attr; if ((GdiGetHandleUserData(hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) && ( Rgn_Attr != NULL )) { PGDIBSOBJECT pgO; pgO = GdiAllocBatchCommand(NULL, GdiBCDelRgn); if (pgO) { pgO->hgdiobj = hrgn; return TRUE; } } #endif return NtGdiDeleteObjectApp(hrgn); }
/* * @implemented */ HPEN WINAPI CreatePen( int nPenStyle, int nWidth, COLORREF crColor) { /* HPEN hPen; PBRUSH_ATTR Pen_Attr; */ if (nPenStyle < PS_SOLID) nPenStyle = PS_SOLID; if (nPenStyle > PS_DASHDOTDOT) { if (nPenStyle == PS_NULL) return GetStockObject(NULL_PEN); if (nPenStyle != PS_INSIDEFRAME) nPenStyle = PS_SOLID; } #if 0 hPen = hGetPEBHandle(hctPenHandle, nPenStyle); if ( nWidth || nPenStyle || !hPen ) { return NtGdiCreatePen(nPenStyle, nWidth, crColor, NULL); } if ((GdiGetHandleUserData( hPen, GDI_OBJECT_TYPE_PEN, (PVOID) &Pen_Attr)) && ( Pen_Attr != NULL )) { if ( Pen_Attr->lbColor != crColor) { Pen_Attr->lbColor = crColor; Pen_Attr->AttrFlags |= ATTR_NEW_COLOR; } return hPen; } DeleteObject(hPen); #endif return NtGdiCreatePen(nPenStyle, nWidth, crColor, NULL); }
/* * @unimplemented */ int WINAPI StretchDIBits( HDC hdc, int XDest, int YDest, int nDestWidth, int nDestHeight, int XSrc, int YSrc, int nSrcWidth, int nSrcHeight, CONST VOID *lpBits, CONST BITMAPINFO *lpBitsInfo, UINT iUsage, DWORD dwRop) { PDC_ATTR pDc_Attr; PBITMAPINFO pConvertedInfo = NULL; UINT ConvertedInfoSize = 0; INT LinesCopied = 0; UINT cjBmpScanSize = 0; PVOID pvSafeBits = NULL; BOOL Hit = FALSE; DPRINT("StretchDIBits %p : %p : %u\n", lpBits, lpBitsInfo, iUsage); #if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) { if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC) return MFDRV_StretchBlt( hdc, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, nSrcWidth, nSrcHeight, lpBits, lpBitsInfo, iUsage, dwRop); else { PLDC pLDC = GdiGetLDC(hdc); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return 0; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_StretchBlt(hdc, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, nSrcWidth, nSrcHeight, lpBits, lpBitsInfo, iUsage, dwRop); } return 0; } } #endif pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage, &ConvertedInfoSize, FALSE); if (!pConvertedInfo) { return 0; } cjBmpScanSize = GdiGetBitmapBitsSize((BITMAPINFO *) pConvertedInfo); if (lpBits) { pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize); if (pvSafeBits) { _SEH2_TRY { RtlCopyMemory(pvSafeBits, lpBits, cjBmpScanSize); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Hit = TRUE; } _SEH2_END if (Hit) { // We don't die, we continue on with a allocated safe pointer to kernel // space..... DPRINT1("StretchDIBits fail to read BitMapInfo: %p or Bits: %p & Size: %u\n", pConvertedInfo, lpBits, cjBmpScanSize); } DPRINT("StretchDIBits Allocate Bits %u!!!\n", cjBmpScanSize); } } if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr)) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } /* if ( !pDc_Attr || iUsage == DIB_PAL_COLORS || ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/ { LinesCopied = NtGdiStretchDIBitsInternal(hdc, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, nSrcWidth, nSrcHeight, pvSafeBits, pConvertedInfo, (DWORD) iUsage, dwRop, ConvertedInfoSize, cjBmpScanSize, NULL); } if (pvSafeBits) RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits); if (lpBitsInfo != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); return LinesCopied; }
/* * @implemented * */ INT WINAPI SetDIBitsToDevice( HDC hdc, int XDest, int YDest, DWORD Width, DWORD Height, int XSrc, int YSrc, UINT StartScan, UINT ScanLines, CONST VOID *Bits, CONST BITMAPINFO *lpbmi, UINT ColorUse) { PDC_ATTR pDc_Attr; PBITMAPINFO pConvertedInfo; UINT ConvertedInfoSize; INT LinesCopied = 0; UINT cjBmpScanSize = 0; BOOL Hit = FALSE; PVOID pvSafeBits = (PVOID) Bits; if (!ScanLines || !lpbmi || !Bits) return 0; if (ColorUse && ColorUse != DIB_PAL_COLORS && ColorUse != DIB_PAL_COLORS + 1) return 0; pConvertedInfo = ConvertBitmapInfo(lpbmi, ColorUse, &ConvertedInfoSize, FALSE); if (!pConvertedInfo) return 0; #if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) { if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC) return MFDRV_SetDIBitsToDevice( hdc, XDest, YDest, Width, Height, XSrc, YSrc, StartScan, ScanLines, Bits, lpbmi, ColorUse); else { PLDC pLDC = GdiGetLDC(hdc); if ( !pLDC ) { SetLastError(ERROR_INVALID_HANDLE); return 0; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_SetDIBitsToDevice(hdc, XDest, YDest, Width, Height, XSrc, YSrc, StartScan, ScanLines, Bits, lpbmi, ColorUse); } return 0; } } #endif if ((pConvertedInfo->bmiHeader.biCompression == BI_RLE8) || (pConvertedInfo->bmiHeader.biCompression == BI_RLE4)) { /* For compressed data, we must set the whole thing */ StartScan = 0; ScanLines = pConvertedInfo->bmiHeader.biHeight; } cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO) lpbmi, ScanLines); pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize); if (pvSafeBits) { _SEH2_TRY { RtlCopyMemory(pvSafeBits, Bits, cjBmpScanSize); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Hit = TRUE; } _SEH2_END if (Hit) { // We don't die, we continue on with a allocated safe pointer to kernel // space..... DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %p or Bits: %p & Size: %u\n", pConvertedInfo, Bits, cjBmpScanSize); } DPRINT("SetDIBitsToDevice Allocate Bits %u!!!\n", cjBmpScanSize); } if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr)) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } /* if ( !pDc_Attr || // DC is Public ColorUse == DIB_PAL_COLORS || ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/ { LinesCopied = NtGdiSetDIBitsToDeviceInternal(hdc, XDest, YDest, Width, Height, XSrc, YSrc, StartScan, ScanLines, (LPBYTE) pvSafeBits, (LPBITMAPINFO) pConvertedInfo, ColorUse, cjBmpScanSize, ConvertedInfoSize, TRUE, NULL); } if (Bits != pvSafeBits) RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits); if (lpbmi != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); return LinesCopied; }
HDC FASTCALL IntCreateDICW( LPCWSTR lpwszDriver, LPCWSTR lpwszDevice, LPCWSTR lpwszOutput, PDEVMODEW lpInitData, ULONG iType) { UNICODE_STRING Device, Output; HDC hdc = NULL; BOOL Display = FALSE, Default = FALSE; ULONG UMdhpdev = 0; HANDLE hspool = NULL; if ( !ghSpooler && !LoadTheSpoolerDrv()) { DPRINT1("WinSpooler.Drv Did not load!\n"); } else { DPRINT("WinSpooler.Drv Loaded! hMod -> 0x%p\n", ghSpooler); } if ((!lpwszDevice) && (!lpwszDriver)) { Default = TRUE; // Ask Win32k to set Default device. Display = TRUE; // Most likely to be DISPLAY. } else { if ((lpwszDevice) && (wcslen(lpwszDevice) != 0)) // First { if (!_wcsnicmp(lpwszDevice, L"\\\\.\\DISPLAY",11)) Display = TRUE; RtlInitUnicodeString(&Device, lpwszDevice); } else { if (lpwszDriver) // Second { if ((!_wcsnicmp(lpwszDriver, L"DISPLAY",7)) || (!_wcsnicmp(lpwszDriver, L"\\\\.\\DISPLAY",11))) Display = TRUE; RtlInitUnicodeString(&Device, lpwszDriver); } } } if (lpwszOutput) RtlInitUnicodeString(&Output, lpwszOutput); if (!Display) { //Handle Print device or something else. DPRINT1("Not a DISPLAY device! %wZ\n", &Device); } hdc = NtGdiOpenDCW((Default ? NULL : &Device), (PDEVMODEW) lpInitData, (lpwszOutput ? &Output : NULL), iType, // DCW 0 and ICW 1. Display, hspool, (PVOID) &UMdhpdev ); #if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) { PDC_ATTR Dc_Attr; PLDC pLDC; GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID*)&Dc_Attr); pLDC = LocalAlloc(LMEM_ZEROINIT, sizeof(LDC)); Dc_Attr->pvLDC = pLDC; pLDC->hDC = hdc; pLDC->iType = LDC_LDC; // 1 (init) local DC, 2 EMF LDC DbgPrint("DC_ATTR Allocated -> 0x%x\n",Dc_Attr); } #endif return hdc; }
/* * @implemented */ INT WINAPI ExtSelectClipRgn( _In_ HDC hdc, _In_ HRGN hrgn, _In_ INT iMode) { INT Ret; HRGN NewRgn = NULL; HANDLE_METADC(INT, ExtSelectClipRgn, 0, hdc, hrgn, iMode); #if 0 if ( hrgn ) { if ( GetLayout(hdc) & LAYOUT_RTL ) { if ( MirrorRgnDC(hdc, hrgn, &NewRgn) ) { if ( NewRgn ) hrgn = NewRgn; } } } #endif /* Batch handles RGN_COPY only! */ if (iMode == RGN_COPY) { #if 0 PDC_ATTR pDc_Attr; PRGN_ATTR pRgn_Attr = NULL; /* hrgn can be NULL unless the RGN_COPY mode is specified. */ if (hrgn) GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr); if ( GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &pDc_Attr) && pDc_Attr ) { PGDI_TABLE_ENTRY pEntry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hdc); PTEB pTeb = NtCurrentTeb(); if ( pTeb->Win32ThreadInfo != NULL && pTeb->GdiTebBatch.HDC == hdc && !(pDc_Attr->ulDirty_ & DC_DIBSECTION) && !(pEntry->Flags & GDI_ENTRY_VALIDATE_VIS) ) { if (!hrgn || (hrgn && pRgn_Attr && pRgn_Attr->iComplexity <= SIMPLEREGION) ) { if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSEXTSELCLPRGN)) <= GDIBATCHBUFSIZE) { // FIXME: This is broken, use GdiAllocBatchCommand! PGDIBSEXTSELCLPRGN pgO = (PGDIBSEXTSELCLPRGN)(&pTeb->GdiTebBatch.Buffer[0] + pTeb->GdiTebBatch.Offset); pgO->gbHdr.Cmd = GdiBCExtSelClipRgn; pgO->gbHdr.Size = sizeof(GDIBSEXTSELCLPRGN); pgO->fnMode = iMode; if ( hrgn && pRgn_Attr ) { Ret = pRgn_Attr->iComplexity; if ( pDc_Attr->VisRectRegion.Rect.left >= pRgn_Attr->Rect.right || pDc_Attr->VisRectRegion.Rect.top >= pRgn_Attr->Rect.bottom || pDc_Attr->VisRectRegion.Rect.right <= pRgn_Attr->Rect.left || pDc_Attr->VisRectRegion.Rect.bottom <= pRgn_Attr->Rect.top ) Ret = NULLREGION; pgO->left = pRgn_Attr->Rect.left; pgO->top = pRgn_Attr->Rect.top; pgO->right = pRgn_Attr->Rect.right; pgO->bottom = pRgn_Attr->Rect.bottom; } else { Ret = pDc_Attr->VisRectRegion.Flags; pgO->fnMode |= 0x80000000; // Set no hrgn mode. } pTeb->GdiTebBatch.Offset += sizeof(GDIBSEXTSELCLPRGN); pTeb->GdiBatchCount++; if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush(); if ( NewRgn ) DeleteObject(NewRgn); return Ret; } } } } #endif } Ret = NtGdiExtSelectClipRgn(hdc, hrgn, iMode); if ( NewRgn ) DeleteObject(NewRgn); return Ret; }
/* * @implemented */ HRGN WINAPI CreateRectRgn(int x1, int y1, int x2, int y2) { PRGN_ATTR pRgn_Attr; HRGN hrgn; int tmp; /// <- //// Remove when Brush/Pen/Rgn Attr is ready! return NtGdiCreateRectRgn(x1,y1,x2,y2); //// /* Normalize points */ tmp = x1; if ( x1 > x2 ) { x1 = x2; x2 = tmp; } tmp = y1; if ( y1 > y2 ) { y1 = y2; y2 = tmp; } /* Check outside 24 bit limit for universal set. Chp 9 Areas, pg 560.*/ if ( x1 < -(1<<27) || y1 < -(1<<27) || x2 > (1<<27)-1 || y2 > (1<<27)-1 ) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; } hrgn = hGetPEBHandle(hctRegionHandle, 0); if (!hrgn) hrgn = NtGdiCreateRectRgn(0, 0, 1, 1); if (!hrgn) return hrgn; if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr)) { DPRINT1("No Attr for Region handle!!!\n"); DeleteRegion(hrgn); return NULL; } if (( x1 == x2) || (y1 == y2)) { pRgn_Attr->iComplexity = NULLREGION; pRgn_Attr->Rect.left = pRgn_Attr->Rect.top = pRgn_Attr->Rect.right = pRgn_Attr->Rect.bottom = 0; } else { pRgn_Attr->iComplexity = SIMPLEREGION; pRgn_Attr->Rect.left = x1; pRgn_Attr->Rect.top = y1; pRgn_Attr->Rect.right = x2; pRgn_Attr->Rect.bottom = y2; } pRgn_Attr->AttrFlags = (ATTR_RGN_DIRTY|ATTR_RGN_VALID); return hrgn; }
/* * @implemented */ BOOL WINAPI SetBrushOrgEx(HDC hdc, int nXOrg, int nYOrg, LPPOINT lppt) { PDC_ATTR Dc_Attr; #if 0 // Handle something other than a normal dc object. if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) { PLDC pLDC = GdiGetLDC(hdc); if ( (pLDC == NULL) || (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (pLDC->iType == LDC_EMFLDC) { return EMFDRV_SetBrushOrg(hdc, nXOrg, nYOrg); // ReactOS only. } return FALSE; } #endif if (GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) { PTEB pTeb = NtCurrentTeb(); if (lppt) { lppt->x = Dc_Attr->ptlBrushOrigin.x; lppt->y = Dc_Attr->ptlBrushOrigin.y; } if ((nXOrg == Dc_Attr->ptlBrushOrigin.x) && (nYOrg == Dc_Attr->ptlBrushOrigin.y)) return TRUE; if(((pTeb->GdiTebBatch.HDC == NULL) || (pTeb->GdiTebBatch.HDC == hdc)) && ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSSETBRHORG)) <= GDIBATCHBUFSIZE) && (!(Dc_Attr->ulDirty_ & DC_DIBSECTION)) ) { PGDIBSSETBRHORG pgSBO = (PGDIBSSETBRHORG)(&pTeb->GdiTebBatch.Buffer[0] + pTeb->GdiTebBatch.Offset); Dc_Attr->ptlBrushOrigin.x = nXOrg; Dc_Attr->ptlBrushOrigin.y = nYOrg; pgSBO->gbHdr.Cmd = GdiBCSetBrushOrg; pgSBO->gbHdr.Size = sizeof(GDIBSSETBRHORG); pgSBO->ptlBrushOrigin = Dc_Attr->ptlBrushOrigin; pTeb->GdiTebBatch.Offset += sizeof(GDIBSSETBRHORG); pTeb->GdiTebBatch.HDC = hdc; pTeb->GdiBatchCount++; DPRINT("Loading the Flush!! COUNT-> %lu\n", pTeb->GdiBatchCount); if (pTeb->GdiBatchCount >= GDI_BatchLimit) { DPRINT("Call GdiFlush!!\n"); NtGdiFlush(); DPRINT("Exit GdiFlush!!\n"); } return TRUE; } } return NtGdiSetBrushOrg(hdc,nXOrg,nYOrg,lppt); }
HGDIOBJ FASTCALL hGetPEBHandle(HANDLECACHETYPE Type, COLORREF cr) { int Number, Offset, MaxNum, GdiType; HANDLE Lock; HGDIOBJ Handle = NULL; Lock = InterlockedCompareExchangePointer( (PVOID*)&GdiHandleCache->ulLock, NtCurrentTeb(), NULL ); if (Lock) return Handle; Number = GdiHandleCache->ulNumHandles[Type]; if (Type == hctBrushHandle) { Offset = 0; MaxNum = CACHE_BRUSH_ENTRIES; GdiType = GDILoObjType_LO_BRUSH_TYPE; } else if (Type == hctPenHandle) { Offset = CACHE_BRUSH_ENTRIES; MaxNum = CACHE_PEN_ENTRIES; GdiType = GDILoObjType_LO_PEN_TYPE; } else if (Type == hctRegionHandle) { Offset = CACHE_BRUSH_ENTRIES+CACHE_PEN_ENTRIES; MaxNum = CACHE_REGION_ENTRIES; GdiType = GDILoObjType_LO_REGION_TYPE; } else // Font is not supported here. { return Handle; } if ( Number && Number <= MaxNum ) { PBRUSH_ATTR pBrush_Attr; HGDIOBJ *hPtr; hPtr = GdiHandleCache->Handle + Offset; Handle = hPtr[Number - 1]; if (GdiGetHandleUserData( Handle, GdiType, (PVOID) &pBrush_Attr)) { if (pBrush_Attr->AttrFlags & ATTR_CACHED) { DPRINT("Get Handle! Type %d Count %lu PEB 0x%p\n", Type, GdiHandleCache->ulNumHandles[Type], NtCurrentTeb()->ProcessEnvironmentBlock); pBrush_Attr->AttrFlags &= ~ATTR_CACHED; hPtr[Number - 1] = NULL; GdiHandleCache->ulNumHandles[Type]--; if ( Type == hctBrushHandle ) // Handle only brush. { if ( pBrush_Attr->lbColor != cr ) { pBrush_Attr->lbColor = cr ; pBrush_Attr->AttrFlags |= ATTR_NEW_COLOR; } } } } else { Handle = NULL; } } (void)InterlockedExchangePointer((PVOID*)&GdiHandleCache->ulLock, Lock); return Handle; }