blob: dac376a634fda6b8627e7360925339809ebcd934 [file] [log] [blame]
/*
* 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 = firstDriver;
TRACE(": %s\n", name);
while (driver && name)
{
if (!strcasecmp( driver->name, name )) return driver->funcs;
driver = driver->next;
}
return genericDriver ? genericDriver->funcs : 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);
}