source: trunk/src/ddraw/OS2CLIPPER.CPP@ 6901

Last change on this file since 6901 was 6901, checked in by sandervl, 24 years ago

clipper updates

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