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

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

ScrollDC implemented

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