BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) { BRUSHOBJ *brush; BOOL ret = FALSE; if (!(brush = GDI_GetObjPtr( handle, OBJ_BRUSH ))) return FALSE; if (!brush->info) { BITMAPOBJ *bmp = GDI_GetObjPtr( brush->bitmap, OBJ_BITMAP ); if (bmp) { store_bitmap_bits( brush, bmp ); GDI_ReleaseObj( brush->bitmap ); } } if (brush->info) { memcpy( info, brush->info, get_dib_info_size( brush->info, brush->usage )); if (info->bmiHeader.biBitCount <= 8 && !info->bmiHeader.biClrUsed) fill_default_color_table( info ); *bits = brush->bits.ptr; *usage = brush->usage; ret = TRUE; } GDI_ReleaseObj( handle ); return ret; }
/*********************************************************************** * SetPaletteEntries [GDI32.@] * * Sets color values for range in palette. * * RETURNS * Success: Number of entries that were set * Failure: 0 */ UINT WINAPI SetPaletteEntries( HPALETTE hpalette, /* [in] Handle of logical palette */ UINT start, /* [in] Index of first entry to set */ UINT count, /* [in] Number of entries to set */ const PALETTEENTRY *entries) /* [in] Address of array of structures */ { PALETTEOBJ * palPtr; UINT numEntries; TRACE("hpal=%p,start=%i,count=%i\n",hpalette,start,count ); hpalette = get_full_gdi_handle( hpalette ); if (hpalette == GetStockObject(DEFAULT_PALETTE)) return 0; palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL ); if (!palPtr) return 0; numEntries = palPtr->count; if (start >= numEntries) { GDI_ReleaseObj( hpalette ); return 0; } if (start+count > numEntries) count = numEntries - start; memcpy( &palPtr->entries[start], entries, count * sizeof(PALETTEENTRY) ); GDI_ReleaseObj( hpalette ); UnrealizeObject( hpalette ); return count; }
/*********************************************************************** * BITMAP_SelectObject */ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc ) { HGDIOBJ ret; BITMAPOBJ *bitmap; DC *dc; if (!(dc = get_dc_ptr( hdc ))) return 0; if (GetObjectType( hdc ) != OBJ_MEMDC) { ret = 0; goto done; } ret = dc->hBitmap; if (handle == dc->hBitmap) goto done; /* nothing to do */ if (!(bitmap = GDI_GetObjPtr( handle, BITMAP_MAGIC ))) { ret = 0; goto done; } if (bitmap->header.dwCount && (handle != GetStockObject(DEFAULT_BITMAP))) { WARN( "Bitmap already selected in another DC\n" ); GDI_ReleaseObj( handle ); ret = 0; goto done; } if (!bitmap->funcs && !BITMAP_SetOwnerDC( handle, dc )) { GDI_ReleaseObj( handle ); ret = 0; goto done; } if (dc->funcs->pSelectBitmap && !dc->funcs->pSelectBitmap( dc->physDev, handle )) { GDI_ReleaseObj( handle ); ret = 0; } else { dc->hBitmap = handle; GDI_inc_ref_count( handle ); dc->dirty = 0; SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight); GDI_ReleaseObj( handle ); DC_InitDC( dc ); GDI_dec_ref_count( ret ); } done: release_dc_ptr( dc ); return ret; }
/*********************************************************************** * DeleteObject (GDI32.@) */ BOOL WINAPI DeleteObject( HGDIOBJ obj ) { /* Check if object is valid */ GDIOBJHDR * header; if (HIWORD(obj)) return FALSE; if (!(header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ))) return FALSE; if (!(header->wMagic & OBJECT_NOSYSTEM) && (header->wMagic >= FIRST_MAGIC) && (header->wMagic <= LAST_MAGIC)) { TRACE("Preserving system object %04x\n", obj); GDI_ReleaseObj( obj ); return TRUE; } if (header->dwCount) { TRACE("delayed for %04x because object in use, count %ld\n", obj, header->dwCount ); header->dwCount |= 0x80000000; /* mark for delete */ GDI_ReleaseObj( obj ); return TRUE; } TRACE("%04x\n", obj ); /* Delete object */ switch(GDIMAGIC(header->wMagic)) { case PEN_MAGIC: return GDI_FreeObject( obj, header ); case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header ); case FONT_MAGIC: return FONT_DeleteObject( obj, (FONTOBJ*)header ); case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header); case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header); case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header ); case DC_MAGIC: GDI_ReleaseObj( obj ); return DeleteDC(obj); case 0 : WARN("Already deleted\n"); break; default: WARN("Unknown magic number (%04x)\n",GDIMAGIC(header->wMagic)); } GDI_ReleaseObj( obj ); return FALSE; }
static BOOL copy_bitmap( BRUSHOBJ *brush, HBITMAP bitmap ) { BITMAPINFO *info; BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP ); if (!bmp) return FALSE; if (!bmp->dib) { if ((brush->bitmap = CreateBitmap( bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, bmp->bitmap.bmPlanes, bmp->bitmap.bmBitsPixel, NULL ))) { if (bmp->funcs->pCopyBitmap( bitmap, brush->bitmap )) { BITMAPOBJ *copy = GDI_GetObjPtr( brush->bitmap, OBJ_BITMAP ); copy->funcs = bmp->funcs; GDI_ReleaseObj( copy ); } else { DeleteObject( brush->bitmap ); brush->bitmap = 0; } } GDI_ReleaseObj( bitmap ); return brush->bitmap != 0; } info = HeapAlloc( GetProcessHeap(), 0, get_dib_info_size( (BITMAPINFO *)&bmp->dib->dsBmih, DIB_RGB_COLORS )); if (!info) goto done; info->bmiHeader = bmp->dib->dsBmih; if (info->bmiHeader.biCompression == BI_BITFIELDS) memcpy( &info->bmiHeader + 1, bmp->dib->dsBitfields, sizeof(bmp->dib->dsBitfields) ); else if (info->bmiHeader.biClrUsed) memcpy( &info->bmiHeader + 1, bmp->color_table, info->bmiHeader.biClrUsed * sizeof(RGBQUAD) ); if (!(brush->bits.ptr = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) { HeapFree( GetProcessHeap(), 0, info ); goto done; } memcpy( brush->bits.ptr, bmp->dib->dsBm.bmBits, info->bmiHeader.biSizeImage ); brush->bits.is_copy = TRUE; brush->bits.free = free_heap_bits; brush->info = info; brush->usage = DIB_RGB_COLORS; done: GDI_ReleaseObj( bitmap ); return brush->info != NULL; }
/*********************************************************************** * PEN_SelectObject */ static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc ) { PENOBJ *pen; HGDIOBJ ret = 0; DC *dc = get_dc_ptr( hdc ); WORD type; if (!dc) { SetLastError( ERROR_INVALID_HANDLE ); return 0; } if ((pen = get_any_obj_ptr( handle, &type ))) { struct brush_pattern *pattern; PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectPen ); switch (type) { case OBJ_PEN: pattern = NULL; break; case OBJ_EXTPEN: pattern = &pen->pattern; if (!pattern->info) pattern = NULL; break; default: GDI_ReleaseObj( handle ); release_dc_ptr( dc ); return 0; } GDI_inc_ref_count( handle ); GDI_ReleaseObj( handle ); if (!physdev->funcs->pSelectPen( physdev, handle, pattern )) { GDI_dec_ref_count( handle ); } else { ret = dc->hPen; dc->hPen = handle; GDI_dec_ref_count( ret ); } } release_dc_ptr( dc ); return ret; }
/*********************************************************************** * BRUSH_SelectObject */ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc ) { BRUSHOBJ *brush; HGDIOBJ ret = 0; DC *dc = get_dc_ptr( hdc ); if (!dc) { SetLastError( ERROR_INVALID_HANDLE ); return 0; } if ((brush = GDI_GetObjPtr( handle, OBJ_BRUSH ))) { PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectBrush ); HBITMAP bitmap = brush->bitmap; BITMAPINFO *info; void *bits; UINT usage; if (bitmap && !brush->info) { BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP ); /* fetch the bitmap bits if we are selecting into a different type of DC */ if (bmp && bmp->funcs != physdev->funcs) store_bitmap_bits( brush, bmp ); GDI_ReleaseObj( bitmap ); } info = brush->info; bits = brush->bits.ptr; usage = brush->usage; GDI_inc_ref_count( handle ); GDI_ReleaseObj( handle ); if (!physdev->funcs->pSelectBrush( physdev, handle, bitmap, info, bits, usage )) { GDI_dec_ref_count( handle ); } else { ret = dc->hBrush; dc->hBrush = handle; GDI_dec_ref_count( ret ); } } release_dc_ptr( dc ); return ret; }
/*********************************************************************** * SetMetaRgn (GDI32.@) */ INT WINAPI SetMetaRgn( HDC hdc ) { INT ret; RECT dummy; DC *dc = DC_GetDCPtr( hdc ); if (!dc) return ERROR; if (dc->hMetaClipRgn) { /* the intersection becomes the new meta region */ DeleteObject( dc->hMetaRgn ); DeleteObject( dc->hClipRgn ); dc->hMetaRgn = dc->hMetaClipRgn; dc->hClipRgn = 0; dc->hMetaClipRgn = 0; } else if (dc->hClipRgn) { dc->hMetaRgn = dc->hClipRgn; dc->hClipRgn = 0; } /* else nothing to do */ /* Note: no need to call CLIPPING_UpdateGCRegion, the overall clip region hasn't changed */ ret = GetRgnBox( dc->hMetaRgn, &dummy ); GDI_ReleaseObj( hdc ); return ret; }
/*********************************************************************** * CreatePenIndirect (GDI32.@) */ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen ) { PENOBJ * penPtr; HPEN hpen; if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, (HGDIOBJ *)&hpen, &pen_funcs ))) return 0; if (pen->lopnStyle == PS_USERSTYLE || pen->lopnStyle == PS_ALTERNATE) penPtr->logpen.elpPenStyle = PS_SOLID; else penPtr->logpen.elpPenStyle = pen->lopnStyle; if (pen->lopnStyle == PS_NULL) { penPtr->logpen.elpWidth = 1; penPtr->logpen.elpColor = RGB(0, 0, 0); } else { penPtr->logpen.elpWidth = abs(pen->lopnWidth.x); penPtr->logpen.elpColor = pen->lopnColor; } penPtr->logpen.elpBrushStyle = BS_SOLID; penPtr->logpen.elpHatch = 0; penPtr->logpen.elpNumEntries = 0; penPtr->logpen.elpStyleEntry[0] = 0; GDI_ReleaseObj( hpen ); return hpen; }
/*********************************************************************** * EMFDRV_SelectObject */ HGDIOBJ EMFDRV_SelectObject( DC *dc, HGDIOBJ handle ) { GDIOBJHDR * ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ); HGDIOBJ ret = 0; if (!ptr) return 0; TRACE("hdc=%04x %04x\n", dc->hSelf, handle ); switch(GDIMAGIC(ptr->wMagic)) { case PEN_MAGIC: ret = EMFDRV_PEN_SelectObject( dc, handle ); break; case BRUSH_MAGIC: ret = EMFDRV_BRUSH_SelectObject( dc, handle ); break; case FONT_MAGIC: ret = EMFDRV_FONT_SelectObject( dc, handle ); break; case BITMAP_MAGIC: ret = EMFDRV_BITMAP_SelectObject( dc, handle ); break; } GDI_ReleaseObj( handle ); return ret; }
/*********************************************************************** * BITMAP_SetOwnerDC * * Set the type of DC that owns the bitmap. This is used when the * bitmap is selected into a device to initialize the bitmap function * table. */ static BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev ) { BITMAPOBJ *bitmap; BOOL ret = TRUE; /* never set the owner of the stock bitmap since it can be selected in multiple DCs */ if (hbitmap == GetStockObject(DEFAULT_BITMAP)) return TRUE; if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return FALSE; if (!bitmap->dib && bitmap->funcs != physdev->funcs) { /* we can only change from the null driver to some other driver */ if (bitmap->funcs == &null_driver) { if (physdev->funcs->pCreateBitmap) { ret = physdev->funcs->pCreateBitmap( physdev, hbitmap ); if (ret) { bitmap->funcs = physdev->funcs; set_initial_bitmap_bits( hbitmap, bitmap ); } } else bitmap->funcs = &dib_driver; /* use the DIB driver to emulate DDB support */ } else { FIXME( "Trying to select bitmap %p in different DC type\n", hbitmap ); ret = FALSE; } } GDI_ReleaseObj( hbitmap ); return ret; }
/*********************************************************************** * GetNearestPaletteIndex [GDI32.@] * * Gets palette index for color. * * NOTES * Should index be initialized to CLR_INVALID instead of 0? * * RETURNS * Success: Index of entry in logical palette * Failure: CLR_INVALID */ UINT WINAPI GetNearestPaletteIndex( HPALETTE hpalette, /* [in] Handle of logical color palette */ COLORREF color) /* [in] Color to be matched */ { PALETTEOBJ* palObj = GDI_GetObjPtr( hpalette, OBJ_PAL ); UINT index = 0; if( palObj ) { int i, diff = 0x7fffffff; int r,g,b; PALETTEENTRY* entry = palObj->entries; for( i = 0; i < palObj->count && diff ; i++, entry++) { r = entry->peRed - GetRValue(color); g = entry->peGreen - GetGValue(color); b = entry->peBlue - GetBValue(color); r = r*r + g*g + b*b; if( r < diff ) { index = i; diff = r; } } GDI_ReleaseObj( hpalette ); } TRACE("(%p,%06x): returning %d\n", hpalette, color, index ); return index; }
/*********************************************************************** * BITMAP_GetObject */ static INT BITMAP_GetObject( HGDIOBJ handle, INT count, LPVOID buffer ) { INT ret; BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP ); if (!bmp) return 0; if (!buffer) ret = sizeof(BITMAP); else if (count < sizeof(BITMAP)) ret = 0; else if (bmp->dib) { if (count >= sizeof(DIBSECTION)) { DIBSECTION *dib = buffer; *dib = *bmp->dib; dib->dsBmih.biHeight = abs( dib->dsBmih.biHeight ); ret = sizeof(DIBSECTION); } else /* if (count >= sizeof(BITMAP)) */ { DIBSECTION *dib = bmp->dib; memcpy( buffer, &dib->dsBm, sizeof(BITMAP) ); ret = sizeof(BITMAP); } } else { memcpy( buffer, &bmp->bitmap, sizeof(BITMAP) ); ((BITMAP *) buffer)->bmBits = NULL; ret = sizeof(BITMAP); } GDI_ReleaseObj( handle ); return ret; }
/***************************************************************************** * @ [GDI32.104] * * This should load the correct driver for lpszDevice and calls this driver's * DeviceCapabilities proc. * * FIXME: convert DeviceCapabilities to unicode in the driver interface */ DWORD WINAPI GDI_CallDeviceCapabilities16( LPCSTR lpszDevice, LPCSTR lpszPort, WORD fwCapability, LPSTR lpszOutput, LPDEVMODEA lpdm ) { WCHAR deviceW[300]; WCHAR bufW[300]; char buf[300]; HDC hdc; DC *dc; INT ret = -1; TRACE("(%s, %s, %d, %p, %p)\n", lpszDevice, lpszPort, fwCapability, lpszOutput, lpdm ); if (!lpszDevice) return -1; if (!MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, deviceW, 300)) return -1; if(!DRIVER_GetDriverName( deviceW, bufW, 300 )) return -1; if (!WideCharToMultiByte(CP_ACP, 0, bufW, -1, buf, 300, NULL, NULL)) return -1; if (!(hdc = CreateICA( buf, lpszDevice, lpszPort, NULL ))) return -1; if ((dc = DC_GetDCPtr( hdc ))) { if (dc->funcs->pDeviceCapabilities) ret = dc->funcs->pDeviceCapabilities( buf, lpszDevice, lpszPort, fwCapability, lpszOutput, lpdm ); GDI_ReleaseObj( hdc ); } DeleteDC( hdc ); return ret; }
/*********************************************************************** * BITMAP_SetOwnerDC * * Set the type of DC that owns the bitmap. This is used when the * bitmap is selected into a device to initialize the bitmap function * table. */ BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, DC *dc ) { BITMAPOBJ *bitmap; BOOL ret; /* never set the owner of the stock bitmap since it can be selected in multiple DCs */ if (hbitmap == GetStockObject(DEFAULT_BITMAP)) return TRUE; if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return FALSE; ret = TRUE; if (!bitmap->funcs) /* not owned by a DC yet */ { if (dc->funcs->pCreateBitmap) ret = dc->funcs->pCreateBitmap( dc->physDev, hbitmap, bitmap->bitmap.bmBits ); if (ret) bitmap->funcs = dc->funcs; } else if (bitmap->funcs != dc->funcs) { FIXME( "Trying to select bitmap %p in different DC type\n", hbitmap ); ret = FALSE; } GDI_ReleaseObj( hbitmap ); return ret; }
/*********************************************************************** * ScaleWindowExtEx (GDI32.@) */ BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT xNum, INT xDenom, INT yNum, INT yDenom, LPSIZE size ) { BOOL ret = TRUE; DC * dc = DC_GetDCPtr( hdc ); if (!dc) return FALSE; if (dc->funcs->pScaleWindowExt) { ret = dc->funcs->pScaleWindowExt( dc, xNum, xDenom, yNum, yDenom ); goto done; } if (size) { size->cx = dc->wndExtX; size->cy = dc->wndExtY; } if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC)) goto done; if (!xNum || !xDenom || !xNum || !yDenom) { ret = FALSE; goto done; } dc->wndExtX = (dc->wndExtX * xNum) / xDenom; dc->wndExtY = (dc->wndExtY * yNum) / yDenom; if (dc->wndExtX == 0) dc->wndExtX = 1; if (dc->wndExtY == 0) dc->wndExtY = 1; if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc ); DC_UpdateXforms( dc ); done: GDI_ReleaseObj( hdc ); return ret; }
/*********************************************************************** * SetWindowExtEx (GDI32.@) */ BOOL WINAPI SetWindowExtEx( HDC hdc, INT x, INT y, LPSIZE size ) { BOOL ret = TRUE; DC * dc = DC_GetDCPtr( hdc ); if (!dc) return FALSE; if (dc->funcs->pSetWindowExt) { ret = dc->funcs->pSetWindowExt( dc, x, y ); goto done; } if (size) { size->cx = dc->wndExtX; size->cy = dc->wndExtY; } if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC)) goto done; if (!x || !y) { ret = FALSE; goto done; } dc->wndExtX = x; dc->wndExtY = y; if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc ); DC_UpdateXforms( dc ); done: GDI_ReleaseObj( hdc ); return ret; }
/*********************************************************************** * GetPaletteEntries [GDI32.@] * * Retrieves palette entries. * * RETURNS * Success: Number of entries from logical palette * Failure: 0 */ UINT WINAPI GetPaletteEntries( HPALETTE hpalette, /* [in] Handle of logical palette */ UINT start, /* [in] First entry to receive */ UINT count, /* [in] Number of entries to receive */ LPPALETTEENTRY entries) /* [out] Address of array receiving entries */ { PALETTEOBJ * palPtr; UINT numEntries; TRACE("hpal = %p, count=%i\n", hpalette, count ); palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL ); if (!palPtr) return 0; /* NOTE: not documented but test show this to be the case */ if (count == 0) { count = palPtr->count; } else { numEntries = palPtr->count; if (start+count > numEntries) count = numEntries - start; if (entries) { if (start >= numEntries) count = 0; else memcpy( entries, &palPtr->entries[start], count * sizeof(PALETTEENTRY) ); } } GDI_ReleaseObj( hpalette ); return count; }
/*********************************************************************** * GDIRealizePalette (Not a Windows API) */ UINT WINAPI GDIRealizePalette( HDC hdc ) { UINT realized = 0; DC* dc = get_dc_ptr( hdc ); if (!dc) return 0; TRACE("%p...\n", hdc ); if( dc->hPalette == GetStockObject( DEFAULT_PALETTE )) { PHYSDEV physdev = GET_DC_PHYSDEV( dc, pRealizeDefaultPalette ); realized = physdev->funcs->pRealizeDefaultPalette( physdev ); } else if (InterlockedExchangePointer( (void **)&hLastRealizedPalette, dc->hPalette ) != dc->hPalette) { PHYSDEV physdev = GET_DC_PHYSDEV( dc, pRealizePalette ); PALETTEOBJ *palPtr = GDI_GetObjPtr( dc->hPalette, OBJ_PAL ); if (palPtr) { realized = physdev->funcs->pRealizePalette( physdev, dc->hPalette, (dc->hPalette == hPrimaryPalette) ); palPtr->unrealize = physdev->funcs->pUnrealizePalette; GDI_ReleaseObj( dc->hPalette ); } } else TRACE(" skipping (hLastRealizedPalette = %p)\n", hLastRealizedPalette); release_dc_ptr( dc ); TRACE(" realized %i colors.\n", realized ); return realized; }
/*********************************************************************** * UnrealizeObject (GDI32.@) */ BOOL WINAPI UnrealizeObject( HGDIOBJ obj ) { BOOL result = TRUE; /* Check if object is valid */ GDIOBJHDR * header = GDI_GetObjPtr( obj, MAGIC_DONTCARE ); if (!header) return FALSE; TRACE("%04x\n", obj ); /* Unrealize object */ switch(GDIMAGIC(header->wMagic)) { case PALETTE_MAGIC: result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header ); break; case BRUSH_MAGIC: /* Windows resets the brush origin. We don't need to. */ break; } GDI_ReleaseObj( obj ); return result; }
/*********************************************************************** * IntersectVisRect (GDI.98) */ INT16 WINAPI IntersectVisRect16( HDC16 hdc16, INT16 left, INT16 top, INT16 right, INT16 bottom ) { HRGN tempRgn; INT16 ret; POINT pt[2]; HDC hdc = HDC_32( hdc16 ); DC * dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; pt[0].x = left; pt[0].y = top; pt[1].x = right; pt[1].y = bottom; LPtoDP( hdc, pt, 2 ); TRACE("%p %ld,%ld - %ld,%ld\n", hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y); if (!(tempRgn = CreateRectRgn( pt[0].x, pt[0].y, pt[1].x, pt[1].y ))) ret = ERROR; else { ret = CombineRgn( dc->hVisRgn, dc->hVisRgn, tempRgn, RGN_AND ); DeleteObject( tempRgn ); } if (ret != ERROR) CLIPPING_UpdateGCRegion( dc ); GDI_ReleaseObj( hdc ); return ret; }
/*********************************************************************** * GetCurrentObject (GDI32.@) */ HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type) { HANDLE ret = 0; DC * dc = DC_GetDCPtr( hdc ); if (dc) { switch (type) { case OBJ_PEN: ret = dc->hPen; break; case OBJ_BRUSH: ret = dc->hBrush; break; case OBJ_PAL: ret = dc->hPalette; break; case OBJ_FONT: ret = dc->hFont; break; case OBJ_BITMAP: ret = dc->hBitmap; break; default: /* the SDK only mentions those above */ FIXME("(%08x,%d): unknown type.\n",hdc,type); break; } GDI_ReleaseObj( hdc ); } return ret; }
/*********************************************************************** * GetObject (GDI.82) */ INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer ) { GDIOBJHDR * ptr; INT16 result = 0; TRACE("%04x %d %p\n", handle, count, buffer ); if (!count) return 0; if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0; switch(GDIMAGIC(ptr->wMagic)) { case PEN_MAGIC: result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer ); break; case BRUSH_MAGIC: result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer ); break; case BITMAP_MAGIC: result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer ); break; case FONT_MAGIC: result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer ); break; case PALETTE_MAGIC: result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer ); break; } GDI_ReleaseObj( handle ); return result; }
/*********************************************************************** * GetObjectW (GDI32.@) */ INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer ) { GDIOBJHDR * ptr; INT result = 0; TRACE("%08x %d %p\n", handle, count, buffer ); if (!count) return 0; if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0; switch(GDIMAGIC(ptr->wMagic)) { case PEN_MAGIC: result = PEN_GetObject( (PENOBJ *)ptr, count, buffer ); break; case BRUSH_MAGIC: result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer ); break; case BITMAP_MAGIC: result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer ); break; case FONT_MAGIC: result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer ); break; case PALETTE_MAGIC: result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer ); break; default: FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) ); break; } GDI_ReleaseObj( handle ); return result; }
/****************************************************************************** * ExtSelectClipRgn [GDI32.@] */ INT WINAPI ExtSelectClipRgn( HDC hdc, HRGN hrgn, INT fnMode ) { INT retval; RECT rect; DC * dc = DC_GetDCUpdate( hdc ); if (!dc) return ERROR; TRACE("%p %p %d\n", hdc, hrgn, fnMode ); if (dc->funcs->pExtSelectClipRgn) { retval = dc->funcs->pExtSelectClipRgn( dc->physDev, hrgn, fnMode ); GDI_ReleaseObj( hdc ); return retval; } if (!hrgn) { if (fnMode == RGN_COPY) { if (dc->hClipRgn) DeleteObject( dc->hClipRgn ); dc->hClipRgn = 0; } else { FIXME("Unimplemented: hrgn NULL in mode: %d\n", fnMode); GDI_ReleaseObj( hdc ); return ERROR; } } else { if (!dc->hClipRgn) create_default_clip_region( dc ); if(fnMode == RGN_COPY) CombineRgn( dc->hClipRgn, hrgn, 0, fnMode ); else CombineRgn( dc->hClipRgn, dc->hClipRgn, hrgn, fnMode); } CLIPPING_UpdateGCRegion( dc ); GDI_ReleaseObj( hdc ); return GetClipBox(hdc, &rect); }
/*********************************************************************** * GetBitmapBits [GDI32.@] * * Copies bitmap bits of bitmap to buffer. * * RETURNS * Success: Number of bytes copied * Failure: 0 */ LONG WINAPI GetBitmapBits( HBITMAP hbitmap, /* [in] Handle to bitmap */ LONG count, /* [in] Number of bytes to copy */ LPVOID bits) /* [out] Pointer to buffer to receive bits */ { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *info = (BITMAPINFO *)buffer; struct gdi_image_bits src_bits; struct bitblt_coords src; int dst_stride, max, ret; BITMAPOBJ *bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ); if (!bmp) return 0; dst_stride = get_bitmap_stride( bmp->dib.dsBm.bmWidth, bmp->dib.dsBm.bmBitsPixel ); ret = max = dst_stride * bmp->dib.dsBm.bmHeight; if (!bits) goto done; if (count > max) count = max; ret = count; src.visrect.left = 0; src.visrect.right = bmp->dib.dsBm.bmWidth; src.visrect.top = 0; src.visrect.bottom = (count + dst_stride - 1) / dst_stride; src.x = src.y = 0; src.width = src.visrect.right - src.visrect.left; src.height = src.visrect.bottom - src.visrect.top; if (!get_image_from_bitmap( bmp, info, &src_bits, &src )) { const char *src_ptr = src_bits.ptr; int src_stride = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount ); /* GetBitmapBits returns 16-bit aligned data */ if (info->bmiHeader.biHeight > 0) { src_ptr += (info->bmiHeader.biHeight - 1) * src_stride; src_stride = -src_stride; } src_ptr += src.visrect.top * src_stride; if (src_stride == dst_stride) memcpy( bits, src_ptr, count ); else while (count > 0) { memcpy( bits, src_ptr, min( count, dst_stride ) ); src_ptr += src_stride; bits = (char *)bits + dst_stride; count -= dst_stride; } if (src_bits.free) src_bits.free( &src_bits ); } else ret = 0; done: GDI_ReleaseObj( hbitmap ); return ret; }
/*********************************************************************** * AnimatePalette [GDI32.@] * * Replaces entries in logical palette. * * RETURNS * Success: TRUE * Failure: FALSE * * FIXME * Should use existing mapping when animating a primary palette */ BOOL WINAPI AnimatePalette( HPALETTE hPal, /* [in] Handle to logical palette */ UINT StartIndex, /* [in] First entry in palette */ UINT NumEntries, /* [in] Count of entries in palette */ const PALETTEENTRY* PaletteColors) /* [in] Pointer to first replacement */ { TRACE("%p (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries); if( hPal != GetStockObject(DEFAULT_PALETTE) ) { PALETTEOBJ * palPtr; UINT pal_entries; const PALETTEENTRY *pptr = PaletteColors; const DC_FUNCTIONS *funcs; palPtr = GDI_GetObjPtr( hPal, OBJ_PAL ); if (!palPtr) return 0; pal_entries = palPtr->count; if (StartIndex >= pal_entries) { GDI_ReleaseObj( hPal ); return 0; } if (StartIndex+NumEntries > pal_entries) NumEntries = pal_entries - StartIndex; for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) { /* According to MSDN, only animate PC_RESERVED colours */ if (palPtr->entries[StartIndex].peFlags & PC_RESERVED) { TRACE("Animating colour (%d,%d,%d) to (%d,%d,%d)\n", palPtr->entries[StartIndex].peRed, palPtr->entries[StartIndex].peGreen, palPtr->entries[StartIndex].peBlue, pptr->peRed, pptr->peGreen, pptr->peBlue); palPtr->entries[StartIndex] = *pptr; } else { TRACE("Not animating entry %d -- not PC_RESERVED\n", StartIndex); } } funcs = palPtr->funcs; GDI_ReleaseObj( hPal ); if (funcs && funcs->pRealizePalette) funcs->pRealizePalette( NULL, hPal, hPal == hPrimaryPalette ); } return TRUE; }
/********************************************************************** * SetAbortProc (GDI32.@) * */ INT WINAPI SetAbortProc(HDC hdc, ABORTPROC abrtprc) { DC *dc = DC_GetDCPtr( hdc ); if (!dc) return FALSE; dc->pAbortProc = abrtprc; GDI_ReleaseObj( hdc ); return TRUE; }
/********************************************************************** * SetAbortProc (GDI.381) */ INT16 WINAPI SetAbortProc16(HDC16 hdc, ABORTPROC16 abrtprc) { DC *dc = DC_GetDCPtr( hdc ); if (!dc) return FALSE; dc->pAbortProc16 = abrtprc; GDI_ReleaseObj( hdc ); return SetAbortProc( hdc, call_abort_proc16 ); }
/*********************************************************************** * dec_ref_count * * Decrement the reference count of a GDI object. */ inline static void dec_ref_count( HGDIOBJ handle ) { GDIOBJHDR *header; if ((header = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) { if (header->dwCount) header->dwCount--; if (header->dwCount != 0x80000000) GDI_ReleaseObj( handle ); else { /* handle delayed DeleteObject*/ header->dwCount = 0; GDI_ReleaseObj( handle ); TRACE( "executing delayed DeleteObject for %04x\n", handle ); DeleteObject( handle ); } } }