Exemplo n.º 1
0
Arquivo: dc.c Projeto: Barrell/wine
void dibdrv_set_window_surface( DC *dc, struct window_surface *surface )
{
    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *info = (BITMAPINFO *)buffer;
    RECT rect;
    void *bits;
    PHYSDEV windev;
    struct windrv_physdev *physdev;
    struct dibdrv_physdev *dibdrv;

    TRACE( "%p %p\n", dc->hSelf, surface );

    windev = pop_dc_driver( dc, &window_driver );

    if (surface)
    {
        if (windev) push_dc_driver( &dc->physDev, windev, windev->funcs );
        else
        {
            if (!window_driver.pCreateDC( &dc->physDev, NULL, NULL, NULL, NULL )) return;
            windev = find_dc_driver( dc, &window_driver );
        }

        physdev = get_windrv_physdev( windev );
        window_surface_add_ref( surface );
        if (physdev->surface) window_surface_release( physdev->surface );
        physdev->surface = surface;

        dibdrv = physdev->dibdrv;
        bits = surface->funcs->get_info( surface, info );
        init_dib_info_from_bitmapinfo( &dibdrv->dib, info, bits );
        /* clip the device rect to the surface */
        rect = surface->rect;
        offset_rect( &rect, dc->device_rect.left, dc->device_rect.top );
        intersect_rect( &dc->device_rect, &dc->device_rect, &rect );
        dibdrv->dib.rect = dc->vis_rect;
        offset_rect( &dibdrv->dib.rect, -rect.left, -rect.top );
        dibdrv->bounds = surface->funcs->get_bounds( surface );
        DC_InitDC( dc );
    }
    else if (windev)
    {
        dib_driver.pDeleteDC( pop_dc_driver( dc, &dib_driver ));
        windev->funcs->pDeleteDC( windev );
        DC_InitDC( dc );
    }
}
Exemplo n.º 2
0
Arquivo: bitmap.c Projeto: bpon/wine
/***********************************************************************
 *           BITMAP_SelectObject
 */
static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
{
    HGDIOBJ ret;
    BITMAPOBJ *bitmap;
    DC *dc;
    PHYSDEV physdev = NULL, old_physdev = NULL, pathdev = NULL;

    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, OBJ_BITMAP )))
    {
        ret = 0;
        goto done;
    }

    if (bitmap->header.selcount && (handle != GetStockObject(DEFAULT_BITMAP)))
    {
        WARN( "Bitmap already selected in another DC\n" );
        GDI_ReleaseObj( handle );
        ret = 0;
        goto done;
    }

    if (dc->physDev->funcs == &path_driver) pathdev = pop_dc_driver( &dc->physDev );

    old_physdev = GET_DC_PHYSDEV( dc, pSelectBitmap );
    if(old_physdev == dc->dibdrv)
        old_physdev = pop_dc_driver( &dc->physDev );

    physdev = GET_DC_PHYSDEV( dc, pSelectBitmap );
    if (bitmap->dib || physdev->funcs == &null_driver)
    {
        physdev = dc->dibdrv;
        if (physdev) push_dc_driver( &dc->physDev, physdev, physdev->funcs );
        else
        {
            if (!dib_driver.pCreateDC( &dc->physDev, NULL, NULL, NULL, NULL )) goto done;
            dc->dibdrv = physdev = dc->physDev;
        }
    }

    if (!BITMAP_SetOwnerDC( handle, physdev ))
    {
        GDI_ReleaseObj( handle );
        ret = 0;
        goto done;
    }
    if (!physdev->funcs->pSelectBitmap( physdev, handle ))
    {
        GDI_ReleaseObj( handle );
        ret = 0;
    }
    else
    {
        dc->hBitmap = handle;
        GDI_inc_ref_count( handle );
        dc->dirty = 0;
        dc->vis_rect.left   = 0;
        dc->vis_rect.top    = 0;
        dc->vis_rect.right  = bitmap->bitmap.bmWidth;
        dc->vis_rect.bottom = bitmap->bitmap.bmHeight;
        GDI_ReleaseObj( handle );
        DC_InitDC( dc );
        GDI_dec_ref_count( ret );
    }

 done:
    if(!ret)
    {
        if (physdev && physdev == dc->dibdrv)
            pop_dc_driver( &dc->physDev );
        if (old_physdev && old_physdev == dc->dibdrv)
            push_dc_driver( &dc->physDev, old_physdev, old_physdev->funcs );
    }
    if (pathdev) push_dc_driver( &dc->physDev, pathdev, pathdev->funcs );
    release_dc_ptr( dc );
    return ret;
}