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

Last change on this file since 21483 was 21483, checked in by dmik, 15 years ago

ddraw: Don't define CINTERFACE twice.

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