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