From 5c1a752d613a681b54120718e033d3166f4122a0 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 22 Oct 2012 15:05:54 +0200 Subject: [PATCH] gdi32: Export a function to retrieve the module handle of the graphics driver for a DC. --- dlls/gdi32/dc.c | 5 ++++- dlls/gdi32/driver.c | 42 ++++++++++++++++++++++++++++++++++----- dlls/gdi32/gdi32.spec | 3 +++ dlls/gdi32/gdi_private.h | 4 ++-- include/wine/gdi_driver.h | 1 + 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index be9b016411a..7d70bf48934 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -81,6 +81,7 @@ DC *alloc_dc_ptr( WORD magic ) dc->nulldrv.funcs = &null_driver; dc->physDev = &dc->nulldrv; + dc->module = gdi32_module; dc->thread = GetCurrentThreadId(); dc->refcount = 1; dc->wndExtX = 1; @@ -568,6 +569,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, HDC hdc; DC * dc; const struct gdi_dc_funcs *funcs; + HMODULE module; WCHAR buf[300]; GDI_CheckNotLock(); @@ -582,7 +584,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, strcpyW(buf, driver); } - if (!(funcs = DRIVER_load_driver( buf ))) + if (!(funcs = DRIVER_load_driver( buf, &module ))) { ERR( "no driver found for %s\n", debugstr_w(buf) ); return 0; @@ -590,6 +592,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, if (!(dc = alloc_dc_ptr( OBJ_DC ))) return 0; hdc = dc->hSelf; + dc->module = module; dc->hBitmap = GDI_inc_ref_count( GetStockObject( DEFAULT_BITMAP )); TRACE("(driver=%s, device=%s, output=%s): returning %p\n", diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index 9c5ddb80b2c..ca21d4db3e5 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -48,6 +48,7 @@ struct graphics_driver static struct list drivers = LIST_INIT( drivers ); static struct graphics_driver *display_driver; +static DWORD display_driver_load_error; const struct gdi_dc_funcs *font_driver = NULL; @@ -92,14 +93,18 @@ static struct graphics_driver *create_driver( HMODULE module ) * * Special case for loading the display driver: get the name from the config file */ -static const struct gdi_dc_funcs *get_display_driver(void) +static const struct gdi_dc_funcs *get_display_driver( HMODULE *module_ret ) { struct graphics_driver *driver; char buffer[MAX_PATH], libname[32], *name, *next; HMODULE module = 0; HKEY hkey; - if (display_driver) return display_driver->funcs; /* already loaded */ + if (display_driver) + { + *module_ret = display_driver->module; + return display_driver->funcs; /* already loaded */ + } strcpy( buffer, "x11" ); /* default value */ /* @@ Wine registry key: HKCU\Software\Wine\Drivers */ @@ -121,6 +126,8 @@ static const struct gdi_dc_funcs *get_display_driver(void) name = next; } + if (!module) display_driver_load_error = GetLastError(); + if (!(driver = create_driver( module ))) { MESSAGE( "Could not create graphics driver '%s'\n", buffer ); @@ -140,7 +147,7 @@ static const struct gdi_dc_funcs *get_display_driver(void) /********************************************************************** * DRIVER_load_driver */ -const struct gdi_dc_funcs *DRIVER_load_driver( LPCWSTR name ) +const struct gdi_dc_funcs *DRIVER_load_driver( LPCWSTR name, HMODULE *module_ret ) { HMODULE module; struct graphics_driver *driver, *new_driver; @@ -148,11 +155,16 @@ const struct gdi_dc_funcs *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 get_display_driver(); + if (!strcmpiW( name, displayW ) || !strcmpiW( name, display1W )) + return get_display_driver( module_ret ); if ((module = GetModuleHandleW( name ))) { - if (display_driver && display_driver->module == module) return display_driver->funcs; + if (display_driver && display_driver->module == module) + { + *module_ret = module; + return display_driver->funcs; + } EnterCriticalSection( &driver_section ); LIST_FOR_EACH_ENTRY( driver, &drivers, struct graphics_driver, entry ) { @@ -182,11 +194,31 @@ const struct gdi_dc_funcs *DRIVER_load_driver( LPCWSTR name ) list_add_head( &drivers, &driver->entry ); TRACE( "loaded driver %p for %s\n", driver, debugstr_w(name) ); done: + *module_ret = driver->module; LeaveCriticalSection( &driver_section ); return driver->funcs; } +/*********************************************************************** + * __wine_get_driver_module (GDI32.@) + */ +HMODULE CDECL __wine_get_driver_module( HDC hdc ) +{ + DC *dc; + HMODULE ret = 0; + + if ((dc = get_dc_ptr( hdc ))) + { + ret = dc->module; + release_dc_ptr( dc ); + if (!ret) SetLastError( display_driver_load_error ); + } + else SetLastError( ERROR_INVALID_HANDLE ); + return ret; +} + + static INT nulldrv_AbortDoc( PHYSDEV dev ) { return 0; diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec index cdc7b4b03ae..80b1b686b9b 100644 --- a/dlls/gdi32/gdi32.spec +++ b/dlls/gdi32/gdi32.spec @@ -513,5 +513,8 @@ @ cdecl __wine_make_gdi_object_system(long long) @ cdecl __wine_set_visible_region(long long ptr ptr ptr) +# Graphics drivers +@ cdecl __wine_get_driver_module(long) + # OpenGL @ cdecl __wine_get_wgl_driver(long long) diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 70589b93f05..806ca35acb4 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -71,7 +71,7 @@ typedef struct tagDC struct tagDC *saved_dc; DWORD_PTR dwHookData; DCHOOKPROC hookProc; /* DC hook */ - + HMODULE module; /* module handle of the graphics driver */ BOOL bounds_enabled:1; /* bounds tracking is enabled */ BOOL path_open:1; /* path is currently open (only for saved DCs) */ @@ -272,7 +272,7 @@ extern const struct gdi_dc_funcs null_driver DECLSPEC_HIDDEN; extern const struct gdi_dc_funcs dib_driver DECLSPEC_HIDDEN; extern const struct gdi_dc_funcs path_driver DECLSPEC_HIDDEN; extern const struct gdi_dc_funcs *font_driver DECLSPEC_HIDDEN; -extern const struct gdi_dc_funcs *DRIVER_load_driver( LPCWSTR name ) DECLSPEC_HIDDEN; +extern const struct gdi_dc_funcs *DRIVER_load_driver( LPCWSTR name, HMODULE *module ) DECLSPEC_HIDDEN; extern BOOL DRIVER_GetDriverName( LPCWSTR device, LPWSTR driver, DWORD size ) DECLSPEC_HIDDEN; /* enhmetafile.c */ diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index e942ed9dd3a..3d4e6c5604b 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -275,6 +275,7 @@ WINGDIAPI WORD WINAPI SetHookFlags(HDC,WORD); extern void CDECL __wine_make_gdi_object_system( HGDIOBJ handle, BOOL set ); extern void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect, const RECT *device_rect, struct window_surface *surface ); +extern HMODULE CDECL __wine_get_driver_module( HDC hdc ); extern struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version ); #endif /* __WINE_WINE_GDI_DRIVER_H */