source: trunk/src/user32/dcrgn.cpp@ 10367

Last change on this file since 10367 was 10316, checked in by sandervl, 22 years ago

Visible & Clip region changes

File size: 11.9 KB
Line 
1/* $Id: dcrgn.cpp,v 1.9 2003-11-12 14:10:19 sandervl Exp $ */
2
3/*
4 * DC functions for USER32
5 *
6 * Project Odin Software License can be found in LICENSE.TXT
7 *
8 */
9
10/*****************************************************************************
11 * Includes *
12 *****************************************************************************/
13
14#include <odin.h>
15
16#define INCL_WIN
17#define INCL_GPI
18#define INCL_GREALL
19#define INCL_DEV
20#include <os2wrap.h>
21//#include <pmddi.h>
22#include <stdlib.h>
23
24#include <string.h>
25#include <win32type.h>
26#include <win32api.h>
27#include <winconst.h>
28#include <misc.h>
29#include <win32wbase.h>
30#include <math.h>
31#include <limits.h>
32#include "oslibwin.h"
33#include "oslibmsg.h"
34#include <dcdata.h>
35#include <objhandle.h>
36#include <wingdi32.h>
37
38#define INCLUDED_BY_DC
39#include "dc.h"
40
41#define DBG_LOCALLOG DBG_dcrgn
42#include "dbglocal.h"
43
44#ifdef DEBUG
45//#define dprintfRegion(a,b,c) if(DbgEnabledLvl2USER32[DBG_LOCALLOG] == 1) dprintfRegion1(a,b,c)
46//#define dprintfRegion(a,b,c) dprintfRegion1(a,b,c)
47
48static void dprintfRegion(HWND hWnd, HRGN hrgnClip)
49{
50 RGNRECT rgnRect = {0, 16, 0, RECTDIR_LFRT_TOPBOT};
51 RECTL rectRegion[16];
52 APIRET rc;
53 HDC hdc;
54
55 hdc = GetDCEx(hWnd, NULL, DCX_CACHE_W|DCX_USESTYLE_W);
56 dprintf(("dprintfRegion %x %x", hWnd, hdc));
57 rc = GpiQueryRegionRects(hdc, hrgnClip, NULL, &rgnRect, &rectRegion[0]);
58 for(int i=0;i<rgnRect.crcReturned;i++) {
59 dprintf(("(%d,%d)(%d,%d)", rectRegion[i].xLeft, rectRegion[i].yBottom, rectRegion[i].xRight, rectRegion[i].yTop));
60 }
61 ReleaseDC(hWnd, hdc);
62}
63#else
64#define dprintfRegion(b,c)
65#endif
66
67//******************************************************************************
68//******************************************************************************
69BOOL WIN32API GetUpdateRect(HWND hwnd, LPRECT pRect, BOOL erase)
70{
71 if (!hwnd)
72 {
73 dprintf(("GetUpdateRect %x %x %d -> invalid handle!!", hwnd, pRect, erase));
74 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
75 return FALSE;
76 }
77
78 RECTL rectl, rectlClient;
79 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
80
81 if (!wnd)
82 {
83 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
84 dprintf(("GetUpdateRect %x %x %d -> invalid handle!!", hwnd, pRect, erase));
85 return FALSE;
86 }
87
88 dprintf(("GetUpdateRect %x %x %d", hwnd, pRect, erase));
89
90 //check if the application previously didn't handle a WM_PAINT msg properly
91 wnd->checkForDirtyUpdateRegion();
92
93 BOOL updateRegionExists = WinQueryUpdateRect(wnd->getOS2WindowHandle(), pRect ? &rectl : NULL);
94 if (!pRect) {
95 dprintf(("GetUpdateRect returned %d", updateRegionExists));
96 RELEASE_WNDOBJ(wnd);
97 return (updateRegionExists);
98 }
99
100 if(updateRegionExists)
101 {
102 //CB: for PM empty rect is valid
103 if ((rectl.xLeft == rectl.xRight) || (rectl.yTop == rectl.yBottom)) {
104 if(pRect) {
105 pRect->left = pRect->top = pRect->right = pRect->bottom = 0;
106 }
107 RELEASE_WNDOBJ(wnd);
108 return FALSE;
109 }
110 mapOS2ToWin32Rect(wnd->getClientHeight(), (PRECTLOS2)&rectl, pRect);
111
112 if(wnd->isOwnDC() && GetMapMode(wnd->getOwnDC()) != MM_TEXT_W)
113 {
114 DPtoLP(wnd->getOwnDC(), (LPPOINT)pRect, 2);
115 }
116 if (erase)
117 sendEraseBkgnd (wnd);
118 }
119 else
120 {
121 if(pRect) {
122 pRect->left = pRect->top = pRect->right = pRect->bottom = 0;
123 }
124 }
125
126 dprintf(("GetUpdateRect returned (%d,%d)(%d,%d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
127 RELEASE_WNDOBJ(wnd);
128 return updateRegionExists;
129}
130//******************************************************************************
131//TODO: Seems to return region in window coordinates instead of client coordinates
132//******************************************************************************
133int WIN32API GetUpdateRgn(HWND hwnd, HRGN hrgn, BOOL erase)
134{
135 LONG lComplexity;
136 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
137
138 hrgn = ObjWinToOS2Region(hrgn);
139 if(!wnd || !hrgn)
140 {
141 dprintf(("WARNING: GetUpdateRgn %x %x %d; invalid handle", hwnd, hrgn, erase));
142 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
143 if(wnd) RELEASE_WNDOBJ(wnd);
144 return ERROR_W;
145 }
146 //check if the application previously didn't handle a WM_PAINT msg properly
147 wnd->checkForDirtyUpdateRegion();
148
149 lComplexity = WinQueryUpdateRegion(wnd->getOS2WindowHandle(), hrgn);
150 if(lComplexity == RGN_ERROR) {
151 dprintf(("WARNING: GetUpdateRgn %x %x %d; RGN_ERROR", hwnd, hrgn, erase));
152 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
153 RELEASE_WNDOBJ(wnd);
154 return ERROR_W;
155 }
156
157 if(lComplexity != RGN_NULL)
158 {
159 dprintfRegion(hwnd, hrgn);
160 if(!setWinDeviceRegionFromPMDeviceRegion(hrgn, hrgn, NULL, wnd->getOS2WindowHandle()))
161 {
162 dprintf(("WARNING: GetUpdateRgn %x %x %d; setWinDeviceRegionFromPMDeviceRegion failed!", hwnd, hrgn, erase));
163 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
164 RELEASE_WNDOBJ(wnd);
165 return ERROR_W;
166 }
167 if(erase) sendEraseBkgnd(wnd);
168 }
169 RELEASE_WNDOBJ(wnd);
170 return lComplexity;
171}
172//******************************************************************************
173//TODO: Seems to return region in window coordinates instead of client coordinates
174//******************************************************************************
175int WIN32API GetUpdateRgnFrame(HWND hwnd, HRGN hrgn)
176{
177 LONG lComplexity;
178 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
179
180 hrgn = ObjWinToOS2Region(hrgn);
181 if(!wnd || !hrgn)
182 {
183 dprintf(("WARNING: GetUpdateRgnFrame %x %x invalid handle", hwnd, hrgn));
184 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
185 if(wnd) RELEASE_WNDOBJ(wnd);
186 return ERROR_W;
187 }
188 lComplexity = WinQueryUpdateRegion(wnd->getOS2FrameWindowHandle(), hrgn);
189 if(lComplexity == RGN_ERROR) {
190 dprintf(("WARNING: GetUpdateRgnFrame %x %x RGN_ERROR", hwnd, hrgn));
191 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
192 RELEASE_WNDOBJ(wnd);
193 return ERROR_W;
194 }
195
196 if(lComplexity != RGN_NULL)
197 {
198 dprintfRegion(hwnd, hrgn);
199 if(!setWinDeviceRegionFromPMDeviceRegion(hrgn, hrgn, NULL, wnd->getOS2FrameWindowHandle()))
200 {
201 dprintf(("WARNING: GetUpdateRgnFrame %x %x; setWinDeviceRegionFromPMDeviceRegion failed!", hwnd, hrgn));
202 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
203 RELEASE_WNDOBJ(wnd);
204 return ERROR_W;
205 }
206 }
207 RELEASE_WNDOBJ(wnd);
208 return lComplexity;
209}
210//******************************************************************************
211//TODO: Check
212//******************************************************************************
213INT WIN32API ExcludeUpdateRgn(HDC hdc, HWND hwnd)
214{
215 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
216 pDCData pHps = (pDCData)GpiQueryDCData((HPS)hdc);
217 LONG lComplexity;
218
219 if(!wnd || !pHps)
220 {
221 dprintf(("WARNING: ExcludeUpdateRgn %x %x; invalid handle", hdc, hwnd));
222 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
223 if(wnd) RELEASE_WNDOBJ(wnd);
224 return ERROR_W;
225 }
226 dprintf(("USER32: ExcludeUpdateRgn %x %x", hdc, hwnd));
227
228 lComplexity = WinExcludeUpdateRegion(pHps->hps, wnd->getOS2WindowHandle());
229 if(lComplexity == RGN_ERROR) {
230 SetLastError(ERROR_INVALID_HANDLE_W); //todo: correct error
231 }
232 else SetLastError(ERROR_SUCCESS_W);
233
234 RELEASE_WNDOBJ(wnd);
235 return lComplexity; // windows and PM values are identical
236}
237/*****************************************************************************
238 * Name : int WIN32API GetWindowRgn
239 * Purpose : The GetWindowRgn function obtains a copy of the window region of a window.
240 * Parameters: HWND hWnd handle to window whose window region is to be obtained
241 * HRGN hRgn handle to region that receives a copy of the window region
242 * Variables :
243 * Result : NULLREGION, SIMPLEREGION, COMPLEXREGION, ERROR
244 * Remark :
245 * Status : UNTESTED STUB
246 *
247 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
248 *****************************************************************************/
249
250int WIN32API GetWindowRgn(HWND hwnd, HRGN hRgn)
251{
252 Win32BaseWindow *window;
253 HRGN hWindowRegion;
254
255 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
256 if(!window) {
257 dprintf(("SetWindowContextHelpId, window %x not found", hwnd));
258 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
259 return 0;
260 }
261 dprintf(("USER32:GetWindowRgn (%x,%x)", hwnd, hRgn));
262 hWindowRegion = window->GetWindowRegion();
263 RELEASE_WNDOBJ(window);
264 return CombineRgn(hRgn, hWindowRegion, 0, RGN_COPY_W);
265}
266/*****************************************************************************
267 * Name : int WIN32API SetWindowRgn
268 * Purpose : The SetWindowRgn function sets the window region of a window. The
269 * window region determines the area within the window where the
270 * operating system permits drawing. The operating system does not
271 * display any portion of a window that lies outside of the window region
272 * When this function is called, the system sends the WM_WINDOWPOSCHANGING and
273 * WM_WINDOWPOSCHANGED messages to the window.
274 *
275 * Parameters: HWND hWnd handle to window whose window region is to be set
276 * HRGN hRgn handle to region
277 * BOOL bRedraw window redraw flag
278 * Variables :
279 * Result : If the function succeeds, the return value is non-zero.
280 * If the function fails, the return value is zero.
281 * Remark :
282 * Status : UNTESTED STUB
283 *
284 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
285 *****************************************************************************/
286
287int WIN32API SetWindowRgn(HWND hwnd,
288 HRGN hRgn,
289 BOOL bRedraw)
290{
291 Win32BaseWindow *window;
292 HRGN hWindowRegion;
293
294 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
295 if(!window) {
296 dprintf(("SetWindowContextHelpId, window %x not found", hwnd));
297 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
298 return 0;
299 }
300 dprintf(("USER32:SetWindowRgn (%x,%x,%d)", hwnd, hRgn, bRedraw));
301 if(window->GetWindowRegion()) {
302 DeleteObject(window->GetWindowRegion());
303 }
304 window->SetWindowRegion(hRgn);
305 if(bRedraw) {
306 RedrawWindow(hwnd, 0, 0, RDW_UPDATENOW_W);
307 }
308 RELEASE_WNDOBJ(window);
309//TODO:
310// When this function is called, the system sends the WM_WINDOWPOSCHANGING and
311// WM_WINDOWPOSCHANGED messages to the window.
312 return 1;
313}
314//******************************************************************************
315// WinSetVisibleRgnNotifyProc
316// To set a notification procedure for visible region changes of a specific window.
317// The procedure will be called when a WM_VRNENABLED message is posted
318// with ffVisRgnChanged set to TRUE
319//
320// Parameters:
321// HWND hwnd window handle
322// VISRGN_NOTIFY_PROC lpNotifyProc notification proc or NULL to clear proc
323// DWORD dwUserData value used as 3rd parameter during
324// visible region callback
325//
326// NOTE: Internal API
327//******************************************************************************
328BOOL WIN32API WinSetVisibleRgnNotifyProc(HWND hwnd, VISRGN_NOTIFY_PROC lpNotifyProc,
329 DWORD dwUserData)
330{
331 Win32BaseWindow *window;
332
333 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
334 if(!window) {
335 dprintf(("WinSetVisibleRgnNotifyProc, window %x not found", hwnd));
336 return FALSE;
337 }
338 BOOL ret = window->setVisibleRgnNotifyProc(lpNotifyProc, dwUserData);
339 RELEASE_WNDOBJ(window);
340 return ret;
341}
342//******************************************************************************
343//******************************************************************************
Note: See TracBrowser for help on using the repository browser.