diff --git a/dlls/winex11.drv/graphics.c b/dlls/winex11.drv/graphics.c index b07234bbc22..4dafb5a339b 100644 --- a/dlls/winex11.drv/graphics.c +++ b/dlls/winex11.drv/graphics.c @@ -75,20 +75,23 @@ static const int X11DRV_XROPfunction[16] = /* get the rectangle in device coordinates, with optional mirroring */ static RECT get_device_rect( HDC hdc, int left, int top, int right, int bottom ) { + DWORD layout; RECT rect; + NtGdiGetDCDword( hdc, NtGdiGetLayout, &layout ); + rect.left = left; rect.top = top; rect.right = right; rect.bottom = bottom; - if (GetLayout( hdc ) & LAYOUT_RTL) + if (layout & LAYOUT_RTL) { /* shift the rectangle so that the right border is included after mirroring */ /* it would be more correct to do this after LPtoDP but that's not what Windows does */ rect.left--; rect.right--; } - LPtoDP( hdc, (POINT *)&rect, 2 ); + lp_to_dp( hdc, (POINT *)&rect, 2 ); if (rect.left > rect.right) { int tmp = rect.left; @@ -157,7 +160,7 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) RECT *rect, tmp; XRectangle *xrect; - if (!(size = GetRegionData( hrgn, 0, NULL ))) return NULL; + if (!(size = NtGdiGetRegionData( hrgn, 0, NULL ))) return NULL; if (sizeof(XRectangle) > sizeof(RECT)) { /* add extra size for XRectangle array */ @@ -165,7 +168,7 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) size += count * (sizeof(XRectangle) - sizeof(RECT)); } if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return NULL; - if (!GetRegionData( hrgn, size, data )) + if (!NtGdiGetRegionData( hrgn, size, data )) { HeapFree( GetProcessHeap(), 0, data ); return NULL; @@ -175,7 +178,7 @@ RGNDATA *X11DRV_GetRegionData( HRGN hrgn, HDC hdc_lptodp ) xrect = (XRectangle *)data->Buffer; if (hdc_lptodp) /* map to device coordinates */ { - LPtoDP( hdc_lptodp, (POINT *)rect, data->rdh.nCount * 2 ); + lp_to_dp( hdc_lptodp, (POINT *)rect, data->rdh.nCount * 2 ); for (i = 0; i < data->rdh.nCount; i++) { if (rect[i].right < rect[i].left) @@ -271,10 +274,10 @@ BOOL add_extra_clipping_region( X11DRV_PDEVICE *dev, HRGN rgn ) if (!rgn) return FALSE; if (dev->region) { - if (!(clip = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE; - CombineRgn( clip, dev->region, rgn, RGN_AND ); + if (!(clip = NtGdiCreateRectRgn( 0, 0, 0, 0 ))) return FALSE; + NtGdiCombineRgn( clip, dev->region, rgn, RGN_AND ); update_x11_clipping( dev, clip ); - DeleteObject( clip ); + NtGdiDeleteObjectApp( clip ); } else update_x11_clipping( dev, rgn ); return TRUE; @@ -311,25 +314,31 @@ void CDECL X11DRV_SetDeviceClipping( PHYSDEV dev, HRGN rgn ) */ BOOL X11DRV_SetupGCForPatBlt( X11DRV_PDEVICE *physDev, GC gc, BOOL fMapColors ) { + DWORD bk_color, text_color, rop_mode, bk_mode, poly_fill_mode; XGCValues val; unsigned long mask; Pixmap pixmap = 0; POINT pt; if (physDev->brush.style == BS_NULL) return FALSE; + + NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetBkColor, &bk_color ); + NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetROP2, &rop_mode ); + if (physDev->brush.pixel == -1) { /* Special case used for monochrome pattern brushes. * We need to swap foreground and background because * Windows does it the wrong way... */ - val.foreground = X11DRV_PALETTE_ToPhysical( physDev, GetBkColor(physDev->dev.hdc) ); - val.background = X11DRV_PALETTE_ToPhysical( physDev, GetTextColor(physDev->dev.hdc) ); + NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetTextColor, &text_color ); + val.foreground = X11DRV_PALETTE_ToPhysical( physDev, bk_color ); + val.background = X11DRV_PALETTE_ToPhysical( physDev, text_color ); } else { val.foreground = physDev->brush.pixel; - val.background = X11DRV_PALETTE_ToPhysical( physDev, GetBkColor(physDev->dev.hdc) ); + val.background = X11DRV_PALETTE_ToPhysical( physDev, bk_color ); } if (fMapColors && X11DRV_PALETTE_XPixelToPalette) { @@ -337,7 +346,7 @@ BOOL X11DRV_SetupGCForPatBlt( X11DRV_PDEVICE *physDev, GC gc, BOOL fMapColors ) val.background = X11DRV_PALETTE_XPixelToPalette[val.background]; } - val.function = X11DRV_XROPfunction[GetROP2(physDev->dev.hdc)-1]; + val.function = X11DRV_XROPfunction[rop_mode - 1]; /* ** Let's replace GXinvert by GXxor with (black xor white) ** This solves the selection color and leak problems in excel @@ -354,7 +363,8 @@ BOOL X11DRV_SetupGCForPatBlt( X11DRV_PDEVICE *physDev, GC gc, BOOL fMapColors ) { case FillStippled: case FillOpaqueStippled: - if (GetBkMode(physDev->dev.hdc)==OPAQUE) val.fill_style = FillOpaqueStippled; + NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetBkMode, &bk_mode ); + if (bk_mode == OPAQUE) val.fill_style = FillOpaqueStippled; val.stipple = physDev->brush.pixmap; mask = GCStipple; break; @@ -383,10 +393,13 @@ BOOL X11DRV_SetupGCForPatBlt( X11DRV_PDEVICE *physDev, GC gc, BOOL fMapColors ) mask = 0; break; } - GetBrushOrgEx( physDev->dev.hdc, &pt ); + + NtGdiGetDCPoint( physDev->dev.hdc, NtGdiGetBrushOrgEx, &pt ); + NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetPolyFillMode, &poly_fill_mode ); + val.ts_x_origin = physDev->dc_rect.left + pt.x; val.ts_y_origin = physDev->dc_rect.top + pt.y; - val.fill_rule = (GetPolyFillMode(physDev->dev.hdc) == WINDING) ? WindingRule : EvenOddRule; + val.fill_rule = poly_fill_mode == WINDING ? WindingRule : EvenOddRule; XChangeGC( gdi_display, gc, GCFunction | GCForeground | GCBackground | GCFillStyle | GCFillRule | GCTileStipXOrigin | GCTileStipYOrigin | mask, @@ -416,8 +429,10 @@ BOOL X11DRV_SetupGCForBrush( X11DRV_PDEVICE *physDev ) */ static BOOL X11DRV_SetupGCForPen( X11DRV_PDEVICE *physDev ) { + DWORD rop2, bk_color, bk_mode; XGCValues val; - UINT rop2 = GetROP2(physDev->dev.hdc); + + NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetROP2, &rop2 ); if (physDev->pen.style == PS_NULL) return FALSE; @@ -444,7 +459,8 @@ static BOOL X11DRV_SetupGCForPen( X11DRV_PDEVICE *physDev ) val.foreground = physDev->pen.pixel; val.function = X11DRV_XROPfunction[rop2-1]; } - val.background = X11DRV_PALETTE_ToPhysical( physDev, GetBkColor(physDev->dev.hdc) ); + NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetBkColor, &bk_color ); + val.background = X11DRV_PALETTE_ToPhysical( physDev, bk_color ); val.fill_style = FillSolid; val.line_width = physDev->pen.width; if (val.line_width <= 1) { @@ -477,7 +493,8 @@ static BOOL X11DRV_SetupGCForPen( X11DRV_PDEVICE *physDev ) } if (physDev->pen.dash_len) - val.line_style = ((GetBkMode(physDev->dev.hdc) == OPAQUE) && (!physDev->pen.ext)) + val.line_style = (NtGdiGetDCDword( physDev->dev.hdc, NtGdiGetBkMode, &bk_mode) && + bk_mode == OPAQUE && !physDev->pen.ext) ? LineDoubleDash : LineOnOffDash; else val.line_style = LineSolid; @@ -504,7 +521,7 @@ INT X11DRV_XWStoDS( HDC hdc, INT width ) pt[0].y = 0; pt[1].x = width; pt[1].y = 0; - LPtoDP( hdc, pt, 2 ); + lp_to_dp( hdc, pt, 2 ); return pt[1].x - pt[0].x; } @@ -521,7 +538,7 @@ INT X11DRV_YWStoDS( HDC hdc, INT height ) pt[0].y = 0; pt[1].x = 0; pt[1].y = height; - LPtoDP( hdc, pt, 2 ); + lp_to_dp( hdc, pt, 2 ); return pt[1].y - pt[0].y; } @@ -533,10 +550,10 @@ BOOL CDECL X11DRV_LineTo( PHYSDEV dev, INT x, INT y ) X11DRV_PDEVICE *physDev = get_x11drv_dev( dev ); POINT pt[2]; - GetCurrentPositionEx( dev->hdc, &pt[0] ); + NtGdiGetDCPoint( dev->hdc, NtGdiGetCurrentPosition, &pt[0] ); pt[1].x = x; pt[1].y = y; - LPtoDP( dev->hdc, pt, 2 ); + lp_to_dp( dev->hdc, pt, 2 ); add_pen_device_bounds( physDev, pt, 2 ); if (X11DRV_SetupGCForPen( physDev )) @@ -561,6 +578,7 @@ static BOOL X11DRV_DrawArc( PHYSDEV dev, INT left, INT top, INT right, INT botto X11DRV_PDEVICE *physDev = get_x11drv_dev( dev ); INT xcenter, ycenter, istart_angle, idiff_angle; INT width, oldwidth; + DWORD arc_dir; double start_angle, end_angle; XPoint points[4]; POINT start, end; @@ -570,13 +588,13 @@ static BOOL X11DRV_DrawArc( PHYSDEV dev, INT left, INT top, INT right, INT botto start.y = ystart; end.x = xend; end.y = yend; - LPtoDP(dev->hdc, &start, 1); - LPtoDP(dev->hdc, &end, 1); + lp_to_dp(dev->hdc, &start, 1); + lp_to_dp(dev->hdc, &end, 1); if ((rc.left == rc.right) || (rc.top == rc.bottom) ||(lines && ((rc.right-rc.left==1)||(rc.bottom-rc.top==1)))) return TRUE; - if (GetArcDirection( dev->hdc ) == AD_CLOCKWISE) + if (NtGdiGetDCDword( dev->hdc, NtGdiGetArcDirection, &arc_dir ) && arc_dir == AD_CLOCKWISE) { POINT tmp = start; start = end; end = tmp; } oldwidth = width = physDev->pen.width; @@ -843,7 +861,7 @@ BOOL CDECL X11DRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bott pts[0].x = pts[0].y = 0; pts[1].x = ell_width; pts[1].y = ell_height; - LPtoDP(dev->hdc, pts, 2); + lp_to_dp(dev->hdc, pts, 2); ell_width = max(abs( pts[1].x - pts[0].x ), 1); ell_height = max(abs( pts[1].y - pts[0].y ), 1); @@ -1024,7 +1042,7 @@ COLORREF CDECL X11DRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ) pt.x = x; pt.y = y; - LPtoDP( dev->hdc, &pt, 1 ); + lp_to_dp( dev->hdc, &pt, 1 ); pixel = X11DRV_PALETTE_ToPhysical( physDev, color ); XSetForeground( gdi_display, physDev->gc, pixel ); @@ -1063,9 +1081,9 @@ BOOL CDECL X11DRV_PaintRgn( PHYSDEV dev, HRGN hrgn ) XFillRectangles( gdi_display, physDev->drawable, physDev->gc, rect, data->rdh.nCount ); HeapFree( GetProcessHeap(), 0, data ); } - if (GetRgnBox( hrgn, &rc )) + if (NtGdiGetRgnBox( hrgn, &rc )) { - LPtoDP( dev->hdc, (POINT *)&rc, 2 ); + lp_to_dp( dev->hdc, (POINT *)&rc, 2 ); add_device_bounds( physDev, &rc ); } return TRUE; @@ -1084,7 +1102,7 @@ static BOOL X11DRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ) points = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*pt) ); if (!points) return FALSE; memcpy( points, pt, count * sizeof(*pt) ); - LPtoDP( dev->hdc, points, count ); + lp_to_dp( dev->hdc, points, count ); add_pen_device_bounds( physDev, points, count ); if (!(xpoints = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (count+1) ))) @@ -1135,16 +1153,22 @@ BOOL CDECL X11DRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, points = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*pt) ); if (!points) return FALSE; memcpy( points, pt, total * sizeof(*pt) ); - LPtoDP( dev->hdc, points, total ); + lp_to_dp( dev->hdc, points, total ); add_pen_device_bounds( physDev, points, total ); if (X11DRV_SetupGCForBrush( physDev )) { + DWORD poly_fill_mode; XRectangle *rect; - HRGN hrgn = CreatePolyPolygonRgn( points, counts, polygons, GetPolyFillMode( dev->hdc ) ); - RGNDATA *data = X11DRV_GetRegionData( hrgn, 0 ); + HRGN hrgn; + RGNDATA *data; - DeleteObject( hrgn ); + NtGdiGetDCDword( dev->hdc, NtGdiGetPolyFillMode, &poly_fill_mode ); + hrgn = UlongToHandle( NtGdiPolyPolyDraw( UlongToHandle(poly_fill_mode), points, + (const ULONG *)counts, polygons, + NtGdiPolyPolygonRgn )); + data = X11DRV_GetRegionData( hrgn, 0 ); + NtGdiDeleteObjectApp( hrgn ); if (!data) goto done; rect = (XRectangle *)data->Buffer; for (i = 0; i < data->rdh.nCount; i++) @@ -1202,7 +1226,7 @@ BOOL CDECL X11DRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* count points = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*pt) ); if (!points) return FALSE; memcpy( points, pt, total * sizeof(*pt) ); - LPtoDP( dev->hdc, points, total ); + lp_to_dp( dev->hdc, points, total ); add_pen_device_bounds( physDev, points, total ); if (X11DRV_SetupGCForPen ( physDev )) @@ -1239,27 +1263,27 @@ static BOOL x11drv_stroke_and_fill_path( PHYSDEV dev, BOOL stroke, BOOL fill ) XPoint *xpoints; int i, j, size; - FlattenPath( dev->hdc ); - if ((size = GetPath( dev->hdc, NULL, NULL, 0 )) == -1) return FALSE; + NtGdiFlattenPath( dev->hdc ); + if ((size = NtGdiGetPath( dev->hdc, NULL, NULL, 0 )) == -1) return FALSE; if (!size) { - AbortPath( dev->hdc ); + NtGdiAbortPath( dev->hdc ); return TRUE; } xpoints = HeapAlloc( GetProcessHeap(), 0, (size + 1) * sizeof(*xpoints) ); points = HeapAlloc( GetProcessHeap(), 0, size * sizeof(*points) ); flags = HeapAlloc( GetProcessHeap(), 0, size * sizeof(*flags) ); if (!points || !flags || !xpoints) goto done; - if (GetPath( dev->hdc, points, flags, size ) == -1) goto done; - LPtoDP( dev->hdc, points, size ); + if (NtGdiGetPath( dev->hdc, points, flags, size ) == -1) goto done; + lp_to_dp( dev->hdc, points, size ); if (fill && X11DRV_SetupGCForBrush( physDev )) { XRectangle *rect; - HRGN hrgn = PathToRegion( dev->hdc ); + HRGN hrgn = NtGdiPathToRegion( dev->hdc ); RGNDATA *data = X11DRV_GetRegionData( hrgn, 0 ); - DeleteObject( hrgn ); + NtGdiDeleteObjectApp( hrgn ); if (!data) goto done; rect = (XRectangle *)data->Buffer; for (i = 0; i < data->rdh.nCount; i++) @@ -1296,7 +1320,7 @@ static BOOL x11drv_stroke_and_fill_path( PHYSDEV dev, BOOL stroke, BOOL fill ) } add_pen_device_bounds( physDev, points, size ); - AbortPath( dev->hdc ); + NtGdiAbortPath( dev->hdc ); ret = TRUE; done: @@ -1423,7 +1447,7 @@ BOOL CDECL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT pt.x = x; pt.y = y; - LPtoDP( dev->hdc, &pt, 1 ); + lp_to_dp( dev->hdc, &pt, 1 ); if (!physDev->region) { @@ -1434,8 +1458,8 @@ BOOL CDECL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT } else { - if (!PtInRegion( physDev->region, pt.x, pt.y )) return FALSE; - GetRgnBox( physDev->region, &rect ); + if (!NtGdiPtInRegion( physDev->region, pt.x, pt.y )) return FALSE; + NtGdiGetRgnBox( physDev->region, &rect ); rect.left = max( rect.left, 0 ); rect.top = max( rect.top, 0 ); rect.right = min( rect.right, physDev->dc_rect.right - physDev->dc_rect.left ); @@ -1511,7 +1535,7 @@ BOOL CDECL X11DRV_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert, pt[0].y = v[0].y; pt[1].x = v[1].x; pt[1].y = v[1].y; - LPtoDP( dev->hdc, pt, 2 ); + lp_to_dp( dev->hdc, pt, 2 ); dx = pt[1].x - pt[0].x; if (!dx) continue; if (dx < 0) /* swap the colors */ @@ -1561,7 +1585,7 @@ BOOL CDECL X11DRV_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert, pt[0].y = v[0].y; pt[1].x = v[1].x; pt[1].y = v[1].y; - LPtoDP( dev->hdc, pt, 2 ); + lp_to_dp( dev->hdc, pt, 2 ); dy = pt[1].y - pt[0].y; if (!dy) continue; if (dy < 0) /* swap the colors */ diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index dacd7b171cf..18afc0e133d 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -840,6 +840,13 @@ static inline BOOL is_window_rect_mapped( const RECT *rect ) max( rect->bottom, rect->top + 1 ) > virtual_rect.top); } +/* GDI helpers */ + +static inline BOOL lp_to_dp( HDC hdc, POINT *points, INT count ) +{ + return NtGdiTransformPoints( hdc, points, points, count, NtGdiLPtoDP ); +} + /* registry helpers */ extern HKEY open_hkcu_key( const char *name ) DECLSPEC_HIDDEN;