Fixed error handling in DGA_IDirectDraw2Impl_GetCaps().
[wine] / graphics / driver.c
1 /*
2  * Graphics driver management functions
3  *
4  * Copyright 1996 Alexandre Julliard
5  */
6
7 #include <string.h>
8 #include "gdi.h"
9 #include "heap.h"
10 #include "debugtools.h"
11
12 DEFAULT_DEBUG_CHANNEL(driver)
13
14 typedef struct tagGRAPHICS_DRIVER
15 {
16     struct tagGRAPHICS_DRIVER *next;
17     LPSTR                      name;
18     const DC_FUNCTIONS        *funcs;
19 } GRAPHICS_DRIVER;
20
21 static GRAPHICS_DRIVER *firstDriver = NULL;
22 static GRAPHICS_DRIVER *genericDriver = NULL;
23
24 /**********************************************************************
25  *           DRIVER_RegisterDriver
26  */
27 BOOL DRIVER_RegisterDriver( LPCSTR name, const DC_FUNCTIONS *funcs )
28 {
29     GRAPHICS_DRIVER *driver = HeapAlloc( SystemHeap, 0, sizeof(*driver) );
30     if (!driver) return FALSE;
31     driver->funcs = funcs;
32     if (name)
33     {
34         driver->name  = HEAP_strdupA( SystemHeap, 0, name );
35         driver->next  = firstDriver;
36         firstDriver = driver;
37         return TRUE;
38     }
39     /* No name -> it's the generic driver */
40     if (genericDriver)
41     {
42         WARN(" already a generic driver\n" );
43         HeapFree( SystemHeap, 0, driver );
44         return FALSE;
45     }
46     driver->name = NULL;
47     genericDriver = driver;
48     return TRUE;
49 }
50
51
52 /**********************************************************************
53  *           DRIVER_FindDriver
54  */
55 const DC_FUNCTIONS *DRIVER_FindDriver( LPCSTR name )
56 {
57     GRAPHICS_DRIVER *driver = firstDriver;
58
59     TRACE(": %s\n", name);
60     while (driver && name)
61     {
62         if (!strcasecmp( driver->name, name )) return driver->funcs;
63         driver = driver->next;
64     }
65     return genericDriver ? genericDriver->funcs : NULL;
66 }
67
68
69 /**********************************************************************
70  *           DRIVER_UnregisterDriver
71  */
72 BOOL DRIVER_UnregisterDriver( LPCSTR name )
73 {
74     if (name)
75     {
76         GRAPHICS_DRIVER **ppDriver = &firstDriver;
77         while (*ppDriver)
78         {
79             if (!strcasecmp( (*ppDriver)->name, name ))
80             {
81                 GRAPHICS_DRIVER *driver = *ppDriver;
82                 (*ppDriver) = driver->next;
83                 HeapFree( SystemHeap, 0, driver->name );
84                 HeapFree( SystemHeap, 0, driver );
85                 return TRUE;
86             }
87             ppDriver = &(*ppDriver)->next;
88         }
89         return FALSE;
90     }
91     else
92     {
93         if (!genericDriver) return FALSE;
94         HeapFree( SystemHeap, 0, genericDriver );
95         genericDriver = NULL;
96         return TRUE;
97     }
98 }
99
100 /*****************************************************************************
101  *      DRIVER_GetDriverName
102  *
103  */
104 BOOL DRIVER_GetDriverName( LPCSTR device, LPSTR driver, DWORD size )
105 {
106     char *p;
107     size = GetProfileStringA("devices", device, "", driver, size);
108     if(!size) return FALSE;
109
110     p = strchr(driver, ',');
111     if(!p) return FALSE;
112     *p = '\0';
113     TRACE("Found '%s' for '%s'\n", driver, device);
114     return TRUE;
115 }
116     
117 /*****************************************************************************
118  *      GDI_CallDevInstall16   [GDI32.100]
119  *
120  * This should thunk to 16-bit and simply call the proc with the given args.
121  */
122 INT WINAPI GDI_CallDevInstall16( FARPROC16 lpfnDevInstallProc, HWND hWnd, 
123                                  LPSTR lpModelName, LPSTR OldPort, LPSTR NewPort )
124 {
125     FIXME("(%p, %04x, %s, %s, %s)\n", 
126           lpfnDevInstallProc, hWnd, lpModelName, OldPort, NewPort );
127     return -1;
128 }
129
130 /*****************************************************************************
131  *      GDI_CallExtDeviceModePropSheet16   [GDI32.101]
132  *
133  * This should load the correct driver for lpszDevice and calls this driver's
134  * ExtDeviceModePropSheet proc. 
135  *
136  * Note: The driver calls a callback routine for each property sheet page; these 
137  * pages are supposed to be filled into the structure pointed to by lpPropSheet.
138  * The layout of this structure is:
139  * 
140  * struct
141  * {
142  *   DWORD  nPages;
143  *   DWORD  unknown;
144  *   HPROPSHEETPAGE  pages[10];
145  * };
146  */
147 INT WINAPI GDI_CallExtDeviceModePropSheet16( HWND hWnd, LPCSTR lpszDevice, 
148                                              LPCSTR lpszPort, LPVOID lpPropSheet )
149 {
150     FIXME("(%04x, %s, %s, %p)\n", 
151       hWnd, lpszDevice, lpszPort, lpPropSheet );
152     return -1;
153 }
154
155 /*****************************************************************************
156  *      GDI_CallExtDeviceMode16   [GDI32.102]
157  *
158  * This should load the correct driver for lpszDevice and calls this driver's
159  * ExtDeviceMode proc.
160  */
161 INT WINAPI GDI_CallExtDeviceMode16( HWND hwnd, 
162                                     LPDEVMODEA lpdmOutput, LPSTR lpszDevice, 
163                                     LPSTR lpszPort, LPDEVMODEA lpdmInput, 
164                                     LPSTR lpszProfile, DWORD fwMode )
165 {
166     char buf[300];
167     const DC_FUNCTIONS *funcs;
168
169     TRACE("(%04x, %p, %s, %s, %p, %s, %ld)\n", 
170           hwnd, lpdmOutput, lpszDevice, lpszPort, 
171           lpdmInput, lpszProfile, fwMode );
172
173     if(!DRIVER_GetDriverName( lpszDevice, buf, sizeof(buf) )) return -1;
174     funcs = DRIVER_FindDriver( buf );
175     if(!funcs || !funcs->pExtDeviceMode) return -1;
176     return funcs->pExtDeviceMode(hwnd, lpdmOutput, lpszDevice, lpszPort,
177                                  lpdmInput, lpszProfile, fwMode);
178 }
179
180 /****************************************************************************
181  *      GDI_CallAdvancedSetupDialog16     [GDI32.103]
182  *
183  * This should load the correct driver for lpszDevice and calls this driver's
184  * AdvancedSetupDialog proc.
185  */
186 INT WINAPI GDI_CallAdvancedSetupDialog16( HWND hwnd, LPSTR lpszDevice,
187                                           LPDEVMODEA devin, LPDEVMODEA devout )
188 {
189     TRACE("(%04x, %s, %p, %p)\n", 
190           hwnd, lpszDevice, devin, devout );
191     return -1;
192 }
193
194 /*****************************************************************************
195  *      GDI_CallDeviceCapabilities16      [GDI32.104]
196  *
197  * This should load the correct driver for lpszDevice and calls this driver's
198  * DeviceCapabilities proc.
199  */
200 DWORD WINAPI GDI_CallDeviceCapabilities16( LPCSTR lpszDevice, LPCSTR lpszPort,
201                                            WORD fwCapability, LPSTR lpszOutput,
202                                            LPDEVMODEA lpdm )
203 {
204     char buf[300];
205     const DC_FUNCTIONS *funcs;
206
207     TRACE("(%s, %s, %d, %p, %p)\n", 
208           lpszDevice, lpszPort, fwCapability, lpszOutput, lpdm );
209
210
211     if(!DRIVER_GetDriverName( lpszDevice, buf, sizeof(buf) )) return -1;
212     funcs = DRIVER_FindDriver( buf );
213     if(!funcs || !funcs->pDeviceCapabilities) return -1;
214     return funcs->pDeviceCapabilities( lpszDevice, lpszPort, fwCapability,
215                                        lpszOutput, lpdm);
216 }
217
218