bd9306ae2eb7e3e0527fa4e0d66db84ee5efe01b
[reactos.git] / win32ss / gdi / ntgdi / gdibatch.c
1
2 #include <win32k.h>
3
4 #define NDEBUG
5 #include <debug.h>
6
7
8 //
9 // Gdi Batch Flush support functions.
10 //
11
12 //
13 // DoDeviceSync
14 //
15 // based on IntEngEnter from eng/engmisc.c
16 //
17 VOID
18 FASTCALL
19 DoDeviceSync( SURFOBJ *Surface, PRECTL Rect, FLONG fl)
20 {
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))
25 {
26 if (Device->DriverFunctions.SynchronizeSurface)
27 {
28 Device->DriverFunctions.SynchronizeSurface(Surface, Rect, fl);
29 }
30 else
31 {
32 if (Device->DriverFunctions.Synchronize)
33 {
34 Device->DriverFunctions.Synchronize(Surface->dhpdev, Rect);
35 }
36 }
37 }
38 }
39
40 VOID
41 FASTCALL
42 SynchonizeDriver(FLONG Flags)
43 {
44 SURFOBJ *SurfObj;
45 //PPDEVOBJ Device;
46
47 if (Flags & GCAPS2_SYNCFLUSH)
48 Flags = DSS_FLUSH_EVENT;
49 if (Flags & GCAPS2_SYNCTIMER)
50 Flags = DSS_TIMER_EVENT;
51
52 //Device = IntEnumHDev();
53 // UNIMPLEMENTED;
54 //ASSERT(FALSE);
55 SurfObj = 0;// EngLockSurface( Device->pSurface );
56 if(!SurfObj) return;
57 DoDeviceSync( SurfObj, NULL, Flags);
58 EngUnlockSurface(SurfObj);
59 return;
60 }
61
62 //
63 // Process the batch.
64 //
65 ULONG
66 FASTCALL
67 GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
68 {
69 ULONG Cmd = 0, Size = 0;
70 PDC_ATTR pdcattr = NULL;
71
72 if (dc)
73 {
74 pdcattr = dc->pdcattr;
75 }
76
77 _SEH2_TRY
78 {
79 Cmd = pHdr->Cmd;
80 Size = pHdr->Size; // Return the full size of the structure.
81 }
82 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
83 {
84 DPRINT1("WARNING! GdiBatch Fault!\n");
85 _SEH2_YIELD(return 0;)
86 }
87 _SEH2_END;
88
89 switch(Cmd)
90 {
91 case GdiBCPatBlt:
92 break;
93
94 case GdiBCPolyPatBlt:
95 break;
96
97 case GdiBCTextOut:
98 break;
99
100 case GdiBCExtTextOut:
101 break;
102
103 case GdiBCSetBrushOrg:
104 {
105 PGDIBSSETBRHORG pgSBO;
106 if (!dc) break;
107 pgSBO = (PGDIBSSETBRHORG) pHdr;
108 pdcattr->ptlBrushOrigin = pgSBO->ptlBrushOrigin;
109 DC_vSetBrushOrigin(dc, pgSBO->ptlBrushOrigin.x, pgSBO->ptlBrushOrigin.y);
110 break;
111 }
112
113 case GdiBCExtSelClipRgn:
114 break;
115
116 case GdiBCSelObj:
117 {
118 PGDIBSOBJECT pgO;
119
120 if (!dc) break;
121 pgO = (PGDIBSOBJECT) pHdr;
122
123 DC_hSelectFont(dc, (HFONT)pgO->hgdiobj);
124 break;
125 }
126
127 case GdiBCDelRgn:
128 DPRINT("Delete Region Object!\n");
129 /* Fall through */
130 case GdiBCDelObj:
131 {
132 PGDIBSOBJECT pgO = (PGDIBSOBJECT) pHdr;
133 GreDeleteObject( pgO->hgdiobj );
134 break;
135 }
136
137 default:
138 break;
139 }
140
141 return Size;
142 }
143
144 /*
145 * NtGdiFlush
146 *
147 * Flushes the calling thread's current batch.
148 */
149 __kernel_entry
150 NTSTATUS
151 APIENTRY
152 NtGdiFlush(
153 VOID)
154 {
155 SynchonizeDriver(GCAPS2_SYNCFLUSH);
156 return STATUS_SUCCESS;
157 }
158
159 /*
160 * NtGdiFlushUserBatch
161 *
162 * Callback for thread batch flush routine.
163 *
164 * Think small & fast!
165 */
166 NTSTATUS
167 APIENTRY
168 NtGdiFlushUserBatch(VOID)
169 {
170 PTEB pTeb = NtCurrentTeb();
171 ULONG GdiBatchCount = pTeb->GdiBatchCount;
172
173 if( (GdiBatchCount > 0) && (GdiBatchCount <= (GDIBATCHBUFSIZE/4)))
174 {
175 HDC hDC = (HDC) pTeb->GdiTebBatch.HDC;
176
177 /* If hDC is zero and the buffer fills up with delete objects we need
178 to run anyway.
179 */
180 if (hDC || GdiBatchCount)
181 {
182 PCHAR pHdr = (PCHAR)&pTeb->GdiTebBatch.Buffer[0];
183 PDC pDC = NULL;
184
185 if (GDI_HANDLE_GET_TYPE(hDC) == GDILoObjType_LO_DC_TYPE && GreIsHandleValid(hDC))
186 {
187 pDC = DC_LockDc(hDC);
188 }
189
190 // No need to init anything, just go!
191 for (; GdiBatchCount > 0; GdiBatchCount--)
192 {
193 ULONG Size;
194 // Process Gdi Batch!
195 Size = GdiFlushUserBatch(pDC, (PGDIBATCHHDR) pHdr);
196 if (!Size) break;
197 pHdr += Size;
198 }
199
200 if (pDC)
201 {
202 DC_UnlockDc(pDC);
203 }
204
205 // Exit and clear out for the next round.
206 pTeb->GdiTebBatch.Offset = 0;
207 pTeb->GdiBatchCount = 0;
208 pTeb->GdiTebBatch.HDC = 0;
209 }
210 }
211
212 // FIXME: On Windows XP the function returns &pTeb->RealClientId, maybe VOID?
213 return STATUS_SUCCESS;
214 }
215
216