/* * @implemented * */ int WINAPI SetBkMode( _In_ HDC hdc, _In_ int iBkMode) { PDC_ATTR pdcattr; INT iOldMode; HANDLE_METADC(INT, SetBkMode, 0, hdc, iBkMode); /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } iOldMode = pdcattr->lBkMode; pdcattr->jBkMode = iBkMode; // Processed pdcattr->lBkMode = iBkMode; // Raw return iOldMode; }
/* * @implemented */ COLORREF WINAPI SetDCPenColor( _In_ HDC hdc, _In_ COLORREF crColor) { PDC_ATTR pdcattr; COLORREF crOldColor; /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return CLR_INVALID; } /* We handle only enhanced meta DCs here */ HANDLE_METADC(COLORREF, SetDCPenColor, CLR_INVALID, hdc, crColor); /* Get old color and store the new */ crOldColor = pdcattr->ulPenClr; pdcattr->ulPenClr = (ULONG)crColor; if (pdcattr->crPenClr != crColor) { pdcattr->ulDirty_ |= DIRTY_LINE; pdcattr->crPenClr = crColor; } return crOldColor; }
/* * @implemented */ COLORREF WINAPI SetBkColor( _In_ HDC hdc, _In_ COLORREF crColor) { PDC_ATTR pdcattr; COLORREF crOldColor; HANDLE_METADC(COLORREF, SetBkColor, CLR_INVALID, hdc, crColor); /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return CLR_INVALID; } /* Get old color and store the new */ crOldColor = pdcattr->ulBackgroundClr; pdcattr->ulBackgroundClr = crColor; if (pdcattr->crBackgroundClr != crColor) { pdcattr->ulDirty_ |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); pdcattr->crBackgroundClr = crColor; } return crOldColor; }
HPEN WINAPI GdiSelectPen( _In_ HDC hdc, _In_ HPEN hpen) { PDC_ATTR pdcattr; HPEN hpenOld; HANDLE_METADC(HPEN, SelectPen, NULL, hdc, hpen); /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; } /* Get the current pen. If it matches the new pen, we're done */ hpenOld = pdcattr->hpen; if (hpenOld == hpen) return hpenOld; /* Set the new pen and update dirty flags */ pdcattr->ulDirty_ |= DC_PEN_DIRTY; pdcattr->hpen = hpen; return hpenOld; }
/* * @implemented */ int WINAPI SetStretchBltMode( _In_ HDC hdc, _In_ int iStretchMode) { INT iOldMode; PDC_ATTR pdcattr; HANDLE_METADC(INT, SetStretchBltMode, 0, hdc, iStretchMode); /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } iOldMode = pdcattr->lStretchBltMode; pdcattr->lStretchBltMode = iStretchMode; // Wine returns an error here. We set the default. if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK; pdcattr->jStretchBltMode = iStretchMode; return iOldMode; }
HBRUSH WINAPI GdiSelectBrush( _In_ HDC hdc, _In_ HBRUSH hbr) { PDC_ATTR pdcattr; HBRUSH hbrOld; HANDLE_METADC(HBRUSH, SelectBrush, NULL, hdc, hbr); /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; } /* Get the current brush. If it matches the new brush, we're done */ hbrOld = pdcattr->hbrush; if (hbrOld == hbr) return hbrOld; /* Set the new brush and update dirty flags */ pdcattr->hbrush = hbr; pdcattr->ulDirty_ |= DC_BRUSH_DIRTY; return hbrOld; }
/* * @unimplemented */ int WINAPI SetPolyFillMode( _In_ HDC hdc, _In_ int iPolyFillMode) { INT iOldPolyFillMode; PDC_ATTR pdcattr; HANDLE_METADC(INT, SetPolyFillMode, 0, hdc, iPolyFillMode); /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) { if (pdcattr->ulDirty_ & DC_MODE_DIRTY) { NtGdiFlush(); // Sync up pdcattr from Kernel space. pdcattr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY); } } iOldPolyFillMode = pdcattr->lFillMode; pdcattr->lFillMode = iPolyFillMode; return iOldPolyFillMode; }
/* * @implemented */ int WINAPI SetROP2( _In_ HDC hdc, _In_ int rop2) { PDC_ATTR pdcattr; INT rop2Old; HANDLE_METADC(INT, SetROP2, 0, hdc, rop2); /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) { if (pdcattr->ulDirty_ & DC_MODE_DIRTY) { NtGdiFlush(); pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; } } rop2Old = pdcattr->jROP2; pdcattr->jROP2 = (BYTE)rop2; return rop2Old; }
/* * @unimplemented */ BOOL WINAPI RestoreDC(IN HDC hdc, IN INT iLevel) { HANDLE_METADC(BOOL, RestoreDC, FALSE, hdc, iLevel); return NtGdiRestoreDC(hdc, iLevel); }
/* * @implemented */ BOOL WINAPI SelectClipPath( HDC hdc, int iMode) { HANDLE_METADC(BOOL, SelectClipPath, FALSE, hdc, iMode); return NtGdiSelectClipPath(hdc, iMode); }
/* * @implemented */ INT WINAPI OffsetClipRgn( HDC hdc, INT nXOffset, INT nYOffset) { HANDLE_METADC(INT, OffsetClipRgn, ERROR, hdc, nXOffset, nYOffset); return NtGdiOffsetClipRgn(hdc, nXOffset, nYOffset); }
/* * @implemented */ BOOL WINAPI LineTo( _In_ HDC hdc, _In_ INT x, _In_ INT y ) { HANDLE_METADC(BOOL, LineTo, FALSE, hdc, x, y); return NtGdiLineTo(hdc, x, y); }
HPALETTE WINAPI SelectPalette( HDC hdc, HPALETTE hpal, BOOL bForceBackground) { HANDLE_METADC(HPALETTE, SelectPalette, NULL, hdc, hpal, bForceBackground); return NtUserSelectPalette(hdc, hpal, bForceBackground); }
/* * @implemented */ COLORREF WINAPI SetPixel( _In_ HDC hdc, _In_ INT x, _In_ INT y, _In_ COLORREF crColor) { HANDLE_METADC(COLORREF, SetPixel, CLR_INVALID, hdc, x, y, crColor); return NtGdiSetPixel(hdc, x, y, crColor); }
/* * @implemented */ INT WINAPI IntersectClipRect( _In_ HDC hdc, _In_ INT nLeft, _In_ INT nTop, _In_ INT nRight, _In_ INT nBottom) { HANDLE_METADC(INT, IntersectClipRect, ERROR, hdc, nLeft, nTop, nRight, nBottom); return NtGdiIntersectClipRect(hdc, nLeft, nTop, nRight, nBottom); }
/* * @implemented */ INT WINAPI ExcludeClipRect( _In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom) { HANDLE_METADC(INT, ExcludeClipRect, ERROR, hdc, xLeft, yTop, xRight, yBottom); return NtGdiExcludeClipRect(hdc, xLeft, yTop, xRight, yBottom); }
/* * @implemented */ BOOL WINAPI Rectangle( _In_ HDC hdc, _In_ INT left, _In_ INT top, _In_ INT right, _In_ INT bottom) { HANDLE_METADC(BOOL, Rectangle, FALSE, hdc, left, top, right, bottom); return NtGdiRectangle(hdc, left, top, right, bottom); }
/* * @implemented */ BOOL WINAPI Ellipse( _In_ HDC hdc, _In_ INT left, _In_ INT top, _In_ INT right, _In_ INT bottom) { HANDLE_METADC(BOOL, Ellipse, FALSE, hdc, left, top, right, bottom); return NtGdiEllipse(hdc, left, top, right, bottom); }
/* * @implemented */ BOOL WINAPI InvertRgn( _In_ HDC hdc, _In_ HRGN hrgn) { if (hrgn == NULL) return FALSE; HANDLE_METADC(BOOL, InvertRgn, FALSE, hdc, hrgn); return NtGdiInvertRgn(hdc, hrgn); }
/* * @implemented */ BOOL WINAPI FillRgn( _In_ HDC hdc, _In_ HRGN hrgn, _In_ HBRUSH hbr) { if ((hrgn == NULL) || (hbr == NULL)) return FALSE; HANDLE_METADC(BOOL, FillRgn, FALSE, hdc, hrgn, hbr); return NtGdiFillRgn(hdc, hrgn, hbr); }
/* * @implemented */ BOOL WINAPI RoundRect( _In_ HDC hdc, _In_ INT left, _In_ INT top, _In_ INT right, _In_ INT bottom, _In_ INT width, _In_ INT height) { HANDLE_METADC(BOOL, RoundRect, FALSE, hdc, left, top, right, bottom, width, height); return NtGdiRoundRect(hdc, left, top, right, bottom, width, height); }
/* * @implemented */ BOOL WINAPI FrameRgn( _In_ HDC hdc, _In_ HRGN hrgn, _In_ HBRUSH hbr, _In_ INT nWidth, _In_ INT nHeight) { if ((hrgn == NULL) || (hbr == NULL)) return FALSE; HANDLE_METADC(BOOL, FrameRgn, FALSE, hdc, hrgn, hbr, nWidth, nHeight); return NtGdiFrameRgn(hdc, hrgn, hbr, nWidth, nHeight); }
HFONT WINAPI GdiSelectFont( _In_ HDC hdc, _In_ HFONT hfont) { PDC_ATTR pdcattr; HFONT hfontOld; HANDLE_METADC(HFONT, SelectFont, NULL, hdc, hfont); /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; } /* Get the current font. If it matches the new font, we're done */ hfontOld = pdcattr->hlfntNew; if (hfontOld == hfont) return hfontOld; /* Set the new font and update dirty flags */ pdcattr->hlfntNew = hfont; pdcattr->ulDirty_ &= ~SLOW_WIDTHS; pdcattr->ulDirty_ |= DIRTY_CHARSET; /* If the DC does not have a DIB section selected, try a batch command */ if (!(pdcattr->ulDirty_ & DC_DIBSECTION)) { PGDIBSOBJECT pgO; pgO = GdiAllocBatchCommand(hdc, GdiBCSelObj); if (pgO) { pgO->hgdiobj = hfont; return hfontOld; } } /* We could not use the batch command, call win32k */ return NtGdiSelectFont(hdc, hfont); }
BOOL WINAPI MoveToEx( _In_ HDC hdc, _In_ INT x, _In_ INT y, _Out_opt_ LPPOINT ppt) { PDC_ATTR pdcattr; HANDLE_METADC(BOOL, MoveTo, FALSE, hdc, x, y, ppt); /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (ppt) { if ( pdcattr->ulDirty_ & DIRTY_PTLCURRENT ) // Double hit! { ppt->x = pdcattr->ptfxCurrent.x; // ret prev before change. ppt->y = pdcattr->ptfxCurrent.y; DPtoLP (hdc, ppt, 1); // reconvert back. } else { ppt->x = pdcattr->ptlCurrent.x; ppt->y = pdcattr->ptlCurrent.y; } } pdcattr->ptlCurrent.x = x; pdcattr->ptlCurrent.y = y; pdcattr->ulDirty_ &= ~DIRTY_PTLCURRENT; pdcattr->ulDirty_ |= ( DIRTY_PTFXCURRENT|DIRTY_STYLESTATE); // Set dirty return TRUE; }
/* * @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; HANDLE_METADC(INT, SetDIBitsToDevice, 0, hdc, XDest, YDest, Width, Height, XSrc, YSrc, StartScan, ScanLines, Bits, lpbmi, ColorUse); 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; }
/* * @implemented * */ int WINAPI GetDeviceCaps( _In_ HDC hdc, _In_ int nIndex) { PDC_ATTR pdcattr; PDEVCAPS pDevCaps = GdiDevCaps; // Primary display device capabilities. DPRINT("Device CAPS1\n"); HANDLE_METADC(INT, GetDeviceCaps, 0, hdc, nIndex); /* Get the DC attribute */ pdcattr = GdiGetDcAttr(hdc); if (pdcattr == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } if (!(pdcattr->ulDirty_ & DC_PRIMARY_DISPLAY)) return NtGdiGetDeviceCaps(hdc, nIndex); switch (nIndex) { 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 */ 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; }