source: trunk/src/ddraw/clipper.cpp@ 9459

Last change on this file since 9459 was 9459, checked in by sandervl, 23 years ago

cleanup + don't change the window size/status in SetCooperativeLevel

File size: 11.1 KB
Line 
1/* $Id: clipper.cpp,v 1.1 2002-12-04 10:34:57 sandervl Exp $ */
2
3/*
4 * DX clipper class routines
5 *
6 * Copyright 1998-2001 Sander van Leeuwen
7 * Copyright 1999 Markus Montkowski
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 * TODO: This is NOT THREAD SAFE!!!
12 *
13 */
14
15#define _OS2WIN_H
16#define FAR
17
18#include <odin.h>
19#include <winbase.h>
20#include <memory.h>
21
22#define INITGUID
23#include "ddraw2d.h"
24#include "clipper.h"
25#include <misc.h>
26#include <winerror.h>
27#include <winuser.h>
28#include <winuser32.h>
29#include "oslibgpi.h"
30
31//******************************************************************************
32//******************************************************************************
33OS2IDirectDrawClipper::OS2IDirectDrawClipper(void) :
34 Referenced(0), lastError(DD_OK), fDrawingAllowed(TRUE),
35 clipWindow(0), lpRgnData(NULL), fClipListChanged(FALSE),
36 fClipListChangedInt(FALSE)
37{
38 // this constructor creates an unassociated instance of the ddraw clipper,
39 // no ddraw object is associated
40
41 lpVtbl = &Vtbl;
42 Vtbl.AddRef = ClipAddRef;
43 Vtbl.Release = ClipRelease;
44 Vtbl.QueryInterface = ClipQueryInterface;
45 Vtbl.GetClipList = ClipGetClipList;
46 Vtbl.GetHWnd = ClipGetHWnd;
47 Vtbl.Initialize = ClipInitialize;
48 Vtbl.IsClipListChanged = ClipIsClipListChanged;
49 Vtbl.SetClipList = ClipSetClipList;
50 Vtbl.SetHWnd = ClipSetHWnd;
51
52 lpDraw = NULL;
53 // lpDraw->Vtbl.AddRef(lpDraw);
54 // hDive = lpDirectDraw->GetDiveInstance();
55
56}
57
58//******************************************************************************
59//******************************************************************************
60OS2IDirectDrawClipper::OS2IDirectDrawClipper(OS2IDirectDraw *lpDirectDraw) :
61 Referenced(0), lastError(DD_OK), fDrawingAllowed(TRUE),
62 clipWindow(0), lpRgnData(NULL), fClipListChanged(FALSE),
63 fClipListChangedInt(FALSE)
64{
65 lpVtbl = &Vtbl;
66 Vtbl.AddRef = ClipAddRef;
67 Vtbl.Release = ClipRelease;
68 Vtbl.QueryInterface = ClipQueryInterface;
69 Vtbl.GetClipList = ClipGetClipList;
70 Vtbl.GetHWnd = ClipGetHWnd;
71 Vtbl.Initialize = ClipInitialize;
72 Vtbl.IsClipListChanged = ClipIsClipListChanged;
73 Vtbl.SetClipList = ClipSetClipList;
74 Vtbl.SetHWnd = ClipSetHWnd;
75
76 lpDraw = lpDirectDraw;
77 lpDraw->Vtbl.AddRef(lpDraw);
78 hDive = lpDirectDraw->GetDiveInstance();
79}
80//******************************************************************************
81//******************************************************************************
82OS2IDirectDrawClipper::~OS2IDirectDrawClipper()
83{
84 if(lpRgnData) free(lpRgnData);
85 if(clipWindow) {
86 WinSetVisibleRgnNotifyProc(clipWindow, NULL, 0);
87 }
88 lpDraw->Vtbl.Release(lpDraw);
89}
90//******************************************************************************
91//******************************************************************************
92HRESULT WIN32API ClipQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj)
93{
94 dprintf(("DDRAW: ClipQueryInterface\n"));
95
96 *ppvObj = NULL;
97
98 if(!IsEqualGUID(riid, IID_IDirectDrawClipper) &&
99 !IsEqualGUID(riid, CLSID_DirectDrawClipper))
100//&& !IsEqualGUID(riid, IID_IUnknown))
101 return E_NOINTERFACE;
102
103 *ppvObj = This;
104
105 ClipAddRef(This);
106 return(DD_OK);
107}
108//******************************************************************************
109//******************************************************************************
110ULONG WIN32API ClipAddRef(THIS This)
111{
112 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
113
114 dprintf(("DDRAW: OS2IDirectDrawClipper::AddRef %d\n", me->Referenced+1));
115
116 return ++me->Referenced;
117}
118//******************************************************************************
119//******************************************************************************
120ULONG WIN32API ClipRelease(THIS This)
121{
122 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
123
124 dprintf(("DDRAW: OS2IDirectDrawClipper::Release %d", me->Referenced-1));
125
126 if(me->Referenced)
127 {
128 me->Referenced--;
129 if(me->Referenced == 0)
130 {
131 delete( me);
132 return(0);
133 }
134 else
135 return me->Referenced;
136 }
137 else
138 return(0);
139}
140//******************************************************************************
141//******************************************************************************
142HRESULT WIN32API ClipGetClipList(THIS This, LPRECT lpRect, LPRGNDATA lpClipList,
143 LPDWORD lpdwSize)
144{
145 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
146 HRESULT rc = DD_OK;
147
148 dprintf(("DDRAW: ClipGetClipList %x %x %x %x", This, lpRect, lpClipList, lpdwSize));
149
150 if(!lpdwSize) {
151 return DDERR_INVALIDPARAMS;
152 }
153 if(lpRect) {
154 dprintf(("WARNING: clipping the cliplist is not yet implemented"));
155 }
156 if(me->clipWindow)
157 {
158 RECT *rect = (RECT *)&lpClipList->Buffer;
159 DWORD regiondatasize;
160
161 if(me->lpRgnData == NULL) {
162 DebugInt3();
163 return DDERR_NOCLIPLIST;
164 }
165 //TODO: This is NOT THREAD SAFE!!!
166 regiondatasize = me->lpRgnData->rdh.dwSize + me->lpRgnData->rdh.nCount*sizeof(RECT);
167 if(lpClipList == NULL) {
168 *lpdwSize = regiondatasize;
169 return DD_OK;
170 }
171
172 if(*lpdwSize < regiondatasize) {
173 *lpdwSize = regiondatasize;
174 return DDERR_REGIONTOOSMALL;
175 }
176 memcpy(lpClipList, me->lpRgnData, regiondatasize);
177 dprintf(("Boundary rectangle (%d,%d)(%d,%d)", lpClipList->rdh.rcBound.left, lpClipList->rdh.rcBound.top, lpClipList->rdh.rcBound.right, lpClipList->rdh.rcBound.bottom));
178 }
179 else { //todo!!
180 dprintf(("ClipGetClipList not complete if not associated with window!"));
181 rc = DDERR_NOCLIPLIST;
182 }
183 return rc;
184}
185//******************************************************************************
186//******************************************************************************
187HRESULT WIN32API ClipGetHWnd(THIS This, HWND FAR *pHwnd)
188{
189 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
190
191 dprintf(("DDRAW: ClipGetHWnd %x %x", This, me->clipWindow));
192
193 *pHwnd = me->clipWindow;
194 return(DD_OK);
195}
196//******************************************************************************
197//******************************************************************************
198HRESULT WIN32API ClipInitialize(THIS This, LPDIRECTDRAW lpDD, DWORD dwFlags)
199{
200 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
201
202 dprintf(("DDRAW: ClipInitialize %x %x %x", This, lpDD, dwFlags));
203
204 // check parameters
205 if (dwFlags != 0)
206 return DDERR_INVALIDPARAMS;
207
208 // check if already initialized
209 if (me->hDive != NULL)
210 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
211
212 // initialize this instance (created with DirectDrawCreateClipper)
213
214 if (lpDD != NULL)
215 {
216 OS2IDirectDraw *os2DD = (OS2IDirectDraw *)lpDD;
217 me->lpDraw = os2DD;
218 me->lpDraw->Vtbl.AddRef(me->lpDraw);
219 me->hDive = me->lpDraw->GetDiveInstance();
220 }
221 else
222 {
223 // we're supposed to create an independent DirectDrawClipper object
224 // now.
225 if (me->lpDraw != NULL)
226 {
227 // we're not handling this any other currently
228 return(DDERR_ALREADYINITIALIZED);
229 }
230 // else
231 // we've been independent and remain so ...
232 }
233
234 return(DD_OK);
235}
236//******************************************************************************
237//******************************************************************************
238HRESULT WIN32API ClipIsClipListChanged(THIS This, BOOL *lpbChanged)
239{
240 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
241
242 dprintf(("DDRAW: ClipIsClipListChanged %x %x", This, lpbChanged));
243
244 if(lpbChanged == NULL) {
245 return DDERR_INVALIDPARAMS;
246 }
247 *lpbChanged = me->fClipListChanged;
248 me->fClipListChanged = FALSE;
249 return(DD_OK);
250}
251//******************************************************************************
252//******************************************************************************
253HRESULT WIN32API ClipSetClipList(THIS This, LPRGNDATA lpClipList, DWORD dwFlags)
254{
255 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
256
257 dprintf(("DDRAW: ClipSetClipList %x %x %x", This, lpClipList, dwFlags));
258
259 if(me->clipWindow) {
260 return DDERR_CLIPPERISUSINGHWND;
261 }
262 if(lpClipList == NULL) {
263 //TODO: should protect this with a critical section
264 if(me->lpRgnData) {
265 free(me->lpRgnData);
266 me->lpRgnData = NULL;
267 }
268 return DD_OK;
269 }
270 //TODO: return error if a clip list is already active??
271 if(me->lpRgnData) {
272 free(me->lpRgnData);
273 me->lpRgnData = NULL;
274 }
275 me->lpRgnData = (LPRGNDATA)malloc(lpClipList->rdh.dwSize + lpClipList->rdh.nCount*sizeof(RECT));
276 memcpy(me->lpRgnData, lpClipList, lpClipList->rdh.dwSize + lpClipList->rdh.nCount*sizeof(RECT));
277 return DD_OK;
278}
279//******************************************************************************
280//******************************************************************************
281BOOL WIN32API ClipVisRgnCallback(HWND hwnd, BOOL fDrawingAllowed, DWORD dwUserData)
282{
283 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)dwUserData;
284 LPRGNDATA lpClipList, lpRgnOld;
285
286 dprintf(("DDRAW: ClipVisRgnCallback %x %x %x", me, hwnd, fDrawingAllowed));
287 if(me && me->clipWindow == hwnd) {
288 me->fClipListChanged = TRUE;
289 me->fClipListChangedInt = TRUE; //internal flag
290 lpRgnOld = me->lpRgnData;
291 if(fDrawingAllowed == FALSE) {
292 me->fDrawingAllowed = FALSE;
293 lpClipList = (LPRGNDATA)malloc(sizeof(RGNDATA));
294 lpClipList->rdh.dwSize = sizeof(lpClipList->rdh);
295 lpClipList->rdh.iType = RDH_RECTANGLES; // one and only possible value
296 lpClipList->rdh.nCount = 0;
297 lpClipList->rdh.nRgnSize = 0;
298 me->lpRgnData = lpClipList;
299 }
300 else {
301 me->fDrawingAllowed = TRUE;
302 me->lpRgnData = OSLibQueryVisibleRegion(hwnd, (me->lpDraw) ? me->lpDraw->GetScreenHeight() : 0);
303 }
304 free(lpRgnOld);
305 }
306 return TRUE;
307}
308//******************************************************************************
309//DWORD param not used in DirectX 3
310//******************************************************************************
311HRESULT WIN32API ClipSetHWnd(THIS This, DWORD reserved, HWND hwnd)
312{
313 OS2IDirectDrawClipper *me = (OS2IDirectDrawClipper *)This;
314
315 dprintf(("DDRAW: ClipSetHWnd %x %x %x", This, reserved, hwnd));
316
317 if(!IsWindow(hwnd)) {
318 dprintf(("WARNING: ClipSetHWnd invalid window handle"));
319 return DDERR_INVALIDPARAMS;
320 }
321 if(me->clipWindow) {
322 //TODO: Is this really allowed??
323 WinSetVisibleRgnNotifyProc(me->clipWindow, NULL, 0);
324 }
325 me->clipWindow = hwnd;
326 WinSetVisibleRgnNotifyProc(hwnd, ClipVisRgnCallback, (DWORD)me);
327
328 me->lpRgnData = OSLibQueryVisibleRegion(hwnd, (me->lpDraw) ? me->lpDraw->GetScreenHeight() : 0);
329 me->fClipListChanged = TRUE;
330 me->fClipListChangedInt = TRUE; //internal flag
331
332 return(DD_OK);
333}
334//******************************************************************************
335//******************************************************************************
Note: See TracBrowser for help on using the repository browser.