/********************************************************************** * DRIVER_load_driver */ const DC_FUNCTIONS *DRIVER_load_driver( LPCWSTR name ) { HMODULE module; struct graphics_driver *driver; static const WCHAR displayW[] = { 'd','i','s','p','l','a','y',0 }; static const WCHAR display1W[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0}; EnterCriticalSection( &driver_section ); /* display driver is a special case */ if (!strcmpiW( name, displayW ) || !strcmpiW( name, display1W )) { driver = load_display_driver(); LeaveCriticalSection( &driver_section ); return &driver->funcs; } if ((module = GetModuleHandleW( name ))) { for (driver = first_driver; driver; driver = driver->next) { if (driver->module == module) { driver->count++; LeaveCriticalSection( &driver_section ); return &driver->funcs; } } } if (!(module = LoadLibraryW( name ))) { LeaveCriticalSection( &driver_section ); return NULL; } if (!(driver = create_driver( module ))) { FreeLibrary( module ); LeaveCriticalSection( &driver_section ); return NULL; } TRACE( "loaded driver %p for %s\n", driver, debugstr_w(name) ); LeaveCriticalSection( &driver_section ); return &driver->funcs; }
/********************************************************************** * DRIVER_load_driver */ const DC_FUNCTIONS *DRIVER_load_driver( LPCWSTR name ) { HMODULE module; struct graphics_driver *driver, *new_driver; static const WCHAR displayW[] = { 'd','i','s','p','l','a','y',0 }; 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 ((module = GetModuleHandleW( name ))) { if (display_driver && display_driver->module == module) return &display_driver->funcs; EnterCriticalSection( &driver_section ); LIST_FOR_EACH_ENTRY( driver, &drivers, struct graphics_driver, entry ) { if (driver->module == module) goto done; } LeaveCriticalSection( &driver_section ); } if (!(module = LoadLibraryW( name ))) return NULL; if (!(new_driver = create_driver( module ))) { FreeLibrary( module ); return NULL; } /* check if someone else added it in the meantime */ EnterCriticalSection( &driver_section ); LIST_FOR_EACH_ENTRY( driver, &drivers, struct graphics_driver, entry ) { if (driver->module != module) continue; FreeLibrary( module ); HeapFree( GetProcessHeap(), 0, new_driver ); goto done; } driver = new_driver; list_add_head( &drivers, &driver->entry ); TRACE( "loaded driver %p for %s\n", driver, debugstr_w(name) ); done: LeaveCriticalSection( &driver_section ); return &driver->funcs; }
/********************************************************************** * 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) { 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 */ strcpy( buffer, "x11" ); /* default value */ /* @@ Wine registry key: HKCU\Software\Wine\Drivers */ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey )) { DWORD type, count = sizeof(buffer); RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count ); RegCloseKey( hkey ); } name = buffer; while (name) { next = strchr( name, ',' ); if (next) *next++ = 0; snprintf( libname, sizeof(libname), "wine%s.drv", name ); if ((module = LoadLibraryA( libname )) != 0) break; name = next; } if (!(driver = create_driver( module ))) { MESSAGE( "Could not create graphics driver '%s'\n", buffer ); FreeLibrary( module ); ExitProcess(1); } if (InterlockedCompareExchangePointer( (void **)&display_driver, driver, NULL )) { /* somebody beat us to it */ FreeLibrary( driver->module ); HeapFree( GetProcessHeap(), 0, driver ); } return &display_driver->funcs; }
/********************************************************************** * load_display_driver * * Special case for loading the display driver: get the name from the config file */ static struct graphics_driver *load_display_driver(void) { char buffer[MAX_PATH], libname[32], *name, *next; HMODULE module = 0; HKEY hkey; if (display_driver) /* already loaded */ { display_driver->count++; return display_driver; } strcpy( buffer, "x11" ); /* default value */ /* @@ Wine registry key: HKCU\Software\Wine\Drivers */ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey )) { DWORD type, count = sizeof(buffer); RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count ); RegCloseKey( hkey ); } name = buffer; while (name) { next = strchr( name, ',' ); if (next) *next++ = 0; snprintf( libname, sizeof(libname), "wine%s.drv", name ); if ((module = LoadLibraryA( libname )) != 0) break; name = next; } if (!(display_driver = create_driver( module ))) { MESSAGE( "Could not create graphics driver '%s'\n", buffer ); FreeLibrary( module ); ExitProcess(1); } display_driver->count++; /* we don't want to free it */ return display_driver; }