234 lines
6.9 KiB
C
234 lines
6.9 KiB
C
/*
|
|
* 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;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* GDI_CallDevInstall16 [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;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* GDI_CallExtDeviceModePropSheet16 [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;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* GDI_CallExtDeviceMode16 [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);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* GDI_CallAdvancedSetupDialog16 [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;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* GDI_CallDeviceCapabilities16 [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);
|
|
|
|
}
|
|
|
|
|