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

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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