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

Last change on this file since 1351 was 1351, checked in by sandervl, 26 years ago

Listbox changes + EnumChildWindow rewrite

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