mirror of
https://github.com/reactos/reactos.git
synced 2024-09-30 22:47:28 +00:00
Win32k:
- Forked dcutil and gdibatch. - Added our first batch SetBrushOrg. - cleaned up dcutil. - Added dcattr support for NtGdiSetBrushOrg. - Tested with qemu and hardware. Needs vendor app testing. svn path=/trunk/; revision=30064
This commit is contained in:
parent
6383a43920
commit
405a934dab
|
@ -624,6 +624,31 @@ NtGdiSetBrushOrg(HDC hDC, INT XOrg, INT YOrg, LPPOINT Point)
|
|||
|
||||
dc->Dc_Attr.ptlBrushOrigin.x = XOrg;
|
||||
dc->Dc_Attr.ptlBrushOrigin.y = YOrg;
|
||||
|
||||
if (dc->pDc_Attr)
|
||||
{
|
||||
PDC_ATTR Dc_Attr = dc->pDc_Attr;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(Dc_Attr,
|
||||
sizeof(DC_ATTR),
|
||||
1);
|
||||
Dc_Attr->ptlBrushOrigin = dc->Dc_Attr.ptlBrushOrigin;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DC_UnlockDc(dc);
|
||||
SetLastNtError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
DC_UnlockDc(dc);
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -30,8 +30,7 @@ CopytoUserDcAttr(PDC dc, PDC_ATTR Dc_Attr, FLONG Dirty)
|
|||
Dc_Attr->ulPenClr = dc->Dc_Attr.ulPenClr;
|
||||
Dc_Attr->crPenClr = dc->Dc_Attr.crPenClr;
|
||||
|
||||
Dc_Attr->ptlBrushOrigin.x = dc->Dc_Attr.ptlBrushOrigin.x;
|
||||
Dc_Attr->ptlBrushOrigin.y = dc->Dc_Attr.ptlBrushOrigin.y;
|
||||
Dc_Attr->ptlBrushOrigin = dc->Dc_Attr.ptlBrushOrigin;
|
||||
|
||||
Dc_Attr->lTextAlign = dc->Dc_Attr.lTextAlign;
|
||||
Dc_Attr->lTextExtra = dc->Dc_Attr.lTextExtra;
|
||||
|
@ -40,16 +39,11 @@ CopytoUserDcAttr(PDC dc, PDC_ATTR Dc_Attr, FLONG Dirty)
|
|||
Dc_Attr->iMapMode = dc->Dc_Attr.iMapMode;
|
||||
Dc_Attr->iGraphicsMode = dc->Dc_Attr.iGraphicsMode;
|
||||
|
||||
Dc_Attr->ptlCurrent.x = dc->Dc_Attr.ptlCurrent.x;
|
||||
Dc_Attr->ptlCurrent.y = dc->Dc_Attr.ptlCurrent.y;
|
||||
Dc_Attr->ptlWindowOrg.x = dc->Dc_Attr.ptlWindowOrg.x;
|
||||
Dc_Attr->ptlWindowOrg.y = dc->Dc_Attr.ptlWindowOrg.y;
|
||||
Dc_Attr->szlWindowExt.cx = dc->Dc_Attr.szlWindowExt.cx;
|
||||
Dc_Attr->szlWindowExt.cy = dc->Dc_Attr.szlWindowExt.cy;
|
||||
Dc_Attr->ptlViewportOrg.x = dc->Dc_Attr.ptlViewportOrg.x;
|
||||
Dc_Attr->ptlViewportOrg.y = dc->Dc_Attr.ptlViewportOrg.y;
|
||||
Dc_Attr->szlViewportExt.cx = dc->Dc_Attr.szlViewportExt.cx;
|
||||
Dc_Attr->szlViewportExt.cy = dc->Dc_Attr.szlViewportExt.cy;
|
||||
Dc_Attr->ptlCurrent = dc->Dc_Attr.ptlCurrent;
|
||||
Dc_Attr->ptlWindowOrg = dc->Dc_Attr.ptlWindowOrg;
|
||||
Dc_Attr->szlWindowExt = dc->Dc_Attr.szlWindowExt;
|
||||
Dc_Attr->ptlViewportOrg = dc->Dc_Attr.ptlViewportOrg;
|
||||
Dc_Attr->szlViewportExt = dc->Dc_Attr.szlViewportExt;
|
||||
|
||||
Dc_Attr->ulDirty_ = dc->Dc_Attr.ulDirty_; //Copy flags! We may have set them.
|
||||
|
||||
|
@ -268,80 +262,3 @@ DCU_SynchDcAttrtoW32k(HDC hDC, FLONG Dirty)
|
|||
return Ret;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Gdi Batch Flush support functions.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Process the batch.
|
||||
//
|
||||
ULONG
|
||||
FASTCALL
|
||||
GdiFlushUserBatch(HDC hDC, PGDIBATCHHDR pHdr)
|
||||
{
|
||||
switch(pHdr->Cmd)
|
||||
{
|
||||
case GdiBCPatBlt: // Highest pri first!
|
||||
case GdiBCPolyPatBlt:
|
||||
case GdiBCTextOut:
|
||||
case GdiBCExtTextOut:
|
||||
case GdiBCSetBrushOrg:
|
||||
case GdiBCExtSelClipRgn:
|
||||
case GdiBCSelObj:
|
||||
case GdiBCDelObj:
|
||||
case GdiBCDelRgn:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return pHdr->Size; // Return the full size of the structure.
|
||||
}
|
||||
|
||||
/*
|
||||
* NtGdiFlush
|
||||
*
|
||||
* Flushes the calling thread's current batch.
|
||||
*/
|
||||
VOID
|
||||
APIENTRY
|
||||
NtGdiFlush(VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* NtGdiFlushUserBatch
|
||||
*
|
||||
* Callback for thread batch flush routine.
|
||||
*
|
||||
* Think small & fast!
|
||||
*/
|
||||
NTSTATUS
|
||||
APIENTRY
|
||||
NtGdiFlushUserBatch(VOID)
|
||||
{
|
||||
PTEB pTeb = NtCurrentTeb();
|
||||
ULONG GdiBatchCount = pTeb->GdiBatchCount;
|
||||
|
||||
if( (GdiBatchCount > 0) && (GdiBatchCount <= GDIBATCHBUFSIZE))
|
||||
{
|
||||
HDC hDC = (HDC) pTeb->GdiTebBatch.HDC;
|
||||
if (hDC)
|
||||
{
|
||||
PULONG pHdr = &pTeb->GdiTebBatch.Buffer[0];
|
||||
// No need to init anything, just go!
|
||||
for (; GdiBatchCount > 0; GdiBatchCount--)
|
||||
{
|
||||
// Process Gdi Batch!
|
||||
pHdr += GdiFlushUserBatch( hDC, (PGDIBATCHHDR) pHdr );
|
||||
}
|
||||
// Exit and clear out for the next round.
|
||||
pTeb->GdiTebBatch.Offset = 0;
|
||||
pTeb->GdiBatchCount = 0;
|
||||
pTeb->GdiTebBatch.HDC = 0;
|
||||
}
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
102
reactos/subsystems/win32/win32k/objects/gdibatch.c
Normal file
102
reactos/subsystems/win32/win32k/objects/gdibatch.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
|
||||
#include <w32k.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// Gdi Batch Flush support functions.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Process the batch.
|
||||
//
|
||||
ULONG
|
||||
FASTCALL
|
||||
GdiFlushUserBatch(HDC hDC, PGDIBATCHHDR pHdr)
|
||||
{
|
||||
PDC dc = DC_LockDc(hDC);
|
||||
if (!dc) return 0;
|
||||
// The thread is on the end of sunset.
|
||||
switch(pHdr->Cmd)
|
||||
{
|
||||
case GdiBCPatBlt: // Highest pri first!
|
||||
break;
|
||||
case GdiBCPolyPatBlt:
|
||||
break;
|
||||
case GdiBCTextOut:
|
||||
break;
|
||||
case GdiBCExtTextOut:
|
||||
break;
|
||||
case GdiBCSetBrushOrg:
|
||||
{
|
||||
PGDIBSSETBRHORG pgSBO = (PGDIBSSETBRHORG) pHdr;
|
||||
dc->Dc_Attr.ptlBrushOrigin = pgSBO->ptlBrushOrigin;
|
||||
break;
|
||||
}
|
||||
case GdiBCExtSelClipRgn:
|
||||
break;
|
||||
case GdiBCSelObj:
|
||||
break;
|
||||
case GdiBCDelObj:
|
||||
break;
|
||||
case GdiBCDelRgn:
|
||||
break;
|
||||
default:
|
||||
DC_UnlockDc(dc);
|
||||
return 0;
|
||||
}
|
||||
DC_UnlockDc(dc);
|
||||
return pHdr->Size; // Return the full size of the structure.
|
||||
}
|
||||
|
||||
/*
|
||||
* NtGdiFlush
|
||||
*
|
||||
* Flushes the calling thread's current batch.
|
||||
*/
|
||||
VOID
|
||||
APIENTRY
|
||||
NtGdiFlush(VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* NtGdiFlushUserBatch
|
||||
*
|
||||
* Callback for thread batch flush routine.
|
||||
*
|
||||
* Think small & fast!
|
||||
*/
|
||||
NTSTATUS
|
||||
APIENTRY
|
||||
NtGdiFlushUserBatch(VOID)
|
||||
{
|
||||
PTEB pTeb = NtCurrentTeb();
|
||||
ULONG GdiBatchCount = pTeb->GdiBatchCount;
|
||||
|
||||
if( (GdiBatchCount > 0) && (GdiBatchCount <= GDIBATCHBUFSIZE))
|
||||
{
|
||||
HDC hDC = (HDC) pTeb->GdiTebBatch.HDC;
|
||||
if (hDC)
|
||||
{
|
||||
PULONG pHdr = &pTeb->GdiTebBatch.Buffer[0];
|
||||
// No need to init anything, just go!
|
||||
for (; GdiBatchCount > 0; GdiBatchCount--)
|
||||
{
|
||||
// Process Gdi Batch!
|
||||
pHdr += GdiFlushUserBatch( hDC, (PGDIBATCHHDR) pHdr );
|
||||
}
|
||||
// Exit and clear out for the next round.
|
||||
pTeb->GdiTebBatch.Offset = 0;
|
||||
pTeb->GdiBatchCount = 0;
|
||||
pTeb->GdiTebBatch.HDC = 0;
|
||||
}
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -148,6 +148,7 @@
|
|||
<file>dcutil.c</file>
|
||||
<file>dibobj.c</file>
|
||||
<file>fillshap.c</file>
|
||||
<file>gdibatch.c</file>
|
||||
<file>gdiobj.c</file>
|
||||
<file>icm.c</file>
|
||||
<file>line.c</file>
|
||||
|
|
Loading…
Reference in a new issue