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

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

DIBSection changes, EB's file io additions, Jens Weissner's changes to several dlls

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