Sync with trunk (r47116), hopefully without breaking anything.
[reactos.git] / subsystems / win32 / win32k / eng / engmisc.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /* $Id$ */
20
21 #include <win32k.h>
22
23 #define NDEBUG
24 #include <debug.h>
25
26 BOOL APIENTRY
27 IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
28 SURFOBJ *psoDest,
29 RECTL *DestRect,
30 BOOL ReadOnly,
31 POINTL *Translate,
32 SURFOBJ **ppsoOutput)
33 {
34 LONG Exchange;
35 SIZEL BitmapSize;
36 POINTL SrcPoint;
37 LONG Width;
38 RECTL ClippedDestRect;
39
40 /* Normalize */
41 if (DestRect->right < DestRect->left)
42 {
43 Exchange = DestRect->left;
44 DestRect->left = DestRect->right;
45 DestRect->right = Exchange;
46 }
47 if (DestRect->bottom < DestRect->top)
48 {
49 Exchange = DestRect->top;
50 DestRect->top = DestRect->bottom;
51 DestRect->bottom = Exchange;
52 }
53
54 if (NULL != psoDest && STYPE_BITMAP != psoDest->iType &&
55 (NULL == psoDest->pvScan0 || 0 == psoDest->lDelta))
56 {
57 /* Driver needs to support DrvCopyBits, else we can't do anything */
58 SURFACE *psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
59 if (!(psurfDest->flHooks & HOOK_COPYBITS))
60 {
61 return FALSE;
62 }
63
64 /* Allocate a temporary bitmap */
65 BitmapSize.cx = DestRect->right - DestRect->left;
66 BitmapSize.cy = DestRect->bottom - DestRect->top;
67 Width = DIB_GetDIBWidthBytes(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat));
68 EnterLeave->OutputBitmap = EngCreateBitmap(BitmapSize, Width,
69 psoDest->iBitmapFormat,
70 BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
71
72 if (!EnterLeave->OutputBitmap)
73 {
74 DPRINT1("EngCreateBitmap() failed\n");
75 return FALSE;
76 }
77
78 *ppsoOutput = EngLockSurface((HSURF)EnterLeave->OutputBitmap);
79 if (*ppsoOutput == NULL)
80 {
81 EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
82 return FALSE;
83 }
84
85 EnterLeave->DestRect.left = 0;
86 EnterLeave->DestRect.top = 0;
87 EnterLeave->DestRect.right = BitmapSize.cx;
88 EnterLeave->DestRect.bottom = BitmapSize.cy;
89 SrcPoint.x = DestRect->left;
90 SrcPoint.y = DestRect->top;
91 ClippedDestRect = EnterLeave->DestRect;
92 if (SrcPoint.x < 0)
93 {
94 ClippedDestRect.left -= SrcPoint.x;
95 SrcPoint.x = 0;
96 }
97 if (psoDest->sizlBitmap.cx < SrcPoint.x + ClippedDestRect.right - ClippedDestRect.left)
98 {
99 ClippedDestRect.right = ClippedDestRect.left + psoDest->sizlBitmap.cx - SrcPoint.x;
100 }
101 if (SrcPoint.y < 0)
102 {
103 ClippedDestRect.top -= SrcPoint.y;
104 SrcPoint.y = 0;
105 }
106 if (psoDest->sizlBitmap.cy < SrcPoint.y + ClippedDestRect.bottom - ClippedDestRect.top)
107 {
108 ClippedDestRect.bottom = ClippedDestRect.top + psoDest->sizlBitmap.cy - SrcPoint.y;
109 }
110 EnterLeave->TrivialClipObj = EngCreateClip();
111 if (EnterLeave->TrivialClipObj == NULL)
112 {
113 EngUnlockSurface(*ppsoOutput);
114 EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
115 return FALSE;
116 }
117 EnterLeave->TrivialClipObj->iDComplexity = DC_TRIVIAL;
118 if (ClippedDestRect.left < (*ppsoOutput)->sizlBitmap.cx &&
119 0 <= ClippedDestRect.right &&
120 SrcPoint.x < psoDest->sizlBitmap.cx &&
121 ClippedDestRect.top <= (*ppsoOutput)->sizlBitmap.cy &&
122 0 <= ClippedDestRect.bottom &&
123 SrcPoint.y < psoDest->sizlBitmap.cy &&
124 ! GDIDEVFUNCS(psoDest).CopyBits(
125 *ppsoOutput, psoDest,
126 EnterLeave->TrivialClipObj, NULL,
127 &ClippedDestRect, &SrcPoint))
128 {
129 EngDeleteClip(EnterLeave->TrivialClipObj);
130 EngFreeMem((*ppsoOutput)->pvBits);
131 EngUnlockSurface(*ppsoOutput);
132 EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
133 return FALSE;
134 }
135 EnterLeave->DestRect.left = DestRect->left;
136 EnterLeave->DestRect.top = DestRect->top;
137 EnterLeave->DestRect.right = DestRect->right;
138 EnterLeave->DestRect.bottom = DestRect->bottom;
139 Translate->x = - DestRect->left;
140 Translate->y = - DestRect->top;
141 }
142 else
143 {
144 Translate->x = 0;
145 Translate->y = 0;
146 *ppsoOutput = psoDest;
147 }
148
149 if (NULL != *ppsoOutput)
150 {
151 SURFACE* psurfOutput = CONTAINING_RECORD(*ppsoOutput, SURFACE, SurfObj);
152 if (0 != (psurfOutput->flHooks & HOOK_SYNCHRONIZE))
153 {
154 if (NULL != GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface)
155 {
156 GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface(*ppsoOutput, DestRect, 0);
157 }
158 else if (STYPE_BITMAP == (*ppsoOutput)->iType
159 && NULL != GDIDEVFUNCS(*ppsoOutput).Synchronize)
160 {
161 GDIDEVFUNCS(*ppsoOutput).Synchronize((*ppsoOutput)->dhpdev, DestRect);
162 }
163 }
164 }
165 else return FALSE;
166
167 EnterLeave->DestObj = psoDest;
168 EnterLeave->OutputObj = *ppsoOutput;
169 EnterLeave->ReadOnly = ReadOnly;
170
171 return TRUE;
172 }
173
174 BOOL APIENTRY
175 IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave)
176 {
177 POINTL SrcPoint;
178 BOOL Result = TRUE;
179
180 if (EnterLeave->OutputObj != EnterLeave->DestObj && NULL != EnterLeave->OutputObj)
181 {
182 if (! EnterLeave->ReadOnly)
183 {
184 SrcPoint.x = 0;
185 SrcPoint.y = 0;
186 if (EnterLeave->DestRect.left < 0)
187 {
188 SrcPoint.x = - EnterLeave->DestRect.left;
189 EnterLeave->DestRect.left = 0;
190 }
191 if (EnterLeave->DestObj->sizlBitmap.cx < EnterLeave->DestRect.right)
192 {
193 EnterLeave->DestRect.right = EnterLeave->DestObj->sizlBitmap.cx;
194 }
195 if (EnterLeave->DestRect.top < 0)
196 {
197 SrcPoint.y = - EnterLeave->DestRect.top;
198 EnterLeave->DestRect.top = 0;
199 }
200 if (EnterLeave->DestObj->sizlBitmap.cy < EnterLeave->DestRect.bottom)
201 {
202 EnterLeave->DestRect.bottom = EnterLeave->DestObj->sizlBitmap.cy;
203 }
204 if (SrcPoint.x < EnterLeave->OutputObj->sizlBitmap.cx &&
205 EnterLeave->DestRect.left <= EnterLeave->DestRect.right &&
206 EnterLeave->DestRect.left < EnterLeave->DestObj->sizlBitmap.cx &&
207 SrcPoint.y < EnterLeave->OutputObj->sizlBitmap.cy &&
208 EnterLeave->DestRect.top <= EnterLeave->DestRect.bottom &&
209 EnterLeave->DestRect.top < EnterLeave->DestObj->sizlBitmap.cy)
210 {
211 Result = GDIDEVFUNCS(EnterLeave->DestObj).CopyBits(
212 EnterLeave->DestObj,
213 EnterLeave->OutputObj,
214 EnterLeave->TrivialClipObj, NULL,
215 &EnterLeave->DestRect, &SrcPoint);
216 }
217 else
218 {
219 Result = TRUE;
220 }
221 }
222 EngFreeMem(EnterLeave->OutputObj->pvBits);
223 EngUnlockSurface(EnterLeave->OutputObj);
224 EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
225 EngDeleteClip(EnterLeave->TrivialClipObj);
226 }
227 else
228 {
229 Result = TRUE;
230 }
231
232 return Result;
233 }
234
235 HANDLE APIENTRY
236 EngGetProcessHandle(VOID)
237 {
238 /* http://www.osr.com/ddk/graphics/gdifncs_3tif.htm
239 In Windows 2000 and later, the EngGetProcessHandle function always returns NULL.
240 FIXME - what does NT4 return? */
241 return NULL;
242 }
243
244 VOID
245 APIENTRY
246 EngGetCurrentCodePage(OUT PUSHORT OemCodePage,
247 OUT PUSHORT AnsiCodePage)
248 {
249 /* Forward to kernel */
250 RtlGetDefaultCodePage(AnsiCodePage, OemCodePage);
251 }
252
253 BOOL
254 APIENTRY
255 EngQuerySystemAttribute(
256 IN ENG_SYSTEM_ATTRIBUTE CapNum,
257 OUT PDWORD pCapability)
258 {
259 SYSTEM_BASIC_INFORMATION sbi;
260 SYSTEM_PROCESSOR_INFORMATION spi;
261
262 switch (CapNum)
263 {
264 case EngNumberOfProcessors:
265 NtQuerySystemInformation(SystemBasicInformation,
266 &sbi,
267 sizeof(SYSTEM_BASIC_INFORMATION),
268 NULL);
269 *pCapability = sbi.NumberOfProcessors;
270 return TRUE;
271
272 case EngProcessorFeature:
273 NtQuerySystemInformation(SystemProcessorInformation,
274 &spi,
275 sizeof(SYSTEM_PROCESSOR_INFORMATION),
276 NULL);
277 *pCapability = spi.ProcessorFeatureBits;
278 return TRUE;
279
280 default:
281 break;
282 }
283
284 return FALSE;
285 }
286
287 ULONGLONG
288 APIENTRY
289 EngGetTickCount(VOID)
290 {
291 ULONG Multiplier;
292 LARGE_INTEGER TickCount;
293
294 /* Get the multiplier and current tick count */
295 KeQueryTickCount(&TickCount);
296 Multiplier = SharedUserData->TickCountMultiplier;
297
298 /* Convert to milliseconds and return */
299 return (Int64ShrlMod32(UInt32x32To64(Multiplier, TickCount.LowPart), 24) +
300 (Multiplier * (TickCount.HighPart << 8)));
301 }
302
303
304
305
306 /* EOF */