2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
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.
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.
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.
27 IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave
,
38 RECTL ClippedDestRect
;
41 if (DestRect
->right
< DestRect
->left
)
43 Exchange
= DestRect
->left
;
44 DestRect
->left
= DestRect
->right
;
45 DestRect
->right
= Exchange
;
47 if (DestRect
->bottom
< DestRect
->top
)
49 Exchange
= DestRect
->top
;
50 DestRect
->top
= DestRect
->bottom
;
51 DestRect
->bottom
= Exchange
;
54 if (NULL
!= psoDest
&& STYPE_BITMAP
!= psoDest
->iType
&&
55 (NULL
== psoDest
->pvScan0
|| 0 == psoDest
->lDelta
))
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
))
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
);
72 if (!EnterLeave
->OutputBitmap
)
74 DPRINT1("EngCreateBitmap() failed\n");
78 *ppsoOutput
= EngLockSurface((HSURF
)EnterLeave
->OutputBitmap
);
79 if (*ppsoOutput
== NULL
)
81 EngDeleteSurface((HSURF
)EnterLeave
->OutputBitmap
);
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
;
94 ClippedDestRect
.left
-= SrcPoint
.x
;
97 if (psoDest
->sizlBitmap
.cx
< SrcPoint
.x
+ ClippedDestRect
.right
- ClippedDestRect
.left
)
99 ClippedDestRect
.right
= ClippedDestRect
.left
+ psoDest
->sizlBitmap
.cx
- SrcPoint
.x
;
103 ClippedDestRect
.top
-= SrcPoint
.y
;
106 if (psoDest
->sizlBitmap
.cy
< SrcPoint
.y
+ ClippedDestRect
.bottom
- ClippedDestRect
.top
)
108 ClippedDestRect
.bottom
= ClippedDestRect
.top
+ psoDest
->sizlBitmap
.cy
- SrcPoint
.y
;
110 EnterLeave
->TrivialClipObj
= EngCreateClip();
111 if (EnterLeave
->TrivialClipObj
== NULL
)
113 EngUnlockSurface(*ppsoOutput
);
114 EngDeleteSurface((HSURF
)EnterLeave
->OutputBitmap
);
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
))
129 EngDeleteClip(EnterLeave
->TrivialClipObj
);
130 EngFreeMem((*ppsoOutput
)->pvBits
);
131 EngUnlockSurface(*ppsoOutput
);
132 EngDeleteSurface((HSURF
)EnterLeave
->OutputBitmap
);
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
;
146 *ppsoOutput
= psoDest
;
149 if (NULL
!= *ppsoOutput
)
151 SURFACE
* psurfOutput
= CONTAINING_RECORD(*ppsoOutput
, SURFACE
, SurfObj
);
152 if (0 != (psurfOutput
->flHooks
& HOOK_SYNCHRONIZE
))
154 if (NULL
!= GDIDEVFUNCS(*ppsoOutput
).SynchronizeSurface
)
156 GDIDEVFUNCS(*ppsoOutput
).SynchronizeSurface(*ppsoOutput
, DestRect
, 0);
158 else if (STYPE_BITMAP
== (*ppsoOutput
)->iType
159 && NULL
!= GDIDEVFUNCS(*ppsoOutput
).Synchronize
)
161 GDIDEVFUNCS(*ppsoOutput
).Synchronize((*ppsoOutput
)->dhpdev
, DestRect
);
167 EnterLeave
->DestObj
= psoDest
;
168 EnterLeave
->OutputObj
= *ppsoOutput
;
169 EnterLeave
->ReadOnly
= ReadOnly
;
175 IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave
)
180 if (EnterLeave
->OutputObj
!= EnterLeave
->DestObj
&& NULL
!= EnterLeave
->OutputObj
)
182 if (! EnterLeave
->ReadOnly
)
186 if (EnterLeave
->DestRect
.left
< 0)
188 SrcPoint
.x
= - EnterLeave
->DestRect
.left
;
189 EnterLeave
->DestRect
.left
= 0;
191 if (EnterLeave
->DestObj
->sizlBitmap
.cx
< EnterLeave
->DestRect
.right
)
193 EnterLeave
->DestRect
.right
= EnterLeave
->DestObj
->sizlBitmap
.cx
;
195 if (EnterLeave
->DestRect
.top
< 0)
197 SrcPoint
.y
= - EnterLeave
->DestRect
.top
;
198 EnterLeave
->DestRect
.top
= 0;
200 if (EnterLeave
->DestObj
->sizlBitmap
.cy
< EnterLeave
->DestRect
.bottom
)
202 EnterLeave
->DestRect
.bottom
= EnterLeave
->DestObj
->sizlBitmap
.cy
;
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
)
211 Result
= GDIDEVFUNCS(EnterLeave
->DestObj
).CopyBits(
213 EnterLeave
->OutputObj
,
214 EnterLeave
->TrivialClipObj
, NULL
,
215 &EnterLeave
->DestRect
, &SrcPoint
);
222 EngFreeMem(EnterLeave
->OutputObj
->pvBits
);
223 EngUnlockSurface(EnterLeave
->OutputObj
);
224 EngDeleteSurface((HSURF
)EnterLeave
->OutputBitmap
);
225 EngDeleteClip(EnterLeave
->TrivialClipObj
);
236 EngGetProcessHandle(VOID
)
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? */
246 EngGetCurrentCodePage(OUT PUSHORT OemCodePage
,
247 OUT PUSHORT AnsiCodePage
)
249 /* Forward to kernel */
250 RtlGetDefaultCodePage(AnsiCodePage
, OemCodePage
);
255 EngQuerySystemAttribute(
256 IN ENG_SYSTEM_ATTRIBUTE CapNum
,
257 OUT PDWORD pCapability
)
259 SYSTEM_BASIC_INFORMATION sbi
;
260 SYSTEM_PROCESSOR_INFORMATION spi
;
264 case EngNumberOfProcessors
:
265 NtQuerySystemInformation(SystemBasicInformation
,
267 sizeof(SYSTEM_BASIC_INFORMATION
),
269 *pCapability
= sbi
.NumberOfProcessors
;
272 case EngProcessorFeature
:
273 NtQuerySystemInformation(SystemProcessorInformation
,
275 sizeof(SYSTEM_PROCESSOR_INFORMATION
),
277 *pCapability
= spi
.ProcessorFeatureBits
;
289 EngGetTickCount(VOID
)
292 LARGE_INTEGER TickCount
;
294 /* Get the multiplier and current tick count */
295 KeQueryTickCount(&TickCount
);
296 Multiplier
= SharedUserData
->TickCountMultiplier
;
298 /* Convert to milliseconds and return */
299 return (Int64ShrlMod32(UInt32x32To64(Multiplier
, TickCount
.LowPart
), 24) +
300 (Multiplier
* (TickCount
.HighPart
<< 8)));