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

Last change on this file since 1333 was 1333, checked in by cbratschi, 26 years ago

added WINE scrollbars to frame, fixed pmframe, WM_ENTERIDLE

File size: 42.0 KB
Line 
1/* $Id: dc.cpp,v 1.14 1999-10-17 12:17:42 cbratschi 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
1008dprintf (("User32: UpdateWindow hwnd %x -> wnd %x", hwnd, wnd));
1009
1010 if (WinQueryUpdateRect (wnd->getOS2WindowHandle(), NULL))
1011 sendEraseBkgnd (wnd);
1012
1013 wnd->MsgPaint(0);
1014
1015 SetFS(sel);
1016 return (TRUE);
1017}
1018
1019// This implementation of RedrawWindow supports
1020// RDW_ERASE
1021// RDW_NOERASE
1022// RDW_INTERNALPAINT
1023// RDW_NOINTERNALPAINT
1024// RDW_INVALIDATE
1025// RDW_VALIDATE
1026// RDW_ERASENOW
1027// RDW_UPDATENOW
1028
1029ODINFUNCTION4(BOOL,RedrawWindow,HWND, hwnd,
1030 const RECT*, pRect,
1031 HRGN, hrgn,
1032 DWORD, redraw)
1033{
1034 Win32BaseWindow *wnd;
1035
1036 if (redraw & (RDW_FRAME_W | RDW_NOFRAME_W))
1037 {
1038 _O32_SetLastError (ERROR_NOT_SUPPORTED);
1039 return FALSE;
1040 }
1041
1042//@@@PH USHORT sel = RestoreOS2FS();
1043//@@@PH dprintf(("USER32: RedrawWindow %X, %X %X %X", hwnd, pRect, hrgn, redraw));
1044
1045 if (hwnd == NULLHANDLE)
1046 {
1047 hwnd = HWND_DESKTOP;
1048 wnd = Win32BaseWindow::GetWindowFromOS2Handle(OSLIB_HWND_DESKTOP);
1049
1050 if (!wnd)
1051 {
1052 dprintf(("USER32:dc: RedrawWindow can't find desktop window %08xh\n",
1053 hwnd));
1054 _O32_SetLastError (ERROR_INVALID_PARAMETER);
1055//@@@PH SetFS(sel);
1056 return FALSE;
1057 }
1058
1059 }
1060 else
1061 {
1062 wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1063
1064 if (!wnd)
1065 {
1066 dprintf(("USER32:dc: RedrawWindow can't find window %08xh\n",
1067 hwnd));
1068 _O32_SetLastError (ERROR_INVALID_PARAMETER);
1069//@@@PH SetFS(sel);
1070 return FALSE;
1071 }
1072 hwnd = wnd->getOS2WindowHandle();
1073 }
1074
1075 BOOL IncludeChildren = redraw & RDW_ALLCHILDREN_W ? TRUE : FALSE;
1076 BOOL success = TRUE;
1077 HPS hpsTemp = NULLHANDLE;
1078 HRGN hrgnTemp = NULLHANDLE;
1079 RECTL rectl;
1080
1081 if (redraw & RDW_UPDATENOW_W) redraw &= ~RDW_ERASENOW_W;
1082
1083 if (redraw & RDW_NOERASE_W)
1084 wnd->setEraseBkgnd (FALSE);
1085
1086 if (redraw & RDW_UPDATENOW_W)
1087 wnd->setSupressErase (FALSE);
1088 else if (redraw & RDW_ERASENOW_W)
1089 wnd->setSupressErase (FALSE);
1090#if 0
1091 else
1092 {
1093 QMSG qmsg;
1094 BOOL erase;
1095
1096 erase = (WinPeekMsg (HABX, &qmsg, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE)
1097 && (redraw & RDW_NOERASE_W) == 0);
1098
1099 wnd->setSupressErase (!erase);
1100 }
1101
1102 if (redraw & (RDW_NOINTERNALPAINT_W | RDW_INTERNALPAINT_W))
1103 {
1104 QMSG qmsg;
1105
1106 WinPeekMsg( (HAB)0, &qmsg, hwnd, WM_VIRTUAL_INTERNALPAINT,
1107 WM_VIRTUAL_INTERNALPAINT, PM_REMOVE );
1108 }
1109#endif
1110
1111 if (hrgn)
1112 {
1113 ULONG BytesNeeded;
1114 PRGNDATA_W RgnData;
1115 PRECTL pr;
1116 int i;
1117 LONG height = wnd ? wnd->getWindowHeight() : OSLibQueryScreenHeight();
1118
1119 if (!hrgn)
1120 goto error;
1121
1122 BytesNeeded = _O32_GetRegionData (hrgn, 0, NULL);
1123 RgnData = (PRGNDATA_W)_alloca (BytesNeeded);
1124 if (RgnData == NULL)
1125 goto error;
1126 _O32_GetRegionData (hrgn, BytesNeeded, RgnData);
1127
1128 pr = (PRECTL)(RgnData->Buffer);
1129 for (i = RgnData->rdh.nCount; i > 0; i--, pr++) {
1130 LONG temp = pr->yTop;
1131 pr->yTop = height - pr->yBottom;
1132 pr->yBottom = height - temp;
1133 }
1134
1135 hpsTemp = WinGetScreenPS (HWND_DESKTOP);
1136 hrgnTemp = GpiCreateRegion (hpsTemp, RgnData->rdh.nCount, (PRECTL)(RgnData->Buffer));
1137 if (!hrgnTemp) goto error;
1138 }
1139 else if (pRect)
1140 {
1141 LONG height = wnd ? wnd->getWindowHeight() : OSLibQueryScreenHeight();
1142
1143 PMRECT_FROM_WINRECT (rectl, *pRect);
1144 rectl.yTop = height - rectl.yTop;
1145 rectl.yBottom = height - rectl.yBottom;
1146 }
1147
1148 if (redraw & RDW_INVALIDATE_W)
1149 {
1150 if (redraw & RDW_ERASE_W)
1151 wnd->setEraseBkgnd (TRUE, TRUE);
1152
1153 if (!pRect && !hrgn)
1154 success = WinInvalidateRect (hwnd, NULL, IncludeChildren);
1155 else if (hrgn)
1156 success = WinInvalidateRegion (hwnd, hrgnTemp, IncludeChildren);
1157 else
1158 success = WinInvalidateRect (hwnd, &rectl, IncludeChildren);
1159 if (!success) goto error;
1160 }
1161 else if (redraw & RDW_VALIDATE_W)
1162 {
1163 if (WinQueryUpdateRect (hwnd, NULL))
1164 {
1165 if (!pRect && !hrgn)
1166 success = WinValidateRect (hwnd, NULL, IncludeChildren);
1167 else if (hrgn)
1168 success = WinValidateRegion (hwnd, hrgnTemp, IncludeChildren);
1169 else
1170 success = WinValidateRect (hwnd, &rectl, IncludeChildren);
1171 if (!success) goto error;
1172 }
1173 }
1174
1175 if (WinQueryUpdateRect (hwnd, NULL))
1176 {
1177 if (redraw & RDW_UPDATENOW_W)
1178 wnd->MsgPaint (0, FALSE);
1179
1180 else if ((redraw & RDW_ERASE_W) && (redraw & RDW_ERASENOW_W))
1181 wnd->setEraseBkgnd (FALSE, !sendEraseBkgnd (wnd));
1182 }
1183 else if ((redraw & RDW_INTERNALPAINT_W) && !(redraw & RDW_INVALIDATE_W))
1184 {
1185 if (redraw & RDW_UPDATENOW_W)
1186 wnd->MsgPaint (0, FALSE);
1187// else
1188// WinPostMsg( hwnd, WM_VIRTUAL_INTERNALPAINT, MPVOID, MPVOID );
1189 }
1190
1191error:
1192 /* clean up */
1193 if (hrgnTemp)
1194 GpiDestroyRegion (hpsTemp, hrgnTemp);
1195
1196 if (hpsTemp)
1197 WinReleasePS (hpsTemp);
1198
1199 if ((redraw & RDW_INVALIDATE_W) == 0)
1200 wnd->setSupressErase (FALSE);
1201 else if ((redraw & RDW_ERASENOW_W) == RDW_ERASENOW_W)
1202 wnd->setSupressErase (TRUE);
1203
1204 if (!success)
1205 _O32_SetLastError (ERROR_INVALID_PARAMETER);
1206
1207//@@@PH SetFS(sel);
1208 return (success);
1209}
1210
1211BOOL WIN32API InvalidateRect (HWND hwnd, const RECT *pRect, BOOL erase)
1212{
1213 USHORT sel = RestoreOS2FS();
1214// Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1215 BOOL result;
1216
1217// todo !!
1218// if ( isFrame without client )
1219// erase = TRUE;
1220
1221 result = RedrawWindow (hwnd, pRect, NULLHANDLE,
1222 RDW_ALLCHILDREN_W | RDW_INVALIDATE_W |
1223 (erase ? RDW_ERASE_W : 0) |
1224 (hwnd == NULLHANDLE ? RDW_UPDATENOW_W : 0));
1225 SetFS(sel);
1226 return (result);
1227}
1228
1229BOOL WIN32API InvalidateRgn (HWND hwnd, HRGN hrgn, BOOL erase)
1230{
1231 USHORT sel = RestoreOS2FS();
1232// Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1233 BOOL result;
1234
1235// todo !!
1236// if ( isFrame without client )
1237// erase = TRUE;
1238
1239 result = RedrawWindow (hwnd, NULL, hrgn,
1240 RDW_ALLCHILDREN_W | RDW_INVALIDATE_W |
1241 (erase ? RDW_ERASE_W : 0) |
1242 (hwnd == NULLHANDLE ? RDW_UPDATENOW_W : 0));
1243 SetFS(sel);
1244 return (result);
1245}
1246
1247BOOL setPMRgnIntoWinRgn (HRGN hrgnPM, HRGN hrgnWin, LONG height)
1248{
1249 BOOL rc;
1250 HPS hps = WinGetScreenPS (HWND_DESKTOP);
1251 RGNRECT rgnRect;
1252 rgnRect.ircStart = 1;
1253 rgnRect.crc = 0;
1254 rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT; // doesn't make a difference because we're getting them all
1255
1256 rc = GpiQueryRegionRects (hps, hrgnPM, NULL, &rgnRect, NULL);
1257
1258 if (rc && (rgnRect.crcReturned > 0))
1259 {
1260 PRECTL Rcls = new RECTL[rgnRect.crcReturned];
1261 PRECTL pRcl = Rcls;
1262
1263 if (Rcls != NULL)
1264 {
1265 rgnRect.crc = rgnRect.crcReturned;
1266 rc = GpiQueryRegionRects (hps, hrgnPM, NULL, &rgnRect, Rcls);
1267
1268 rc = _O32_SetRectRgn (hrgnWin, pRcl->xLeft,
1269 pRcl->xRight,
1270 height - pRcl->yTop,
1271 height - pRcl->yBottom);
1272
1273 if (rgnRect.crcReturned > 1)
1274 {
1275 int i;
1276 HRGN temp;
1277 temp = _O32_CreateRectRgn (0, 0, 1, 1);
1278
1279 for (i = 1, pRcl++; rc && (i < rgnRect.crcReturned); i++, pRcl++)
1280 {
1281 rc = _O32_SetRectRgn (temp, pRcl->xLeft,
1282 pRcl->xRight,
1283 height - pRcl->yTop,
1284 height - pRcl->yBottom);
1285 rc &= _O32_CombineRgn (hrgnWin, hrgnWin, temp, RGN_OR_W);
1286 }
1287 _O32_DeleteObject (temp);
1288 }
1289 delete[] Rcls;
1290 }
1291 else
1292 {
1293 rc = FALSE;
1294 }
1295 }
1296 else
1297 {
1298 rc = _O32_SetRectRgn (hrgnWin, 0, 0, 0, 0);
1299 }
1300
1301 WinReleasePS (hps);
1302 return (rc);
1303}
1304
1305BOOL WIN32API ScrollDC (HDC hDC, int dx, int dy, const RECT *pScroll,
1306 const RECT *pClip, HRGN hrgnUpdate, LPRECT pRectUpdate)
1307{
1308 USHORT sel = RestoreOS2FS();
1309 BOOL rc = TRUE;
1310
1311 dprintf (("USER32: ScrollDC"));
1312
1313 if (!hDC)
1314 {
1315 SetFS(sel);
1316 return (FALSE);
1317 }
1318
1319 pDCData pHps = (pDCData)GpiQueryDCData ((HPS)hDC);
1320 HWND hwnd = pHps->hwnd;
1321 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1322
1323 if ((hwnd == NULLHANDLE) || !wnd)
1324 {
1325 SetFS(sel);
1326 return (FALSE);
1327 }
1328
1329 POINTL ptl[2] = { 0, 0, dx, dy };
1330
1331 GpiConvert (pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, ptl);
1332 dx = (int)(ptl[1].x - ptl[0].x);
1333 dy = (int)(ptl[1].y - ptl[0].y);
1334
1335 RECTL scrollRect;
1336 RECTL clipRect;
1337
1338 if (pClip)
1339 {
1340 clipRect.xLeft = min (pClip->left, pClip->right);
1341 clipRect.xRight = max (pClip->left, pClip->right);
1342 clipRect.yTop = max (pClip->top, pClip->bottom);
1343 clipRect.yBottom = min (pClip->top, pClip->bottom);
1344
1345 if ((pHps->graphicsMode == GM_COMPATIBLE_W) &&
1346 (clipRect.xLeft != clipRect.xRight) &&
1347 (clipRect.yBottom != clipRect.yTop))
1348 {
1349 if (abs((int)pHps->viewportXExt) <= abs((int)pHps->windowExt.cx))
1350 clipRect.xRight -= abs(pHps->worldXDeltaFor1Pixel);
1351 else
1352 clipRect.xLeft += abs(pHps->worldXDeltaFor1Pixel);
1353
1354 if (abs((int)pHps->viewportYExt) <= abs((int)pHps->windowExt.cy))
1355 clipRect.yTop -= abs(pHps->worldYDeltaFor1Pixel);
1356 else
1357 clipRect.yBottom += abs(pHps->worldYDeltaFor1Pixel);
1358 }
1359 GpiConvert (pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, (PPOINTL)&clipRect);
1360 if (clipRect.xRight < clipRect.xLeft) {
1361 ULONG temp = clipRect.xLeft;
1362 clipRect.xLeft = clipRect.xRight;
1363 clipRect.xRight = temp;
1364 }
1365 if (clipRect.yTop < clipRect.yBottom) {
1366 ULONG temp = clipRect.yBottom;
1367 clipRect.yBottom = clipRect.yTop;
1368 clipRect.yTop = temp;
1369 }
1370 }
1371
1372 if (pScroll)
1373 {
1374 scrollRect.xLeft = min (pScroll->left, pScroll->right);
1375 scrollRect.xRight = max (pScroll->left, pScroll->right);
1376 scrollRect.yTop = max (pScroll->top, pScroll->bottom);
1377 scrollRect.yBottom = min (pScroll->top, pScroll->bottom);
1378
1379 if ((pHps->graphicsMode == GM_COMPATIBLE_W) &&
1380 (scrollRect.xLeft != scrollRect.xRight) &&
1381 (scrollRect.yBottom != scrollRect.yTop))
1382 {
1383 if (abs((int)pHps->viewportXExt) <= abs((int)pHps->windowExt.cx))
1384 scrollRect.xRight -= abs(pHps->worldXDeltaFor1Pixel);
1385 else
1386 scrollRect.xLeft += abs(pHps->worldXDeltaFor1Pixel);
1387
1388 if (abs((int)pHps->viewportYExt) <= abs((int)pHps->windowExt.cy))
1389 scrollRect.yTop -= abs(pHps->worldYDeltaFor1Pixel);
1390 else
1391 scrollRect.yBottom += abs(pHps->worldYDeltaFor1Pixel);
1392 }
1393 GpiConvert (pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, (PPOINTL)&scrollRect);
1394 if (scrollRect.xRight < scrollRect.xLeft) {
1395 ULONG temp = scrollRect.xLeft;
1396 scrollRect.xLeft = scrollRect.xRight;
1397 scrollRect.xRight = temp;
1398 }
1399 if (scrollRect.yTop < scrollRect.yBottom) {
1400 ULONG temp = scrollRect.yBottom;
1401 scrollRect.yBottom = scrollRect.yTop;
1402 scrollRect.yTop = temp;
1403 }
1404 }
1405 RECTL rectlUpdate;
1406 HRGN hrgn;
1407
1408 LONG lComplexity = WinScrollWindow (hwnd, dx, dy, (pScroll) ? &scrollRect : NULL, (pClip) ? &clipRect : NULL, hrgn, &rectlUpdate, 0);
1409 if (lComplexity == RGN_ERROR)
1410 {
1411 SetFS(sel);
1412 return (FALSE);
1413 }
1414
1415 RECT winRectUpdate;
1416 LONG height = wnd->getWindowHeight();
1417
1418 winRectUpdate.left = rectlUpdate.xLeft;
1419 winRectUpdate.right = rectlUpdate.xRight;
1420 winRectUpdate.top = height - rectlUpdate.yTop;
1421 winRectUpdate.bottom = height - rectlUpdate.yBottom;
1422
1423 if (pRectUpdate)
1424 *pRectUpdate = winRectUpdate;
1425
1426 if (hrgnUpdate)
1427 rc = setPMRgnIntoWinRgn (hrgn, hrgnUpdate, height);
1428
1429 SetFS(sel);
1430 return (rc);
1431}
1432
1433//******************************************************************************
1434//******************************************************************************
1435BOOL WIN32API ScrollWindow(HWND hwnd, int dx, int dy, const RECT *pScroll, const RECT *pClip)
1436{
1437 USHORT sel = RestoreOS2FS();
1438 Win32BaseWindow *window;
1439 APIRET rc;
1440 RECTL clientRect;
1441 RECTL scrollRect;
1442 RECTL clipRect;
1443 PRECTL pScrollRect = NULL;
1444 PRECTL pClipRect = NULL;
1445 ULONG scrollFlags = SW_INVALIDATERGN;
1446
1447 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1448 if(!window) {
1449 dprintf(("ScrollWindow, window %x not found", hwnd));
1450 SetFS(sel);
1451 return 0;
1452 }
1453 dprintf(("ScrollWindow %x %d %d\n", hwnd, dx, dy));
1454 MapWin32ToOS2Rectl(window->getClientRect(), (PRECTLOS2)&clientRect);
1455 //Rectangle could be relative to parent window, so fix this
1456 if(clientRect.yBottom != 0) {
1457 clientRect.yTop -= clientRect.yBottom;
1458 clientRect.yBottom = 0;
1459 }
1460 if(clientRect.xLeft != 0) {
1461 clientRect.xRight -= clientRect.xLeft;
1462 clientRect.xLeft = 0;
1463 }
1464 if(pScroll) {
1465 MapWin32ToOS2Rectl((RECT *)pScroll, (PRECTLOS2)&scrollRect);
1466 pScrollRect = &scrollRect;
1467
1468 //Scroll rectangle relative to client area
1469 pScrollRect->xLeft += clientRect.xLeft;
1470 pScrollRect->xRight += clientRect.xLeft;
1471 pScrollRect->yTop += clientRect.yBottom;
1472 pScrollRect->yBottom += clientRect.yBottom;
1473 WinIntersectRect ((HAB) 0, pScrollRect, pScrollRect, &clientRect);
1474 }
1475 else scrollFlags |= SW_SCROLLCHILDREN;
1476
1477 if(pClip) {
1478 MapWin32ToOS2Rectl((RECT *)pClip, (PRECTLOS2)&clipRect);
1479 pClipRect = &clipRect;
1480
1481 //Clip rectangle relative to client area
1482 pClipRect->xLeft += clientRect.xLeft;
1483 pClipRect->xRight += clientRect.xLeft;
1484 pClipRect->yTop += clientRect.yBottom;
1485 pClipRect->yBottom += clientRect.yBottom;
1486 WinIntersectRect ((HAB) 0, pClipRect, pClipRect, &clientRect);
1487 }
1488
1489 dy = revertDy (window, dy);
1490
1491 rc = WinScrollWindow(window->getOS2WindowHandle(), dx, dy,
1492 pScrollRect, pClipRect, NULLHANDLE,
1493 NULL, scrollFlags);
1494
1495 SetFS(sel);
1496 return (rc != RGN_ERROR);
1497}
1498//******************************************************************************
1499//******************************************************************************
1500INT WIN32API ScrollWindowEx(HWND hwnd, int dx, int dy, const RECT *pScroll, const RECT *pClip,
1501 HRGN hrgnUpdate, PRECT pRectUpdate, UINT scrollFlag)
1502{
1503 USHORT sel = RestoreOS2FS();
1504 Win32BaseWindow *window;
1505 APIRET rc;
1506 RECTL scrollRect;
1507 RECTL clipRect;
1508 ULONG scrollFlags = 0;
1509 int regionType = ERROR_W;
1510
1511 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1512 if(!window) {
1513 dprintf(("ScrollWindowEx, window %x not found", hwnd));
1514 SetFS(sel);
1515 return 0;
1516 }
1517
1518 dprintf(("ScrollWindowEx %x %d %d\n", hwnd, dx, dy));
1519
1520 dy = revertDy (window, dy);
1521
1522 if (scrollFlag & SW_INVALIDATE_W) scrollFlags |= SW_INVALIDATERGN;
1523 if (scrollFlag & SW_SCROLLCHILDREN_W) scrollFlags |= SW_SCROLLCHILDREN;
1524
1525 if(pScroll) MapWin32ToOS2Rectl((RECT *)pScroll, (PRECTLOS2)&scrollRect);
1526 if(pClip) MapWin32ToOS2Rectl((RECT *)pClip, (PRECTLOS2)&clipRect);
1527
1528 RECTL rectlUpdate;
1529 HRGN hrgn;
1530
1531 LONG lComplexity = WinScrollWindow (window->getOS2WindowHandle(), dx, dy,
1532 (pScroll) ? &scrollRect : NULL,
1533 (pClip) ? &clipRect : NULL,
1534 hrgn, &rectlUpdate, scrollFlags);
1535 if (lComplexity == RGN_ERROR)
1536 {
1537 SetFS(sel);
1538 return (0);
1539 }
1540
1541 RECT winRectUpdate;
1542 LONG height = window->getWindowHeight();
1543
1544 winRectUpdate.left = rectlUpdate.xLeft;
1545 winRectUpdate.right = rectlUpdate.xRight;
1546 winRectUpdate.top = height - rectlUpdate.yTop;
1547 winRectUpdate.bottom = height - rectlUpdate.yBottom;
1548
1549 if (pRectUpdate)
1550 *pRectUpdate = winRectUpdate;
1551
1552 if (hrgnUpdate)
1553 rc = setPMRgnIntoWinRgn (hrgn, hrgnUpdate, height);
1554
1555 if ((scrollFlag & SW_INVALIDATE_W) &&
1556 ((lComplexity == RGN_RECT) || (lComplexity == RGN_COMPLEX)))
1557 {
1558 rc = InvalidateRect (hwnd, &winRectUpdate, scrollFlag & SW_ERASE_W);
1559 if (rc == FALSE)
1560 {
1561 SetFS(sel);
1562 return (0);
1563 }
1564 }
1565
1566 switch (lComplexity)
1567 {
1568 case RGN_NULL:
1569 regionType = NULLREGION_W;
1570 break;
1571 case RGN_RECT:
1572 regionType = SIMPLEREGION_W;
1573 break;
1574 case RGN_COMPLEX:
1575 regionType = COMPLEXREGION_W;
1576 break;
1577 default:
1578 regionType = ERROR_W;
1579 break;
1580 }
1581
1582 SetFS(sel);
1583 return (regionType);
1584}
1585//******************************************************************************
1586//******************************************************************************
Note: See TracBrowser for help on using the repository browser.