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

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

take clipping info into account when blitting

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