source: trunk/src/user32/dc.cpp@ 1194

Last change on this file since 1194 was 1087, checked in by dengert, 26 years ago

ScrollWindowEx implemented

File size: 41.1 KB
Line 
1/* $Id: dc.cpp,v 1.11 1999-09-28 18:14:57 dengert Exp $ */
2
3/*
4 * DC functions for USER32
5 *
6 * Project Odin Software License can be found in LICENSE.TXT
7 *
8 */
9
10#define INCL_WIN
11#define INCL_GPI
12#define INCL_GREALL
13#define INCL_DEV
14#include <os2.h>
15#include <pmddi.h>
16#include <os2sel.h>
17#include <stdlib.h>
18#include "win32type.h"
19#include <winconst.h>
20#include <wprocess.h>
21#include <misc.h>
22#include <win32wbase.h>
23#include <math.h>
24#include <limits.h>
25#include "oslibwin.h"
26#include "dcdata.h"
27
28#undef SEVERITY_ERROR
29#include <winerror.h>
30
31#ifndef OPEN32API
32#define OPEN32API _System
33#endif
34
35/*********************/
36typedef struct
37{
38 HDC hdc;
39 BOOL fErase;
40 RECT rcPaint;
41 BOOL fRestore;
42 BOOL IncUpdate;
43 BYTE rgbReserved[32];
44} PAINTSTRUCT_W, *PPAINTSTRUCT_W, *LPPAINTSTRUCT_W;
45
46#define PS_SOLID_W 0x00000000
47#define PS_DASH_W 0x00000001
48#define PS_DOT_W 0x00000002
49#define PS_DASHDOT_W 0x00000003
50#define PS_DASHDOTDOT_W 0x00000004
51#define PS_NULL_W 0x00000005
52#define PS_INSIDEFRAME_W 0x00000006
53#define PS_USERSTYLE_W 0x00000007
54#define PS_ALTERNATE_W 0x00000008
55#define PS_STYLE_MASK_W 0x0000000f
56
57typedef struct
58{
59 UINT lopnStyle;
60 POINT lopnWidth;
61 ULONG lopnColor;
62} LOGPEN_W, *LPLOGPEN_W;
63
64typedef struct tagEXTLOGPEN
65{
66 DWORD elpPenStyle;
67 DWORD elpWidth;
68 DWORD elpBrushStyle;
69 DWORD elpColor;
70 DWORD elpNumEntries;
71 DWORD elpStyleEntry[1];
72} EXTLOGPEN_W, *PEXTLOGPEN_W, *NPEXTLOGPEN_W, *LPEXTLOGPEN_W;
73
74typedef struct
75{
76 UINT lbStyle;
77 ULONG lbColor;
78 INT lbHatch;
79} LOGBRUSH_W, *LPLOGBRUSH_W;
80
81typedef struct _penobject
82{
83 ULONG filler[9];
84 union {
85 struct {
86 PEXTLOGPEN_W pExtLogPen;
87 LOGBRUSH_W logbrush;
88 LOGPEN_W logpen;
89 } ExtPen;
90 struct {
91 LOGPEN_W logpen;
92 } Pen;
93 };
94} tPenObject, *pPenObject;
95
96/* DC Graphics Mode */
97#define GM_COMPATIBLE_W 1
98#define GM_ADVANCED_W 2
99
100#define DCX_WINDOW_W 0x00000001L
101#define DCX_CACHE_W 0x00000002L
102#define DCX_NORESETATTRS_W 0x00000004L
103#define DCX_CLIPCHILDREN_W 0x00000008L
104#define DCX_CLIPSIBLINGS_W 0x00000010L
105#define DCX_PARENTCLIP_W 0x00000020L
106#define DCX_EXCLUDERGN_W 0x00000040L
107#define DCX_INTERSECTRGN_W 0x00000080L
108#define DCX_EXCLUDEUPDATE_W 0x00000100L
109#define DCX_INTERSECTUPDATE_W 0x00000200L
110#define DCX_LOCKWINDOWUPDATE_W 0x00000400L
111#define DCX_VALIDATE_W 0x00200000L
112
113#define RDW_INVALIDATE_W 0x0001
114#define RDW_INTERNALPAINT_W 0x0002
115#define RDW_ERASE_W 0x0004
116#define RDW_VALIDATE_W 0x0008
117#define RDW_NOINTERNALPAINT_W 0x0010
118#define RDW_NOERASE_W 0x0020
119#define RDW_NOCHILDREN_W 0x0040
120#define RDW_ALLCHILDREN_W 0x0080
121#define RDW_UPDATENOW_W 0x0100
122#define RDW_ERASENOW_W 0x0200
123#define RDW_FRAME_W 0x0400
124#define RDW_NOFRAME_W 0x0800
125
126typedef struct _RGNDATAHEADER_W {
127 DWORD dwSize;
128 DWORD iType;
129 DWORD nCount;
130 DWORD nRgnSize;
131 RECT rcBound;
132} RGNDATAHEADER_W, *LPRGNDATAHEADER_W;
133
134typedef struct _RGNDATA_W {
135 RGNDATAHEADER_W rdh;
136 char Buffer[1];
137} RGNDATA_W , *PRGNDATA_W , *LPRGNDATA_W ;
138
139
140/* Xform FLAGS */
141#define MWT_IDENTITY_W 1
142#define MWT_LEFTMULTIPLY_W 2
143#define MWT_RIGHTMULTIPLY_W 3
144
145/* Mapping Modes */
146#define MM_TEXT_W 1
147#define MM_LOMETRIC_W 2
148#define MM_HIMETRIC_W 3
149#define MM_LOENGLISH_W 4
150#define MM_HIENGLISH_W 5
151#define MM_TWIPS_W 6
152#define MM_ISOTROPIC_W 7
153#define MM_ANISOTROPIC_W 8
154
155#define RGN_OR_W 2
156
157/* Window scrolling */
158#define SW_SCROLLCHILDREN_W 0x0001
159#define SW_INVALIDATE_W 0x0002
160#define SW_ERASE_W 0x0004
161
162/*********************/
163
164BOOL APIENTRY GpiEnableYInversion (HPS hps, LONG lHeight);
165LONG APIENTRY GpiQueryYInversion (HPS hps);
166PVOID APIENTRY GpiAllocateDCData (HPS GpiH, ULONG size);
167PVOID APIENTRY GpiQueryDCData (HPS hps);
168HDC OPEN32API HPSToHDC (HWND hwnd, HPS hps, HDC hdc, PVOID);
169void OPEN32API DeleteHDC (HDC hdc);
170BOOL OPEN32API _O32_EndPaint (HWND hwnd, const PAINTSTRUCT_W *lpps);
171int OPEN32API _O32_GetUpdateRgn (HWND hwnd, HRGN hrgn, BOOL erase);
172ULONG OPEN32API _O32_GetRegionData (HRGN hrgn, ULONG count, PRGNDATA_W pData);
173BOOL OPEN32API _O32_DeleteObject (LHANDLE hgdiobj);
174int OPEN32API _O32_ReleaseDC (HWND hwnd, HDC hdc);
175VOID OPEN32API _O32_SetLastError( DWORD );
176BOOL OPEN32API _O32_SetRectRgn (HRGN dest, int left, int top, int right, int bottom);
177int OPEN32API _O32_CombineRgn (HRGN dest, HRGN src1, HRGN src2, int mode);
178HRGN OPEN32API _O32_CreateRectRgn (int left, int top, int right, int bottom);
179
180#ifndef DEVESC_SETPS
181 #define DEVESC_SETPS 49149L
182#endif
183
184#define FLOAT_TO_FIXED(x) ((FIXED) ((x) * 65536.0))
185#define MICRO_HPS_TO_HDC(x) ((x) & 0xFFFFFFFE)
186
187#define PMRECT_FROM_WINRECT( pmRect, winRect ) \
188{ \
189 (pmRect).xLeft = (winRect).left; \
190 (pmRect).yBottom = (winRect).bottom; \
191 (pmRect).xRight = (winRect).right; \
192 (pmRect).yTop = (winRect).top; \
193}
194
195#define WINRECT_FROM_PMRECT( winRect, pmRect ) \
196{ \
197 (winRect).left = (pmRect).xLeft; \
198 (winRect).top = (pmRect).yTop; \
199 (winRect).right = (pmRect).xRight; \
200 (winRect).bottom = (pmRect).yBottom; \
201}
202
203#define MEM_HPS_MAX 768
204
205const XFORM_W XFORMIdentity = { 1.0, 0.0, 0.0, 1.0, 0, 0 };
206const MATRIXLF matrixlfIdentity = { 0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0};
207
208BOOL setPageXForm(Win32BaseWindow *wnd, pDCData pHps);
209BOOL changePageXForm(Win32BaseWindow *wnd, pDCData pHps, PPOINTL pValue, int x, int y, PPOINTL pPrev);
210LONG clientHeight(Win32BaseWindow *wnd, HWND hwnd, pDCData pHps);
211
212void TestWideLine (pDCData pHps)
213{
214 const LOGPEN_W *pLogPen;
215
216 pHps->isWideLine = FALSE;
217 pLogPen = pHps->penIsExtPen ?
218 &(pHps->lastPenObject->ExtPen.logpen) :
219 &(pHps->lastPenObject->Pen.logpen);
220
221 if (((pLogPen->lopnStyle & PS_STYLE_MASK_W) != PS_NULL_W) &&
222 (pLogPen->lopnWidth.x > 0))
223 {
224 POINTL aptl[2] = { 0, 0, pLogPen->lopnWidth.x, pLogPen->lopnWidth.x };
225
226 GpiConvert(pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, aptl);
227
228 ULONG dx = abs(aptl[0].x - aptl[1].x);
229 ULONG dy = abs(aptl[0].y - aptl[1].y);
230
231 pHps->isWideLine = (dx > 1) || (dy > 1);
232 }
233}
234
235void Calculate1PixelDelta(pDCData pHps)
236{
237 POINTL aptl[2] = {0, 0, 1, 1};
238
239 GpiConvert(pHps->hps, CVTC_DEVICE, CVTC_WORLD, 2, aptl);
240 pHps->worldYDeltaFor1Pixel = (int)(aptl[1].y - aptl[0].y);
241 pHps->worldXDeltaFor1Pixel = (int)(aptl[1].x - aptl[0].x); // 171182
242}
243
244//******************************************************************************
245
246int setMapMode(Win32BaseWindow *wnd, pDCData pHps, int mode)
247{
248 int prevMode = 0;
249 ULONG flOptions;
250
251 switch (mode)
252 {
253 case MM_HIENGLISH_W : flOptions = PU_HIENGLISH; break;
254 case MM_LOENGLISH_W : flOptions = PU_LOENGLISH; break;
255 case MM_HIMETRIC_W : flOptions = PU_HIMETRIC ; break;
256 case MM_LOMETRIC_W : flOptions = PU_LOMETRIC ; break;
257 case MM_TEXT_W : flOptions = PU_PELS ; break;
258 case MM_TWIPS_W : flOptions = PU_TWIPS ; break;
259 case MM_ANISOTROPIC_W: flOptions = PU_PELS ; break;
260 case MM_ISOTROPIC_W : flOptions = PU_LOMETRIC ; break;
261 default:
262 _O32_SetLastError (ERROR_INVALID_PARAMETER);
263 return FALSE;
264 }
265
266 prevMode = pHps->MapMode; /* store previous mode */
267 pHps->MapMode = mode;
268
269 if (mode == MM_TEXT_W)
270 {
271 pHps->viewportXExt =
272 pHps->viewportYExt = 1.0;
273 pHps->windowExt.cx =
274 pHps->windowExt.cy = 1;
275 }
276 else if (mode != MM_ANISOTROPIC_W)
277 {
278 RECTL rectl;
279 SIZEL sizel;
280 ULONG data[3];
281
282 data[0] = flOptions;
283 data[1] = data[2] = 0;
284
285 if (DevEscape(pHps->hdc ? pHps->hdc : pHps->hps, DEVESC_SETPS, 12, (PBYTE)data, 0, 0) == DEVESC_ERROR)
286 {
287 _O32_SetLastError (ERROR_INVALID_PARAMETER);
288 return 0;
289 }
290
291 GpiQueryPageViewport(pHps->hps, &rectl);
292 pHps->viewportXExt = (double)rectl.xRight;
293 pHps->viewportYExt = -(double)rectl.yTop;
294
295 GreGetPageUnits(pHps->hdc? pHps->hdc : pHps->hps, &sizel);
296 pHps->windowExt.cx = sizel.cx;
297 pHps->windowExt.cy = sizel.cy;
298
299 data[0] = PU_PELS;
300 DevEscape(pHps->hdc ? pHps->hdc : pHps->hps, DEVESC_SETPS, 12, (PBYTE)data, 0, 0);
301 }
302
303 if (((prevMode != MM_ISOTROPIC_W) && (prevMode != MM_ANISOTROPIC_W)) &&
304 ((mode == MM_ISOTROPIC_W) || (mode == MM_ANISOTROPIC_W)))
305 {
306 if (pHps->lWndXExtSave && pHps->lWndYExtSave)
307 {
308 changePageXForm (wnd, pHps, (PPOINTL)&pHps->windowExt,
309 pHps->lWndXExtSave, pHps->lWndYExtSave, NULL );
310 pHps->lWndXExtSave = pHps->lWndYExtSave = 0;
311 }
312 if (pHps->lVwpXExtSave && pHps->lVwpYExtSave)
313 {
314 changePageXForm (wnd, pHps, NULL,
315 pHps->lVwpXExtSave, pHps->lVwpYExtSave, NULL );
316 pHps->lVwpXExtSave = pHps->lVwpYExtSave = 0;
317 }
318 }
319
320 setPageXForm(wnd, pHps);
321
322 return prevMode;
323}
324
325BOOL setPageXForm(Win32BaseWindow *wnd, pDCData pHps)
326{
327 MATRIXLF mlf;
328 BOOL rc = TRUE;
329
330 pHps->height = clientHeight(wnd, 0, pHps) - 1;
331
332 double xScale = pHps->viewportXExt / (double)pHps->windowExt.cx;
333 double yScale = pHps->viewportYExt / (double)pHps->windowExt.cy;
334
335 mlf.fxM11 = FLOAT_TO_FIXED(xScale);
336 mlf.fxM12 = 0;
337 mlf.lM13 = 0;
338 mlf.fxM21 = 0;
339 mlf.fxM22 = FLOAT_TO_FIXED(yScale);
340 mlf.lM23 = 0;
341 mlf.lM31 = pHps->viewportOrg.x - (LONG)(pHps->windowOrg.x * xScale);
342 mlf.lM32 = pHps->viewportOrg.y - (LONG)(pHps->windowOrg.y * yScale);
343
344 pHps->isLeftLeft = mlf.fxM11 >= 0;
345 pHps->isTopTop = mlf.fxM22 >= 0;
346
347 BOOL bEnableYInversion = FALSE;
348 if ((mlf.fxM22 > 0) ||
349 ((pHps->graphicsMode == GM_ADVANCED_W) &&
350 ((pHps->MapMode == MM_ANISOTROPIC_W) ||
351 (pHps->MapMode == MM_ISOTROPIC_W))))
352 {
353 bEnableYInversion = TRUE;
354 }
355 else
356 {
357 bEnableYInversion = FALSE;
358 mlf.lM32 = pHps->HPStoHDCInversionHeight + pHps->height - mlf.lM32;
359 mlf.fxM22 = -mlf.fxM22;
360 }
361
362 if (!pHps->isMetaPS)
363// if ((!pHps->isMetaPS) ||
364// (pHps->pMetaFileObject && pHps->pMetaFileObject->isEnhanced()))
365 rc = GpiSetDefaultViewMatrix(pHps->hps, 8, &mlf, TRANSFORM_REPLACE);
366
367 if (bEnableYInversion)
368 GpiEnableYInversion(pHps->hps, pHps->height + pHps->HPStoHDCInversionHeight);
369 else
370 GpiEnableYInversion(pHps->hps, 0);
371
372 TestWideLine(pHps);
373 Calculate1PixelDelta(pHps);
374 return rc;
375}
376
377BOOL changePageXForm(Win32BaseWindow *wnd, pDCData pHps, PPOINTL pValue, int x, int y, PPOINTL pPrev)
378{
379 BOOL result = FALSE;
380
381 if (pValue)
382 {
383 if (pPrev)
384 *pPrev = *pValue;
385
386 if ((pValue->x == x) && (pValue->y == y)) {
387 return TRUE;
388 }
389 pValue->x = x;
390 pValue->y = y;
391 }
392 else
393 {
394 if (pPrev)
395 {
396 pPrev->x = (int)pHps->viewportXExt;
397 pPrev->y = (int)pHps->viewportYExt;
398 }
399 pHps->viewportXExt = (double)x;
400 pHps->viewportYExt = (double)y;
401 }
402
403 if (pHps->MapMode == MM_ISOTROPIC_W)
404 {
405 double xExt = fabs(pHps->viewportXExt);
406 double yExt = fabs(pHps->viewportYExt);
407 double sf = fabs((double)pHps->windowExt.cx / pHps->windowExt.cy);
408
409 if (xExt > (yExt * sf))
410 {
411 xExt = yExt * sf;
412
413 if ((double)LONG_MAX <= xExt) return (result);
414
415 if (pHps->viewportXExt < 0.0)
416 pHps->viewportXExt = -xExt;
417 else
418 pHps->viewportXExt = xExt;
419 }
420 else
421 {
422 yExt = xExt / sf;
423
424 if ((double)LONG_MAX <= yExt) return (result);
425
426 if (pHps->viewportYExt < 0.0)
427 pHps->viewportYExt = -yExt;
428 else
429 pHps->viewportYExt = yExt;
430 }
431 }
432 result = setPageXForm(wnd, pHps);
433
434 return (result);
435}
436
437LONG clientHeight(Win32BaseWindow *wnd, HWND hwnd, pDCData pHps)
438{
439 if ((hwnd == 0) && (pHps != 0))
440 hwnd = pHps->hwnd;
441
442 if ((hwnd != 0) || (pHps == 0))
443 {
444 if (wnd)
445 return (wnd->getWindowHeight());
446 else
447 return OSLibQueryScreenHeight();
448 }
449 else if (pHps->bitmapHandle)
450 {
451 return pHps->bitmapHeight;
452 }
453 else if (pHps->isMetaPS)
454 {
455 return 0;
456 }
457 else if (pHps->isPrinter)
458 {
459 return pHps->printPageHeight;
460 }
461 else
462 {
463 return MEM_HPS_MAX;
464 }
465}
466
467BOOL isYup (pDCData pHps)
468{
469 if (((pHps->windowExt.cy < 0) && (pHps->viewportYExt > 0.0)) ||
470 ((pHps->windowExt.cy > 0) && (pHps->viewportYExt < 0.0)))
471 {
472 if ((pHps->graphicsMode == GM_COMPATIBLE_W) ||
473 ((pHps->graphicsMode == GM_ADVANCED_W) && (pHps->xform.eM22 >= 0.0)))
474 return TRUE;
475 }
476 else
477 {
478 if ((pHps->graphicsMode == GM_ADVANCED_W) && (pHps->xform.eM22 < 0.0))
479 return TRUE;
480 }
481 return FALSE;
482}
483
484INT revertDy (Win32BaseWindow *wnd, INT dy)
485{
486 if (wnd->isOwnDC())
487 {
488 pDCData pHps = (pDCData)GpiQueryDCData (wnd->getOwnDC());
489
490 if (pHps != NULLHANDLE)
491 if (!isYup (pHps))
492 dy = -dy;
493 }
494 else
495 {
496 dy = -dy;
497 }
498 return (dy);
499}
500
501VOID removeClientArea(pDCData pHps)
502{
503 pHps->isClient = FALSE;
504
505 if (pHps->isClientArea)
506 {
507 pHps->isClientArea = FALSE;
508 GreSetupDC(pHps->hps,
509 pHps->hrgnVis,
510 pHps->ptlOrigin.x,
511 pHps->ptlOrigin.y,
512 0,
513 SETUPDC_ORIGIN | SETUPDC_VISRGN | SETUPDC_RECALCCLIP);
514 }
515}
516
517BOOL selectClientArea(Win32BaseWindow *wnd, pDCData pHps, PRECTL prclPaint)
518{
519 RECTL rcl;
520 HRGN hrgnRect;
521 HWND hwnd;
522
523 if (!wnd) return (FALSE);
524
525 pHps->isClient = TRUE;
526 hwnd = pHps->hwnd;
527
528 rcl.xLeft = rcl.yBottom = 0;
529 rcl.xRight = wnd->getWindowWidth();
530 rcl.yTop = wnd->getWindowHeight();
531
532 WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL) &rcl, 2);
533 pHps->ptlOrigin = *((PPOINTL) &rcl);
534
535 if (pHps->hrgnVis == 0)
536 pHps->hrgnVis = GreCreateRectRegion(pHps->hps, &rcl, 1);
537
538 hrgnRect = GreCreateRectRegion(pHps->hps, &rcl, 1);
539
540 if (!pHps->isClientArea)
541 GreCopyClipRegion(pHps->hps, pHps->hrgnVis, 0, COPYCRGN_VISRGN);
542
543 GreCombineRegion(pHps->hps, hrgnRect, pHps->hrgnVis, hrgnRect, CRGN_AND);
544 GreSetupDC(pHps->hps,
545 hrgnRect,
546 rcl.xLeft,
547 rcl.yBottom,
548 prclPaint,
549 SETUPDC_ORIGIN | SETUPDC_VISRGN | SETUPDC_RECALCCLIP);
550
551 pHps->isClientArea = TRUE;
552 GreDestroyRegion(pHps->hps, hrgnRect);
553
554 return (TRUE);
555}
556
557HDC sendEraseBkgnd (Win32BaseWindow *wnd)
558{
559 BOOL erased;
560 HWND hwnd;
561 HDC hdc;
562 HPS hps;
563 HRGN hrgnUpdate, hrgnOld, hrgnClip, hrgnCombined;
564 RECTL rectl = { 1, 1, 2, 2 };
565
566 hwnd = wnd->getOS2WindowHandle();
567 hps = WinGetPS(hwnd);
568
569 hrgnUpdate = GpiCreateRegion (hps, 1, &rectl);
570 WinQueryUpdateRegion (hwnd, hrgnUpdate);
571 hrgnClip = GpiQueryClipRegion (hps);
572
573 if (hrgnClip == NULLHANDLE)
574 {
575 GpiSetClipRegion (hps, hrgnUpdate, &hrgnOld);
576 }
577 else
578 {
579 hrgnCombined = GpiCreateRegion (hps, 1, &rectl);
580 GpiCombineRegion (hps, hrgnCombined, hrgnClip, hrgnUpdate, CRGN_AND);
581 GpiSetClipRegion (hps, hrgnCombined, &hrgnOld);
582 GpiDestroyRegion (hps, hrgnUpdate);
583 GpiDestroyRegion (hps, hrgnClip);
584 }
585 if (hrgnOld != NULLHANDLE)
586 GpiDestroyRegion (hps, hrgnOld);
587
588 hdc = HPSToHDC (hwnd, hps, NULL, NULL);
589
590 erased = wnd->MsgEraseBackGround (hdc);
591
592 DeleteHDC (hdc);
593 WinReleasePS (hps);
594
595 return erased;
596}
597
598void releaseOwnDC (HDC hps)
599{
600 pDCData pHps = (pDCData)GpiQueryDCData ((HPS)hps);
601
602 if (pHps) {
603 if (pHps->hrgnHDC)
604 GpiDestroyRegion (pHps->hps, pHps->hrgnHDC);
605
606 GpiSetBitmap (pHps->hps, NULL);
607 _O32_DeleteObject (pHps->nullBitmapHandle);
608 GpiDestroyPS(pHps->hps);
609
610 if (pHps->hdc)
611 DevCloseDC(pHps->hdc);
612
613// how can a memory chunk allocated by GpiAllocateDCData freed by delete?
614// delete pHps;
615 }
616}
617
618HDC WIN32API BeginPaint (HWND hWnd, PPAINTSTRUCT_W lpps)
619{
620 HWND hwnd = hWnd ? hWnd : HWND_DESKTOP;
621 pDCData pHps = NULLHANDLE;
622 RECTL rect;
623 HPS hPS_ownDC = NULLHANDLE;
624
625 dprintf (("USER32: BeginPaint(%x)", hWnd));
626
627 if ( !lpps )
628 {
629 _O32_SetLastError (ERROR_INVALID_PARAMETER);
630 return (HDC)NULLHANDLE;
631 }
632
633 USHORT sel = RestoreOS2FS();
634 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
635
636 if ((hwnd != HWND_DESKTOP) && wnd->isOwnDC())
637 {
638 hPS_ownDC = wnd->getOwnDC();
639 pHps = (pDCData)GpiQueryDCData(hPS_ownDC);
640 if (!pHps)
641 {
642 _O32_SetLastError (ERROR_INVALID_PARAMETER);
643 SetFS(sel);
644 return (HDC)NULLHANDLE;
645 }
646 }
647
648 HWND hwndClient = wnd->getOS2WindowHandle();
649 HPS hps = WinBeginPaint(hwndClient, hPS_ownDC, &rect);
650
651 if (!pHps)
652 {
653 HDC hdc = HPSToHDC (hwndClient, hps, NULL, NULL);
654 pHps = (pDCData)GpiQueryDCData(hps);
655 }
656
657 if (wnd->isFrameWindow())
658 {
659// WinSendMsg( hwnd, /* WM_DRAW */ 0x20D, (MPARAM)hps, MPVOID );
660 selectClientArea(wnd, pHps, &rect);
661 }
662
663 if (hPS_ownDC == 0)
664 setMapMode (wnd, pHps, MM_TEXT_W);
665 else
666 setPageXForm (wnd, pHps);
667
668 pHps->hdcType = TYPE_3;
669 lpps->hdc = (HDC)hps;
670
671 if (wnd->isEraseBkgnd())
672 wnd->setEraseBkgnd (FALSE, !wnd->MsgEraseBackGround(lpps->hdc));
673 wnd->setSupressErase (FALSE);
674 lpps->fErase = wnd->isPSErase();
675
676 if (!hPS_ownDC)
677 {
678 long height = wnd->getWindowHeight();
679 rect.yTop = height - rect.yTop;
680 rect.yBottom = height - rect.yBottom;
681 }
682 else
683 {
684 rect.yTop--;
685 rect.yBottom--;
686 GpiConvert(pHps->hps, CVTC_DEVICE, CVTC_WORLD, 2, (PPOINTL)&rect);
687 }
688
689 WINRECT_FROM_PMRECT(lpps->rcPaint, rect);
690
691 SetFS(sel);
692 _O32_SetLastError(0);
693 return (HDC)pHps->hps;
694}
695
696BOOL WIN32API EndPaint (HWND hwnd, const PAINTSTRUCT_W *pPaint)
697{
698dprintf (("USER32: EndPaint(%x)", hwnd));
699
700 if (!pPaint || !pPaint->hdc )
701 return TRUE;
702
703 USHORT sel = RestoreOS2FS();
704 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
705
706 if (!wnd) goto exit;
707
708 if (wnd->isOwnDC())
709 {
710 pDCData pHps = (pDCData)GpiQueryDCData((HPS)pPaint->hdc);
711 if (pHps && (pHps->hdcType == TYPE_3))
712 {
713 removeClientArea (pHps);
714 WinEndPaint (pHps->hps);
715 }
716 }
717 else
718 {
719 _O32_EndPaint (HWND_DESKTOP, pPaint);
720 }
721
722exit:
723 SetFS(sel);
724 _O32_SetLastError(0);
725 return TRUE;
726}
727
728BOOL WIN32API GetUpdateRect (HWND hwnd, LPRECT pRect, BOOL erase)
729{
730 if (hwnd)
731 {
732 _O32_SetLastError (ERROR_INVALID_HANDLE);
733 return FALSE;
734 }
735
736 RECTL rectl;
737 USHORT sel = RestoreOS2FS();
738 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
739
740 BOOL updateRegionExists = WinQueryUpdateRect (hwnd, pRect ? &rectl : NULL);
741 if (!pRect) {
742 SetFS(sel);
743 return (updateRegionExists);
744 }
745
746 if (updateRegionExists)
747 {
748 if (wnd->isOwnDC())
749 {
750 pDCData pHps = NULL;
751 pHps = (pDCData)GpiQueryDCData(wnd->getOwnDC());
752 if (!pHps)
753 {
754 _O32_SetLastError (ERROR_INVALID_HANDLE);
755 SetFS(sel);
756 return FALSE;
757 }
758 GpiConvert (pHps->hps, CVTC_DEVICE, CVTC_WORLD, 2, (PPOINTL)&rectl);
759 }
760 else
761 {
762 long height = wnd->getWindowHeight();
763 rectl.yTop = height - rectl.yTop;
764 rectl.yBottom = height - rectl.yBottom;
765 }
766
767 if (pRect)
768 WINRECT_FROM_PMRECT (*pRect, rectl);
769
770 if (erase)
771 sendEraseBkgnd (wnd);
772 }
773 else
774 {
775 if (pRect)
776 pRect->left = pRect->top = pRect->right = pRect->bottom = 0;
777 }
778
779 SetFS(sel);
780 return updateRegionExists;
781}
782
783int WIN32API GetUpdateRgn (HWND hwnd, HRGN hrgn, BOOL erase)
784{
785 USHORT sel = RestoreOS2FS();
786 LONG Complexity;
787
788 Complexity = _O32_GetUpdateRgn (hwnd, hrgn, FALSE);
789 if (erase && (Complexity > NULLREGION_W)) {
790 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
791 sendEraseBkgnd (wnd);
792 }
793
794 SetFS(sel);
795 return Complexity;
796}
797
798// This implementation of GetDCEx supports
799// DCX_WINDOW
800// DCX_CACHE
801// DCX_EXCLUDERGN (complex regions allowed)
802// DCX_INTERSECTRGN (complex regions allowed)
803
804HDC WIN32API GetDCEx (HWND hwnd, HRGN hrgn, ULONG flags)
805{
806 USHORT sel = RestoreOS2FS();
807 Win32BaseWindow *wnd = NULL;
808 HWND hWindow;
809 BOOL success;
810 pDCData pHps = NULL;
811 HPS hps = NULLHANDLE;
812 BOOL drawingAllowed = TRUE;
813 BOOL isWindowOwnDC;
814 BOOL creatingOwnDC = FALSE;
815 PS_Type psType;
816
817 if (hwnd)
818 {
819 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
820 if (flags & DCX_WINDOW_W)
821 hWindow = wnd->getOS2FrameWindowHandle();
822 else
823 hWindow = wnd->getOS2WindowHandle();
824 }
825 else
826 hWindow = HWND_DESKTOP;
827
828dprintf (("User32: GetDCEx hwnd %x (%x %x) -> wnd %x", hwnd, hrgn, flags, wnd));
829
830 isWindowOwnDC = (((hWindow == HWND_DESKTOP) ? FALSE : wnd->isOwnDC())
831 && !(flags & DCX_CACHE_W));
832 if (isWindowOwnDC)
833 {
834 hps = wnd->getOwnDC();
835 if (hps)
836 {
837 pDCData pHps = (pDCData)GpiQueryDCData (hps);
838 if (!pHps)
839 goto error;
840
841 if (flags & DCX_WINDOW_W)
842 removeClientArea (pHps);
843 else
844 selectClientArea (wnd, pHps, 0);
845
846 setPageXForm (wnd, pHps);
847
848 pHps->hdcType = TYPE_1;
849 SetFS(sel);
850 return (HDC)hps;
851 }
852 else
853 creatingOwnDC = TRUE;
854 }
855
856 if (isWindowOwnDC)
857 {
858 SIZEL sizel = {0,0};
859 hps = GpiCreatePS (WinQueryAnchorBlock (hWindow),
860 WinOpenWindowDC (hWindow),
861 &sizel, PU_PELS | GPIT_MICRO | GPIA_ASSOC );
862 psType = MICRO;
863 }
864 else
865 {
866 if (hWindow == HWND_DESKTOP)
867 hps = WinGetScreenPS (hWindow);
868 else
869 hps = WinGetPS (hWindow);
870
871 psType = MICRO_CACHED;
872 }
873
874 if (!hps)
875 goto error;
876
877 HPSToHDC (hWindow, hps, NULL, NULL);
878 pHps = (pDCData)GpiQueryDCData (hps);
879
880 if (!(flags & DCX_WINDOW_W)) {
881 if (selectClientArea (wnd, pHps, 0))
882 setMapMode (wnd, pHps, MM_TEXT_W);
883 }
884
885 if ((flags & DCX_EXCLUDERGN_W) || (flags & DCX_INTERSECTRGN_W))
886 {
887 ULONG BytesNeeded;
888 PRGNDATA_W RgnData;
889 PRECTL pr;
890 int i;
891 LONG height = OSLibQueryScreenHeight();
892
893 if (!hrgn)
894 goto error;
895
896 BytesNeeded = _O32_GetRegionData (hrgn, 0, NULL);
897 RgnData = (PRGNDATA_W)_alloca (BytesNeeded);
898 if (RgnData == NULL)
899 goto error;
900 _O32_GetRegionData (hrgn, BytesNeeded, RgnData);
901
902 i = RgnData->rdh.nCount;
903 pr = (PRECTL)(RgnData->Buffer);
904
905 success = TRUE;
906 if (flags & DCX_EXCLUDERGN_W)
907 for (; (i > 0) && success; i--, pr++) {
908 LONG y = pr->yBottom;
909
910 pr->yBottom = height - pr->yTop;
911 pr->yTop = height - y;
912 success &= GpiExcludeClipRectangle (pHps->hps, pr);
913 }
914 else
915 for (; (i > 0) && success; i--, pr++) {
916 LONG y = pr->yBottom;
917
918 pr->yBottom = height - pr->yTop;
919 pr->yTop = height - y;
920 success &= GpiIntersectClipRectangle (pHps->hps, pr);
921 }
922 if (!success)
923 goto error;
924 }
925
926 if (creatingOwnDC)
927 wnd->setOwnDC ((HDC)hps);
928
929 pHps->psType = psType;
930 pHps->hdcType = TYPE_1;
931 GpiSetDrawControl (hps, DCTL_DISPLAY, drawingAllowed ? DCTL_ON : DCTL_OFF);
932
933 SetFS(sel);
934 return (HDC)pHps->hps;
935
936error:
937 /* Something went wrong; clean up
938 */
939 if (pHps)
940 {
941 if (pHps->hps)
942 {
943 if(pHps->psType == MICRO_CACHED)
944 WinReleasePS(pHps->hps);
945 else
946 GpiDestroyPS(pHps->hps);
947 }
948
949 if (pHps->hdc) DevCloseDC(pHps->hdc);
950 if (pHps->hrgnHDC) GpiDestroyRegion(pHps->hps, pHps->hrgnHDC);
951
952 _O32_DeleteObject (pHps->nullBitmapHandle);
953 }
954 _O32_SetLastError (ERROR_INVALID_PARAMETER);
955 SetFS(sel);
956 return NULL;
957}
958
959HDC WIN32API GetDC (HWND hwnd)
960{
961 return GetDCEx (hwnd, NULL, 0);
962}
963
964HDC WIN32API GetWindowDC (HWND hwnd)
965{
966 return GetDCEx (hwnd, NULL, DCX_WINDOW_W);
967}
968
969int WIN32API ReleaseDC (HWND hwnd, HDC hdc)
970{
971 USHORT sel = RestoreOS2FS();
972 BOOL isOwnDC = FALSE;
973 int rc;
974
975 if (hwnd)
976 {
977 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
978 isOwnDC = wnd->isOwnDC();
979 }
980 if (isOwnDC)
981 rc = TRUE;
982 else
983 rc = _O32_ReleaseDC (0, hdc);
984
985 SetFS(sel);
986 dprintf(("ReleaseDC %x %x", hwnd, hdc));
987 return (rc);
988}
989
990BOOL WIN32API UpdateWindow (HWND hwnd)
991{
992 if (!hwnd)
993 return FALSE;
994
995 USHORT sel = RestoreOS2FS();
996 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
997
998dprintf (("User32: UpdateWindow hwnd %x -> wnd %x", hwnd, wnd));
999
1000 if (WinQueryUpdateRect (wnd->getOS2WindowHandle(), NULL))
1001 sendEraseBkgnd (wnd);
1002
1003 wnd->MsgPaint(0);
1004
1005 SetFS(sel);
1006 return (TRUE);
1007}
1008
1009// This implementation of RedrawWindow supports
1010// RDW_ERASE
1011// RDW_NOERASE
1012// RDW_INTERNALPAINT
1013// RDW_NOINTERNALPAINT
1014// RDW_INVALIDATE
1015// RDW_VALIDATE
1016// RDW_ERASENOW
1017// RDW_UPDATENOW
1018
1019BOOL WIN32API RedrawWindow (HWND hwnd, const RECT *pRect, HRGN hrgn, DWORD redraw)
1020{
1021 Win32BaseWindow *wnd;
1022
1023 if (redraw & (RDW_FRAME_W | RDW_NOFRAME_W))
1024 {
1025 _O32_SetLastError (ERROR_NOT_SUPPORTED);
1026 return FALSE;
1027 }
1028
1029 USHORT sel = RestoreOS2FS();
1030 dprintf(("USER32: RedrawWindow %X, %X %X %X", hwnd, pRect, hrgn, redraw));
1031
1032 if (hwnd == NULLHANDLE) {
1033 hwnd = HWND_DESKTOP;
1034 wnd = Win32BaseWindow::GetWindowFromOS2Handle(OSLIB_HWND_DESKTOP);
1035 }
1036 else
1037 {
1038 wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1039
1040 if (!wnd)
1041 {
1042 _O32_SetLastError (ERROR_INVALID_PARAMETER);
1043 SetFS(sel);
1044 return FALSE;
1045 }
1046 hwnd = wnd->getOS2WindowHandle();
1047 }
1048
1049 BOOL IncludeChildren = redraw & RDW_ALLCHILDREN_W ? TRUE : FALSE;
1050 BOOL success = TRUE;
1051 HPS hpsTemp = NULLHANDLE;
1052 HRGN hrgnTemp = NULLHANDLE;
1053 RECTL rectl;
1054
1055 if (redraw & RDW_UPDATENOW_W) redraw &= ~RDW_ERASENOW_W;
1056
1057 if (redraw & RDW_NOERASE_W)
1058 wnd->setEraseBkgnd (FALSE);
1059
1060 if (redraw & RDW_UPDATENOW_W)
1061 wnd->setSupressErase (FALSE);
1062 else if (redraw & RDW_ERASENOW_W)
1063 wnd->setSupressErase (FALSE);
1064#if 0
1065 else
1066 {
1067 QMSG qmsg;
1068 BOOL erase;
1069
1070 erase = (WinPeekMsg (HABX, &qmsg, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE)
1071 && (redraw & RDW_NOERASE_W) == 0);
1072
1073 wnd->setSupressErase (!erase);
1074 }
1075
1076 if (redraw & (RDW_NOINTERNALPAINT_W | RDW_INTERNALPAINT_W))
1077 {
1078 QMSG qmsg;
1079
1080 WinPeekMsg( (HAB)0, &qmsg, hwnd, WM_VIRTUAL_INTERNALPAINT,
1081 WM_VIRTUAL_INTERNALPAINT, PM_REMOVE );
1082 }
1083#endif
1084
1085 if (hrgn)
1086 {
1087 ULONG BytesNeeded;
1088 PRGNDATA_W RgnData;
1089 PRECTL pr;
1090 int i;
1091 LONG height = wnd ? wnd->getWindowHeight() : OSLibQueryScreenHeight();
1092
1093 if (!hrgn)
1094 goto error;
1095
1096 BytesNeeded = _O32_GetRegionData (hrgn, 0, NULL);
1097 RgnData = (PRGNDATA_W)_alloca (BytesNeeded);
1098 if (RgnData == NULL)
1099 goto error;
1100 _O32_GetRegionData (hrgn, BytesNeeded, RgnData);
1101
1102 pr = (PRECTL)(RgnData->Buffer);
1103 for (i = RgnData->rdh.nCount; i > 0; i--, pr++) {
1104 LONG temp = pr->yTop;
1105 pr->yTop = height - pr->yBottom;
1106 pr->yBottom = height - temp;
1107 }
1108
1109 hpsTemp = WinGetScreenPS (HWND_DESKTOP);
1110 hrgnTemp = GpiCreateRegion (hpsTemp, RgnData->rdh.nCount, (PRECTL)(RgnData->Buffer));
1111 if (!hrgnTemp) goto error;
1112 }
1113 else if (pRect)
1114 {
1115 LONG height = wnd ? wnd->getWindowHeight() : OSLibQueryScreenHeight();
1116
1117 PMRECT_FROM_WINRECT (rectl, *pRect);
1118 rectl.yTop = height - rectl.yTop;
1119 rectl.yBottom = height - rectl.yBottom;
1120 }
1121
1122 if (redraw & RDW_INVALIDATE_W)
1123 {
1124 if (redraw & RDW_ERASE_W)
1125 wnd->setEraseBkgnd (TRUE, TRUE);
1126
1127 if (!pRect && !hrgn)
1128 success = WinInvalidateRect (hwnd, NULL, IncludeChildren);
1129 else if (hrgn)
1130 success = WinInvalidateRegion (hwnd, hrgnTemp, IncludeChildren);
1131 else
1132 success = WinInvalidateRect (hwnd, &rectl, IncludeChildren);
1133 if (!success) goto error;
1134 }
1135 else if (redraw & RDW_VALIDATE_W)
1136 {
1137 if (WinQueryUpdateRect (hwnd, NULL))
1138 {
1139 if (!pRect && !hrgn)
1140 success = WinValidateRect (hwnd, NULL, IncludeChildren);
1141 else if (hrgn)
1142 success = WinValidateRegion (hwnd, hrgnTemp, IncludeChildren);
1143 else
1144 success = WinValidateRect (hwnd, &rectl, IncludeChildren);
1145 if (!success) goto error;
1146 }
1147 }
1148
1149 if (WinQueryUpdateRect (hwnd, NULL))
1150 {
1151 if (redraw & RDW_UPDATENOW_W)
1152 wnd->MsgPaint (0, FALSE);
1153
1154 else if ((redraw & RDW_ERASE_W) && (redraw & RDW_ERASENOW_W))
1155 wnd->setEraseBkgnd (FALSE, !sendEraseBkgnd (wnd));
1156 }
1157 else if ((redraw & RDW_INTERNALPAINT_W) && !(redraw & RDW_INVALIDATE_W))
1158 {
1159 if (redraw & RDW_UPDATENOW_W)
1160 wnd->MsgPaint (0, FALSE);
1161// else
1162// WinPostMsg( hwnd, WM_VIRTUAL_INTERNALPAINT, MPVOID, MPVOID );
1163 }
1164
1165error:
1166 /* clean up */
1167 if (hrgnTemp)
1168 GpiDestroyRegion (hpsTemp, hrgnTemp);
1169
1170 if (hpsTemp)
1171 WinReleasePS (hpsTemp);
1172
1173 if ((redraw & RDW_INVALIDATE_W) == 0)
1174 wnd->setSupressErase (FALSE);
1175 else if ((redraw & RDW_ERASENOW_W) == RDW_ERASENOW_W)
1176 wnd->setSupressErase (TRUE);
1177
1178 if (!success)
1179 _O32_SetLastError (ERROR_INVALID_PARAMETER);
1180
1181 SetFS(sel);
1182 return (success);
1183}
1184
1185BOOL WIN32API InvalidateRect (HWND hwnd, const RECT *pRect, BOOL erase)
1186{
1187 USHORT sel = RestoreOS2FS();
1188// Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1189 BOOL result;
1190
1191// todo !!
1192// if ( isFrame without client )
1193// erase = TRUE;
1194
1195 result = RedrawWindow (hwnd, pRect, NULLHANDLE,
1196 RDW_ALLCHILDREN_W | RDW_INVALIDATE_W |
1197 (erase ? RDW_ERASE_W : 0) |
1198 (hwnd == NULLHANDLE ? RDW_UPDATENOW_W : 0));
1199 SetFS(sel);
1200 return (result);
1201}
1202
1203BOOL WIN32API InvalidateRgn (HWND hwnd, HRGN hrgn, BOOL erase)
1204{
1205 USHORT sel = RestoreOS2FS();
1206// Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1207 BOOL result;
1208
1209// todo !!
1210// if ( isFrame without client )
1211// erase = TRUE;
1212
1213 result = RedrawWindow (hwnd, NULL, hrgn,
1214 RDW_ALLCHILDREN_W | RDW_INVALIDATE_W |
1215 (erase ? RDW_ERASE_W : 0) |
1216 (hwnd == NULLHANDLE ? RDW_UPDATENOW_W : 0));
1217 SetFS(sel);
1218 return (result);
1219}
1220
1221BOOL setPMRgnIntoWinRgn (HRGN hrgnPM, HRGN hrgnWin, LONG height)
1222{
1223 BOOL rc;
1224 HPS hps = WinGetScreenPS (HWND_DESKTOP);
1225 RGNRECT rgnRect;
1226 rgnRect.ircStart = 1;
1227 rgnRect.crc = 0;
1228 rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT; // doesn't make a difference because we're getting them all
1229
1230 rc = GpiQueryRegionRects (hps, hrgnPM, NULL, &rgnRect, NULL);
1231
1232 if (rc && (rgnRect.crcReturned > 0))
1233 {
1234 PRECTL Rcls = new RECTL[rgnRect.crcReturned];
1235 PRECTL pRcl = Rcls;
1236
1237 if (Rcls != NULL)
1238 {
1239 rgnRect.crc = rgnRect.crcReturned;
1240 rc = GpiQueryRegionRects (hps, hrgnPM, NULL, &rgnRect, Rcls);
1241
1242 rc = _O32_SetRectRgn (hrgnWin, pRcl->xLeft,
1243 pRcl->xRight,
1244 height - pRcl->yTop,
1245 height - pRcl->yBottom);
1246
1247 if (rgnRect.crcReturned > 1)
1248 {
1249 int i;
1250 HRGN temp;
1251 temp = _O32_CreateRectRgn (0, 0, 1, 1);
1252
1253 for (i = 1, pRcl++; rc && (i < rgnRect.crcReturned); i++, pRcl++)
1254 {
1255 rc = _O32_SetRectRgn (temp, pRcl->xLeft,
1256 pRcl->xRight,
1257 height - pRcl->yTop,
1258 height - pRcl->yBottom);
1259 rc &= _O32_CombineRgn (hrgnWin, hrgnWin, temp, RGN_OR_W);
1260 }
1261 _O32_DeleteObject (temp);
1262 }
1263 delete[] Rcls;
1264 }
1265 else
1266 {
1267 rc = FALSE;
1268 }
1269 }
1270 else
1271 {
1272 rc = _O32_SetRectRgn (hrgnWin, 0, 0, 0, 0);
1273 }
1274
1275 WinReleasePS (hps);
1276 return (rc);
1277}
1278
1279BOOL WIN32API ScrollDC (HDC hDC, int dx, int dy, const RECT *pScroll,
1280 const RECT *pClip, HRGN hrgnUpdate, LPRECT pRectUpdate)
1281{
1282 USHORT sel = RestoreOS2FS();
1283 BOOL rc = TRUE;
1284
1285 dprintf (("USER32: ScrollDC"));
1286
1287 if (!hDC)
1288 {
1289 SetFS(sel);
1290 return (FALSE);
1291 }
1292
1293 pDCData pHps = (pDCData)GpiQueryDCData ((HPS)hDC);
1294 HWND hwnd = pHps->hwnd;
1295 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1296
1297 if ((hwnd == NULLHANDLE) || !wnd)
1298 {
1299 SetFS(sel);
1300 return (FALSE);
1301 }
1302
1303 POINTL ptl[2] = { 0, 0, dx, dy };
1304
1305 GpiConvert (pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, ptl);
1306 dx = (int)(ptl[1].x - ptl[0].x);
1307 dy = (int)(ptl[1].y - ptl[0].y);
1308
1309 RECTL scrollRect;
1310 RECTL clipRect;
1311
1312 if (pClip)
1313 {
1314 clipRect.xLeft = min (pClip->left, pClip->right);
1315 clipRect.xRight = max (pClip->left, pClip->right);
1316 clipRect.yTop = max (pClip->top, pClip->bottom);
1317 clipRect.yBottom = min (pClip->top, pClip->bottom);
1318
1319 if ((pHps->graphicsMode == GM_COMPATIBLE_W) &&
1320 (clipRect.xLeft != clipRect.xRight) &&
1321 (clipRect.yBottom != clipRect.yTop))
1322 {
1323 if (abs((int)pHps->viewportXExt) <= abs((int)pHps->windowExt.cx))
1324 clipRect.xRight -= abs(pHps->worldXDeltaFor1Pixel);
1325 else
1326 clipRect.xLeft += abs(pHps->worldXDeltaFor1Pixel);
1327
1328 if (abs((int)pHps->viewportYExt) <= abs((int)pHps->windowExt.cy))
1329 clipRect.yTop -= abs(pHps->worldYDeltaFor1Pixel);
1330 else
1331 clipRect.yBottom += abs(pHps->worldYDeltaFor1Pixel);
1332 }
1333 GpiConvert (pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, (PPOINTL)&clipRect);
1334 if (clipRect.xRight < clipRect.xLeft) {
1335 ULONG temp = clipRect.xLeft;
1336 clipRect.xLeft = clipRect.xRight;
1337 clipRect.xRight = temp;
1338 }
1339 if (clipRect.yTop < clipRect.yBottom) {
1340 ULONG temp = clipRect.yBottom;
1341 clipRect.yBottom = clipRect.yTop;
1342 clipRect.yTop = temp;
1343 }
1344 }
1345
1346 if (pScroll)
1347 {
1348 scrollRect.xLeft = min (pScroll->left, pScroll->right);
1349 scrollRect.xRight = max (pScroll->left, pScroll->right);
1350 scrollRect.yTop = max (pScroll->top, pScroll->bottom);
1351 scrollRect.yBottom = min (pScroll->top, pScroll->bottom);
1352
1353 if ((pHps->graphicsMode == GM_COMPATIBLE_W) &&
1354 (scrollRect.xLeft != scrollRect.xRight) &&
1355 (scrollRect.yBottom != scrollRect.yTop))
1356 {
1357 if (abs((int)pHps->viewportXExt) <= abs((int)pHps->windowExt.cx))
1358 scrollRect.xRight -= abs(pHps->worldXDeltaFor1Pixel);
1359 else
1360 scrollRect.xLeft += abs(pHps->worldXDeltaFor1Pixel);
1361
1362 if (abs((int)pHps->viewportYExt) <= abs((int)pHps->windowExt.cy))
1363 scrollRect.yTop -= abs(pHps->worldYDeltaFor1Pixel);
1364 else
1365 scrollRect.yBottom += abs(pHps->worldYDeltaFor1Pixel);
1366 }
1367 GpiConvert (pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, (PPOINTL)&scrollRect);
1368 if (scrollRect.xRight < scrollRect.xLeft) {
1369 ULONG temp = scrollRect.xLeft;
1370 scrollRect.xLeft = scrollRect.xRight;
1371 scrollRect.xRight = temp;
1372 }
1373 if (scrollRect.yTop < scrollRect.yBottom) {
1374 ULONG temp = scrollRect.yBottom;
1375 scrollRect.yBottom = scrollRect.yTop;
1376 scrollRect.yTop = temp;
1377 }
1378 }
1379 RECTL rectlUpdate;
1380 HRGN hrgn;
1381
1382 LONG lComplexity = WinScrollWindow (hwnd, dx, dy, (pScroll) ? &scrollRect : NULL, (pClip) ? &clipRect : NULL, hrgn, &rectlUpdate, 0);
1383 if (lComplexity == RGN_ERROR)
1384 {
1385 SetFS(sel);
1386 return (FALSE);
1387 }
1388
1389 RECT winRectUpdate;
1390 LONG height = wnd->getWindowHeight();
1391
1392 winRectUpdate.left = rectlUpdate.xLeft;
1393 winRectUpdate.right = rectlUpdate.xRight;
1394 winRectUpdate.top = height - rectlUpdate.yTop;
1395 winRectUpdate.bottom = height - rectlUpdate.yBottom;
1396
1397 if (pRectUpdate)
1398 *pRectUpdate = winRectUpdate;
1399
1400 if (hrgnUpdate)
1401 rc = setPMRgnIntoWinRgn (hrgn, hrgnUpdate, height);
1402
1403 SetFS(sel);
1404 return (rc);
1405}
1406
1407//******************************************************************************
1408//******************************************************************************
1409BOOL WIN32API ScrollWindow(HWND hwnd, int dx, int dy, const RECT *pScroll, const RECT *pClip)
1410{
1411 USHORT sel = RestoreOS2FS();
1412 Win32BaseWindow *window;
1413 APIRET rc;
1414 RECTL clientRect;
1415 RECTL scrollRect;
1416 RECTL clipRect;
1417 PRECTL pScrollRect = NULL;
1418 PRECTL pClipRect = NULL;
1419 ULONG scrollFlags = SW_INVALIDATERGN;
1420
1421 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1422 if(!window) {
1423 dprintf(("ScrollWindow, window %x not found", hwnd));
1424 SetFS(sel);
1425 return 0;
1426 }
1427 dprintf(("ScrollWindow %x %d %d\n", hwnd, dx, dy));
1428 MapWin32ToOS2Rectl(window->getClientRect(), (PRECTLOS2)&clientRect);
1429 //Rectangle could be relative to parent window, so fix this
1430 if(clientRect.yBottom != 0) {
1431 clientRect.yTop -= clientRect.yBottom;
1432 clientRect.yBottom = 0;
1433 }
1434 if(clientRect.xLeft != 0) {
1435 clientRect.xRight -= clientRect.xLeft;
1436 clientRect.xLeft = 0;
1437 }
1438 if(pScroll) {
1439 MapWin32ToOS2Rectl((RECT *)pScroll, (PRECTLOS2)&scrollRect);
1440 pScrollRect = &scrollRect;
1441
1442 //Scroll rectangle relative to client area
1443 pScrollRect->xLeft += clientRect.xLeft;
1444 pScrollRect->xRight += clientRect.xLeft;
1445 pScrollRect->yTop += clientRect.yBottom;
1446 pScrollRect->yBottom += clientRect.yBottom;
1447 WinIntersectRect ((HAB) 0, pScrollRect, pScrollRect, &clientRect);
1448 }
1449 else scrollFlags |= SW_SCROLLCHILDREN;
1450
1451 if(pClip) {
1452 MapWin32ToOS2Rectl((RECT *)pClip, (PRECTLOS2)&clipRect);
1453 pClipRect = &clipRect;
1454
1455 //Clip rectangle relative to client area
1456 pClipRect->xLeft += clientRect.xLeft;
1457 pClipRect->xRight += clientRect.xLeft;
1458 pClipRect->yTop += clientRect.yBottom;
1459 pClipRect->yBottom += clientRect.yBottom;
1460 WinIntersectRect ((HAB) 0, pClipRect, pClipRect, &clientRect);
1461 }
1462
1463 dy = revertDy (window, dy);
1464
1465 rc = WinScrollWindow(window->getOS2WindowHandle(), dx, dy,
1466 pScrollRect, pClipRect, NULLHANDLE,
1467 NULL, scrollFlags);
1468
1469 SetFS(sel);
1470 return (rc != RGN_ERROR);
1471}
1472//******************************************************************************
1473//******************************************************************************
1474INT WIN32API ScrollWindowEx(HWND hwnd, int dx, int dy, const RECT *pScroll, const RECT *pClip,
1475 HRGN hrgnUpdate, PRECT pRectUpdate, UINT scrollFlag)
1476{
1477 USHORT sel = RestoreOS2FS();
1478 Win32BaseWindow *window;
1479 APIRET rc;
1480 RECTL scrollRect;
1481 RECTL clipRect;
1482 ULONG scrollFlags = 0;
1483 int regionType = ERROR_W;
1484
1485 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1486 if(!window) {
1487 dprintf(("ScrollWindowEx, window %x not found", hwnd));
1488 SetFS(sel);
1489 return 0;
1490 }
1491
1492 dprintf(("ScrollWindowEx %x %d %d\n", hwnd, dx, dy));
1493
1494 dy = revertDy (window, dy);
1495
1496 if (scrollFlag & SW_INVALIDATE_W) scrollFlags |= SW_INVALIDATERGN;
1497 if (scrollFlag & SW_SCROLLCHILDREN_W) scrollFlags |= SW_SCROLLCHILDREN;
1498
1499 if(pScroll) MapWin32ToOS2Rectl((RECT *)pScroll, (PRECTLOS2)&scrollRect);
1500 if(pClip) MapWin32ToOS2Rectl((RECT *)pClip, (PRECTLOS2)&clipRect);
1501
1502 RECTL rectlUpdate;
1503 HRGN hrgn;
1504
1505 LONG lComplexity = WinScrollWindow (window->getOS2WindowHandle(), dx, dy,
1506 (pScroll) ? &scrollRect : NULL,
1507 (pClip) ? &clipRect : NULL,
1508 hrgn, &rectlUpdate, scrollFlags);
1509 if (lComplexity == RGN_ERROR)
1510 {
1511 SetFS(sel);
1512 return (0);
1513 }
1514
1515 RECT winRectUpdate;
1516 LONG height = window->getWindowHeight();
1517
1518 winRectUpdate.left = rectlUpdate.xLeft;
1519 winRectUpdate.right = rectlUpdate.xRight;
1520 winRectUpdate.top = height - rectlUpdate.yTop;
1521 winRectUpdate.bottom = height - rectlUpdate.yBottom;
1522
1523 if (pRectUpdate)
1524 *pRectUpdate = winRectUpdate;
1525
1526 if (hrgnUpdate)
1527 rc = setPMRgnIntoWinRgn (hrgn, hrgnUpdate, height);
1528
1529 if ((scrollFlag & SW_INVALIDATE_W) &&
1530 ((lComplexity == RGN_RECT) || (lComplexity == RGN_COMPLEX)))
1531 {
1532 rc = InvalidateRect (hwnd, &winRectUpdate, scrollFlag & SW_ERASE_W);
1533 if (rc == FALSE)
1534 {
1535 SetFS(sel);
1536 return (0);
1537 }
1538 }
1539
1540 switch (lComplexity)
1541 {
1542 case RGN_NULL:
1543 regionType = NULLREGION_W;
1544 break;
1545 case RGN_RECT:
1546 regionType = SIMPLEREGION_W;
1547 break;
1548 case RGN_COMPLEX:
1549 regionType = COMPLEXREGION_W;
1550 break;
1551 default:
1552 regionType = ERROR_W;
1553 break;
1554 }
1555
1556 SetFS(sel);
1557 return (regionType);
1558}
1559//******************************************************************************
1560//******************************************************************************
Note: See TracBrowser for help on using the repository browser.