xref: /reactos/win32ss/gdi/ntgdi/gdibatch.c (revision 94b4b5c1)
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