Implement OpenGL overriding of surface's flip method.
[wine] / dlls / ddraw / d3ddevice / main.c
1 /* Direct3D Device
2  * Copyright (c) 1998 Lionel ULMER
3  *
4  * This file contains all the common stuff for D3D devices.
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "windef.h"
26 #include "winerror.h"
27 #include "wine/obj_base.h"
28 #include "ddraw.h"
29 #include "d3d.h"
30 #include "wine/debug.h"
31
32 #include "d3d_private.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
35
36 /*******************************************************************************
37  *                              IDirect3DDevice2
38  */
39
40 HRESULT WINAPI IDirect3DDevice2Impl_QueryInterface(
41     LPDIRECT3DDEVICE2 iface, REFIID riid, LPVOID* ppvObj
42 ) {
43     ICOM_THIS(IDirect3DDevice2Impl,iface);
44     FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
45     return S_OK;
46 }
47
48 ULONG WINAPI IDirect3DDevice2Impl_AddRef(LPDIRECT3DDEVICE2 iface)
49 {
50     ICOM_THIS(IDirect3DDevice2Impl,iface);
51     TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
52
53     return ++(This->ref);
54 }
55
56
57
58 ULONG WINAPI IDirect3DDevice2Impl_Release(LPDIRECT3DDEVICE2 iface)
59 {
60     ICOM_THIS(IDirect3DDevice2Impl,iface);
61     TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
62
63     if (!--(This->ref)) {
64         /* Release texture associated with the device */ 
65         if (This->current_texture)
66             IDirect3DTexture2Impl_Release((LPDIRECT3DTEXTURE2)This->current_texture);
67                   
68         HeapFree(GetProcessHeap(),0,This);
69         return 0;
70     }
71     return This->ref;
72 }
73
74
75 /*** IDirect3DDevice2 methods ***/
76 HRESULT WINAPI IDirect3DDevice2Impl_GetCaps(
77     LPDIRECT3DDEVICE2 iface, LPD3DDEVICEDESC lpdescsoft,
78     LPD3DDEVICEDESC lpdeschard
79 ) {
80     ICOM_THIS(IDirect3DDevice2Impl,iface);
81     FIXME("(%p)->(%p,%p), stub!\n", This, lpdescsoft, lpdeschard);
82     return DD_OK;
83 }
84
85
86
87 HRESULT WINAPI IDirect3DDevice2Impl_SwapTextureHandles(
88     LPDIRECT3DDEVICE2 iface,LPDIRECT3DTEXTURE2 lpD3DTex1,LPDIRECT3DTEXTURE2 lpD3DTex2
89 ) {
90     ICOM_THIS(IDirect3DDevice2Impl,iface);
91     IDirect3DTexture2Impl tmp;
92     TRACE("(%p)->(%p,%p)\n", This, lpD3DTex1, lpD3DTex2);
93
94     tmp = *(IDirect3DTexture2Impl*)lpD3DTex1;
95     *(IDirect3DTexture2Impl*)lpD3DTex1 = *(IDirect3DTexture2Impl*)lpD3DTex2;
96     *(IDirect3DTexture2Impl*)lpD3DTex2 = tmp;
97
98     return DD_OK;
99 }
100
101 HRESULT WINAPI IDirect3DDevice2Impl_GetStats(
102     LPDIRECT3DDEVICE2 iface, LPD3DSTATS lpstats)
103 {
104     ICOM_THIS(IDirect3DDevice2Impl,iface);
105     FIXME("(%p)->(%p): stub\n", This, lpstats);
106
107     return DD_OK;
108 }
109
110 HRESULT WINAPI IDirect3DDevice2Impl_AddViewport(
111     LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp
112 ) {
113     ICOM_THIS(IDirect3DDevice2Impl,iface);
114     IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
115     TRACE("(%p)->(%p)\n", This, ilpvp);
116
117     /* Adds this viewport to the viewport list */
118     ilpvp->next = This->viewport_list;
119     This->viewport_list = ilpvp;
120
121     return DD_OK;
122 }
123
124 HRESULT WINAPI IDirect3DDevice2Impl_DeleteViewport(
125     LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp)
126 {
127     ICOM_THIS(IDirect3DDevice2Impl,iface);
128     IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
129     IDirect3DViewport2Impl *cur, *prev;
130     TRACE("(%p)->(%p)\n", This, lpvp);
131
132     /* Finds this viewport in the list */
133     prev = NULL;
134     cur = This->viewport_list;
135     while ((cur != NULL) && (cur != ilpvp)) {
136         prev = cur;
137         cur = cur->next;
138     }
139     if (cur == NULL)
140         return DDERR_INVALIDOBJECT;
141
142     /* And remove it */
143     if (prev == NULL)
144         This->viewport_list = cur->next;
145     else
146         prev->next = cur->next;
147     return DD_OK;
148 }
149
150 HRESULT WINAPI IDirect3DDevice2Impl_NextViewport(
151     LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp,
152     LPDIRECT3DVIEWPORT2* lplpvp, DWORD dwFlags
153 ) {
154     ICOM_THIS(IDirect3DDevice2Impl,iface);
155     IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
156     IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
157     TRACE("(%p)->(%p,%p,%08lx)\n", This, lpvp, lpvp, dwFlags);
158
159     switch (dwFlags) {
160     case D3DNEXT_NEXT:
161         *ilplpvp = ilpvp->next;
162         break;
163     case D3DNEXT_HEAD:
164         *ilplpvp = This->viewport_list;
165         break;
166     case D3DNEXT_TAIL:
167         ilpvp = This->viewport_list;
168         while (ilpvp->next != NULL)
169             ilpvp = ilpvp->next;
170         *ilplpvp = ilpvp;
171         break;
172     default:
173         return DDERR_INVALIDPARAMS;
174     }
175     return DD_OK;
176 }
177
178 HRESULT WINAPI IDirect3DDevice2Impl_EnumTextureFormats(
179     LPDIRECT3DDEVICE2 iface, LPD3DENUMTEXTUREFORMATSCALLBACK cb, LPVOID context
180 ) {
181     ICOM_THIS(IDirect3DDevice2Impl,iface);
182     FIXME("(%p)->(%p,%p), stub!\n", This, cb, context);
183
184     return DD_OK; /* no texture formats in stub implementation */
185 }
186
187
188
189 HRESULT WINAPI IDirect3DDevice2Impl_BeginScene(LPDIRECT3DDEVICE2 iface)
190 {
191     ICOM_THIS(IDirect3DDevice2Impl,iface);
192
193     FIXME("(%p)->(), stub!\n", This);
194
195     /* Here, we should get the DDraw surface and 'copy it' to the
196      OpenGL surface.... */
197     return DD_OK;
198 }
199
200 HRESULT WINAPI IDirect3DDevice2Impl_EndScene(LPDIRECT3DDEVICE2 iface)
201 {
202     ICOM_THIS(IDirect3DDevice2Impl,iface);
203     FIXME("(%p)->(): stub\n", This);
204     return DD_OK;
205 }
206
207 HRESULT WINAPI IDirect3DDevice2Impl_GetDirect3D(
208     LPDIRECT3DDEVICE2 iface, LPDIRECT3D2 *lpd3d2
209 ) {
210     ICOM_THIS(IDirect3DDevice2Impl,iface);
211     TRACE("(%p)->(%p)\n", This, lpd3d2);
212     *lpd3d2 = (LPDIRECT3D2)This->d3d;
213     return DD_OK;
214 }
215
216 /*** DrawPrimitive API ***/
217 HRESULT WINAPI IDirect3DDevice2Impl_SetCurrentViewport(
218     LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 lpvp
219 ) {
220     ICOM_THIS(IDirect3DDevice2Impl,iface);
221     IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
222     TRACE("(%p)->(%p)\n", This, ilpvp);
223
224     /* Should check if the viewport was added or not */
225
226     /* Set this viewport as the current viewport */
227     This->current_viewport = ilpvp;
228
229     /* Activate this viewport */
230     ilpvp->device.active_device2 = This;
231     ilpvp->activate(ilpvp);
232
233     return DD_OK;
234 }
235
236
237
238 HRESULT WINAPI IDirect3DDevice2Impl_GetCurrentViewport(
239     LPDIRECT3DDEVICE2 iface, LPDIRECT3DVIEWPORT2 *lplpvp
240 ) {
241     ICOM_THIS(IDirect3DDevice2Impl,iface);
242     FIXME("(%p)->(%p): stub\n", This, lplpvp);
243
244     /* Returns the current viewport */
245     *lplpvp = (LPDIRECT3DVIEWPORT2)This->current_viewport;
246
247     return DD_OK;
248 }
249
250 HRESULT WINAPI IDirect3DDevice2Impl_SetRenderTarget(
251     LPDIRECT3DDEVICE2 iface, LPDIRECTDRAWSURFACE lpdds, DWORD dwFlags
252 ) {
253     ICOM_THIS(IDirect3DDevice2Impl,iface);
254     FIXME("(%p)->(%p,%08lx): stub\n", This, lpdds, dwFlags);
255
256     return DD_OK;
257 }
258
259 HRESULT WINAPI IDirect3DDevice2Impl_GetRenderTarget(
260     LPDIRECT3DDEVICE2 iface, LPDIRECTDRAWSURFACE *lplpdds
261 ) {
262     ICOM_THIS(IDirect3DDevice2Impl,iface);
263     TRACE("(%p)->(%p)\n", This, lplpdds);
264
265     /* Returns the current rendering target (the surface on wich we render) */
266     *lplpdds = (LPDIRECTDRAWSURFACE)This->surface;
267
268     return DD_OK;
269 }
270
271 HRESULT WINAPI IDirect3DDevice2Impl_Begin(
272     LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
273     DWORD dwFlags
274 ) {
275     ICOM_THIS(IDirect3DDevice2Impl,iface);
276     FIXME("(%p)->(%d,%d,%08lx): stub\n", This, d3dp, d3dv, dwFlags);
277
278     return DD_OK;
279 }
280
281 HRESULT WINAPI IDirect3DDevice2Impl_BeginIndexed(
282     LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
283     LPVOID lpvert, DWORD numvert, DWORD dwFlags
284 ) {
285     ICOM_THIS(IDirect3DDevice2Impl,iface);
286     FIXME("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvert, numvert, dwFlags);
287
288     return DD_OK;
289 }
290
291 HRESULT WINAPI IDirect3DDevice2Impl_Vertex(
292     LPDIRECT3DDEVICE2 iface,LPVOID lpvert
293 ) {
294     ICOM_THIS(IDirect3DDevice2Impl,iface);
295     FIXME("(%p)->(%p): stub\n", This, lpvert);
296
297     return DD_OK;
298 }
299
300 HRESULT WINAPI IDirect3DDevice2Impl_Index(LPDIRECT3DDEVICE2 iface, WORD index) {
301     ICOM_THIS(IDirect3DDevice2Impl,iface);
302     FIXME("(%p)->(%d): stub\n", This, index);
303
304     return DD_OK;
305 }
306
307
308
309 HRESULT WINAPI IDirect3DDevice2Impl_End(LPDIRECT3DDEVICE2 iface,DWORD dwFlags) {
310     ICOM_THIS(IDirect3DDevice2Impl,iface);
311     FIXME("(%p)->(%08lx): stub\n", This, dwFlags);
312
313     return DD_OK;
314 }
315
316 HRESULT WINAPI IDirect3DDevice2Impl_GetRenderState(
317     LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE d3drs, LPDWORD lprstate
318 ) {
319     ICOM_THIS(IDirect3DDevice2Impl,iface);
320     FIXME("(%p)->(%d,%p): stub\n", This, d3drs, lprstate);
321
322     return DD_OK;
323 }
324
325 HRESULT WINAPI IDirect3DDevice2Impl_SetRenderState(
326     LPDIRECT3DDEVICE2 iface, D3DRENDERSTATETYPE dwRenderStateType,
327     DWORD dwRenderState
328 ) {
329     ICOM_THIS(IDirect3DDevice2Impl,iface);
330
331     FIXME("(%p)->(%d,%ld)\n", This, dwRenderStateType, dwRenderState);
332
333     return DD_OK;
334 }
335
336 HRESULT WINAPI IDirect3DDevice2Impl_GetLightState(
337     LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE d3dls, LPDWORD lplstate
338 ) {
339     ICOM_THIS(IDirect3DDevice2Impl,iface);
340     FIXME("(%p)->(%d,%p): stub\n", This, d3dls, lplstate);
341
342     return DD_OK;
343 }
344
345
346
347 HRESULT WINAPI IDirect3DDevice2Impl_SetLightState(
348     LPDIRECT3DDEVICE2 iface, D3DLIGHTSTATETYPE dwLightStateType,
349     DWORD dwLightState
350 ) {
351     ICOM_THIS(IDirect3DDevice2Impl,iface);
352     FIXME("(%p)->(%d,%08lx): stub\n", This, dwLightStateType, dwLightState);
353     return DD_OK;
354 }
355
356 HRESULT WINAPI IDirect3DDevice2Impl_SetTransform(
357     LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
358 ) {
359     ICOM_THIS(IDirect3DDevice2Impl,iface);
360     FIXME("(%p)->(%d,%p),stub!\n",This,d3dts,lpmatrix);
361     return DD_OK;
362 }
363
364
365
366 HRESULT WINAPI IDirect3DDevice2Impl_GetTransform(
367     LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
368 ) {
369     ICOM_THIS(IDirect3DDevice2Impl,iface);
370     FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
371
372     return DD_OK;
373 }
374
375
376
377 HRESULT WINAPI IDirect3DDevice2Impl_MultiplyTransform(
378     LPDIRECT3DDEVICE2 iface, D3DTRANSFORMSTATETYPE d3dts, LPD3DMATRIX lpmatrix
379 ) {
380     ICOM_THIS(IDirect3DDevice2Impl,iface);
381     FIXME("(%p)->(%d,%p): stub\n", This, d3dts, lpmatrix);
382
383     return DD_OK;
384 }
385
386 HRESULT WINAPI IDirect3DDevice2Impl_DrawPrimitive(
387     LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
388     LPVOID lpvertex, DWORD vertcount, DWORD dwFlags
389 ) {
390   ICOM_THIS(IDirect3DDevice2Impl,iface);
391
392   FIXME("(%p)->(%d,%d,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, dwFlags);
393
394   return D3D_OK;
395 }
396
397 HRESULT WINAPI IDirect3DDevice2Impl_DrawIndexedPrimitive(
398     LPDIRECT3DDEVICE2 iface, D3DPRIMITIVETYPE d3dp, D3DVERTEXTYPE d3dv,
399     LPVOID lpvertex, DWORD vertcount, LPWORD lpindexes, DWORD indexcount,
400     DWORD dwFlags
401 ) {
402     ICOM_THIS(IDirect3DDevice2Impl,iface);
403     FIXME("(%p)->(%d,%d,%p,%ld,%p,%ld,%08lx): stub\n", This, d3dp, d3dv, lpvertex, vertcount, lpindexes, indexcount, dwFlags);
404     return D3D_OK;
405 }
406
407 HRESULT WINAPI IDirect3DDevice2Impl_SetClipStatus(
408     LPDIRECT3DDEVICE2 iface, LPD3DCLIPSTATUS lpcs
409 ) {
410     ICOM_THIS(IDirect3DDevice2Impl,iface);
411     FIXME("(%p)->(%p): stub\n", This, lpcs);
412
413     return DD_OK;
414 }
415
416 HRESULT WINAPI IDirect3DDevice2Impl_GetClipStatus(
417     LPDIRECT3DDEVICE2 iface, LPD3DCLIPSTATUS lpcs
418 ) {
419     ICOM_THIS(IDirect3DDevice2Impl,iface);
420     FIXME("(%p)->(%p): stub\n", This, lpcs);
421
422     return DD_OK;
423 }
424
425 /*******************************************************************************
426  *                              Direct3DDevice
427  */
428 HRESULT WINAPI IDirect3DDeviceImpl_QueryInterface(
429     LPDIRECT3DDEVICE iface, REFIID riid, LPVOID* ppvObj
430 ) {
431     ICOM_THIS(IDirect3DDeviceImpl,iface);
432     FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
433     return S_OK;
434 }
435
436 ULONG WINAPI IDirect3DDeviceImpl_AddRef(LPDIRECT3DDEVICE iface)
437 {
438     ICOM_THIS(IDirect3DDeviceImpl,iface);
439     TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
440
441     return ++(This->ref);
442 }
443
444 ULONG WINAPI IDirect3DDeviceImpl_Release(LPDIRECT3DDEVICE iface)
445 {
446     ICOM_THIS(IDirect3DDeviceImpl,iface);
447     TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
448
449     if (!--(This->ref)) {
450         /* Release texture associated with the device */ 
451         if (This->current_texture)
452             IDirect3DTexture2Impl_Release((LPDIRECT3DTEXTURE2)This->current_texture);
453             
454         HeapFree(GetProcessHeap(),0,This);
455         return 0;
456     }
457     return This->ref;
458 }
459
460 HRESULT WINAPI IDirect3DDeviceImpl_Initialize(
461     LPDIRECT3DDEVICE iface, LPDIRECT3D lpd3d, LPGUID lpGUID,
462     LPD3DDEVICEDESC lpd3ddvdesc
463 ) {
464     ICOM_THIS(IDirect3DDeviceImpl,iface);
465     FIXME("(%p)->(%p,%p,%p): stub\n", This, lpd3d,lpGUID, lpd3ddvdesc);
466
467     return DDERR_ALREADYINITIALIZED;
468 }
469
470
471 HRESULT WINAPI IDirect3DDeviceImpl_GetCaps(
472     LPDIRECT3DDEVICE iface, LPD3DDEVICEDESC lpD3DHWDevDesc,
473     LPD3DDEVICEDESC lpD3DSWDevDesc
474 ) {
475     ICOM_THIS(IDirect3DDeviceImpl,iface);
476     FIXME("(%p)->(%p,%p): stub\n", This, lpD3DHWDevDesc, lpD3DSWDevDesc);
477
478     return DD_OK;
479 }
480
481
482 HRESULT WINAPI IDirect3DDeviceImpl_SwapTextureHandles(
483     LPDIRECT3DDEVICE iface, LPDIRECT3DTEXTURE lpD3DTex1,
484     LPDIRECT3DTEXTURE lpD3DTex2
485 ) {
486     ICOM_THIS(IDirect3DDeviceImpl,iface);
487     IDirect3DTexture2Impl tmp;
488     TRACE("(%p)->(%p,%p)\n", This, lpD3DTex1, lpD3DTex2);
489
490     tmp = *(IDirect3DTexture2Impl*)lpD3DTex1;
491     *(IDirect3DTexture2Impl*)lpD3DTex1 = *(IDirect3DTexture2Impl*)lpD3DTex2;
492     *(IDirect3DTexture2Impl*)lpD3DTex2 = tmp;
493
494     return DD_OK;
495 }
496
497 HRESULT WINAPI IDirect3DDeviceImpl_CreateExecuteBuffer(
498     LPDIRECT3DDEVICE iface, LPD3DEXECUTEBUFFERDESC lpDesc,
499     LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer, IUnknown *pUnkOuter
500 ) {
501     ICOM_THIS(IDirect3DDeviceImpl,iface);
502     FIXME("(%p)->(%p,%p,%p): stub\n", This, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter);
503     return DD_OK;
504 }
505
506 HRESULT WINAPI IDirect3DDeviceImpl_GetStats(
507     LPDIRECT3DDEVICE iface, LPD3DSTATS lpD3DStats
508 ) {
509     ICOM_THIS(IDirect3DDeviceImpl,iface);
510     FIXME("(%p)->(%p): stub\n", This, lpD3DStats);
511
512     return DD_OK;
513 }
514
515
516 HRESULT WINAPI IDirect3DDeviceImpl_Execute(
517     LPDIRECT3DDEVICE iface, LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
518     LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags
519 ) {
520     ICOM_THIS(IDirect3DDeviceImpl,iface);
521     TRACE("(%p)->(%p,%p,%08ld)\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags);
522
523     /* Put this as the default context */
524
525     /* Execute... */
526     ((IDirect3DExecuteBufferImpl*)lpDirect3DExecuteBuffer)->execute(lpDirect3DExecuteBuffer, iface, (IDirect3DViewport*)lpDirect3DViewport);
527
528     return DD_OK;
529 }
530
531 HRESULT WINAPI IDirect3DDeviceImpl_AddViewport(
532     LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp
533 ) {
534     ICOM_THIS(IDirect3DDeviceImpl,iface);
535     IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
536     TRACE("(%p)->(%p)\n", This, ilpvp);
537
538     /* Adds this viewport to the viewport list */
539     ilpvp->next = This->viewport_list;
540     This->viewport_list = ilpvp;
541
542     return DD_OK;
543 }
544
545
546
547 HRESULT WINAPI IDirect3DDeviceImpl_DeleteViewport(
548     LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp
549 ) {
550     ICOM_THIS(IDirect3DDeviceImpl,iface);
551     IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
552     IDirect3DViewport2Impl *cur, *prev;
553     TRACE("(%p)->(%p)\n", This, lpvp);
554
555     /* Finds this viewport in the list */
556     prev = NULL;
557     cur = This->viewport_list;
558     while ((cur != NULL) && (cur != ilpvp)) {
559         prev = cur;
560         cur = cur->next;
561     }
562     if (cur == NULL)
563         return DDERR_INVALIDOBJECT;
564
565     /* And remove it */
566     if (prev == NULL)
567         This->viewport_list = cur->next;
568     else
569         prev->next = cur->next;
570     return DD_OK;
571 }
572
573 HRESULT WINAPI IDirect3DDeviceImpl_NextViewport(
574     LPDIRECT3DDEVICE iface, LPDIRECT3DVIEWPORT lpvp,
575     LPDIRECT3DVIEWPORT* lplpvp, DWORD dwFlags
576 ) {
577     ICOM_THIS(IDirect3DDeviceImpl,iface);
578     IDirect3DViewport2Impl* ilpvp=(IDirect3DViewport2Impl*)lpvp;
579     IDirect3DViewport2Impl** ilplpvp=(IDirect3DViewport2Impl**)lplpvp;
580     TRACE("(%p)->(%p,%p,%08lx)\n", This, ilpvp, ilplpvp, dwFlags);
581
582     switch (dwFlags) {
583     case D3DNEXT_NEXT:
584         *ilplpvp = ilpvp->next;
585         break;
586     case D3DNEXT_HEAD:
587         *ilplpvp = This->viewport_list;
588         break;
589     case D3DNEXT_TAIL:
590         ilpvp = This->viewport_list;
591         while (ilpvp->next != NULL)
592             ilpvp = ilpvp->next;
593         *ilplpvp = ilpvp;
594         break;
595     default:
596         return DDERR_INVALIDPARAMS;
597     }
598     return DD_OK;
599 }
600
601 HRESULT WINAPI IDirect3DDeviceImpl_Pick(
602     LPDIRECT3DDEVICE iface, LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer,
603     LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags, LPD3DRECT lpRect
604 ) {
605     ICOM_THIS(IDirect3DDeviceImpl,iface);
606     TRACE("(%p)->(%p,%p,%08lx,%p): stub\n", This, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags, lpRect);
607     return DD_OK;
608 }
609
610 HRESULT WINAPI IDirect3DDeviceImpl_GetPickRecords(
611     LPDIRECT3DDEVICE iface, LPDWORD lpCount, LPD3DPICKRECORD lpD3DPickRec
612 ) {
613     ICOM_THIS(IDirect3DDeviceImpl,iface);
614     FIXME("(%p)->(%p,%p): stub\n", This, lpCount, lpD3DPickRec);
615
616     return DD_OK;
617 }
618
619
620 HRESULT WINAPI IDirect3DDeviceImpl_EnumTextureFormats(
621     LPDIRECT3DDEVICE iface,LPD3DENUMTEXTUREFORMATSCALLBACK lpd3dEnumTextureProc,
622     LPVOID lpArg
623 ) {
624     ICOM_THIS(IDirect3DDeviceImpl,iface);
625     FIXME("(%p)->(%p,%p): stub\n", This, lpd3dEnumTextureProc, lpArg);
626     return D3D_OK;
627 }
628
629
630 HRESULT WINAPI IDirect3DDeviceImpl_CreateMatrix(
631     LPDIRECT3DDEVICE iface, LPD3DMATRIXHANDLE lpD3DMatHandle
632 )
633 {
634     ICOM_THIS(IDirect3DDeviceImpl,iface);
635     TRACE("(%p)->(%p)\n", This, lpD3DMatHandle);
636
637     *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(D3DMATRIX));
638
639     return DD_OK;
640 }
641
642
643 HRESULT WINAPI IDirect3DDeviceImpl_SetMatrix(
644     LPDIRECT3DDEVICE iface, D3DMATRIXHANDLE d3dMatHandle,
645     const LPD3DMATRIX lpD3DMatrix)
646 {
647     ICOM_THIS(IDirect3DDeviceImpl,iface);
648     TRACE("(%p)->(%08lx,%p)\n", This, d3dMatHandle, lpD3DMatrix);
649
650     dump_mat(lpD3DMatrix);
651     *((D3DMATRIX *) d3dMatHandle) = *lpD3DMatrix;
652     return DD_OK;
653 }
654
655
656 HRESULT WINAPI IDirect3DDeviceImpl_GetMatrix(
657     LPDIRECT3DDEVICE iface,D3DMATRIXHANDLE D3DMatHandle,LPD3DMATRIX lpD3DMatrix
658 ) {
659     ICOM_THIS(IDirect3DDeviceImpl,iface);
660     TRACE("(%p)->(%08lx,%p)\n", This, D3DMatHandle, lpD3DMatrix);
661
662     *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle);
663
664     return DD_OK;
665 }
666
667
668 HRESULT WINAPI IDirect3DDeviceImpl_DeleteMatrix(
669     LPDIRECT3DDEVICE iface, D3DMATRIXHANDLE d3dMatHandle
670 ) {
671     ICOM_THIS(IDirect3DDeviceImpl,iface);
672     TRACE("(%p)->(%08lx)\n", This, d3dMatHandle);
673     HeapFree(GetProcessHeap(),0, (void *) d3dMatHandle);
674     return DD_OK;
675 }
676
677
678 HRESULT WINAPI IDirect3DDeviceImpl_BeginScene(LPDIRECT3DDEVICE iface)
679 {
680     ICOM_THIS(IDirect3DDeviceImpl,iface);
681     FIXME("(%p)->(): stub\n", This);
682     return DD_OK;
683 }
684
685 /* This is for the moment copy-pasted from IDirect3DDevice2...
686    Will make a common function ... */
687 HRESULT WINAPI IDirect3DDeviceImpl_EndScene(LPDIRECT3DDEVICE iface)
688 {
689     ICOM_THIS(IDirect3DDeviceImpl,iface);
690     FIXME("(%p)->(): stub\n", This);
691     return DD_OK;
692 }
693
694 HRESULT WINAPI IDirect3DDeviceImpl_GetDirect3D(
695     LPDIRECT3DDEVICE iface, LPDIRECT3D *lpDirect3D
696 ) {
697     ICOM_THIS(IDirect3DDeviceImpl,iface);
698     FIXME("(%p)->(%p): stub\n", This, lpDirect3D);
699
700     return DD_OK;
701 }
702
703 /*******************************************************************************
704  *                              Direct3DDevice VTable
705  */
706 static ICOM_VTABLE(IDirect3DDevice) WINE_UNUSED d3d_d3ddevice_vtbl =
707 {
708   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
709   IDirect3DDeviceImpl_QueryInterface,
710   IDirect3DDeviceImpl_AddRef,
711   IDirect3DDeviceImpl_Release,
712   IDirect3DDeviceImpl_Initialize,
713   IDirect3DDeviceImpl_GetCaps,
714   IDirect3DDeviceImpl_SwapTextureHandles,
715   IDirect3DDeviceImpl_CreateExecuteBuffer,
716   IDirect3DDeviceImpl_GetStats,
717   IDirect3DDeviceImpl_Execute,
718   IDirect3DDeviceImpl_AddViewport,
719   IDirect3DDeviceImpl_DeleteViewport,
720   IDirect3DDeviceImpl_NextViewport,
721   IDirect3DDeviceImpl_Pick,
722   IDirect3DDeviceImpl_GetPickRecords,
723   IDirect3DDeviceImpl_EnumTextureFormats,
724   IDirect3DDeviceImpl_CreateMatrix,
725   IDirect3DDeviceImpl_SetMatrix,
726   IDirect3DDeviceImpl_GetMatrix,
727   IDirect3DDeviceImpl_DeleteMatrix,
728   IDirect3DDeviceImpl_BeginScene,
729   IDirect3DDeviceImpl_EndScene,
730   IDirect3DDeviceImpl_GetDirect3D,
731 };