xref: /reactos/win32ss/gdi/eng/engmisc.c (revision 84ccccab)
1 /*
2  * COPYRIGHT:         See COPYING in the top level directory
3  * PROJECT:           ReactOS Win32k subsystem
4  * PURPOSE:           ENG misc Functions
5  * FILE:              win32ss/gdi/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(
233     _Out_ PUSHORT OemCodePage,
234     _Out_ PUSHORT AnsiCodePage)
235 {
236     /* Forward to kernel */
237     RtlGetDefaultCodePage(AnsiCodePage, OemCodePage);
238 }
239 
240 BOOL
241 APIENTRY
242 EngQuerySystemAttribute(
243    _In_ ENG_SYSTEM_ATTRIBUTE CapNum,
244    _Out_ PDWORD pCapability)
245 {
246     SYSTEM_BASIC_INFORMATION sbi;
247     SYSTEM_PROCESSOR_INFORMATION spi;
248     NTSTATUS status;
249 
250     switch (CapNum)
251     {
252         case EngNumberOfProcessors:
253             status = NtQuerySystemInformation(SystemBasicInformation,
254                                               &sbi,
255                                               sizeof(SYSTEM_BASIC_INFORMATION),
256                                               NULL);
257             if (!NT_SUCCESS(status))
258             {
259                 DPRINT1("Failed to query basic information: 0x%lx\n", status);
260                 return FALSE;
261             }
262 
263             *pCapability = sbi.NumberOfProcessors;
264             return TRUE;
265 
266         case EngProcessorFeature:
267             status = NtQuerySystemInformation(SystemProcessorInformation,
268                                               &spi,
269                                               sizeof(SYSTEM_PROCESSOR_INFORMATION),
270                                               NULL);
271             if (!NT_SUCCESS(status))
272             {
273                 DPRINT1("Failed to query processor information: 0x%lx\n", status);
274                 return FALSE;
275             }
276             *pCapability = spi.ProcessorFeatureBits;
277             return TRUE;
278 
279         default:
280             break;
281     }
282 
283     return FALSE;
284 }
285 
286 ULONGLONG
287 APIENTRY
288 EngGetTickCount(VOID)
289 {
290     ULONG Multiplier;
291     LARGE_INTEGER TickCount;
292 
293     /* Get the multiplier and current tick count */
294     KeQueryTickCount(&TickCount);
295     Multiplier = SharedUserData->TickCountMultiplier;
296 
297     /* Convert to milliseconds and return */
298     return (Int64ShrlMod32(UInt32x32To64(Multiplier, TickCount.LowPart), 24) +
299             (Multiplier * (TickCount.HighPart << 8)));
300 }
301 
302 /* EOF */
303