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

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

Window creation rewrite + bugfixes. NOT WORKING CORRECTLY YET..

File size: 41.9 KB
Line 
1/* $Id: dc.cpp,v 1.13 1999-10-14 09:22:38 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 selectClientArea(wnd, pHps, &rect);
670// }
671
672 if (hPS_ownDC == 0)
673 setMapMode (wnd, pHps, MM_TEXT_W);
674 else
675 setPageXForm (wnd, pHps);
676
677 pHps->hdcType = TYPE_3;
678 lpps->hdc = (HDC)hps;
679
680 if (wnd->isEraseBkgnd())
681 wnd->setEraseBkgnd (FALSE, !wnd->MsgEraseBackGround(lpps->hdc));
682 wnd->setSupressErase (FALSE);
683 lpps->fErase = wnd->isPSErase();
684
685 if (!hPS_ownDC)
686 {
687 long height = wnd->getWindowHeight();
688 rect.yTop = height - rect.yTop;
689 rect.yBottom = height - rect.yBottom;
690 }
691 else
692 {
693 rect.yTop--;
694 rect.yBottom--;
695 GpiConvert(pHps->hps, CVTC_DEVICE, CVTC_WORLD, 2, (PPOINTL)&rect);
696 }
697
698 WINRECT_FROM_PMRECT(lpps->rcPaint, rect);
699
700 SetFS(sel);
701 _O32_SetLastError(0);
702 return (HDC)pHps->hps;
703}
704
705BOOL WIN32API EndPaint (HWND hwnd, const PAINTSTRUCT_W *pPaint)
706{
707dprintf (("USER32: EndPaint(%x)", hwnd));
708
709 if (!pPaint || !pPaint->hdc )
710 return TRUE;
711
712 USHORT sel = RestoreOS2FS();
713 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
714
715 if (!wnd) goto exit;
716
717 if (wnd->isOwnDC())
718 {
719 pDCData pHps = (pDCData)GpiQueryDCData((HPS)pPaint->hdc);
720 if (pHps && (pHps->hdcType == TYPE_3))
721 {
722 removeClientArea (pHps);
723 WinEndPaint (pHps->hps);
724 }
725 }
726 else
727 {
728 _O32_EndPaint (HWND_DESKTOP, pPaint);
729 }
730
731exit:
732 SetFS(sel);
733 _O32_SetLastError(0);
734 return TRUE;
735}
736
737BOOL WIN32API GetUpdateRect (HWND hwnd, LPRECT pRect, BOOL erase)
738{
739 if (hwnd)
740 {
741 _O32_SetLastError (ERROR_INVALID_HANDLE);
742 return FALSE;
743 }
744
745 RECTL rectl;
746 USHORT sel = RestoreOS2FS();
747 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
748
749 BOOL updateRegionExists = WinQueryUpdateRect (hwnd, pRect ? &rectl : NULL);
750 if (!pRect) {
751 SetFS(sel);
752 return (updateRegionExists);
753 }
754
755 if (updateRegionExists)
756 {
757 if (wnd->isOwnDC())
758 {
759 pDCData pHps = NULL;
760 pHps = (pDCData)GpiQueryDCData(wnd->getOwnDC());
761 if (!pHps)
762 {
763 _O32_SetLastError (ERROR_INVALID_HANDLE);
764 SetFS(sel);
765 return FALSE;
766 }
767 GpiConvert (pHps->hps, CVTC_DEVICE, CVTC_WORLD, 2, (PPOINTL)&rectl);
768 }
769 else
770 {
771 long height = wnd->getWindowHeight();
772 rectl.yTop = height - rectl.yTop;
773 rectl.yBottom = height - rectl.yBottom;
774 }
775
776 if (pRect)
777 WINRECT_FROM_PMRECT (*pRect, rectl);
778
779 if (erase)
780 sendEraseBkgnd (wnd);
781 }
782 else
783 {
784 if (pRect)
785 pRect->left = pRect->top = pRect->right = pRect->bottom = 0;
786 }
787
788 SetFS(sel);
789 return updateRegionExists;
790}
791
792int WIN32API GetUpdateRgn (HWND hwnd, HRGN hrgn, BOOL erase)
793{
794 USHORT sel = RestoreOS2FS();
795 LONG Complexity;
796
797 Complexity = _O32_GetUpdateRgn (hwnd, hrgn, FALSE);
798 if (erase && (Complexity > NULLREGION_W)) {
799 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
800 sendEraseBkgnd (wnd);
801 }
802
803 SetFS(sel);
804 return Complexity;
805}
806
807// This implementation of GetDCEx supports
808// DCX_WINDOW
809// DCX_CACHE
810// DCX_EXCLUDERGN (complex regions allowed)
811// DCX_INTERSECTRGN (complex regions allowed)
812
813HDC WIN32API GetDCEx (HWND hwnd, HRGN hrgn, ULONG flags)
814{
815 USHORT sel = RestoreOS2FS();
816 Win32BaseWindow *wnd = NULL;
817 HWND hWindow;
818 BOOL success;
819 pDCData pHps = NULL;
820 HPS hps = NULLHANDLE;
821 BOOL drawingAllowed = TRUE;
822 BOOL isWindowOwnDC;
823 BOOL creatingOwnDC = FALSE;
824 PS_Type psType;
825
826 if (hwnd)
827 {
828 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
829 if (flags & DCX_WINDOW_W)
830 hWindow = wnd->getOS2FrameWindowHandle();
831 else
832 hWindow = wnd->getOS2WindowHandle();
833 }
834 else
835 hWindow = HWND_DESKTOP;
836
837dprintf (("User32: GetDCEx hwnd %x (%x %x) -> wnd %x", hwnd, hrgn, flags, wnd));
838
839 isWindowOwnDC = (((hWindow == HWND_DESKTOP) ? FALSE : wnd->isOwnDC())
840 && !(flags & DCX_CACHE_W));
841 if (isWindowOwnDC)
842 {
843 hps = wnd->getOwnDC();
844 if (hps)
845 {
846 pDCData pHps = (pDCData)GpiQueryDCData (hps);
847 if (!pHps)
848 goto error;
849
850 if (flags & DCX_WINDOW_W)
851 removeClientArea (pHps);
852 else
853 selectClientArea (wnd, pHps, 0);
854
855 setPageXForm (wnd, pHps);
856
857 pHps->hdcType = TYPE_1;
858 SetFS(sel);
859 return (HDC)hps;
860 }
861 else
862 creatingOwnDC = TRUE;
863 }
864
865 if (isWindowOwnDC)
866 {
867 SIZEL sizel = {0,0};
868 hps = GpiCreatePS (WinQueryAnchorBlock (hWindow),
869 WinOpenWindowDC (hWindow),
870 &sizel, PU_PELS | GPIT_MICRO | GPIA_ASSOC );
871 psType = MICRO;
872 }
873 else
874 {
875 if (hWindow == HWND_DESKTOP)
876 hps = WinGetScreenPS (hWindow);
877 else
878 hps = WinGetPS (hWindow);
879
880 psType = MICRO_CACHED;
881 }
882
883 if (!hps)
884 goto error;
885
886 HPSToHDC (hWindow, hps, NULL, NULL);
887 pHps = (pDCData)GpiQueryDCData (hps);
888
889 if (!(flags & DCX_WINDOW_W)) {
890 if (selectClientArea (wnd, pHps, 0))
891 setMapMode (wnd, pHps, MM_TEXT_W);
892 }
893
894 if ((flags & DCX_EXCLUDERGN_W) || (flags & DCX_INTERSECTRGN_W))
895 {
896 ULONG BytesNeeded;
897 PRGNDATA_W RgnData;
898 PRECTL pr;
899 int i;
900 LONG height = OSLibQueryScreenHeight();
901
902 if (!hrgn)
903 goto error;
904
905 BytesNeeded = _O32_GetRegionData (hrgn, 0, NULL);
906 RgnData = (PRGNDATA_W)_alloca (BytesNeeded);
907 if (RgnData == NULL)
908 goto error;
909 _O32_GetRegionData (hrgn, BytesNeeded, RgnData);
910
911 i = RgnData->rdh.nCount;
912 pr = (PRECTL)(RgnData->Buffer);
913
914 success = TRUE;
915 if (flags & DCX_EXCLUDERGN_W)
916 for (; (i > 0) && success; i--, pr++) {
917 LONG y = pr->yBottom;
918
919 pr->yBottom = height - pr->yTop;
920 pr->yTop = height - y;
921 success &= GpiExcludeClipRectangle (pHps->hps, pr);
922 }
923 else
924 for (; (i > 0) && success; i--, pr++) {
925 LONG y = pr->yBottom;
926
927 pr->yBottom = height - pr->yTop;
928 pr->yTop = height - y;
929 success &= GpiIntersectClipRectangle (pHps->hps, pr);
930 }
931 if (!success)
932 goto error;
933 }
934
935 if (creatingOwnDC)
936 wnd->setOwnDC ((HDC)hps);
937
938 pHps->psType = psType;
939 pHps->hdcType = TYPE_1;
940 GpiSetDrawControl (hps, DCTL_DISPLAY, drawingAllowed ? DCTL_ON : DCTL_OFF);
941
942 SetFS(sel);
943 return (HDC)pHps->hps;
944
945error:
946 /* Something went wrong; clean up
947 */
948 if (pHps)
949 {
950 if (pHps->hps)
951 {
952 if(pHps->psType == MICRO_CACHED)
953 WinReleasePS(pHps->hps);
954 else
955 GpiDestroyPS(pHps->hps);
956 }
957
958 if (pHps->hdc) DevCloseDC(pHps->hdc);
959 if (pHps->hrgnHDC) GpiDestroyRegion(pHps->hps, pHps->hrgnHDC);
960
961 _O32_DeleteObject (pHps->nullBitmapHandle);
962 }
963 _O32_SetLastError (ERROR_INVALID_PARAMETER);
964 SetFS(sel);
965 return NULL;
966}
967
968HDC WIN32API GetDC (HWND hwnd)
969{
970 return GetDCEx (hwnd, NULL, 0);
971}
972
973HDC WIN32API GetWindowDC (HWND hwnd)
974{
975 return GetDCEx (hwnd, NULL, DCX_WINDOW_W);
976}
977
978int WIN32API ReleaseDC (HWND hwnd, HDC hdc)
979{
980 USHORT sel = RestoreOS2FS();
981 BOOL isOwnDC = FALSE;
982 int rc;
983
984 if (hwnd)
985 {
986 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
987 isOwnDC = wnd->isOwnDC();
988 }
989 if (isOwnDC)
990 rc = TRUE;
991 else
992 rc = _O32_ReleaseDC (0, hdc);
993
994 SetFS(sel);
995 dprintf(("ReleaseDC %x %x", hwnd, hdc));
996 return (rc);
997}
998
999BOOL WIN32API UpdateWindow (HWND hwnd)
1000{
1001 if (!hwnd)
1002 return FALSE;
1003
1004 USHORT sel = RestoreOS2FS();
1005 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1006
1007dprintf (("User32: UpdateWindow hwnd %x -> wnd %x", hwnd, wnd));
1008
1009 if (WinQueryUpdateRect (wnd->getOS2WindowHandle(), NULL))
1010 sendEraseBkgnd (wnd);
1011
1012 wnd->MsgPaint(0);
1013
1014 SetFS(sel);
1015 return (TRUE);
1016}
1017
1018// This implementation of RedrawWindow supports
1019// RDW_ERASE
1020// RDW_NOERASE
1021// RDW_INTERNALPAINT
1022// RDW_NOINTERNALPAINT
1023// RDW_INVALIDATE
1024// RDW_VALIDATE
1025// RDW_ERASENOW
1026// RDW_UPDATENOW
1027
1028ODINFUNCTION4(BOOL,RedrawWindow,HWND, hwnd,
1029 const RECT*, pRect,
1030 HRGN, hrgn,
1031 DWORD, redraw)
1032{
1033 Win32BaseWindow *wnd;
1034
1035 if (redraw & (RDW_FRAME_W | RDW_NOFRAME_W))
1036 {
1037 _O32_SetLastError (ERROR_NOT_SUPPORTED);
1038 return FALSE;
1039 }
1040
1041//@@@PH USHORT sel = RestoreOS2FS();
1042//@@@PH dprintf(("USER32: RedrawWindow %X, %X %X %X", hwnd, pRect, hrgn, redraw));
1043
1044 if (hwnd == NULLHANDLE)
1045 {
1046 hwnd = HWND_DESKTOP;
1047 wnd = Win32BaseWindow::GetWindowFromOS2Handle(OSLIB_HWND_DESKTOP);
1048
1049 if (!wnd)
1050 {
1051 dprintf(("USER32:dc: RedrawWindow can't find desktop window %08xh\n",
1052 hwnd));
1053 _O32_SetLastError (ERROR_INVALID_PARAMETER);
1054//@@@PH SetFS(sel);
1055 return FALSE;
1056 }
1057
1058 }
1059 else
1060 {
1061 wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1062
1063 if (!wnd)
1064 {
1065 dprintf(("USER32:dc: RedrawWindow can't find window %08xh\n",
1066 hwnd));
1067 _O32_SetLastError (ERROR_INVALID_PARAMETER);
1068//@@@PH SetFS(sel);
1069 return FALSE;
1070 }
1071 hwnd = wnd->getOS2WindowHandle();
1072 }
1073
1074 BOOL IncludeChildren = redraw & RDW_ALLCHILDREN_W ? TRUE : FALSE;
1075 BOOL success = TRUE;
1076 HPS hpsTemp = NULLHANDLE;
1077 HRGN hrgnTemp = NULLHANDLE;
1078 RECTL rectl;
1079
1080 if (redraw & RDW_UPDATENOW_W) redraw &= ~RDW_ERASENOW_W;
1081
1082 if (redraw & RDW_NOERASE_W)
1083 wnd->setEraseBkgnd (FALSE);
1084
1085 if (redraw & RDW_UPDATENOW_W)
1086 wnd->setSupressErase (FALSE);
1087 else if (redraw & RDW_ERASENOW_W)
1088 wnd->setSupressErase (FALSE);
1089#if 0
1090 else
1091 {
1092 QMSG qmsg;
1093 BOOL erase;
1094
1095 erase = (WinPeekMsg (HABX, &qmsg, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE)
1096 && (redraw & RDW_NOERASE_W) == 0);
1097
1098 wnd->setSupressErase (!erase);
1099 }
1100
1101 if (redraw & (RDW_NOINTERNALPAINT_W | RDW_INTERNALPAINT_W))
1102 {
1103 QMSG qmsg;
1104
1105 WinPeekMsg( (HAB)0, &qmsg, hwnd, WM_VIRTUAL_INTERNALPAINT,
1106 WM_VIRTUAL_INTERNALPAINT, PM_REMOVE );
1107 }
1108#endif
1109
1110 if (hrgn)
1111 {
1112 ULONG BytesNeeded;
1113 PRGNDATA_W RgnData;
1114 PRECTL pr;
1115 int i;
1116 LONG height = wnd ? wnd->getWindowHeight() : OSLibQueryScreenHeight();
1117
1118 if (!hrgn)
1119 goto error;
1120
1121 BytesNeeded = _O32_GetRegionData (hrgn, 0, NULL);
1122 RgnData = (PRGNDATA_W)_alloca (BytesNeeded);
1123 if (RgnData == NULL)
1124 goto error;
1125 _O32_GetRegionData (hrgn, BytesNeeded, RgnData);
1126
1127 pr = (PRECTL)(RgnData->Buffer);
1128 for (i = RgnData->rdh.nCount; i > 0; i--, pr++) {
1129 LONG temp = pr->yTop;
1130 pr->yTop = height - pr->yBottom;
1131 pr->yBottom = height - temp;
1132 }
1133
1134 hpsTemp = WinGetScreenPS (HWND_DESKTOP);
1135 hrgnTemp = GpiCreateRegion (hpsTemp, RgnData->rdh.nCount, (PRECTL)(RgnData->Buffer));
1136 if (!hrgnTemp) goto error;
1137 }
1138 else if (pRect)
1139 {
1140 LONG height = wnd ? wnd->getWindowHeight() : OSLibQueryScreenHeight();
1141
1142 PMRECT_FROM_WINRECT (rectl, *pRect);
1143 rectl.yTop = height - rectl.yTop;
1144 rectl.yBottom = height - rectl.yBottom;
1145 }
1146
1147 if (redraw & RDW_INVALIDATE_W)
1148 {
1149 if (redraw & RDW_ERASE_W)
1150 wnd->setEraseBkgnd (TRUE, TRUE);
1151
1152 if (!pRect && !hrgn)
1153 success = WinInvalidateRect (hwnd, NULL, IncludeChildren);
1154 else if (hrgn)
1155 success = WinInvalidateRegion (hwnd, hrgnTemp, IncludeChildren);
1156 else
1157 success = WinInvalidateRect (hwnd, &rectl, IncludeChildren);
1158 if (!success) goto error;
1159 }
1160 else if (redraw & RDW_VALIDATE_W)
1161 {
1162 if (WinQueryUpdateRect (hwnd, NULL))
1163 {
1164 if (!pRect && !hrgn)
1165 success = WinValidateRect (hwnd, NULL, IncludeChildren);
1166 else if (hrgn)
1167 success = WinValidateRegion (hwnd, hrgnTemp, IncludeChildren);
1168 else
1169 success = WinValidateRect (hwnd, &rectl, IncludeChildren);
1170 if (!success) goto error;
1171 }
1172 }
1173
1174 if (WinQueryUpdateRect (hwnd, NULL))
1175 {
1176 if (redraw & RDW_UPDATENOW_W)
1177 wnd->MsgPaint (0, FALSE);
1178
1179 else if ((redraw & RDW_ERASE_W) && (redraw & RDW_ERASENOW_W))
1180 wnd->setEraseBkgnd (FALSE, !sendEraseBkgnd (wnd));
1181 }
1182 else if ((redraw & RDW_INTERNALPAINT_W) && !(redraw & RDW_INVALIDATE_W))
1183 {
1184 if (redraw & RDW_UPDATENOW_W)
1185 wnd->MsgPaint (0, FALSE);
1186// else
1187// WinPostMsg( hwnd, WM_VIRTUAL_INTERNALPAINT, MPVOID, MPVOID );
1188 }
1189
1190error:
1191 /* clean up */
1192 if (hrgnTemp)
1193 GpiDestroyRegion (hpsTemp, hrgnTemp);
1194
1195 if (hpsTemp)
1196 WinReleasePS (hpsTemp);
1197
1198 if ((redraw & RDW_INVALIDATE_W) == 0)
1199 wnd->setSupressErase (FALSE);
1200 else if ((redraw & RDW_ERASENOW_W) == RDW_ERASENOW_W)
1201 wnd->setSupressErase (TRUE);
1202
1203 if (!success)
1204 _O32_SetLastError (ERROR_INVALID_PARAMETER);
1205
1206//@@@PH SetFS(sel);
1207 return (success);
1208}
1209
1210BOOL WIN32API InvalidateRect (HWND hwnd, const RECT *pRect, BOOL erase)
1211{
1212 USHORT sel = RestoreOS2FS();
1213// Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1214 BOOL result;
1215
1216// todo !!
1217// if ( isFrame without client )
1218// erase = TRUE;
1219
1220 result = RedrawWindow (hwnd, pRect, NULLHANDLE,
1221 RDW_ALLCHILDREN_W | RDW_INVALIDATE_W |
1222 (erase ? RDW_ERASE_W : 0) |
1223 (hwnd == NULLHANDLE ? RDW_UPDATENOW_W : 0));
1224 SetFS(sel);
1225 return (result);
1226}
1227
1228BOOL WIN32API InvalidateRgn (HWND hwnd, HRGN hrgn, BOOL erase)
1229{
1230 USHORT sel = RestoreOS2FS();
1231// Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1232 BOOL result;
1233
1234// todo !!
1235// if ( isFrame without client )
1236// erase = TRUE;
1237
1238 result = RedrawWindow (hwnd, NULL, hrgn,
1239 RDW_ALLCHILDREN_W | RDW_INVALIDATE_W |
1240 (erase ? RDW_ERASE_W : 0) |
1241 (hwnd == NULLHANDLE ? RDW_UPDATENOW_W : 0));
1242 SetFS(sel);
1243 return (result);
1244}
1245
1246BOOL setPMRgnIntoWinRgn (HRGN hrgnPM, HRGN hrgnWin, LONG height)
1247{
1248 BOOL rc;
1249 HPS hps = WinGetScreenPS (HWND_DESKTOP);
1250 RGNRECT rgnRect;
1251 rgnRect.ircStart = 1;
1252 rgnRect.crc = 0;
1253 rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT; // doesn't make a difference because we're getting them all
1254
1255 rc = GpiQueryRegionRects (hps, hrgnPM, NULL, &rgnRect, NULL);
1256
1257 if (rc && (rgnRect.crcReturned > 0))
1258 {
1259 PRECTL Rcls = new RECTL[rgnRect.crcReturned];
1260 PRECTL pRcl = Rcls;
1261
1262 if (Rcls != NULL)
1263 {
1264 rgnRect.crc = rgnRect.crcReturned;
1265 rc = GpiQueryRegionRects (hps, hrgnPM, NULL, &rgnRect, Rcls);
1266
1267 rc = _O32_SetRectRgn (hrgnWin, pRcl->xLeft,
1268 pRcl->xRight,
1269 height - pRcl->yTop,
1270 height - pRcl->yBottom);
1271
1272 if (rgnRect.crcReturned > 1)
1273 {
1274 int i;
1275 HRGN temp;
1276 temp = _O32_CreateRectRgn (0, 0, 1, 1);
1277
1278 for (i = 1, pRcl++; rc && (i < rgnRect.crcReturned); i++, pRcl++)
1279 {
1280 rc = _O32_SetRectRgn (temp, pRcl->xLeft,
1281 pRcl->xRight,
1282 height - pRcl->yTop,
1283 height - pRcl->yBottom);
1284 rc &= _O32_CombineRgn (hrgnWin, hrgnWin, temp, RGN_OR_W);
1285 }
1286 _O32_DeleteObject (temp);
1287 }
1288 delete[] Rcls;
1289 }
1290 else
1291 {
1292 rc = FALSE;
1293 }
1294 }
1295 else
1296 {
1297 rc = _O32_SetRectRgn (hrgnWin, 0, 0, 0, 0);
1298 }
1299
1300 WinReleasePS (hps);
1301 return (rc);
1302}
1303
1304BOOL WIN32API ScrollDC (HDC hDC, int dx, int dy, const RECT *pScroll,
1305 const RECT *pClip, HRGN hrgnUpdate, LPRECT pRectUpdate)
1306{
1307 USHORT sel = RestoreOS2FS();
1308 BOOL rc = TRUE;
1309
1310 dprintf (("USER32: ScrollDC"));
1311
1312 if (!hDC)
1313 {
1314 SetFS(sel);
1315 return (FALSE);
1316 }
1317
1318 pDCData pHps = (pDCData)GpiQueryDCData ((HPS)hDC);
1319 HWND hwnd = pHps->hwnd;
1320 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1321
1322 if ((hwnd == NULLHANDLE) || !wnd)
1323 {
1324 SetFS(sel);
1325 return (FALSE);
1326 }
1327
1328 POINTL ptl[2] = { 0, 0, dx, dy };
1329
1330 GpiConvert (pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, ptl);
1331 dx = (int)(ptl[1].x - ptl[0].x);
1332 dy = (int)(ptl[1].y - ptl[0].y);
1333
1334 RECTL scrollRect;
1335 RECTL clipRect;
1336
1337 if (pClip)
1338 {
1339 clipRect.xLeft = min (pClip->left, pClip->right);
1340 clipRect.xRight = max (pClip->left, pClip->right);
1341 clipRect.yTop = max (pClip->top, pClip->bottom);
1342 clipRect.yBottom = min (pClip->top, pClip->bottom);
1343
1344 if ((pHps->graphicsMode == GM_COMPATIBLE_W) &&
1345 (clipRect.xLeft != clipRect.xRight) &&
1346 (clipRect.yBottom != clipRect.yTop))
1347 {
1348 if (abs((int)pHps->viewportXExt) <= abs((int)pHps->windowExt.cx))
1349 clipRect.xRight -= abs(pHps->worldXDeltaFor1Pixel);
1350 else
1351 clipRect.xLeft += abs(pHps->worldXDeltaFor1Pixel);
1352
1353 if (abs((int)pHps->viewportYExt) <= abs((int)pHps->windowExt.cy))
1354 clipRect.yTop -= abs(pHps->worldYDeltaFor1Pixel);
1355 else
1356 clipRect.yBottom += abs(pHps->worldYDeltaFor1Pixel);
1357 }
1358 GpiConvert (pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, (PPOINTL)&clipRect);
1359 if (clipRect.xRight < clipRect.xLeft) {
1360 ULONG temp = clipRect.xLeft;
1361 clipRect.xLeft = clipRect.xRight;
1362 clipRect.xRight = temp;
1363 }
1364 if (clipRect.yTop < clipRect.yBottom) {
1365 ULONG temp = clipRect.yBottom;
1366 clipRect.yBottom = clipRect.yTop;
1367 clipRect.yTop = temp;
1368 }
1369 }
1370
1371 if (pScroll)
1372 {
1373 scrollRect.xLeft = min (pScroll->left, pScroll->right);
1374 scrollRect.xRight = max (pScroll->left, pScroll->right);
1375 scrollRect.yTop = max (pScroll->top, pScroll->bottom);
1376 scrollRect.yBottom = min (pScroll->top, pScroll->bottom);
1377
1378 if ((pHps->graphicsMode == GM_COMPATIBLE_W) &&
1379 (scrollRect.xLeft != scrollRect.xRight) &&
1380 (scrollRect.yBottom != scrollRect.yTop))
1381 {
1382 if (abs((int)pHps->viewportXExt) <= abs((int)pHps->windowExt.cx))
1383 scrollRect.xRight -= abs(pHps->worldXDeltaFor1Pixel);
1384 else
1385 scrollRect.xLeft += abs(pHps->worldXDeltaFor1Pixel);
1386
1387 if (abs((int)pHps->viewportYExt) <= abs((int)pHps->windowExt.cy))
1388 scrollRect.yTop -= abs(pHps->worldYDeltaFor1Pixel);
1389 else
1390 scrollRect.yBottom += abs(pHps->worldYDeltaFor1Pixel);
1391 }
1392 GpiConvert (pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, (PPOINTL)&scrollRect);
1393 if (scrollRect.xRight < scrollRect.xLeft) {
1394 ULONG temp = scrollRect.xLeft;
1395 scrollRect.xLeft = scrollRect.xRight;
1396 scrollRect.xRight = temp;
1397 }
1398 if (scrollRect.yTop < scrollRect.yBottom) {
1399 ULONG temp = scrollRect.yBottom;
1400 scrollRect.yBottom = scrollRect.yTop;
1401 scrollRect.yTop = temp;
1402 }
1403 }
1404 RECTL rectlUpdate;
1405 HRGN hrgn;
1406
1407 LONG lComplexity = WinScrollWindow (hwnd, dx, dy, (pScroll) ? &scrollRect : NULL, (pClip) ? &clipRect : NULL, hrgn, &rectlUpdate, 0);
1408 if (lComplexity == RGN_ERROR)
1409 {
1410 SetFS(sel);
1411 return (FALSE);
1412 }
1413
1414 RECT winRectUpdate;
1415 LONG height = wnd->getWindowHeight();
1416
1417 winRectUpdate.left = rectlUpdate.xLeft;
1418 winRectUpdate.right = rectlUpdate.xRight;
1419 winRectUpdate.top = height - rectlUpdate.yTop;
1420 winRectUpdate.bottom = height - rectlUpdate.yBottom;
1421
1422 if (pRectUpdate)
1423 *pRectUpdate = winRectUpdate;
1424
1425 if (hrgnUpdate)
1426 rc = setPMRgnIntoWinRgn (hrgn, hrgnUpdate, height);
1427
1428 SetFS(sel);
1429 return (rc);
1430}
1431
1432//******************************************************************************
1433//******************************************************************************
1434BOOL WIN32API ScrollWindow(HWND hwnd, int dx, int dy, const RECT *pScroll, const RECT *pClip)
1435{
1436 USHORT sel = RestoreOS2FS();
1437 Win32BaseWindow *window;
1438 APIRET rc;
1439 RECTL clientRect;
1440 RECTL scrollRect;
1441 RECTL clipRect;
1442 PRECTL pScrollRect = NULL;
1443 PRECTL pClipRect = NULL;
1444 ULONG scrollFlags = SW_INVALIDATERGN;
1445
1446 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1447 if(!window) {
1448 dprintf(("ScrollWindow, window %x not found", hwnd));
1449 SetFS(sel);
1450 return 0;
1451 }
1452 dprintf(("ScrollWindow %x %d %d\n", hwnd, dx, dy));
1453 MapWin32ToOS2Rectl(window->getClientRect(), (PRECTLOS2)&clientRect);
1454 //Rectangle could be relative to parent window, so fix this
1455 if(clientRect.yBottom != 0) {
1456 clientRect.yTop -= clientRect.yBottom;
1457 clientRect.yBottom = 0;
1458 }
1459 if(clientRect.xLeft != 0) {
1460 clientRect.xRight -= clientRect.xLeft;
1461 clientRect.xLeft = 0;
1462 }
1463 if(pScroll) {
1464 MapWin32ToOS2Rectl((RECT *)pScroll, (PRECTLOS2)&scrollRect);
1465 pScrollRect = &scrollRect;
1466
1467 //Scroll rectangle relative to client area
1468 pScrollRect->xLeft += clientRect.xLeft;
1469 pScrollRect->xRight += clientRect.xLeft;
1470 pScrollRect->yTop += clientRect.yBottom;
1471 pScrollRect->yBottom += clientRect.yBottom;
1472 WinIntersectRect ((HAB) 0, pScrollRect, pScrollRect, &clientRect);
1473 }
1474 else scrollFlags |= SW_SCROLLCHILDREN;
1475
1476 if(pClip) {
1477 MapWin32ToOS2Rectl((RECT *)pClip, (PRECTLOS2)&clipRect);
1478 pClipRect = &clipRect;
1479
1480 //Clip rectangle relative to client area
1481 pClipRect->xLeft += clientRect.xLeft;
1482 pClipRect->xRight += clientRect.xLeft;
1483 pClipRect->yTop += clientRect.yBottom;
1484 pClipRect->yBottom += clientRect.yBottom;
1485 WinIntersectRect ((HAB) 0, pClipRect, pClipRect, &clientRect);
1486 }
1487
1488 dy = revertDy (window, dy);
1489
1490 rc = WinScrollWindow(window->getOS2WindowHandle(), dx, dy,
1491 pScrollRect, pClipRect, NULLHANDLE,
1492 NULL, scrollFlags);
1493
1494 SetFS(sel);
1495 return (rc != RGN_ERROR);
1496}
1497//******************************************************************************
1498//******************************************************************************
1499INT WIN32API ScrollWindowEx(HWND hwnd, int dx, int dy, const RECT *pScroll, const RECT *pClip,
1500 HRGN hrgnUpdate, PRECT pRectUpdate, UINT scrollFlag)
1501{
1502 USHORT sel = RestoreOS2FS();
1503 Win32BaseWindow *window;
1504 APIRET rc;
1505 RECTL scrollRect;
1506 RECTL clipRect;
1507 ULONG scrollFlags = 0;
1508 int regionType = ERROR_W;
1509
1510 window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1511 if(!window) {
1512 dprintf(("ScrollWindowEx, window %x not found", hwnd));
1513 SetFS(sel);
1514 return 0;
1515 }
1516
1517 dprintf(("ScrollWindowEx %x %d %d\n", hwnd, dx, dy));
1518
1519 dy = revertDy (window, dy);
1520
1521 if (scrollFlag & SW_INVALIDATE_W) scrollFlags |= SW_INVALIDATERGN;
1522 if (scrollFlag & SW_SCROLLCHILDREN_W) scrollFlags |= SW_SCROLLCHILDREN;
1523
1524 if(pScroll) MapWin32ToOS2Rectl((RECT *)pScroll, (PRECTLOS2)&scrollRect);
1525 if(pClip) MapWin32ToOS2Rectl((RECT *)pClip, (PRECTLOS2)&clipRect);
1526
1527 RECTL rectlUpdate;
1528 HRGN hrgn;
1529
1530 LONG lComplexity = WinScrollWindow (window->getOS2WindowHandle(), dx, dy,
1531 (pScroll) ? &scrollRect : NULL,
1532 (pClip) ? &clipRect : NULL,
1533 hrgn, &rectlUpdate, scrollFlags);
1534 if (lComplexity == RGN_ERROR)
1535 {
1536 SetFS(sel);
1537 return (0);
1538 }
1539
1540 RECT winRectUpdate;
1541 LONG height = window->getWindowHeight();
1542
1543 winRectUpdate.left = rectlUpdate.xLeft;
1544 winRectUpdate.right = rectlUpdate.xRight;
1545 winRectUpdate.top = height - rectlUpdate.yTop;
1546 winRectUpdate.bottom = height - rectlUpdate.yBottom;
1547
1548 if (pRectUpdate)
1549 *pRectUpdate = winRectUpdate;
1550
1551 if (hrgnUpdate)
1552 rc = setPMRgnIntoWinRgn (hrgn, hrgnUpdate, height);
1553
1554 if ((scrollFlag & SW_INVALIDATE_W) &&
1555 ((lComplexity == RGN_RECT) || (lComplexity == RGN_COMPLEX)))
1556 {
1557 rc = InvalidateRect (hwnd, &winRectUpdate, scrollFlag & SW_ERASE_W);
1558 if (rc == FALSE)
1559 {
1560 SetFS(sel);
1561 return (0);
1562 }
1563 }
1564
1565 switch (lComplexity)
1566 {
1567 case RGN_NULL:
1568 regionType = NULLREGION_W;
1569 break;
1570 case RGN_RECT:
1571 regionType = SIMPLEREGION_W;
1572 break;
1573 case RGN_COMPLEX:
1574 regionType = COMPLEXREGION_W;
1575 break;
1576 default:
1577 regionType = ERROR_W;
1578 break;
1579 }
1580
1581 SetFS(sel);
1582 return (regionType);
1583}
1584//******************************************************************************
1585//******************************************************************************
Note: See TracBrowser for help on using the repository browser.