* the y-x-banding that's so nice to have...
*/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
else
{
xrect = ExAllocatePoolWithTag(PagedPool, rgnSrc->rdh.nCount * sizeof(RECT), TAG_REGION);
+ if(!xrect)
+ return FALSE;
if (rgnDst->Buffer && rgnDst->Buffer != &rgnDst->rdh.rcBound)
ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION); //free the old buffer. will be assigned to xrect below.
}
- if (xrect)
+ if (rgnDst != rgnSrc)
{
- ULONG i;
-
- if (rgnDst != rgnSrc)
- {
- *rgnDst = *rgnSrc;
- }
+ *rgnDst = *rgnSrc;
+ }
- if (off->x || off->y)
- {
- for (i = 0; i < rgnDst->rdh.nCount; i++)
- {
- xrect[i].left = (rgnSrc->Buffer + i)->left + off->x;
- xrect[i].right = (rgnSrc->Buffer + i)->right + off->x;
- xrect[i].top = (rgnSrc->Buffer + i)->top + off->y;
- xrect[i].bottom = (rgnSrc->Buffer + i)->bottom + off->y;
- }
- rgnDst->rdh.rcBound.left += off->x;
- rgnDst->rdh.rcBound.right += off->x;
- rgnDst->rdh.rcBound.top += off->y;
- rgnDst->rdh.rcBound.bottom += off->y;
- }
- else
+ if (off->x || off->y)
+ {
+ ULONG i;
+ for (i = 0; i < rgnDst->rdh.nCount; i++)
{
- COPY_RECTS(xrect, rgnSrc->Buffer, rgnDst->rdh.nCount);
+ xrect[i].left = (rgnSrc->Buffer + i)->left + off->x;
+ xrect[i].right = (rgnSrc->Buffer + i)->right + off->x;
+ xrect[i].top = (rgnSrc->Buffer + i)->top + off->y;
+ xrect[i].bottom = (rgnSrc->Buffer + i)->bottom + off->y;
}
-
- rgnDst->Buffer = xrect;
+ rgnDst->rdh.rcBound.left += off->x;
+ rgnDst->rdh.rcBound.right += off->x;
+ rgnDst->rdh.rcBound.top += off->y;
+ rgnDst->rdh.rcBound.bottom += off->y;
}
else
- return FALSE;
+ {
+ COPY_RECTS(xrect, rgnSrc->Buffer, rgnDst->rdh.nCount);
+ }
+
+ rgnDst->Buffer = xrect;
}
else if ((rect->left >= rect->right) ||
(rect->top >= rect->bottom) ||
{
HRGN hReg;
PROSRGNDATA pReg;
- INT Index;
- PGDI_TABLE_ENTRY Entry;
-
+
pReg = (PROSRGNDATA)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION);
if(!pReg)
{
return NULL;
}
-
+
hReg = pReg->BaseObject.hHmgr;
if (nReg == 0 || nReg == 1)
}
}
- KeEnterCriticalRegion();
- Index = GDI_HANDLE_GET_INDEX(hReg);
- Entry = &GdiHandleTable->Entries[Index];
- Entry->UserData = AllocateObjectAttr();
- KeLeaveCriticalRegion();
-
EMPTY_REGION(pReg);
pReg->rdh.dwSize = sizeof(RGNDATAHEADER);
pReg->rdh.nCount = nReg;
return pReg;
}
+//
+// Allocate User Space Region Handle.
+//
+PROSRGNDATA
+FASTCALL
+REGION_AllocUserRgnWithHandle(INT nRgn)
+{
+ PROSRGNDATA pRgn;
+ PGDI_TABLE_ENTRY Entry;
+
+ pRgn = REGION_AllocRgnWithHandle(nRgn);
+ if (pRgn)
+ {
+ Entry = GDI_HANDLE_GET_ENTRY(GdiHandleTable, pRgn->BaseObject.hHmgr);
+ Entry->UserData = AllocateObjectAttr();
+ }
+ return pRgn;
+}
+
PROSRGNDATA
FASTCALL
RGNOBJAPI_Lock(HRGN hRgn, PRGN_ATTR *ppRgn_Attr)
{
- INT Index;
PGDI_TABLE_ENTRY Entry;
- PROSRGNDATA pRgn;
PRGN_ATTR pRgn_Attr;
- HANDLE pid;
+ PROSRGNDATA pRgn = NULL;
pRgn = REGION_LockRgn(hRgn);
- if (pRgn)
+ if (pRgn && GDIOBJ_OwnedByCurrentProcess(hRgn))
{
- KeEnterCriticalRegion();
- Index = GDI_HANDLE_GET_INDEX(hRgn);
- Entry = &GdiHandleTable->Entries[Index];
+ Entry = GDI_HANDLE_GET_ENTRY(GdiHandleTable, hRgn);
pRgn_Attr = Entry->UserData;
- pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
- KeLeaveCriticalRegion();
- if ( pid == NtCurrentTeb()->ClientId.UniqueProcess &&
- pRgn_Attr )
+ if ( pRgn_Attr )
{
_SEH2_TRY
{
FASTCALL
RGNOBJAPI_Unlock(PROSRGNDATA pRgn)
{
- INT Index;
PGDI_TABLE_ENTRY Entry;
PRGN_ATTR pRgn_Attr;
- HANDLE pid;
- if (pRgn)
+ if (pRgn && GDIOBJ_OwnedByCurrentProcess(pRgn->BaseObject.hHmgr))
{
- KeEnterCriticalRegion();
- Index = GDI_HANDLE_GET_INDEX(pRgn->BaseObject.hHmgr);
- Entry = &GdiHandleTable->Entries[Index];
+ Entry = GDI_HANDLE_GET_ENTRY(GdiHandleTable, pRgn->BaseObject.hHmgr);
pRgn_Attr = Entry->UserData;
- pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
- KeLeaveCriticalRegion();
- if ( pid == NtCurrentTeb()->ClientId.UniqueProcess &&
- pRgn_Attr )
+ if ( pRgn_Attr )
{
_SEH2_TRY
{
//
// System Region Functions
//
-INT
-FASTCALL
-IntSysRegComplexity(HRGN hRgn)
-{
- PROSRGNDATA pRgn;
- INT Ret;
-
- pRgn = REGION_LockRgn(hRgn);
- Ret = REGION_Complexity( pRgn );
- REGION_UnlockRgn(pRgn);
- return Ret;
-}
-
-HRGN
+PROSRGNDATA
FASTCALL
-IntSysCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
+IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
{
PROSRGNDATA pRgn;
- HRGN hRgn;
pRgn = (PROSRGNDATA)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION);
if (!pRgn)
{
return NULL;
}
- hRgn = pRgn->BaseObject.hHmgr;
pRgn->Buffer = &pRgn->rdh.rcBound;
REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect);
REGION_UnlockRgn(pRgn);
- return hRgn;
+ return pRgn;
+}
+
+HRGN
+FASTCALL
+IntSysCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
+{
+ PROSRGNDATA pRgn = IntSysCreateRectpRgn(LeftRect,TopRect,RightRect,BottomRect);
+ return (pRgn ? pRgn->BaseObject.hHmgr : NULL);
}
BOOL INTERNAL_CALL
{
PROSRGNDATA pRgn = (PROSRGNDATA)ObjectBody;
if (pRgn->Buffer && pRgn->Buffer != &pRgn->rdh.rcBound)
- ExFreePool(pRgn->Buffer);
+ ExFreePoolWithTag(pRgn->Buffer, TAG_REGION);
return TRUE;
}
else if (src2Rgn == NULL)
{
DPRINT1("IntGdiCombineRgn requires hSrc2 != NULL for combine mode %d!\n", CombineMode);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
}
}
}
else
{
DPRINT("IntGdiCombineRgn: hSrc1 unavailable\n");
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
}
}
else
{
DPRINT("IntGdiCombineRgn: hDest unavailable\n");
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
}
return result;
}
-PROSRGNDATA
-FASTCALL
-IntGdiCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
-{
- PROSRGNDATA pRgn;
-
- if (!(pRgn = REGION_AllocRgnWithHandle(1))) return NULL;
-
- REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect);
- RGNOBJAPI_Unlock(pRgn);
- // Return pointer with Share locks.
- pRgn = GDIOBJ_ShareLockObj(pRgn->BaseObject.hHmgr, GDI_OBJECT_TYPE_REGION);
-
- return pRgn;
-}
-
INT FASTCALL
REGION_GetRgnBox(
PROSRGNDATA Rgn,
ASSERT(!(pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)));
- if (!(tmpVisRgn = NtGdiCreateRectRgn(0, 0, 0, 0))) return FALSE;
+ if (!(tmpVisRgn = IntSysCreateRectRgn(0, 0, 0, 0))) return FALSE;
// Transform region into device co-ords
- if (!REGION_LPTODP(dc, tmpVisRgn, hRgn) ||
+ if (!REGION_LPTODP(dc, tmpVisRgn, hRgn) ||
NtGdiOffsetRgn(tmpVisRgn, dc->ptlDCOrig.x, dc->ptlDCOrig.y) == ERROR)
{
- GreDeleteObject(tmpVisRgn);
+ REGION_FreeRgnByHandle(tmpVisRgn);
return FALSE;
}
visrgn = RGNOBJAPI_Lock(tmpVisRgn, NULL);
if (visrgn == NULL)
{
- GreDeleteObject(tmpVisRgn);
+ REGION_FreeRgnByHandle(tmpVisRgn);
return FALSE;
}
0xFFFF);//FIXME:don't know what to put here
RGNOBJAPI_Unlock(visrgn);
- GreDeleteObject(tmpVisRgn);
+ REGION_FreeRgnByHandle(tmpVisRgn);
// Fill the region
- return TRUE;
+ return bRet;
}
BOOL
}
}
+INT
+FASTCALL
+IntGdiOffsetRgn(
+ PROSRGNDATA rgn,
+ INT XOffset,
+ INT YOffset )
+{
+ if (XOffset || YOffset)
+ {
+ int nbox = rgn->rdh.nCount;
+ PRECTL pbox = rgn->Buffer;
+
+ if (nbox && pbox)
+ {
+ while (nbox--)
+ {
+ pbox->left += XOffset;
+ pbox->right += XOffset;
+ pbox->top += YOffset;
+ pbox->bottom += YOffset;
+ pbox++;
+ }
+ if (rgn->Buffer != &rgn->rdh.rcBound)
+ {
+ rgn->rdh.rcBound.left += XOffset;
+ rgn->rdh.rcBound.right += XOffset;
+ rgn->rdh.rcBound.top += YOffset;
+ rgn->rdh.rcBound.bottom += YOffset;
+ }
+ }
+ }
+ return REGION_Complexity(rgn);
+}
+
/***********************************************************************
* REGION_InsertEdgeInET
*
if (mode == 0 || mode > 2) return 0;
- if (!(region = REGION_AllocRgnWithHandle(nbpolygons)))
+ if (!(region = REGION_AllocUserRgnWithHandle(nbpolygons)))
return 0;
hrgn = region->BaseObject.hHmgr;
if ( CombineMode > RGN_COPY && CombineMode < RGN_AND)
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return ERROR;
}
destRgn = RGNOBJAPI_Lock(hDest, NULL);
if (!destRgn)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
if (!src1Rgn)
{
RGNOBJAPI_Unlock(destRgn);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return ERROR;
}
HRGN hRgn;
/* Allocate region data structure with space for 1 RECTL */
- if (!(pRgn = REGION_AllocRgnWithHandle(1)))
+ if (!(pRgn = REGION_AllocUserRgnWithHandle(1)))
{
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
hRgn = pRgn->BaseObject.hHmgr;
/* Create region */
d = (ellipse_height < 128) ? ((3 * ellipse_height) >> 2) : 64;
- if (!(obj = REGION_AllocRgnWithHandle(d))) return 0;
+ if (!(obj = REGION_AllocUserRgnWithHandle(d))) return 0;
hrgn = obj->BaseObject.hHmgr;
/* Ellipse algorithm, based on an article by K. Porter */
return ERROR;
}
- if (rgn1->rdh.nCount != rgn2->rdh.nCount ||
- rgn1->rdh.nCount == 0 ||
- rgn1->rdh.rcBound.left != rgn2->rdh.rcBound.left ||
- rgn1->rdh.rcBound.right != rgn2->rdh.rcBound.right ||
- rgn1->rdh.rcBound.top != rgn2->rdh.rcBound.top ||
- rgn1->rdh.rcBound.bottom != rgn2->rdh.rcBound.bottom)
- goto exit;
+ if ( rgn1->rdh.nCount != rgn2->rdh.nCount ) goto exit;
+
+ if ( rgn1->rdh.nCount == 0 )
+ {
+ bRet = TRUE;
+ goto exit;
+ }
+
+ if ( rgn1->rdh.rcBound.left != rgn2->rdh.rcBound.left ||
+ rgn1->rdh.rcBound.right != rgn2->rdh.rcBound.right ||
+ rgn1->rdh.rcBound.top != rgn2->rdh.rcBound.top ||
+ rgn1->rdh.rcBound.bottom != rgn2->rdh.rcBound.bottom )
+ goto exit;
tRect1 = rgn1->Buffer;
tRect2 = rgn2->Buffer;
if (!tRect1 || !tRect2)
- goto exit;
+ goto exit;
for (i=0; i < rgn1->rdh.nCount; i++)
{
- if (tRect1[i].left != tRect2[i].left ||
- tRect1[i].right != tRect2[i].right ||
- tRect1[i].top != tRect2[i].top ||
- tRect1[i].bottom != tRect2[i].bottom)
- goto exit;
+ if ( tRect1[i].left != tRect2[i].left ||
+ tRect1[i].right != tRect2[i].right ||
+ tRect1[i].top != tRect2[i].top ||
+ tRect1[i].bottom != tRect2[i].bottom )
+ goto exit;
}
bRet = TRUE;
DWORD dwSize = 0;
NTSTATUS Status = STATUS_SUCCESS;
MATRIX matrix;
+ XFORMOBJ xo;
DPRINT("NtGdiExtCreateRegion\n");
_SEH2_TRY
return NULL;
}
- Region = REGION_AllocRgnWithHandle(nCount);
+ Region = REGION_AllocUserRgnWithHandle(nCount);
if (Region == NULL)
{
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
hRgn = Region->BaseObject.hHmgr;
/* Init the XFORMOBJ from the Xform struct */
Status = STATUS_INVALID_PARAMETER;
- ret = XFORMOBJ_iSetXform((XFORMOBJ*)&matrix, (XFORML*)Xform);
+ XFORMOBJ_vInit(&xo, &matrix);
+ ret = XFORMOBJ_iSetXform(&xo, (XFORML*)Xform);
/* Check for error, also no scale and shear allowed */
if (ret != DDI_ERROR && ret != GX_GENERAL)
{
/* Apply the coordinate transformation on the rects */
- if (XFORMOBJ_bApplyXform((XFORMOBJ*)&matrix,
+ if (XFORMOBJ_bApplyXform(&xo,
XF_LTOL,
nCount * 2,
RgnData->Buffer,
_SEH2_END;
if (!NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
RGNOBJAPI_Unlock(Region);
GreDeleteObject(hRgn);
return NULL;
HRGN FrameRgn;
BOOL Ret;
- if (!(FrameRgn = NtGdiCreateRectRgn(0, 0, 0, 0)))
+ if (!(FrameRgn = IntSysCreateRectRgn(0, 0, 0, 0)))
{
return FALSE;
}
if (!REGION_CreateFrameRgn(FrameRgn, hRgn, Width, Height))
{
- GreDeleteObject(FrameRgn);
+ REGION_FreeRgnByHandle(FrameRgn);
return FALSE;
}
Ret = NtGdiFillRgn(hDC, FrameRgn, hBrush);
- GreDeleteObject(FrameRgn);
+ REGION_FreeRgnByHandle(FrameRgn);
return Ret;
}
-/* See wine, msdn, osr and Feng Yuan - Windows Graphics Programming Win32 Gdi And Directdraw
-
- 1st: http://www.codeproject.com/gdi/cliprgnguide.asp is wrong!
-
- The intersection of the clip with the meta region is not Rao it's API!
- Go back and read 7.2 Clipping pages 418-19:
- Rao = API & Vis:
- 1) The Rao region is the intersection of the API region and the system region,
- named after the Microsoft engineer who initially proposed it.
- 2) The Rao region can be calculated from the API region and the system region.
-
- API:
- API region is the intersection of the meta region and the clipping region,
- clearly named after the fact that it is controlled by GDI API calls.
-*/
-INT APIENTRY
-NtGdiGetRandomRgn(
- HDC hDC,
- HRGN hDest,
- INT iCode
-)
-{
- INT ret = 0;
- PDC pDC;
- HRGN hSrc = NULL;
- POINT org;
-
- pDC = DC_LockDc(hDC);
- if (pDC == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return -1;
- }
-
- switch (iCode)
- {
- case CLIPRGN:
- hSrc = pDC->rosdc.hClipRgn;
-// if (pDC->dclevel.prgnClip) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnClip)->BaseObject.hHmgr;
- break;
- case METARGN:
- if (pDC->dclevel.prgnMeta) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.hHmgr;
- break;
- case APIRGN:
- hSrc = pDC->rosdc.hClipRgn;
-// if (pDC->prgnAPI) hSrc = ((PROSRGNDATA)pDC->prgnAPI)->BaseObject.hHmgr;
-// else if (pDC->dclevel.prgnClip) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnClip)->BaseObject.hHmgr;
-// else if (pDC->dclevel.prgnMeta) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.hHmgr;
- break;
- case SYSRGN:
- hSrc = pDC->rosdc.hVisRgn;
-// if (pDC->prgnVis) hSrc = ((PROSRGNDATA)pDC->prgnVis)->BaseObject.hHmgr;
- break;
- default:
- hSrc = 0;
- }
- if (hSrc)
- {
- if (NtGdiCombineRgn(hDest, hSrc, 0, RGN_COPY) == ERROR)
- {
- ret = -1;
- }
- else
- {
- ret = 1;
- }
- }
- if (iCode == SYSRGN)
- {
- IntGdiGetDCOrg(pDC, &org);
- NtGdiOffsetRgn(hDest, org.x, org.y );
- }
-
- DC_UnlockDc(pDC);
-
- return ret;
-}
-
INT APIENTRY
NtGdiGetRgnBox(
HRGN hRgn,
if (!(RgnData = RGNOBJAPI_Lock(hRgn, NULL)))
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return ERROR;
}
- if (XOffset || YOffset)
- {
- int nbox = rgn->rdh.nCount;
- PRECTL pbox = rgn->Buffer;
+ ret = IntGdiOffsetRgn(rgn, XOffset, YOffset);
- if (nbox && pbox)
- {
- while (nbox--)
- {
- pbox->left += XOffset;
- pbox->right += XOffset;
- pbox->top += YOffset;
- pbox->bottom += YOffset;
- pbox++;
- }
- if (rgn->Buffer != &rgn->rdh.rcBound)
- {
- rgn->rdh.rcBound.left += XOffset;
- rgn->rdh.rcBound.right += XOffset;
- rgn->rdh.rcBound.top += YOffset;
- rgn->rdh.rcBound.bottom += YOffset;
- }
- }
- }
- ret = REGION_Complexity(rgn);
RGNOBJAPI_Unlock(rgn);
return ret;
}
if (!(Rgn = RGNOBJAPI_Lock(hDest, NULL)))
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return NULL;
}