source: trunk/src/gdi32/region.cpp@ 4557

Last change on this file since 4557 was 4557, checked in by sandervl, 25 years ago

rewrote transform +coordinate apis

File size: 51.0 KB
Line 
1/* $Id: region.cpp,v 1.16 2000-11-05 18:48:22 sandervl Exp $ */
2
3/*
4 * GDI32 region code
5 *
6 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Patrick Haller
8 *
9 * TODO: Metafile recording
10 * TODO: Do we need to translate & set the last error for Gpi operations?
11 *
12 * Project Odin Software License can be found in LICENSE.TXT
13 *
14 */
15#define INCL_GPI
16#define INCL_WIN
17#include <os2wrap.h> //need odin wrappers
18
19#include <win32type.h>
20#include <win32api.h>
21#include <winconst.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <string.h>
25#include <misc.h>
26#include <odinwrap.h>
27#include <objhandle.h>
28#include <dcdata.h>
29#include <winuser32.h>
30#include <win32wnd.h>
31#include "oslibgpi.h"
32
33#define DBG_LOCALLOG DBG_region
34#include "dbglocal.h"
35
36typedef enum
37{
38 AS_DEVICE,
39 AS_WORLD
40} InterpMode;
41
42#define MEM_HPS_MAX 768
43
44static void convertDeviceRect(HWND hwnd, pDCData pHps, PRECTL pRectl, ULONG count);
45
46#define convertWinDeviceRectToPMDeviceRect(arg1, arg2, arg3) convertDeviceRect(arg1, arg2, arg3)
47#define convertPMDeviceRectToWinDeviceRect(arg1, arg2, arg3) convertDeviceRect(arg1, arg2, arg3)
48
49inline void convertDeviceRect(pDCData pHps, PRECTL pRectl, ULONG count)
50{
51 convertDeviceRect(0, pHps, pRectl, count);
52}
53inline void convertDeviceRect(HWND hwnd, PRECTL pRectl, ULONG count)
54{
55 convertDeviceRect(hwnd, 0, pRectl, count);
56}
57
58HPS hpsRegion = 0;
59
60//******************************************************************************
61//******************************************************************************
62BOOL InitRegionSpace()
63{
64 hpsRegion = WinGetScreenPS(HWND_DESKTOP);
65 return hpsRegion != 0;
66}
67//******************************************************************************
68//******************************************************************************
69static LONG hdcHeight(HWND hwnd, pDCData pHps)
70{
71 if(hwnd == 0 && pHps != 0)
72 hwnd = pHps->hwnd;
73
74 if(hwnd != 0 || pHps == 0)
75 {
76 RECT rect;
77 RECTL rectl;
78 LONG y = 0;
79
80 if(pHps == 0 || pHps->isClient) //client area
81 {
82 if(GetClientRect(OS2ToWin32Handle(hwnd), &rect) == TRUE) {
83 y = rect.bottom - rect.top;
84 }
85 }
86 else
87 if(WinQueryWindowRect(hwnd, &rectl)) //whole window
88 y = rectl.yTop;
89
90 return y;
91 }
92 else
93 if(pHps->bitmapHandle)
94 {
95 return pHps->bitmapHeight;
96 }
97 else
98 if(pHps->isMetaPS)
99 {
100 return 0;
101 }
102 else
103 if(pHps->isPrinter)
104 {
105 return pHps->printPageHeight;
106 }
107 else
108 {
109 return MEM_HPS_MAX;
110 }
111}
112//******************************************************************************
113//******************************************************************************
114static LONG hdcWidth(HWND hwnd, pDCData pHps)
115{
116 if(hwnd == 0 && pHps != 0)
117 hwnd = pHps->hwnd;
118
119 if(hwnd != 0 || pHps == 0)
120 {
121 RECT rect;
122 RECTL rectl;
123 LONG x = 0;
124
125 if(pHps == 0 || pHps->isClient) //client area
126 {
127 if(GetClientRect(OS2ToWin32Handle(hwnd), &rect) == TRUE) {
128 x = rect.right - rect.left;
129 }
130 }
131 else
132 if(WinQueryWindowRect(hwnd, &rectl)) //whole window
133 x = rectl.xRight;
134
135 return x;
136 }
137// else
138// DebugInt3();
139 return 0;
140}
141//******************************************************************************
142//******************************************************************************
143static void convertWinWorldRectToPMDeviceRect(pDCData pHps_Hdc, PRECTL pRects, UINT count = 1)
144{
145 PRECTL pRectl;
146 for (int x=0; x < count; x++)
147 {
148 pRectl = &pRects[x];
149
150 if(pRectl->yTop < pRectl->yBottom) {
151 ULONG temp = pRectl->yBottom;
152 pRectl->yBottom = pRectl->yTop;
153 pRectl->yTop = temp;
154 }
155 BOOL success = GpiConvert( pHps_Hdc->hps, CVTC_WORLD, CVTC_DEVICE, 2, (PPOINTL)pRectl);
156 if(!success)
157 {
158 break;
159 }
160 if(pRectl->yTop < pRectl->yBottom) {
161 ULONG temp = pRectl->yBottom;
162 pRectl->yBottom = pRectl->yTop;
163 pRectl->yTop = temp;
164 }
165 }
166}
167//******************************************************************************
168//******************************************************************************
169static void convertDeviceRect(HWND hwnd, pDCData pHps, PRECTL pRectl, ULONG count)
170{
171 long wHeight, wWidth;
172
173 if(hwnd == HWND_DESKTOP) {
174 wHeight = OSLibGetScreenHeight();
175 wWidth = OSLibGetScreenWidth();
176 }
177 else {
178 wHeight = hdcHeight(hwnd, pHps);
179 wWidth = hdcWidth(hwnd, pHps);
180 }
181
182 if(pHps)
183 {
184 wHeight += pHps->HPStoHDCInversionHeight;
185 }
186
187 if(hwnd || (pHps && pHps->hwnd)) {
188 for(int x=0; x < count; x++)
189 {
190 if(pRectl[x].xRight > wWidth) {
191 pRectl[x].xRight = wWidth;
192 }
193 if(pRectl[x].yTop > wHeight) {
194 pRectl[x].yTop = 0;
195 }
196 else pRectl[x].yTop = wHeight - pRectl[x].yTop;
197
198 pRectl[x].yBottom = wHeight - pRectl[x].yBottom;
199 }
200 }
201 else {
202 for(int x=0; x < count; x++)
203 {
204 pRectl[x].yTop = wHeight - pRectl[x].yTop;
205 pRectl[x].yBottom = wHeight - pRectl[x].yBottom;
206 }
207 }
208}
209//******************************************************************************
210//******************************************************************************
211static void convertPMDeviceRectToWinWorldRect(pDCData pHps_Hdc, PRECTL pRectl)
212{
213 GpiConvert(pHps_Hdc->hps, CVTC_DEVICE, CVTC_WORLD, 2, (PPOINTL)pRectl );
214}
215//******************************************************************************
216//******************************************************************************
217BOOL interpretRegionAs(pDCData pHps, HRGN hrgnDest, HRGN hrgnSrc, InterpMode mode)
218{
219 BOOL success = FALSE;
220 int x, i;
221 HPS hpsDest;
222
223 if(pHps)
224 {
225 if(!hrgnDest) {
226 hrgnDest = pHps->hrgnHDC;
227#ifdef DEBUG
228 if(hrgnDest == 0) {
229 DebugInt3();
230 }
231#endif
232 }
233 hpsDest = pHps->hps;
234 }
235 else {
236 DebugInt3();
237 return FALSE;
238 }
239
240 RGNRECT rgnRect;
241 rgnRect.ircStart = 1;
242 rgnRect.crc = 0;
243 rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT;
244 success = GpiQueryRegionRects(hpsRegion, hrgnSrc, NULL, &rgnRect, NULL);
245 if(success)
246 {
247 if(rgnRect.crcReturned > 0)
248 {
249 rgnRect.crc = rgnRect.crcReturned;
250 PRECTL pRectl = new RECTL[rgnRect.crcReturned];
251 success = GpiQueryRegionRects(hpsRegion, hrgnSrc, NULL, &rgnRect, pRectl);
252 if(success)
253 {
254 if(mode == AS_DEVICE)
255 {
256 ULONG temp;
257 for(x=0; x < rgnRect.crcReturned; x++)
258 {
259 temp = pRectl[x].yBottom;
260 pRectl[x].yBottom = pRectl[x].yTop;
261 pRectl[x].yTop = temp;
262 }
263 convertWinDeviceRectToPMDeviceRect(pHps, pRectl, rgnRect.crcReturned);
264 }
265 else
266 {
267 GpiConvert(pHps->hps, CVTC_WORLD, CVTC_DEVICE, rgnRect.crcReturned<<1, (PPOINTL)pRectl);
268
269 ULONG temp;
270 for(i=0; i < rgnRect.crcReturned; i++)
271 {
272 if(pRectl[i].yTop < pRectl[i].yBottom)
273 {
274 temp = pRectl[i].yBottom + 1;
275 pRectl[i].yBottom = pRectl[i].yTop + 1;
276 pRectl[i].yTop = temp;
277 }
278 else
279 {
280 pRectl[i].yTop++;
281 pRectl[i].yBottom++;
282 }
283 }
284 }
285 success = GpiSetRegion(hpsDest, hrgnDest, rgnRect.crcReturned, pRectl);
286 }
287 delete[] pRectl;
288 }
289 else
290 {
291 success = GpiSetRegion(hpsDest, hrgnDest, 0, NULL);
292 }
293 }
294 return success;
295}
296//******************************************************************************
297//exported (used by user32)
298//******************************************************************************
299BOOL WIN32API setWinDeviceRegionFromPMDeviceRegion(HRGN winHrgn, HRGN pmHrgn, pDCData pHpsPmHrgn, HWND hwndPmHrgn)
300{
301 BOOL success;
302 int x;
303 BOOL mustReleaseScreenPS = FALSE;
304 HPS hps;
305
306 if(pHpsPmHrgn || hwndPmHrgn)
307 {
308 if(pHpsPmHrgn)
309 hps = pHpsPmHrgn->hps;
310 else
311 {
312 hps = WinGetScreenPS(HWND_DESKTOP);
313 mustReleaseScreenPS = TRUE;
314 }
315
316 RGNRECT rgnRect;
317 rgnRect.ircStart = 1;
318 rgnRect.crc = 0;
319 rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT;
320 success = GpiQueryRegionRects(hps, pmHrgn, NULL, &rgnRect, NULL);
321 if(success )
322 {
323 if(rgnRect.crcReturned > 0)
324 {
325 rgnRect.crc = rgnRect.crcReturned;
326 PRECTL pRectl = new RECTL[rgnRect.crcReturned];
327 success = GpiQueryRegionRects(hps, pmHrgn, NULL, &rgnRect, pRectl);
328 if(success)
329 {
330 if(pHpsPmHrgn)
331 convertPMDeviceRectToWinDeviceRect(pHpsPmHrgn, pRectl, rgnRect.crcReturned);
332 else
333 convertPMDeviceRectToWinDeviceRect(hwndPmHrgn, pRectl, rgnRect.crcReturned);
334
335 for(x=0; x < rgnRect.crcReturned; x++)
336 {
337 ULONG temp = pRectl[x].yBottom;
338 pRectl[x].yBottom = pRectl[x].yTop;
339 pRectl[x].yTop = temp;
340 }
341
342 success = GpiSetRegion(hpsRegion, winHrgn, rgnRect.crcReturned, pRectl);
343 }
344 delete[] pRectl;
345 }
346 else
347 {
348 success = GpiSetRegion(hpsRegion, winHrgn, 0, NULL);
349 }
350 }
351 }
352 else
353 success = FALSE;
354
355 if(mustReleaseScreenPS)
356 WinReleasePS(hps);
357
358 return success;
359}
360//******************************************************************************
361//******************************************************************************
362ODINFUNCTIONNODBG2(int, SelectClipRgn, HDC, hdc, HRGN, hrgn)
363{
364 LONG lComplexity = RGN_NULL;
365 HRGN hrgnNewClip;
366 HRGN hrgnOldClip;
367
368 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
369 if(!pHps)
370 {
371 dprintf(("WARNING: SelectClipRgn: invalid hdc!", hdc, hrgn));
372 SetLastError(ERROR_INVALID_HANDLE_W);
373 return ERROR_W;
374 }
375
376 if(hrgn)
377 {
378 hrgn = ObjGetHandleData(hrgn);
379 if(hrgn == HANDLE_OBJ_ERROR) {
380 dprintf(("WARNING: SelectClipRgn: invalid region!", hdc, hrgn));
381 SetLastError(ERROR_INVALID_HANDLE_W);
382 return ERROR_W;
383 }
384 }
385
386 if(hrgn)
387 {
388 RECTL rectl = {0,0,1,1};
389 hrgnNewClip = GpiCreateRegion(pHps->hps, 1, &rectl);
390 if(interpretRegionAs(pHps, hrgnNewClip, hrgn, AS_DEVICE) == 0)
391 {
392 lComplexity = RGN_ERROR;
393 }
394 }
395 else
396 hrgnNewClip = 0;
397
398 if(lComplexity != RGN_ERROR)
399 {
400 if(hrgnNewClip == 0) {
401 GpiSetClipPath(pHps->hps, 0, SCP_RESET);
402 }
403 lComplexity = GpiSetClipRegion(pHps->hps, hrgnNewClip, &hrgnOldClip);
404 if (lComplexity != RGN_ERROR )
405 {
406 dprintf(("SelectClipRgn: %x %x", hdc, hrgn));
407 if(hrgnOldClip)
408 GpiDestroyRegion(pHps->hps, hrgnOldClip);
409
410 //todo: metafile recording
411 SetLastError(ERROR_SUCCESS_W);
412 return lComplexity;
413 }
414 }
415
416 dprintf(("WARNING: SelectClipRgn: RGN_ERROR!", hdc, hrgn));
417 if(hrgnNewClip)
418 GpiDestroyRegion(pHps->hps, hrgnNewClip);
419
420 SetLastError(ERROR_SUCCESS_W);
421 return lComplexity;
422}
423//******************************************************************************
424//******************************************************************************
425ODINFUNCTIONNODBG3(int, ExtSelectClipRgn, HDC, hdc, HRGN, hrgn, int, mode)
426{
427 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
428 if (!pHps)
429 {
430 dprintf(("WARNING: ExtSelectRgn %x %x %d invalid hdc", hdc, hrgn, mode));
431 SetLastError(ERROR_INVALID_HANDLE_W);
432 return ERROR_W;
433 }
434
435 LONG lComplexity;
436 HRGN hrgnCurrent = NULLHANDLE;
437
438 if(!hrgn && mode != RGN_COPY_W)
439 {
440 SetLastError(ERROR_INVALID_PARAMETER_W);
441 dprintf(("WARNING: ExtSelectRgn %x %x %d invalid parameter", hdc, hrgn, mode));
442 return ERROR_W;
443 }
444
445 LONG lMode;
446 switch (mode)
447 {
448 case RGN_AND_W : lMode = CRGN_AND ; break;
449 case RGN_COPY_W : lMode = CRGN_COPY; break;
450 case RGN_DIFF_W : lMode = CRGN_DIFF; break;
451 case RGN_OR_W : lMode = CRGN_OR ; break;
452 case RGN_XOR_W : lMode = CRGN_XOR ; break;
453 default:
454 {
455 SetLastError(ERROR_INVALID_PARAMETER_W);
456 dprintf(("WARNING: ExtSelectRgn %x %x %d invalid parameter", hdc, hrgn, mode));
457 return ERROR_W;
458 }
459 }
460
461 if(hrgn)
462 {
463 hrgn = ObjGetHandleData(hrgn);
464 if(hrgn == HANDLE_OBJ_ERROR) {
465 dprintf(("WARNING: ExtSelectRgn %x %x %d invalid region handle", hdc, hrgn, mode));
466 SetLastError(ERROR_INVALID_HANDLE_W);
467 return 0;
468 }
469 }
470
471 dprintf(("WARNING: ExtSelectRgn %x %x %d", hdc, hrgn, mode));
472 //TODO: metafile recording
473 if(hrgn)
474 {
475 if(!interpretRegionAs(pHps, 0, hrgn, AS_DEVICE) )
476 {
477 return ERROR_W;
478 }
479 }
480 else
481 {
482 //remove clip region
483 GpiSetClipPath(pHps->hps, 0, SCP_RESET);
484 GpiSetClipRegion(pHps->hps, NULLHANDLE, &hrgnCurrent);
485
486 if(hrgnCurrent)
487 GpiDestroyRegion(pHps->hps, hrgnCurrent);
488
489 return NULLREGION_W;
490 }
491
492 GpiSetClipRegion(pHps->hps, NULLHANDLE, &hrgnCurrent);
493
494 if(hrgnCurrent == NULLHANDLE)
495 {
496 lMode = CRGN_COPY;
497 RECTL rectl = {0, 0, 1, 1};
498 hrgnCurrent = GpiCreateRegion(pHps->hps, 1, &rectl);
499 }
500
501 HRGN hrgnSrc1;
502 HRGN hrgnSrc2;
503 if(lMode != CRGN_COPY)
504 {
505 hrgnSrc1 = hrgnCurrent;
506 hrgnSrc2 = pHps->hrgnHDC;
507 }
508 else
509 {
510 hrgnSrc1 = pHps->hrgnHDC;
511 hrgnSrc2 = NULLHANDLE;
512 }
513
514 lComplexity = GpiCombineRegion(pHps->hps, hrgnCurrent, hrgnSrc1, hrgnSrc2, lMode);
515 if (lComplexity != RGN_ERROR)
516 {
517 HRGN hrgnOld;
518 lComplexity = GpiSetClipRegion(pHps->hps, hrgnCurrent, &hrgnOld);
519 SetLastError(ERROR_SUCCESS_W);
520 if (lComplexity != RGN_ERROR)
521 return lComplexity;
522 }
523 SetLastError(ERROR_SUCCESS_W);
524 return ERROR_W;
525}
526//******************************************************************************
527//******************************************************************************
528ODINFUNCTIONNODBG2(int, GetClipBox, HDC, hdc, PRECT, lpRect)
529{
530 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
531 RECTL rectl;
532 LONG lComplexity;
533 int rc;
534
535 if(!hdc || !lpRect || !pHps) {
536 dprintf(("GDI32: GetClipBox %x %x ERROR_INVALID_PARAMETER", hdc, lpRect));
537 SetLastError(ERROR_INVALID_PARAMETER_W);
538 return ERROR_W;
539 }
540 if(pHps->isPrinter)
541 {
542 lpRect->left = 0;
543 lpRect->top = 0;
544 lpRect->right = GetDeviceCaps( hdc, HORZRES_W);
545 lpRect->bottom = GetDeviceCaps( hdc, VERTRES_W);
546 includeBottomRightPoint(pHps, (PPOINTLOS2)&rectl);
547 convertPMDeviceRectToWinWorldRect(pHps, &rectl);
548
549 rc = SIMPLEREGION_W;
550 }
551 else {
552 lComplexity = GpiQueryClipBox(pHps->hps, &rectl);
553 if(lComplexity == RGN_ERROR)
554 {
555 rc = ERROR_W;
556 }
557 else
558 if(lComplexity == RGN_NULL)
559 {
560 memset(lpRect, 0, sizeof(*lpRect));
561 rc = NULLREGION_W;
562 }
563 else {
564#ifndef INVERT
565 //Convert coordinates from PM to win32
566 if (pHps->yInvert > 0) {
567 LONG temp = pHps->yInvert - rectl.yBottom;
568 rectl.yBottom = pHps->yInvert - rectl.yTop;
569 rectl.yTop = temp;
570 }
571#endif
572 //Convert including/including to including/excluding
573 includeBottomRightPoint(pHps, (PPOINTLOS2)&rectl);
574
575 lpRect->left = rectl.xLeft;
576 lpRect->right = rectl.xRight;
577
578 if(rectl.yBottom > rectl.yTop) {
579 lpRect->top = rectl.yTop;
580 lpRect->bottom = rectl.yBottom;
581 }
582 else {
583 lpRect->top = rectl.yBottom;
584 lpRect->bottom = rectl.yTop;
585 }
586
587 rc = (lComplexity == RGN_RECT) ? SIMPLEREGION_W : COMPLEXREGION_W;
588 }
589 }
590// if(lpRect->left == 0 && lpRect->top == 0 && lpRect->right == 0 && lpRect->bottom == 0)
591// DebugInt3();
592 dprintf(("GDI32: GetClipBox of %X returned %d; (%d,%d)(%d,%d)", hdc, rc, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom));
593 return rc;
594}
595//******************************************************************************
596//******************************************************************************
597ODINFUNCTIONNODBG2(int, GetClipRgn, HDC, hdc, HRGN, hrgn)
598{
599 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
600 BOOL success;
601 LONG lComplexity = RGN_RECT;
602 HRGN hrgnClip = NULL, hrgnTemp;
603
604 hrgn = ObjGetHandleData(hrgn);
605 if(hrgn == HANDLE_OBJ_ERROR || !pHps) {
606 dprintf(("WARNING: GetClipRgn %x %x invalid handle", hdc, hrgn));
607 SetLastError(ERROR_INVALID_HANDLE_W);
608 return 0;
609 }
610
611 if(GpiSetClipRegion(pHps->hps, NULL, &hrgnClip) == RGN_ERROR) {
612 dprintf(("WARNING: GetClipRgn GpiSetClipRegion failed! (%x)", WinGetLastError(0)));
613 SetLastError(ERROR_INVALID_PARAMETER_W); //todo right errror
614 return 0;
615 }
616 if(hrgnClip) {
617 if(!setWinDeviceRegionFromPMDeviceRegion(hrgn, hrgnClip, pHps, NULL)) {
618 dprintf(("WARNING: GetClipRgn setWinDeviceRegionFromPMDeviceRegion failed!"));
619 GpiSetClipRegion(pHps->hps, hrgnClip, &hrgnTemp);
620 SetLastError(ERROR_INVALID_PARAMETER_W); //todo right errror
621 return 0;
622 }
623 if(GpiSetClipRegion(pHps->hps, hrgnClip, &hrgnTemp) == RGN_ERROR )
624 {
625 dprintf(("WARNING: GetClipRgn GpiSetClipRegion failed %x!", WinGetLastError(0)));
626 SetLastError(ERROR_INVALID_PARAMETER_W); //todo right errror
627 return 0;
628 }
629 }
630 else lComplexity = RGN_NULL;
631
632 dprintf(("GetClipRgn %x %x returned %d", hdc, hrgn, lComplexity != RGN_NULL));
633 SetLastError(ERROR_SUCCESS_W);
634 if(lComplexity == RGN_NULL)
635 return 0;
636 else return 1;
637}
638//******************************************************************************
639//******************************************************************************
640ODINFUNCTIONNODBG5(int, ExcludeClipRect, HDC, hdc, int, left, int, top, int, right, int, bottom)
641{
642 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
643 if(!pHps)
644 {
645 dprintf(("WARNING: ExcludeClipRgn %x (%d,%d)(%d,%d) invalid hdc", hdc, left, top, right, bottom));
646 SetLastError(ERROR_INVALID_HANDLE_W);
647 return ERROR_W;
648 }
649
650 LONG lComplexity;
651 RECTL rectl = { left, bottom, right, top };
652
653 excludeBottomRightPoint(pHps, (PPOINTLOS2)&rectl);
654 if(rectl.yTop < rectl.yBottom) {
655 ULONG temp = rectl.yBottom;
656 rectl.yBottom = rectl.yTop;
657 rectl.yTop = temp;
658 }
659
660#ifndef INVERT
661 if (pHps->yInvert > 0) {
662 LONG temp = pHps->yInvert - rectl.yBottom;
663 rectl.yBottom = pHps->yInvert - rectl.yTop;
664 rectl.yTop = temp;
665 }
666#endif
667
668 dprintf(("ExcludeClipRgn %x (%d,%d)(%d,%d)", hdc, left, top, right, bottom));
669 lComplexity = GpiExcludeClipRectangle(pHps->hps, &rectl);
670 if (lComplexity == RGN_ERROR) {
671 SetLastError(ERROR_INVALID_PARAMETER_W); //TODO: wrong error
672 return ERROR_W;
673 }
674
675 //todo metafile recording
676
677 SetLastError(ERROR_SUCCESS_W);
678 return lComplexity;
679}
680//******************************************************************************
681//******************************************************************************
682ODINFUNCTIONNODBG5(int, IntersectClipRect, HDC, hdc, int, left, int, top, int, right, int, bottom)
683{
684 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
685 LONG lComplexity;
686 BOOL success;
687
688 if(!pHps) {
689 dprintf(("WARNING: IntersectClipRgn %x (%d,%d)(%d,%d) invalid hdc", hdc, left, top, right, bottom));
690 SetLastError(ERROR_INVALID_HANDLE_W);
691 return ERROR_W;
692 }
693 RECTL rectl = { left, bottom, right, top };
694
695 excludeBottomRightPoint(pHps, (PPOINTLOS2)&rectl);
696 if(rectl.yTop < rectl.yBottom) {
697 ULONG temp = rectl.yBottom;
698 rectl.yBottom = rectl.yTop;
699 rectl.yTop = temp;
700 }
701
702#ifndef INVERT
703 //Convert coordinates from PM to win32
704 if (pHps->yInvert > 0) {
705 LONG temp = pHps->yInvert - rectl.yBottom;
706 rectl.yBottom = pHps->yInvert - rectl.yTop;
707 rectl.yTop = temp;
708 }
709#endif
710
711 dprintf(("IntersectClipRgn %x (%d,%d)(%d,%d)", hdc, left, top, right, bottom));
712 lComplexity = GpiIntersectClipRectangle(pHps->hps, &rectl);
713
714 //todo metafile recording
715
716 SetLastError(ERROR_SUCCESS_W);
717 return lComplexity;
718}
719//******************************************************************************
720//******************************************************************************
721ODINFUNCTIONNODBG3(int, OffsetClipRgn, HDC, hdc, int, nXOffset, int, nYOffset )
722{
723 BOOL success;
724 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
725 LONG lComplexity;
726
727 if(!pHps) {
728 dprintf(("OffsetClipRgn %x (%d,%d) invalid hdc", hdc, nXOffset, nYOffset));
729 SetLastError(ERROR_INVALID_HANDLE_W);
730 return ERROR_W;
731 }
732
733 dprintf(("OffsetClipRgn %x (%d,%d)", hdc, nXOffset, nYOffset));
734 POINTL pointl = { nXOffset, nYOffset };
735#ifndef INVERT
736 if (pHps->yInvert > 0) {
737 pointl.y = pHps->yInvert - pointl.y;
738 }
739#endif
740
741 lComplexity = GpiOffsetClipRegion(pHps->hps, &pointl);
742
743 //todo metafile recording
744
745 SetLastError(ERROR_SUCCESS_W);
746 return lComplexity;
747}
748//******************************************************************************
749//******************************************************************************
750ODINFUNCTIONNODBG4(HRGN, CreatePolyPolygonRgn, const POINT * , lppt, const int *, pPolyCount, int, nCount, int, fnPolyFillMode)
751{
752 LONG flMode;
753
754 switch(fnPolyFillMode)
755 {
756 case ALTERNATE_W:
757 flMode = POLYGON_ALTERNATE;
758 break;
759 case WINDING_W:
760 flMode = POLYGON_WINDING;
761 break;
762 default:
763 dprintf(("WARNING: CreatePolyPolygonRgn %x %x %d %d invalid parameter", lppt, pPolyCount, nCount, fnPolyFillMode));
764 SetLastError(ERROR_INVALID_PARAMETER_W);
765 return 0;
766 }
767
768 if(nCount < 1)
769 {
770 dprintf(("WARNING: CreatePolyPolygonRgn %x %x %d %d invalid parameter", lppt, pPolyCount, nCount, fnPolyFillMode));
771 SetLastError(ERROR_INVALID_PARAMETER_W);
772 return 0;
773 }
774
775 PPOLYGON pPolygon = new POLYGON[nCount];
776 if(!pPolygon) {
777 dprintf(("ERROR: CreatePolyPolygonRgn: out of memory!!"));
778 SetLastError(ERROR_OUTOFMEMORY_W);
779 return 0;
780 }
781 dprintf(("CreatePolyPolygonRgn %x %x %d %d", lppt, pPolyCount, nCount, fnPolyFillMode));
782
783 PPOINTL pPointl = (PPOINTL)lppt+1; // skip first point
784 for (int x=0; x < nCount; x++) {
785 pPolygon[x].ulPoints = (x == 0) ? pPolyCount[x] - 1 : pPolyCount[x];
786 pPolygon[x].aPointl = pPointl;
787 pPointl += pPolygon[x].ulPoints;
788 }
789 GpiMove(hpsRegion, (PPOINTL)lppt);
790 HRGN hrgn = GpiCreatePolygonRegion(hpsRegion, nCount, pPolygon, POLYGON_BOUNDARY | flMode);
791
792 delete[] pPolygon;
793
794 if(!hrgn) {
795 SetLastError(ERROR_INVALID_PARAMETER_W); //todo: not right
796 return 0;
797 }
798
799 if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
800 SetLastError(ERROR_OUTOFMEMORY_W);
801 return 0;
802 }
803 SetLastError(ERROR_SUCCESS_W);
804 return hrgn;
805}
806//******************************************************************************
807//******************************************************************************
808ODINFUNCTIONNODBG4(HRGN, CreateRectRgn, int, left, int, top, int, right, int, bottom)
809{
810 HRGN hrgn;
811 RECTL rectl = { left, top < bottom ? top : bottom, right, top < bottom ? bottom : top };
812
813 hrgn = GpiCreateRegion(hpsRegion, 1, &rectl);
814 if(!hrgn) {
815 dprintf(("WARNING: CreateRectRgn: GpiCreateRectRegion failed! %x", WinGetLastError(0)));
816 SetLastError(ERROR_INVALID_PARAMETER_W); //todo: not right
817 return 0;
818 }
819
820 if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
821 SetLastError(ERROR_OUTOFMEMORY_W);
822 return 0;
823 }
824 dprintf(("CreateRectRegion (%d,%d)(%d,%d) returned %x", left, top, right, bottom, hrgn));
825 SetLastError(ERROR_SUCCESS_W);
826 return hrgn;
827}
828//******************************************************************************
829//******************************************************************************
830ODINFUNCTIONNODBG1(HRGN, CreateRectRgnIndirect, const RECT *, lprc)
831{
832 return CreateRectRgn(lprc->left, lprc->top, lprc->right, lprc->bottom);
833}
834//******************************************************************************
835//******************************************************************************
836ODINFUNCTIONNODBG6(HRGN, CreateRoundRectRgn, int, left, int, top, int, right, int, bottom, int, nWidthEllipse, int, nHeightEllipse)
837{
838 HRGN hrgn;
839 RECTL rectl = { left, top < bottom ? top : bottom, right, top < bottom ? bottom : top };
840
841 PPOINTL pPointl = (PPOINTL)&rectl;
842
843 GpiMove(hpsRegion, &pPointl[0]);
844 hrgn = GpiCreateRoundRectRegion(hpsRegion, &pPointl[1], labs(nWidthEllipse), labs(nHeightEllipse));
845
846 if(!hrgn) {
847 SetLastError(ERROR_INVALID_PARAMETER_W); //todo: not right
848 dprintf(("WARNING: CreateRoundRectRgn: GpiCreateRoundRectRegion failed! %x", WinGetLastError(0)));
849 return 0;
850 }
851
852 if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
853 SetLastError(ERROR_OUTOFMEMORY_W);
854 return 0;
855 }
856 dprintf(("CreateRoundRectRegion (%d,%d)(%d,%d) (%d,%d) returned %x", left, top, right, bottom, nWidthEllipse, nHeightEllipse, hrgn));
857 SetLastError(ERROR_SUCCESS_W);
858 return hrgn;
859}
860//******************************************************************************
861//******************************************************************************
862ODINFUNCTIONNODBG3(HRGN, ExtCreateRegion, const XFORM_W *, pXform, DWORD, count, const RGNDATA *, pData)
863{
864 HRGN hrgn;
865
866 if(!pData || count < (sizeof(RGNDATAHEADER) + pData->rdh.nCount * sizeof(RECT))) {
867 dprintf(("WARNING: ExtCreateRegion %x %d %x; invalid parameter", pXform, count, pData));
868 SetLastError(ERROR_INVALID_PARAMETER_W);
869 return 0;
870 }
871
872 PRECTL pRectl = new RECTL[pData->rdh.nCount];
873 PRECT pDataRects = (PRECT)pData->Buffer;
874 for(int i=0; i < pData->rdh.nCount; i++) {
875 MapWin32ToOS2Rect(pDataRects[i], pRectl[i]);
876 }
877
878 BOOL doShear = pXform && (pXform->eM12 || pXform->eM21);
879 HPS hpsTemp = NULLHANDLE;
880
881 dprintf(("ExtCreateRegion %x %d %x", pXform, count, pData));
882 if(doShear) {
883 hpsTemp = WinGetPS(HWND_DESKTOP);
884 GpiBeginPath(hpsTemp, 1);
885
886 MATRIXLF matrixlf;
887 matrixlf.fxM11 = pXform->eM11 * (float)0x10000;
888 matrixlf.fxM12 = pXform->eM12 * (float)0x10000;
889 matrixlf.lM13 = 0;
890 matrixlf.fxM21 = pXform->eM21 * (float)0x10000;
891 matrixlf.fxM22 = pXform->eM22 * (float)0x10000;
892 matrixlf.lM23 = 0;
893 matrixlf.lM31 = pXform->eDx;
894 matrixlf.lM32 = pXform->eDy;
895 matrixlf.lM33 = 1;
896
897 GpiSetModelTransformMatrix(hpsTemp, 9, &matrixlf, TRANSFORM_REPLACE);
898 }
899
900 for(i=0; i < pData->rdh.nCount; i++)
901 {
902 LONG temp = pRectl[i].yTop;
903 pRectl[i].yTop = pRectl[i].yBottom;
904 pRectl[i].yBottom = temp;
905
906 if(pXform)
907 {
908 PPOINTL pPointl = ((PPOINTL)&pRectl[i]);
909
910 if (doShear) {
911 GpiMove(hpsTemp, pPointl);
912 GpiBox(hpsTemp, DRO_OUTLINE, pPointl+1, 0, 0);
913 }
914 else
915 {
916 for(int j=0; j < 2; j++) {
917 pPointl[j].x = (pXform->eM11 * (float)pPointl[j].x) + (pXform->eM12 * (float)pPointl[j].y) + pXform->eDx;
918 pPointl[j].y = (pXform->eM21 * (float)pPointl[j].x) + (pXform->eM22 * (float)pPointl[j].y) + pXform->eDy;
919 }
920
921 PRECTL pRectlT = (PRECTL)pPointl;
922 if (pRectlT->xLeft > pRectlT->xRight) {
923 LONG temp = pRectlT->xLeft;
924 pRectlT->xLeft = pRectlT->xRight;
925 pRectlT->xRight = temp;
926 }
927 if (pRectlT->yBottom > pRectlT->yTop) {
928 LONG temp = pRectlT->yBottom;
929 pRectlT->yBottom = pRectlT->yTop;
930 pRectlT->yTop = temp;
931 }
932 }
933 }
934 }
935
936 if(doShear) {
937 GpiEndPath(hpsTemp);
938 hrgn = GpiPathToRegion(hpsTemp, 1, FPATH_WINDING);
939
940 if(pRectl)
941 delete[] pRectl;
942
943 if(hrgn == 0) {
944 dprintf(("WARNING: ExtCreateRegion GpiCreateRegion failed! (%x)", WinGetLastError(0)));
945 SetLastError(ERROR_INVALID_PARAMETER_W);
946 return 0;
947 }
948 WinReleasePS(hpsTemp);
949 }
950 else {
951 hrgn = GpiCreateRegion(hpsRegion, pData->rdh.nCount, pRectl);
952 if(pRectl)
953 delete[] pRectl;
954
955 if(hrgn == 0) {
956 dprintf(("WARNING: ExtCreateRegion GpiCreateRegion failed! (%x)", WinGetLastError(0)));
957 SetLastError(ERROR_INVALID_PARAMETER_W);
958 return 0;
959 }
960 }
961
962 if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
963 SetLastError(ERROR_OUTOFMEMORY_W);
964 return 0;
965 }
966 SetLastError(ERROR_SUCCESS_W);
967 return hrgn;
968}
969//******************************************************************************
970//******************************************************************************
971ODINFUNCTIONNODBG4(HRGN, CreateEllipticRgn, int, left, int, top, int, right, int, bottom)
972{
973 HRGN hrgn;
974
975 RECTL rectl = { left,
976 top < bottom ? top : bottom,
977 right,
978 top < bottom ? bottom : top };
979
980 dprintf(("CreateEllipticRgn (%d,%d)(%d,%d)", left, top, right, bottom));
981 hrgn = GpiCreateEllipticRegion(hpsRegion, &rectl);
982
983 if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
984 SetLastError(ERROR_OUTOFMEMORY_W);
985 return 0;
986 }
987 SetLastError(ERROR_SUCCESS_W);
988 return hrgn;
989}
990//******************************************************************************
991//******************************************************************************
992ODINFUNCTIONNODBG1(HRGN, CreateEllipticRgnIndirect, const RECT *, pRect)
993{
994 return CreateEllipticRgn(pRect->left, pRect->top, pRect->right, pRect->bottom);
995}
996//******************************************************************************
997//******************************************************************************
998ODINFUNCTIONNODBG3(HRGN, CreatePolygonRgn, const POINT *, lppt, int, cPoints, int, fnPolyFillMode)
999{
1000 HRGN hrgn;
1001 LONG flMode;
1002
1003 if(!lppt || cPoints < 2) {
1004 dprintf(("WARNING: CreatePolygonRgn %x %d %d invalid parameter", lppt, cPoints, fnPolyFillMode));
1005 SetLastError(ERROR_INVALID_PARAMETER_W);
1006 return 0;
1007 }
1008
1009 switch (fnPolyFillMode)
1010 {
1011 case ALTERNATE_W :
1012 flMode = POLYGON_ALTERNATE;
1013 break;
1014 case WINDING_W :
1015 flMode = POLYGON_WINDING;
1016 break;
1017 default:
1018 dprintf(("WARNING: CreatePolygonRgn %x %d %d invalid parameter", lppt, cPoints, fnPolyFillMode));
1019 SetLastError(ERROR_INVALID_PARAMETER_W);
1020 return 0;
1021 }
1022
1023 dprintf(("CreatePolygonRgn %x %d %d", lppt, cPoints, fnPolyFillMode));
1024
1025
1026 POLYGON polygon;
1027 polygon.ulPoints = cPoints - 1;
1028 polygon.aPointl = (PPOINTL)(lppt + 1);
1029
1030 GpiMove(hpsRegion, (PPOINTL)lppt);
1031 hrgn = GpiCreatePolygonRegion(hpsRegion, 1, &polygon, POLYGON_BOUNDARY | flMode);
1032
1033 if(ObjAllocateHandle(&hrgn, hrgn, GDIOBJ_REGION) == FALSE) {
1034 SetLastError(ERROR_OUTOFMEMORY_W);
1035 return 0;
1036 }
1037 SetLastError(ERROR_SUCCESS_W);
1038 return hrgn;
1039}
1040//******************************************************************************
1041//******************************************************************************
1042ODINFUNCTIONNODBG4(int, CombineRgn, HRGN, hrgnDest, HRGN, hrgnSrc1, HRGN, hrgnSrc2, int, combineMode)
1043{
1044 ULONG lComplexity;
1045 LONG mode;
1046
1047 switch(combineMode) {
1048 case RGN_AND_W:
1049 mode = CRGN_AND;
1050 break;
1051 case RGN_COPY_W:
1052 mode = CRGN_COPY;
1053 break;
1054 case RGN_DIFF_W:
1055 mode = CRGN_DIFF;
1056 break;
1057 case RGN_OR_W:
1058 mode = CRGN_OR;
1059 break;
1060 case RGN_XOR_W:
1061 mode = CRGN_XOR;
1062 break;
1063 default:
1064 dprintf(("WARNING: CombineRgn %x %x %x %d; invalid mode!", hrgnDest, hrgnSrc1, hrgnSrc2, combineMode));
1065 SetLastError(ERROR_INVALID_PARAMETER_W);
1066 return ERROR_W;
1067 }
1068
1069 hrgnDest = ObjGetHandleData(hrgnDest);
1070 hrgnSrc1 = ObjGetHandleData(hrgnSrc1);
1071 hrgnSrc2 = ObjGetHandleData(hrgnSrc2);
1072 if(hrgnDest == HANDLE_OBJ_ERROR || hrgnSrc1 == HANDLE_OBJ_ERROR || (hrgnSrc2 == HANDLE_OBJ_ERROR && combineMode != RGN_COPY_W)) {
1073 dprintf(("WARNING: CombineRgn %x %x %x %d invalid region", hrgnDest, hrgnSrc1, hrgnSrc2, combineMode));
1074 SetLastError(ERROR_INVALID_HANDLE_W);
1075 return ERROR_W;
1076 }
1077
1078 lComplexity = GpiCombineRegion(hpsRegion, hrgnDest, hrgnSrc1, hrgnSrc2, mode);
1079 if(lComplexity == RGN_ERROR) {
1080 dprintf(("WARNING: CombineRgn %x %x %x %d GpiCombineRegion failed (%x)", hrgnDest, hrgnSrc1, hrgnSrc2, mode, WinGetLastError(0)));
1081 SetLastError(ERROR_INVALID_HANDLE_W);
1082 return ERROR_W;
1083 }
1084 SetLastError(ERROR_SUCCESS_W);
1085 return lComplexity;
1086}
1087//******************************************************************************
1088//******************************************************************************
1089ODINFUNCTIONNODBG2(BOOL, EqualRgn, HRGN, hrgn1, HRGN, hrgn2)
1090{
1091 LONG lEquality;
1092
1093 hrgn1 = ObjGetHandleData(hrgn1);
1094 hrgn2 = ObjGetHandleData(hrgn2);
1095 if(hrgn1 == HANDLE_OBJ_ERROR || hrgn2 == HANDLE_OBJ_ERROR) {
1096 dprintf(("WARNING: EqualRgn %x %x invalid region", hrgn1, hrgn2));
1097 SetLastError(ERROR_INVALID_HANDLE_W);
1098 return FALSE;
1099 }
1100 lEquality = GpiEqualRegion(hpsRegion, hrgn1, hrgn2);
1101
1102 dprintf(("EqualRgn %x %x = %d", hrgn1, hrgn2, lEquality));
1103 SetLastError(ERROR_SUCCESS_W);
1104
1105 if(lEquality == EQRGN_EQUAL)
1106 return TRUE;
1107 else
1108 if(lEquality == EQRGN_NOTEQUAL)
1109 return FALSE;
1110 else {
1111 return FALSE;
1112 }
1113}
1114//******************************************************************************
1115//******************************************************************************
1116ODINFUNCTIONNODBG5(BOOL, SetRectRgn, HRGN, hrgn, int, left, int, top, int, right, int, bottom)
1117{
1118 BOOL result = FALSE;
1119
1120 hrgn = ObjGetHandleData(hrgn);
1121 if(hrgn == HANDLE_OBJ_ERROR) {
1122 dprintf(("WARNING: SetRectRgn %x (%d,%d)(%d,%d) invalid region handle", hrgn, left, top, right, bottom));
1123 SetLastError(ERROR_INVALID_HANDLE_W);
1124 return 0;
1125 }
1126 RECTL rectl = { left, top, right, bottom }; //reversed y coordinates
1127 if(GpiSetRegion(hpsRegion, hrgn, 1, &rectl)) {
1128 dprintf(("SetRectRgn %x (%d,%d)(%d,%d)", hrgn, left, top, right, bottom));
1129 return TRUE;
1130 }
1131 dprintf(("WARNING: SetRectRgn %x (%d,%d)(%d,%d) GpiSetRegion failed %x", hrgn, left, top, right, bottom, WinGetLastError(0)));
1132 return FALSE;
1133}
1134//******************************************************************************
1135//******************************************************************************
1136ODINFUNCTIONNODBG3(ULONG, GetRegionData, HRGN, hrgn, ULONG, count, PRGNDATA, pData)
1137{
1138 if(!count && pData)
1139 {
1140 dprintf(("WARNING: GetRegionData %x %d %x; invalid parameter", hrgn, count, pData));
1141 SetLastError(ERROR_INVALID_PARAMETER_W);
1142 return 0;
1143 }
1144 hrgn = ObjGetHandleData(hrgn);
1145 if(hrgn == HANDLE_OBJ_ERROR) {
1146 dprintf(("WARNING: GetRegionData %x %d %x; invalid region handle", hrgn, count, pData));
1147 SetLastError(ERROR_INVALID_HANDLE_W);
1148 return 0;
1149 }
1150 RGNRECT rgnRect;
1151 rgnRect.ircStart = 1;
1152 rgnRect.crc = 0;
1153 rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT;
1154 if(!GpiQueryRegionRects(hpsRegion, hrgn, NULL, &rgnRect, NULL))
1155 {
1156 dprintf(("WARNING: GetRegionData %x %d %x: GpiQueryRegionRects failed! (%x)", hrgn, count, pData, WinGetLastError(0)));
1157 return 0;
1158 }
1159
1160 dprintf(("GetRegionData %x %d %x", hrgn, count, pData));
1161
1162 ULONG bufSizeNeeded = rgnRect.crcReturned * sizeof(RECT) + sizeof (RGNDATAHEADER);
1163
1164 if(pData && (count >= (sizeof(RGNDATAHEADER) + rgnRect.crcReturned * sizeof(RECT))))
1165 {
1166 //we actually need to flip the top & bottom values, but as the layout of the PM RECTL and
1167 //Win32 RECT have exactly those two members reversed, we don't do this for the returned
1168 //rectangles (more efficient)
1169 PRECTL pRectl = (PRECTL)pData->Buffer;
1170 rgnRect.crc = rgnRect.crcReturned;
1171 if(!GpiQueryRegionRects(hpsRegion, hrgn, NULL, &rgnRect, pRectl))
1172 {
1173 dprintf(("WARNING: GetRegionData: GpiQueryRegionRects failed! (%x)", WinGetLastError(0)));
1174 return 0;
1175 }
1176
1177 RECTL boundRect;
1178 GpiQueryRegionBox(hpsRegion, hrgn, &boundRect); // no need to check rc
1179
1180 pData->rdh.dwSize = sizeof(pData->rdh);
1181 pData->rdh.iType = RDH_RECTANGLES_W; // one and only possible value
1182 pData->rdh.nCount = rgnRect.crcReturned;
1183 pData->rdh.nRgnSize = rgnRect.crcReturned * sizeof(RECTL);
1184
1185 //flip top & bottom for bounding rectangle (not really necessary; but cleaner coding)
1186 LONG temp = boundRect.yTop;
1187 boundRect.yTop = boundRect.yBottom;
1188 boundRect.yBottom = temp;
1189 MapOS2ToWin32Rect(boundRect, pData->rdh.rcBound);
1190 }
1191
1192 //return size needed
1193 return bufSizeNeeded;
1194}
1195//******************************************************************************
1196//******************************************************************************
1197ODINFUNCTIONNODBG2(int, GetRgnBox, HRGN, hrgn, PRECT, pRect)
1198{
1199 BOOL success;
1200 LONG lComplexity;
1201
1202 hrgn = ObjGetHandleData(hrgn);
1203 if(hrgn == HANDLE_OBJ_ERROR) {
1204 dprintf(("WARNING: GetRgnBox %x %x invalid region!", hrgn, pRect));
1205 SetLastError(ERROR_INVALID_HANDLE_W);
1206 return FALSE;
1207 }
1208
1209 dprintf(("GetRgnBox %x %x", hrgn, pRect));
1210
1211 RECTL rectl;
1212 lComplexity = GpiQueryRegionBox(hpsRegion, hrgn, &rectl);
1213 if(lComplexity != RGN_ERROR)
1214 {
1215 //no conversion required, just flip top & bottom
1216 ULONG temp = rectl.yBottom;
1217 rectl.yBottom = rectl.yTop;
1218 rectl.yTop = temp;
1219
1220 MapOS2ToWin32Rect(rectl, *pRect);
1221 }
1222 else {
1223 lComplexity = ERROR_W;
1224 dprintf(("WARNING: GetRgnBox error in region!"));
1225 }
1226
1227 SetLastError(ERROR_SUCCESS_W);
1228 return lComplexity;
1229}
1230//******************************************************************************
1231//******************************************************************************
1232ODINFUNCTIONNODBG2(BOOL, InvertRgn, HDC, hdc, HRGN, hrgn)
1233{
1234 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
1235
1236 hrgn = ObjGetHandleData(hrgn);
1237 if(!pHps || hrgn == HANDLE_OBJ_ERROR) {
1238 dprintf(("WARNING: InvertRgn %x %x invalid handle!", hdc, hrgn));
1239 SetLastError(ERROR_INVALID_HANDLE_W);
1240 return FALSE;
1241 }
1242 //todo metafile recording
1243
1244 dprintf(("InvertRgn %x %x", hdc, hrgn));
1245
1246 interpretRegionAs(pHps, NULL, hrgn, AS_WORLD);
1247
1248 LONG lHits = GPI_ERROR;
1249 HRGN hrgnOld;
1250 LONG lComplexity ;
1251 RECTL boundingRect; // this gets a rectangle in world cordinates!
1252
1253 lComplexity = GpiQueryRegionBox(pHps->hps, pHps->hrgnHDC, &boundingRect);
1254 if(lComplexity != RGN_ERROR)
1255 {
1256 lComplexity = GpiSetClipRegion(pHps->hps, pHps->hrgnHDC, &hrgnOld);
1257 if(lComplexity != RGN_ERROR)
1258 {
1259 RECTL rectls[2];
1260 rectls[0] = boundingRect;
1261 rectls[1] = boundingRect;
1262 lHits = GpiBitBlt(pHps->hps, NULL, 3, (PPOINTL)rectls,
1263 ROP_DSTINVERT, 0);
1264
1265 /* Restore the old region */
1266 GpiSetClipRegion(pHps->hps, hrgnOld, &hrgnOld);
1267 }
1268 }
1269
1270 if(lHits == GPI_ERROR || lComplexity == RGN_ERROR)
1271 {
1272 dprintf(("WARNING: InvertRgn error during Gpi operation (%x) (%d,%d)", WinGetLastError(0), lHits, lComplexity));
1273 return FALSE;
1274 }
1275
1276 return TRUE;
1277}
1278//******************************************************************************
1279//******************************************************************************
1280ODINFUNCTIONNODBG3(int, OffsetRgn, HRGN, hrgn, int, xOffset, int, yOffset)
1281{
1282 LONG lComplexity;
1283
1284 hrgn = ObjGetHandleData(hrgn);
1285 if(hrgn == HANDLE_OBJ_ERROR) {
1286 dprintf(("WARNING: OffsetRgn %x %d %d invalid handle!", hrgn, xOffset, yOffset));
1287 SetLastError(ERROR_INVALID_HANDLE_W);
1288 return ERROR_W;
1289 }
1290 dprintf(("OffsetRgn %x %d %d", hrgn, xOffset, yOffset));
1291
1292 POINTL ptlOffset = {xOffset, yOffset};
1293 GpiOffsetRegion(hpsRegion, hrgn, &ptlOffset);
1294
1295 RECTL rectl[8];
1296 RGNRECT rgnRect;
1297 rgnRect.ircStart = 1;
1298 rgnRect.crc = 8;
1299 rgnRect.ulDirection = RECTDIR_LFRT_TOPBOT; // doesn't make a difference
1300 if(GpiQueryRegionRects(hpsRegion, hrgn, NULL, &rgnRect, &rectl[0]))
1301 {
1302 switch (rgnRect.crcReturned) {
1303 case 0:
1304 lComplexity = NULLREGION_W;
1305 break;
1306 case 1:
1307 lComplexity = SIMPLEREGION_W;
1308 break;
1309 default:
1310 lComplexity = COMPLEXREGION_W;
1311 break;
1312 }
1313 }
1314 else {
1315 lComplexity = ERROR_W;
1316 dprintf(("WARNING: OffsetRgn error in region! (%x)", WinGetLastError(0)));
1317 }
1318
1319 SetLastError(ERROR_SUCCESS_W);
1320
1321 return lComplexity;
1322}
1323//******************************************************************************
1324//******************************************************************************
1325ODINFUNCTIONNODBG5(BOOL, FrameRgn, HDC, hdc, HRGN, hrgn, HBRUSH, hBrush, int, width, int, height)
1326{
1327 HBRUSH hbrushRestore = 0;
1328 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
1329
1330 hrgn = ObjGetHandleData(hrgn);
1331 if(!pHps || hrgn == HANDLE_OBJ_ERROR) {
1332 dprintf(("WARNING: FrameRgn %x %x %x (%d,%d) invalid handle!", hdc, hrgn, hBrush, width, height));
1333 SetLastError(ERROR_INVALID_HANDLE_W);
1334 return FALSE;
1335 }
1336
1337 width = abs(width);
1338 height = abs(height);
1339
1340 if(pHps->lastBrushKey != (UINT)hBrush)
1341 {
1342 hbrushRestore = SelectObject(hdc, hBrush);
1343 if(!hbrushRestore)
1344 {
1345 dprintf(("WARNING: FrameRgn %x %x %x (%d,%d) invalid brush!", hdc, hrgn, hBrush, width, height));
1346 SetLastError(ERROR_INVALID_HANDLE_W);
1347 return FALSE;
1348 }
1349 }
1350 dprintf(("FrameRgn %x %x %x (%d,%d)", hdc, hrgn, hBrush, width, height));
1351 interpretRegionAs(pHps, NULL, hrgn, AS_WORLD);
1352
1353 SIZEL thickness = { width, height };
1354 LONG lHits = GpiFrameRegion(pHps->hps, pHps->hrgnHDC, &thickness);
1355
1356 SetLastError(ERROR_SUCCESS_W);
1357
1358 // Restore the brush if necessary
1359 if(hbrushRestore)
1360 SelectObject(hdc, hbrushRestore);
1361
1362 //todo metafile recording
1363 return (lHits != GPI_ERROR);
1364}
1365//******************************************************************************
1366//******************************************************************************
1367ODINFUNCTIONNODBG3(BOOL, FillRgn, HDC, hdc, HRGN, hrgn, HBRUSH, hBrush)
1368{
1369 BOOL success;
1370 HBRUSH hbrushRestore = 0;
1371
1372 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
1373
1374 hrgn = ObjGetHandleData(hrgn);
1375 if(!pHps || hrgn == HANDLE_OBJ_ERROR) {
1376 dprintf(("WARNING: FillRgn %x %x %x invalid handle!", hdc, hrgn, hBrush));
1377 SetLastError(ERROR_INVALID_HANDLE_W);
1378 return FALSE;
1379 }
1380
1381 if(pHps->lastBrushKey != (UINT)hBrush)
1382 {
1383 hbrushRestore = SelectObject(hdc, hBrush);
1384 if (!hbrushRestore)
1385 {
1386 dprintf(("WARNING: FillRgn %x %x %x invalid brush!", hdc, hrgn, hBrush));
1387 SetLastError(ERROR_INVALID_HANDLE_W);
1388 return FALSE;
1389 }
1390 }
1391 dprintf(("FillRgn %x %x %x", hdc, hrgn, hBrush));
1392
1393 interpretRegionAs(pHps, NULL, hrgn, AS_WORLD);
1394
1395 success = GpiPaintRegion(pHps->hps, pHps->hrgnHDC);
1396
1397 //todo metafile recording
1398
1399 /* Restore the brush if necessary */
1400 if(hbrushRestore)
1401 SelectObject(hdc, hbrushRestore);
1402
1403 return(success);
1404}
1405//******************************************************************************
1406//******************************************************************************
1407ODINFUNCTIONNODBG2(BOOL, PaintRgn, HDC, hdc, HRGN, hrgn)
1408{
1409 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
1410 if(!pHps)
1411 {
1412 SetLastError(ERROR_INVALID_HANDLE_W);
1413 return FALSE;
1414 }
1415
1416 return FillRgn(hdc, hrgn, (HBRUSH) pHps->lastBrushKey);
1417}
1418//******************************************************************************
1419//******************************************************************************
1420ODINFUNCTIONNODBG3(BOOL, PtInRegion, HRGN, hrgn, int, x, int, y)
1421{
1422 BOOL success;
1423 LONG lInside;
1424
1425 hrgn = ObjGetHandleData(hrgn);
1426 if(hrgn == HANDLE_OBJ_ERROR) {
1427 dprintf(("WARNING: PtInRgn %x (%d,%d) invalid region!", hrgn, x, y));
1428 SetLastError(ERROR_INVALID_HANDLE_W);
1429 return FALSE;
1430 }
1431
1432 POINTL pointl = {x,y};
1433 lInside = GpiPtInRegion(hpsRegion, hrgn, &pointl);
1434 if(lInside == PRGN_ERROR) {
1435 success = FALSE;
1436 }
1437 else success = TRUE;
1438
1439 SetLastError(ERROR_SUCCESS_W);
1440
1441 dprintf(("WARNING: PtInRgn %x (%d,%d) returned %d", hrgn, x, y, (success && lInside == PRGN_INSIDE) ? 1 : 0));
1442
1443 if(success && lInside == PRGN_INSIDE)
1444 return TRUE;
1445 else
1446 return FALSE;
1447}
1448//******************************************************************************
1449//******************************************************************************
1450ODINFUNCTIONNODBG2(BOOL, RectInRegion, HRGN, hrgn, const RECT *, pRect)
1451{
1452 BOOL success;
1453 LONG lInside;
1454
1455 if(!pRect) {
1456 dprintf(("WARNING: RectInRgn %x %x invalid parameter!", hrgn, pRect));
1457 SetLastError(ERROR_INVALID_PARAMETER_W);
1458 return FALSE;
1459 }
1460 hrgn = ObjGetHandleData(hrgn);
1461 if(hrgn == HANDLE_OBJ_ERROR) {
1462 dprintf(("WARNING: RectInRgn %x %x invalid region", hrgn, pRect));
1463 SetLastError(ERROR_INVALID_HANDLE_W);
1464 return FALSE;
1465 }
1466
1467 RECTL rectl;
1468 MapWin32ToOS2Rect(*pRect, rectl);
1469 //switch bottom & top
1470 UINT temp = rectl.yBottom;
1471 rectl.yBottom = rectl.yTop;
1472 rectl.yTop = temp;
1473
1474 lInside = GpiRectInRegion(hpsRegion, hrgn, &rectl);
1475 if(lInside == RRGN_ERROR) {
1476 success = FALSE;
1477 }
1478 else success = TRUE;
1479
1480 SetLastError(ERROR_SUCCESS_W);
1481
1482 dprintf(("WARNING: RectInRgn %x %x returned %d", hrgn, pRect, (success && (lInside == RRGN_INSIDE || lInside == RRGN_PARTIAL)) ? 1 : 0));
1483
1484 if(success && (lInside == RRGN_INSIDE || lInside == RRGN_PARTIAL))
1485 return TRUE;
1486 else
1487 return FALSE;
1488}
1489//******************************************************************************
1490//Returned region in device coordinates (undocumented behaviour)
1491//******************************************************************************
1492ODINFUNCTIONNODBG1(HRGN, PathToRegion, HDC, hdc)
1493{
1494 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
1495 if(!pHps)
1496 {
1497 dprintf(("WARNING: PathToRegion %x; invalid hdc!", hdc));
1498 SetLastError(ERROR_INVALID_HANDLE_W);
1499 return NULLHANDLE;
1500 }
1501
1502 HRGN hrgn, hrgnTemp, hrgnwin;
1503
1504 dprintf(("GDI32: PathToRegion %x", hdc));
1505
1506 hrgnTemp = GpiPathToRegion(pHps->hps, 1, (pHps->polyFillMode == ALTERNATE_W) ? FPATH_ALTERNATE : FPATH_WINDING);
1507 if(hrgnTemp == NULLHANDLE)
1508 goto error;
1509
1510 hrgnwin = CreateRectRgn(1, 1, 2, 2);
1511 hrgn = ObjGetHandleData(hrgnwin);
1512 if(hrgn == HANDLE_OBJ_ERROR) {
1513 dprintf(("WARNING: PathToRegion invalid region", hrgnwin));
1514 SetLastError(ERROR_INVALID_HANDLE_W);
1515 return NULLHANDLE;
1516 }
1517
1518 if(!setWinDeviceRegionFromPMDeviceRegion(hrgn, hrgnTemp, pHps, NULL))
1519 goto error;
1520
1521 GpiDestroyRegion(pHps->hps, hrgnTemp);
1522
1523 return hrgnwin;
1524
1525error:
1526 if(hrgnwin)
1527 DeleteObject(hrgnwin);
1528
1529 SetLastError(ERROR_INVALID_HANDLE_W); //todo right error
1530 return NULLHANDLE;
1531}
1532//******************************************************************************
1533//Needs wrapper as this file includes os2.h!!
1534//******************************************************************************
1535ODINFUNCTIONNODBG1(BOOL, OSLibDeleteRegion, HANDLE, hRegion)
1536{
1537 if(GpiDestroyRegion(hpsRegion, hRegion) == FALSE) {
1538 dprintf(("WARNING: OSLibDeleteRegion %x; GpiDestroyRegion failed (%x)", hRegion, WinGetLastError(0)));
1539 }
1540 return (0);
1541}
1542/*****************************************************************************
1543 * Name : int GetMetaRgn
1544 * Purpose : The GetMetaRgn function retrieves the current metaregion for
1545 * the specified device context.
1546 * Parameters: HDC hdc handle of device context
1547 * HRGN hrgn handle of region
1548 * Variables :
1549 * Result : 0 / 1
1550 * Remark :
1551 * Status : UNTESTED STUB
1552 *
1553 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1554 *****************************************************************************/
1555
1556ODINFUNCTIONNODBG2(int, GetMetaRgn, HDC, hdc, HRGN, hrgn)
1557{
1558 dprintf(("GDI32: GetMetaRgn(%08xh, %08xh) not implemented.\n",
1559 hdc,
1560 hrgn));
1561
1562 SetLastError(ERROR_SUCCESS_W);
1563 return (0);
1564}
1565/*****************************************************************************
1566 * Name : int SetMetaRgn
1567 * Purpose : The SetMetaRgn function intersects the current clipping region
1568 * for the specified device context with the current metaregion
1569 * and saves the combined region as the new metaregion for the
1570 * specified device context. The clipping region is reset to a null region.
1571 * Parameters: HDC hdc handle of device context
1572 * Variables :
1573 * Result : TRUE / FALSE
1574 * Remark :
1575 * Status : UNTESTED STUB
1576 *
1577 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
1578 *****************************************************************************/
1579
1580ODINFUNCTIONNODBG1(BOOL, SetMetaRgn, HDC, hdc)
1581{
1582 dprintf(("GDI32: SetMetaRgn(%08xh) not implemented.\n",
1583 hdc));
1584
1585 SetLastError(ERROR_SUCCESS_W);
1586 return (NULLREGION_W);
1587}
1588//******************************************************************************
1589//******************************************************************************
Note: See TracBrowser for help on using the repository browser.