region_tt* region_tt::alloc() { size_t len = sizeof (gdi_region_shared_tt); BYTE *shm = alloc_gdi_shared_memory( len ); if (!shm) return NULL; BYTE *user_shm = kernel_to_user( shm ); region_tt* region = new region_tt; if (!region) return NULL; region->handle = alloc_gdi_handle( FALSE, GDI_OBJECT_REGION, user_shm, region ); if (!region->handle) { delete region; return 0; } region->rgn = (gdi_region_shared_tt*) shm; region->empty_region(); region->rgn->flags = 0; region->rgn->type = 0; region->maxRects = RGN_DEFAULT_RECTS; region->rects = new rect_tt[ region->maxRects ]; return region; }
/*********************************************************************** * CreatePalette [GDI32.@] * * Creates a logical color palette. * * RETURNS * Success: Handle to logical palette * Failure: NULL */ HPALETTE WINAPI CreatePalette( const LOGPALETTE* palette) /* [in] Pointer to logical color palette */ { PALETTEOBJ * palettePtr; HPALETTE hpalette; int size; if (!palette) return 0; TRACE("entries=%i\n", palette->palNumEntries); if (!(palettePtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*palettePtr) ))) return 0; palettePtr->unrealize = NULL; palettePtr->version = palette->palVersion; palettePtr->count = palette->palNumEntries; size = palettePtr->count * sizeof(*palettePtr->entries); if (!(palettePtr->entries = HeapAlloc( GetProcessHeap(), 0, size ))) { HeapFree( GetProcessHeap(), 0, palettePtr ); return 0; } memcpy( palettePtr->entries, palette->palPalEntry, size ); if (!(hpalette = alloc_gdi_handle( palettePtr, OBJ_PAL, &palette_funcs ))) { HeapFree( GetProcessHeap(), 0, palettePtr->entries ); HeapFree( GetProcessHeap(), 0, palettePtr ); } TRACE(" returning %p\n", hpalette); return hpalette; }
/*********************************************************************** * CreateBrushIndirect (GDI32.@) * * Create a logical brush with a given style, color or pattern. * * PARAMS * brush [I] Pointer to a LOGBRUSH structure describing the desired brush. * * RETURNS * A handle to the created brush, or a NULL handle if the brush cannot be * created. * * NOTES * - The brush returned should be freed by the caller using DeleteObject() * when it is no longer required. * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap * is used. */ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush ) { BRUSHOBJ * ptr; HBRUSH hbrush; HGLOBAL hmem = 0; if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) return 0; ptr->logbrush = *brush; switch (ptr->logbrush.lbStyle) { case BS_SOLID: case BS_HOLLOW: case BS_HATCHED: break; case BS_PATTERN8X8: ptr->logbrush.lbStyle = BS_PATTERN; /* fall through */ case BS_PATTERN: if (!copy_bitmap( ptr, (HBITMAP)ptr->logbrush.lbHatch )) goto error; ptr->logbrush.lbColor = 0; break; case BS_DIBPATTERN: hmem = (HGLOBAL)ptr->logbrush.lbHatch; if (!(ptr->logbrush.lbHatch = (ULONG_PTR)GlobalLock( hmem ))) goto error; /* fall through */ case BS_DIBPATTERNPT: ptr->usage = ptr->logbrush.lbColor; ptr->info = copy_packed_dib( (BITMAPINFO *)ptr->logbrush.lbHatch, ptr->usage ); if (hmem) GlobalUnlock( hmem ); if (!ptr->info) goto error; ptr->bits.ptr = (char *)ptr->info + get_dib_info_size( ptr->info, ptr->usage ); ptr->logbrush.lbStyle = BS_DIBPATTERN; ptr->logbrush.lbColor = 0; break; case BS_DIBPATTERN8X8: case BS_MONOPATTERN: case BS_INDEXED: default: WARN( "invalid brush style %u\n", ptr->logbrush.lbStyle ); goto error; } if ((hbrush = alloc_gdi_handle( &ptr->header, OBJ_BRUSH, &brush_funcs ))) { TRACE("%p\n", hbrush); return hbrush; } error: if (ptr->bitmap) DeleteObject( ptr->bitmap ); HeapFree( GetProcessHeap(), 0, ptr->info ); HeapFree( GetProcessHeap(), 0, ptr ); return 0; }
/*********************************************************************** * CreateBrushIndirect (GDI32.@) * * Create a logical brush with a given style, color or pattern. * * PARAMS * brush [I] Pointer to a LOGBRUSH structure describing the desired brush. * * RETURNS * A handle to the created brush, or a NULL handle if the brush cannot be * created. * * NOTES * - The brush returned should be freed by the caller using DeleteObject() * when it is no longer required. * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap * is used. */ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush ) { BRUSHOBJ * ptr; HBRUSH hbrush; if (!(ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr) ))) return 0; ptr->logbrush = *brush; if (store_brush_pattern( &ptr->logbrush, &ptr->pattern ) && (hbrush = alloc_gdi_handle( ptr, OBJ_BRUSH, &brush_funcs ))) { TRACE("%p\n", hbrush); return hbrush; } free_brush_pattern( &ptr->pattern ); HeapFree( GetProcessHeap(), 0, ptr ); return 0; }
/*********************************************************************** * CreatePenIndirect (GDI32.@) */ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen ) { PENOBJ * penPtr; HPEN hpen; if (pen->lopnStyle == PS_NULL) { hpen = GetStockObject(NULL_PEN); if (hpen) return hpen; } if (!(penPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*penPtr) ))) return 0; penPtr->logpen.elpPenStyle = pen->lopnStyle; penPtr->logpen.elpWidth = abs(pen->lopnWidth.x); penPtr->logpen.elpColor = pen->lopnColor; penPtr->logpen.elpBrushStyle = BS_SOLID; switch (pen->lopnStyle) { case PS_SOLID: case PS_DASH: case PS_DOT: case PS_DASHDOT: case PS_DASHDOTDOT: case PS_INSIDEFRAME: break; case PS_NULL: penPtr->logpen.elpWidth = 1; penPtr->logpen.elpColor = 0; break; default: penPtr->logpen.elpPenStyle = PS_SOLID; break; } if (!(hpen = alloc_gdi_handle( penPtr, OBJ_PEN, &pen_funcs ))) HeapFree( GetProcessHeap(), 0, penPtr ); return hpen; }
/*********************************************************************** * CreatePenIndirect (GDI32.@) */ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen ) { PENOBJ * penPtr; HPEN hpen; if (pen->lopnStyle == PS_NULL) { hpen = GetStockObject(NULL_PEN); if (hpen) return hpen; } if (!(penPtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*penPtr) ))) 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; if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_PEN, &pen_funcs ))) HeapFree( GetProcessHeap(), 0, penPtr ); return hpen; }
/****************************************************************************** * CreateBitmapIndirect [GDI32.@] * * Creates a bitmap with the specified info. * * PARAMS * bmp [I] Pointer to the bitmap info describing the bitmap * * RETURNS * Success: Handle to bitmap * Failure: NULL. Use GetLastError() to determine the cause. * * NOTES * If a width or height of 0 are given, a 1x1 monochrome bitmap is returned. */ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) { BITMAP bm; BITMAPOBJ *bmpobj; HBITMAP hbitmap; if (!bmp || bmp->bmType) { SetLastError( ERROR_INVALID_PARAMETER ); return NULL; } if (bmp->bmWidth > 0x7ffffff || bmp->bmHeight > 0x7ffffff) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; } bm = *bmp; if (!bm.bmWidth || !bm.bmHeight) { return GetStockObject( DEFAULT_BITMAP ); } else { if (bm.bmHeight < 0) bm.bmHeight = -bm.bmHeight; if (bm.bmWidth < 0) bm.bmWidth = -bm.bmWidth; } if (bm.bmPlanes != 1) { FIXME("planes = %d\n", bm.bmPlanes); SetLastError( ERROR_INVALID_PARAMETER ); return NULL; } /* Windows only uses 1, 4, 8, 16, 24 and 32 bpp */ if(bm.bmBitsPixel == 1) bm.bmBitsPixel = 1; else if(bm.bmBitsPixel <= 4) bm.bmBitsPixel = 4; else if(bm.bmBitsPixel <= 8) bm.bmBitsPixel = 8; else if(bm.bmBitsPixel <= 16) bm.bmBitsPixel = 16; else if(bm.bmBitsPixel <= 24) bm.bmBitsPixel = 24; else if(bm.bmBitsPixel <= 32) bm.bmBitsPixel = 32; else { WARN("Invalid bmBitsPixel %d, returning ERROR_INVALID_PARAMETER\n", bm.bmBitsPixel); SetLastError(ERROR_INVALID_PARAMETER); return NULL; } /* Windows ignores the provided bm.bmWidthBytes */ bm.bmWidthBytes = get_bitmap_stride( bm.bmWidth, bm.bmBitsPixel ); /* XP doesn't allow to create bitmaps larger than 128 Mb */ if (bm.bmHeight > 128 * 1024 * 1024 / bm.bmWidthBytes) { SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return 0; } /* Create the BITMAPOBJ */ if (!(bmpobj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*bmpobj) ))) { SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return 0; } bmpobj->dib.dsBm = bm; bmpobj->dib.dsBm.bmBits = NULL; if (!(hbitmap = alloc_gdi_handle( &bmpobj->header, OBJ_BITMAP, &bitmap_funcs ))) { HeapFree( GetProcessHeap(), 0, bmpobj ); return 0; } if (bm.bmBits) SetBitmapBits( hbitmap, bm.bmHeight * bm.bmWidthBytes, bm.bmBits ); TRACE("%dx%d, bpp %d planes %d: returning %p\n", bm.bmWidth, bm.bmHeight, bm.bmBitsPixel, bm.bmPlanes, hbitmap); return hbitmap; }
HPEN WINAPI ExtCreatePen( DWORD style, DWORD width, const LOGBRUSH * brush, DWORD style_count, const DWORD *style_bits ) { PENOBJ * penPtr; HPEN hpen; if ((style & PS_STYLE_MASK) == PS_USERSTYLE) { if(((INT)style_count) <= 0) return 0; if ((style_count > 16) || !style_bits) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } if ((style & PS_TYPE_MASK) == PS_GEOMETRIC) { UINT i; BOOL has_neg = FALSE, all_zero = TRUE; for(i = 0; (i < style_count) && !has_neg; i++) { has_neg = has_neg || (((INT)(style_bits[i])) < 0); all_zero = all_zero && (style_bits[i] == 0); } if(all_zero || has_neg) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } } } else { if (style_count || style_bits) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } } if ((style & PS_STYLE_MASK) == PS_NULL) return CreatePen( PS_NULL, 0, brush->lbColor ); if ((style & PS_TYPE_MASK) == PS_GEOMETRIC) { /* PS_ALTERNATE is applicable only for cosmetic pens */ if ((style & PS_STYLE_MASK) == PS_ALTERNATE) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } if (brush->lbHatch && ((brush->lbStyle != BS_SOLID) && (brush->lbStyle != BS_HOLLOW))) { static int fixme_hatches_shown; if (!fixme_hatches_shown++) FIXME("Hatches not implemented\n"); } } else { /* PS_INSIDEFRAME is applicable only for geometric pens */ if ((style & PS_STYLE_MASK) == PS_INSIDEFRAME || width != 1) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } } if (!(penPtr = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PENOBJ,logpen.elpStyleEntry[style_count])))) return 0; penPtr->logpen.elpPenStyle = style; penPtr->logpen.elpWidth = abs(width); penPtr->logpen.elpBrushStyle = brush->lbStyle; penPtr->logpen.elpColor = brush->lbColor; penPtr->logpen.elpHatch = brush->lbHatch; penPtr->logpen.elpNumEntries = style_count; memcpy(penPtr->logpen.elpStyleEntry, style_bits, style_count * sizeof(DWORD)); if (!(hpen = alloc_gdi_handle( &penPtr->header, OBJ_EXTPEN, &pen_funcs ))) HeapFree( GetProcessHeap(), 0, penPtr ); return hpen; }
HPEN WINAPI ExtCreatePen( DWORD style, DWORD width, const LOGBRUSH * brush, DWORD style_count, const DWORD *style_bits ) { PENOBJ *penPtr = NULL; HPEN hpen; LOGBRUSH logbrush; if ((style_count || style_bits) && (style & PS_STYLE_MASK) != PS_USERSTYLE) goto invalid; switch (style & PS_STYLE_MASK) { case PS_NULL: return CreatePen( PS_NULL, 0, brush->lbColor ); case PS_SOLID: case PS_DASH: case PS_DOT: case PS_DASHDOT: case PS_DASHDOTDOT: break; case PS_USERSTYLE: if (((INT)style_count) <= 0) return 0; if ((style_count > 16) || !style_bits) goto invalid; if ((style & PS_TYPE_MASK) == PS_GEOMETRIC) { UINT i; BOOL has_neg = FALSE, all_zero = TRUE; for(i = 0; (i < style_count) && !has_neg; i++) { has_neg = has_neg || (((INT)(style_bits[i])) < 0); all_zero = all_zero && (style_bits[i] == 0); } if (all_zero || has_neg) goto invalid; } break; case PS_INSIDEFRAME: /* applicable only for geometric pens */ if ((style & PS_TYPE_MASK) != PS_GEOMETRIC) goto invalid; break; case PS_ALTERNATE: /* applicable only for cosmetic pens */ if ((style & PS_TYPE_MASK) == PS_GEOMETRIC) goto invalid; break; default: SetLastError(ERROR_INVALID_PARAMETER); return 0; } if ((style & PS_TYPE_MASK) == PS_GEOMETRIC) { if (brush->lbStyle == BS_NULL) return CreatePen( PS_NULL, 0, 0 ); } else { if (width != 1) goto invalid; if (brush->lbStyle != BS_SOLID) goto invalid; } if (!(penPtr = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PENOBJ,logpen.elpStyleEntry[style_count])))) return 0; logbrush = *brush; if (!store_brush_pattern( &logbrush, &penPtr->pattern )) goto invalid; if (logbrush.lbStyle == BS_DIBPATTERN) logbrush.lbStyle = BS_DIBPATTERNPT; penPtr->logpen.elpPenStyle = style; penPtr->logpen.elpWidth = abs((int)width); penPtr->logpen.elpBrushStyle = logbrush.lbStyle; penPtr->logpen.elpColor = logbrush.lbColor; penPtr->logpen.elpHatch = brush->lbHatch; penPtr->logpen.elpNumEntries = style_count; memcpy(penPtr->logpen.elpStyleEntry, style_bits, style_count * sizeof(DWORD)); if (!(hpen = alloc_gdi_handle( penPtr, OBJ_EXTPEN, &pen_funcs ))) { free_brush_pattern( &penPtr->pattern ); HeapFree( GetProcessHeap(), 0, penPtr ); } return hpen; invalid: HeapFree( GetProcessHeap(), 0, penPtr ); SetLastError( ERROR_INVALID_PARAMETER ); return 0; }
/*********************************************************************** * CreateBrushIndirect (GDI32.@) * * Create a logical brush with a given style, color or pattern. * * PARAMS * brush [I] Pointer to a LOGBRUSH structure describing the desired brush. * * RETURNS * A handle to the created brush, or a NULL handle if the brush cannot be * created. * * NOTES * - The brush returned should be freed by the caller using DeleteObject() * when it is no longer required. * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap * is used. */ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush ) { BRUSHOBJ * ptr; HBRUSH hbrush; if (!(ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr) ))) return 0; ptr->logbrush.lbStyle = brush->lbStyle; ptr->logbrush.lbColor = brush->lbColor; ptr->logbrush.lbHatch = brush->lbHatch; switch (ptr->logbrush.lbStyle) { case BS_PATTERN8X8: ptr->logbrush.lbStyle = BS_PATTERN; /* fall through */ case BS_PATTERN: ptr->logbrush.lbHatch = (ULONG_PTR)BITMAP_CopyBitmap( (HBITMAP) ptr->logbrush.lbHatch ); if (!ptr->logbrush.lbHatch) goto error; break; case BS_DIBPATTERNPT: ptr->logbrush.lbStyle = BS_DIBPATTERN; ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( (BITMAPINFO *) ptr->logbrush.lbHatch, ptr->logbrush.lbColor); if (!ptr->logbrush.lbHatch) goto error; break; case BS_DIBPATTERN8X8: case BS_DIBPATTERN: { BITMAPINFO* bmi; HGLOBAL h = (HGLOBAL)ptr->logbrush.lbHatch; ptr->logbrush.lbStyle = BS_DIBPATTERN; if (!(bmi = GlobalLock( h ))) goto error; ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( bmi, ptr->logbrush.lbColor); GlobalUnlock( h ); if (!ptr->logbrush.lbHatch) goto error; break; } default: if(ptr->logbrush.lbStyle > BS_MONOPATTERN) goto error; break; } if ((hbrush = alloc_gdi_handle( &ptr->header, OBJ_BRUSH, &brush_funcs ))) { TRACE("%p\n", hbrush); return hbrush; } error: if (ptr->logbrush.lbHatch) { if (ptr->logbrush.lbStyle == BS_PATTERN) DeleteObject( (HGDIOBJ)ptr->logbrush.lbHatch ); else if (ptr->logbrush.lbStyle == BS_DIBPATTERN) GlobalFree( (HGLOBAL)ptr->logbrush.lbHatch ); } HeapFree( GetProcessHeap(), 0, ptr ); return 0; }