7 BOOL FASTCALL
IntPatBlt( PDC
,INT
,INT
,INT
,INT
,DWORD
,PEBRUSHOBJ
);
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 ULONG Cmd
= 0, Size
= 0;
71 PDC_ATTR pdcattr
= NULL
;
75 pdcattr
= dc
->pdcattr
;
81 Size
= pHdr
->Size
; // Return the full size of the structure.
83 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
85 DPRINT1("WARNING! GdiBatch Fault!\n");
86 _SEH2_YIELD(return 0;)
97 COLORREF crColor
, crBkColor
, crBrushClr
;
98 ULONG ulForegroundClr
, ulBackgroundClr
, ulBrushClr
;
100 pgDPB
= (PGDIBSPATBLT
) pHdr
;
101 /* Convert the ROP3 to a ROP4 */
102 dwRop
= pgDPB
->dwRop
;
103 dwRop
= MAKEROP4(dwRop
& 0xFF0000, dwRop
);
104 /* Check if the rop uses a source */
105 if (WIN32_ROP4_USES_SOURCE(dwRop
))
107 /* This is not possible */
110 /* Check if the DC has no surface (empty mem or info DC) */
111 if (dc
->dclevel
.pSurface
== NULL
)
116 // Save current attributes and flags
117 crColor
= dc
->pdcattr
->crForegroundClr
;
118 crBkColor
= dc
->pdcattr
->ulBackgroundClr
;
119 crBrushClr
= dc
->pdcattr
->crBrushClr
;
120 ulForegroundClr
= dc
->pdcattr
->ulForegroundClr
;
121 ulBackgroundClr
= dc
->pdcattr
->ulBackgroundClr
;
122 ulBrushClr
= dc
->pdcattr
->ulBrushClr
;
123 hOrgBrush
= dc
->pdcattr
->hbrush
;
124 flags
= dc
->pdcattr
->ulDirty_
& (DIRTY_BACKGROUND
| DIRTY_TEXT
| DIRTY_FILL
| DC_BRUSH_DIRTY
);
125 // Set the attribute snapshot
126 dc
->pdcattr
->hbrush
= pgDPB
->hbrush
;
127 dc
->pdcattr
->crForegroundClr
= pgDPB
->crForegroundClr
;
128 dc
->pdcattr
->crBackgroundClr
= pgDPB
->crBackgroundClr
;
129 dc
->pdcattr
->crBrushClr
= pgDPB
->crBrushClr
;
130 dc
->pdcattr
->ulForegroundClr
= pgDPB
->ulForegroundClr
;
131 dc
->pdcattr
->ulBackgroundClr
= pgDPB
->ulBackgroundClr
;
132 dc
->pdcattr
->ulBrushClr
= pgDPB
->ulBrushClr
;
133 // Process dirty attributes if any
134 if (dc
->pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
135 DC_vUpdateFillBrush(dc
);
136 if (dc
->pdcattr
->ulDirty_
& DIRTY_TEXT
)
137 DC_vUpdateTextBrush(dc
);
138 if (pdcattr
->ulDirty_
& DIRTY_BACKGROUND
)
139 DC_vUpdateBackgroundBrush(dc
);
140 /* Call the internal function */
141 IntPatBlt(dc
, pgDPB
->nXLeft
, pgDPB
->nYLeft
, pgDPB
->nWidth
, pgDPB
->nHeight
, dwRop
, &dc
->eboFill
);
142 // Restore attributes and flags
143 dc
->pdcattr
->hbrush
= hOrgBrush
;
144 dc
->pdcattr
->crForegroundClr
= crColor
;
145 dc
->pdcattr
->crBackgroundClr
= crBkColor
;
146 dc
->pdcattr
->crBrushClr
= crBrushClr
;
147 dc
->pdcattr
->ulForegroundClr
= ulForegroundClr
;
148 dc
->pdcattr
->ulBackgroundClr
= ulBackgroundClr
;
149 dc
->pdcattr
->ulBrushClr
= ulBrushClr
;
150 dc
->pdcattr
->ulDirty_
|= flags
;
154 case GdiBCPolyPatBlt
:
162 COLORREF crColor
, crBkColor
, crBrushClr
;
163 ULONG ulForegroundClr
, ulBackgroundClr
, ulBrushClr
;
165 pgDPB
= (PGDIBSPPATBLT
) pHdr
;
166 /* Convert the ROP3 to a ROP4 */
168 dwRop
= MAKEROP4(dwRop
& 0xFF0000, dwRop
);
169 /* Check if the rop uses a source */
170 if (WIN32_ROP4_USES_SOURCE(dwRop
))
172 /* This is not possible */
175 /* Check if the DC has no surface (empty mem or info DC) */
176 if (dc
->dclevel
.pSurface
== NULL
)
181 // Save current attributes and flags
182 crColor
= dc
->pdcattr
->crForegroundClr
;
183 crBkColor
= dc
->pdcattr
->ulBackgroundClr
;
184 crBrushClr
= dc
->pdcattr
->crBrushClr
;
185 ulForegroundClr
= dc
->pdcattr
->ulForegroundClr
;
186 ulBackgroundClr
= dc
->pdcattr
->ulBackgroundClr
;
187 ulBrushClr
= dc
->pdcattr
->ulBrushClr
;
188 flags
= dc
->pdcattr
->ulDirty_
& (DIRTY_BACKGROUND
| DIRTY_TEXT
| DIRTY_FILL
| DC_BRUSH_DIRTY
);
189 // Set the attribute snapshot
190 dc
->pdcattr
->crForegroundClr
= pgDPB
->crForegroundClr
;
191 dc
->pdcattr
->crBackgroundClr
= pgDPB
->crBackgroundClr
;
192 dc
->pdcattr
->crBrushClr
= pgDPB
->crBrushClr
;
193 dc
->pdcattr
->ulForegroundClr
= pgDPB
->ulForegroundClr
;
194 dc
->pdcattr
->ulBackgroundClr
= pgDPB
->ulBackgroundClr
;
195 dc
->pdcattr
->ulBrushClr
= pgDPB
->ulBrushClr
;
196 // Process dirty attributes if any
197 if (dc
->pdcattr
->ulDirty_
& DIRTY_TEXT
)
198 DC_vUpdateTextBrush(dc
);
199 if (pdcattr
->ulDirty_
& DIRTY_BACKGROUND
)
200 DC_vUpdateBackgroundBrush(dc
);
202 DPRINT1("GdiBCPolyPatBlt Testing\n");
203 pRects
= pgDPB
->pRect
;
204 cRects
= pgDPB
->Count
;
206 for (i
= 0; i
< cRects
; i
++)
208 pbrush
= BRUSH_ShareLockBrush(pRects
->hBrush
);
210 /* Check if we could lock the brush */
213 /* Initialize a brush object */
214 EBRUSHOBJ_vInitFromDC(&eboFill
, pbrush
, dc
);
225 /* Cleanup the brush object and unlock the brush */
226 EBRUSHOBJ_vCleanup(&eboFill
);
227 BRUSH_ShareUnlockBrush(pbrush
);
232 // Restore attributes and flags
233 dc
->pdcattr
->crForegroundClr
= crColor
;
234 dc
->pdcattr
->crBackgroundClr
= crBkColor
;
235 dc
->pdcattr
->crBrushClr
= crBrushClr
;
236 dc
->pdcattr
->ulForegroundClr
= ulForegroundClr
;
237 dc
->pdcattr
->ulBackgroundClr
= ulBackgroundClr
;
238 dc
->pdcattr
->ulBrushClr
= ulBrushClr
;
239 dc
->pdcattr
->ulDirty_
|= flags
;
245 case GdiBCExtTextOut
:
247 //GreExtTextOutW( hDC,
259 case GdiBCSetBrushOrg
:
261 PGDIBSSETBRHORG pgSBO
;
263 pgSBO
= (PGDIBSSETBRHORG
) pHdr
;
264 pdcattr
->ptlBrushOrigin
= pgSBO
->ptlBrushOrigin
;
265 DC_vSetBrushOrigin(dc
, pgSBO
->ptlBrushOrigin
.x
, pgSBO
->ptlBrushOrigin
.y
);
269 case GdiBCExtSelClipRgn
:
277 pgO
= (PGDIBSOBJECT
) pHdr
;
279 DC_hSelectFont(dc
, (HFONT
)pgO
->hgdiobj
);
284 DPRINT("Delete Region Object!\n");
288 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
) pHdr
;
289 GreDeleteObject( pgO
->hgdiobj
);
303 * Flushes the calling thread's current batch.
311 SynchonizeDriver(GCAPS2_SYNCFLUSH
);
312 return STATUS_SUCCESS
;
316 * NtGdiFlushUserBatch
318 * Callback for thread batch flush routine.
320 * Think small & fast!
324 NtGdiFlushUserBatch(VOID
)
326 PTEB pTeb
= NtCurrentTeb();
327 ULONG GdiBatchCount
= pTeb
->GdiBatchCount
;
329 if( (GdiBatchCount
> 0) && (GdiBatchCount
<= (GDIBATCHBUFSIZE
/4)))
331 HDC hDC
= (HDC
) pTeb
->GdiTebBatch
.HDC
;
333 /* If hDC is zero and the buffer fills up with delete objects we need
336 if (hDC
|| GdiBatchCount
)
338 PCHAR pHdr
= (PCHAR
)&pTeb
->GdiTebBatch
.Buffer
[0];
341 if (GDI_HANDLE_GET_TYPE(hDC
) == GDILoObjType_LO_DC_TYPE
&& GreIsHandleValid(hDC
))
343 pDC
= DC_LockDc(hDC
);
346 // No need to init anything, just go!
347 for (; GdiBatchCount
> 0; GdiBatchCount
--)
350 // Process Gdi Batch!
351 Size
= GdiFlushUserBatch(pDC
, (PGDIBATCHHDR
) pHdr
);
361 // Exit and clear out for the next round.
362 pTeb
->GdiTebBatch
.Offset
= 0;
363 pTeb
->GdiBatchCount
= 0;
364 pTeb
->GdiTebBatch
.HDC
= 0;
368 // FIXME: On Windows XP the function returns &pTeb->RealClientId, maybe VOID?
369 return STATUS_SUCCESS
;