1c2c66affSColin Finck
2c2c66affSColin Finck #include <win32k.h>
3c2c66affSColin Finck
4c2c66affSColin Finck #define NDEBUG
5c2c66affSColin Finck #include <debug.h>
6c2c66affSColin Finck
7b6262a25Sjimtabor BOOL FASTCALL IntPatBlt( PDC,INT,INT,INT,INT,DWORD,PEBRUSHOBJ);
8d57f7becSJames Tabor BOOL APIENTRY IntExtTextOutW(IN PDC,IN INT,IN INT,IN UINT,IN OPTIONAL PRECTL,IN LPCWSTR,IN INT,IN OPTIONAL LPINT,IN DWORD);
9d57f7becSJames Tabor
10c2c66affSColin Finck
11c2c66affSColin Finck //
12c2c66affSColin Finck // Gdi Batch Flush support functions.
13c2c66affSColin Finck //
14c2c66affSColin Finck
15c2c66affSColin Finck //
16c2c66affSColin Finck // DoDeviceSync
17c2c66affSColin Finck //
18c2c66affSColin Finck // based on IntEngEnter from eng/engmisc.c
19c2c66affSColin Finck //
20c2c66affSColin Finck VOID
21c2c66affSColin Finck FASTCALL
DoDeviceSync(SURFOBJ * Surface,PRECTL Rect,FLONG fl)22c2c66affSColin Finck DoDeviceSync( SURFOBJ *Surface, PRECTL Rect, FLONG fl)
23c2c66affSColin Finck {
24c2c66affSColin Finck PPDEVOBJ Device = (PDEVOBJ*)Surface->hdev;
25c2c66affSColin Finck // No punting and "Handle to a surface, provided that the surface is device-managed.
26c2c66affSColin Finck // Otherwise, dhsurf is zero".
27c2c66affSColin Finck if (!(Device->flFlags & PDEV_DRIVER_PUNTED_CALL) && (Surface->dhsurf))
28c2c66affSColin Finck {
29c2c66affSColin Finck if (Device->DriverFunctions.SynchronizeSurface)
30c2c66affSColin Finck {
31c2c66affSColin Finck Device->DriverFunctions.SynchronizeSurface(Surface, Rect, fl);
32c2c66affSColin Finck }
33c2c66affSColin Finck else
34c2c66affSColin Finck {
35c2c66affSColin Finck if (Device->DriverFunctions.Synchronize)
36c2c66affSColin Finck {
37c2c66affSColin Finck Device->DriverFunctions.Synchronize(Surface->dhpdev, Rect);
38c2c66affSColin Finck }
39c2c66affSColin Finck }
40c2c66affSColin Finck }
41c2c66affSColin Finck }
42c2c66affSColin Finck
43c2c66affSColin Finck VOID
44c2c66affSColin Finck FASTCALL
SynchronizeDriver(FLONG Flags)45d57f7becSJames Tabor SynchronizeDriver(FLONG Flags)
46c2c66affSColin Finck {
47c2c66affSColin Finck SURFOBJ *SurfObj;
48c2c66affSColin Finck //PPDEVOBJ Device;
49c2c66affSColin Finck
50c2c66affSColin Finck if (Flags & GCAPS2_SYNCFLUSH)
51c2c66affSColin Finck Flags = DSS_FLUSH_EVENT;
52c2c66affSColin Finck if (Flags & GCAPS2_SYNCTIMER)
53c2c66affSColin Finck Flags = DSS_TIMER_EVENT;
54c2c66affSColin Finck
55c2c66affSColin Finck //Device = IntEnumHDev();
56c2c66affSColin Finck // UNIMPLEMENTED;
57c2c66affSColin Finck //ASSERT(FALSE);
58c2c66affSColin Finck SurfObj = 0;// EngLockSurface( Device->pSurface );
59c2c66affSColin Finck if(!SurfObj) return;
60c2c66affSColin Finck DoDeviceSync( SurfObj, NULL, Flags);
61c2c66affSColin Finck EngUnlockSurface(SurfObj);
62c2c66affSColin Finck return;
63c2c66affSColin Finck }
64c2c66affSColin Finck
65c2c66affSColin Finck //
66c2c66affSColin Finck // Process the batch.
67c2c66affSColin Finck //
68c2c66affSColin Finck ULONG
69c2c66affSColin Finck FASTCALL
GdiFlushUserBatch(PDC dc,PGDIBATCHHDR pHdr)70c2c66affSColin Finck GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
71c2c66affSColin Finck {
72c2c66affSColin Finck ULONG Cmd = 0, Size = 0;
73c2c66affSColin Finck PDC_ATTR pdcattr = NULL;
74c2c66affSColin Finck
75c2c66affSColin Finck if (dc)
76c2c66affSColin Finck {
77c2c66affSColin Finck pdcattr = dc->pdcattr;
78c2c66affSColin Finck }
79c2c66affSColin Finck
80c2c66affSColin Finck _SEH2_TRY
81c2c66affSColin Finck {
82c2c66affSColin Finck Cmd = pHdr->Cmd;
83c2c66affSColin Finck Size = pHdr->Size; // Return the full size of the structure.
84c2c66affSColin Finck }
85c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
86c2c66affSColin Finck {
87c2c66affSColin Finck DPRINT1("WARNING! GdiBatch Fault!\n");
88c2c66affSColin Finck _SEH2_YIELD(return 0;)
89c2c66affSColin Finck }
90c2c66affSColin Finck _SEH2_END;
91c2c66affSColin Finck
92c2c66affSColin Finck switch(Cmd)
93c2c66affSColin Finck {
94c2c66affSColin Finck case GdiBCPatBlt:
95b6262a25Sjimtabor {
96b6262a25Sjimtabor PGDIBSPATBLT pgDPB;
97b6262a25Sjimtabor DWORD dwRop, flags;
98b6262a25Sjimtabor HBRUSH hOrgBrush;
99b6262a25Sjimtabor COLORREF crColor, crBkColor, crBrushClr;
100b6262a25Sjimtabor ULONG ulForegroundClr, ulBackgroundClr, ulBrushClr;
101b6262a25Sjimtabor if (!dc) break;
102b6262a25Sjimtabor pgDPB = (PGDIBSPATBLT) pHdr;
103b6262a25Sjimtabor /* Convert the ROP3 to a ROP4 */
104b6262a25Sjimtabor dwRop = pgDPB->dwRop;
105b6262a25Sjimtabor dwRop = MAKEROP4(dwRop & 0xFF0000, dwRop);
106b6262a25Sjimtabor /* Check if the rop uses a source */
107b6262a25Sjimtabor if (WIN32_ROP4_USES_SOURCE(dwRop))
108b6262a25Sjimtabor {
109b6262a25Sjimtabor /* This is not possible */
110c2c66affSColin Finck break;
111b6262a25Sjimtabor }
112b6262a25Sjimtabor /* Check if the DC has no surface (empty mem or info DC) */
113b6262a25Sjimtabor if (dc->dclevel.pSurface == NULL)
114b6262a25Sjimtabor {
115b6262a25Sjimtabor /* Nothing to do */
116b6262a25Sjimtabor break;
117b6262a25Sjimtabor }
118b6262a25Sjimtabor // Save current attributes and flags
119b6262a25Sjimtabor crColor = dc->pdcattr->crForegroundClr;
120b6262a25Sjimtabor crBkColor = dc->pdcattr->ulBackgroundClr;
121b6262a25Sjimtabor crBrushClr = dc->pdcattr->crBrushClr;
122b6262a25Sjimtabor ulForegroundClr = dc->pdcattr->ulForegroundClr;
123b6262a25Sjimtabor ulBackgroundClr = dc->pdcattr->ulBackgroundClr;
124b6262a25Sjimtabor ulBrushClr = dc->pdcattr->ulBrushClr;
125b6262a25Sjimtabor hOrgBrush = dc->pdcattr->hbrush;
126b6262a25Sjimtabor flags = dc->pdcattr->ulDirty_ & (DIRTY_BACKGROUND | DIRTY_TEXT | DIRTY_FILL | DC_BRUSH_DIRTY);
127b6262a25Sjimtabor // Set the attribute snapshot
128b6262a25Sjimtabor dc->pdcattr->hbrush = pgDPB->hbrush;
129b6262a25Sjimtabor dc->pdcattr->crForegroundClr = pgDPB->crForegroundClr;
130b6262a25Sjimtabor dc->pdcattr->crBackgroundClr = pgDPB->crBackgroundClr;
131b6262a25Sjimtabor dc->pdcattr->crBrushClr = pgDPB->crBrushClr;
132b6262a25Sjimtabor dc->pdcattr->ulForegroundClr = pgDPB->ulForegroundClr;
133b6262a25Sjimtabor dc->pdcattr->ulBackgroundClr = pgDPB->ulBackgroundClr;
134b6262a25Sjimtabor dc->pdcattr->ulBrushClr = pgDPB->ulBrushClr;
135d57f7becSJames Tabor // Process dirty attributes if any.
136b6262a25Sjimtabor if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
137b6262a25Sjimtabor DC_vUpdateFillBrush(dc);
138b6262a25Sjimtabor if (dc->pdcattr->ulDirty_ & DIRTY_TEXT)
139b6262a25Sjimtabor DC_vUpdateTextBrush(dc);
140b6262a25Sjimtabor if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
141b6262a25Sjimtabor DC_vUpdateBackgroundBrush(dc);
142b6262a25Sjimtabor /* Call the internal function */
143b6262a25Sjimtabor IntPatBlt(dc, pgDPB->nXLeft, pgDPB->nYLeft, pgDPB->nWidth, pgDPB->nHeight, dwRop, &dc->eboFill);
144b6262a25Sjimtabor // Restore attributes and flags
145b6262a25Sjimtabor dc->pdcattr->hbrush = hOrgBrush;
146b6262a25Sjimtabor dc->pdcattr->crForegroundClr = crColor;
147b6262a25Sjimtabor dc->pdcattr->crBackgroundClr = crBkColor;
148b6262a25Sjimtabor dc->pdcattr->crBrushClr = crBrushClr;
149b6262a25Sjimtabor dc->pdcattr->ulForegroundClr = ulForegroundClr;
150b6262a25Sjimtabor dc->pdcattr->ulBackgroundClr = ulBackgroundClr;
151b6262a25Sjimtabor dc->pdcattr->ulBrushClr = ulBrushClr;
152b6262a25Sjimtabor dc->pdcattr->ulDirty_ |= flags;
153b6262a25Sjimtabor break;
154b6262a25Sjimtabor }
155c2c66affSColin Finck
156c2c66affSColin Finck case GdiBCPolyPatBlt:
157b6262a25Sjimtabor {
158b6262a25Sjimtabor PGDIBSPPATBLT pgDPB;
159b6262a25Sjimtabor EBRUSHOBJ eboFill;
160b6262a25Sjimtabor PBRUSH pbrush;
161b6262a25Sjimtabor PPATRECT pRects;
162d57f7becSJames Tabor INT i;
163b6262a25Sjimtabor DWORD dwRop, flags;
164b6262a25Sjimtabor COLORREF crColor, crBkColor, crBrushClr;
165b6262a25Sjimtabor ULONG ulForegroundClr, ulBackgroundClr, ulBrushClr;
166b6262a25Sjimtabor if (!dc) break;
167b6262a25Sjimtabor pgDPB = (PGDIBSPPATBLT) pHdr;
168b6262a25Sjimtabor /* Convert the ROP3 to a ROP4 */
169b6262a25Sjimtabor dwRop = pgDPB->rop4;
170b6262a25Sjimtabor dwRop = MAKEROP4(dwRop & 0xFF0000, dwRop);
171b6262a25Sjimtabor /* Check if the rop uses a source */
172b6262a25Sjimtabor if (WIN32_ROP4_USES_SOURCE(dwRop))
173b6262a25Sjimtabor {
174b6262a25Sjimtabor /* This is not possible */
175c2c66affSColin Finck break;
176b6262a25Sjimtabor }
177b6262a25Sjimtabor /* Check if the DC has no surface (empty mem or info DC) */
178b6262a25Sjimtabor if (dc->dclevel.pSurface == NULL)
179b6262a25Sjimtabor {
180b6262a25Sjimtabor /* Nothing to do */
181b6262a25Sjimtabor break;
182b6262a25Sjimtabor }
183b6262a25Sjimtabor // Save current attributes and flags
184b6262a25Sjimtabor crColor = dc->pdcattr->crForegroundClr;
185b6262a25Sjimtabor crBkColor = dc->pdcattr->ulBackgroundClr;
186b6262a25Sjimtabor crBrushClr = dc->pdcattr->crBrushClr;
187b6262a25Sjimtabor ulForegroundClr = dc->pdcattr->ulForegroundClr;
188b6262a25Sjimtabor ulBackgroundClr = dc->pdcattr->ulBackgroundClr;
189b6262a25Sjimtabor ulBrushClr = dc->pdcattr->ulBrushClr;
190b6262a25Sjimtabor flags = dc->pdcattr->ulDirty_ & (DIRTY_BACKGROUND | DIRTY_TEXT | DIRTY_FILL | DC_BRUSH_DIRTY);
191b6262a25Sjimtabor // Set the attribute snapshot
192b6262a25Sjimtabor dc->pdcattr->crForegroundClr = pgDPB->crForegroundClr;
193b6262a25Sjimtabor dc->pdcattr->crBackgroundClr = pgDPB->crBackgroundClr;
194b6262a25Sjimtabor dc->pdcattr->crBrushClr = pgDPB->crBrushClr;
195b6262a25Sjimtabor dc->pdcattr->ulForegroundClr = pgDPB->ulForegroundClr;
196b6262a25Sjimtabor dc->pdcattr->ulBackgroundClr = pgDPB->ulBackgroundClr;
197b6262a25Sjimtabor dc->pdcattr->ulBrushClr = pgDPB->ulBrushClr;
198b6262a25Sjimtabor // Process dirty attributes if any
199b6262a25Sjimtabor if (dc->pdcattr->ulDirty_ & DIRTY_TEXT)
200b6262a25Sjimtabor DC_vUpdateTextBrush(dc);
201b6262a25Sjimtabor if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
202b6262a25Sjimtabor DC_vUpdateBackgroundBrush(dc);
203c2c66affSColin Finck
204b6262a25Sjimtabor DPRINT1("GdiBCPolyPatBlt Testing\n");
205d57f7becSJames Tabor pRects = &pgDPB->pRect[0];
206b6262a25Sjimtabor
207d57f7becSJames Tabor for (i = 0; i < pgDPB->Count; i++)
208b6262a25Sjimtabor {
209b6262a25Sjimtabor pbrush = BRUSH_ShareLockBrush(pRects->hBrush);
210b6262a25Sjimtabor
211b6262a25Sjimtabor /* Check if we could lock the brush */
212b6262a25Sjimtabor if (pbrush != NULL)
213b6262a25Sjimtabor {
214b6262a25Sjimtabor /* Initialize a brush object */
215b6262a25Sjimtabor EBRUSHOBJ_vInitFromDC(&eboFill, pbrush, dc);
216b6262a25Sjimtabor
217b6262a25Sjimtabor IntPatBlt(
218b6262a25Sjimtabor dc,
219b6262a25Sjimtabor pRects->r.left,
220b6262a25Sjimtabor pRects->r.top,
221b6262a25Sjimtabor pRects->r.right,
222b6262a25Sjimtabor pRects->r.bottom,
223b6262a25Sjimtabor dwRop,
224b6262a25Sjimtabor &eboFill);
225b6262a25Sjimtabor
226b6262a25Sjimtabor /* Cleanup the brush object and unlock the brush */
227b6262a25Sjimtabor EBRUSHOBJ_vCleanup(&eboFill);
228b6262a25Sjimtabor BRUSH_ShareUnlockBrush(pbrush);
229b6262a25Sjimtabor }
230b6262a25Sjimtabor pRects++;
231b6262a25Sjimtabor }
232b6262a25Sjimtabor
233b6262a25Sjimtabor // Restore attributes and flags
234b6262a25Sjimtabor dc->pdcattr->crForegroundClr = crColor;
235b6262a25Sjimtabor dc->pdcattr->crBackgroundClr = crBkColor;
236b6262a25Sjimtabor dc->pdcattr->crBrushClr = crBrushClr;
237b6262a25Sjimtabor dc->pdcattr->ulForegroundClr = ulForegroundClr;
238b6262a25Sjimtabor dc->pdcattr->ulBackgroundClr = ulBackgroundClr;
239b6262a25Sjimtabor dc->pdcattr->ulBrushClr = ulBrushClr;
240b6262a25Sjimtabor dc->pdcattr->ulDirty_ |= flags;
241b6262a25Sjimtabor break;
242b6262a25Sjimtabor }
243d57f7becSJames Tabor
244c2c66affSColin Finck case GdiBCTextOut:
245d57f7becSJames Tabor {
246d57f7becSJames Tabor PGDIBSTEXTOUT pgO;
247d57f7becSJames Tabor COLORREF crColor = -1, crBkColor;
248d57f7becSJames Tabor ULONG ulForegroundClr, ulBackgroundClr;
24904a04659Sjimtabor DWORD flags = 0, flXform = 0, saveflags, saveflXform = 0;
250d57f7becSJames Tabor FLONG flTextAlign = -1;
251d57f7becSJames Tabor HANDLE hlfntNew;
252d57f7becSJames Tabor PRECTL lprc;
253d57f7becSJames Tabor USHORT jBkMode;
254d57f7becSJames Tabor LONG lBkMode;
25504a04659Sjimtabor POINTL ptlViewportOrg;
256d57f7becSJames Tabor if (!dc) break;
257d57f7becSJames Tabor pgO = (PGDIBSTEXTOUT) pHdr;
258d57f7becSJames Tabor
259d57f7becSJames Tabor // Save current attributes, flags and Set the attribute snapshots
260d57f7becSJames Tabor saveflags = dc->pdcattr->ulDirty_ & (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_TEXT|DIRTY_FILL|DC_BRUSH_DIRTY|DIRTY_CHARSET);
261d57f7becSJames Tabor
262d57f7becSJames Tabor // In this instance check for differences and set the appropriate dirty flags.
263d57f7becSJames Tabor if ( dc->pdcattr->crForegroundClr != pgO->crForegroundClr)
264d57f7becSJames Tabor {
265d57f7becSJames Tabor crColor = dc->pdcattr->crForegroundClr;
266d57f7becSJames Tabor dc->pdcattr->crForegroundClr = pgO->crForegroundClr;
267d57f7becSJames Tabor ulForegroundClr = dc->pdcattr->ulForegroundClr;
268d57f7becSJames Tabor dc->pdcattr->ulForegroundClr = pgO->ulForegroundClr;
269d57f7becSJames Tabor flags |= (DIRTY_FILL|DIRTY_LINE|DIRTY_TEXT);
270d57f7becSJames Tabor }
271d57f7becSJames Tabor if (dc->pdcattr->crBackgroundClr != pgO->crBackgroundClr)
272d57f7becSJames Tabor {
273d57f7becSJames Tabor crBkColor = dc->pdcattr->ulBackgroundClr;
274d57f7becSJames Tabor dc->pdcattr->crBackgroundClr = pgO->crBackgroundClr;
275d57f7becSJames Tabor ulBackgroundClr = dc->pdcattr->ulBackgroundClr;
276d57f7becSJames Tabor dc->pdcattr->ulBackgroundClr = pgO->ulBackgroundClr;
277d57f7becSJames Tabor flags |= (DIRTY_FILL|DIRTY_LINE|DIRTY_TEXT|DIRTY_BACKGROUND);
278d57f7becSJames Tabor }
279d57f7becSJames Tabor if (dc->pdcattr->flTextAlign != pgO->flTextAlign)
280d57f7becSJames Tabor {
281d57f7becSJames Tabor flTextAlign = dc->pdcattr->flTextAlign;
282d57f7becSJames Tabor dc->pdcattr->flTextAlign = pgO->flTextAlign;
283d57f7becSJames Tabor }
284d57f7becSJames Tabor if (dc->pdcattr->hlfntNew != pgO->hlfntNew)
285d57f7becSJames Tabor {
286d57f7becSJames Tabor hlfntNew = dc->pdcattr->hlfntNew;
287d57f7becSJames Tabor dc->pdcattr->hlfntNew = pgO->hlfntNew;
288d57f7becSJames Tabor dc->pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
289d57f7becSJames Tabor flags |= DIRTY_CHARSET;
290d57f7becSJames Tabor }
291d57f7becSJames Tabor
29204a04659Sjimtabor if ( dc->pdcattr->ptlViewportOrg.x != pgO->ptlViewportOrg.x ||
29304a04659Sjimtabor dc->pdcattr->ptlViewportOrg.y != pgO->ptlViewportOrg.y )
29404a04659Sjimtabor {
29504a04659Sjimtabor saveflXform = dc->pdcattr->flXform & (PAGE_XLATE_CHANGED|WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID);
29604a04659Sjimtabor ptlViewportOrg = dc->pdcattr->ptlViewportOrg;
29704a04659Sjimtabor dc->pdcattr->ptlViewportOrg = pgO->ptlViewportOrg;
29804a04659Sjimtabor flXform = (PAGE_XLATE_CHANGED|WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID);
29904a04659Sjimtabor }
30004a04659Sjimtabor
301b2ce1ae2Sjimtabor dc->pdcattr->flXform |= flXform;
302d57f7becSJames Tabor dc->pdcattr->ulDirty_ |= flags;
303d57f7becSJames Tabor
304d57f7becSJames Tabor jBkMode = dc->pdcattr->jBkMode;
305d57f7becSJames Tabor dc->pdcattr->jBkMode = pgO->lBkMode;
306d57f7becSJames Tabor lBkMode = dc->pdcattr->lBkMode;
307d57f7becSJames Tabor dc->pdcattr->lBkMode = pgO->lBkMode;
308d57f7becSJames Tabor
309d57f7becSJames Tabor lprc = (pgO->Options & GDIBS_NORECT) ? NULL : &pgO->Rect;
310d57f7becSJames Tabor pgO->Options &= ~GDIBS_NORECT;
311d57f7becSJames Tabor
312d57f7becSJames Tabor IntExtTextOutW( dc,
313d57f7becSJames Tabor pgO->x,
314d57f7becSJames Tabor pgO->y,
315d57f7becSJames Tabor pgO->Options,
316d57f7becSJames Tabor lprc,
317d57f7becSJames Tabor (LPCWSTR)&pgO->String[pgO->Size/sizeof(WCHAR)],
318d57f7becSJames Tabor pgO->cbCount,
319d57f7becSJames Tabor pgO->Size ? (LPINT)&pgO->Buffer : NULL,
320d57f7becSJames Tabor pgO->iCS_CP );
321d57f7becSJames Tabor
322d57f7becSJames Tabor // Restore attributes and flags
323d57f7becSJames Tabor dc->pdcattr->jBkMode = jBkMode;
324d57f7becSJames Tabor dc->pdcattr->lBkMode = lBkMode;
325d57f7becSJames Tabor
32604a04659Sjimtabor if (saveflXform)
32704a04659Sjimtabor {
32804a04659Sjimtabor dc->pdcattr->ptlViewportOrg = ptlViewportOrg;
32904a04659Sjimtabor dc->pdcattr->flXform |= saveflXform|flXform;
33004a04659Sjimtabor }
33104a04659Sjimtabor
332d57f7becSJames Tabor if (flags & DIRTY_TEXT && crColor != -1)
333d57f7becSJames Tabor {
334d57f7becSJames Tabor dc->pdcattr->crForegroundClr = crColor;
335d57f7becSJames Tabor dc->pdcattr->ulForegroundClr = ulForegroundClr;
336d57f7becSJames Tabor }
337d57f7becSJames Tabor if (flags & DIRTY_BACKGROUND)
338d57f7becSJames Tabor {
339d57f7becSJames Tabor dc->pdcattr->crBackgroundClr = crBkColor;
340d57f7becSJames Tabor dc->pdcattr->ulBackgroundClr = ulBackgroundClr;
341d57f7becSJames Tabor }
342d57f7becSJames Tabor if (flTextAlign != -1)
343d57f7becSJames Tabor {
344d57f7becSJames Tabor dc->pdcattr->flTextAlign = flTextAlign;
345d57f7becSJames Tabor }
346d57f7becSJames Tabor
347d57f7becSJames Tabor if (flags & DIRTY_CHARSET)
348d57f7becSJames Tabor {
349d57f7becSJames Tabor dc->pdcattr->hlfntNew = hlfntNew;
350d57f7becSJames Tabor dc->pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
351d57f7becSJames Tabor }
352d57f7becSJames Tabor dc->pdcattr->ulDirty_ |= saveflags | flags;
3532cc766b0Sjimtabor dc->pdcattr->flXform |= saveflXform | flXform;
354c2c66affSColin Finck break;
355d57f7becSJames Tabor }
356c2c66affSColin Finck
357c2c66affSColin Finck case GdiBCExtTextOut:
358b6262a25Sjimtabor {
359d57f7becSJames Tabor PGDIBSEXTTEXTOUT pgO;
360d57f7becSJames Tabor COLORREF crBkColor;
361d57f7becSJames Tabor ULONG ulBackgroundClr;
36204a04659Sjimtabor POINTL ptlViewportOrg;
36304a04659Sjimtabor DWORD flags = 0, flXform = 0, saveflags, saveflXform = 0;
364d57f7becSJames Tabor if (!dc) break;
365d57f7becSJames Tabor pgO = (PGDIBSEXTTEXTOUT) pHdr;
366d57f7becSJames Tabor
367d57f7becSJames Tabor saveflags = dc->pdcattr->ulDirty_ & (DIRTY_BACKGROUND|DIRTY_TEXT|DIRTY_FILL|DC_BRUSH_DIRTY|DIRTY_CHARSET);
368d57f7becSJames Tabor
369d57f7becSJames Tabor if (dc->pdcattr->crBackgroundClr != pgO->ulBackgroundClr)
370d57f7becSJames Tabor {
371d57f7becSJames Tabor crBkColor = dc->pdcattr->crBackgroundClr;
372d57f7becSJames Tabor ulBackgroundClr = dc->pdcattr->ulBackgroundClr;
373d57f7becSJames Tabor dc->pdcattr->crBackgroundClr = pgO->ulBackgroundClr;
374d57f7becSJames Tabor dc->pdcattr->ulBackgroundClr = pgO->ulBackgroundClr;
375d57f7becSJames Tabor flags |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL);
376d57f7becSJames Tabor }
377d57f7becSJames Tabor
37804a04659Sjimtabor if ( dc->pdcattr->ptlViewportOrg.x != pgO->ptlViewportOrg.x ||
37904a04659Sjimtabor dc->pdcattr->ptlViewportOrg.y != pgO->ptlViewportOrg.y )
38004a04659Sjimtabor {
38104a04659Sjimtabor saveflXform = dc->pdcattr->flXform & (PAGE_XLATE_CHANGED|WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID);
38204a04659Sjimtabor ptlViewportOrg = dc->pdcattr->ptlViewportOrg;
38304a04659Sjimtabor dc->pdcattr->ptlViewportOrg = pgO->ptlViewportOrg;
38404a04659Sjimtabor flXform = (PAGE_XLATE_CHANGED|WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID);
38504a04659Sjimtabor }
38604a04659Sjimtabor
387b2ce1ae2Sjimtabor dc->pdcattr->flXform |= flXform;
388d57f7becSJames Tabor dc->pdcattr->ulDirty_ |= flags;
389d57f7becSJames Tabor
390d57f7becSJames Tabor IntExtTextOutW( dc,
391d57f7becSJames Tabor 0,
392d57f7becSJames Tabor 0,
393d57f7becSJames Tabor pgO->Options,
394d57f7becSJames Tabor &pgO->Rect,
395d57f7becSJames Tabor NULL,
396d57f7becSJames Tabor pgO->Count,
397d57f7becSJames Tabor NULL,
398d57f7becSJames Tabor 0 );
399d57f7becSJames Tabor
40004a04659Sjimtabor if (saveflXform)
40104a04659Sjimtabor {
40204a04659Sjimtabor dc->pdcattr->ptlViewportOrg = ptlViewportOrg;
40304a04659Sjimtabor dc->pdcattr->flXform |= saveflXform|flXform;
40404a04659Sjimtabor }
40504a04659Sjimtabor
406d57f7becSJames Tabor if (flags & DIRTY_BACKGROUND)
407d57f7becSJames Tabor {
408d57f7becSJames Tabor dc->pdcattr->crBackgroundClr = crBkColor;
409d57f7becSJames Tabor dc->pdcattr->ulBackgroundClr = ulBackgroundClr;
410d57f7becSJames Tabor }
411d57f7becSJames Tabor dc->pdcattr->ulDirty_ |= saveflags | flags;
4122cc766b0Sjimtabor dc->pdcattr->flXform |= saveflXform | flXform;
413c2c66affSColin Finck break;
414b6262a25Sjimtabor }
415c2c66affSColin Finck
416c2c66affSColin Finck case GdiBCSetBrushOrg:
417c2c66affSColin Finck {
418c2c66affSColin Finck PGDIBSSETBRHORG pgSBO;
419c2c66affSColin Finck if (!dc) break;
420c2c66affSColin Finck pgSBO = (PGDIBSSETBRHORG) pHdr;
421c2c66affSColin Finck pdcattr->ptlBrushOrigin = pgSBO->ptlBrushOrigin;
422c2c66affSColin Finck DC_vSetBrushOrigin(dc, pgSBO->ptlBrushOrigin.x, pgSBO->ptlBrushOrigin.y);
423c2c66affSColin Finck break;
424c2c66affSColin Finck }
425c2c66affSColin Finck
426c2c66affSColin Finck case GdiBCExtSelClipRgn:
427*94b4b5c1Sjimtabor {
428*94b4b5c1Sjimtabor PGDIBSEXTSELCLPRGN pgO;
429*94b4b5c1Sjimtabor if (!dc) break;
430*94b4b5c1Sjimtabor pgO = (PGDIBSEXTSELCLPRGN) pHdr;
431*94b4b5c1Sjimtabor IntGdiExtSelectClipRect( dc, &pgO->rcl, pgO->fnMode);
432c2c66affSColin Finck break;
433*94b4b5c1Sjimtabor }
434c2c66affSColin Finck
435c2c66affSColin Finck case GdiBCSelObj:
436c2c66affSColin Finck {
437c2c66affSColin Finck PGDIBSOBJECT pgO;
438c2c66affSColin Finck
439c2c66affSColin Finck if (!dc) break;
440c2c66affSColin Finck pgO = (PGDIBSOBJECT) pHdr;
441c2c66affSColin Finck
442c2c66affSColin Finck DC_hSelectFont(dc, (HFONT)pgO->hgdiobj);
443c2c66affSColin Finck break;
444c2c66affSColin Finck }
445c2c66affSColin Finck
446c2c66affSColin Finck case GdiBCDelRgn:
447c2c66affSColin Finck DPRINT("Delete Region Object!\n");
448c2c66affSColin Finck /* Fall through */
449c2c66affSColin Finck case GdiBCDelObj:
450c2c66affSColin Finck {
451c2c66affSColin Finck PGDIBSOBJECT pgO = (PGDIBSOBJECT) pHdr;
452c2c66affSColin Finck GreDeleteObject( pgO->hgdiobj );
453c2c66affSColin Finck break;
454c2c66affSColin Finck }
455c2c66affSColin Finck
456c2c66affSColin Finck default:
457c2c66affSColin Finck break;
458c2c66affSColin Finck }
459c2c66affSColin Finck
460c2c66affSColin Finck return Size;
461c2c66affSColin Finck }
462c2c66affSColin Finck
463c2c66affSColin Finck /*
464c2c66affSColin Finck * NtGdiFlush
465c2c66affSColin Finck *
466c2c66affSColin Finck * Flushes the calling thread's current batch.
467c2c66affSColin Finck */
468c2c66affSColin Finck __kernel_entry
469c2c66affSColin Finck NTSTATUS
470c2c66affSColin Finck APIENTRY
NtGdiFlush(VOID)471c2c66affSColin Finck NtGdiFlush(
472c2c66affSColin Finck VOID)
473c2c66affSColin Finck {
474d57f7becSJames Tabor SynchronizeDriver(GCAPS2_SYNCFLUSH);
475c2c66affSColin Finck return STATUS_SUCCESS;
476c2c66affSColin Finck }
477c2c66affSColin Finck
478c2c66affSColin Finck /*
479c2c66affSColin Finck * NtGdiFlushUserBatch
480c2c66affSColin Finck *
481c2c66affSColin Finck * Callback for thread batch flush routine.
482c2c66affSColin Finck *
483c2c66affSColin Finck * Think small & fast!
484c2c66affSColin Finck */
485c2c66affSColin Finck NTSTATUS
486c2c66affSColin Finck APIENTRY
NtGdiFlushUserBatch(VOID)487c2c66affSColin Finck NtGdiFlushUserBatch(VOID)
488c2c66affSColin Finck {
489c2c66affSColin Finck PTEB pTeb = NtCurrentTeb();
490c2c66affSColin Finck ULONG GdiBatchCount = pTeb->GdiBatchCount;
491c2c66affSColin Finck
492c2c66affSColin Finck if( (GdiBatchCount > 0) && (GdiBatchCount <= (GDIBATCHBUFSIZE/4)))
493c2c66affSColin Finck {
494c2c66affSColin Finck HDC hDC = (HDC) pTeb->GdiTebBatch.HDC;
495c2c66affSColin Finck
496c2c66affSColin Finck /* If hDC is zero and the buffer fills up with delete objects we need
497c2c66affSColin Finck to run anyway.
498c2c66affSColin Finck */
499c2c66affSColin Finck if (hDC || GdiBatchCount)
500c2c66affSColin Finck {
501c2c66affSColin Finck PCHAR pHdr = (PCHAR)&pTeb->GdiTebBatch.Buffer[0];
502c2c66affSColin Finck PDC pDC = NULL;
503c2c66affSColin Finck
504c2c66affSColin Finck if (GDI_HANDLE_GET_TYPE(hDC) == GDILoObjType_LO_DC_TYPE && GreIsHandleValid(hDC))
505c2c66affSColin Finck {
506c2c66affSColin Finck pDC = DC_LockDc(hDC);
507c2c66affSColin Finck }
508c2c66affSColin Finck
509c2c66affSColin Finck // No need to init anything, just go!
510c2c66affSColin Finck for (; GdiBatchCount > 0; GdiBatchCount--)
511c2c66affSColin Finck {
512c2c66affSColin Finck ULONG Size;
513c2c66affSColin Finck // Process Gdi Batch!
514c2c66affSColin Finck Size = GdiFlushUserBatch(pDC, (PGDIBATCHHDR) pHdr);
515c2c66affSColin Finck if (!Size) break;
516c2c66affSColin Finck pHdr += Size;
517c2c66affSColin Finck }
518c2c66affSColin Finck
519c2c66affSColin Finck if (pDC)
520c2c66affSColin Finck {
521c2c66affSColin Finck DC_UnlockDc(pDC);
522c2c66affSColin Finck }
523c2c66affSColin Finck
524c2c66affSColin Finck // Exit and clear out for the next round.
525c2c66affSColin Finck pTeb->GdiTebBatch.Offset = 0;
526c2c66affSColin Finck pTeb->GdiBatchCount = 0;
527c2c66affSColin Finck pTeb->GdiTebBatch.HDC = 0;
528c2c66affSColin Finck }
529c2c66affSColin Finck }
530c2c66affSColin Finck
531c2c66affSColin Finck // FIXME: On Windows XP the function returns &pTeb->RealClientId, maybe VOID?
532c2c66affSColin Finck return STATUS_SUCCESS;
533c2c66affSColin Finck }
534