* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI Driver Surace Functions
- * FILE: subsys/win32k/eng/surface.c
+ * FILE: win32ss/gdi/eng/surface.c
* PROGRAMERS: Jason Filby
* Timo Kreuzer
* TESTING TO BE DONE:
_In_ ULONG iFormat,
_In_ ULONG fjBitmap,
_In_opt_ ULONG cjWidth,
+ _In_opt_ ULONG cjBufSize,
_In_opt_ PVOID pvBits)
{
ULONG cBitsPixel, cjBits, cjObject;
SURFOBJ *pso;
PVOID pvSection;
- ASSERT(!pvBits || (iType == STYPE_BITMAP));
+ NT_ASSERT(!pvBits || (iType == STYPE_BITMAP));
+ NT_ASSERT((iFormat <= BMF_32BPP) || (cjBufSize != 0));
+ NT_ASSERT((LONG)cy > 0);
/* Verify format */
if ((iFormat < BMF_1BPP) || (iFormat > BMF_PNG))
cjWidth = WIDTH_BYTES_ALIGN32(cx, cBitsPixel);
}
- /* Calculate the bitmap size in bytes */
- cjBits = cjWidth * cy;
+ /* Is this an uncompressed format? */
+ if (iFormat <= BMF_32BPP)
+ {
+ /* Calculate the correct bitmap size in bytes */
+ if (!NT_SUCCESS(RtlULongMult(cjWidth, cy, &cjBits)))
+ {
+ DPRINT1("Overflow calculating size: cjWidth %lu, cy %lu\n",
+ cjWidth, cy);
+ return NULL;
+ }
+
+ /* Did we get a buffer and size? */
+ if ((pvBits != NULL) && (cjBufSize != 0))
+ {
+ /* Make sure the buffer is large enough */
+ if (cjBufSize < cjBits)
+ {
+ DPRINT1("Buffer is too small, required: %lu, got %lu\n",
+ cjBits, cjBufSize);
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ /* Compressed format, use the provided size */
+ NT_ASSERT(cjBufSize != 0);
+ cjBits = cjBufSize;
+ }
/* Check if we need an extra large object */
if ((iType == STYPE_BITMAP) && (pvBits == NULL) &&
}
/* Check for arithmetic overflow */
- if ((cjBits < cjWidth) || (cjObject < sizeof(SURFACE)))
+ if (cjObject < sizeof(SURFACE))
{
/* Fail! */
+ DPRINT1("Overflow calculating cjObject: cjBits %lu\n", cjBits);
return NULL;
}
iFormat,
fl,
lWidth,
+ 0,
pvBits);
if (!psurf)
{
- DPRINT1("SURFACE_AllocSurface failed.\n");
+ DPRINT1("SURFACE_AllocSurface failed. (STYPE_BITMAP, sizl.cx=%ld, sizl.cy=%ld, iFormat=%lu, fl=%lu, lWidth=%ld, pvBits=0x%p)\n",
+ sizl.cx, sizl.cy, iFormat, fl, lWidth, pvBits);
return NULL;
}
iFormat,
0,
0,
+ 0,
NULL);
if (!psurf)
{
- DPRINT1("SURFACE_AllocSurface failed.\n");
+ DPRINT1("SURFACE_AllocSurface failed. (STYPE_DEVBITMAP, sizl.cx=%ld, sizl.cy=%ld, iFormat=%lu)\n",
+ sizl.cx, sizl.cy, iFormat);
return NULL;
}
iFormat,
0,
0,
+ 0,
NULL);
if (!psurf)
{
- DPRINT1("SURFACE_AllocSurface failed.\n");
+ DPRINT1("SURFACE_AllocSurface failed. (STYPE_DEVICE, sizl.cx=%ld, sizl.cy=%ld, iFormat=%lu)\n",
+ sizl.cx, sizl.cy, iFormat);
return NULL;
}
_In_ FLONG flHooks,
_In_ FLONG flSurface,
_In_ DHSURF dhsurf,
- _In_ VOID *pvScan0,
+ _In_ PVOID pvScan0,
_In_ LONG lDelta,
- _Reserved_ VOID *pvReserved)
+ _Reserved_ PVOID pvReserved)
{
SURFOBJ *pso;
PSURFACE psurf;
PDEVOBJ* ppdev;
PPALETTE ppal;
+ /* Lock the surface */
psurf = SURFACE_ShareLockSurface(hsurf);
if (psurf == NULL)
{
+ DPRINT1("Failed to reference surface %p\n", hsurf);
return FALSE;
}
ppdev = (PDEVOBJ*)hdev;
pso = &psurf->SurfObj;
pso->dhsurf = dhsurf;
- pso->lDelta = lDelta;
- pso->pvScan0 = pvScan0;
/* Associate the hdev */
pso->hdev = hdev;
SURFACE_vSetPalette(psurf, ppal);
PALETTE_ShareUnlockPalette(ppal);
+ /* Update surface flags */
+ if (flSurface & MS_NOTSYSTEMMEMORY)
+ pso->fjBitmap |= BMF_NOTSYSMEM;
+ else
+ pso->fjBitmap &= ~BMF_NOTSYSMEM;
+ if (flSurface & MS_SHAREDACCESS)
+ psurf->flags |= SHAREACCESS_SURFACE;
+ else
+ psurf->flags &= ~SHAREACCESS_SURFACE;
+
+ /* Check if the caller passed bitmap bits */
+ if ((pvScan0 != NULL) && (lDelta != 0))
+ {
+ /* Update the fields */
+ pso->pvScan0 = pvScan0;
+ pso->lDelta = lDelta;
+
+ /* This is a bitmap now! */
+ pso->iType = STYPE_BITMAP;
+
+ /* Check memory layout */
+ if (lDelta > 0)
+ {
+ /* Topdown is the normal way */
+ pso->cjBits = lDelta * pso->sizlBitmap.cy;
+ pso->pvBits = pso->pvScan0;
+ pso->fjBitmap |= BMF_TOPDOWN;
+ }
+ else
+ {
+ /* Inversed bitmap (bottom up) */
+ pso->cjBits = (-lDelta) * pso->sizlBitmap.cy;
+ pso->pvBits = (PCHAR)pso->pvScan0 - pso->cjBits - lDelta;
+ pso->fjBitmap &= ~BMF_TOPDOWN;
+ }
+ }
+ else
+ {
+ /* Set bits to NULL */
+ pso->pvBits = NULL;
+ pso->pvScan0 = NULL;
+ pso->lDelta = 0;
+
+ /* Set appropriate surface type */
+ if (pso->iType != STYPE_DEVICE)
+ pso->iType = STYPE_DEVBITMAP;
+ }
+
SURFACE_ShareUnlockSurface(psurf);
return TRUE;
psurf = SURFACE_ShareLockSurface(hsurf);
if (!psurf)
{
- DPRINT1("Could not reference surface to delete\n");
+ DPRINT1("Could not reference surface %p to delete\n", hsurf);
return FALSE;
}
return psurf ? &psurf->SurfObj : NULL;
}
-VOID
+__kernel_entry
+NTSTATUS
APIENTRY
-NtGdiEngUnlockSurface(IN SURFOBJ *pso)
+NtGdiEngUnlockSurface(
+ _In_ SURFOBJ *pso)
{
UNIMPLEMENTED;
ASSERT(FALSE);
+ return STATUS_NOT_IMPLEMENTED;
}
VOID