wined3d: Convert source files to utf-8.
[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, RECT *Rect, RGNDATA *ClipList, DWORD *Size)
100 {
101     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
102     TRACE("(%p,%p,%p,%p)\n", This, Rect, ClipList, Size);
103
104     if (This->hWnd)
105     {
106         HDC hDC = GetDCEx(This->hWnd, NULL, DCX_WINDOW);
107         if (hDC)
108         {
109             HRGN hRgn = CreateRectRgn(0,0,0,0);
110             if (GetRandomRgn(hDC, hRgn, SYSRGN))
111             {
112                 if (GetVersion() & 0x80000000)
113                 {
114                     /* map region to screen coordinates */
115                     POINT org;
116                     GetDCOrgEx( hDC, &org );
117                     OffsetRgn( hRgn, org.x, org.y );
118                 }
119                 if (Rect)
120                 {
121                     HRGN hRgnClip = CreateRectRgn(Rect->left, Rect->top,
122                         Rect->right, Rect->bottom);
123                     CombineRgn(hRgn, hRgn, hRgnClip, RGN_AND);
124                     DeleteObject(hRgnClip);
125                 }
126                 *Size = GetRegionData(hRgn, *Size, ClipList);
127             }
128             DeleteObject(hRgn);
129             ReleaseDC(This->hWnd, hDC);
130         }
131         return WINED3D_OK;
132     }
133     else
134     {
135         static int warned = 0;
136         if (warned++ < 10)
137             FIXME("(%p,%p,%p,%p),stub!\n",This,Rect,ClipList,Size);
138         if (Size) *Size=0;
139         return WINEDDERR_NOCLIPLIST;
140     }
141 }
142
143 static HRESULT WINAPI IWineD3DClipperImpl_SetClipList(IWineD3DClipper *iface, RGNDATA *rgn, DWORD Flags)
144 {
145     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
146     static int warned = 0;
147
148     if (warned++ < 10 || rgn == NULL)
149         FIXME("(%p,%p,%d),stub!\n",This,rgn,Flags);
150     return WINED3D_OK;
151 }
152
153 static HRESULT WINAPI IWineD3DClipperImpl_GetHwnd(IWineD3DClipper *iface, HWND *hwnd)
154 {
155     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
156     TRACE("(%p)->(%p)\n", This, hwnd);
157
158     *hwnd = This->hWnd;
159     return WINED3D_OK;
160 }
161
162 static HRESULT WINAPI IWineD3DClipperImpl_IsClipListChanged(IWineD3DClipper *iface, BOOL *changed)
163 {
164     IWineD3DClipperImpl *This = (IWineD3DClipperImpl *)iface;
165     FIXME("(%p)->(%p),stub!\n",This,changed);
166
167     /* XXX What is safest? */
168     *changed = FALSE;
169
170     return WINED3D_OK;
171 }
172
173 static const IWineD3DClipperVtbl IWineD3DClipper_Vtbl =
174 {
175     IWineD3DClipperImpl_QueryInterface,
176     IWineD3DClipperImpl_AddRef,
177     IWineD3DClipperImpl_Release,
178     IWineD3DClipperImpl_GetParent,
179     IWineD3DClipperImpl_GetClipList,
180     IWineD3DClipperImpl_GetHwnd,
181     IWineD3DClipperImpl_IsClipListChanged,
182     IWineD3DClipperImpl_SetClipList,
183     IWineD3DClipperImpl_SetHwnd
184 };
185
186 IWineD3DClipper* WINAPI WineDirect3DCreateClipper(IUnknown *Parent)
187 {
188     IWineD3DClipperImpl *obj;
189
190     TRACE("Creating clipper, parent %p\n", Parent);
191     obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));
192     if(!obj)
193     {
194         ERR("Out of memory when trying to allocate a WineD3D Clipper\n");
195         return NULL;
196     }
197
198     obj->lpVtbl = &IWineD3DClipper_Vtbl;
199     obj->Parent = Parent;
200
201     IWineD3DClipper_AddRef((IWineD3DClipper *)obj);
202     return (IWineD3DClipper *) obj;
203 }