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