Commit the stuff. Lots of changes. I'll write a proper list of changes when it's...
[reactos.git] / subsystems / win32 / win32k / objects / gdibatch.c
1
2 #include <w32k.h>
3
4 #define NDEBUG
5 #include <debug.h>
6
7
8 //
9 //
10 // Gdi Batch Flush support functions.
11 //
12
13 //
14 // DoDeviceSync
15 //
16 // based on IntEngEnter from eng/engmisc.c
17 //
18 VOID
19 FASTCALL
20 DoDeviceSync( SURFOBJ *Surface, PRECTL Rect, FLONG fl)
21 {
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))
26 {
27 if (Device->DriverFunctions.SynchronizeSurface)
28 {
29 Device->DriverFunctions.SynchronizeSurface(Surface, Rect, fl);
30 }
31 else
32 {
33 if (Device->DriverFunctions.Synchronize)
34 {
35 Device->DriverFunctions.Synchronize(Surface->dhpdev, Rect);
36 }
37 }
38 }
39 }
40
41 VOID
42 FASTCALL
43 SynchonizeDriver(FLONG Flags)
44 {
45 SURFOBJ *SurfObj;
46 PPDEVOBJ Device;
47
48 if (Flags & GCAPS2_SYNCFLUSH)
49 Flags = DSS_FLUSH_EVENT;
50 if (Flags & GCAPS2_SYNCTIMER)
51 Flags = DSS_TIMER_EVENT;
52
53 Device = IntEnumHDev();
54 // UNIMPLEMENTED;
55 //ASSERT(FALSE);
56 SurfObj = 0;// EngLockSurface( Device->pSurface );
57 if(!SurfObj) return;
58 DoDeviceSync( SurfObj, NULL, Flags);
59 EngUnlockSurface(SurfObj);
60 return;
61 }
62
63 //
64 // Process the batch.
65 //
66 ULONG
67 FASTCALL
68 GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
69 {
70 PDC_ATTR pdcattr = NULL;
71
72 if (dc)
73 {
74 pdcattr = dc->pdcattr;
75 }
76 // The thread is approaching the end of sunset.
77 switch(pHdr->Cmd)
78 {
79 case GdiBCPatBlt: // Highest pri first!
80 break;
81 case GdiBCPolyPatBlt:
82 break;
83 case GdiBCTextOut:
84 break;
85 case GdiBCExtTextOut:
86 break;
87 case GdiBCSetBrushOrg:
88 {
89 PGDIBSSETBRHORG pgSBO;
90 if(!dc) break;
91 pgSBO = (PGDIBSSETBRHORG) pHdr;
92 pdcattr->ptlBrushOrigin = pgSBO->ptlBrushOrigin;
93 break;
94 }
95 case GdiBCExtSelClipRgn:
96 break;
97 case GdiBCSelObj:
98 {
99 PGDIBSOBJECT pgO;
100 if(!dc) break;
101 pgO = (PGDIBSOBJECT) pHdr;
102 TextIntRealizeFont((HFONT) pgO->hgdiobj, NULL);
103 pdcattr->ulDirty_ &= ~(DIRTY_CHARSET);
104 }
105 case GdiBCDelObj:
106 case GdiBCDelRgn:
107 {
108 PGDIBSOBJECT pgO = (PGDIBSOBJECT) pHdr;
109 GreDeleteObject( pgO->hgdiobj );
110 break;
111 }
112 default:
113 break;
114 }
115
116 return pHdr->Size; // Return the full size of the structure.
117 }
118
119 /*
120 * NtGdiFlush
121 *
122 * Flushes the calling thread's current batch.
123 */
124 VOID
125 APIENTRY
126 NtGdiFlush(VOID)
127 {
128 SynchonizeDriver(GCAPS2_SYNCFLUSH);
129 }
130
131 /*
132 * NtGdiFlushUserBatch
133 *
134 * Callback for thread batch flush routine.
135 *
136 * Think small & fast!
137 */
138 NTSTATUS
139 APIENTRY
140 NtGdiFlushUserBatch(VOID)
141 {
142 PTEB pTeb = NtCurrentTeb();
143 ULONG GdiBatchCount = pTeb->GdiBatchCount;
144
145 if( (GdiBatchCount > 0) && (GdiBatchCount <= (GDIBATCHBUFSIZE/4)))
146 {
147 HDC hDC = (HDC) pTeb->GdiTebBatch.HDC;
148
149 /* If hDC is zero and the buffer fills up with delete objects we need
150 to run anyway. So, hard code to the system batch limit. */
151 if ((hDC) || (GdiBatchCount >= GDI_BATCH_LIMIT))
152 {
153 PCHAR pHdr = (PCHAR)&pTeb->GdiTebBatch.Buffer[0];
154 PDC pDC = NULL;
155
156 if (hDC && !IsObjectDead(hDC))
157 {
158 pDC = DC_LockDc(hDC);
159 }
160
161 // No need to init anything, just go!
162 for (; GdiBatchCount > 0; GdiBatchCount--)
163 {
164 // Process Gdi Batch!
165 pHdr += GdiFlushUserBatch(pDC, (PGDIBATCHHDR) pHdr);
166 }
167
168 if (pDC)
169 {
170 DC_UnlockDc(pDC);
171 }
172
173 // Exit and clear out for the next round.
174 pTeb->GdiTebBatch.Offset = 0;
175 pTeb->GdiBatchCount = 0;
176 pTeb->GdiTebBatch.HDC = 0;
177 }
178 }
179
180 // FIXME: on xp the function returns &pTeb->RealClientId, maybe VOID?
181 return STATUS_SUCCESS;
182 }
183
184