gdi32: Add a mechanism for stacking gdi drivers.
This commit is contained in:
parent
ec54c80ee5
commit
6419edfb6d
|
@ -79,7 +79,8 @@ DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
|
||||||
|
|
||||||
dc->funcs = funcs;
|
dc->funcs = funcs;
|
||||||
dc->nulldrv.funcs = &null_driver;
|
dc->nulldrv.funcs = &null_driver;
|
||||||
dc->physDev = NULL;
|
dc->nulldrv.next = NULL;
|
||||||
|
dc->physDev = &dc->nulldrv;
|
||||||
dc->thread = GetCurrentThreadId();
|
dc->thread = GetCurrentThreadId();
|
||||||
dc->refcount = 1;
|
dc->refcount = 1;
|
||||||
dc->dirty = 0;
|
dc->dirty = 0;
|
||||||
|
@ -228,6 +229,34 @@ void update_dc( DC *dc )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* push_dc_driver
|
||||||
|
*
|
||||||
|
* Push a driver on top of the DC driver stack.
|
||||||
|
*/
|
||||||
|
void push_dc_driver( DC * dc, PHYSDEV physdev )
|
||||||
|
{
|
||||||
|
physdev->next = dc->physDev;
|
||||||
|
physdev->hdc = dc->hSelf;
|
||||||
|
dc->physDev = physdev;
|
||||||
|
dc->funcs = physdev->funcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* pop_dc_driver
|
||||||
|
*
|
||||||
|
* Pop the top driver from the DC driver stack.
|
||||||
|
*/
|
||||||
|
void pop_dc_driver( DC * dc, PHYSDEV physdev )
|
||||||
|
{
|
||||||
|
assert( physdev == dc->physDev );
|
||||||
|
assert( physdev != &dc->nulldrv );
|
||||||
|
dc->physDev = physdev->next;
|
||||||
|
dc->funcs = dc->physDev->funcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* DC_DeleteObject
|
* DC_DeleteObject
|
||||||
*/
|
*/
|
||||||
|
@ -633,6 +662,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
|
||||||
{
|
{
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
DC * dc;
|
DC * dc;
|
||||||
|
PHYSDEV physdev;
|
||||||
const DC_FUNCTIONS *funcs;
|
const DC_FUNCTIONS *funcs;
|
||||||
WCHAR buf[300];
|
WCHAR buf[300];
|
||||||
|
|
||||||
|
@ -663,14 +693,15 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
|
||||||
debugstr_w(driver), debugstr_w(device), debugstr_w(output), dc->hSelf );
|
debugstr_w(driver), debugstr_w(device), debugstr_w(output), dc->hSelf );
|
||||||
|
|
||||||
if (dc->funcs->pCreateDC &&
|
if (dc->funcs->pCreateDC &&
|
||||||
!dc->funcs->pCreateDC( hdc, &dc->physDev, buf, device, output, initData ))
|
!dc->funcs->pCreateDC( hdc, &physdev, buf, device, output, initData ))
|
||||||
{
|
{
|
||||||
WARN("creation aborted by device\n" );
|
WARN("creation aborted by device\n" );
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->physDev->funcs = funcs;
|
physdev->funcs = funcs;
|
||||||
dc->physDev->hdc = hdc;
|
push_dc_driver( dc, physdev );
|
||||||
|
|
||||||
dc->vis_rect.left = 0;
|
dc->vis_rect.left = 0;
|
||||||
dc->vis_rect.top = 0;
|
dc->vis_rect.top = 0;
|
||||||
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
|
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
|
||||||
|
@ -782,21 +813,20 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
|
||||||
dc->vis_rect.bottom = 1;
|
dc->vis_rect.bottom = 1;
|
||||||
if (!(dc->hVisRgn = CreateRectRgn( 0, 0, 1, 1 ))) goto error; /* default bitmap is 1x1 */
|
if (!(dc->hVisRgn = CreateRectRgn( 0, 0, 1, 1 ))) goto error; /* default bitmap is 1x1 */
|
||||||
|
|
||||||
/* Copy the driver-specific physical device info into
|
|
||||||
* the new DC. The driver may use this read-only info
|
|
||||||
* while creating the compatible DC below. */
|
|
||||||
dc->physDev = physDev;
|
|
||||||
ret = dc->hSelf;
|
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 (dc->funcs->pCreateDC &&
|
if (dc->funcs->pCreateDC &&
|
||||||
!dc->funcs->pCreateDC( dc->hSelf, &dc->physDev, NULL, NULL, NULL, NULL ))
|
!dc->funcs->pCreateDC( dc->hSelf, &physDev, NULL, NULL, NULL, NULL ))
|
||||||
{
|
{
|
||||||
WARN("creation aborted by device\n");
|
WARN("creation aborted by device\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->physDev->funcs = funcs;
|
physDev->funcs = funcs;
|
||||||
dc->physDev->hdc = hdc;
|
push_dc_driver( dc, physDev );
|
||||||
DC_InitDC( dc );
|
DC_InitDC( dc );
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -319,9 +319,8 @@ HDC WINAPI CreateEnhMetaFileW(
|
||||||
free_dc_ptr( dc );
|
free_dc_ptr( dc );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dc->physDev = (PHYSDEV)physDev;
|
|
||||||
physDev->dev.funcs = &EMFDRV_Funcs;
|
physDev->dev.funcs = &EMFDRV_Funcs;
|
||||||
physDev->dev.hdc = dc->hSelf;
|
push_dc_driver( dc, &physDev->dev );
|
||||||
physDev->hdc = dc->hSelf;
|
physDev->hdc = dc->hSelf;
|
||||||
|
|
||||||
if(description) { /* App name\0Title\0\0 */
|
if(description) { /* App name\0Title\0\0 */
|
||||||
|
|
|
@ -75,6 +75,7 @@ typedef struct tagGDIOBJHDR
|
||||||
typedef struct gdi_physdev
|
typedef struct gdi_physdev
|
||||||
{
|
{
|
||||||
const struct tagDC_FUNCS *funcs;
|
const struct tagDC_FUNCS *funcs;
|
||||||
|
struct gdi_physdev *next;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
} *PHYSDEV;
|
} *PHYSDEV;
|
||||||
|
|
||||||
|
@ -377,6 +378,8 @@ extern BOOL free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
|
||||||
extern DC *get_dc_ptr( HDC hdc ) DECLSPEC_HIDDEN;
|
extern DC *get_dc_ptr( HDC hdc ) DECLSPEC_HIDDEN;
|
||||||
extern void release_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
|
extern void release_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
|
||||||
extern void update_dc( DC *dc ) DECLSPEC_HIDDEN;
|
extern void update_dc( DC *dc ) DECLSPEC_HIDDEN;
|
||||||
|
extern void push_dc_driver( DC * dc, PHYSDEV physdev ) DECLSPEC_HIDDEN;
|
||||||
|
extern void pop_dc_driver( DC * dc, PHYSDEV physdev ) DECLSPEC_HIDDEN;
|
||||||
extern void DC_InitDC( DC * dc ) DECLSPEC_HIDDEN;
|
extern void DC_InitDC( DC * dc ) DECLSPEC_HIDDEN;
|
||||||
extern void DC_UpdateXforms( DC * dc ) DECLSPEC_HIDDEN;
|
extern void DC_UpdateXforms( DC * dc ) DECLSPEC_HIDDEN;
|
||||||
extern INT save_dc_state( HDC hdc ) DECLSPEC_HIDDEN;
|
extern INT save_dc_state( HDC hdc ) DECLSPEC_HIDDEN;
|
||||||
|
@ -395,7 +398,14 @@ 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;
|
||||||
|
|
||||||
#define GET_DC_PHYSDEV(dc,func) ((dc)->physDev->funcs->func ? (dc)->physDev : &(dc)->nulldrv)
|
static inline PHYSDEV get_physdev_entry_point( PHYSDEV dev, size_t offset )
|
||||||
|
{
|
||||||
|
while (!((void **)dev->funcs)[offset / sizeof(void *)]) dev = dev->next;
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_DC_PHYSDEV(dc,func) get_physdev_entry_point( (dc)->physDev, FIELD_OFFSET(DC_FUNCTIONS,func))
|
||||||
|
#define GET_NEXT_PHYSDEV(dev,func) get_physdev_entry_point( (dev)->next, FIELD_OFFSET(DC_FUNCTIONS,func))
|
||||||
|
|
||||||
/* enhmetafile.c */
|
/* enhmetafile.c */
|
||||||
extern HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk ) DECLSPEC_HIDDEN;
|
extern HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -171,9 +171,8 @@ static DC *MFDRV_AllocMetaFile(void)
|
||||||
free_dc_ptr( dc );
|
free_dc_ptr( dc );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
dc->physDev = (PHYSDEV)physDev;
|
|
||||||
physDev->dev.funcs = &MFDRV_Funcs;
|
physDev->dev.funcs = &MFDRV_Funcs;
|
||||||
physDev->dev.hdc = dc->hSelf;
|
push_dc_driver( dc, &physDev->dev );
|
||||||
physDev->hdc = dc->hSelf;
|
physDev->hdc = dc->hSelf;
|
||||||
|
|
||||||
if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
|
if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
|
||||||
|
|
|
@ -353,7 +353,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
void *reserved[2]; /* reserved for gdi */
|
void *reserved[3]; /* reserved for gdi */
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
PSFONT font; /* Current PS font */
|
PSFONT font; /* Current PS font */
|
||||||
DOWNLOAD *downloaded_fonts;
|
DOWNLOAD *downloaded_fonts;
|
||||||
|
|
|
@ -144,7 +144,7 @@ struct xrender_info;
|
||||||
/* X physical device */
|
/* X physical device */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
void *reserved[2]; /* reserved for gdi */
|
void *reserved[3]; /* reserved for gdi */
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
GC gc; /* X Window GC */
|
GC gc; /* X Window GC */
|
||||||
Drawable drawable;
|
Drawable drawable;
|
||||||
|
|
Loading…
Reference in New Issue