7 BOOL FASTCALL
IntPatBlt( PDC
,INT
,INT
,INT
,INT
,DWORD
,PEBRUSHOBJ
);
8 BOOL APIENTRY
IntExtTextOutW(IN PDC
,IN INT
,IN INT
,IN UINT
,IN OPTIONAL PRECTL
,IN LPCWSTR
,IN INT
,IN OPTIONAL LPINT
,IN DWORD
);
12 // Gdi Batch Flush support functions.
18 // based on IntEngEnter from eng/engmisc.c
22 DoDeviceSync( SURFOBJ
*Surface
, PRECTL Rect
, FLONG fl
)
24 PPDEVOBJ Device
= (PDEVOBJ
*)Surface
->hdev
;
25 // No punting and "Handle to a surface, provided that the surface is device-managed.
26 // Otherwise, dhsurf is zero".
27 if (!(Device
->flFlags
& PDEV_DRIVER_PUNTED_CALL
) && (Surface
->dhsurf
))
29 if (Device
->DriverFunctions
.SynchronizeSurface
)
31 Device
->DriverFunctions
.SynchronizeSurface(Surface
, Rect
, fl
);
35 if (Device
->DriverFunctions
.Synchronize
)
37 Device
->DriverFunctions
.Synchronize(Surface
->dhpdev
, Rect
);
45 SynchronizeDriver(FLONG Flags
)
50 if (Flags
& GCAPS2_SYNCFLUSH
)
51 Flags
= DSS_FLUSH_EVENT
;
52 if (Flags
& GCAPS2_SYNCTIMER
)
53 Flags
= DSS_TIMER_EVENT
;
55 //Device = IntEnumHDev();
58 SurfObj
= 0;// EngLockSurface( Device->pSurface );
60 DoDeviceSync( SurfObj
, NULL
, Flags
);
61 EngUnlockSurface(SurfObj
);
70 GdiFlushUserBatch(PDC dc
, PGDIBATCHHDR pHdr
)
72 ULONG Cmd
= 0, Size
= 0;
73 PDC_ATTR pdcattr
= NULL
;
77 pdcattr
= dc
->pdcattr
;
83 Size
= pHdr
->Size
; // Return the full size of the structure.
85 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
87 DPRINT1("WARNING! GdiBatch Fault!\n");
88 _SEH2_YIELD(return 0;)
99 COLORREF crColor
, crBkColor
, crBrushClr
;
100 ULONG ulForegroundClr
, ulBackgroundClr
, ulBrushClr
;
102 pgDPB
= (PGDIBSPATBLT
) pHdr
;
103 /* Convert the ROP3 to a ROP4 */
104 dwRop
= pgDPB
->dwRop
;
105 dwRop
= MAKEROP4(dwRop
& 0xFF0000, dwRop
);
106 /* Check if the rop uses a source */
107 if (WIN32_ROP4_USES_SOURCE(dwRop
))
109 /* This is not possible */
112 /* Check if the DC has no surface (empty mem or info DC) */
113 if (dc
->dclevel
.pSurface
== NULL
)
118 // Save current attributes and flags
119 crColor
= dc
->pdcattr
->crForegroundClr
;
120 crBkColor
= dc
->pdcattr
->ulBackgroundClr
;
121 crBrushClr
= dc
->pdcattr
->crBrushClr
;
122 ulForegroundClr
= dc
->pdcattr
->ulForegroundClr
;
123 ulBackgroundClr
= dc
->pdcattr
->ulBackgroundClr
;
124 ulBrushClr
= dc
->pdcattr
->ulBrushClr
;
125 hOrgBrush
= dc
->pdcattr
->hbrush
;
126 flags
= dc
->pdcattr
->ulDirty_
& (DIRTY_BACKGROUND
| DIRTY_TEXT
| DIRTY_FILL
| DC_BRUSH_DIRTY
);
127 // Set the attribute snapshot
128 dc
->pdcattr
->hbrush
= pgDPB
->hbrush
;
129 dc
->pdcattr
->crForegroundClr
= pgDPB
->crForegroundClr
;
130 dc
->pdcattr
->crBackgroundClr
= pgDPB
->crBackgroundClr
;
131 dc
->pdcattr
->crBrushClr
= pgDPB
->crBrushClr
;
132 dc
->pdcattr
->ulForegroundClr
= pgDPB
->ulForegroundClr
;
133 dc
->pdcattr
->ulBackgroundClr
= pgDPB
->ulBackgroundClr
;
134 dc
->pdcattr
->ulBrushClr
= pgDPB
->ulBrushClr
;
135 // Process dirty attributes if any.
136 if (dc
->pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
137 DC_vUpdateFillBrush(dc
);
138 if (dc
->pdcattr
->ulDirty_
& DIRTY_TEXT
)
139 DC_vUpdateTextBrush(dc
);
140 if (pdcattr
->ulDirty_
& DIRTY_BACKGROUND
)
141 DC_vUpdateBackgroundBrush(dc
);
142 /* Call the internal function */
143 IntPatBlt(dc
, pgDPB
->nXLeft
, pgDPB
->nYLeft
, pgDPB
->nWidth
, pgDPB
->nHeight
, dwRop
, &dc
->eboFill
);
144 // Restore attributes and flags
145 dc
->pdcattr
->hbrush
= hOrgBrush
;
146 dc
->pdcattr
->crForegroundClr
= crColor
;
147 dc
->pdcattr
->crBackgroundClr
= crBkColor
;
148 dc
->pdcattr
->crBrushClr
= crBrushClr
;
149 dc
->pdcattr
->ulForegroundClr
= ulForegroundClr
;
150 dc
->pdcattr
->ulBackgroundClr
= ulBackgroundClr
;
151 dc
->pdcattr
->ulBrushClr
= ulBrushClr
;
152 dc
->pdcattr
->ulDirty_
|= flags
;
156 case GdiBCPolyPatBlt
:
164 COLORREF crColor
, crBkColor
, crBrushClr
;
165 ULONG ulForegroundClr
, ulBackgroundClr
, ulBrushClr
;
167 pgDPB
= (PGDIBSPPATBLT
) pHdr
;
168 /* Convert the ROP3 to a ROP4 */
170 dwRop
= MAKEROP4(dwRop
& 0xFF0000, dwRop
);
171 /* Check if the rop uses a source */
172 if (WIN32_ROP4_USES_SOURCE(dwRop
))
174 /* This is not possible */
177 /* Check if the DC has no surface (empty mem or info DC) */
178 if (dc
->dclevel
.pSurface
== NULL
)
183 // Save current attributes and flags
184 crColor
= dc
->pdcattr
->crForegroundClr
;
185 crBkColor
= dc
->pdcattr
->ulBackgroundClr
;
186 crBrushClr
= dc
->pdcattr
->crBrushClr
;
187 ulForegroundClr
= dc
->pdcattr
->ulForegroundClr
;
188 ulBackgroundClr
= dc
->pdcattr
->ulBackgroundClr
;
189 ulBrushClr
= dc
->pdcattr
->ulBrushClr
;
190 flags
= dc
->pdcattr
->ulDirty_
& (DIRTY_BACKGROUND
| DIRTY_TEXT
| DIRTY_FILL
| DC_BRUSH_DIRTY
);
191 // Set the attribute snapshot
192 dc
->pdcattr
->crForegroundClr
= pgDPB
->crForegroundClr
;
193 dc
->pdcattr
->crBackgroundClr
= pgDPB
->crBackgroundClr
;
194 dc
->pdcattr
->crBrushClr
= pgDPB
->crBrushClr
;
195 dc
->pdcattr
->ulForegroundClr
= pgDPB
->ulForegroundClr
;
196 dc
->pdcattr
->ulBackgroundClr
= pgDPB
->ulBackgroundClr
;
197 dc
->pdcattr
->ulBrushClr
= pgDPB
->ulBrushClr
;
198 // Process dirty attributes if any
199 if (dc
->pdcattr
->ulDirty_
& DIRTY_TEXT
)
200 DC_vUpdateTextBrush(dc
);
201 if (pdcattr
->ulDirty_
& DIRTY_BACKGROUND
)
202 DC_vUpdateBackgroundBrush(dc
);
204 DPRINT1("GdiBCPolyPatBlt Testing\n");
205 pRects
= &pgDPB
->pRect
[0];
207 for (i
= 0; i
< pgDPB
->Count
; i
++)
209 pbrush
= BRUSH_ShareLockBrush(pRects
->hBrush
);
211 /* Check if we could lock the brush */
214 /* Initialize a brush object */
215 EBRUSHOBJ_vInitFromDC(&eboFill
, pbrush
, dc
);
226 /* Cleanup the brush object and unlock the brush */
227 EBRUSHOBJ_vCleanup(&eboFill
);
228 BRUSH_ShareUnlockBrush(pbrush
);
233 // Restore attributes and flags
234 dc
->pdcattr
->crForegroundClr
= crColor
;
235 dc
->pdcattr
->crBackgroundClr
= crBkColor
;
236 dc
->pdcattr
->crBrushClr
= crBrushClr
;
237 dc
->pdcattr
->ulForegroundClr
= ulForegroundClr
;
238 dc
->pdcattr
->ulBackgroundClr
= ulBackgroundClr
;
239 dc
->pdcattr
->ulBrushClr
= ulBrushClr
;
240 dc
->pdcattr
->ulDirty_
|= flags
;
247 COLORREF crColor
= -1, crBkColor
;
248 ULONG ulForegroundClr
, ulBackgroundClr
;
249 DWORD flags
= 0, flXform
= 0, saveflags
, saveflXform
= 0;
250 FLONG flTextAlign
= -1;
255 POINTL ptlViewportOrg
;
257 pgO
= (PGDIBSTEXTOUT
) pHdr
;
259 // Save current attributes, flags and Set the attribute snapshots
260 saveflags
= dc
->pdcattr
->ulDirty_
& (DIRTY_BACKGROUND
|DIRTY_LINE
|DIRTY_TEXT
|DIRTY_FILL
|DC_BRUSH_DIRTY
|DIRTY_CHARSET
);
262 // In this instance check for differences and set the appropriate dirty flags.
263 if ( dc
->pdcattr
->crForegroundClr
!= pgO
->crForegroundClr
)
265 crColor
= dc
->pdcattr
->crForegroundClr
;
266 dc
->pdcattr
->crForegroundClr
= pgO
->crForegroundClr
;
267 ulForegroundClr
= dc
->pdcattr
->ulForegroundClr
;
268 dc
->pdcattr
->ulForegroundClr
= pgO
->ulForegroundClr
;
269 flags
|= (DIRTY_FILL
|DIRTY_LINE
|DIRTY_TEXT
);
271 if (dc
->pdcattr
->crBackgroundClr
!= pgO
->crBackgroundClr
)
273 crBkColor
= dc
->pdcattr
->ulBackgroundClr
;
274 dc
->pdcattr
->crBackgroundClr
= pgO
->crBackgroundClr
;
275 ulBackgroundClr
= dc
->pdcattr
->ulBackgroundClr
;
276 dc
->pdcattr
->ulBackgroundClr
= pgO
->ulBackgroundClr
;
277 flags
|= (DIRTY_FILL
|DIRTY_LINE
|DIRTY_TEXT
|DIRTY_BACKGROUND
);
279 if (dc
->pdcattr
->flTextAlign
!= pgO
->flTextAlign
)
281 flTextAlign
= dc
->pdcattr
->flTextAlign
;
282 dc
->pdcattr
->flTextAlign
= pgO
->flTextAlign
;
284 if (dc
->pdcattr
->hlfntNew
!= pgO
->hlfntNew
)
286 hlfntNew
= dc
->pdcattr
->hlfntNew
;
287 dc
->pdcattr
->hlfntNew
= pgO
->hlfntNew
;
288 dc
->pdcattr
->ulDirty_
&= ~SLOW_WIDTHS
;
289 flags
|= DIRTY_CHARSET
;
292 if ( dc
->pdcattr
->ptlViewportOrg
.x
!= pgO
->ptlViewportOrg
.x
||
293 dc
->pdcattr
->ptlViewportOrg
.y
!= pgO
->ptlViewportOrg
.y
)
295 saveflXform
= dc
->pdcattr
->flXform
& (PAGE_XLATE_CHANGED
|WORLD_XFORM_CHANGED
|DEVICE_TO_WORLD_INVALID
);
296 ptlViewportOrg
= dc
->pdcattr
->ptlViewportOrg
;
297 dc
->pdcattr
->ptlViewportOrg
= pgO
->ptlViewportOrg
;
298 flXform
= (PAGE_XLATE_CHANGED
|WORLD_XFORM_CHANGED
|DEVICE_TO_WORLD_INVALID
);
301 dc
->pdcattr
->flXform
|= flXform
;
302 dc
->pdcattr
->ulDirty_
|= flags
;
304 jBkMode
= dc
->pdcattr
->jBkMode
;
305 dc
->pdcattr
->jBkMode
= pgO
->lBkMode
;
306 lBkMode
= dc
->pdcattr
->lBkMode
;
307 dc
->pdcattr
->lBkMode
= pgO
->lBkMode
;
309 lprc
= (pgO
->Options
& GDIBS_NORECT
) ? NULL
: &pgO
->Rect
;
310 pgO
->Options
&= ~GDIBS_NORECT
;
317 (LPCWSTR
)&pgO
->String
[pgO
->Size
/sizeof(WCHAR
)],
319 pgO
->Size
? (LPINT
)&pgO
->Buffer
: NULL
,
322 // Restore attributes and flags
323 dc
->pdcattr
->jBkMode
= jBkMode
;
324 dc
->pdcattr
->lBkMode
= lBkMode
;
328 dc
->pdcattr
->ptlViewportOrg
= ptlViewportOrg
;
329 dc
->pdcattr
->flXform
|= saveflXform
|flXform
;
332 if (flags
& DIRTY_TEXT
&& crColor
!= -1)
334 dc
->pdcattr
->crForegroundClr
= crColor
;
335 dc
->pdcattr
->ulForegroundClr
= ulForegroundClr
;
337 if (flags
& DIRTY_BACKGROUND
)
339 dc
->pdcattr
->crBackgroundClr
= crBkColor
;
340 dc
->pdcattr
->ulBackgroundClr
= ulBackgroundClr
;
342 if (flTextAlign
!= -1)
344 dc
->pdcattr
->flTextAlign
= flTextAlign
;
347 if (flags
& DIRTY_CHARSET
)
349 dc
->pdcattr
->hlfntNew
= hlfntNew
;
350 dc
->pdcattr
->ulDirty_
&= ~SLOW_WIDTHS
;
352 dc
->pdcattr
->ulDirty_
|= saveflags
| flags
;
353 dc
->pdcattr
->flXform
|= saveflXform
| flXform
;
357 case GdiBCExtTextOut
:
359 PGDIBSEXTTEXTOUT pgO
;
361 ULONG ulBackgroundClr
;
362 POINTL ptlViewportOrg
;
363 DWORD flags
= 0, flXform
= 0, saveflags
, saveflXform
= 0;
365 pgO
= (PGDIBSEXTTEXTOUT
) pHdr
;
367 saveflags
= dc
->pdcattr
->ulDirty_
& (DIRTY_BACKGROUND
|DIRTY_TEXT
|DIRTY_FILL
|DC_BRUSH_DIRTY
|DIRTY_CHARSET
);
369 if (dc
->pdcattr
->crBackgroundClr
!= pgO
->ulBackgroundClr
)
371 crBkColor
= dc
->pdcattr
->crBackgroundClr
;
372 ulBackgroundClr
= dc
->pdcattr
->ulBackgroundClr
;
373 dc
->pdcattr
->crBackgroundClr
= pgO
->ulBackgroundClr
;
374 dc
->pdcattr
->ulBackgroundClr
= pgO
->ulBackgroundClr
;
375 flags
|= (DIRTY_BACKGROUND
|DIRTY_LINE
|DIRTY_FILL
);
378 if ( dc
->pdcattr
->ptlViewportOrg
.x
!= pgO
->ptlViewportOrg
.x
||
379 dc
->pdcattr
->ptlViewportOrg
.y
!= pgO
->ptlViewportOrg
.y
)
381 saveflXform
= dc
->pdcattr
->flXform
& (PAGE_XLATE_CHANGED
|WORLD_XFORM_CHANGED
|DEVICE_TO_WORLD_INVALID
);
382 ptlViewportOrg
= dc
->pdcattr
->ptlViewportOrg
;
383 dc
->pdcattr
->ptlViewportOrg
= pgO
->ptlViewportOrg
;
384 flXform
= (PAGE_XLATE_CHANGED
|WORLD_XFORM_CHANGED
|DEVICE_TO_WORLD_INVALID
);
387 dc
->pdcattr
->flXform
|= flXform
;
388 dc
->pdcattr
->ulDirty_
|= flags
;
402 dc
->pdcattr
->ptlViewportOrg
= ptlViewportOrg
;
403 dc
->pdcattr
->flXform
|= saveflXform
|flXform
;
406 if (flags
& DIRTY_BACKGROUND
)
408 dc
->pdcattr
->crBackgroundClr
= crBkColor
;
409 dc
->pdcattr
->ulBackgroundClr
= ulBackgroundClr
;
411 dc
->pdcattr
->ulDirty_
|= saveflags
| flags
;
412 dc
->pdcattr
->flXform
|= saveflXform
| flXform
;
416 case GdiBCSetBrushOrg
:
418 PGDIBSSETBRHORG pgSBO
;
420 pgSBO
= (PGDIBSSETBRHORG
) pHdr
;
421 pdcattr
->ptlBrushOrigin
= pgSBO
->ptlBrushOrigin
;
422 DC_vSetBrushOrigin(dc
, pgSBO
->ptlBrushOrigin
.x
, pgSBO
->ptlBrushOrigin
.y
);
426 case GdiBCExtSelClipRgn
:
434 pgO
= (PGDIBSOBJECT
) pHdr
;
436 DC_hSelectFont(dc
, (HFONT
)pgO
->hgdiobj
);
441 DPRINT("Delete Region Object!\n");
445 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
) pHdr
;
446 GreDeleteObject( pgO
->hgdiobj
);
460 * Flushes the calling thread's current batch.
468 SynchronizeDriver(GCAPS2_SYNCFLUSH
);
469 return STATUS_SUCCESS
;
473 * NtGdiFlushUserBatch
475 * Callback for thread batch flush routine.
477 * Think small & fast!
481 NtGdiFlushUserBatch(VOID
)
483 PTEB pTeb
= NtCurrentTeb();
484 ULONG GdiBatchCount
= pTeb
->GdiBatchCount
;
486 if( (GdiBatchCount
> 0) && (GdiBatchCount
<= (GDIBATCHBUFSIZE
/4)))
488 HDC hDC
= (HDC
) pTeb
->GdiTebBatch
.HDC
;
490 /* If hDC is zero and the buffer fills up with delete objects we need
493 if (hDC
|| GdiBatchCount
)
495 PCHAR pHdr
= (PCHAR
)&pTeb
->GdiTebBatch
.Buffer
[0];
498 if (GDI_HANDLE_GET_TYPE(hDC
) == GDILoObjType_LO_DC_TYPE
&& GreIsHandleValid(hDC
))
500 pDC
= DC_LockDc(hDC
);
503 // No need to init anything, just go!
504 for (; GdiBatchCount
> 0; GdiBatchCount
--)
507 // Process Gdi Batch!
508 Size
= GdiFlushUserBatch(pDC
, (PGDIBATCHHDR
) pHdr
);
518 // Exit and clear out for the next round.
519 pTeb
->GdiTebBatch
.Offset
= 0;
520 pTeb
->GdiBatchCount
= 0;
521 pTeb
->GdiTebBatch
.HDC
= 0;
525 // FIXME: On Windows XP the function returns &pTeb->RealClientId, maybe VOID?
526 return STATUS_SUCCESS
;