10 // Gdi Batch Flush support functions.
16 // based on IntEngEnter from eng/engmisc.c
20 DoDeviceSync( SURFOBJ
*Surface
, PRECTL Rect
, FLONG fl
)
22 PPDEVOBJ Device
= (PDEVOBJ
*)Surface
->hdev
;
23 // No punting and "Handle to a surface, provided that the surface is device-managed.
24 // Otherwise, dhsurf is zero".
25 if (!(Device
->flFlags
& PDEV_DRIVER_PUNTED_CALL
) && (Surface
->dhsurf
))
27 if (Device
->DriverFunctions
.SynchronizeSurface
)
29 Device
->DriverFunctions
.SynchronizeSurface(Surface
, Rect
, fl
);
33 if (Device
->DriverFunctions
.Synchronize
)
35 Device
->DriverFunctions
.Synchronize(Surface
->dhpdev
, Rect
);
43 SynchonizeDriver(FLONG Flags
)
48 if (Flags
& GCAPS2_SYNCFLUSH
)
49 Flags
= DSS_FLUSH_EVENT
;
50 if (Flags
& GCAPS2_SYNCTIMER
)
51 Flags
= DSS_TIMER_EVENT
;
53 Device
= IntEnumHDev();
56 SurfObj
= 0;// EngLockSurface( Device->pSurface );
58 DoDeviceSync( SurfObj
, NULL
, Flags
);
59 EngUnlockSurface(SurfObj
);
68 GdiFlushUserBatch(PDC dc
, PGDIBATCHHDR pHdr
)
70 PDC_ATTR pdcattr
= NULL
;
74 pdcattr
= dc
->pdcattr
;
76 // The thread is approaching the end of sunset.
79 case GdiBCPatBlt
: // Highest pri first!
87 case GdiBCSetBrushOrg
:
89 PGDIBSSETBRHORG pgSBO
;
91 pgSBO
= (PGDIBSSETBRHORG
) pHdr
;
92 pdcattr
->ptlBrushOrigin
= pgSBO
->ptlBrushOrigin
;
95 case GdiBCExtSelClipRgn
:
101 pgO
= (PGDIBSOBJECT
) pHdr
;
102 TextIntRealizeFont((HFONT
) pgO
->hgdiobj
, NULL
);
103 pdcattr
->ulDirty_
&= ~(DIRTY_CHARSET
);
108 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
) pHdr
;
109 GreDeleteObject( pgO
->hgdiobj
);
116 return pHdr
->Size
; // Return the full size of the structure.
122 * Flushes the calling thread's current batch.
128 SynchonizeDriver(GCAPS2_SYNCFLUSH
);
132 * NtGdiFlushUserBatch
134 * Callback for thread batch flush routine.
136 * Think small & fast!
140 NtGdiFlushUserBatch(VOID
)
142 PTEB pTeb
= NtCurrentTeb();
143 ULONG GdiBatchCount
= pTeb
->GdiBatchCount
;
145 if( (GdiBatchCount
> 0) && (GdiBatchCount
<= (GDIBATCHBUFSIZE
/4)))
147 HDC hDC
= (HDC
) pTeb
->GdiTebBatch
.HDC
;
149 /* If hDC is zero and the buffer fills up with delete objects we need
150 to run anyway. So, hard code to the system batch limit. */
151 if ((hDC
) || (GdiBatchCount
>= GDI_BATCH_LIMIT
))
153 PCHAR pHdr
= (PCHAR
)&pTeb
->GdiTebBatch
.Buffer
[0];
156 if (hDC
&& !IsObjectDead(hDC
))
158 pDC
= DC_LockDc(hDC
);
161 // No need to init anything, just go!
162 for (; GdiBatchCount
> 0; GdiBatchCount
--)
164 // Process Gdi Batch!
165 pHdr
+= GdiFlushUserBatch(pDC
, (PGDIBATCHHDR
) pHdr
);
173 // Exit and clear out for the next round.
174 pTeb
->GdiTebBatch
.Offset
= 0;
175 pTeb
->GdiBatchCount
= 0;
176 pTeb
->GdiTebBatch
.HDC
= 0;
180 // FIXME: on xp the function returns &pTeb->RealClientId, maybe VOID?
181 return STATUS_SUCCESS
;