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

View File

@ -493,6 +493,7 @@ const DC_FUNCTIONS dib_driver =
NULL, /* pChord */ NULL, /* pChord */
NULL, /* pCloseFigure */ NULL, /* pCloseFigure */
NULL, /* pCreateBitmap */ NULL, /* pCreateBitmap */
NULL, /* pCreateCompatibleDC */
NULL, /* pCreateDC */ NULL, /* pCreateDC */
NULL, /* pCreateDIBSection */ NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */ 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 * 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; struct graphics_driver *driver;
char buffer[MAX_PATH], libname[32], *name, *next; 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}; static const WCHAR display1W[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
/* display driver is a special case */ /* 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 ))) if ((module = GetModuleHandleW( name )))
{ {
@ -218,6 +218,12 @@ static BOOL nulldrv_CreateBitmap( PHYSDEV dev, HBITMAP bitmap )
return TRUE; 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, static BOOL nulldrv_CreateDC( HDC hdc, PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
LPCWSTR output, const DEVMODEW *devmode ) LPCWSTR output, const DEVMODEW *devmode )
{ {
@ -664,6 +670,7 @@ const DC_FUNCTIONS null_driver =
nulldrv_Chord, /* pChord */ nulldrv_Chord, /* pChord */
nulldrv_CloseFigure, /* pCloseFigure */ nulldrv_CloseFigure, /* pCloseFigure */
nulldrv_CreateBitmap, /* pCreateBitmap */ nulldrv_CreateBitmap, /* pCreateBitmap */
nulldrv_CreateCompatibleDC, /* pCreateCompatibleDC */
nulldrv_CreateDC, /* pCreateDC */ nulldrv_CreateDC, /* pCreateDC */
nulldrv_CreateDIBSection, /* pCreateDIBSection */ nulldrv_CreateDIBSection, /* pCreateDIBSection */
nulldrv_DeleteBitmap, /* pDeleteBitmap */ nulldrv_DeleteBitmap, /* pDeleteBitmap */

View File

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

View File

@ -342,7 +342,6 @@ extern DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, str
/* driver.c */ /* driver.c */
extern const DC_FUNCTIONS null_driver DECLSPEC_HIDDEN; extern const DC_FUNCTIONS null_driver DECLSPEC_HIDDEN;
extern const DC_FUNCTIONS dib_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 const DC_FUNCTIONS *DRIVER_load_driver( LPCWSTR name ) DECLSPEC_HIDDEN;
extern BOOL DRIVER_GetDriverName( LPCWSTR device, LPWSTR driver, DWORD size ) 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_Chord, /* pChord */
MFDRV_CloseFigure, /* pCloseFigure */ MFDRV_CloseFigure, /* pCloseFigure */
NULL, /* pCreateBitmap */ NULL, /* pCreateBitmap */
NULL, /* pCreateCompatibleDC */
NULL, /* pCreateDC */ NULL, /* pCreateDC */
NULL, /* pCreateDIBSection */ NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */ NULL, /* pDeleteBitmap */

View File

@ -114,6 +114,7 @@ static const LOGFONTA DefaultLogFont = {
}; };
static const CHAR default_devmodeA[] = "Default DevMode"; static const CHAR default_devmodeA[] = "Default DevMode";
static const struct gdi_dc_funcs psdrv_funcs;
/********************************************************************* /*********************************************************************
* DllMain * 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 * PSDRV_CreateDC
*/ */
@ -306,26 +328,18 @@ static BOOL PSDRV_CreateDC( HDC hdc, PHYSDEV *pdev, LPCWSTR driver, LPCWSTR devi
{ {
PSDRV_PDEVICE *physDev; PSDRV_PDEVICE *physDev;
PRINTERINFO *pi; PRINTERINFO *pi;
DWORD len;
/* If no device name was specified, retrieve the device name char *deviceA;
* 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);
}
TRACE("(%s %s %s %p)\n", debugstr_w(driver), debugstr_w(device), TRACE("(%s %s %s %p)\n", debugstr_w(driver), debugstr_w(device),
debugstr_w(output), initData); 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) return FALSE;
if(!pi->Fonts) { 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 = create_psdrv_physdev( pi ))) return FALSE;
if (!physDev) return FALSE;
*pdev = &physDev->dev; *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) { if (output && *output) {
INT len = WideCharToMultiByte( CP_ACP, 0, output, -1, NULL, 0, NULL, NULL ); INT len = WideCharToMultiByte( CP_ACP, 0, output, -1, NULL, 0, NULL, NULL );
if ((physDev->job.output = HeapAlloc( PSDRV_Heap, 0, len ))) if ((physDev->job.output = HeapAlloc( PSDRV_Heap, 0, len )))
WideCharToMultiByte( CP_ACP, 0, output, -1, physDev->job.output, len, NULL, NULL ); WideCharToMultiByte( CP_ACP, 0, output, -1, physDev->job.output, len, NULL, NULL );
} else }
physDev->job.output = NULL;
physDev->job.id = 0;
if(initData) { if(initData) {
DEVMODEA *devmodeA = DEVMODEdupWtoA(PSDRV_Heap, 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 * PSDRV_DeleteDC
@ -813,6 +829,7 @@ static const struct gdi_dc_funcs psdrv_funcs =
PSDRV_Chord, /* pChord */ PSDRV_Chord, /* pChord */
NULL, /* pCloseFigure */ NULL, /* pCloseFigure */
NULL, /* pCreateBitmap */ NULL, /* pCreateBitmap */
PSDRV_CreateCompatibleDC, /* pCreateCompatibleDC */
PSDRV_CreateDC, /* pCreateDC */ PSDRV_CreateDC, /* pCreateDC */
NULL, /* pCreateDIBSection */ NULL, /* pCreateDIBSection */
NULL, /* pDeleteBitmap */ 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_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 WCHAR dpi_value_name[] = {'L','o','g','P','i','x','e','l','s','\0'};
static const struct gdi_dc_funcs x11drv_funcs;
/****************************************************************************** /******************************************************************************
* get_dpi * get_dpi
@ -115,50 +116,68 @@ void X11DRV_GDI_Finalize(void)
/* XCloseDisplay( gdi_display ); */ /* 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 * X11DRV_CreateDC
*/ */
static BOOL X11DRV_CreateDC( HDC hdc, PHYSDEV *pdev, LPCWSTR driver, LPCWSTR device, static BOOL X11DRV_CreateDC( HDC hdc, PHYSDEV *pdev, LPCWSTR driver, LPCWSTR device,
LPCWSTR output, const DEVMODEW* initData ) 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; 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; *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 ); * X11DRV_CreateCompatibleDC
XSetGraphicsExposures( gdi_display, physDev->gc, False ); */
XSetSubwindowMode( gdi_display, physDev->gc, IncludeInferiors ); static BOOL X11DRV_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev )
XFlush( gdi_display ); {
wine_tsx11_unlock(); 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; return TRUE;
} }
@ -456,6 +475,7 @@ static const struct gdi_dc_funcs x11drv_funcs =
X11DRV_Chord, /* pChord */ X11DRV_Chord, /* pChord */
NULL, /* pCloseFigure */ NULL, /* pCloseFigure */
X11DRV_CreateBitmap, /* pCreateBitmap */ X11DRV_CreateBitmap, /* pCreateBitmap */
X11DRV_CreateCompatibleDC, /* pCreateCompatibleDC */
X11DRV_CreateDC, /* pCreateDC */ X11DRV_CreateDC, /* pCreateDC */
X11DRV_CreateDIBSection, /* pCreateDIBSection */ X11DRV_CreateDIBSection, /* pCreateDIBSection */
X11DRV_DeleteBitmap, /* pDeleteBitmap */ 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 (*pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
BOOL (*pCloseFigure)(PHYSDEV); BOOL (*pCloseFigure)(PHYSDEV);
BOOL (*pCreateBitmap)(PHYSDEV,HBITMAP); BOOL (*pCreateBitmap)(PHYSDEV,HBITMAP);
BOOL (*pCreateCompatibleDC)(PHYSDEV,PHYSDEV*);
BOOL (*pCreateDC)(HDC,PHYSDEV *,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*); BOOL (*pCreateDC)(HDC,PHYSDEV *,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
HBITMAP (*pCreateDIBSection)(PHYSDEV,HBITMAP,BITMAPINFO *,UINT); HBITMAP (*pCreateDIBSection)(PHYSDEV,HBITMAP,BITMAPINFO *,UINT);
BOOL (*pDeleteBitmap)(HBITMAP); BOOL (*pDeleteBitmap)(HBITMAP);
@ -188,7 +189,7 @@ struct gdi_dc_funcs
}; };
/* increment this when you change the DC function table */ /* 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 ) static inline PHYSDEV get_physdev_entry_point( PHYSDEV dev, size_t offset )
{ {