9 // Gdi Batch Flush support functions.
15 // based on IntEngEnter from eng/engmisc.c
19 DoDeviceSync( SURFOBJ
*Surface
, PRECTL Rect
, FLONG fl
)
21 PPDEVOBJ Device
= (PDEVOBJ
*)Surface
->hdev
;
22 // No punting and "Handle to a surface, provided that the surface is device-managed.
23 // Otherwise, dhsurf is zero".
24 if (!(Device
->flFlags
& PDEV_DRIVER_PUNTED_CALL
) && (Surface
->dhsurf
))
26 if (Device
->DriverFunctions
.SynchronizeSurface
)
28 Device
->DriverFunctions
.SynchronizeSurface(Surface
, Rect
, fl
);
32 if (Device
->DriverFunctions
.Synchronize
)
34 Device
->DriverFunctions
.Synchronize(Surface
->dhpdev
, Rect
);
42 SynchonizeDriver(FLONG Flags
)
47 if (Flags
& GCAPS2_SYNCFLUSH
)
48 Flags
= DSS_FLUSH_EVENT
;
49 if (Flags
& GCAPS2_SYNCTIMER
)
50 Flags
= DSS_TIMER_EVENT
;
52 //Device = IntEnumHDev();
55 SurfObj
= 0;// EngLockSurface( Device->pSurface );
57 DoDeviceSync( SurfObj
, NULL
, Flags
);
58 EngUnlockSurface(SurfObj
);
67 GdiFlushUserBatch(PDC dc
, PGDIBATCHHDR pHdr
)
69 ULONG Cmd
= 0, Size
= 0;
70 PDC_ATTR pdcattr
= NULL
;
74 pdcattr
= dc
->pdcattr
;
80 Size
= pHdr
->Size
; // Return the full size of the structure.
82 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
84 DPRINT1("WARNING! GdiBatch Fault!\n");
85 _SEH2_YIELD(return 0;)
100 case GdiBCExtTextOut
:
103 case GdiBCSetBrushOrg
:
105 PGDIBSSETBRHORG pgSBO
;
107 pgSBO
= (PGDIBSSETBRHORG
) pHdr
;
108 pdcattr
->ptlBrushOrigin
= pgSBO
->ptlBrushOrigin
;
109 DC_vSetBrushOrigin(dc
, pgSBO
->ptlBrushOrigin
.x
, pgSBO
->ptlBrushOrigin
.y
);
113 case GdiBCExtSelClipRgn
:
121 pgO
= (PGDIBSOBJECT
) pHdr
;
123 DC_hSelectFont(dc
, (HFONT
)pgO
->hgdiobj
);
128 DPRINT("Delete Region Object!\n");
132 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
) pHdr
;
133 GreDeleteObject( pgO
->hgdiobj
);
147 * Flushes the calling thread's current batch.
155 SynchonizeDriver(GCAPS2_SYNCFLUSH
);
156 return STATUS_SUCCESS
;
160 * NtGdiFlushUserBatch
162 * Callback for thread batch flush routine.
164 * Think small & fast!
168 NtGdiFlushUserBatch(VOID
)
170 PTEB pTeb
= NtCurrentTeb();
171 ULONG GdiBatchCount
= pTeb
->GdiBatchCount
;
173 if( (GdiBatchCount
> 0) && (GdiBatchCount
<= (GDIBATCHBUFSIZE
/4)))
175 HDC hDC
= (HDC
) pTeb
->GdiTebBatch
.HDC
;
177 /* If hDC is zero and the buffer fills up with delete objects we need
180 if (hDC
|| GdiBatchCount
)
182 PCHAR pHdr
= (PCHAR
)&pTeb
->GdiTebBatch
.Buffer
[0];
185 if (GDI_HANDLE_GET_TYPE(hDC
) == GDILoObjType_LO_DC_TYPE
&& GreIsHandleValid(hDC
))
187 pDC
= DC_LockDc(hDC
);
190 // No need to init anything, just go!
191 for (; GdiBatchCount
> 0; GdiBatchCount
--)
194 // Process Gdi Batch!
195 Size
= GdiFlushUserBatch(pDC
, (PGDIBATCHHDR
) pHdr
);
205 // Exit and clear out for the next round.
206 pTeb
->GdiTebBatch
.Offset
= 0;
207 pTeb
->GdiBatchCount
= 0;
208 pTeb
->GdiTebBatch
.HDC
= 0;
212 // FIXME: On Windows XP the function returns &pTeb->RealClientId, maybe VOID?
213 return STATUS_SUCCESS
;