wined3d: Properly check if an attribute is used in TRACE_STRIDED.
[wine] / dlls / wined3d / clipper.c
1 /* IWineD3DClipper implementation
2  *
3  * Copyright 2000 (c) Marcus Meissner
4  * Copyright 2000 (c) TransGaming Technologies Inc.
5  * Copyright 2006 (c) Stefan Dösinger
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23 #include <stdio.h>
24 #ifdef HAVE_FLOAT_H
25 # include <float.h>
26 #endif
27 #include "wined3d_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
30
31 static HRESULT WINAPI IWineD3DClipperImpl_QueryInterface(IWineD3DClipper *iface, REFIID riid, void **Obj)
32 {
33     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
34
35     TRACE("(%p)->(%p,%p)\n", This, riid, Obj);
36     if (IsEqualGUID(&IID_IUnknown, riid)
37         || IsEqualGUID(&IID_IWineD3DClipper, riid))
38     {
39         *Obj = iface;
40         IWineD3DClipper_AddRef(iface);
41         return S_OK;
42     }
43     else
44     {
45         return E_NOINTERFACE;
46     }
47 }
48
49 static ULONG WINAPI IWineD3DClipperImpl_AddRef(IWineD3DClipper *iface )
50 {
51     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
52     ULONG ref = InterlockedIncrement(&This->ref);
53
54     TRACE("(%p)->() incrementing from %u.\n", This, ref - 1);
55
56     return ref;
57 }
58
59 static ULONG WINAPI IWineD3DClipperImpl_Release(IWineD3DClipper *iface)
60 {
61     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
62     ULONG ref = InterlockedDecrement(&This->ref);
63
64     TRACE("(%p)->() decrementing from %u.\n", This, ref + 1);
65
66     if (ref == 0)
67     {
68         HeapFree(GetProcessHeap(), 0, This);
69         return 0;
70     }
71     else return ref;
72 }
73
74 static HRESULT WINAPI IWineD3DClipperImpl_GetParent(IWineD3DClipper *iface, IUnknown **Parent)
75 {
76     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
77     TRACE("(%p)->(%p)\n", This, Parent);
78
79     *Parent = This->Parent;
80     IUnknown_AddRef(*Parent);
81     return WINED3D_OK;
82 }
83
84 static HRESULT WINAPI IWineD3DClipperImpl_SetHwnd(IWineD3DClipper *iface, DWORD Flags, HWND hWnd)
85 {
86     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
87
88     TRACE("(%p)->(0x%08x,%p)\n", This, Flags, hWnd);
89     if( Flags )
90     {
91         FIXME("Flags = 0x%08x, not supported.\n",Flags);
92         return WINED3DERR_INVALIDCALL;
93     }
94
95     This->hWnd = hWnd;
96     return WINED3D_OK;
97 }
98
99 static HRESULT WINAPI IWineD3DClipperImpl_GetClipList(IWineD3DClipper *iface, const RECT *Rect,
100         RGNDATA *ClipList, DWORD *Size)
101 {
102     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
103     TRACE("(%p,%p,%p,%p)\n", This, Rect, ClipList, Size);
104
105     if (This->hWnd)
106     {
107         HDC hDC = GetDCEx(This->hWnd, NULL, DCX_WINDOW);
108         if (hDC)
109         {
110             HRGN hRgn = CreateRectRgn(0,0,0,0);
111             if (GetRandomRgn(hDC, hRgn, SYSRGN))
112             {
113                 if (GetVersion() & 0x80000000)
114                 {
115                     /* map region to screen coordinates */
116                     POINT org;
117                     GetDCOrgEx( hDC, &org );
118                     OffsetRgn( hRgn, org.x, org.y );
119                 }
120                 if (Rect)
121                 {
122                     HRGN hRgnClip = CreateRectRgn(Rect->left, Rect->top,
123                         Rect->right, Rect->bottom);
124                     CombineRgn(hRgn, hRgn, hRgnClip, RGN_AND);
125                     DeleteObject(hRgnClip);
126                 }
127                 *Size = GetRegionData(hRgn, *Size, ClipList);
128             }
129             DeleteObject(hRgn);
130             ReleaseDC(This->hWnd, hDC);
131         }
132         return WINED3D_OK;
133     }
134     else
135     {
136         static int warned = 0;
137         if (warned++ < 10)
138             FIXME("(%p,%p,%p,%p),stub!\n",This,Rect,ClipList,Size);
139         if (Size) *Size=0;
140         return WINEDDERR_NOCLIPLIST;
141     }
142 }
143
144 static HRESULT WINAPI IWineD3DClipperImpl_SetClipList(IWineD3DClipper *iface, const RGNDATA *rgn, DWORD Flags)
145 {
146     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
147     static int warned = 0;
148
149     if (warned++ < 10 || rgn == NULL)
150         FIXME("(%p,%p,%d),stub!\n",This,rgn,Flags);
151     return WINED3D_OK;
152 }
153
154 static HRESULT WINAPI IWineD3DClipperImpl_GetHwnd(IWineD3DClipper *iface, HWND *hwnd)
155 {
156     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
157     TRACE("(%p)->(%p)\n", This, hwnd);
158
159     *hwnd = This->hWnd;
160     return WINED3D_OK;
161 }
162
163 static HRESULT WINAPI IWineD3DClipperImpl_IsClipListChanged(IWineD3DClipper *iface, BOOL *changed)
164 {
165     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
166     FIXME("(%p)->(%p),stub!\n",This,changed);
167
168     /* XXX What is safest? */
169     *changed = FALSE;
170
171     return WINED3D_OK;
172 }
173
174 static const IWineD3DClipperVtbl IWineD3DClipper_Vtbl =
175 {
176     IWineD3DClipperImpl_QueryInterface,
177     IWineD3DClipperImpl_AddRef,
178     IWineD3DClipperImpl_Release,
179     IWineD3DClipperImpl_GetParent,
180     IWineD3DClipperImpl_GetClipList,
181     IWineD3DClipperImpl_GetHwnd,
182     IWineD3DClipperImpl_IsClipListChanged,
183     IWineD3DClipperImpl_SetClipList,
184     IWineD3DClipperImpl_SetHwnd
185 };
186
187 IWineD3DClipper* WINAPI WineDirect3DCreateClipper(IUnknown *Parent)
188 {
189     IWineD3DClipperImpl *obj;
190
191     TRACE("Creating clipper, parent %p\n", Parent);
192     obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));
193     if(!obj)
194     {
195         ERR("Out of memory when trying to allocate a WineD3D Clipper\n");
196         return NULL;
197     }
198
199     obj->lpVtbl = &IWineD3DClipper_Vtbl;
200     obj->Parent = Parent;
201
202     IWineD3DClipper_AddRef((IWineD3DClipper *)obj);
203     return (IWineD3DClipper *) obj;
204 }