[YAROTOWS] Reintegrate the branch. For a brighter future.
[reactos.git] / reactos / 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->flags & 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 = WIDTH_BYTES_ALIGN32(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 EngUnlockSurface(*ppsoOutput);
131 EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
132 return FALSE;
133 }
134 EnterLeave->DestRect.left = DestRect->left;
135 EnterLeave->DestRect.top = DestRect->top;
136 EnterLeave->DestRect.right = DestRect->right;
137 EnterLeave->DestRect.bottom = DestRect->bottom;
138 Translate->x = - DestRect->left;
139 Translate->y = - DestRect->top;
140 }
141 else
142 {
143 Translate->x = 0;
144 Translate->y = 0;
145 *ppsoOutput = psoDest;
146 }
147
148 if (NULL != *ppsoOutput)
149 {
150 SURFACE* psurfOutput = CONTAINING_RECORD(*ppsoOutput, SURFACE, SurfObj);
151 if (0 != (psurfOutput->flags & HOOK_SYNCHRONIZE))
152 {
153 if (NULL != GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface)
154 {
155 GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface(*ppsoOutput, DestRect, 0);
156 }
157 else if (STYPE_BITMAP == (*ppsoOutput)->iType
158 && NULL != GDIDEVFUNCS(*ppsoOutput).Synchronize)
159 {
160 GDIDEVFUNCS(*ppsoOutput).Synchronize((*ppsoOutput)->dhpdev, DestRect);
161 }
162 }
163 }
164 else return FALSE;
165
166 EnterLeave->DestObj = psoDest;
167 EnterLeave->OutputObj = *ppsoOutput;
168 EnterLeave->ReadOnly = ReadOnly;
169
170 return TRUE;
171 }
172
173 BOOL APIENTRY
174 IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave)
175 {
176 POINTL SrcPoint;
177 BOOL Result = TRUE;
178
179 if (EnterLeave->OutputObj != EnterLeave->DestObj && NULL != EnterLeave->OutputObj)
180 {
181 if (! EnterLeave->ReadOnly)
182 {
183 SrcPoint.x = 0;
184 SrcPoint.y = 0;
185 if (EnterLeave->DestRect.left < 0)
186 {
187 SrcPoint.x = - EnterLeave->DestRect.left;
188 EnterLeave->DestRect.left = 0;
189 }
190 if (EnterLeave->DestObj->sizlBitmap.cx < EnterLeave->DestRect.right)
191 {
192 EnterLeave->DestRect.right = EnterLeave->DestObj->sizlBitmap.cx;
193 }
194 if (EnterLeave->DestRect.top < 0)
195 {
196 SrcPoint.y = - EnterLeave->DestRect.top;
197 EnterLeave->DestRect.top = 0;
198 }
199 if (EnterLeave->DestObj->sizlBitmap.cy < EnterLeave->DestRect.bottom)
200 {
201 EnterLeave->DestRect.bottom = EnterLeave->DestObj->sizlBitmap.cy;
202 }
203 if (SrcPoint.x < EnterLeave->OutputObj->sizlBitmap.cx &&
204 EnterLeave->DestRect.left <= EnterLeave->DestRect.right &&
205 EnterLeave->DestRect.left < EnterLeave->DestObj->sizlBitmap.cx &&
206 SrcPoint.y < EnterLeave->OutputObj->sizlBitmap.cy &&
207 EnterLeave->DestRect.top <= EnterLeave->DestRect.bottom &&
208 EnterLeave->DestRect.top < EnterLeave->DestObj->sizlBitmap.cy)
209 {
210 Result = GDIDEVFUNCS(EnterLeave->DestObj).CopyBits(
211 EnterLeave->DestObj,
212 EnterLeave->OutputObj,
213 EnterLeave->TrivialClipObj, NULL,
214 &EnterLeave->DestRect, &SrcPoint);
215 }
216 else
217 {
218 Result = TRUE;
219 }
220 }
221 EngUnlockSurface(EnterLeave->OutputObj);
222 EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
223 EngDeleteClip(EnterLeave->TrivialClipObj);
224 }
225 else
226 {
227 Result = TRUE;
228 }
229
230 return Result;
231 }
232
233 HANDLE APIENTRY
234 EngGetProcessHandle(VOID)
235 {
236 /* http://www.osr.com/ddk/graphics/gdifncs_3tif.htm
237 In Windows 2000 and later, the EngGetProcessHandle function always returns NULL.
238 FIXME - what does NT4 return? */
239 return NULL;
240 }
241
242 VOID
243 APIENTRY
244 EngGetCurrentCodePage(OUT PUSHORT OemCodePage,
245 OUT PUSHORT AnsiCodePage)
246 {
247 /* Forward to kernel */
248 RtlGetDefaultCodePage(AnsiCodePage, OemCodePage);
249 }
250
251 BOOL
252 APIENTRY
253 EngQuerySystemAttribute(
254 IN ENG_SYSTEM_ATTRIBUTE CapNum,
255 OUT PDWORD pCapability)
256 {
257 SYSTEM_BASIC_INFORMATION sbi;
258 SYSTEM_PROCESSOR_INFORMATION spi;
259
260 switch (CapNum)
261 {
262 case EngNumberOfProcessors:
263 NtQuerySystemInformation(SystemBasicInformation,
264 &sbi,
265 sizeof(SYSTEM_BASIC_INFORMATION),
266 NULL);
267 *pCapability = sbi.NumberOfProcessors;
268 return TRUE;
269
270 case EngProcessorFeature:
271 NtQuerySystemInformation(SystemProcessorInformation,
272 &spi,
273 sizeof(SYSTEM_PROCESSOR_INFORMATION),
274 NULL);
275 *pCapability = spi.ProcessorFeatureBits;
276 return TRUE;
277
278 default:
279 break;
280 }
281
282 return FALSE;
283 }
284
285 ULONGLONG
286 APIENTRY
287 EngGetTickCount(VOID)
288 {
289 ULONG Multiplier;
290 LARGE_INTEGER TickCount;
291
292 /* Get the multiplier and current tick count */
293 KeQueryTickCount(&TickCount);
294 Multiplier = SharedUserData->TickCountMultiplier;
295
296 /* Convert to milliseconds and return */
297 return (Int64ShrlMod32(UInt32x32To64(Multiplier, TickCount.LowPart), 24) +
298 (Multiplier * (TickCount.HighPart << 8)));
299 }
300
301
302
303
304 /* EOF */