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

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

some more DC related functions

File size: 31.7 KB
Line 
1/* $Id: dc.cpp,v 1.2 1999-09-16 18:00:43 dengert Exp $ */
2
3/*
4 * DC functions for USER32
5 *
6 * Project Odin Software License can be found in LICENSE.TXT
7 *
8 */
9
10#define INCL_WIN
11#define INCL_GPI
12#define INCL_GREALL
13#define INCL_DEV
14#include <os2.h>
15#include <pmddi.h>
16#include <os2sel.h>
17#include <stdlib.h>
18#include "win32type.h"
19#include <winconst.h>
20#include <wprocess.h>
21#include <misc.h>
22#include <win32wbase.h>
23#include <math.h>
24#include <limits.h>
25#include "oslibwin.h"
26
27#ifndef OPEN32API
28#define OPEN32API _System
29#endif
30
31/*********************/
32typedef struct _tagXFORM
33{
34 FLOAT eM11;
35 FLOAT eM12;
36 FLOAT eM21;
37 FLOAT eM22;
38 FLOAT eDx;
39 FLOAT eDy;
40} XFORM_W, *PXFORM_W, *LPXFORM_W;
41
42typedef struct
43{
44 HDC hdc;
45 BOOL fErase;
46 RECT rcPaint;
47 BOOL fRestore;
48 BOOL IncUpdate;
49 BYTE rgbReserved[32];
50} PAINTSTRUCT_W, *PPAINTSTRUCT_W, *LPPAINTSTRUCT_W;
51
52#define PS_SOLID_W 0x00000000
53#define PS_DASH_W 0x00000001
54#define PS_DOT_W 0x00000002
55#define PS_DASHDOT_W 0x00000003
56#define PS_DASHDOTDOT_W 0x00000004
57#define PS_NULL_W 0x00000005
58#define PS_INSIDEFRAME_W 0x00000006
59#define PS_USERSTYLE_W 0x00000007
60#define PS_ALTERNATE_W 0x00000008
61#define PS_STYLE_MASK_W 0x0000000f
62
63typedef struct
64{
65 UINT lopnStyle;
66 POINT lopnWidth;
67 ULONG lopnColor;
68} LOGPEN_W, *LPLOGPEN_W;
69
70typedef struct tagEXTLOGPEN
71{
72 DWORD elpPenStyle;
73 DWORD elpWidth;
74 DWORD elpBrushStyle;
75 DWORD elpColor;
76 DWORD elpNumEntries;
77 DWORD elpStyleEntry[1];
78} EXTLOGPEN_W, *PEXTLOGPEN_W, *NPEXTLOGPEN_W, *LPEXTLOGPEN_W;
79
80typedef struct
81{
82 UINT lbStyle;
83 ULONG lbColor;
84 INT lbHatch;
85} LOGBRUSH_W, *LPLOGBRUSH_W;
86
87typedef struct _penobject
88{
89 ULONG filler[9];
90 union {
91 struct {
92 PEXTLOGPEN_W pExtLogPen;
93 LOGBRUSH_W logbrush;
94 LOGPEN_W logpen;
95 } ExtPen;
96 struct {
97 LOGPEN_W logpen;
98 } Pen;
99 };
100} tPenObject, *pPenObject;
101
102/* DC Graphics Mode */
103#define GM_COMPATIBLE_W 1
104#define GM_ADVANCED_W 2
105
106#define DCX_WINDOW_W 0x00000001L
107#define DCX_CACHE_W 0x00000002L
108#define DCX_NORESETATTRS_W 0x00000004L
109#define DCX_CLIPCHILDREN_W 0x00000008L
110#define DCX_CLIPSIBLINGS_W 0x00000010L
111#define DCX_PARENTCLIP_W 0x00000020L
112#define DCX_EXCLUDERGN_W 0x00000040L
113#define DCX_INTERSECTRGN_W 0x00000080L
114#define DCX_EXCLUDEUPDATE_W 0x00000100L
115#define DCX_INTERSECTUPDATE_W 0x00000200L
116#define DCX_LOCKWINDOWUPDATE_W 0x00000400L
117#define DCX_VALIDATE_W 0x00200000L
118
119#define RDW_INVALIDATE_W 0x0001
120#define RDW_INTERNALPAINT_W 0x0002
121#define RDW_ERASE_W 0x0004
122#define RDW_VALIDATE_W 0x0008
123#define RDW_NOINTERNALPAINT_W 0x0010
124#define RDW_NOERASE_W 0x0020
125#define RDW_NOCHILDREN_W 0x0040
126#define RDW_ALLCHILDREN_W 0x0080
127#define RDW_UPDATENOW_W 0x0100
128#define RDW_ERASENOW_W 0x0200
129#define RDW_FRAME_W 0x0400
130#define RDW_NOFRAME_W 0x0800
131
132typedef struct _RGNDATAHEADER_W {
133 DWORD dwSize;
134 DWORD iType;
135 DWORD nCount;
136 DWORD nRgnSize;
137 RECT rcBound;
138} RGNDATAHEADER_W, *LPRGNDATAHEADER_W;
139
140typedef struct _RGNDATA_W {
141 RGNDATAHEADER_W rdh;
142 char Buffer[1];
143} RGNDATA_W , *PRGNDATA_W , *LPRGNDATA_W ;
144
145
146/* Xform FLAGS */
147#define MWT_IDENTITY_W 1
148#define MWT_LEFTMULTIPLY_W 2
149#define MWT_RIGHTMULTIPLY_W 3
150
151/* Mapping Modes */
152#define MM_TEXT_W 1
153#define MM_LOMETRIC_W 2
154#define MM_HIMETRIC_W 3
155#define MM_LOENGLISH_W 4
156#define MM_HIENGLISH_W 5
157#define MM_TWIPS_W 6
158#define MM_ISOTROPIC_W 7
159#define MM_ANISOTROPIC_W 8
160
161enum PS_Type { MICRO_CACHED, MICRO, NORMAL };
162enum HDC_Type{ TYPE_0, TYPE_1, TYPE_2, TYPE_3, TYPE_4 };
163
164typedef struct _DCData
165{
166 HDC hdc;
167 HWND hwnd;
168 HPS hps;
169
170 UINT lastBrushHandle;
171 PVOID lastBrushObject;
172 UINT lastPenHandle;
173 pPenObject lastPenObject;
174 UINT lastFontHandle;
175 PVOID lastFontObject;
176 UINT lastBitmapHandle;
177 PVOID lastBitmapObject;
178 UINT lastPaletteHandle;
179 PVOID lastPaletteObject;
180
181 UINT nullBitmapHandle;
182
183 ULONG BkColor;
184 ULONG TextColor;
185 ULONG BkColor_PM;
186 ULONG TextColor_PM;
187
188 int BkMode;
189 ULONG BkMode_PM;
190
191 int ROP2Mode;
192 int ROP2Mode_PM;
193
194 unsigned isMemoryPS:1;
195 unsigned isMetaPS:1;
196 unsigned isPrinter:1;
197 unsigned isFrameWindow:1;
198 unsigned isOD_QUEUED:1;
199 unsigned isOD_INFO:1;
200 unsigned isClient:1;
201 unsigned isClientArea:1;
202 unsigned isLeftLeft:1;
203 unsigned isTopTop:1;
204 unsigned isWideLine:1;
205 unsigned alignUpdateCP:1;
206 unsigned isCacheable:1;
207 unsigned penIsExtPen:1;
208 unsigned isValid:1;
209 unsigned inPath:1;
210 unsigned isStartDoc:1;
211 unsigned resetStockFonts:1;
212 unsigned unused:14;
213
214 ULONG MapMode;
215 HBITMAP bitmapHandle;
216 ULONG bitmapHeight;
217 ULONG bitmapWidth;
218 ULONG hMeta;
219 PVOID pMetaFileObject;
220 int polyFillMode;
221 int arcDirection;
222 int stretchBltMode;
223 int graphicsMode;
224 HRGN hrgnHDC;
225
226 PS_Type psType;
227
228 HDC_Type hdcType;
229 USHORT usFiller;
230 POINTL viewportOrg;
231 double viewportXExt;
232 double viewportYExt;
233 POINTL windowOrg;
234 SIZEL windowExt;
235 HRGN hrgnVis;
236 POINTL ptlOrigin;
237 ULONG printPageHeight;
238 PVOID printerObject;
239
240 LONG taMode;
241 XFORM_W xform;
242
243 INT worldYDeltaFor1Pixel;
244 INT worldXDeltaFor1Pixel;
245 ULONG colorMode;
246 PULONG pLogColorTable;
247
248 ULONG lcidBitfield;
249
250 HWND hwndRealize;
251 ULONG cpeMap;
252
253 LONG lTechnology;
254
255 LONG lWndXExtSave, lWndYExtSave,
256 lVwpXExtSave, lVwpYExtSave;
257
258 int height;
259
260 POINTL brushOrgPoint;
261
262 PVOID pEnhMetaPalette;
263 PVOID lpAbortProc;
264 ULONG HPStoHDCInversionHeight;
265
266 int saveLevel;
267
268 struct _DCData *nextDCData;
269} tDCData, *pDCData;
270
271/*********************/
272
273BOOL APIENTRY GpiEnableYInversion (HPS hps, LONG lHeight);
274LONG APIENTRY GpiQueryYInversion (HPS hps);
275PVOID APIENTRY GpiAllocateDCData (HPS GpiH, ULONG size);
276PVOID APIENTRY GpiQueryDCData (HPS hps);
277HDC OPEN32API HPSToHDC (HWND hwnd, HPS hps, HDC hdc, PVOID);
278void OPEN32API DeleteHDC (HDC hdc);
279BOOL OPEN32API _O32_EndPaint (HWND hwnd, const PAINTSTRUCT_W *lpps);
280int OPEN32API _O32_GetUpdateRgn (HWND hwnd, HRGN hrgn, BOOL erase);
281ULONG OPEN32API _O32_GetRegionData (HRGN hrgn, ULONG count, PRGNDATA_W pData);
282BOOL OPEN32API _O32_DeleteObject (LHANDLE hgdiobj);
283int OPEN32API _O32_ReleaseDC (HWND hwnd, HDC hdc);
284
285#ifndef DEVESC_SETPS
286 #define DEVESC_SETPS 49149L
287#endif
288
289#define FLOAT_TO_FIXED(x) ((FIXED) ((x) * 65536.0))
290#define MICRO_HPS_TO_HDC(x) ((x) & 0xFFFFFFFE)
291
292#define PMRECT_FROM_WINRECT( pmRect, winRect ) \
293{ \
294 (pmRect).xLeft = (winRect).left; \
295 (pmRect).yBottom = (winRect).bottom; \
296 (pmRect).xRight = (winRect).right; \
297 (pmRect).yTop = (winRect).top; \
298}
299
300#define WINRECT_FROM_PMRECT( winRect, pmRect ) \
301{ \
302 (winRect).left = (pmRect).xLeft; \
303 (winRect).top = (pmRect).yTop; \
304 (winRect).right = (pmRect).xRight; \
305 (winRect).bottom = (pmRect).yBottom; \
306}
307
308#define MEM_HPS_MAX 768
309
310const XFORM_W XFORMIdentity = { 1.0, 0.0, 0.0, 1.0, 0, 0 };
311const MATRIXLF matrixlfIdentity = { 0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0};
312
313BOOL setPageXForm(Win32BaseWindow *wnd, pDCData pHps);
314BOOL changePageXForm(Win32BaseWindow *wnd, pDCData pHps, PPOINTL pValue, int x, int y, PPOINTL pPrev);
315LONG clientHeight(Win32BaseWindow *wnd, HWND hwnd, pDCData pHps);
316
317void TestWideLine (pDCData pHps)
318{
319 const LOGPEN_W *pLogPen;
320
321 pHps->isWideLine = FALSE;
322 pLogPen = pHps->penIsExtPen ?
323 &(pHps->lastPenObject->ExtPen.logpen) :
324 &(pHps->lastPenObject->Pen.logpen);
325
326 if (((pLogPen->lopnStyle & PS_STYLE_MASK_W) != PS_NULL_W) &&
327 (pLogPen->lopnWidth.x > 0))
328 {
329 POINTL aptl[2] = { 0, 0, pLogPen->lopnWidth.x, pLogPen->lopnWidth.x };
330
331 GpiConvert(pHps->hps, CVTC_WORLD, CVTC_DEVICE, 2, aptl);
332
333 ULONG dx = abs(aptl[0].x - aptl[1].x);
334 ULONG dy = abs(aptl[0].y - aptl[1].y);
335
336 pHps->isWideLine = (dx > 1) || (dy > 1);
337 }
338}
339
340void Calculate1PixelDelta(pDCData pHps)
341{
342 POINTL aptl[2] = {0, 0, 1, 1};
343
344 GpiConvert(pHps->hps, CVTC_DEVICE, CVTC_WORLD, 2, aptl);
345 pHps->worldYDeltaFor1Pixel = (int)(aptl[1].y - aptl[0].y);
346 pHps->worldXDeltaFor1Pixel = (int)(aptl[1].x - aptl[0].x); // 171182
347}
348
349//******************************************************************************
350
351int setMapMode(Win32BaseWindow *wnd, pDCData pHps, int mode)
352{
353 int prevMode = 0;
354 ULONG flOptions;
355
356 switch (mode)
357 {
358 case MM_HIENGLISH_W : flOptions = PU_HIENGLISH; break;
359 case MM_LOENGLISH_W : flOptions = PU_LOENGLISH; break;
360 case MM_HIMETRIC_W : flOptions = PU_HIMETRIC ; break;
361 case MM_LOMETRIC_W : flOptions = PU_LOMETRIC ; break;
362 case MM_TEXT_W : flOptions = PU_PELS ; break;
363 case MM_TWIPS_W : flOptions = PU_TWIPS ; break;
364 case MM_ANISOTROPIC_W: flOptions = PU_PELS ; break;
365 case MM_ISOTROPIC_W : flOptions = PU_LOMETRIC ; break;
366 default:
367// SET_ERROR_WIN(ERROR_INVALID_PARAMETER_W);
368 return FALSE;
369 }
370
371 prevMode = pHps->MapMode; /* store previous mode */
372 pHps->MapMode = mode;
373
374 if (mode == MM_TEXT_W)
375 {
376 pHps->viewportXExt =
377 pHps->viewportYExt = 1.0;
378 pHps->windowExt.cx =
379 pHps->windowExt.cy = 1;
380 }
381 else if (mode != MM_ANISOTROPIC_W)
382 {
383 RECTL rectl;
384 SIZEL sizel;
385 ULONG data[3];
386
387 data[0] = flOptions;
388 data[1] = data[2] = 0;
389
390 if (DevEscape(pHps->hdc ? pHps->hdc : pHps->hps, DEVESC_SETPS, 12, (PBYTE)data, 0, 0) == DEVESC_ERROR)
391 {
392// SET_ERROR_LAST();
393 return 0;
394 }
395
396 GpiQueryPageViewport(pHps->hps, &rectl);
397 pHps->viewportXExt = (double)rectl.xRight;
398 pHps->viewportYExt = -(double)rectl.yTop;
399
400 GreGetPageUnits(pHps->hdc? pHps->hdc : pHps->hps, &sizel);
401 pHps->windowExt.cx = sizel.cx;
402 pHps->windowExt.cy = sizel.cy;
403
404 data[0] = PU_PELS;
405 DevEscape(pHps->hdc ? pHps->hdc : pHps->hps, DEVESC_SETPS, 12, (PBYTE)data, 0, 0);
406 }
407
408 if (((prevMode != MM_ISOTROPIC_W) && (prevMode != MM_ANISOTROPIC_W)) &&
409 ((mode == MM_ISOTROPIC_W) || (mode == MM_ANISOTROPIC_W)))
410 {
411 if (pHps->lWndXExtSave && pHps->lWndYExtSave)
412 {
413 changePageXForm (wnd, pHps, (PPOINTL)&pHps->windowExt,
414 pHps->lWndXExtSave, pHps->lWndYExtSave, NULL );
415 pHps->lWndXExtSave = pHps->lWndYExtSave = 0;
416 }
417 if (pHps->lVwpXExtSave && pHps->lVwpYExtSave)
418 {
419 changePageXForm (wnd, pHps, NULL,
420 pHps->lVwpXExtSave, pHps->lVwpYExtSave, NULL );
421 pHps->lVwpXExtSave = pHps->lVwpYExtSave = 0;
422 }
423 }
424
425 setPageXForm(wnd, pHps);
426
427 return prevMode;
428}
429
430BOOL setPageXForm(Win32BaseWindow *wnd, pDCData pHps)
431{
432 MATRIXLF mlf;
433 BOOL rc = TRUE;
434
435 pHps->height = clientHeight(wnd, 0, pHps) - 1;
436
437 double xScale = pHps->viewportXExt / (double)pHps->windowExt.cx;
438 double yScale = pHps->viewportYExt / (double)pHps->windowExt.cy;
439
440 mlf.fxM11 = FLOAT_TO_FIXED(xScale);
441 mlf.fxM12 = 0;
442 mlf.lM13 = 0;
443 mlf.fxM21 = 0;
444 mlf.fxM22 = FLOAT_TO_FIXED(yScale);
445 mlf.lM23 = 0;
446 mlf.lM31 = pHps->viewportOrg.x - (LONG)(pHps->windowOrg.x * xScale);
447 mlf.lM32 = pHps->viewportOrg.y - (LONG)(pHps->windowOrg.y * yScale);
448
449 pHps->isLeftLeft = mlf.fxM11 >= 0;
450 pHps->isTopTop = mlf.fxM22 >= 0;
451
452 BOOL bEnableYInversion = FALSE;
453 if ((mlf.fxM22 > 0) ||
454 ((pHps->graphicsMode == GM_ADVANCED_W) &&
455 ((pHps->MapMode == MM_ANISOTROPIC_W) ||
456 (pHps->MapMode == MM_ISOTROPIC_W))))
457 {
458 bEnableYInversion = TRUE;
459 }
460 else
461 {
462 bEnableYInversion = FALSE;
463 mlf.lM32 = pHps->HPStoHDCInversionHeight + pHps->height - mlf.lM32;
464 mlf.fxM22 = -mlf.fxM22;
465 }
466
467 if (!pHps->isMetaPS)
468// if ((!pHps->isMetaPS) ||
469// (pHps->pMetaFileObject && pHps->pMetaFileObject->isEnhanced()))
470 rc = GpiSetDefaultViewMatrix(pHps->hps, 8, &mlf, TRANSFORM_REPLACE);
471
472 if (bEnableYInversion)
473 GpiEnableYInversion(pHps->hps, pHps->height + pHps->HPStoHDCInversionHeight);
474 else
475 GpiEnableYInversion(pHps->hps, 0);
476
477 TestWideLine(pHps);
478 Calculate1PixelDelta(pHps);
479 return rc;
480}
481
482BOOL changePageXForm(Win32BaseWindow *wnd, pDCData pHps, PPOINTL pValue, int x, int y, PPOINTL pPrev)
483{
484 BOOL result = FALSE;
485
486 if (pValue)
487 {
488 if (pPrev)
489 *pPrev = *pValue;
490
491 if ((pValue->x == x) && (pValue->y == y)) {
492 return TRUE;
493 }
494 pValue->x = x;
495 pValue->y = y;
496 }
497 else
498 {
499 if (pPrev)
500 {
501 pPrev->x = (int)pHps->viewportXExt;
502 pPrev->y = (int)pHps->viewportYExt;
503 }
504 pHps->viewportXExt = (double)x;
505 pHps->viewportYExt = (double)y;
506 }
507
508 if (pHps->MapMode == MM_ISOTROPIC_W)
509 {
510 double xExt = fabs(pHps->viewportXExt);
511 double yExt = fabs(pHps->viewportYExt);
512 double sf = fabs((double)pHps->windowExt.cx / pHps->windowExt.cy);
513
514 if (xExt > (yExt * sf))
515 {
516 xExt = yExt * sf;
517
518 if ((double)LONG_MAX <= xExt) return (result);
519
520 if (pHps->viewportXExt < 0.0)
521 pHps->viewportXExt = -xExt;
522 else
523 pHps->viewportXExt = xExt;
524 }
525 else
526 {
527 yExt = xExt / sf;
528
529 if ((double)LONG_MAX <= yExt) return (result);
530
531 if (pHps->viewportYExt < 0.0)
532 pHps->viewportYExt = -yExt;
533 else
534 pHps->viewportYExt = yExt;
535 }
536 }
537 result = setPageXForm(wnd, pHps);
538
539 return (result);
540}
541
542LONG clientHeight(Win32BaseWindow *wnd, HWND hwnd, pDCData pHps)
543{
544 if ((hwnd == 0) && (pHps != 0))
545 hwnd = pHps->hwnd;
546
547 if ((hwnd != 0) || (pHps == 0))
548 {
549 if (wnd)
550 return (wnd->getWindowHeight());
551 else
552 return OSLibQueryScreenHeight();
553 }
554 else if (pHps->bitmapHandle)
555 {
556 return pHps->bitmapHeight;
557 }
558 else if (pHps->isMetaPS)
559 {
560 return 0;
561 }
562 else if (pHps->isPrinter)
563 {
564 return pHps->printPageHeight;
565 }
566 else
567 {
568 return MEM_HPS_MAX;
569 }
570}
571
572VOID removeClientArea(pDCData pHps)
573{
574 pHps->isClient = FALSE;
575
576 if (pHps->isClientArea)
577 {
578 pHps->isClientArea = FALSE;
579 GreSetupDC(pHps->hps,
580 pHps->hrgnVis,
581 pHps->ptlOrigin.x,
582 pHps->ptlOrigin.y,
583 0,
584 SETUPDC_ORIGIN | SETUPDC_VISRGN | SETUPDC_RECALCCLIP);
585 }
586}
587
588BOOL selectClientArea(Win32BaseWindow *wnd, pDCData pHps, PRECTL prclPaint)
589{
590 RECTL rcl;
591 HRGN hrgnRect;
592 HWND hwnd;
593
594 if (!wnd) return (FALSE);
595
596 pHps->isClient = TRUE;
597 hwnd = pHps->hwnd;
598
599 rcl.xLeft = rcl.yBottom = 0;
600 rcl.xRight = wnd->getWindowWidth();
601 rcl.yTop = wnd->getWindowHeight();
602
603 WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL) &rcl, 2);
604 pHps->ptlOrigin = *((PPOINTL) &rcl);
605
606 if (pHps->hrgnVis == 0)
607 pHps->hrgnVis = GreCreateRectRegion(pHps->hps, &rcl, 1);
608
609 hrgnRect = GreCreateRectRegion(pHps->hps, &rcl, 1);
610
611 if (!pHps->isClientArea)
612 GreCopyClipRegion(pHps->hps, pHps->hrgnVis, 0, COPYCRGN_VISRGN);
613
614 GreCombineRegion(pHps->hps, hrgnRect, pHps->hrgnVis, hrgnRect, CRGN_AND);
615 GreSetupDC(pHps->hps,
616 hrgnRect,
617 rcl.xLeft,
618 rcl.yBottom,
619 prclPaint,
620 SETUPDC_ORIGIN | SETUPDC_VISRGN | SETUPDC_RECALCCLIP);
621
622 pHps->isClientArea = TRUE;
623 GreDestroyRegion(pHps->hps, hrgnRect);
624
625 return (TRUE);
626}
627
628HDC sendEraseBkgnd (Win32BaseWindow *wnd)
629{
630 BOOL erased;
631 HWND hwnd;
632 HDC hdc;
633 HPS hps;
634 HRGN hrgnUpdate, hrgnOld, hrgnClip, hrgnCombined;
635 RECTL rectl = { 1, 1, 2, 2 };
636
637 hwnd = wnd->getOS2WindowHandle();
638 hps = WinGetPS(hwnd);
639
640 hrgnUpdate = GpiCreateRegion (hps, 1, &rectl);
641 WinQueryUpdateRegion (hwnd, hrgnUpdate);
642 hrgnClip = GpiQueryClipRegion (hps);
643
644 if (hrgnClip == NULLHANDLE)
645 {
646 GpiSetClipRegion (hps, hrgnUpdate, &hrgnOld);
647 }
648 else
649 {
650 hrgnCombined = GpiCreateRegion (hps, 1, &rectl);
651 GpiCombineRegion (hps, hrgnCombined, hrgnClip, hrgnUpdate, CRGN_AND);
652 GpiSetClipRegion (hps, hrgnCombined, &hrgnOld);
653 GpiDestroyRegion (hps, hrgnUpdate);
654 GpiDestroyRegion (hps, hrgnClip);
655 }
656 if (hrgnOld != NULLHANDLE)
657 GpiDestroyRegion (hps, hrgnOld);
658
659 hdc = HPSToHDC (hwnd, hps, NULL, NULL);
660
661 erased = wnd->MsgEraseBackGround (hdc);
662
663 DeleteHDC (hdc);
664 WinReleasePS (hps);
665
666 return erased;
667}
668
669void releaseOwnDC (HDC hps)
670{
671 pDCData pHps = (pDCData)GpiQueryDCData ((HPS)hps);
672
673 if (pHps) {
674 if (pHps->hrgnHDC)
675 GpiDestroyRegion (pHps->hps, pHps->hrgnHDC);
676
677 GpiSetBitmap (pHps->hps, NULL);
678 _O32_DeleteObject (pHps->nullBitmapHandle);
679 GpiDestroyPS(pHps->hps);
680
681 if (pHps->hdc)
682 DevCloseDC(pHps->hdc);
683
684// how can a memory chunk allocated by GpiAllocateDCData freed by delete?
685// delete pHps;
686 }
687}
688
689HDC WIN32API BeginPaint (HWND hWnd, PPAINTSTRUCT_W lpps)
690{
691 HWND hwnd = hWnd ? hWnd : HWND_DESKTOP;
692 pDCData pHps = NULLHANDLE;
693 RECTL rect;
694 HPS hPS_ownDC = NULLHANDLE;
695
696dprintf (("USER32: BeginPaint(%x)", hWnd));
697
698 if ( !lpps )
699 {
700// SET_ERROR_WIN( ERROR_INVALID_PARAMETER_W );
701 return (HDC)NULLHANDLE;
702 }
703
704 USHORT sel = RestoreOS2FS();
705 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
706
707 if ((hwnd != HWND_DESKTOP) && wnd->isOwnDC())
708 {
709 hPS_ownDC = wnd->getOwnDC();
710 pHps = (pDCData)GpiQueryDCData(hPS_ownDC);
711 if (!pHps)
712 {
713// SET_ERROR_LAST();
714 SetFS(sel);
715 return (HDC)NULLHANDLE;
716 }
717 }
718
719 HWND hwndClient = wnd->getOS2WindowHandle();
720 HPS hps = WinBeginPaint(hwndClient, hPS_ownDC, &rect);
721
722 if (!pHps)
723 {
724 HDC hdc = HPSToHDC (hwndClient, hps, NULL, NULL);
725 pHps = (pDCData)GpiQueryDCData(hps);
726 }
727
728 if (wnd->isFrameWindow())
729 {
730// WinSendMsg( hwnd, /* WM_DRAW */ 0x20D, (MPARAM)hps, MPVOID );
731 selectClientArea(wnd, pHps, &rect);
732 }
733
734 if (hPS_ownDC == 0)
735 setMapMode (wnd, pHps, MM_TEXT_W);
736 else
737 setPageXForm (wnd, pHps);
738
739 pHps->hdcType = TYPE_3;
740 lpps->hdc = (HDC)hps;
741 lpps->fErase = !wnd->MsgEraseBackGround(lpps->hdc);
742
743 if (!hPS_ownDC)
744 {
745 long height = wnd->getWindowHeight();
746 rect.yTop = height - rect.yTop;
747 rect.yBottom = height - rect.yBottom;
748 }
749 else
750 {
751 rect.yTop--;
752 rect.yBottom--;
753 GpiConvert(pHps->hps, CVTC_DEVICE, CVTC_WORLD, 2, (PPOINTL)&rect);
754 }
755
756 WINRECT_FROM_PMRECT(lpps->rcPaint, rect);
757
758 SetFS(sel);
759 return (HDC)pHps->hps;
760}
761
762BOOL WIN32API EndPaint (HWND hwnd, const PAINTSTRUCT_W *pPaint)
763{
764dprintf (("USER32: EndPaint(%x)", hwnd));
765
766 if (!pPaint || !pPaint->hdc )
767 return TRUE;
768
769 USHORT sel = RestoreOS2FS();
770 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
771
772 if (!wnd) goto exit;
773
774 if (wnd->isOwnDC())
775 {
776 pDCData pHps = (pDCData)GpiQueryDCData((HPS)pPaint->hdc);
777 if (pHps && (pHps->hdcType == TYPE_3))
778 {
779 removeClientArea (pHps);
780 WinEndPaint (pHps->hps);
781 }
782 }
783 else
784 {
785 _O32_EndPaint (HWND_DESKTOP, pPaint);
786 }
787
788exit:
789 SetFS(sel);
790 return TRUE;
791}
792
793BOOL WIN32API GetUpdateRect (HWND hwnd, LPRECT pRect, BOOL erase)
794{
795 if (hwnd)
796 {
797// SET_ERROR_WIN( ERROR_INVALID_HANDLE_W );
798 return FALSE;
799 }
800
801 RECTL rectl;
802 USHORT sel = RestoreOS2FS();
803 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
804
805 BOOL updateRegionExists = WinQueryUpdateRect (hwnd, pRect ? &rectl : NULL);
806 if (!pRect) {
807 SetFS(sel);
808 return (updateRegionExists);
809 }
810
811 if (updateRegionExists)
812 {
813 if (wnd->isOwnDC())
814 {
815 pDCData pHps = NULL;
816 pHps = (pDCData)GpiQueryDCData(wnd->getOwnDC());
817 if (!pHps)
818 {
819// SET_ERROR_WIN(ERROR_INVALID_HANDLE_W);
820 SetFS(sel);
821 return FALSE;
822 }
823 GpiConvert (pHps->hps, CVTC_DEVICE, CVTC_WORLD, 2, (PPOINTL)&rectl);
824 }
825 else
826 {
827 long height = wnd->getWindowHeight();
828 rectl.yTop = height - rectl.yTop;
829 rectl.yBottom = height - rectl.yBottom;
830 }
831
832 if (pRect)
833 WINRECT_FROM_PMRECT (*pRect, rectl);
834
835 if (erase)
836 sendEraseBkgnd (wnd);
837 }
838 else
839 {
840 if (pRect)
841 pRect->left = pRect->top = pRect->right = pRect->bottom = 0;
842 }
843
844 SetFS(sel);
845 return updateRegionExists;
846}
847
848int WIN32API GetUpdateRgn (HWND hwnd, HRGN hrgn, BOOL erase)
849{
850 USHORT sel = RestoreOS2FS();
851 LONG Complexity;
852
853 Complexity = _O32_GetUpdateRgn (hwnd, hrgn, FALSE);
854 if (erase && (Complexity > NULLREGION_W)) {
855 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
856 sendEraseBkgnd (wnd);
857 }
858
859 SetFS(sel);
860 return Complexity;
861}
862
863// This implementation of GetDCEx supports
864// DCX_WINDOW
865// DCX_CACHE
866// DCX_EXCLUDERGN (complex regions allowed)
867// DCX_INTERSECTRGN (complex regions allowed)
868
869HDC WIN32API GetDCEx (HWND hwnd, HRGN hrgn, ULONG flags)
870{
871 USHORT sel = RestoreOS2FS();
872 Win32BaseWindow *wnd = NULL;
873 HWND hWindow;
874 BOOL success;
875 pDCData pHps = NULL;
876 HPS hps = NULLHANDLE;
877 BOOL drawingAllowed = TRUE;
878 BOOL isWindowOwnDC;
879 BOOL creatingOwnDC = FALSE;
880 PS_Type psType;
881
882 if (hwnd)
883 {
884 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
885 if (flags & DCX_WINDOW_W)
886 hWindow = wnd->getOS2FrameWindowHandle();
887 else
888 hWindow = wnd->getOS2WindowHandle();
889 }
890 else
891 hWindow = HWND_DESKTOP;
892
893dprintf (("User32: GetDCEx hwnd %x (%x %x) -> wnd %x", hwnd, hrgn, flags, wnd));
894
895 isWindowOwnDC = (((hWindow == HWND_DESKTOP) ? FALSE : wnd->isOwnDC())
896 && !(flags & DCX_CACHE_W));
897 if (isWindowOwnDC)
898 {
899 hps = wnd->getOwnDC();
900 if (hps)
901 {
902 pDCData pHps = (pDCData)GpiQueryDCData (hps);
903 if (!pHps)
904 goto error;
905
906 if (flags & DCX_WINDOW_W)
907 removeClientArea (pHps);
908 else
909 selectClientArea (wnd, pHps, 0);
910
911 setPageXForm (wnd, pHps);
912
913 pHps->hdcType = TYPE_1;
914 SetFS(sel);
915 return (HDC)hps;
916 }
917 else
918 creatingOwnDC = TRUE;
919 }
920
921 if (isWindowOwnDC)
922 {
923 SIZEL sizel = {0,0};
924 hps = GpiCreatePS (WinQueryAnchorBlock (hWindow),
925 WinOpenWindowDC (hWindow),
926 &sizel, PU_PELS | GPIT_MICRO | GPIA_ASSOC );
927 psType = MICRO;
928 }
929 else
930 {
931 if (hWindow == HWND_DESKTOP)
932 hps = WinGetScreenPS (hWindow);
933 else
934 hps = WinGetPS (hWindow);
935
936 psType = MICRO_CACHED;
937 }
938
939 if (!hps)
940 goto error;
941
942 HPSToHDC (hWindow, hps, NULL, NULL);
943 pHps = (pDCData)GpiQueryDCData (hps);
944
945 if (!(flags & DCX_WINDOW_W)) {
946 if (selectClientArea (wnd, pHps, 0))
947 setMapMode (wnd, pHps, MM_TEXT_W);
948 }
949
950 if ((flags & DCX_EXCLUDERGN_W) || (flags & DCX_INTERSECTRGN_W))
951 {
952 ULONG BytesNeeded;
953 PRGNDATA_W RgnData;
954 PRECTL pr;
955 int i;
956 LONG height = OSLibQueryScreenHeight();
957
958 if (!hrgn)
959 goto error;
960
961 BytesNeeded = _O32_GetRegionData (hrgn, 0, NULL);
962 RgnData = (PRGNDATA_W)_alloca (BytesNeeded);
963 if (RgnData == NULL)
964 goto error;
965 _O32_GetRegionData (hrgn, BytesNeeded, RgnData);
966
967 i = RgnData->rdh.nCount;
968 pr = (PRECTL)(RgnData->Buffer);
969
970 success = TRUE;
971 if (flags & DCX_EXCLUDERGN_W)
972 for (; (i > 0) && success; i--, pr++) {
973 LONG y = pr->yBottom;
974
975 pr->yBottom = height - pr->yTop;
976 pr->yTop = height - y;
977 success &= GpiExcludeClipRectangle (pHps->hps, pr);
978 }
979 else
980 for (; (i > 0) && success; i--, pr++) {
981 LONG y = pr->yBottom;
982
983 pr->yBottom = height - pr->yTop;
984 pr->yTop = height - y;
985 success &= GpiIntersectClipRectangle (pHps->hps, pr);
986 }
987 if (!success)
988 goto error;
989 }
990
991 if (creatingOwnDC)
992 wnd->setOwnDC ((HDC)hps);
993
994 pHps->psType = psType;
995 pHps->hdcType = TYPE_1;
996 GpiSetDrawControl (hps, DCTL_DISPLAY, drawingAllowed ? DCTL_ON : DCTL_OFF);
997
998 SetFS(sel);
999 return (HDC)pHps->hps;
1000
1001error:
1002 /* Something went wrong; clean up
1003 */
1004 if (pHps)
1005 {
1006 if (pHps->hps)
1007 {
1008 if(pHps->psType == MICRO_CACHED)
1009 WinReleasePS(pHps->hps);
1010 else
1011 GpiDestroyPS(pHps->hps);
1012 }
1013
1014 if (pHps->hdc) DevCloseDC(pHps->hdc);
1015 if (pHps->hrgnHDC) GpiDestroyRegion(pHps->hps, pHps->hrgnHDC);
1016
1017 _O32_DeleteObject (pHps->nullBitmapHandle);
1018 }
1019// SET_ERROR_LAST();
1020 SetFS(sel);
1021 return NULL;
1022}
1023
1024HDC WIN32API GetDC (HWND hwnd)
1025{
1026 return GetDCEx (hwnd, NULL, 0);
1027}
1028
1029HDC WIN32API GetWindowDC (HWND hwnd)
1030{
1031 return GetDCEx (hwnd, NULL, DCX_WINDOW_W);
1032}
1033
1034int WIN32API ReleaseDC (HWND hwnd, HDC hdc)
1035{
1036 USHORT sel = RestoreOS2FS();
1037 BOOL isOwnDC = FALSE;
1038 int rc;
1039
1040 if (hwnd)
1041 {
1042 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1043 isOwnDC = wnd->isOwnDC();
1044 }
1045 if (isOwnDC)
1046 rc = TRUE;
1047 else
1048 rc = _O32_ReleaseDC (0, hdc);
1049
1050 SetFS(sel);
1051 return (rc);
1052}
1053
1054BOOL WIN32API UpdateWindow (HWND hwnd)
1055{
1056 if (!hwnd)
1057 return FALSE;
1058
1059 USHORT sel = RestoreOS2FS();
1060 Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1061
1062dprintf (("User32: UpdateWindow hwnd %x -> wnd %x", hwnd, wnd));
1063
1064 if (WinQueryUpdateRect (wnd->getOS2WindowHandle(), NULL))
1065 sendEraseBkgnd (wnd);
1066
1067 wnd->MsgPaint(0);
1068
1069 SetFS(sel);
1070 return (TRUE);
1071}
1072
1073// This implementation of RedrawWindow supports
1074// RDW_ERASE
1075// RDW_NOERASE
1076// RDW_INTERNALPAINT
1077// RDW_NOINTERNALPAINT
1078// RDW_INVALIDATE
1079// RDW_VALIDATE
1080// RDW_ERASENOW
1081// RDW_UPDATENOW
1082
1083BOOL WIN32API RedrawWindow (HWND hwnd, const RECT *pRect, HRGN hrgn, DWORD redraw)
1084{
1085 Win32BaseWindow *wnd;
1086
1087 if (redraw & (RDW_FRAME_W | RDW_NOFRAME_W))
1088 {
1089// SET_ERROR_WIN( ERROR_NOT_SUPPORTED_W );
1090 return FALSE;
1091 }
1092
1093 USHORT sel = RestoreOS2FS();
1094 dprintf(("USER32: RedrawWindow %X, %X %X %X", hwnd, pRect, hrgn, redraw));
1095
1096 if (hwnd == NULLHANDLE) {
1097 hwnd = HWND_DESKTOP;
1098 wnd = NULL;
1099 }
1100 else
1101 {
1102 wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1103
1104 if (!wnd)
1105 {
1106// SET_ERROR_LAST();
1107 SetFS(sel);
1108 return FALSE;
1109 }
1110 hwnd = wnd->getOS2WindowHandle();
1111 }
1112
1113 BOOL IncludeChildren = redraw & RDW_ALLCHILDREN_W ? TRUE : FALSE;
1114 BOOL success = TRUE;
1115 HPS hpsTemp = NULLHANDLE;
1116 HRGN hrgnTemp = NULLHANDLE;
1117 RECTL rectl;
1118
1119 if (redraw & RDW_UPDATENOW_W) redraw &= ~RDW_ERASENOW_W;
1120
1121#if 0
1122 if (redraw & RDW_NOERASE_W)
1123 setEraseBkgnd (FALSE);
1124
1125 if (redraw & RDW_UPDATENOW_W)
1126 setSupressErase (TRUE, FALSE);
1127 else if (redraw & RDW_ERASENOW_W)
1128 setSupressErase (FALSE, FALSE);
1129 else
1130 {
1131 QMSG qmsg;
1132 BOOL bErase;
1133
1134 bErase = (WinPeekMsg (HABX, &qmsg, hwnd, WM_PAINT, WM_PAINT, PM_REMOVE)
1135 && (redraw & RDW_NOERASE_W) == 0);
1136
1137 setSupressErase (FALSE, !bErase);
1138 }
1139
1140 if (redraw & (RDW_NOINTERNALPAINT_W | RDW_INTERNALPAINT_W))
1141 {
1142 QMSG qmsg;
1143
1144 WinPeekMsg( (HAB)0, &qmsg, hwnd, WM_VIRTUAL_INTERNALPAINT,
1145 WM_VIRTUAL_INTERNALPAINT, PM_REMOVE );
1146 }
1147#endif
1148
1149 if (hrgn)
1150 {
1151 ULONG BytesNeeded;
1152 PRGNDATA_W RgnData;
1153 PRECTL pr;
1154 int i;
1155 LONG height = wnd ? wnd->getWindowHeight() : OSLibQueryScreenHeight();
1156
1157 if (!hrgn)
1158 goto error;
1159
1160 BytesNeeded = _O32_GetRegionData (hrgn, 0, NULL);
1161 RgnData = (PRGNDATA_W)_alloca (BytesNeeded);
1162 if (RgnData == NULL)
1163 goto error;
1164 _O32_GetRegionData (hrgn, BytesNeeded, RgnData);
1165
1166 pr = (PRECTL)(RgnData->Buffer);
1167 for (i = RgnData->rdh.nCount; i > 0; i--, pr++) {
1168 LONG temp = pr->yTop;
1169 pr->yTop = height - pr->yBottom;
1170 pr->yBottom = height - temp;
1171 }
1172
1173 hpsTemp = WinGetScreenPS (HWND_DESKTOP);
1174 hrgnTemp = GpiCreateRegion (hpsTemp, RgnData->rdh.nCount, (PRECTL)(RgnData->Buffer));
1175 if (!hrgnTemp) goto error;
1176 }
1177 else if (pRect)
1178 {
1179 LONG height = wnd ? wnd->getWindowHeight() : OSLibQueryScreenHeight();
1180
1181 PMRECT_FROM_WINRECT (rectl, *pRect);
1182 rectl.yTop = height - rectl.yTop;
1183 rectl.yBottom = height - rectl.yBottom;
1184 }
1185
1186 if (redraw & RDW_INVALIDATE_W)
1187 {
1188// if (redraw & RDW_ERASE_W)
1189// setEraseBkgnd (TRUE, TRUE);
1190
1191 if (!pRect && !hrgn)
1192 success = WinInvalidateRect (hwnd, NULL, IncludeChildren);
1193 else if (hrgn)
1194 success = WinInvalidateRegion (hwnd, hrgnTemp, IncludeChildren);
1195 else
1196 success = WinInvalidateRect (hwnd, &rectl, IncludeChildren);
1197 if (!success) goto error;
1198 }
1199 else if (redraw & RDW_VALIDATE_W)
1200 {
1201 if (WinQueryUpdateRect (hwnd, NULL))
1202 {
1203 if (!pRect && !hrgn)
1204 success = WinValidateRect (hwnd, NULL, IncludeChildren);
1205 else if (hrgn)
1206 success = WinValidateRegion (hwnd, hrgnTemp, IncludeChildren);
1207 else
1208 success = WinValidateRect (hwnd, &rectl, IncludeChildren);
1209 if (!success) goto error;
1210 }
1211 }
1212
1213 if (WinQueryUpdateRect (hwnd, NULL))
1214 {
1215 if (redraw & RDW_UPDATENOW_W)
1216 wnd->MsgPaint (0, FALSE);
1217
1218// else if ((redraw & RDW_ERASE_W) && (redraw & RDW_ERASENOW_W))
1219// setEraseBkgnd (FALSE, !sendEraseBkgnd (wnd));
1220 }
1221 else if ((redraw & RDW_INTERNALPAINT_W) && !(redraw & RDW_INVALIDATE_W))
1222 {
1223 if (redraw & RDW_UPDATENOW_W)
1224 wnd->MsgPaint (0, FALSE);
1225// else
1226// WinPostMsg( hwnd, WM_VIRTUAL_INTERNALPAINT, MPVOID, MPVOID );
1227 }
1228
1229error:
1230 /* clean up */
1231 if (hrgnTemp)
1232 GpiDestroyRegion (hpsTemp, hrgnTemp);
1233
1234 if (hpsTemp)
1235 WinReleasePS (hpsTemp);
1236
1237// if ((redraw & RDW_INVALIDATE_W) == 0)
1238// setSupressErase (FALSE, FALSE);
1239// else if ((redraw & RDW_ERASENOW_W) == RDW_ERASENOW_W)
1240// setSupressErase (FALSE, TRUE);
1241
1242// if (!success)
1243// SET_ERROR_LAST();
1244
1245 SetFS(sel);
1246 return (success);
1247}
1248
1249BOOL WIN32API InvalidateRect (HWND hwnd, const RECT *pRect, BOOL erase)
1250{
1251 USHORT sel = RestoreOS2FS();
1252// Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1253 BOOL result;
1254
1255// todo !!
1256// if ( isFrame without client )
1257// erase = TRUE;
1258
1259 result = RedrawWindow (hwnd, pRect, NULLHANDLE,
1260 RDW_ALLCHILDREN_W | RDW_INVALIDATE_W |
1261 (erase ? RDW_ERASE_W : 0) |
1262 (hwnd == NULLHANDLE ? RDW_UPDATENOW_W : 0));
1263 SetFS(sel);
1264 return (result);
1265}
1266
1267BOOL WIN32API InvalidateRgn (HWND hwnd, HRGN hrgn, BOOL erase)
1268{
1269 USHORT sel = RestoreOS2FS();
1270// Win32BaseWindow *wnd = Win32BaseWindow::GetWindowFromHandle (hwnd);
1271 BOOL result;
1272
1273// todo !!
1274// if ( isFrame without client )
1275// erase = TRUE;
1276
1277 result = RedrawWindow (hwnd, NULL, hrgn,
1278 RDW_ALLCHILDREN_W | RDW_INVALIDATE_W |
1279 (erase ? RDW_ERASE_W : 0) |
1280 (hwnd == NULLHANDLE ? RDW_UPDATENOW_W : 0));
1281 SetFS(sel);
1282 return (result);
1283}
1284
1285//******************************************************************************
1286//******************************************************************************
1287
Note: See TracBrowser for help on using the repository browser.