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