Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 1 | /* DirectDrawClipper implementation |
| 2 | * |
| 3 | * Copyright 2000 Marcus Meissner |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 4 | * Copyright 2000 TransGaming Technologies Inc. |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 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 |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 19 | */ |
| 20 | |
| 21 | #include "config.h" |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 22 | |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 23 | #include <stdarg.h> |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 24 | #include <stdlib.h> |
James Juran | f4d5fef | 2001-01-26 20:43:40 +0000 | [diff] [blame] | 25 | #include <string.h> |
Patrik Stridvall | 33929be | 2001-07-18 21:04:23 +0000 | [diff] [blame] | 26 | |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 27 | #include "windef.h" |
| 28 | #include "winbase.h" |
| 29 | #include "wingdi.h" |
Patrik Stridvall | 33929be | 2001-07-18 21:04:23 +0000 | [diff] [blame] | 30 | #include "ddraw.h" |
James Juran | f4d5fef | 2001-01-26 20:43:40 +0000 | [diff] [blame] | 31 | #include "winerror.h" |
Patrik Stridvall | 33929be | 2001-07-18 21:04:23 +0000 | [diff] [blame] | 32 | |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 33 | #include "ddraw_private.h" |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 34 | #include "dclipper/main.h" |
| 35 | #include "ddraw/main.h" |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 36 | |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 37 | #include "wine/debug.h" |
Patrik Stridvall | 33929be | 2001-07-18 21:04:23 +0000 | [diff] [blame] | 38 | |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 39 | WINE_DEFAULT_DEBUG_CHANNEL(ddraw); |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 40 | |
| 41 | /****************************************************************************** |
Patrik Stridvall | d9b9c4c | 2001-06-11 20:14:43 +0000 | [diff] [blame] | 42 | * DirectDrawCreateClipper (DDRAW.@) |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 43 | */ |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 44 | |
Alexandre Julliard | 48c4bb3 | 2004-08-12 23:00:51 +0000 | [diff] [blame] | 45 | static IDirectDrawClipperVtbl DDRAW_Clipper_VTable; |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 46 | |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 47 | HRESULT WINAPI DirectDrawCreateClipper( |
| 48 | DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter |
| 49 | ) { |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 50 | IDirectDrawClipperImpl* This; |
| 51 | TRACE("(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter); |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 52 | |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 53 | if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION; |
| 54 | |
| 55 | This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, |
| 56 | sizeof(IDirectDrawClipperImpl)); |
| 57 | if (This == NULL) return E_OUTOFMEMORY; |
| 58 | |
| 59 | ICOM_INIT_INTERFACE(This, IDirectDrawClipper, DDRAW_Clipper_VTable); |
| 60 | This->ref = 1; |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 61 | This->hWnd = 0; |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 62 | This->ddraw_owner = NULL; |
| 63 | |
| 64 | *lplpDDClipper = ICOM_INTERFACE(This, IDirectDrawClipper); |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 65 | return DD_OK; |
| 66 | } |
| 67 | |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 68 | /* This is the classfactory implementation. */ |
| 69 | HRESULT DDRAW_CreateDirectDrawClipper(IUnknown* pUnkOuter, REFIID riid, |
| 70 | LPVOID* ppObj) |
| 71 | { |
| 72 | HRESULT hr; |
| 73 | LPDIRECTDRAWCLIPPER pClip; |
| 74 | |
| 75 | hr = DirectDrawCreateClipper(0, &pClip, pUnkOuter); |
| 76 | if (FAILED(hr)) return hr; |
| 77 | |
| 78 | hr = IDirectDrawClipper_QueryInterface(pClip, riid, ppObj); |
| 79 | IDirectDrawClipper_Release(pClip); |
| 80 | return hr; |
| 81 | } |
| 82 | |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 83 | /****************************************************************************** |
| 84 | * IDirectDrawClipper |
| 85 | */ |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 86 | HRESULT WINAPI Main_DirectDrawClipper_SetHwnd( |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 87 | LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd |
| 88 | ) { |
Alexandre Julliard | f5f7a18 | 2004-09-08 01:50:37 +0000 | [diff] [blame] | 89 | IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 90 | |
| 91 | TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd); |
| 92 | if( dwFlags ) { |
| 93 | FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags); |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 94 | return DDERR_INVALIDPARAMS; |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 95 | } |
| 96 | |
| 97 | This->hWnd = hWnd; |
| 98 | return DD_OK; |
| 99 | } |
| 100 | |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 101 | static void Main_DirectDrawClipper_Destroy(IDirectDrawClipperImpl* This) |
| 102 | { |
| 103 | if (This->ddraw_owner != NULL) |
| 104 | Main_DirectDraw_RemoveClipper(This->ddraw_owner, This); |
| 105 | |
| 106 | HeapFree(GetProcessHeap(), 0 ,This); |
| 107 | } |
| 108 | |
| 109 | void Main_DirectDrawClipper_ForceDestroy(IDirectDrawClipperImpl* This) |
| 110 | { |
| 111 | WARN("deleting clipper %p with refcnt %lu\n", This, This->ref); |
| 112 | Main_DirectDrawClipper_Destroy(This); |
| 113 | } |
| 114 | |
| 115 | ULONG WINAPI Main_DirectDrawClipper_Release(LPDIRECTDRAWCLIPPER iface) { |
Alexandre Julliard | f5f7a18 | 2004-09-08 01:50:37 +0000 | [diff] [blame] | 116 | IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; |
Paul Vriens | 202b340 | 2005-01-09 17:29:21 +0000 | [diff] [blame] | 117 | ULONG ref = InterlockedDecrement(&This->ref); |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 118 | |
Paul Vriens | 202b340 | 2005-01-09 17:29:21 +0000 | [diff] [blame] | 119 | TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1); |
| 120 | |
| 121 | if (ref == 0) |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 122 | { |
| 123 | Main_DirectDrawClipper_Destroy(This); |
| 124 | return 0; |
| 125 | } |
Paul Vriens | 202b340 | 2005-01-09 17:29:21 +0000 | [diff] [blame] | 126 | else return ref; |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 127 | } |
| 128 | |
Tobias Burnus | 998a827 | 2004-08-23 18:50:14 +0000 | [diff] [blame] | 129 | /*********************************************************************** |
| 130 | * IDirectDrawClipper::GetClipList |
| 131 | * |
| 132 | * Retrieve a copy of the clip list |
| 133 | * |
| 134 | * PARAMS |
| 135 | * lpRect Rectangle to be used to clip the clip list or NULL for the |
| 136 | * entire clip list |
| 137 | * lpClipList structure for the resulting copy of the clip list. |
| 138 | If NULL, fills lpdwSize up to the number of bytes necessary to hold |
| 139 | the entire clip. |
| 140 | * lpdwSize Size of resulting clip list; size of the buffer at lpClipList |
| 141 | or, if lpClipList is NULL, receives the required size of the buffer |
| 142 | in bytes |
| 143 | * RETURNS |
| 144 | * Either DD_OK or DDERR_* |
| 145 | */ |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 146 | HRESULT WINAPI Main_DirectDrawClipper_GetClipList( |
Tobias Burnus | 998a827 | 2004-08-23 18:50:14 +0000 | [diff] [blame] | 147 | LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList, |
Robert Shearman | 9e2e594 | 2004-08-24 20:14:26 +0000 | [diff] [blame] | 148 | LPDWORD lpdwSize) |
| 149 | { |
Alexandre Julliard | f5f7a18 | 2004-09-08 01:50:37 +0000 | [diff] [blame] | 150 | IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; |
Robert Shearman | 9e2e594 | 2004-08-24 20:14:26 +0000 | [diff] [blame] | 151 | |
| 152 | TRACE("(%p,%p,%p,%p)\n", This, lpRect, lpClipList, lpdwSize); |
| 153 | |
| 154 | if (This->hWnd) |
| 155 | { |
| 156 | HDC hDC = GetDCEx(This->hWnd, NULL, DCX_WINDOW); |
| 157 | if (hDC) |
| 158 | { |
| 159 | HRGN hRgn = CreateRectRgn(0,0,0,0); |
| 160 | if (GetRandomRgn(hDC, hRgn, SYSRGN)) |
| 161 | { |
| 162 | if (lpRect) |
| 163 | { |
| 164 | HRGN hRgnClip = CreateRectRgn(lpRect->left, lpRect->top, |
| 165 | lpRect->right, lpRect->bottom); |
| 166 | CombineRgn(hRgn, hRgn, hRgnClip, RGN_AND); |
| 167 | DeleteObject(hRgnClip); |
| 168 | } |
| 169 | *lpdwSize = GetRegionData(hRgn, *lpdwSize, lpClipList); |
| 170 | } |
| 171 | DeleteObject(hRgn); |
| 172 | ReleaseDC(This->hWnd, hDC); |
| 173 | } |
| 174 | return DD_OK; |
| 175 | } |
| 176 | else |
| 177 | { |
| 178 | static int warned = 0; |
| 179 | if (warned++ < 10) |
| 180 | FIXME("(%p,%p,%p,%p),stub!\n",This,lpRect,lpClipList,lpdwSize); |
| 181 | if (lpdwSize) *lpdwSize=0; |
| 182 | return DDERR_NOCLIPLIST; |
| 183 | } |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 184 | } |
| 185 | |
Tobias Burnus | 998a827 | 2004-08-23 18:50:14 +0000 | [diff] [blame] | 186 | /*********************************************************************** |
| 187 | * IDirectDrawClipper::SetClipList |
| 188 | * |
| 189 | * Sets or deletes (if lprgn is NULL) the clip list |
| 190 | * |
| 191 | * PARAMS |
| 192 | * lprgn Pointer to a LRGNDATA structure or NULL |
| 193 | * dwFlags not used, must be 0 |
| 194 | * RETURNS |
| 195 | * Either DD_OK or DDERR_* |
| 196 | */ |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 197 | HRESULT WINAPI Main_DirectDrawClipper_SetClipList( |
Tobias Burnus | 998a827 | 2004-08-23 18:50:14 +0000 | [diff] [blame] | 198 | LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 199 | ) { |
Alexandre Julliard | f5f7a18 | 2004-09-08 01:50:37 +0000 | [diff] [blame] | 200 | IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; |
Tobias Burnus | 998a827 | 2004-08-23 18:50:14 +0000 | [diff] [blame] | 201 | static int warned = 0; |
| 202 | if (warned++ < 10 || lprgn == NULL) |
| 203 | FIXME("(%p,%p,%ld),stub!\n",This,lprgn,dwFlag); |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 204 | return DD_OK; |
| 205 | } |
| 206 | |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 207 | HRESULT WINAPI Main_DirectDrawClipper_QueryInterface( |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 208 | LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj |
| 209 | ) { |
Alexandre Julliard | f5f7a18 | 2004-09-08 01:50:37 +0000 | [diff] [blame] | 210 | IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 211 | |
| 212 | if (IsEqualGUID(&IID_IUnknown, riid) |
| 213 | || IsEqualGUID(&IID_IDirectDrawClipper, riid)) |
| 214 | { |
| 215 | *ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper); |
Paul Vriens | 202b340 | 2005-01-09 17:29:21 +0000 | [diff] [blame] | 216 | InterlockedIncrement(&This->ref); |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 217 | return S_OK; |
| 218 | } |
| 219 | else |
| 220 | { |
| 221 | return E_NOINTERFACE; |
| 222 | } |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 223 | } |
| 224 | |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 225 | ULONG WINAPI Main_DirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER iface ) |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 226 | { |
Alexandre Julliard | f5f7a18 | 2004-09-08 01:50:37 +0000 | [diff] [blame] | 227 | IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; |
Paul Vriens | 202b340 | 2005-01-09 17:29:21 +0000 | [diff] [blame] | 228 | ULONG ref = InterlockedIncrement(&This->ref); |
| 229 | |
| 230 | TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1); |
| 231 | |
| 232 | return ref; |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 233 | } |
| 234 | |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 235 | HRESULT WINAPI Main_DirectDrawClipper_GetHWnd( |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 236 | LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr |
| 237 | ) { |
Alexandre Julliard | f5f7a18 | 2004-09-08 01:50:37 +0000 | [diff] [blame] | 238 | IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 239 | FIXME("(%p)->(%p),stub!\n",This,hWndPtr); |
| 240 | |
Vincent Béron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 241 | *hWndPtr = This->hWnd; |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 242 | |
| 243 | return DD_OK; |
| 244 | } |
| 245 | |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 246 | HRESULT WINAPI Main_DirectDrawClipper_Initialize( |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 247 | LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags |
| 248 | ) { |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 249 | IDirectDrawImpl* pOwner; |
Alexandre Julliard | f5f7a18 | 2004-09-08 01:50:37 +0000 | [diff] [blame] | 250 | IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 251 | FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags); |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 252 | |
| 253 | if (This->ddraw_owner != NULL) return DDERR_ALREADYINITIALIZED; |
| 254 | |
| 255 | pOwner = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, lpDD); |
| 256 | This->ddraw_owner = pOwner; |
| 257 | Main_DirectDraw_AddClipper(pOwner, This); |
| 258 | |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 259 | return DD_OK; |
| 260 | } |
| 261 | |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 262 | HRESULT WINAPI Main_DirectDrawClipper_IsClipListChanged( |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 263 | LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged |
| 264 | ) { |
Alexandre Julliard | f5f7a18 | 2004-09-08 01:50:37 +0000 | [diff] [blame] | 265 | IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 266 | FIXME("(%p)->(%p),stub!\n",This,lpbChanged); |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 267 | |
| 268 | /* XXX What is safest? */ |
| 269 | *lpbChanged = FALSE; |
| 270 | |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 271 | return DD_OK; |
| 272 | } |
| 273 | |
Alexandre Julliard | 48c4bb3 | 2004-08-12 23:00:51 +0000 | [diff] [blame] | 274 | static IDirectDrawClipperVtbl DDRAW_Clipper_VTable = |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 275 | { |
Alexandre Julliard | d6c0f9f | 2001-01-04 22:44:55 +0000 | [diff] [blame] | 276 | Main_DirectDrawClipper_QueryInterface, |
| 277 | Main_DirectDrawClipper_AddRef, |
| 278 | Main_DirectDrawClipper_Release, |
| 279 | Main_DirectDrawClipper_GetClipList, |
| 280 | Main_DirectDrawClipper_GetHWnd, |
| 281 | Main_DirectDrawClipper_Initialize, |
| 282 | Main_DirectDrawClipper_IsClipListChanged, |
| 283 | Main_DirectDrawClipper_SetClipList, |
| 284 | Main_DirectDrawClipper_SetHwnd |
Marcus Meissner | 10ad97c | 2000-04-09 14:30:50 +0000 | [diff] [blame] | 285 | }; |