| /* | |
| * Graphics driver management functions | |
| * | |
| * Copyright 1996 Alexandre Julliard | |
| */ | |
| #include <string.h> | |
| #include "gdi.h" | |
| #include "heap.h" | |
| #include "debugtools.h" | |
| DEFAULT_DEBUG_CHANNEL(driver); | |
| typedef struct tagGRAPHICS_DRIVER | |
| { | |
| struct tagGRAPHICS_DRIVER *next; | |
| LPSTR name; | |
| const DC_FUNCTIONS *funcs; | |
| } GRAPHICS_DRIVER; | |
| static GRAPHICS_DRIVER *firstDriver = NULL; | |
| static GRAPHICS_DRIVER *genericDriver = NULL; | |
| /********************************************************************** | |
| * DRIVER_RegisterDriver | |
| */ | |
| BOOL DRIVER_RegisterDriver( LPCSTR name, const DC_FUNCTIONS *funcs ) | |
| { | |
| GRAPHICS_DRIVER *driver = HeapAlloc( GetProcessHeap(), 0, sizeof(*driver) ); | |
| if (!driver) return FALSE; | |
| driver->funcs = funcs; | |
| if (name) | |
| { | |
| driver->name = HEAP_strdupA( GetProcessHeap(), 0, name ); | |
| driver->next = firstDriver; | |
| firstDriver = driver; | |
| return TRUE; | |
| } | |
| /* No name -> it's the generic driver */ | |
| if (genericDriver) | |
| { | |
| WARN(" already a generic driver\n" ); | |
| HeapFree( GetProcessHeap(), 0, driver ); | |
| return FALSE; | |
| } | |
| driver->name = NULL; | |
| genericDriver = driver; | |
| return TRUE; | |
| } | |
| /********************************************************************** | |
| * DRIVER_FindDriver | |
| */ | |
| const DC_FUNCTIONS *DRIVER_FindDriver( LPCSTR name ) | |
| { | |
| GRAPHICS_DRIVER *driver; | |
| HINSTANCE hDriver; | |
| TRACE(": %s\n", name); | |
| if (!name) return genericDriver ? genericDriver->funcs : NULL; | |
| for (driver = firstDriver; driver; driver = driver->next) | |
| if (!strcasecmp( driver->name, name )) return driver->funcs; | |
| if (!(hDriver = LoadLibraryA (name))) return NULL; | |
| for (driver = firstDriver; driver; driver = driver->next) | |
| if (!strcasecmp( driver->name, name )) return driver->funcs; | |
| FreeLibrary (hDriver); | |
| return NULL; | |
| } | |
| /********************************************************************** | |
| * DRIVER_UnregisterDriver | |
| */ | |
| BOOL DRIVER_UnregisterDriver( LPCSTR name ) | |
| { | |
| if (name) | |
| { | |
| GRAPHICS_DRIVER **ppDriver = &firstDriver; | |
| while (*ppDriver) | |
| { | |
| if (!strcasecmp( (*ppDriver)->name, name )) | |
| { | |
| GRAPHICS_DRIVER *driver = *ppDriver; | |
| (*ppDriver) = driver->next; | |
| HeapFree( GetProcessHeap(), 0, driver->name ); | |
| HeapFree( GetProcessHeap(), 0, driver ); | |
| return TRUE; | |
| } | |
| ppDriver = &(*ppDriver)->next; | |
| } | |
| return FALSE; | |
| } | |
| else | |
| { | |
| if (!genericDriver) return FALSE; | |
| HeapFree( GetProcessHeap(), 0, genericDriver ); | |
| genericDriver = NULL; | |
| return TRUE; | |
| } | |
| } | |
| /***************************************************************************** | |
| * DRIVER_GetDriverName | |
| * | |
| */ | |
| BOOL DRIVER_GetDriverName( LPCSTR device, LPSTR driver, DWORD size ) | |
| { | |
| char *p; | |
| size = GetProfileStringA("devices", device, "", driver, size); | |
| if(!size) { | |
| WARN("Unable to find '%s' in [devices] section of win.ini\n", device); | |
| return FALSE; | |
| } | |
| p = strchr(driver, ','); | |
| if(!p) { | |
| WARN("'%s' entry in [devices] section of win.ini is malformed.\n", | |
| device); | |
| return FALSE; | |
| } | |
| *p = '\0'; | |
| TRACE("Found '%s' for '%s'\n", driver, device); | |
| return TRUE; | |
| } | |
| /***************************************************************************** | |
| * @ [GDI32.100] | |
| * | |
| * This should thunk to 16-bit and simply call the proc with the given args. | |
| */ | |
| INT WINAPI GDI_CallDevInstall16( FARPROC16 lpfnDevInstallProc, HWND hWnd, | |
| LPSTR lpModelName, LPSTR OldPort, LPSTR NewPort ) | |
| { | |
| FIXME("(%p, %04x, %s, %s, %s)\n", | |
| lpfnDevInstallProc, hWnd, lpModelName, OldPort, NewPort ); | |
| return -1; | |
| } | |
| /***************************************************************************** | |
| * @ [GDI32.101] | |
| * | |
| * This should load the correct driver for lpszDevice and calls this driver's | |
| * ExtDeviceModePropSheet proc. | |
| * | |
| * Note: The driver calls a callback routine for each property sheet page; these | |
| * pages are supposed to be filled into the structure pointed to by lpPropSheet. | |
| * The layout of this structure is: | |
| * | |
| * struct | |
| * { | |
| * DWORD nPages; | |
| * DWORD unknown; | |
| * HPROPSHEETPAGE pages[10]; | |
| * }; | |
| */ | |
| INT WINAPI GDI_CallExtDeviceModePropSheet16( HWND hWnd, LPCSTR lpszDevice, | |
| LPCSTR lpszPort, LPVOID lpPropSheet ) | |
| { | |
| FIXME("(%04x, %s, %s, %p)\n", | |
| hWnd, lpszDevice, lpszPort, lpPropSheet ); | |
| return -1; | |
| } | |
| /***************************************************************************** | |
| * @ [GDI32.102] | |
| * | |
| * This should load the correct driver for lpszDevice and calls this driver's | |
| * ExtDeviceMode proc. | |
| */ | |
| INT WINAPI GDI_CallExtDeviceMode16( HWND hwnd, | |
| LPDEVMODEA lpdmOutput, LPSTR lpszDevice, | |
| LPSTR lpszPort, LPDEVMODEA lpdmInput, | |
| LPSTR lpszProfile, DWORD fwMode ) | |
| { | |
| char buf[300]; | |
| const DC_FUNCTIONS *funcs; | |
| TRACE("(%04x, %p, %s, %s, %p, %s, %ld)\n", | |
| hwnd, lpdmOutput, lpszDevice, lpszPort, | |
| lpdmInput, lpszProfile, fwMode ); | |
| if(!DRIVER_GetDriverName( lpszDevice, buf, sizeof(buf) )) return -1; | |
| funcs = DRIVER_FindDriver( buf ); | |
| if(!funcs || !funcs->pExtDeviceMode) return -1; | |
| return funcs->pExtDeviceMode(buf, hwnd, lpdmOutput, lpszDevice, lpszPort, | |
| lpdmInput, lpszProfile, fwMode); | |
| } | |
| /**************************************************************************** | |
| * @ [GDI32.103] | |
| * | |
| * This should load the correct driver for lpszDevice and calls this driver's | |
| * AdvancedSetupDialog proc. | |
| */ | |
| INT WINAPI GDI_CallAdvancedSetupDialog16( HWND hwnd, LPSTR lpszDevice, | |
| LPDEVMODEA devin, LPDEVMODEA devout ) | |
| { | |
| TRACE("(%04x, %s, %p, %p)\n", | |
| hwnd, lpszDevice, devin, devout ); | |
| return -1; | |
| } | |
| /***************************************************************************** | |
| * @ [GDI32.104] | |
| * | |
| * This should load the correct driver for lpszDevice and calls this driver's | |
| * DeviceCapabilities proc. | |
| */ | |
| DWORD WINAPI GDI_CallDeviceCapabilities16( LPCSTR lpszDevice, LPCSTR lpszPort, | |
| WORD fwCapability, LPSTR lpszOutput, | |
| LPDEVMODEA lpdm ) | |
| { | |
| char buf[300]; | |
| const DC_FUNCTIONS *funcs; | |
| TRACE("(%s, %s, %d, %p, %p)\n", | |
| lpszDevice, lpszPort, fwCapability, lpszOutput, lpdm ); | |
| if(!DRIVER_GetDriverName( lpszDevice, buf, sizeof(buf) )) return -1; | |
| funcs = DRIVER_FindDriver( buf ); | |
| if(!funcs || !funcs->pDeviceCapabilities) return -1; | |
| return funcs->pDeviceCapabilities( buf, lpszDevice, lpszPort, | |
| fwCapability, lpszOutput, lpdm); | |
| } | |