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
->flags
& HOOK_COPYBITS
))
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
);
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 EngUnlockSurface(*ppsoOutput
);
131 EngDeleteSurface((HSURF
)EnterLeave
->OutputBitmap
);
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
;
145 *ppsoOutput
= psoDest
;
148 if (NULL
!= *ppsoOutput
)
150 SURFACE
* psurfOutput
= CONTAINING_RECORD(*ppsoOutput
, SURFACE
, SurfObj
);
151 if (0 != (psurfOutput
->flags
& HOOK_SYNCHRONIZE
))
153 if (NULL
!= GDIDEVFUNCS(*ppsoOutput
).SynchronizeSurface
)
155 GDIDEVFUNCS(*ppsoOutput
).SynchronizeSurface(*ppsoOutput
, DestRect
, 0);
157 else if (STYPE_BITMAP
== (*ppsoOutput
)->iType
158 && NULL
!= GDIDEVFUNCS(*ppsoOutput
).Synchronize
)
160 GDIDEVFUNCS(*ppsoOutput
).Synchronize((*ppsoOutput
)->dhpdev
, DestRect
);
166 EnterLeave
->DestObj
= psoDest
;
167 EnterLeave
->OutputObj
= *ppsoOutput
;
168 EnterLeave
->ReadOnly
= ReadOnly
;
174 IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave
)
179 if (EnterLeave
->OutputObj
!= EnterLeave
->DestObj
&& NULL
!= EnterLeave
->OutputObj
)
181 if (! EnterLeave
->ReadOnly
)
185 if (EnterLeave
->DestRect
.left
< 0)
187 SrcPoint
.x
= - EnterLeave
->DestRect
.left
;
188 EnterLeave
->DestRect
.left
= 0;
190 if (EnterLeave
->DestObj
->sizlBitmap
.cx
< EnterLeave
->DestRect
.right
)
192 EnterLeave
->DestRect
.right
= EnterLeave
->DestObj
->sizlBitmap
.cx
;
194 if (EnterLeave
->DestRect
.top
< 0)
196 SrcPoint
.y
= - EnterLeave
->DestRect
.top
;
197 EnterLeave
->DestRect
.top
= 0;
199 if (EnterLeave
->DestObj
->sizlBitmap
.cy
< EnterLeave
->DestRect
.bottom
)
201 EnterLeave
->DestRect
.bottom
= EnterLeave
->DestObj
->sizlBitmap
.cy
;
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
)
210 Result
= GDIDEVFUNCS(EnterLeave
->DestObj
).CopyBits(
212 EnterLeave
->OutputObj
,
213 EnterLeave
->TrivialClipObj
, NULL
,
214 &EnterLeave
->DestRect
, &SrcPoint
);
221 EngUnlockSurface(EnterLeave
->OutputObj
);
222 EngDeleteSurface((HSURF
)EnterLeave
->OutputBitmap
);
223 EngDeleteClip(EnterLeave
->TrivialClipObj
);
234 EngGetProcessHandle(VOID
)
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? */
244 EngGetCurrentCodePage(OUT PUSHORT OemCodePage
,
245 OUT PUSHORT AnsiCodePage
)
247 /* Forward to kernel */
248 RtlGetDefaultCodePage(AnsiCodePage
, OemCodePage
);
253 EngQuerySystemAttribute(
254 IN ENG_SYSTEM_ATTRIBUTE CapNum
,
255 OUT PDWORD pCapability
)
257 SYSTEM_BASIC_INFORMATION sbi
;
258 SYSTEM_PROCESSOR_INFORMATION spi
;
262 case EngNumberOfProcessors
:
263 NtQuerySystemInformation(SystemBasicInformation
,
265 sizeof(SYSTEM_BASIC_INFORMATION
),
267 *pCapability
= sbi
.NumberOfProcessors
;
270 case EngProcessorFeature
:
271 NtQuerySystemInformation(SystemProcessorInformation
,
273 sizeof(SYSTEM_PROCESSOR_INFORMATION
),
275 *pCapability
= spi
.ProcessorFeatureBits
;
287 EngGetTickCount(VOID
)
290 LARGE_INTEGER TickCount
;
292 /* Get the multiplier and current tick count */
293 KeQueryTickCount(&TickCount
);
294 Multiplier
= SharedUserData
->TickCountMultiplier
;
296 /* Convert to milliseconds and return */
297 return (Int64ShrlMod32(UInt32x32To64(Multiplier
, TickCount
.LowPart
), 24) +
298 (Multiplier
* (TickCount
.HighPart
<< 8)));