/* create a bitmap appropriate for the given DIB pattern brush */ HBITMAP create_brush_bitmap( X11DRV_PDEVICE *physDev, const struct brush_pattern *pattern ) { HDC memdc; int bpp = screen_bpp; HBITMAP bitmap; const BITMAPINFO *info = pattern->info; if (physDev->depth == 1 || info->bmiHeader.biBitCount == 1) bpp = 1; bitmap = CreateBitmap( info->bmiHeader.biWidth, abs(info->bmiHeader.biHeight), 1, bpp, NULL ); if (!bitmap) return 0; /* make sure it's owned by x11drv */ memdc = CreateCompatibleDC( physDev->dev.hdc ); SelectObject( memdc, bitmap ); DeleteDC( memdc ); if (!X11DRV_get_phys_bitmap( bitmap )) { DeleteObject( bitmap ); return 0; } SetDIBits( physDev->dev.hdc, bitmap, 0, abs(info->bmiHeader.biHeight), pattern->bits.ptr, info, pattern->usage ); return bitmap; }
/*********************************************************************** * BRUSH_SelectPatternBrush */ static BOOL BRUSH_SelectPatternBrush( X11DRV_PDEVICE *physDev, HBITMAP hbitmap ) { BITMAP bitmap; X_PHYSBITMAP *physBitmap = X11DRV_get_phys_bitmap( hbitmap ); if (!physBitmap || !GetObjectW( hbitmap, sizeof(bitmap), &bitmap )) return FALSE; X11DRV_DIB_Lock( physBitmap, DIB_Status_GdiMod ); if ((physDev->depth == 1) && (physBitmap->pixmap_depth != 1)) { wine_tsx11_lock(); /* Special case: a color pattern on a monochrome DC */ physDev->brush.pixmap = XCreatePixmap( gdi_display, root_window, bitmap.bmWidth, bitmap.bmHeight, 1); /* FIXME: should probably convert to monochrome instead */ XCopyPlane( gdi_display, physBitmap->pixmap, physDev->brush.pixmap, get_bitmap_gc(1), 0, 0, bitmap.bmWidth, bitmap.bmHeight, 0, 0, 1 ); wine_tsx11_unlock(); } else { /* XRender is needed because of possible depth conversion */ X11DRV_XRender_CopyBrush(physDev, physBitmap, bitmap.bmWidth, bitmap.bmHeight); } X11DRV_DIB_Unlock( physBitmap, TRUE ); if (physBitmap->pixmap_depth > 1) { physDev->brush.fillStyle = FillTiled; physDev->brush.pixel = 0; /* Ignored */ } else { physDev->brush.fillStyle = FillOpaqueStippled; physDev->brush.pixel = -1; /* Special case (see DC_SetupGCForBrush) */ } return TRUE; }
/*********************************************************************** * BRUSH_SelectDIBPatternBrush */ static BOOL BRUSH_SelectDIBPatternBrush( X11DRV_PDEVICE *physDev, HGLOBAL mem ) { BOOL ret; HDC memdc; BITMAPINFO *info = GlobalLock( mem ); HBITMAP bitmap = CreateDIBitmap( physDev->dev.hdc, &info->bmiHeader, CBM_INIT, (LPBYTE)info + bitmap_info_size( info, DIB_RGB_COLORS ), info, DIB_RGB_COLORS ); /* make sure it's owned by x11drv */ memdc = CreateCompatibleDC( physDev->dev.hdc ); SelectObject( memdc, bitmap ); DeleteDC( memdc ); if ((ret = BRUSH_SelectPatternBrush( physDev, bitmap ))) { X_PHYSBITMAP *physBitmap = X11DRV_get_phys_bitmap( bitmap ); physBitmap->pixmap = 0; /* so it doesn't get freed */ } DeleteObject( bitmap ); GlobalUnlock( mem ); return ret; }
/*********************************************************************** * SelectBrush (X11DRV.@) */ HBRUSH X11DRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush, const struct brush_pattern *pattern ) { X11DRV_PDEVICE *physDev = get_x11drv_dev( dev ); LOGBRUSH logbrush; if (pattern) /* pattern brush */ { X_PHYSBITMAP *physbitmap; HBITMAP bitmap = pattern->bitmap; BOOL delete_bitmap = FALSE; if (!bitmap || !(physbitmap = X11DRV_get_phys_bitmap( bitmap ))) { if (!(bitmap = create_brush_bitmap( physDev, pattern ))) return 0; physbitmap = X11DRV_get_phys_bitmap( bitmap ); delete_bitmap = TRUE; } BRUSH_SelectPatternBrush( physDev, bitmap, physbitmap ); TRACE("BS_PATTERN\n"); physDev->brush.style = BS_PATTERN; if (delete_bitmap) DeleteObject( bitmap ); return hbrush; } if (!GetObjectA( hbrush, sizeof(logbrush), &logbrush )) return 0; TRACE("hdc=%p hbrush=%p\n", dev->hdc, hbrush); if (physDev->brush.pixmap) { wine_tsx11_lock(); XFreePixmap( gdi_display, physDev->brush.pixmap ); wine_tsx11_unlock(); physDev->brush.pixmap = 0; } physDev->brush.style = logbrush.lbStyle; if (hbrush == GetStockObject( DC_BRUSH )) logbrush.lbColor = GetDCBrushColor( dev->hdc ); switch(logbrush.lbStyle) { case BS_NULL: TRACE("BS_NULL\n" ); break; case BS_SOLID: TRACE("BS_SOLID\n" ); BRUSH_SelectSolidBrush( physDev, logbrush.lbColor ); break; case BS_HATCHED: TRACE("BS_HATCHED\n" ); physDev->brush.pixel = X11DRV_PALETTE_ToPhysical( physDev, logbrush.lbColor ); wine_tsx11_lock(); physDev->brush.pixmap = XCreateBitmapFromData( gdi_display, root_window, HatchBrushes[logbrush.lbHatch], 8, 8 ); wine_tsx11_unlock(); physDev->brush.fillStyle = FillStippled; break; } return hbrush; }