* Reorganize the whole ReactOS codebase into a new layout. Discussing it will only...
[reactos.git] / reactos / win32ss / gdi / eng / engmisc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: ENG misc Functions
5 * FILE: subsystems/win32/win32k/eng/engmisc.c
6 * PROGRAMER: ReactOS Team
7 */
8
9 #include <win32k.h>
10
11 #define NDEBUG
12 #include <debug.h>
13
14 BOOL APIENTRY
15 IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
16 SURFOBJ *psoDest,
17 RECTL *DestRect,
18 BOOL ReadOnly,
19 POINTL *Translate,
20 SURFOBJ **ppsoOutput)
21 {
22 LONG Exchange;
23 SIZEL BitmapSize;
24 POINTL SrcPoint;
25 LONG Width;
26 RECTL ClippedDestRect;
27
28 /* Normalize */
29 if (DestRect->right < DestRect->left)
30 {
31 Exchange = DestRect->left;
32 DestRect->left = DestRect->right;
33 DestRect->right = Exchange;
34 }
35 if (DestRect->bottom < DestRect->top)
36 {
37 Exchange = DestRect->top;
38 DestRect->top = DestRect->bottom;
39 DestRect->bottom = Exchange;
40 }
41
42 if (NULL != psoDest && STYPE_BITMAP != psoDest->iType &&
43 (NULL == psoDest->pvScan0 || 0 == psoDest->lDelta))
44 {
45 /* Driver needs to support DrvCopyBits, else we can't do anything */
46 SURFACE *psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
47 if (!(psurfDest->flags & HOOK_COPYBITS))
48 {
49 return FALSE;
50 }
51
52 /* Allocate a temporary bitmap */
53 BitmapSize.cx = DestRect->right - DestRect->left;
54 BitmapSize.cy = DestRect->bottom - DestRect->top;
55 Width = WIDTH_BYTES_ALIGN32(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat));
56 EnterLeave->OutputBitmap = EngCreateBitmap(BitmapSize, Width,
57 psoDest->iBitmapFormat,
58 BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
59
60 if (!EnterLeave->OutputBitmap)
61 {
62 DPRINT1("EngCreateBitmap() failed\n");
63 return FALSE;
64 }
65
66 *ppsoOutput = EngLockSurface((HSURF)EnterLeave->OutputBitmap);
67 if (*ppsoOutput == NULL)
68 {
69 EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
70 return FALSE;
71 }
72
73 EnterLeave->DestRect.left = 0;
74 EnterLeave->DestRect.top = 0;
75 EnterLeave->DestRect.right = BitmapSize.cx;
76 EnterLeave->DestRect.bottom = BitmapSize.cy;
77 SrcPoint.x = DestRect->left;
78 SrcPoint.y = DestRect->top;
79 ClippedDestRect = EnterLeave->DestRect;
80 if (SrcPoint.x < 0)
81 {
82 ClippedDestRect.left -= SrcPoint.x;
83 SrcPoint.x = 0;
84 }
85 if (psoDest->sizlBitmap.cx < SrcPoint.x + ClippedDestRect.right - ClippedDestRect.left)
86 {
87 ClippedDestRect.right = ClippedDestRect.left + psoDest->sizlBitmap.cx - SrcPoint.x;
88 }
89 if (SrcPoint.y < 0)
90 {
91 ClippedDestRect.top -= SrcPoint.y;
92 SrcPoint.y = 0;
93 }
94 if (psoDest->sizlBitmap.cy < SrcPoint.y + ClippedDestRect.bottom - ClippedDestRect.top)
95 {
96 ClippedDestRect.bottom = ClippedDestRect.top + psoDest->sizlBitmap.cy - SrcPoint.y;
97 }
98 EnterLeave->TrivialClipObj = EngCreateClip();
99 if (EnterLeave->TrivialClipObj == NULL)
100 {
101 EngUnlockSurface(*ppsoOutput);
102 EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
103 return FALSE;
104 }
105 EnterLeave->TrivialClipObj->iDComplexity = DC_TRIVIAL;
106 if (ClippedDestRect.left < (*ppsoOutput)->sizlBitmap.cx &&
107 0 <= ClippedDestRect.right &&
108 SrcPoint.x < psoDest->sizlBitmap.cx &&
109 ClippedDestRect.top <= (*ppsoOutput)->sizlBitmap.cy &&
110 0 <= ClippedDestRect.bottom &&
111 SrcPoint.y < psoDest->sizlBitmap.cy &&
112 ! GDIDEVFUNCS(psoDest).CopyBits(
113 *ppsoOutput, psoDest,
114 EnterLeave->TrivialClipObj, NULL,
115 &ClippedDestRect, &SrcPoint))
116 {
117 EngDeleteClip(EnterLeave->TrivialClipObj);
118 EngUnlockSurface(*ppsoOutput);
119 EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
120 return FALSE;
121 }
122 EnterLeave->DestRect.left = DestRect->left;
123 EnterLeave->DestRect.top = DestRect->top;
124 EnterLeave->DestRect.right = DestRect->right;
125 EnterLeave->DestRect.bottom = DestRect->bottom;
126 Translate->x = - DestRect->left;
127 Translate->y = - DestRect->top;
128 }
129 else
130 {
131 Translate->x = 0;
132 Translate->y = 0;
133 *ppsoOutput = psoDest;
134 }
135
136 if (NULL != *ppsoOutput)
137 {
138 SURFACE* psurfOutput = CONTAINING_RECORD(*ppsoOutput, SURFACE, SurfObj);
139 if (0 != (psurfOutput->flags & HOOK_SYNCHRONIZE))
140 {
141 if (NULL != GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface)
142 {
143 GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface(*ppsoOutput, DestRect, 0);
144 }
145 else if (STYPE_BITMAP == (*ppsoOutput)->iType
146 && NULL != GDIDEVFUNCS(*ppsoOutput).Synchronize)
147 {
148 GDIDEVFUNCS(*ppsoOutput).Synchronize((*ppsoOutput)->dhpdev, DestRect);
149 }
150 }
151 }
152 else return FALSE;
153
154 EnterLeave->DestObj = psoDest;
155 EnterLeave->OutputObj = *ppsoOutput;
156 EnterLeave->ReadOnly = ReadOnly;
157
158 return TRUE;
159 }
160
161 BOOL APIENTRY
162 IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave)
163 {
164 POINTL SrcPoint;
165 BOOL Result = TRUE;
166
167 if (EnterLeave->OutputObj != EnterLeave->DestObj && NULL != EnterLeave->OutputObj)
168 {
169 if (! EnterLeave->ReadOnly)
170 {
171 SrcPoint.x = 0;
172 SrcPoint.y = 0;
173 if (EnterLeave->DestRect.left < 0)
174 {
175 SrcPoint.x = - EnterLeave->DestRect.left;
176 EnterLeave->DestRect.left = 0;
177 }
178 if (EnterLeave->DestObj->sizlBitmap.cx < EnterLeave->DestRect.right)
179 {
180 EnterLeave->DestRect.right = EnterLeave->DestObj->sizlBitmap.cx;
181 }
182 if (EnterLeave->DestRect.top < 0)
183 {
184 SrcPoint.y = - EnterLeave->DestRect.top;
185 EnterLeave->DestRect.top = 0;
186 }
187 if (EnterLeave->DestObj->sizlBitmap.cy < EnterLeave->DestRect.bottom)
188 {
189 EnterLeave->DestRect.bottom = EnterLeave->DestObj->sizlBitmap.cy;
190 }
191 if (SrcPoint.x < EnterLeave->OutputObj->sizlBitmap.cx &&
192 EnterLeave->DestRect.left <= EnterLeave->DestRect.right &&
193 EnterLeave->DestRect.left < EnterLeave->DestObj->sizlBitmap.cx &&
194 SrcPoint.y < EnterLeave->OutputObj->sizlBitmap.cy &&
195 EnterLeave->DestRect.top <= EnterLeave->DestRect.bottom &&
196 EnterLeave->DestRect.top < EnterLeave->DestObj->sizlBitmap.cy)
197 {
198 Result = GDIDEVFUNCS(EnterLeave->DestObj).CopyBits(
199 EnterLeave->DestObj,
200 EnterLeave->OutputObj,
201 EnterLeave->TrivialClipObj, NULL,
202 &EnterLeave->DestRect, &SrcPoint);
203 }
204 else
205 {
206 Result = TRUE;
207 }
208 }
209 EngUnlockSurface(EnterLeave->OutputObj);
210 EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
211 EngDeleteClip(EnterLeave->TrivialClipObj);
212 }
213 else
214 {
215 Result = TRUE;
216 }
217
218 return Result;
219 }
220
221 HANDLE APIENTRY
222 EngGetProcessHandle(VOID)
223 {
224 /* http://www.osr.com/ddk/graphics/gdifncs_3tif.htm
225 In Windows 2000 and later, the EngGetProcessHandle function always returns NULL.
226 FIXME: What does NT4 return? */
227 return NULL;
228 }
229
230 VOID
231 APIENTRY
232 EngGetCurrentCodePage(OUT PUSHORT OemCodePage,
233 OUT PUSHORT AnsiCodePage)
234 {
235 /* Forward to kernel */
236 RtlGetDefaultCodePage(AnsiCodePage, OemCodePage);
237 }
238
239 BOOL
240 APIENTRY
241 EngQuerySystemAttribute(
242 IN ENG_SYSTEM_ATTRIBUTE CapNum,
243 OUT PDWORD pCapability)
244 {
245 SYSTEM_BASIC_INFORMATION sbi;
246 SYSTEM_PROCESSOR_INFORMATION spi;
247
248 switch (CapNum)
249 {
250 case EngNumberOfProcessors:
251 NtQuerySystemInformation(SystemBasicInformation,
252 &sbi,
253 sizeof(SYSTEM_BASIC_INFORMATION),
254 NULL);
255 *pCapability = sbi.NumberOfProcessors;
256 return TRUE;
257
258 case EngProcessorFeature:
259 NtQuerySystemInformation(SystemProcessorInformation,
260 &spi,
261 sizeof(SYSTEM_PROCESSOR_INFORMATION),
262 NULL);
263 *pCapability = spi.ProcessorFeatureBits;
264 return TRUE;
265
266 default:
267 break;
268 }
269
270 return FALSE;
271 }
272
273 ULONGLONG
274 APIENTRY
275 EngGetTickCount(VOID)
276 {
277 ULONG Multiplier;
278 LARGE_INTEGER TickCount;
279
280 /* Get the multiplier and current tick count */
281 KeQueryTickCount(&TickCount);
282 Multiplier = SharedUserData->TickCountMultiplier;
283
284 /* Convert to milliseconds and return */
285 return (Int64ShrlMod32(UInt32x32To64(Multiplier, TickCount.LowPart), 24) +
286 (Multiplier * (TickCount.HighPart << 8)));
287 }
288
289 /* EOF */