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

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

Changes for applications that don't validate the update region of a window during WM_PAINT

File size: 9.7 KB
Line 
1/* $Id: dcrgn.cpp,v 1.8 2003-03-22 20:27:11 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//******************************************************************************
45//******************************************************************************
46BOOL WIN32API GetUpdateRect(HWND hwnd, LPRECT pRect, BOOL erase)
47{
48 if (!hwnd)
49 {
50 dprintf(("GetUpdateRect %x %x %d -> invalid handle!!", hwnd, pRect, erase));
51 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
52 return FALSE;
53 }
54
55 RECTL rectl, rectlClient;
56 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
57
58 if (!wnd)
59 {
60 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
61 dprintf(("GetUpdateRect %x %x %d -> invalid handle!!", hwnd, pRect, erase));
62 return FALSE;
63 }
64
65 dprintf(("GetUpdateRect %x %x %d", hwnd, pRect, erase));
66
67 //check if the application previously didn't handle a WM_PAINT msg properly
68 wnd->checkForDirtyUpdateRegion();
69
70 BOOL updateRegionExists = WinQueryUpdateRect(wnd->getOS2WindowHandle(), pRect ? &rectl : NULL);
71 if (!pRect) {
72 dprintf(("GetUpdateRect returned %d", updateRegionExists));
73 RELEASE_WNDOBJ(wnd);
74 return (updateRegionExists);
75 }
76
77 if(updateRegionExists)
78 {
79 //CB: for PM empty rect is valid
80 if ((rectl.xLeft == rectl.xRight) || (rectl.yTop == rectl.yBottom)) {
81 if(pRect) {
82 pRect->left = pRect->top = pRect->right = pRect->bottom = 0;
83 }
84 RELEASE_WNDOBJ(wnd);
85 return FALSE;
86 }
87 mapOS2ToWin32Rect(wnd->getClientHeight(), (PRECTLOS2)&rectl, pRect);
88
89 if(wnd->isOwnDC() && GetMapMode(wnd->getOwnDC()) != MM_TEXT_W)
90 {
91 DPtoLP(wnd->getOwnDC(), (LPPOINT)pRect, 2);
92 }
93 if (erase)
94 sendEraseBkgnd (wnd);
95 }
96 else
97 {
98 if(pRect) {
99 pRect->left = pRect->top = pRect->right = pRect->bottom = 0;
100 }
101 }
102
103 dprintf(("GetUpdateRect returned (%d,%d)(%d,%d)", pRect->left, pRect->top, pRect->right, pRect->bottom));
104 RELEASE_WNDOBJ(wnd);
105 return updateRegionExists;
106}
107//******************************************************************************
108//TODO: Seems to return region in window coordinates instead of client coordinates
109//******************************************************************************
110int WIN32API GetUpdateRgn(HWND hwnd, HRGN hrgn, BOOL erase)
111{
112 LONG lComplexity;
113 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
114
115 hrgn = ObjWinToOS2Region(hrgn);
116 if(!wnd || !hrgn)
117 {
118 dprintf(("WARNING: GetUpdateRgn %x %x %d; invalid handle", hwnd, hrgn, erase));
119 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
120 if(wnd) RELEASE_WNDOBJ(wnd);
121 return ERROR_W;
122 }
123 //check if the application previously didn't handle a WM_PAINT msg properly
124 wnd->checkForDirtyUpdateRegion();
125
126 lComplexity = WinQueryUpdateRegion(wnd->getOS2WindowHandle(), hrgn);
127 if(lComplexity == RGN_ERROR) {
128 dprintf(("WARNING: GetUpdateRgn %x %x %d; RGN_ERROR", hwnd, hrgn, erase));
129 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
130 RELEASE_WNDOBJ(wnd);
131 return ERROR_W;
132 }
133
134 if(lComplexity != RGN_NULL)
135 {
136 if(!setWinDeviceRegionFromPMDeviceRegion(hrgn, hrgn, NULL, wnd->getOS2WindowHandle()))
137 {
138 dprintf(("WARNING: GetUpdateRgn %x %x %d; setWinDeviceRegionFromPMDeviceRegion failed!", hwnd, hrgn, erase));
139 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
140 RELEASE_WNDOBJ(wnd);
141 return ERROR_W;
142 }
143 if(erase) sendEraseBkgnd(wnd);
144 }
145 RELEASE_WNDOBJ(wnd);
146 return lComplexity;
147}
148//******************************************************************************
149//TODO: Check
150//******************************************************************************
151INT WIN32API ExcludeUpdateRgn(HDC hdc, HWND hwnd)
152{
153 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
154 pDCData pHps = (pDCData)GpiQueryDCData((HPS)hdc);
155 LONG lComplexity;
156
157 if(!wnd || !pHps)
158 {
159 dprintf(("WARNING: ExcludeUpdateRgn %x %x; invalid handle", hdc, hwnd));
160 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
161 if(wnd) RELEASE_WNDOBJ(wnd);
162 return ERROR_W;
163 }
164 dprintf(("USER32: ExcludeUpdateRgn %x %x", hdc, hwnd));
165
166 lComplexity = WinExcludeUpdateRegion(pHps->hps, wnd->getOS2WindowHandle());
167 if(lComplexity == RGN_ERROR) {
168 SetLastError(ERROR_INVALID_HANDLE_W); //todo: correct error
169 }
170 else SetLastError(ERROR_SUCCESS_W);
171
172 RELEASE_WNDOBJ(wnd);
173 return lComplexity; // windows and PM values are identical
174}
175/*****************************************************************************
176 * Name : int WIN32API GetWindowRgn
177 * Purpose : The GetWindowRgn function obtains a copy of the window region of a window.
178 * Parameters: HWND hWnd handle to window whose window region is to be obtained
179 * HRGN hRgn handle to region that receives a copy of the window region
180 * Variables :
181 * Result : NULLREGION, SIMPLEREGION, COMPLEXREGION, ERROR
182 * Remark :
183 * Status : UNTESTED STUB
184 *
185 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
186 *****************************************************************************/
187
188int WIN32API GetWindowRgn(HWND hwnd, HRGN hRgn)
189{
190 Win32BaseWindow *window;
191 HRGN hWindowRegion;
192
193 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
194 if(!window) {
195 dprintf(("SetWindowContextHelpId, window %x not found", hwnd));
196 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
197 return 0;
198 }
199 dprintf(("USER32:GetWindowRgn (%x,%x)", hwnd, hRgn));
200 hWindowRegion = window->GetWindowRegion();
201 RELEASE_WNDOBJ(window);
202 return CombineRgn(hRgn, hWindowRegion, 0, RGN_COPY_W);
203}
204/*****************************************************************************
205 * Name : int WIN32API SetWindowRgn
206 * Purpose : The SetWindowRgn function sets the window region of a window. The
207 * window region determines the area within the window where the
208 * operating system permits drawing. The operating system does not
209 * display any portion of a window that lies outside of the window region
210 * When this function is called, the system sends the WM_WINDOWPOSCHANGING and
211 * WM_WINDOWPOSCHANGED messages to the window.
212 *
213 * Parameters: HWND hWnd handle to window whose window region is to be set
214 * HRGN hRgn handle to region
215 * BOOL bRedraw window redraw flag
216 * Variables :
217 * Result : If the function succeeds, the return value is non-zero.
218 * If the function fails, the return value is zero.
219 * Remark :
220 * Status : UNTESTED STUB
221 *
222 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
223 *****************************************************************************/
224
225int WIN32API SetWindowRgn(HWND hwnd,
226 HRGN hRgn,
227 BOOL bRedraw)
228{
229 Win32BaseWindow *window;
230 HRGN hWindowRegion;
231
232 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
233 if(!window) {
234 dprintf(("SetWindowContextHelpId, window %x not found", hwnd));
235 SetLastError(ERROR_INVALID_WINDOW_HANDLE_W);
236 return 0;
237 }
238 dprintf(("USER32:SetWindowRgn (%x,%x,%d)", hwnd, hRgn, bRedraw));
239 if(window->GetWindowRegion()) {
240 DeleteObject(window->GetWindowRegion());
241 }
242 window->SetWindowRegion(hRgn);
243 if(bRedraw) {
244 RedrawWindow(hwnd, 0, 0, RDW_UPDATENOW_W);
245 }
246 RELEASE_WNDOBJ(window);
247//TODO:
248// When this function is called, the system sends the WM_WINDOWPOSCHANGING and
249// WM_WINDOWPOSCHANGED messages to the window.
250 return 1;
251}
252//******************************************************************************
253// WinSetVisibleRgnNotifyProc
254// To set a notification procedure for visible region changes of a specific window.
255// The procedure will be called when a WM_VRNENABLED message is posted
256// with ffVisRgnChanged set to TRUE
257//
258// Parameters:
259// HWND hwnd window handle
260// VISRGN_NOTIFY_PROC lpNotifyProc notification proc or NULL to clear proc
261// DWORD dwUserData value used as 3rd parameter during
262// visible region callback
263//
264// NOTE: Internal API
265//******************************************************************************
266BOOL WIN32API WinSetVisibleRgnNotifyProc(HWND hwnd, VISRGN_NOTIFY_PROC lpNotifyProc,
267 DWORD dwUserData)
268{
269 Win32BaseWindow *window;
270
271 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
272 if(!window) {
273 dprintf(("WinSetVisibleRgnNotifyProc, window %x not found", hwnd));
274 return FALSE;
275 }
276 BOOL ret = window->setVisibleRgnNotifyProc(lpNotifyProc, dwUserData);
277 RELEASE_WNDOBJ(window);
278 return ret;
279}
280//******************************************************************************
281//******************************************************************************
Note: See TracBrowser for help on using the repository browser.