xref: /reactos/dll/directx/wine/d3drm/device.c (revision 4561998a)
1 /*
2  * Implementation of IDirect3DRMDevice Interface
3  *
4  * Copyright 2011, 2012 André Hentschel
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "config.h"
22 #include "wine/port.h"
23 
24 #include "d3drm_private.h"
25 
26 WINE_DEFAULT_DEBUG_CHANNEL(d3drm);
27 
28 static inline struct d3drm_device *impl_from_IDirect3DRMDevice(IDirect3DRMDevice *iface)
29 {
30     return CONTAINING_RECORD(iface, struct d3drm_device, IDirect3DRMDevice_iface);
31 }
32 
33 static inline struct d3drm_device *impl_from_IDirect3DRMDevice2(IDirect3DRMDevice2 *iface)
34 {
35     return CONTAINING_RECORD(iface, struct d3drm_device, IDirect3DRMDevice2_iface);
36 }
37 
38 static inline struct d3drm_device *impl_from_IDirect3DRMDevice3(IDirect3DRMDevice3 *iface)
39 {
40     return CONTAINING_RECORD(iface, struct d3drm_device, IDirect3DRMDevice3_iface);
41 }
42 
43 void d3drm_device_destroy(struct d3drm_device *device)
44 {
45     d3drm_object_cleanup((IDirect3DRMObject *)&device->IDirect3DRMDevice_iface, &device->obj);
46     if (device->device)
47     {
48         TRACE("Releasing attached ddraw interfaces.\n");
49         IDirect3DDevice_Release(device->device);
50     }
51     if (device->render_target)
52         IDirectDrawSurface_Release(device->render_target);
53     if (device->primary_surface)
54     {
55         TRACE("Releasing primary surface and attached clipper.\n");
56         IDirectDrawSurface_Release(device->primary_surface);
57         IDirectDrawClipper_Release(device->clipper);
58     }
59     if (device->ddraw)
60     {
61         IDirectDraw_Release(device->ddraw);
62         IDirect3DRM_Release(device->d3drm);
63     }
64     heap_free(device);
65 }
66 
67 static inline struct d3drm_device *impl_from_IDirect3DRMWinDevice(IDirect3DRMWinDevice *iface)
68 {
69     return CONTAINING_RECORD(iface, struct d3drm_device, IDirect3DRMWinDevice_iface);
70 }
71 
72 HRESULT d3drm_device_create_surfaces_from_clipper(struct d3drm_device *object, IDirectDraw *ddraw, IDirectDrawClipper *clipper, int width, int height, IDirectDrawSurface **surface)
73 {
74     DDSURFACEDESC surface_desc;
75     IDirectDrawSurface *primary_surface, *render_target;
76     HWND window;
77     HRESULT hr;
78 
79     hr = IDirectDrawClipper_GetHWnd(clipper, &window);
80     if (FAILED(hr))
81         return hr;
82 
83     hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
84     if (FAILED(hr))
85         return hr;
86 
87     memset(&surface_desc, 0, sizeof(surface_desc));
88     surface_desc.dwSize = sizeof(surface_desc);
89     surface_desc.dwFlags = DDSD_CAPS;
90     surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
91     hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &primary_surface, NULL);
92     if (FAILED(hr))
93         return hr;
94     hr = IDirectDrawSurface_SetClipper(primary_surface, clipper);
95     if (FAILED(hr))
96     {
97         IDirectDrawSurface_Release(primary_surface);
98         return hr;
99     }
100 
101     memset(&surface_desc, 0, sizeof(surface_desc));
102     surface_desc.dwSize = sizeof(surface_desc);
103     surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
104     surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
105     surface_desc.dwWidth = width;
106     surface_desc.dwHeight = height;
107 
108     hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &render_target, NULL);
109     if (FAILED(hr))
110     {
111         IDirectDrawSurface_Release(primary_surface);
112         return hr;
113     }
114 
115     object->primary_surface = primary_surface;
116     object->clipper = clipper;
117     IDirectDrawClipper_AddRef(clipper);
118     *surface = render_target;
119 
120     return D3DRM_OK;
121 }
122 
123 HRESULT d3drm_device_init(struct d3drm_device *device, UINT version, IDirectDraw *ddraw, IDirectDrawSurface *surface,
124             BOOL create_z_surface)
125 {
126     DDSCAPS caps = { DDSCAPS_ZBUFFER };
127     IDirectDrawSurface *ds = NULL;
128     IDirect3DDevice *device1 = NULL;
129     IDirect3DDevice2 *device2 = NULL;
130     IDirect3D2 *d3d2 = NULL;
131     DDSURFACEDESC desc, surface_desc;
132     HRESULT hr;
133 
134     device->ddraw = ddraw;
135     IDirectDraw_AddRef(ddraw);
136     IDirect3DRM_AddRef(device->d3drm);
137     device->render_target = surface;
138     IDirectDrawSurface_AddRef(surface);
139 
140     desc.dwSize = sizeof(desc);
141     hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
142     if (FAILED(hr))
143         return hr;
144 
145     if (!(desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE))
146         return DDERR_INVALIDCAPS;
147 
148     hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
149     if (SUCCEEDED(hr))
150     {
151         create_z_surface = FALSE;
152         IDirectDrawSurface_Release(ds);
153         ds = NULL;
154     }
155 
156     if (create_z_surface)
157     {
158         memset(&surface_desc, 0, sizeof(surface_desc));
159         surface_desc.dwSize = sizeof(surface_desc);
160         surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT;
161         surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
162         surface_desc.u2.dwZBufferBitDepth = 16;
163         surface_desc.dwWidth = desc.dwWidth;
164         surface_desc.dwHeight = desc.dwHeight;
165         hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &ds, NULL);
166         if (FAILED(hr))
167             return hr;
168 
169         hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
170         IDirectDrawSurface_Release(ds);
171         if (FAILED(hr))
172             return hr;
173     }
174 
175     if (version == 1)
176         hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DRGBDevice, (void **)&device1);
177     else
178     {
179         IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D2, (void**)&d3d2);
180         hr = IDirect3D2_CreateDevice(d3d2, &IID_IDirect3DRGBDevice, surface, &device2);
181         IDirect3D2_Release(d3d2);
182     }
183     if (FAILED(hr))
184     {
185         IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds);
186         return hr;
187     }
188 
189     if (version != 1)
190     {
191         hr = IDirect3DDevice2_QueryInterface(device2, &IID_IDirect3DDevice, (void**)&device1);
192         IDirect3DDevice2_Release(device2);
193         if (FAILED(hr))
194         {
195             IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds);
196             return hr;
197         }
198     }
199     device->device = device1;
200     device->width = desc.dwWidth;
201     device->height = desc.dwHeight;
202 
203     return hr;
204 }
205 
206 static HRESULT d3drm_device_set_ddraw_device_d3d(struct d3drm_device *device, IDirect3D *d3d, IDirect3DDevice *d3d_device)
207 {
208     IDirectDraw *ddraw;
209     IDirectDrawSurface *surface;
210     IDirect3DDevice2 *d3d_device2 = NULL;
211     DDSURFACEDESC desc;
212     HRESULT hr;
213 
214     /* AddRef these interfaces beforehand for the intentional leak on reinitialization. */
215     if (FAILED(hr = IDirect3D_QueryInterface(d3d, &IID_IDirectDraw, (void **)&ddraw)))
216         return hr;
217     IDirect3DRM_AddRef(device->d3drm);
218     IDirect3DDevice_AddRef(d3d_device);
219 
220     /* Fetch render target and get width/height from there */
221     if (FAILED(hr = IDirect3DDevice_QueryInterface(d3d_device, &IID_IDirectDrawSurface, (void **)&surface)))
222     {
223         if (FAILED(hr = IDirect3DDevice_QueryInterface(d3d_device, &IID_IDirect3DDevice2, (void **)&d3d_device2)))
224             return hr;
225         hr = IDirect3DDevice2_GetRenderTarget(d3d_device2, &surface);
226         IDirect3DDevice2_Release(d3d_device2);
227         if (FAILED(hr))
228             return hr;
229     }
230 
231     if (device->ddraw)
232     {
233         if (d3d_device2)
234             IDirectDrawSurface_Release(surface);
235         return D3DRMERR_BADOBJECT;
236     }
237 
238     desc.dwSize = sizeof(desc);
239     hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
240     if (FAILED(hr))
241     {
242         IDirectDrawSurface_Release(surface);
243         return hr;
244     }
245 
246     device->ddraw = ddraw;
247     device->width = desc.dwWidth;
248     device->height = desc.dwHeight;
249     device->device = d3d_device;
250     device->render_target = surface;
251 
252     return hr;
253 }
254 
255 static HRESULT WINAPI d3drm_device3_QueryInterface(IDirect3DRMDevice3 *iface, REFIID riid, void **out)
256 {
257     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
258 
259     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
260 
261     if (IsEqualGUID(riid, &IID_IDirect3DRMDevice)
262             || IsEqualGUID(riid, &IID_IDirect3DRMObject)
263             || IsEqualGUID(riid, &IID_IUnknown))
264     {
265         *out = &device->IDirect3DRMDevice_iface;
266     }
267     else if (IsEqualGUID(riid, &IID_IDirect3DRMDevice2))
268     {
269         *out = &device->IDirect3DRMDevice2_iface;
270     }
271     else if (IsEqualGUID(riid, &IID_IDirect3DRMDevice3))
272     {
273         *out = &device->IDirect3DRMDevice3_iface;
274     }
275     else if (IsEqualGUID(riid, &IID_IDirect3DRMWinDevice))
276     {
277         *out = &device->IDirect3DRMWinDevice_iface;
278     }
279     else
280     {
281         *out = NULL;
282         WARN("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(riid));
283         return CLASS_E_CLASSNOTAVAILABLE;
284     }
285 
286     IUnknown_AddRef((IUnknown *)*out);
287     return S_OK;
288 }
289 
290 static HRESULT WINAPI d3drm_device2_QueryInterface(IDirect3DRMDevice2 *iface, REFIID riid, void **out)
291 {
292     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
293 
294     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
295 
296     return d3drm_device3_QueryInterface(&device->IDirect3DRMDevice3_iface, riid, out);
297 }
298 
299 static HRESULT WINAPI d3drm_device1_QueryInterface(IDirect3DRMDevice *iface, REFIID riid, void **out)
300 {
301     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
302 
303     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
304 
305     return d3drm_device3_QueryInterface(&device->IDirect3DRMDevice3_iface, riid, out);
306 }
307 
308 static ULONG WINAPI d3drm_device3_AddRef(IDirect3DRMDevice3 *iface)
309 {
310     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
311     ULONG refcount = InterlockedIncrement(&device->obj.ref);
312 
313     TRACE("%p increasing refcount to %u.\n", iface, refcount);
314 
315     return refcount;
316 }
317 
318 static ULONG WINAPI d3drm_device2_AddRef(IDirect3DRMDevice2 *iface)
319 {
320     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
321 
322     TRACE("iface %p.\n", iface);
323 
324     return d3drm_device3_AddRef(&device->IDirect3DRMDevice3_iface);
325 }
326 
327 static ULONG WINAPI d3drm_device1_AddRef(IDirect3DRMDevice *iface)
328 {
329     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
330 
331     TRACE("iface %p.\n", iface);
332 
333     return d3drm_device3_AddRef(&device->IDirect3DRMDevice3_iface);
334 }
335 
336 static ULONG WINAPI d3drm_device3_Release(IDirect3DRMDevice3 *iface)
337 {
338     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
339     ULONG refcount = InterlockedDecrement(&device->obj.ref);
340 
341     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
342 
343     if (!refcount)
344         d3drm_device_destroy(device);
345 
346     return refcount;
347 }
348 
349 static ULONG WINAPI d3drm_device2_Release(IDirect3DRMDevice2 *iface)
350 {
351     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
352 
353     TRACE("iface %p.\n", iface);
354 
355     return d3drm_device3_Release(&device->IDirect3DRMDevice3_iface);
356 }
357 
358 static ULONG WINAPI d3drm_device1_Release(IDirect3DRMDevice *iface)
359 {
360     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
361 
362     TRACE("iface %p.\n", iface);
363 
364     return d3drm_device3_Release(&device->IDirect3DRMDevice3_iface);
365 }
366 
367 static HRESULT WINAPI d3drm_device3_Clone(IDirect3DRMDevice3 *iface,
368         IUnknown *outer, REFIID iid, void **out)
369 {
370     FIXME("iface %p, outer %p, iid %s, out %p stub!\n", iface, outer, debugstr_guid(iid), out);
371 
372     return E_NOTIMPL;
373 }
374 
375 static HRESULT WINAPI d3drm_device2_Clone(IDirect3DRMDevice2 *iface,
376         IUnknown *outer, REFIID iid, void **out)
377 {
378     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
379 
380     TRACE("iface %p, outer %p, iid %s, out %p\n", iface, outer, debugstr_guid(iid), out);
381 
382     return d3drm_device3_Clone(&device->IDirect3DRMDevice3_iface, outer, iid, out);
383 }
384 
385 static HRESULT WINAPI d3drm_device1_Clone(IDirect3DRMDevice *iface,
386         IUnknown *outer, REFIID iid, void **out)
387 {
388     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
389 
390     TRACE("iface %p, outer %p, iid %s, out %p.\n", iface, outer, debugstr_guid(iid), out);
391 
392     return d3drm_device3_Clone(&device->IDirect3DRMDevice3_iface, outer, iid, out);
393 }
394 
395 static HRESULT WINAPI d3drm_device3_AddDestroyCallback(IDirect3DRMDevice3 *iface,
396         D3DRMOBJECTCALLBACK cb, void *ctx)
397 {
398     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
399 
400     TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
401 
402     return d3drm_object_add_destroy_callback(&device->obj, cb, ctx);
403 }
404 
405 static HRESULT WINAPI d3drm_device2_AddDestroyCallback(IDirect3DRMDevice2 *iface,
406         D3DRMOBJECTCALLBACK cb, void *ctx)
407 {
408     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
409 
410     TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
411 
412     return d3drm_device3_AddDestroyCallback(&device->IDirect3DRMDevice3_iface, cb, ctx);
413 }
414 
415 static HRESULT WINAPI d3drm_device1_AddDestroyCallback(IDirect3DRMDevice *iface,
416         D3DRMOBJECTCALLBACK cb, void *ctx)
417 {
418     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
419 
420     TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
421 
422     return d3drm_device3_AddDestroyCallback(&device->IDirect3DRMDevice3_iface, cb, ctx);
423 }
424 
425 static HRESULT WINAPI d3drm_device3_DeleteDestroyCallback(IDirect3DRMDevice3 *iface,
426         D3DRMOBJECTCALLBACK cb, void *ctx)
427 {
428     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
429 
430     TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
431 
432     return d3drm_object_delete_destroy_callback(&device->obj, cb, ctx);
433 }
434 
435 static HRESULT WINAPI d3drm_device2_DeleteDestroyCallback(IDirect3DRMDevice2 *iface,
436         D3DRMOBJECTCALLBACK cb, void *ctx)
437 {
438     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
439 
440     TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
441 
442     return d3drm_device3_DeleteDestroyCallback(&device->IDirect3DRMDevice3_iface, cb, ctx);
443 }
444 
445 static HRESULT WINAPI d3drm_device1_DeleteDestroyCallback(IDirect3DRMDevice *iface,
446         D3DRMOBJECTCALLBACK cb, void *ctx)
447 {
448     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
449 
450     TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
451 
452     return d3drm_device3_DeleteDestroyCallback(&device->IDirect3DRMDevice3_iface, cb, ctx);
453 }
454 
455 static HRESULT WINAPI d3drm_device3_SetAppData(IDirect3DRMDevice3 *iface, DWORD data)
456 {
457     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
458 
459     TRACE("iface %p, data %#x.\n", iface, data);
460 
461     device->obj.appdata = data;
462 
463     return D3DRM_OK;
464 }
465 
466 static HRESULT WINAPI d3drm_device2_SetAppData(IDirect3DRMDevice2 *iface, DWORD data)
467 {
468     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
469 
470     TRACE("iface %p, data %#x.\n", iface, data);
471 
472     return d3drm_device3_SetAppData(&device->IDirect3DRMDevice3_iface, data);
473 }
474 
475 static HRESULT WINAPI d3drm_device1_SetAppData(IDirect3DRMDevice *iface, DWORD data)
476 {
477     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
478 
479     TRACE("iface %p, data %#x.\n", iface, data);
480 
481     return d3drm_device3_SetAppData(&device->IDirect3DRMDevice3_iface, data);
482 }
483 
484 static DWORD WINAPI d3drm_device3_GetAppData(IDirect3DRMDevice3 *iface)
485 {
486     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
487 
488     TRACE("iface %p.\n", iface);
489 
490     return device->obj.appdata;
491 }
492 
493 static DWORD WINAPI d3drm_device2_GetAppData(IDirect3DRMDevice2 *iface)
494 {
495     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
496 
497     TRACE("iface %p.\n", iface);
498 
499     return d3drm_device3_GetAppData(&device->IDirect3DRMDevice3_iface);
500 }
501 
502 static DWORD WINAPI d3drm_device1_GetAppData(IDirect3DRMDevice *iface)
503 {
504     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
505 
506     TRACE("iface %p.\n", iface);
507 
508     return d3drm_device3_GetAppData(&device->IDirect3DRMDevice3_iface);
509 }
510 
511 static HRESULT WINAPI d3drm_device3_SetName(IDirect3DRMDevice3 *iface, const char *name)
512 {
513     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
514 
515     TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
516 
517     return d3drm_object_set_name(&device->obj, name);
518 }
519 
520 static HRESULT WINAPI d3drm_device2_SetName(IDirect3DRMDevice2 *iface, const char *name)
521 {
522     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
523 
524     TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
525 
526     return d3drm_device3_SetName(&device->IDirect3DRMDevice3_iface, name);
527 }
528 
529 static HRESULT WINAPI d3drm_device1_SetName(IDirect3DRMDevice *iface, const char *name)
530 {
531     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
532 
533     TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
534 
535     return d3drm_device3_SetName(&device->IDirect3DRMDevice3_iface, name);
536 }
537 
538 static HRESULT WINAPI d3drm_device3_GetName(IDirect3DRMDevice3 *iface, DWORD *size, char *name)
539 {
540     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
541 
542     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
543 
544     return d3drm_object_get_name(&device->obj, size, name);
545 }
546 
547 static HRESULT WINAPI d3drm_device2_GetName(IDirect3DRMDevice2 *iface, DWORD *size, char *name)
548 {
549     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
550 
551     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
552 
553     return d3drm_device3_GetName(&device->IDirect3DRMDevice3_iface, size, name);
554 }
555 
556 static HRESULT WINAPI d3drm_device1_GetName(IDirect3DRMDevice *iface, DWORD *size, char *name)
557 {
558     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
559 
560     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
561 
562     return d3drm_device3_GetName(&device->IDirect3DRMDevice3_iface, size, name);
563 }
564 
565 static HRESULT WINAPI d3drm_device3_GetClassName(IDirect3DRMDevice3 *iface, DWORD *size, char *name)
566 {
567     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
568 
569     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
570 
571     return d3drm_object_get_class_name(&device->obj, size, name);
572 }
573 
574 static HRESULT WINAPI d3drm_device2_GetClassName(IDirect3DRMDevice2 *iface, DWORD *size, char *name)
575 {
576     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
577 
578     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
579 
580     return d3drm_device3_GetClassName(&device->IDirect3DRMDevice3_iface, size, name);
581 }
582 
583 static HRESULT WINAPI d3drm_device1_GetClassName(IDirect3DRMDevice *iface, DWORD *size, char *name)
584 {
585     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
586 
587     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
588 
589     return d3drm_device3_GetClassName(&device->IDirect3DRMDevice3_iface, size, name);
590 }
591 
592 static HRESULT WINAPI d3drm_device3_Init(IDirect3DRMDevice3 *iface, ULONG width, ULONG height)
593 {
594     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
595 
596     FIXME("iface %p, width %u, height %u stub!\n", iface, width, height);
597 
598     device->height = height;
599     device->width = width;
600 
601     return D3DRM_OK;
602 }
603 
604 static HRESULT WINAPI d3drm_device2_Init(IDirect3DRMDevice2 *iface, ULONG width, ULONG height)
605 {
606     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
607 
608     TRACE("iface %p, width %u, height %u.\n", iface, width, height);
609 
610     return d3drm_device3_Init(&device->IDirect3DRMDevice3_iface, width, height);
611 }
612 
613 static HRESULT WINAPI d3drm_device1_Init(IDirect3DRMDevice *iface, ULONG width, ULONG height)
614 {
615     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
616 
617     TRACE("iface %p, width %u, height %u.\n", iface, width, height);
618 
619     return d3drm_device3_Init(&device->IDirect3DRMDevice3_iface, width, height);
620 }
621 
622 static HRESULT WINAPI d3drm_device3_InitFromD3D(IDirect3DRMDevice3 *iface,
623         IDirect3D *d3d, IDirect3DDevice *d3d_device)
624 {
625     FIXME("iface %p, d3d %p, d3d_device %p stub!\n", iface, d3d, d3d_device);
626 
627     if (!d3d || !d3d_device)
628         return D3DRMERR_BADVALUE;
629 
630     return E_NOINTERFACE;
631 }
632 
633 static HRESULT WINAPI d3drm_device2_InitFromD3D(IDirect3DRMDevice2 *iface,
634         IDirect3D *d3d, IDirect3DDevice *d3d_device)
635 {
636     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
637 
638     TRACE("iface %p, d3d %p, d3d_device %p.\n", iface, d3d, d3d_device);
639 
640     return d3drm_device3_InitFromD3D(&device->IDirect3DRMDevice3_iface, d3d, d3d_device);
641 }
642 
643 static HRESULT WINAPI d3drm_device1_InitFromD3D(IDirect3DRMDevice *iface,
644         IDirect3D *d3d, IDirect3DDevice *d3d_device)
645 {
646     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
647 
648     TRACE("iface %p, d3d %p, d3d_device %p.\n", iface, d3d, d3d_device);
649 
650     if (!d3d || !d3d_device)
651         return D3DRMERR_BADVALUE;
652 
653     return d3drm_device_set_ddraw_device_d3d(device, d3d, d3d_device);
654 }
655 
656 static HRESULT WINAPI d3drm_device3_InitFromClipper(IDirect3DRMDevice3 *iface,
657         IDirectDrawClipper *clipper, GUID *guid, int width, int height)
658 {
659     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
660 
661     FIXME("iface %p, clipper %p, guid %s, width %d, height %d stub!\n",
662             iface, clipper, debugstr_guid(guid), width, height);
663 
664     device->height = height;
665     device->width = width;
666 
667     return D3DRM_OK;
668 }
669 
670 static HRESULT WINAPI d3drm_device2_InitFromClipper(IDirect3DRMDevice2 *iface,
671         IDirectDrawClipper *clipper, GUID *guid, int width, int height)
672 {
673     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
674 
675     TRACE("iface %p, clipper %p, guid %s, width %d, height %d.\n",
676             iface, clipper, debugstr_guid(guid), width, height);
677 
678     return d3drm_device3_InitFromClipper(&device->IDirect3DRMDevice3_iface,
679             clipper, guid, width, height);
680 }
681 
682 static HRESULT WINAPI d3drm_device1_InitFromClipper(IDirect3DRMDevice *iface,
683         IDirectDrawClipper *clipper, GUID *guid, int width, int height)
684 {
685     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
686 
687     TRACE("iface %p, clipper %p, guid %s, width %d, height %d.\n",
688         iface, clipper, debugstr_guid(guid), width, height);
689 
690     return d3drm_device3_InitFromClipper(&device->IDirect3DRMDevice3_iface,
691         clipper, guid, width, height);
692 }
693 
694 static HRESULT WINAPI d3drm_device3_Update(IDirect3DRMDevice3 *iface)
695 {
696     FIXME("iface %p stub!\n", iface);
697 
698     return D3DRM_OK;
699 }
700 
701 static HRESULT WINAPI d3drm_device2_Update(IDirect3DRMDevice2 *iface)
702 {
703     FIXME("iface %p stub!\n", iface);
704 
705     return D3DRM_OK;
706 }
707 
708 static HRESULT WINAPI d3drm_device1_Update(IDirect3DRMDevice *iface)
709 {
710     FIXME("iface %p stub!\n", iface);
711 
712     return D3DRM_OK;
713 }
714 
715 static HRESULT WINAPI d3drm_device3_AddUpdateCallback(IDirect3DRMDevice3 *iface,
716         D3DRMUPDATECALLBACK cb, void *ctx)
717 {
718     FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
719 
720     return E_NOTIMPL;
721 }
722 
723 static HRESULT WINAPI d3drm_device2_AddUpdateCallback(IDirect3DRMDevice2 *iface,
724         D3DRMUPDATECALLBACK cb, void *ctx)
725 {
726     FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
727 
728     return E_NOTIMPL;
729 }
730 
731 static HRESULT WINAPI d3drm_device1_AddUpdateCallback(IDirect3DRMDevice *iface,
732         D3DRMUPDATECALLBACK cb, void *ctx)
733 {
734     FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
735 
736     return E_NOTIMPL;
737 }
738 
739 static HRESULT WINAPI d3drm_device3_DeleteUpdateCallback(IDirect3DRMDevice3 *iface,
740         D3DRMUPDATECALLBACK cb, void *ctx)
741 {
742     FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
743 
744     return E_NOTIMPL;
745 }
746 
747 static HRESULT WINAPI d3drm_device2_DeleteUpdateCallback(IDirect3DRMDevice2 *iface,
748         D3DRMUPDATECALLBACK cb, void *ctx)
749 {
750     FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
751 
752     return E_NOTIMPL;
753 }
754 
755 static HRESULT WINAPI d3drm_device1_DeleteUpdateCallback(IDirect3DRMDevice *iface,
756         D3DRMUPDATECALLBACK cb, void *ctx)
757 {
758     FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
759 
760     return E_NOTIMPL;
761 }
762 
763 static HRESULT WINAPI d3drm_device3_SetBufferCount(IDirect3DRMDevice3 *iface, DWORD count)
764 {
765     FIXME("iface %p, count %u stub!\n", iface, count);
766 
767     return E_NOTIMPL;
768 }
769 
770 static HRESULT WINAPI d3drm_device2_SetBufferCount(IDirect3DRMDevice2 *iface, DWORD count)
771 {
772     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
773 
774     TRACE("iface %p, count %u.\n", iface, count);
775 
776     return d3drm_device3_SetBufferCount(&device->IDirect3DRMDevice3_iface, count);
777 }
778 
779 static HRESULT WINAPI d3drm_device1_SetBufferCount(IDirect3DRMDevice *iface, DWORD count)
780 {
781     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
782 
783     TRACE("iface %p, count %u.\n", iface, count);
784 
785     return d3drm_device3_SetBufferCount(&device->IDirect3DRMDevice3_iface, count);
786 }
787 
788 static DWORD WINAPI d3drm_device3_GetBufferCount(IDirect3DRMDevice3 *iface)
789 {
790     FIXME("iface %p stub!\n", iface);
791 
792     return E_NOTIMPL;
793 }
794 
795 static DWORD WINAPI d3drm_device2_GetBufferCount(IDirect3DRMDevice2 *iface)
796 {
797     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
798 
799     TRACE("iface %p.\n", iface);
800 
801     return d3drm_device3_GetBufferCount(&device->IDirect3DRMDevice3_iface);
802 }
803 
804 static DWORD WINAPI d3drm_device1_GetBufferCount(IDirect3DRMDevice *iface)
805 {
806     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
807 
808     TRACE("iface %p.\n", iface);
809 
810     return d3drm_device3_GetBufferCount(&device->IDirect3DRMDevice3_iface);
811 }
812 
813 static HRESULT WINAPI d3drm_device3_SetDither(IDirect3DRMDevice3 *iface, BOOL enable)
814 {
815     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
816 
817     TRACE("iface %p, enable %#x.\n", iface, enable);
818 
819     device->dither = enable;
820 
821     return D3DRM_OK;
822 }
823 
824 static HRESULT WINAPI d3drm_device2_SetDither(IDirect3DRMDevice2 *iface, BOOL enable)
825 {
826     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
827 
828     TRACE("iface %p, enabled %#x.\n", iface, enable);
829 
830     return d3drm_device3_SetDither(&device->IDirect3DRMDevice3_iface, enable);
831 }
832 
833 static HRESULT WINAPI d3drm_device1_SetDither(IDirect3DRMDevice *iface, BOOL enable)
834 {
835     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
836 
837     TRACE("iface %p, enabled %#x.\n", iface, enable);
838 
839     return d3drm_device3_SetDither(&device->IDirect3DRMDevice3_iface, enable);
840 }
841 
842 static HRESULT WINAPI d3drm_device3_SetShades(IDirect3DRMDevice3 *iface, DWORD count)
843 {
844     FIXME("iface %p, count %u stub!\n", iface, count);
845 
846     return E_NOTIMPL;
847 }
848 
849 static HRESULT WINAPI d3drm_device2_SetShades(IDirect3DRMDevice2 *iface, DWORD count)
850 {
851     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
852 
853     TRACE("iface %p, count %u.\n", iface, count);
854 
855     return d3drm_device3_SetShades(&device->IDirect3DRMDevice3_iface, count);
856 }
857 
858 static HRESULT WINAPI d3drm_device1_SetShades(IDirect3DRMDevice *iface, DWORD count)
859 {
860     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
861 
862     TRACE("iface %p, count %u.\n", iface, count);
863 
864     return d3drm_device3_SetShades(&device->IDirect3DRMDevice3_iface, count);
865 }
866 
867 static HRESULT WINAPI d3drm_device3_SetQuality(IDirect3DRMDevice3 *iface, D3DRMRENDERQUALITY quality)
868 {
869     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
870 
871     TRACE("iface %p, quality %u.\n", iface, quality);
872 
873     device->quality = quality;
874 
875     return D3DRM_OK;
876 }
877 
878 static HRESULT WINAPI d3drm_device2_SetQuality(IDirect3DRMDevice2 *iface, D3DRMRENDERQUALITY quality)
879 {
880     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
881 
882     TRACE("iface %p, quality %u.\n", iface, quality);
883 
884     return d3drm_device3_SetQuality(&device->IDirect3DRMDevice3_iface, quality);
885 }
886 
887 static HRESULT WINAPI d3drm_device1_SetQuality(IDirect3DRMDevice *iface, D3DRMRENDERQUALITY quality)
888 {
889     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
890 
891     TRACE("iface %p, quality %u.\n", iface, quality);
892 
893     return d3drm_device3_SetQuality(&device->IDirect3DRMDevice3_iface, quality);
894 }
895 
896 static HRESULT WINAPI d3drm_device3_SetTextureQuality(IDirect3DRMDevice3 *iface, D3DRMTEXTUREQUALITY quality)
897 {
898     FIXME("iface %p, quality %u stub!\n", iface, quality);
899 
900     return E_NOTIMPL;
901 }
902 
903 static HRESULT WINAPI d3drm_device2_SetTextureQuality(IDirect3DRMDevice2 *iface, D3DRMTEXTUREQUALITY quality)
904 {
905     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
906 
907     TRACE("iface %p, quality %u.\n", iface, quality);
908 
909     return d3drm_device3_SetTextureQuality(&device->IDirect3DRMDevice3_iface, quality);
910 }
911 
912 static HRESULT WINAPI d3drm_device1_SetTextureQuality(IDirect3DRMDevice *iface, D3DRMTEXTUREQUALITY quality)
913 {
914     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
915 
916     TRACE("iface %p, quality %u.\n", iface, quality);
917 
918     return d3drm_device3_SetTextureQuality(&device->IDirect3DRMDevice3_iface, quality);
919 }
920 
921 static HRESULT WINAPI d3drm_device3_GetViewports(IDirect3DRMDevice3 *iface, IDirect3DRMViewportArray **array)
922 {
923     FIXME("iface %p, array %p stub!\n", iface, array);
924 
925     return E_NOTIMPL;
926 }
927 
928 static HRESULT WINAPI d3drm_device2_GetViewports(IDirect3DRMDevice2 *iface, IDirect3DRMViewportArray **array)
929 {
930     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
931 
932     TRACE("iface %p, array %p.\n", iface, array);
933 
934     return d3drm_device3_GetViewports(&device->IDirect3DRMDevice3_iface, array);
935 }
936 
937 static HRESULT WINAPI d3drm_device1_GetViewports(IDirect3DRMDevice *iface, IDirect3DRMViewportArray **array)
938 {
939     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
940 
941     TRACE("iface %p, array %p.\n", iface, array);
942 
943     return d3drm_device3_GetViewports(&device->IDirect3DRMDevice3_iface, array);
944 }
945 
946 static BOOL WINAPI d3drm_device3_GetDither(IDirect3DRMDevice3 *iface)
947 {
948     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
949 
950     TRACE("iface %p.\n", iface);
951 
952     return device->dither;
953 }
954 
955 static BOOL WINAPI d3drm_device2_GetDither(IDirect3DRMDevice2 *iface)
956 {
957     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
958 
959     TRACE("iface %p.\n", iface);
960 
961     return d3drm_device3_GetDither(&device->IDirect3DRMDevice3_iface);
962 }
963 
964 static BOOL WINAPI d3drm_device1_GetDither(IDirect3DRMDevice *iface)
965 {
966     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
967 
968     TRACE("iface %p.\n", iface);
969 
970     return d3drm_device3_GetDither(&device->IDirect3DRMDevice3_iface);
971 }
972 
973 static DWORD WINAPI d3drm_device3_GetShades(IDirect3DRMDevice3 *iface)
974 {
975     FIXME("iface %p stub!\n", iface);
976 
977     return E_NOTIMPL;
978 }
979 
980 static DWORD WINAPI d3drm_device2_GetShades(IDirect3DRMDevice2 *iface)
981 {
982     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
983 
984     TRACE("iface %p.\n", iface);
985 
986     return d3drm_device3_GetShades(&device->IDirect3DRMDevice3_iface);
987 }
988 
989 static DWORD WINAPI d3drm_device1_GetShades(IDirect3DRMDevice *iface)
990 {
991     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
992 
993     TRACE("iface %p.\n", iface);
994 
995     return d3drm_device3_GetShades(&device->IDirect3DRMDevice3_iface);
996 }
997 
998 static DWORD WINAPI d3drm_device3_GetHeight(IDirect3DRMDevice3 *iface)
999 {
1000     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
1001 
1002     TRACE("iface %p.\n", iface);
1003 
1004     return device->height;
1005 }
1006 
1007 static DWORD WINAPI d3drm_device2_GetHeight(IDirect3DRMDevice2 *iface)
1008 {
1009     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1010 
1011     TRACE("iface %p.\n", iface);
1012 
1013     return d3drm_device3_GetHeight(&device->IDirect3DRMDevice3_iface);
1014 }
1015 
1016 static DWORD WINAPI d3drm_device1_GetHeight(IDirect3DRMDevice *iface)
1017 {
1018     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
1019 
1020     TRACE("iface %p.\n", iface);
1021 
1022     return d3drm_device3_GetHeight(&device->IDirect3DRMDevice3_iface);
1023 }
1024 
1025 static DWORD WINAPI d3drm_device3_GetWidth(IDirect3DRMDevice3 *iface)
1026 {
1027     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
1028 
1029     TRACE("iface %p.\n", iface);
1030 
1031     return device->width;
1032 }
1033 
1034 static DWORD WINAPI d3drm_device2_GetWidth(IDirect3DRMDevice2 *iface)
1035 {
1036     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1037 
1038     TRACE("iface %p.\n", iface);
1039 
1040     return d3drm_device3_GetWidth(&device->IDirect3DRMDevice3_iface);
1041 }
1042 
1043 static DWORD WINAPI d3drm_device1_GetWidth(IDirect3DRMDevice *iface)
1044 {
1045     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
1046 
1047     TRACE("iface %p.\n", iface);
1048 
1049     return d3drm_device3_GetWidth(&device->IDirect3DRMDevice3_iface);
1050 }
1051 
1052 static DWORD WINAPI d3drm_device3_GetTrianglesDrawn(IDirect3DRMDevice3 *iface)
1053 {
1054     FIXME("iface %p stub!\n", iface);
1055 
1056     return E_NOTIMPL;
1057 }
1058 
1059 static DWORD WINAPI d3drm_device2_GetTrianglesDrawn(IDirect3DRMDevice2 *iface)
1060 {
1061     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1062 
1063     TRACE("iface %p.\n", iface);
1064 
1065     return d3drm_device3_GetTrianglesDrawn(&device->IDirect3DRMDevice3_iface);
1066 }
1067 
1068 static DWORD WINAPI d3drm_device1_GetTrianglesDrawn(IDirect3DRMDevice *iface)
1069 {
1070     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
1071 
1072     TRACE("iface %p.\n", iface);
1073 
1074     return d3drm_device3_GetTrianglesDrawn(&device->IDirect3DRMDevice3_iface);
1075 }
1076 
1077 static DWORD WINAPI d3drm_device3_GetWireframeOptions(IDirect3DRMDevice3 *iface)
1078 {
1079     FIXME("iface %p stub!\n", iface);
1080 
1081     return E_NOTIMPL;
1082 }
1083 
1084 static DWORD WINAPI d3drm_device2_GetWireframeOptions(IDirect3DRMDevice2 *iface)
1085 {
1086     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1087 
1088     TRACE("iface %p.\n", iface);
1089 
1090     return d3drm_device3_GetWireframeOptions(&device->IDirect3DRMDevice3_iface);
1091 }
1092 
1093 static DWORD WINAPI d3drm_device1_GetWireframeOptions(IDirect3DRMDevice *iface)
1094 {
1095     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
1096 
1097     TRACE("iface %p.\n", iface);
1098 
1099     return d3drm_device3_GetWireframeOptions(&device->IDirect3DRMDevice3_iface);
1100 }
1101 
1102 static D3DRMRENDERQUALITY WINAPI d3drm_device3_GetQuality(IDirect3DRMDevice3 *iface)
1103 {
1104     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
1105 
1106     TRACE("iface %p.\n", iface);
1107 
1108     return device->quality;
1109 }
1110 
1111 static D3DRMRENDERQUALITY WINAPI d3drm_device2_GetQuality(IDirect3DRMDevice2 *iface)
1112 {
1113     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1114 
1115     TRACE("iface %p.\n", iface);
1116 
1117     return d3drm_device3_GetQuality(&device->IDirect3DRMDevice3_iface);
1118 }
1119 
1120 static D3DRMRENDERQUALITY WINAPI d3drm_device1_GetQuality(IDirect3DRMDevice *iface)
1121 {
1122     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
1123 
1124     TRACE("iface %p.\n", iface);
1125 
1126     return d3drm_device3_GetQuality(&device->IDirect3DRMDevice3_iface);
1127 }
1128 
1129 static D3DCOLORMODEL WINAPI d3drm_device3_GetColorModel(IDirect3DRMDevice3 *iface)
1130 {
1131     FIXME("iface %p stub!\n", iface);
1132 
1133     return E_NOTIMPL;
1134 }
1135 
1136 static D3DCOLORMODEL WINAPI d3drm_device2_GetColorModel(IDirect3DRMDevice2 *iface)
1137 {
1138     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1139 
1140     TRACE("iface %p.\n", iface);
1141 
1142     return d3drm_device3_GetColorModel(&device->IDirect3DRMDevice3_iface);
1143 }
1144 
1145 static D3DCOLORMODEL WINAPI d3drm_device1_GetColorModel(IDirect3DRMDevice *iface)
1146 {
1147     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
1148 
1149     TRACE("iface %p.\n", iface);
1150 
1151     return d3drm_device3_GetColorModel(&device->IDirect3DRMDevice3_iface);
1152 }
1153 
1154 static D3DRMTEXTUREQUALITY WINAPI d3drm_device3_GetTextureQuality(IDirect3DRMDevice3 *iface)
1155 {
1156     FIXME("iface %p stub!\n", iface);
1157 
1158     return E_NOTIMPL;
1159 }
1160 
1161 static D3DRMTEXTUREQUALITY WINAPI d3drm_device2_GetTextureQuality(IDirect3DRMDevice2 *iface)
1162 {
1163     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1164 
1165     TRACE("iface %p.\n", iface);
1166 
1167     return d3drm_device3_GetTextureQuality(&device->IDirect3DRMDevice3_iface);
1168 }
1169 
1170 static D3DRMTEXTUREQUALITY WINAPI d3drm_device1_GetTextureQuality(IDirect3DRMDevice *iface)
1171 {
1172     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
1173 
1174     TRACE("iface %p.\n", iface);
1175 
1176     return d3drm_device3_GetTextureQuality(&device->IDirect3DRMDevice3_iface);
1177 }
1178 
1179 static HRESULT WINAPI d3drm_device3_GetDirect3DDevice(IDirect3DRMDevice3 *iface, IDirect3DDevice **d3d_device)
1180 {
1181     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
1182     TRACE("iface %p, d3d_device %p!\n", iface, d3d_device);
1183 
1184     *d3d_device = device->device;
1185     IDirect3DDevice_AddRef(*d3d_device);
1186 
1187     return D3DRM_OK;
1188 }
1189 
1190 static HRESULT WINAPI d3drm_device2_GetDirect3DDevice(IDirect3DRMDevice2 *iface, IDirect3DDevice **d3d_device)
1191 {
1192     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1193 
1194     TRACE("iface %p, d3d_device %p.\n", iface, d3d_device);
1195 
1196     return d3drm_device3_GetDirect3DDevice(&device->IDirect3DRMDevice3_iface, d3d_device);
1197 }
1198 
1199 static HRESULT WINAPI d3drm_device1_GetDirect3DDevice(IDirect3DRMDevice *iface, IDirect3DDevice **d3d_device)
1200 {
1201     struct d3drm_device *device = impl_from_IDirect3DRMDevice(iface);
1202 
1203     TRACE("iface %p, d3d_device %p.\n", iface, d3d_device);
1204 
1205     return d3drm_device3_GetDirect3DDevice(&device->IDirect3DRMDevice3_iface, d3d_device);
1206 }
1207 
1208 static HRESULT WINAPI d3drm_device3_InitFromD3D2(IDirect3DRMDevice3 *iface,
1209         IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device)
1210 {
1211     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
1212     IDirect3D *d3d1;
1213     IDirect3DDevice *d3d_device1;
1214     HRESULT hr;
1215 
1216     TRACE("iface %p, d3d %p, d3d_device %p.\n", iface, d3d, d3d_device);
1217 
1218     if (!d3d || !d3d_device)
1219         return D3DRMERR_BADVALUE;
1220 
1221     if (FAILED(hr = IDirect3D2_QueryInterface(d3d, &IID_IDirect3D, (void **)&d3d1)))
1222         return hr;
1223     if (FAILED(hr = IDirect3DDevice2_QueryInterface(d3d_device, &IID_IDirect3DDevice, (void **)&d3d_device1)))
1224     {
1225         IDirect3D_Release(d3d1);
1226         return hr;
1227     }
1228 
1229     hr = d3drm_device_set_ddraw_device_d3d(device, d3d1, d3d_device1);
1230     IDirect3D_Release(d3d1);
1231     IDirect3DDevice_Release(d3d_device1);
1232 
1233     return hr;
1234 }
1235 
1236 static HRESULT WINAPI d3drm_device2_InitFromD3D2(IDirect3DRMDevice2 *iface,
1237         IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device)
1238 {
1239     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1240 
1241     TRACE("iface %p, d3d %p, d3d_device %p.\n", iface, d3d, d3d_device);
1242 
1243     return d3drm_device3_InitFromD3D2(&device->IDirect3DRMDevice3_iface, d3d, d3d_device);
1244 }
1245 
1246 static HRESULT WINAPI d3drm_device3_InitFromSurface(IDirect3DRMDevice3 *iface,
1247         GUID *guid, IDirectDraw *ddraw, IDirectDrawSurface *backbuffer)
1248 {
1249     FIXME("iface %p, guid %s, ddraw %p, backbuffer %p stub!\n",
1250             iface, debugstr_guid(guid), ddraw, backbuffer);
1251 
1252     return E_NOTIMPL;
1253 }
1254 
1255 static HRESULT WINAPI d3drm_device2_InitFromSurface(IDirect3DRMDevice2 *iface,
1256         GUID *guid, IDirectDraw *ddraw, IDirectDrawSurface *backbuffer)
1257 {
1258     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1259 
1260     TRACE("iface %p, guid %s, ddraw %p, backbuffer %p.\n",
1261             iface, debugstr_guid(guid), ddraw, backbuffer);
1262 
1263     return d3drm_device3_InitFromSurface(&device->IDirect3DRMDevice3_iface, guid, ddraw, backbuffer);
1264 }
1265 
1266 static HRESULT WINAPI d3drm_device3_SetRenderMode(IDirect3DRMDevice3 *iface, DWORD flags)
1267 {
1268     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
1269 
1270     TRACE("iface %p, flags %#x.\n", iface, flags);
1271 
1272     device->rendermode = flags;
1273 
1274     return D3DRM_OK;
1275 }
1276 
1277 static HRESULT WINAPI d3drm_device2_SetRenderMode(IDirect3DRMDevice2 *iface, DWORD flags)
1278 {
1279     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1280 
1281     TRACE("iface %p, flags %#x.\n", iface, flags);
1282 
1283     return d3drm_device3_SetRenderMode(&device->IDirect3DRMDevice3_iface, flags);
1284 }
1285 
1286 static DWORD WINAPI d3drm_device3_GetRenderMode(IDirect3DRMDevice3 *iface)
1287 {
1288     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
1289 
1290     TRACE("iface %p.\n", iface);
1291 
1292     return device->rendermode;
1293 }
1294 
1295 static DWORD WINAPI d3drm_device2_GetRenderMode(IDirect3DRMDevice2 *iface)
1296 {
1297     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1298 
1299     TRACE("iface %p.\n", iface);
1300 
1301     return d3drm_device3_GetRenderMode(&device->IDirect3DRMDevice3_iface);
1302 }
1303 
1304 static HRESULT WINAPI d3drm_device3_GetDirect3DDevice2(IDirect3DRMDevice3 *iface, IDirect3DDevice2 **d3d_device)
1305 {
1306     struct d3drm_device *device = impl_from_IDirect3DRMDevice3(iface);
1307 
1308     TRACE("iface %p, d3d_device %p.\n", iface, d3d_device);
1309 
1310     if (FAILED(IDirect3DDevice_QueryInterface(device->device, &IID_IDirect3DDevice2, (void**)d3d_device)))
1311         return D3DRMERR_BADOBJECT;
1312 
1313     return D3DRM_OK;
1314 }
1315 
1316 static HRESULT WINAPI d3drm_device2_GetDirect3DDevice2(IDirect3DRMDevice2 *iface, IDirect3DDevice2 **d3d_device)
1317 {
1318     struct d3drm_device *device = impl_from_IDirect3DRMDevice2(iface);
1319 
1320     TRACE("iface %p, d3d_device %p.\n", iface, d3d_device);
1321 
1322     IDirect3DDevice_QueryInterface(device->device, &IID_IDirect3DDevice2, (void**)d3d_device);
1323 
1324     /* d3drm returns D3DRM_OK even if the call fails. */
1325     return D3DRM_OK;
1326 }
1327 
1328 static HRESULT WINAPI d3drm_device3_FindPreferredTextureFormat(IDirect3DRMDevice3 *iface,
1329         DWORD bitdepths, DWORD flags, DDPIXELFORMAT *pf)
1330 {
1331     FIXME("iface %p, bitdepths %u, flags %#x, pf %p stub!\n", iface, bitdepths, flags, pf);
1332 
1333     return E_NOTIMPL;
1334 }
1335 
1336 static HRESULT WINAPI d3drm_device3_RenderStateChange(IDirect3DRMDevice3 *iface,
1337         D3DRENDERSTATETYPE state, DWORD value, DWORD flags)
1338 {
1339     FIXME("iface %p, state %#x, value %#x, flags %#x stub!\n", iface, state, value, flags);
1340 
1341     return E_NOTIMPL;
1342 }
1343 
1344 static HRESULT WINAPI d3drm_device3_LightStateChange(IDirect3DRMDevice3 *iface,
1345         D3DLIGHTSTATETYPE state, DWORD value, DWORD flags)
1346 {
1347     FIXME("iface %p, state %#x, value %#x, flags %#x stub!\n", iface, state, value, flags);
1348 
1349     return E_NOTIMPL;
1350 }
1351 
1352 static HRESULT WINAPI d3drm_device3_GetStateChangeOptions(IDirect3DRMDevice3 *iface,
1353         DWORD state_class, DWORD state_idx, DWORD *flags)
1354 {
1355     FIXME("iface %p, state_class %#x, state_idx %#x, flags %p stub!\n",
1356             iface, state_class, state_idx, flags);
1357 
1358     return E_NOTIMPL;
1359 }
1360 
1361 static HRESULT WINAPI d3drm_device3_SetStateChangeOptions(IDirect3DRMDevice3 *iface,
1362         DWORD state_class, DWORD state_idx, DWORD flags)
1363 {
1364     FIXME("iface %p, state_class %#x, state_idx %#x, flags %#x stub!\n",
1365             iface, state_class, state_idx, flags);
1366 
1367     return E_NOTIMPL;
1368 }
1369 
1370 static const struct IDirect3DRMDevice3Vtbl d3drm_device3_vtbl =
1371 {
1372     d3drm_device3_QueryInterface,
1373     d3drm_device3_AddRef,
1374     d3drm_device3_Release,
1375     d3drm_device3_Clone,
1376     d3drm_device3_AddDestroyCallback,
1377     d3drm_device3_DeleteDestroyCallback,
1378     d3drm_device3_SetAppData,
1379     d3drm_device3_GetAppData,
1380     d3drm_device3_SetName,
1381     d3drm_device3_GetName,
1382     d3drm_device3_GetClassName,
1383     d3drm_device3_Init,
1384     d3drm_device3_InitFromD3D,
1385     d3drm_device3_InitFromClipper,
1386     d3drm_device3_Update,
1387     d3drm_device3_AddUpdateCallback,
1388     d3drm_device3_DeleteUpdateCallback,
1389     d3drm_device3_SetBufferCount,
1390     d3drm_device3_GetBufferCount,
1391     d3drm_device3_SetDither,
1392     d3drm_device3_SetShades,
1393     d3drm_device3_SetQuality,
1394     d3drm_device3_SetTextureQuality,
1395     d3drm_device3_GetViewports,
1396     d3drm_device3_GetDither,
1397     d3drm_device3_GetShades,
1398     d3drm_device3_GetHeight,
1399     d3drm_device3_GetWidth,
1400     d3drm_device3_GetTrianglesDrawn,
1401     d3drm_device3_GetWireframeOptions,
1402     d3drm_device3_GetQuality,
1403     d3drm_device3_GetColorModel,
1404     d3drm_device3_GetTextureQuality,
1405     d3drm_device3_GetDirect3DDevice,
1406     d3drm_device3_InitFromD3D2,
1407     d3drm_device3_InitFromSurface,
1408     d3drm_device3_SetRenderMode,
1409     d3drm_device3_GetRenderMode,
1410     d3drm_device3_GetDirect3DDevice2,
1411     d3drm_device3_FindPreferredTextureFormat,
1412     d3drm_device3_RenderStateChange,
1413     d3drm_device3_LightStateChange,
1414     d3drm_device3_GetStateChangeOptions,
1415     d3drm_device3_SetStateChangeOptions,
1416 };
1417 
1418 static const struct IDirect3DRMDevice2Vtbl d3drm_device2_vtbl =
1419 {
1420     d3drm_device2_QueryInterface,
1421     d3drm_device2_AddRef,
1422     d3drm_device2_Release,
1423     d3drm_device2_Clone,
1424     d3drm_device2_AddDestroyCallback,
1425     d3drm_device2_DeleteDestroyCallback,
1426     d3drm_device2_SetAppData,
1427     d3drm_device2_GetAppData,
1428     d3drm_device2_SetName,
1429     d3drm_device2_GetName,
1430     d3drm_device2_GetClassName,
1431     d3drm_device2_Init,
1432     d3drm_device2_InitFromD3D,
1433     d3drm_device2_InitFromClipper,
1434     d3drm_device2_Update,
1435     d3drm_device2_AddUpdateCallback,
1436     d3drm_device2_DeleteUpdateCallback,
1437     d3drm_device2_SetBufferCount,
1438     d3drm_device2_GetBufferCount,
1439     d3drm_device2_SetDither,
1440     d3drm_device2_SetShades,
1441     d3drm_device2_SetQuality,
1442     d3drm_device2_SetTextureQuality,
1443     d3drm_device2_GetViewports,
1444     d3drm_device2_GetDither,
1445     d3drm_device2_GetShades,
1446     d3drm_device2_GetHeight,
1447     d3drm_device2_GetWidth,
1448     d3drm_device2_GetTrianglesDrawn,
1449     d3drm_device2_GetWireframeOptions,
1450     d3drm_device2_GetQuality,
1451     d3drm_device2_GetColorModel,
1452     d3drm_device2_GetTextureQuality,
1453     d3drm_device2_GetDirect3DDevice,
1454     d3drm_device2_InitFromD3D2,
1455     d3drm_device2_InitFromSurface,
1456     d3drm_device2_SetRenderMode,
1457     d3drm_device2_GetRenderMode,
1458     d3drm_device2_GetDirect3DDevice2,
1459 };
1460 
1461 static const struct IDirect3DRMDeviceVtbl d3drm_device1_vtbl =
1462 {
1463     d3drm_device1_QueryInterface,
1464     d3drm_device1_AddRef,
1465     d3drm_device1_Release,
1466     d3drm_device1_Clone,
1467     d3drm_device1_AddDestroyCallback,
1468     d3drm_device1_DeleteDestroyCallback,
1469     d3drm_device1_SetAppData,
1470     d3drm_device1_GetAppData,
1471     d3drm_device1_SetName,
1472     d3drm_device1_GetName,
1473     d3drm_device1_GetClassName,
1474     d3drm_device1_Init,
1475     d3drm_device1_InitFromD3D,
1476     d3drm_device1_InitFromClipper,
1477     d3drm_device1_Update,
1478     d3drm_device1_AddUpdateCallback,
1479     d3drm_device1_DeleteUpdateCallback,
1480     d3drm_device1_SetBufferCount,
1481     d3drm_device1_GetBufferCount,
1482     d3drm_device1_SetDither,
1483     d3drm_device1_SetShades,
1484     d3drm_device1_SetQuality,
1485     d3drm_device1_SetTextureQuality,
1486     d3drm_device1_GetViewports,
1487     d3drm_device1_GetDither,
1488     d3drm_device1_GetShades,
1489     d3drm_device1_GetHeight,
1490     d3drm_device1_GetWidth,
1491     d3drm_device1_GetTrianglesDrawn,
1492     d3drm_device1_GetWireframeOptions,
1493     d3drm_device1_GetQuality,
1494     d3drm_device1_GetColorModel,
1495     d3drm_device1_GetTextureQuality,
1496     d3drm_device1_GetDirect3DDevice,
1497 };
1498 
1499 static HRESULT WINAPI d3drm_device_win_QueryInterface(IDirect3DRMWinDevice *iface, REFIID riid, void **out)
1500 {
1501     struct d3drm_device *device = impl_from_IDirect3DRMWinDevice(iface);
1502 
1503     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
1504 
1505     return d3drm_device3_QueryInterface(&device->IDirect3DRMDevice3_iface, riid, out);
1506 }
1507 
1508 static ULONG WINAPI d3drm_device_win_AddRef(IDirect3DRMWinDevice *iface)
1509 {
1510     struct d3drm_device *device = impl_from_IDirect3DRMWinDevice(iface);
1511 
1512     TRACE("iface %p.\n", iface);
1513 
1514     return d3drm_device3_AddRef(&device->IDirect3DRMDevice3_iface);
1515 }
1516 
1517 static ULONG WINAPI d3drm_device_win_Release(IDirect3DRMWinDevice *iface)
1518 {
1519     struct d3drm_device *device = impl_from_IDirect3DRMWinDevice(iface);
1520 
1521     TRACE("iface %p.\n", iface);
1522 
1523     return d3drm_device3_Release(&device->IDirect3DRMDevice3_iface);
1524 }
1525 
1526 static HRESULT WINAPI d3drm_device_win_Clone(IDirect3DRMWinDevice *iface,
1527         IUnknown *outer, REFIID iid, void **out)
1528 {
1529     struct d3drm_device *device = impl_from_IDirect3DRMWinDevice(iface);
1530 
1531     TRACE("iface %p, outer %p, iid %s, out %p\n", iface, outer, debugstr_guid(iid), out);
1532 
1533     return d3drm_device3_Clone(&device->IDirect3DRMDevice3_iface, outer, iid, out);
1534 }
1535 
1536 static HRESULT WINAPI d3drm_device_win_AddDestroyCallback(IDirect3DRMWinDevice *iface,
1537         D3DRMOBJECTCALLBACK cb, void *ctx)
1538 {
1539     FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1540 
1541     return E_NOTIMPL;
1542 }
1543 
1544 static HRESULT WINAPI d3drm_device_win_DeleteDestroyCallback(IDirect3DRMWinDevice *iface,
1545         D3DRMOBJECTCALLBACK cb, void *ctx)
1546 {
1547     FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1548 
1549     return E_NOTIMPL;
1550 }
1551 
1552 static HRESULT WINAPI d3drm_device_win_SetAppData(IDirect3DRMWinDevice *iface, DWORD data)
1553 {
1554     struct d3drm_device *device = impl_from_IDirect3DRMWinDevice(iface);
1555 
1556     TRACE("iface %p, data %#x.\n", iface, data);
1557 
1558     return d3drm_device3_SetAppData(&device->IDirect3DRMDevice3_iface, data);
1559 }
1560 
1561 static DWORD WINAPI d3drm_device_win_GetAppData(IDirect3DRMWinDevice *iface)
1562 {
1563     struct d3drm_device *device = impl_from_IDirect3DRMWinDevice(iface);
1564 
1565     TRACE("iface %p.\n", iface);
1566 
1567     return d3drm_device3_GetAppData(&device->IDirect3DRMDevice3_iface);
1568 }
1569 
1570 static HRESULT WINAPI d3drm_device_win_SetName(IDirect3DRMWinDevice *iface, const char *name)
1571 {
1572     struct d3drm_device *device = impl_from_IDirect3DRMWinDevice(iface);
1573 
1574     TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
1575 
1576     return d3drm_device3_SetName(&device->IDirect3DRMDevice3_iface, name);
1577 }
1578 
1579 static HRESULT WINAPI d3drm_device_win_GetName(IDirect3DRMWinDevice *iface, DWORD *size, char *name)
1580 {
1581     struct d3drm_device *device = impl_from_IDirect3DRMWinDevice(iface);
1582 
1583     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
1584 
1585     return d3drm_device3_GetName(&device->IDirect3DRMDevice3_iface, size, name);
1586 }
1587 
1588 static HRESULT WINAPI d3drm_device_win_GetClassName(IDirect3DRMWinDevice *iface, DWORD *size, char *name)
1589 {
1590     struct d3drm_device *device = impl_from_IDirect3DRMWinDevice(iface);
1591 
1592     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
1593 
1594     return d3drm_device3_GetClassName(&device->IDirect3DRMDevice3_iface, size, name);
1595 }
1596 
1597 static HRESULT WINAPI d3drm_device_win_HandlePaint(IDirect3DRMWinDevice *iface, HDC dc)
1598 {
1599     FIXME("iface %p, dc %p stub!\n", iface, dc);
1600 
1601     return D3DRM_OK;
1602 }
1603 
1604 static HRESULT WINAPI d3drm_device_win_HandleActivate(IDirect3DRMWinDevice *iface, WORD wparam)
1605 {
1606     FIXME("iface %p, wparam %#x stub!\n", iface, wparam);
1607 
1608     return D3DRM_OK;
1609 }
1610 
1611 static const struct IDirect3DRMWinDeviceVtbl d3drm_device_win_vtbl =
1612 {
1613     d3drm_device_win_QueryInterface,
1614     d3drm_device_win_AddRef,
1615     d3drm_device_win_Release,
1616     d3drm_device_win_Clone,
1617     d3drm_device_win_AddDestroyCallback,
1618     d3drm_device_win_DeleteDestroyCallback,
1619     d3drm_device_win_SetAppData,
1620     d3drm_device_win_GetAppData,
1621     d3drm_device_win_SetName,
1622     d3drm_device_win_GetName,
1623     d3drm_device_win_GetClassName,
1624     d3drm_device_win_HandlePaint,
1625     d3drm_device_win_HandleActivate,
1626 };
1627 
1628 struct d3drm_device *unsafe_impl_from_IDirect3DRMDevice3(IDirect3DRMDevice3 *iface)
1629 {
1630     if (!iface)
1631         return NULL;
1632     assert(iface->lpVtbl == &d3drm_device3_vtbl);
1633 
1634     return impl_from_IDirect3DRMDevice3(iface);
1635 }
1636 
1637 HRESULT d3drm_device_create(struct d3drm_device **device, IDirect3DRM *d3drm)
1638 {
1639     static const char classname[] = "Device";
1640     struct d3drm_device *object;
1641 
1642     TRACE("device %p, d3drm %p.\n", device, d3drm);
1643 
1644     if (!(object = heap_alloc_zero(sizeof(*object))))
1645         return E_OUTOFMEMORY;
1646 
1647     object->IDirect3DRMDevice_iface.lpVtbl = &d3drm_device1_vtbl;
1648     object->IDirect3DRMDevice2_iface.lpVtbl = &d3drm_device2_vtbl;
1649     object->IDirect3DRMDevice3_iface.lpVtbl = &d3drm_device3_vtbl;
1650     object->IDirect3DRMWinDevice_iface.lpVtbl = &d3drm_device_win_vtbl;
1651     object->d3drm = d3drm;
1652     d3drm_object_init(&object->obj, classname);
1653 
1654     *device = object;
1655 
1656     return D3DRM_OK;
1657 }
1658