gdi32: Add a driver entry point for CreateCompatibleDC.

This commit is contained in:
Alexandre Julliard 2011-09-07 15:36:58 +02:00
parent 901c1997cb
commit cef1832bfb
9 changed files with 124 additions and 87 deletions

View File

@ -719,7 +719,7 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
{
DC *dc, *origDC;
HDC ret;
const DC_FUNCTIONS *funcs = NULL;
const struct gdi_dc_funcs *funcs = &null_driver;
PHYSDEV physDev = NULL;
GDI_CheckNotLock();
@ -727,14 +727,11 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
if (hdc)
{
if (!(origDC = get_dc_ptr( hdc ))) return 0;
physDev = GET_DC_PHYSDEV( origDC, pCreateDC );
if (physDev != &origDC->nulldrv) funcs = physDev->funcs;
else physDev = NULL;
physDev = GET_DC_PHYSDEV( origDC, pCreateCompatibleDC );
funcs = physDev->funcs;
release_dc_ptr( origDC );
}
if (!funcs && !(funcs = DRIVER_get_display_driver())) return 0;
if (!(dc = alloc_dc_ptr( OBJ_MEMDC ))) goto error;
TRACE("(%p): returning %p\n", hdc, dc->hSelf );
@ -748,17 +745,10 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
ret = dc->hSelf;
/* Pass the driver-specific physical device info into
* the new DC. The driver may use this read-only info
* while creating the compatible DC. */
if (funcs->pCreateDC)
if (!funcs->pCreateCompatibleDC( physDev, &dc->physDev ))
{
if (!funcs->pCreateDC( dc->hSelf, &physDev, NULL, NULL, NULL, NULL ))
{
WARN("creation aborted by device\n");
goto error;
}
push_dc_driver( &dc->physDev, physDev, funcs );
WARN("creation aborted by device\n");
goto error;
}
DC_InitDC( dc );
release_dc_ptr( dc );

View File

@ -493,6 +493,7 @@ const DC_FUNCTIONS dib_driver =
NULL, /* pChord */
NULL, /* pCloseFigure */
NULL, /* pCreateBitmap */
NULL, /* pCreateCompatibleDC */
NULL, /* pCreateDC */
NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */

View File

@ -86,11 +86,11 @@ static struct graphics_driver *create_driver( HMODULE module )
/**********************************************************************
* DRIVER_get_display_driver
* get_display_driver
*
* Special case for loading the display driver: get the name from the config file
*/
const DC_FUNCTIONS *DRIVER_get_display_driver(void)
static const struct gdi_dc_funcs *get_display_driver(void)
{
struct graphics_driver *driver;
char buffer[MAX_PATH], libname[32], *name, *next;
@ -146,7 +146,7 @@ const DC_FUNCTIONS *DRIVER_load_driver( LPCWSTR name )
static const WCHAR display1W[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
/* display driver is a special case */
if (!strcmpiW( name, displayW ) || !strcmpiW( name, display1W )) return DRIVER_get_display_driver();
if (!strcmpiW( name, displayW ) || !strcmpiW( name, display1W )) return get_display_driver();
if ((module = GetModuleHandleW( name )))
{
@ -218,6 +218,12 @@ static BOOL nulldrv_CreateBitmap( PHYSDEV dev, HBITMAP bitmap )
return TRUE;
}
static BOOL nulldrv_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev )
{
if (!display_driver || !display_driver->funcs->pCreateCompatibleDC) return TRUE;
return display_driver->funcs->pCreateCompatibleDC( NULL, pdev );
}
static BOOL nulldrv_CreateDC( HDC hdc, PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
LPCWSTR output, const DEVMODEW *devmode )
{
@ -664,6 +670,7 @@ const DC_FUNCTIONS null_driver =
nulldrv_Chord, /* pChord */
nulldrv_CloseFigure, /* pCloseFigure */
nulldrv_CreateBitmap, /* pCreateBitmap */
nulldrv_CreateCompatibleDC, /* pCreateCompatibleDC */
nulldrv_CreateDC, /* pCreateDC */
nulldrv_CreateDIBSection, /* pCreateDIBSection */
nulldrv_DeleteBitmap, /* pDeleteBitmap */

View File

@ -47,6 +47,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
EMFDRV_Chord, /* pChord */
EMFDRV_CloseFigure, /* pCloseFigure */
NULL, /* pCreateBitmap */
NULL, /* pCreateCompatibleDC */
NULL, /* pCreateDC */
NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */

View File

@ -342,7 +342,6 @@ extern DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, str
/* driver.c */
extern const DC_FUNCTIONS null_driver DECLSPEC_HIDDEN;
extern const DC_FUNCTIONS dib_driver DECLSPEC_HIDDEN;
extern const DC_FUNCTIONS *DRIVER_get_display_driver(void) DECLSPEC_HIDDEN;
extern const DC_FUNCTIONS *DRIVER_load_driver( LPCWSTR name ) DECLSPEC_HIDDEN;
extern BOOL DRIVER_GetDriverName( LPCWSTR device, LPWSTR driver, DWORD size ) DECLSPEC_HIDDEN;

View File

@ -91,6 +91,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
MFDRV_Chord, /* pChord */
MFDRV_CloseFigure, /* pCloseFigure */
NULL, /* pCreateBitmap */
NULL, /* pCreateCompatibleDC */
NULL, /* pCreateDC */
NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */

View File

@ -114,6 +114,7 @@ static const LOGFONTA DefaultLogFont = {
};
static const CHAR default_devmodeA[] = "Default DevMode";
static const struct gdi_dc_funcs psdrv_funcs;
/*********************************************************************
* DllMain
@ -298,6 +299,27 @@ static LPDEVMODEA DEVMODEdupWtoA(HANDLE heap, const DEVMODEW *dmW)
}
static PSDRV_PDEVICE *create_psdrv_physdev( PRINTERINFO *pi )
{
PSDRV_PDEVICE *physDev;
physDev = HeapAlloc( PSDRV_Heap, HEAP_ZERO_MEMORY, sizeof(*physDev) );
if (!physDev) return NULL;
physDev->Devmode = HeapAlloc( PSDRV_Heap, 0, sizeof(PSDRV_DEVMODEA) );
if (!physDev->Devmode)
{
HeapFree( PSDRV_Heap, 0, physDev );
return NULL;
}
*physDev->Devmode = *pi->Devmode;
physDev->pi = pi;
physDev->logPixelsX = pi->ppd->DefaultResolution;
physDev->logPixelsY = pi->ppd->DefaultResolution;
return physDev;
}
/**********************************************************************
* PSDRV_CreateDC
*/
@ -306,26 +328,18 @@ static BOOL PSDRV_CreateDC( HDC hdc, PHYSDEV *pdev, LPCWSTR driver, LPCWSTR devi
{
PSDRV_PDEVICE *physDev;
PRINTERINFO *pi;
/* If no device name was specified, retrieve the device name
* from the PRINTERINFO structure from the DC's physDev.
* (See CreateCompatibleDC) */
if ( !device && *pdev )
{
pi = PSDRV_FindPrinterInfo(get_psdrv_dev(*pdev)->pi->FriendlyName);
}
else
{
DWORD len = WideCharToMultiByte(CP_ACP, 0, device, -1, NULL, 0, NULL, NULL);
char *deviceA = HeapAlloc(GetProcessHeap(), 0, len);
WideCharToMultiByte(CP_ACP, 0, device, -1, deviceA, len, NULL, NULL);
pi = PSDRV_FindPrinterInfo(deviceA);
HeapFree(GetProcessHeap(), 0, deviceA);
}
DWORD len;
char *deviceA;
TRACE("(%s %s %s %p)\n", debugstr_w(driver), debugstr_w(device),
debugstr_w(output), initData);
if (!device) return FALSE;
len = WideCharToMultiByte(CP_ACP, 0, device, -1, NULL, 0, NULL, NULL);
deviceA = HeapAlloc(GetProcessHeap(), 0, len);
WideCharToMultiByte(CP_ACP, 0, device, -1, deviceA, len, NULL, NULL);
pi = PSDRV_FindPrinterInfo(deviceA);
HeapFree(GetProcessHeap(), 0, deviceA);
if(!pi) return FALSE;
if(!pi->Fonts) {
@ -339,30 +353,14 @@ static BOOL PSDRV_CreateDC( HDC hdc, PHYSDEV *pdev, LPCWSTR driver, LPCWSTR devi
}
}
physDev = HeapAlloc( PSDRV_Heap, HEAP_ZERO_MEMORY, sizeof(*physDev) );
if (!physDev) return FALSE;
if (!(physDev = create_psdrv_physdev( pi ))) return FALSE;
*pdev = &physDev->dev;
physDev->pi = pi;
physDev->Devmode = HeapAlloc( PSDRV_Heap, 0, sizeof(PSDRV_DEVMODEA) );
if(!physDev->Devmode) {
HeapFree( PSDRV_Heap, 0, physDev );
return FALSE;
}
*physDev->Devmode = *pi->Devmode;
physDev->logPixelsX = physDev->pi->ppd->DefaultResolution;
physDev->logPixelsY = physDev->pi->ppd->DefaultResolution;
if (output && *output) {
INT len = WideCharToMultiByte( CP_ACP, 0, output, -1, NULL, 0, NULL, NULL );
if ((physDev->job.output = HeapAlloc( PSDRV_Heap, 0, len )))
WideCharToMultiByte( CP_ACP, 0, output, -1, physDev->job.output, len, NULL, NULL );
} else
physDev->job.output = NULL;
physDev->job.id = 0;
}
if(initData) {
DEVMODEA *devmodeA = DEVMODEdupWtoA(PSDRV_Heap, initData);
@ -376,6 +374,24 @@ static BOOL PSDRV_CreateDC( HDC hdc, PHYSDEV *pdev, LPCWSTR driver, LPCWSTR devi
}
/**********************************************************************
* PSDRV_CreateCompatibleDC
*/
static BOOL PSDRV_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev )
{
HDC hdc = (*pdev)->hdc;
PSDRV_PDEVICE *physDev, *orig_dev = get_psdrv_dev( orig );
PRINTERINFO *pi = PSDRV_FindPrinterInfo( orig_dev->pi->FriendlyName );
if (!pi) return FALSE;
if (!(physDev = create_psdrv_physdev( pi ))) return FALSE;
PSDRV_UpdateDevCaps(physDev);
SelectObject( hdc, PSDRV_DefaultFont );
push_dc_driver( pdev, &physDev->dev, &psdrv_funcs );
return TRUE;
}
/**********************************************************************
* PSDRV_DeleteDC
@ -813,6 +829,7 @@ static const struct gdi_dc_funcs psdrv_funcs =
PSDRV_Chord, /* pChord */
NULL, /* pCloseFigure */
NULL, /* pCreateBitmap */
PSDRV_CreateCompatibleDC, /* pCreateCompatibleDC */
PSDRV_CreateDC, /* pCreateDC */
NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */

View File

@ -51,6 +51,7 @@ unsigned int text_caps = (TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
static const WCHAR dpi_key_name[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s','\0'};
static const WCHAR dpi_value_name[] = {'L','o','g','P','i','x','e','l','s','\0'};
static const struct gdi_dc_funcs x11drv_funcs;
/******************************************************************************
* get_dpi
@ -115,50 +116,68 @@ void X11DRV_GDI_Finalize(void)
/* XCloseDisplay( gdi_display ); */
}
static X11DRV_PDEVICE *create_x11_physdev( Drawable drawable )
{
X11DRV_PDEVICE *physDev;
if (!device_init_done) device_init();
if (!(physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physDev) ))) return NULL;
if (!(physDev->region = CreateRectRgn( 0, 0, 0, 0 )))
{
HeapFree( GetProcessHeap(), 0, physDev );
return NULL;
}
wine_tsx11_lock();
physDev->drawable = drawable;
physDev->gc = XCreateGC( gdi_display, drawable, 0, NULL );
XSetGraphicsExposures( gdi_display, physDev->gc, False );
XSetSubwindowMode( gdi_display, physDev->gc, IncludeInferiors );
XFlush( gdi_display );
wine_tsx11_unlock();
return physDev;
}
/**********************************************************************
* X11DRV_CreateDC
*/
static BOOL X11DRV_CreateDC( HDC hdc, PHYSDEV *pdev, LPCWSTR driver, LPCWSTR device,
LPCWSTR output, const DEVMODEW* initData )
{
X11DRV_PDEVICE *physDev;
X11DRV_PDEVICE *physDev = create_x11_physdev( root_window );
if (!device_init_done) device_init();
physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physDev) );
if (!physDev) return FALSE;
physDev->depth = screen_depth;
physDev->color_shifts = &X11DRV_PALETTE_default_shifts;
physDev->drawable_rect = virtual_screen_rect;
SetRect( &physDev->dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left,
virtual_screen_rect.bottom - virtual_screen_rect.top );
*pdev = &physDev->dev;
return TRUE;
}
if (GetObjectType( hdc ) == OBJ_MEMDC)
{
if (!BITMAP_stock_phys_bitmap.hbitmap)
BITMAP_stock_phys_bitmap.hbitmap = GetCurrentObject( hdc, OBJ_BITMAP );
physDev->bitmap = &BITMAP_stock_phys_bitmap;
physDev->drawable = BITMAP_stock_phys_bitmap.pixmap;
physDev->depth = 1;
physDev->color_shifts = NULL;
SetRect( &physDev->drawable_rect, 0, 0, 1, 1 );
physDev->dc_rect = physDev->drawable_rect;
}
else
{
physDev->bitmap = NULL;
physDev->drawable = root_window;
physDev->depth = screen_depth;
physDev->color_shifts = &X11DRV_PALETTE_default_shifts;
physDev->drawable_rect = virtual_screen_rect;
SetRect( &physDev->dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left,
virtual_screen_rect.bottom - virtual_screen_rect.top );
}
physDev->region = CreateRectRgn( 0, 0, 0, 0 );
wine_tsx11_lock();
physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL );
XSetGraphicsExposures( gdi_display, physDev->gc, False );
XSetSubwindowMode( gdi_display, physDev->gc, IncludeInferiors );
XFlush( gdi_display );
wine_tsx11_unlock();
/**********************************************************************
* X11DRV_CreateCompatibleDC
*/
static BOOL X11DRV_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev )
{
X11DRV_PDEVICE *physDev = create_x11_physdev( BITMAP_stock_phys_bitmap.pixmap );
if (!physDev) return FALSE;
if (!BITMAP_stock_phys_bitmap.hbitmap)
BITMAP_stock_phys_bitmap.hbitmap = GetCurrentObject( (*pdev)->hdc, OBJ_BITMAP );
physDev->bitmap = &BITMAP_stock_phys_bitmap;
physDev->depth = 1;
SetRect( &physDev->drawable_rect, 0, 0, 1, 1 );
physDev->dc_rect = physDev->drawable_rect;
push_dc_driver( pdev, &physDev->dev, &x11drv_funcs );
return TRUE;
}
@ -456,6 +475,7 @@ static const struct gdi_dc_funcs x11drv_funcs =
X11DRV_Chord, /* pChord */
NULL, /* pCloseFigure */
X11DRV_CreateBitmap, /* pCreateBitmap */
X11DRV_CreateCompatibleDC, /* pCreateCompatibleDC */
X11DRV_CreateDC, /* pCreateDC */
X11DRV_CreateDIBSection, /* pCreateDIBSection */
X11DRV_DeleteBitmap, /* pDeleteBitmap */

View File

@ -65,6 +65,7 @@ struct gdi_dc_funcs
BOOL (*pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
BOOL (*pCloseFigure)(PHYSDEV);
BOOL (*pCreateBitmap)(PHYSDEV,HBITMAP);
BOOL (*pCreateCompatibleDC)(PHYSDEV,PHYSDEV*);
BOOL (*pCreateDC)(HDC,PHYSDEV *,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
HBITMAP (*pCreateDIBSection)(PHYSDEV,HBITMAP,BITMAPINFO *,UINT);
BOOL (*pDeleteBitmap)(HBITMAP);
@ -188,7 +189,7 @@ struct gdi_dc_funcs
};
/* increment this when you change the DC function table */
#define WINE_GDI_DRIVER_VERSION 11
#define WINE_GDI_DRIVER_VERSION 12
static inline PHYSDEV get_physdev_entry_point( PHYSDEV dev, size_t offset )
{